Sign in to follow this  
hallgeir

Collision detection in a mario-type game?

Recommended Posts

Hi. I'm wondering about one thing: How can I find out what side of an object collides with a specific side of another object? Here's an example - the Super Mario games. What "end" of Mario that collides with the enemies determines if the enemy dies, or you dies. Run straight into one and you get hurt, jump on top of one and IT get hurt. Same with breakable bricks - you can stand on them, they block you if you try to run into them, but you can break them by bashing your skull underneath it. So how is that kind of collision detection done? I'm guessing more has to be done than a simple box-box intersection check. Any help is appreciated, thanks. :)

Share this post


Link to post
Share on other sites
Hi, I'm not certain how Mario handles it.

But here is how many other 2D platformers handle it:
Mario has two hit boxes. One covering his legs, one covering his head.
The enemy mushroom has one hit box.

So when your doing the intersection checks:
If Mario's head hitbox is intersecting with the Mushroom's hitbox: Mario's dead.
Else If Mario's leg hitbox is intersecting with Mushroom's hitbox: Mushroom's dead.
Else, the two aren't touching in this frame, and they should continue on their merry way.

Cheers
-Cuppo

Share this post


Link to post
Share on other sites
The collision detection in the original Super Mario Brothers is a bit glitchy. If Mario is moving downwards, then the enemy is stomped, even if the enemy is above Mario (this can happen near the top of a jump, for example). For the most part no one notices this (except for people making tool assisted speed runs and such). I think it might also check if mario is a certain height above the enemy when the collision happens (if Mario is not falling). So you can look at the height of a character's feet and compare that to some height on the enemy to determine what happens. You might also want to use the previous position instead of the current position when checking this, but I'm not sure how much of a difference it would make or which would create the correct effect in your game.

As for smashing bricks, just look at the character's position and velocity to decide what to do. It may require some tweaking to get it to feel right.

Share this post


Link to post
Share on other sites
Another option is after determining the collision you can check the difference between the two objects, if y is greater than x then you're most likely on the guy's head, or closer to it and if x is greater than you're closer to their side. Also, if y is positive, assuming you do character_y - enemy_y then you're above, and if y is negative then you're below. There are so many ways to do it, it all depends on how accurate you want the result to be and how optimized you want it to be.

Share this post


Link to post
Share on other sites
If you are using vectors for keeping track of your movement, then it becomes quite simple. For example, if your movement vector is [1, 0] and the collision check says there is a collision, then you know that you hit the left side of the enemy. If the vector is [x, -1] then you know that you hit the top of the enemy.

Also, you can do some simple checks to get the information you need. If mario was in the air last frame, then you hit the enemy from the top. If mario was not in the air in the last frame, then you hit him from the side.

Hope that helps.

Share this post


Link to post
Share on other sites
That's not necessarily true about the vector movement. If you are moving right and you get hit then it may be that the enemy is moving faster than you and hit you from the left. In certain applications that will work but there are definitely exceptions.

Share this post


Link to post
Share on other sites
Quote:
Original post by xerodsm
That's not necessarily true about the vector movement. If you are moving right and you get hit then it may be that the enemy is moving faster than you and hit you from the left. In certain applications that will work but there are definitely exceptions.


Thanks for pointing that out. However, in my example I was assuming that the enemies were coming from the right, as in most standard mario-type games. If enemies are coming from both sides, then the movement vector of the enemy will also have to be incorporated. For example if the movement vector of the enemy is [2, 0] and the vector of the player is [1, 0], then the enemy hit the player from the left.

There might be some more problems with this method, since I haven't actually tried it yet.

Share this post


Link to post
Share on other sites
Just a psuedo bit of code, something similar that I used in an arkanoid clone once.

do your normal bounding box collision to test for a collission, then to get what side of the player hit the object, you do this.


// bounding box variables
// player
float px1,px2,py1,py2;
// object
float ox1,ox2,oy1,oy2;

// test for left side
if ( (px1 < ox2) && (px2 > ox2) ) //we hit on the left side of the player
// test the bottom side
if ( (py2 > oy1) && (py1 < oy1) ) //we hit on the bottom side of the player
// so on and so...


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this