Jump to content
  • Advertisement
Sign in to follow this  
bratiefanut

Bounding box collision in a platformer game

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

mj0lcn.jpg

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.

1gcut.jpg

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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!