Simple Math Problem

I’m attempting to make a little if statement that decides whether to render a sprite to the screen or not. On paper it makes perfect sense but for some reason it’s not working at all when I put it into code.
I’ve managed to get one of the equations to work, xLocation > (x+400), everything else just doesn’t work no matter how I’ve tried it.

Code Snip:

// Decides whether to render the sprite or not.
        int x = player.getXLocation();
        int y = player.getYLocation();
        if(xLocation > (x+400) || xLocation < (x-400) || yLocation < (y-400) || yLocation > (y+400))
        {
            renderMe = false;
        }
        else
        {
            renderMe = true;
        }

What I’m trying to do is check if the X and Y locations of the enemy sprite are within 400 in any cardinal direction of the player and if it is then render it, if not then don’t render it. It’s kind of like creating a box around the player and checking if the enemy is inside of it. The four equations I’ve made up are:

  • enemyYPosition < playerYPosition-400
  • enemyYPosition > playerYPosition+400
  • enemyXPosition < playerXPosition-400
  • enemyXPosition > playerXPosition+400

They stand for:

  • If the enemy is further than 400 South of the player.
  • If the enemy is further than 400 North of the player.
  • If the enemy is further than 400 West of the player.
  • If the enemy is further than 400 East of the player

I probably just messed up my math somehow, if anyone can see what I did wrong please say so.

Wait, libgdx or some other library or java2d? Because the y axis is inverted in java2d but not in libgdx

Java2D, I don’t use any non-standard libraries atm.

What exactly is the problem? It’s rendering when it’s not supposed to or it’s not rendering when it’s supposed to?

The code is always setting renderMe to false, even when it shouldn’t; the only time when renderMe is set to true is when the enemy is at least 400 to the West of the player.

Edit: Here is a picture of what I’m trying to do. Render the enemy if it’s within the green area and don’t render it if it’s in the yellow area. http://i.imgur.com/Jb46jTD.png

Have you debugged your code so you know that all location values are correct?

As far as I can see from this test I saved, they are.

[quote]Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
Player xLocation: 582 Player yLocation: 437
182 982 37 837
[/quote]
The odd rows show the player’s location, both X and Y. The even rows show x-400, x+400, y-400, y+400.

Edit: Just tested with the enemy’s location instead of the player’s and it seems that the enemy only appears when it’s 300 away from the player. I’m not sure why it’s 300 instead of the 400. Bleh, this is confusing.

This doesn’t make any sense. You say that your xLocation variable is the player x and your yLocation variable is the player y. However, your “x” variable is already your player x and your “y” variable is also already your player y…

int x = player.getXLocation();
        int y = player.getYLocation();
        System.out.println(xLocation+"   "+yLocation);
        if(xLocation > (x+400))
        {
            renderMe = false;
        }
        else
        {
            renderMe = true;
        }

The x and y variables are the player’s x and y locations. The xLocation and yLocation variables are the enemy’s locations.

Well then, it might help to print the enemy locations… ::slight_smile:

Here’s a readout of all of the data including the enemy’s positions and whether the enemy is visible or not; this is only testing the X axis. http://pastebin.com/ngc8tXu0

Your if-statements look correct. could anything be messing with renderMe between your if-statement and the rendering?

As far as I can see there is nothing that could be, here is a snip of the class where renderMe is used to decide whether to render the sprite or not.

if(nonPlayer.getRenderMe())
        {
            g.drawImage(resource.getSprite(0, playerDirection, spriteCounter), nonPlayer.getXLocation(), nonPlayer.getYLocation(), null);
            
            if (!playerIsWalking)
            {
                spriteCounter = 0;
                spriteCounterTwo = 0;
            }
            else
            {
                if(spriteCounter == 0)
                {
                    spriteCounter = 1;
                }
                else if (spriteCounter == 1 && spriteCounterTwo >= 15)
                {
                     spriteCounter++;
                     spriteCounterTwo = 0;
                }
                else if (spriteCounter == 2 && spriteCounterTwo >= 15)
                {
                    spriteCounter--;
                    spriteCounterTwo = 0;
                }
            }
        }

