Public Group

# Bounding box collision in a platformer game

This topic is 1824 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello devs,

I am making a prototype for my first game (when I say "first" I mean that I camed up with the ideea myself, not games like pong or tic-tac-toe, which by the way, you can see here and here).

I had some problems with gravity but fixed it after a while. Next problem that I faced was bounding box collision detection...

[attachment=19567:Capture.PNG]

With red are drawn the bounding boxes.

I can stay on the top the ground. But like in any other platformer, you will hit the platform from down, left and right too.

I don't really know how to code collision when player hit the platform from other sides.

Here is the code to stay above the platform.

if(player.bbox.Intersect(&platform1.bbox))
{
player.y = platform1.y1 - player.width; //platform1.y1 - top-left corner Y coordinate
}


My bounding box class give me acces just to: x1, y1, x2, y2 coordinates of the bounding box, Intersect function (that checks if 2 bounding boxes intersects) and TestPoint function(that checks if a point is inside a bounding box).

How I can do the collision with the other sides of the platform not only the top of it?

Edited by Bratie Fanut

##### Share on other sites

I cover the topic in detail in this tutorial

Here is the code to detect a collision from any direction:

return (this.x <= rect.x + rect.width &&
rect.x <= this.x + this.width &&
this.y <= rect.y + rect.height &&
rect.y <= this.y + this.height);


The explanation of why it works is in the tutorial.  I actually did a whole series of gamdev math tutorials that you may find useful.

Let me know if you have any questions.

##### Share on other sites
The logic is just the same, you could just swap X and Y for that matter...

Using the same approach you used on your own function:
if(player.bbox.Intersect(&platform1.bbox))
{
//Y axis
if (player.y1 <= platform1.y1) //assuming y1 to be the "bigger-y coordinate"
player.y1 = platform1.y1 - player.height; //To place it on top of the platform.
else
player.y1 = platform1.y2 + 1; //To place it under the platform when hit from below.
//X axis
if (player.x1 >= platform1.x1) //assuming x1 to be the "smaller-x coordinate"
player.x1 = platform1.x2 + 1;
else
player.x1 = platform1.x1 - player.width; //To move it aside from the intersected platform.
}

This could probably work on general situations, with moderate speeds and all that.
I am assuming that (y1, x1) is the top-left coordinate, and (x2, y2) is the bottom-right one.
You'll probably have to adjust the code.

I guess I've been using Box2D for too long, getting lazy. Edited by dejaime

##### Share on other sites

The logic is just the same, you could just swap X and Y for that matter...

Using the same approach you used on your own function:

if(player.bbox.Intersect(&platform1.bbox))
{
//Y axis
if (player.y1 >= platform1.y1) //assuming y1 to be the "bigger-y coordinate"
player.y1 = platform1.y1 - player.height; //To place it on top of the platform.
else
player.y1 = platform1.y2 + 1; //To place it under the platform when hit from below.
//X axis
if (player.x2 >= platform1.x1) //assuming x1 to be the "smaller-x coordinate"
player.x1 = platform1.x1 - player.width; //To move it aside from the intersected platform.
else
player.x1 = platform1.x2 + 1;
}


This could probably work on general situations, with moderate speeds and all that.

I am assuming that (y1, x1) is the top-left coordinate, and (x2, y2) is the bottom-right one.

You'll probably have to adjust the code.

Remember to reset the speeds and all that when it hit an immovable object!

I guess I've been using Box2D for too long, getting lazy.

You are assuming everything right. I am getting lazy too... I should think of another checking in that if statement..

I will try it to see if it works.

##### Share on other sites

I cover the topic in detail in this tutorial

Here is the code to detect a collision from any direction:

return (this.x <= rect.x + rect.width &&
rect.x <= this.x + this.width &&
this.y <= rect.y + rect.height &&
rect.y <= this.y + this.height);


The explanation of why it works is in the tutorial.  I actually did a whole series of gamdev math tutorials that you may find useful.

Let me know if you have any questions.

