1
\$\begingroup\$

I have some rudimentary collision code:

public class Collision {
    static boolean isColliding = false;
    static Rectangle player;
    static Rectangle female;

    public static void collision(){
        Rectangle player = Game.Playerbounds();
        Rectangle female = Game.Femalebounds();

        if(player.intersects(female)){
            isColliding = true;
        }else{
            isColliding = false;
        }
    }
}

And this is the rectangle code:

public static Rectangle Playerbounds() {
    return(new Rectangle(posX, posY, 25, 25));
}

public static Rectangle Femalebounds() {
    return(new Rectangle(femaleX, femaleY, 25, 25));
}

My InputHandling class:

public static void movePlayer(GameContainer gc, int delta){
    Input input = gc.getInput();

    if(input.isKeyDown(input.KEY_W)){
        Game.posY -= walkSpeed * delta;
        walkUp = true;

        if(Collision.isColliding == true){
            Game.posY += walkSpeed * delta;
        }
    }

    if(input.isKeyDown(input.KEY_S)){
        Game.posY += walkSpeed * delta;
        walkDown = true;

        if(Collision.isColliding == true){
            Game.posY -= walkSpeed * delta;
        }
    }

    if(input.isKeyDown(input.KEY_D)){
        Game.posX += walkSpeed * delta;
        walkRight = true;

        if(Collision.isColliding == true){
            Game.posX -= walkSpeed * delta;
        }
    }

    if(input.isKeyDown(input.KEY_A)){
        Game.posX -= walkSpeed * delta;
        walkLeft = true;

        if(Collision.isColliding == true){
            Game.posX += walkSpeed * delta;
        }
    }
}

The code works partially. Only the right and top side of the images collide. How do I correct the rectangle so it will draw on all sides?

\$\endgroup\$
4
  • \$\begingroup\$ "How do I correct the rectangle so it will draw on all sides?" you mean "collide on all sides"? Also are you sure the position the position of the rectangle you create is the same as the entity position? \$\endgroup\$
    – nathan
    Oct 27 '12 at 22:10
  • \$\begingroup\$ Oh yeah it should be collide sorry. And yes I'm sure. That doesn't cause any problems so I haven't changed it. \$\endgroup\$
    – opiop65
    Oct 27 '12 at 22:22
  • \$\begingroup\$ It would be interesting to see what you do when you know a collision happen. You only show the collision detection. \$\endgroup\$
    – nathan
    Oct 27 '12 at 22:23
  • \$\begingroup\$ Oh sorry, I'll update the code to include my inputHandling class. \$\endgroup\$
    – opiop65
    Oct 27 '12 at 22:24
2
\$\begingroup\$
//This checks overlap in a single dimension -- either x or in y
public boolean checkOverlap(int start0, int end0, int start1, int end1) 
{
    if(start0 > start1 && start0 < end1)
        return true;
    if(start1 > start0 && start1 < end0)
        return true;
    return false;
}

//This does it for two dimensions. If overlapping in X AND Y, you've collided.
//You can call this in your movePlayer handler, but if the "females" (er!) move
//AS WELL, then you must do it per update or you will miss collisions (unless
//you make sure all "females" are moved before the player, on each update).    
public bool isColliding(Rectangle rect0, Rectangle rect1)
{
    if (checkOverlap(rect0.x, rect0.x + rect0.width, rect1.x, rect1.x + rect1.width) &&
        checkOverlap(rect0.y, rect0.y + rect0.height, rect1.y, rect1.y + rect1.height))
    {
        //resolve your collision. You don't need to store isColliding -- just
        //calculate, then act on the result. 
    }    
}

On each game loop update: Get your inputs, move the player, get all inputs for other entities and move them, then at the end, run through the full entities list (player + "females") and run isColliding() on each. This the standard way to do 2D AABB collisions.

Actually if you are running through the full list of n entities and comparing them against n-1 other entities, then for the first entity in the list, call it a, you will have to check against b through n, but on checking b you will not have to check it against a (since a was just checked against b in the prior step) or itself, so you would check from c through n... and so on for each remaining entity. This essentially looks like:

for (int i = 0; i < entities.length; i++) //run through ALL entities
{
   Entity e1 = entities[i];
   for (int j = i+1; j < entities.length; j++) //run through each entity AFTER e1
   {
       Entity e2 = entities[j];
       if (isColliding(e1.rect, e2.rect))
           resolveCollisionFor(e1, e2);
   }
}
\$\endgroup\$
2
  • \$\begingroup\$ @opiop65 Any luck? \$\endgroup\$
    – Engineer
    Oct 28 '12 at 18:01
  • \$\begingroup\$ @opiop65, If I helped, then you may as well accept my answer since your accept rating will improve and others will then be more likely to answer your questions in future -- thanks. \$\endgroup\$
    – Engineer
    Oct 28 '12 at 18:18
0
\$\begingroup\$

Looking at your code I think you forgot calling Collision.collision(); before checking if Collision.isColliding == true so Collision.isColliding has always the same value
You should do something like this:

if(input.isKeyDown(input.KEY_W)){
    Game.posY -= walkSpeed * delta;
    walkUp = true;
    Collision.collision();
    if(Collision.isColliding == true){
        Game.posY += walkSpeed * delta;
    }
}   
\$\endgroup\$
1
  • \$\begingroup\$ Thanks, this will probably help later on but it still doesn't fix anything. The boolean updates correctly and is false when not colliding so thats not the problem... \$\endgroup\$
    – opiop65
    Oct 27 '12 at 23:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.