In the one circumstance, which I have previously mentioned, where the code actually does work, this snip works perfectly.

Add system.out.println statements to display the value of renderMe after the if statement, and add some in every step of your drawing function to see where things stop.

I added one in the render code and after it, they’re always the same. Putting them in the various steps of the render code wouldn’t show anything other than true because the render code only runs when renderMe is true.

I know the way that I have everything set up and no matter how I think about this, there should be no reason for this to not be working. It’s getting the position of the player, doing some simple math, checking if a few values are higher or lower than others and then changing a boolean. The fact that this isn’t working is just weird to me…

…this is 2d so we are basically going to be doing culling or w/e it is called in 3d but in 2d.

Since you are using java2d which has some great utilities you should use.

If you want a circle around your player of visible enemies that is very easy.

If you want a square then for Gods sake use shapes/squares/rectangles that java2d gives you. They have a nice intersects method. I could post the code for both but that would not really help you learn so take this and have at it.

Oh god… not the distance formula again. shudders in fear We just finished using that awhile ago. Thanks for the link, I’ll check it over.

I would use the shapes but it seemed easier just to figure everything out without them, it’s worked quite well so-far.

I wonder if one thing you can do is put the player in the middle of the screen and then place an enemy at every single pixel on the screen. If renderMe is true then draw a red pixel for that enemy, if renderMe is false then draw a gray one. This will give you the full picture of where your algorithm is working and where it isn’t.

You don’t necessarily have to put an actual enemy, just iterate through all of the points on the screen.

Don’t do any of that. I will help with how the distance formula works.

The idea is to create a triangle and then find the hypotenuse.

So some psudo code.


public boolean distanceCheck( loc1x, loc1y, loc2x, loc2y, maxDistance)
{
      int xDiff = (loc1x-loc2x);
      xDiff *= xDiff //square it. 
      int yDiff = (loc1y-loc2y);
      yDiff *= yDiff;//square it
      int distance = Math.sqrt(xDiff+yDiff);
      if(distance > maxDistance)
          return false; //not in the circle. 
      else
          return true; 
}


Note that, that all can be done in one line but I use many for the sake of clarity. There is also an optimization that is not all necessary but might be something to look into. You will probably figure it out. Basically, stay away from anything that is not addition, subtraction, or multiplication.

Even though I agree with StumpyStrust, the code snippet you posted should work. If I were you, I’d separate the statements and figure out exactly which one is messing up.


         // Decides whether to render the sprite or not.
        int x = player.getXLocation();
        int y = player.getYLocation();
       
        //Always try to render the enemy. Print out the player and enemy locations.
        renderMe = true;
        System.out.println("Player Location: ("+x+","+y+")");
        System.out.println("Enemy Location: ("+xLocation+","+yLocation+")");
        
        //Put each test case into the "fake" debugger to see which ones trigger. Same code but stretched out.
        if ( xLocation < (x-400) ){
              System.out.println("Render Fail: Enemy Too Far West!");
              renderMe = false;
        }
        if ( xLocation > (x+400) ){
              System.out.println("Render Fail: Enemy Too Far East!");
              renderMe = false;
        }
        if ( yLocation < (y-400) ){
              System.out.println("Render Fail: Enemy Too Far North!");
              renderMe = false;
        }
        if ( yLocation > (y+400) ){
              System.out.println("Render Fail: Enemy Too Far South!");
              renderMe = false;
        }

        //Split up the readout... so that you can read it easier.
        System.out.println("-------------------------------------");


Replace this code snippet with the one you currently have. This should be able to tell you exactly where your code is failing. (Either that, or the code will work…) Either way, it should be much more informative in figuring out what is going wrong, because that code is 100% accurate in my book.