# AABB collision detection not detecting in some cases

I'm using simple AABBs in a tile based world, and for some reason the algorithm does not detect collisions when moving towards the left and then down. I actually upload a video to YouTube to demonstrate the problem because I can't figure out a good way to explain my problem. Here it is: AABB collision detection problem

As you can see, the little wireframe tile that moves around is the player, and when I move to the left, and then try to move down on the tiles, the player just slips right through. Detection works when moving to the right. Here's my algorithm to detect collisions:

public static boolean isColliding(AABB a, AABB b) {
if (Math.abs(a.pos.getX() - b.pos.getX()) < a.size + b.size) {
if (Math.abs(a.pos.getY() - b.pos.getY()) < a.size + b.size) {
return true;
}
}
return false;
}


The pos variable in the AABB class is the center of the AABB in question, and the size is half the size. Here's how I move the player:

if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
move(0, 1, 0, MOVESPEED);
}
if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
move(1, 0, MOVESPEED, 0);
}
if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
move(-1, 0, -MOVESPEED, 0);
}
if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
move(0, -1, 0, -MOVESPEED);
}
if (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && onGround) {
onGround = false;
}


Which references this method:

private void move(float x, float y, float sx, float sy) {
if (getX() / 32 + x >= 0 && getX() / 32 + x <= world.mx && getY() / 32 + y >= 0 && getY() / 32 + y <= world.my) {
if (world.tiles[(int) ((int) getX() / 32 + x)][(int) ((int) getY() / 32 + y)] != null) {

Tile t = world.tiles[(int) ((int) getX() / 32 + x)][(int) ((int) getY() / 32 + y)];
Vector2f tempPos = new Vector2f((pos.getX() + (pos.getX() + 32)) / 2, (pos.getY() + (pos.getY() + 32)) / 2);
box.update(new Vector2f(tempPos.getX() + sx, tempPos.getY() + sy), 16);
t.color = true;

if (!Collision.isColliding(box, t.getBox())) {
setPos(getX() + sx, getY() + sy);
}
} else {
setPos(getX() + sx, getY() + sy);
}
} else {
setPos(getX() + sx, getY() + sy);
}
glPushMatrix();
glTranslatef(getX(), getY(), 0);
glPopMatrix();
}


32 is the tile size and the player size, just for reference. The 'tempPos' vector is just a vector that holds the center of the player's position. AABB is a class that stores a vector and a size variable, and the update method just updates those variables.

I guess my question is either, why is it only working on one axis, or how can I change my move method to be "better"? I've been trying to figure out why this isn't working, and I just can't come up with any ideas because it happens constantly, so it's not that my entities are moving too fast and the algorithm isn't detecting the collisions.

• Looks like you are only checking collision with tiles that are to the left of your player. In your move function, you are truncating with your divisions which may be causing this issue. – congusbongus Dec 10 '13 at 4:18
• So should I check if I'm moving to the left and then instead multiply to find my position? – opiop65 Dec 10 '13 at 10:51
• But wait, no that makes no sense because I'm dividing to find my world coordinates. How does that make any sense? – opiop65 Dec 10 '13 at 11:15

if (world.tiles[(int) ((int) getX() / 32 + x)][(int) ((int) getY() / 32 + y)] != null) {

You're going to be checking the point tile (10, 9), which is fine. But your tile is positioned half way between two tiles. That means you should also be checking the tile (11, 9) for a collision. Casting to an (int) rounds down. But you should also have a conditional where you are rounding up.