Simple Rectangle collision code only half working.

Hello, so I’m currently using rectangle collisions to check whether objects in my game collide or not. I did some research and came across Axis Aligned Bounded Box collision checking which I then implemented into my game.
However, the issue arises when the object moves to negative coordinates in the game, in that case the ball just keeps moving and never collides.

I currently have (0,0) as the center of the game. The X-Axis boundes are from -3.5 to 3.5 and Y-Axis bounds are from 2 to -2. Any collision on the negative coordinates doesn’t compute correctly and therefor no collision occurs according to the function, but it should.

Here is my collision function:

 
bool Model::box_collision(Hbox rect1, Hbox rect2){

 bool collisionX;
 bool collisionY;

    collisionX = rect1.x + rect1.width >= rect2.x && rect2.x+rect2.width >= rect1.x;
    collisionY = rect1.y + rect1.height >= rect2.y && rect2.y + rect2.height >= rect1.y;

return collisionX && collisionY;
}

Any help is appreciated. Thanks! :slight_smile:

Here is your answer:

[QUOTE=ProgrammerX;1290881]Here is your answer:

Thank you for your response ProgrammerX. After looking at that explanation I came up with this. It does work but can you confirm if it logically looks correct?

 static bool box_collision(Hbox rect1, Hbox rect2)
 {

 bool collisionX;
 bool collisionY;

    collisionX = (rect1.x + rect1.width >= rect2.x - rect2.width && rect1.x + rect1.width <= rect2.x + rect2.width) || (rect2.x + rect2.width >= rect1.x - rect1.width && rect2.x + rect2.width <= rect1.x + rect1.width);
    collisionY = (rect1.y + rect1.height >= rect2.y - rect2.height && rect1.y + rect1.height <= rect2.y + rect2.height) || (rect2.y + rect2.height >= rect1.y - rect1.height && rect2.y + rect2.height <= rect1.y + rect1.height);

    return collisionX && collisionY;
}

So the [var]x[/var] and [var]y[/var] fields are the coordinates of the centre, and the [var]width[/var] and [var]height[/var] fields are half the width and height respectively?

Even so, it’s unnecessarily complex. Your first version has the correct structure, but the actual calculations are only correct if X/Y denote one corner.

Also, if the width or height can be negative, then you need to use min/max to determine the edges.

[QUOTE=GClements;1290886]So the [var]x[/var] and [var]y[/var] fields are the coordinates of the centre, and the [var]width[/var] and [var]height[/var] fields are half the width and height respectively?

Even so, it’s unnecessarily complex. Your first version has the correct structure, but the actual calculations are only correct if X/Y denote one corner.

Also, if the width or height can be negative, then you need to use min/max to determine the edges.[/QUOTE]

Width and height are half the total width/height. So height of 2 would mean a total height of 4.

Could you give me a pointer on the min/max to determine the edges, I’m slightly unsure what you mean? Thank you again!

[QUOTE=nephtie;1290887]
Could you give me a pointer on the min/max to determine the edges, I’m slightly unsure what you mean? Thank you again![/QUOTE]
As the stack overflow answer mentions, the intersection test is based upon the positions of the left/right/top/bottom edges.

If width and height are always positive, then the left and right edges are rect.x-rect.width and rect.x+rect.width, and similarly for the top and bottom. If width or height could be negative, then the left edge is the min() of those two values, while the right edge would be the max().

Either way, you only need 4 comparisons: left1<right2 && left2<right1 && bottom1<top2 && bottom2<top1 (assuming that the positive y direction is up).

[QUOTE=GClements;1290890]As the stack overflow answer mentions, the intersection test is based upon the positions of the left/right/top/bottom edges.

If width and height are always positive, then the left and right edges are rect.x-rect.width and rect.x+rect.width, and similarly for the top and bottom. If width or height could be negative, then the left edge is the min() of those two values, while the right edge would be the max().

Either way, you only need 4 comparisons: left1<right2 && left2<right1 && bottom1<top2 && bottom2<top1 (assuming that the positive y direction is up).[/QUOTE]

Thanks a bunch. Got it working now.

As I progressed, a new issue arose. I’m trying to figure out how to take multiple inputs. I use booleans and keyrelease checks and it works flawlessly for single player. But when a second player is introduced, if player 1 is moving then player 2 pauses and can’t progress and vice versa. If anyone could point me to the right direction with this, it would be spectacular.

I will be figuring it out in the meantime.