I will check your tutorials. Thank you:)

##### Share on other sites

You are assuming everything right. I am getting lazy too... I should think of another checking in that if statement..
I will try it to see if it works.

My last code is wrong, the horizontal part, I have just fixed it, please take another look. Edited by dejaime

##### Share on other sites

Its not working.. the condition for y axis and x axis are true at the same time.. so when I jump on the platform I stay on top of it but because x axis conditions are true I am stucked.

##### Share on other sites
Yes, it needs another test level... Be back in a jiffy.

if(player.bbox.Intersect(&platform1.bbox))
{
//Y axis
if (player.y1 <= platform1.y1) {//assuming y1 to be the "bigger-y coordinate"
player.y1 = platform1.y1 - player.height; //To place it on top of the platform.
}
else if (player.y1 >= platform1.y2) {
player.y1 = platform1.y2 + 1; //To place it under the platform when hit from below.
}
//X axis
else {
if (player.x1 >= platform1.x1) //assuming x1 to be the "smaller-x coordinate"
player.x1 = platform1.x2 + 1;
else
player.x1 = platform1.x1 - player.width; //To move it aside from the intersected platform.
}
}

This should prevent it from updating both at the same time... It could also be something like this:

if(player.bbox.Intersect(&platform1.bbox))
{
//Y axis
if (/*vertical collision*/) {
if (player.y1 <= platform1.y1) {//assuming y1 to be the "bigger-y coordinate"
player.y1 = platform1.y1 - player.height; //To place it on top of the platform.
}
else {
player.y1 = platform1.y2 + 1; //To place it under the platform when hit from below.
}
//X axis
if (/*horizontal collision*/) {
if (player.x1 >= platform1.x1) //assuming x1 to be the "smaller-x coordinate"
player.x1 = platform1.x2 + 1;
else
player.x1 = platform1.x1 - player.width; //To move it aside from the intersected platform.
}
}
Sorry for anything wrong, I'm just not used to code without obsessively testing every added code block. I guess I am not used to think ahead...

##### Share on other sites

Can I ask why you don't use a really simple 2D physics system like this one? Something like that is more robust and re-usable than what it looks like you're doing.

##### Share on other sites
Something I used in a project is checking collisions between the front sides of a moving box against the back sides of the others.

After you calculate all the forces influencing your character, you have the resultant force as a 2D vector.

You can verify the numerical signs of the components of this force to know which sides of the box are the front sides, which are the sides facing towards the direction of movement.
The sign of the X component of the force indicates whether a frontal side of the box will be the left or right one, and the sign of the Y component of the force indicates if the other frontal side is up or down. When the force is completely horizontal or vertical so one of the components of the force has a sign of "zero," you will have a single frontal side.

It is these front sides that will collide against the back sides of the other boxes - the front sides of a box can only collide against the back sides of another box, you will never have back-back or front-front side collision.

This helps avoiding a common issue where your character can skip obstacles if it moves more than the width or the height of its collision box on a single frame.
You can use the old frame position for the back sides of the character's box and use the new position for the front sides of the character's box (the position of the front sides after they are moved). This way you don't have a box anymore, but an extruded "shape" that represents the full motion of the character for that frame, and it is something that always seems pass tests no matter the speed of the character.
You can still use rectangle intersections with this. You would supply the coordinates of the top-left corner and the bottom-right corner of the screen area (or bounding box) occupied by this shape as a rectangle to be tested against the others. While this is an approximation, it seems to convey the illusion to great effect.
When a collision is detected, instead of simply stopping the character, you need to move it as much as it is possible to move both horizontally and vertically until it reaches the obstacle. This is simple to calculate based on the position and boundaries of the character and the position and boundaries of the obstacle. This makes the character gently touch a wall instead of keeping a distance from it, in case the character moves farther than its width or height. Edited by Kryzon

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 15
• 11
• 9
• 9
• 38
• ### Forum Statistics

• Total Topics
634129
• Total Posts
3015700
×