Jump to content

  • Log In with Google      Sign In   
  • Create Account

Bounding box collision in a platformer game


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 Vidar son of Odin   Members   -  Reputation: 1322

Like
0Likes
Like

Posted 20 January 2014 - 08:59 AM

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... 

 

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, 20 January 2014 - 09:02 AM.

Check out my portfolio : https://bratie.wordpress.com

"Don't gain the world and lose your soul. Wisdom is better than silver or gold." - Bob Marley

 


Sponsor:

#2 Serapth   Crossbones+   -  Reputation: 5484

Like
4Likes
Like

Posted 20 January 2014 - 10:29 AM

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.



#3 dejaime   Crossbones+   -  Reputation: 4027

Like
1Likes
Like

Posted 20 January 2014 - 10:31 AM

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, 20 January 2014 - 10:56 AM.


#4 Vidar son of Odin   Members   -  Reputation: 1322

Like
0Likes
Like

Posted 20 January 2014 - 10:44 AM

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.


Check out my portfolio : https://bratie.wordpress.com

"Don't gain the world and lose your soul. Wisdom is better than silver or gold." - Bob Marley

 


#5 Vidar son of Odin   Members   -  Reputation: 1322

Like
0Likes
Like

Posted 20 January 2014 - 10:45 AM

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:)


Check out my portfolio : https://bratie.wordpress.com

"Don't gain the world and lose your soul. Wisdom is better than silver or gold." - Bob Marley

 


#6 dejaime   Crossbones+   -  Reputation: 4027

Like
1Likes
Like

Posted 20 January 2014 - 10:55 AM

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, 20 January 2014 - 10:59 AM.


#7 Vidar son of Odin   Members   -  Reputation: 1322

Like
0Likes
Like

Posted 20 January 2014 - 11:33 AM

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.


Check out my portfolio : https://bratie.wordpress.com

"Don't gain the world and lose your soul. Wisdom is better than silver or gold." - Bob Marley

 


#8 dejaime   Crossbones+   -  Reputation: 4027

Like
2Likes
Like

Posted 20 January 2014 - 01:19 PM

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...

#9 NoAdmiral   Members   -  Reputation: 511

Like
0Likes
Like

Posted 20 January 2014 - 01:40 PM

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.


Inspiration from my tea:

"Never wish life were easier. Wish that you were better" -Jim Rohn

 

herwrathmustbedragons.tumblr.com


#10 Kryzon   Prime Members   -  Reputation: 3072

Like
4Likes
Like

Posted 20 January 2014 - 01:44 PM

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, 20 January 2014 - 02:07 PM.


#11 Vidar son of Odin   Members   -  Reputation: 1322

Like
0Likes
Like

Posted 21 January 2014 - 07:25 AM

I finally made it work! Thanks @dejaime and @Kryzon. Thumbs up. 


Check out my portfolio : https://bratie.wordpress.com

"Don't gain the world and lose your soul. Wisdom is better than silver or gold." - Bob Marley

 


#12 BeerNutts   Crossbones+   -  Reputation: 2950

Like
0Likes
Like

Posted 24 January 2014 - 12:43 PM

I finally made it work! Thanks @dejaime and @Kryzon. Thumbs up. 

You can see this thread for answers on the same subject.


My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS