Collision problems in a 2D platformer

Started by
9 comments, last by Zakwayda 12 years, 10 months ago
I need your help guys. I am working on a 2D platformer (see my signature) but I have problems with collision of my character. I want him to jump and walk around like in a Super Mario game.

I am using bounding rectangle collision method and this part works.

The problem is when my character is colliding with a platform, how can I determine whether or not he will stop moving left-right, or up-down if he is falling/jumping ?

I have written a method where you determine which vertex of the character has hit the platform and then depending on the x and y velocity you determine what to do for each case.
In 99% of cases this method works, but from time to time player gets teleported above or under the platform when he shouldn't, he gets stuck... and I am just getting frustrated.

How do you handle this "platforming" issues, I need ideas ? It shouldn't be that hard ?
Advertisement

I need your help guys. I am working on a 2D platformer (see my signature) but I have problems with collision of my character. I want him to jump and walk around like in a Super Mario game.

I am using bounding rectangle collision method and this part works.

The problem is when my character is colliding with a platform, how can I determine whether or not he will stop moving left-right, or up-down if he is falling/jumping ?

Collision is really too complex for this broad a question. Someone could answer it with a book. I will answer it with a blog/tutorial http://www.metanetsoftware.com/technique/tutorialA.html

Check that out and if you have any more specific questions then I will be happy to answer them.

I have written a method where you determine which vertex of the character has hit the platform and then depending on the x and y velocity
[/quote]
what if no vertex is colliding but the shapes are?

what if no vertex is colliding but the shapes are?


??? Every sprite has a collision box which is a rectangle, vertices that I am mentioning are the vertices of those rectangles, they define the area that the sprite occupies. I only have to check is some vertex of sprite Alice is inside the area of sprite Bob. I don't have complex shapes, just rectangles, but I don't know how to respond correctly. I just need an idea, concept how this is done properly on rectangle shapes.

A---B
|[color="#FFFFFF"]-----|
D---C

??? Every sprite has a collision box which is a rectangle, vertices that I am mentioning are the vertices of those rectangles, they define the area that the sprite occupies. I only have to check is some vertex of sprite Alice is inside the area of sprite Bob.

Two rectangles can intersect without any vertex of either being inside the other. This may not have any practical bearing in your case, but it's something to be aware of.

In any case, vertex-containment tests are rarely if ever the optimal solution for this sort of thing (for axis-aligned rectangles, the separating axis test is generally preferred).

Two rectangles can intersect without any vertex of either being inside the other.


Yes, I am aware of that, but this is not an issue in my game.

Collision detection is not the problem, it is what to do after it happens specifically between a moving player and a still platform. I need to prevent him to going inside the platform form left or right, he needs to land on it if he comes above, fall down if he hits it from below, etc.

I have written my method which I know is not very good, I am not trying to fix it here, I need a new concept.

[quote name='jyk' timestamp='1306803708' post='4817716']
Two rectangles can intersect without any vertex of either being inside the other.


Yes, I am aware of that, but this is not an issue in my game.

Collision detection is not the problem, it is what to do after it happens specifically between a moving player and a still platform. I need to prevent him to going inside the platform form left or right, he needs to land on it if he comes above, fall down if he hits it from below, etc.

I have written my method which I know is not very good, I am not trying to fix it here, I need a new concept.
[/quote]


// change the position of the sprite.
mario.y += speed.y;

if(collided && speed.y > 0) // then we know he was falling, so put him on top of the block.
mario.y = block.y - mario.height; // or subtract one more to be sure
// this way mario will be on top of the block after colliding, and not inside


oh god I made so many mistakes the first time, I edited this, I hope nobody read it :o

I'm not completely sure if this is what you want, and "collided" should be substituted with something obviously, this is just pseudocode.
But I hope it helps.
@stromchin: It is not that easy ;)

What if we detect a collision like this (see picture) and sprite has x>0 and y>0 velocity, how do you determine will it land on the platform or will it hit the platform from the left and slide down? The same problem is with all other vertices and x and y velocities.

My code can handle this in most cases and it moves the player away of the platform or puts him on top of it , but it doesn't work always, so I am looking for new solutions. I have read the SAT article but it didn't help, it didn't help.
unledjiv.png
that's why you do y first, and then x.
if it's falling down, and collided, do what I posted before
then (no else or anything, just another check)
if it's moving right, check for collision. if there is still a collision (you already changed y) and it was moving right, then x = block.x - mario.width;

in a case like yours, in my game I gave priority to y. because if you give priority to x he's probably going to fall most of the times.

I don't know in which cases it wouldn't work like this... unless the fall was just too fast.

Now, if you want to really be picky about which side it entered from, you're going to need heavier math.
in the link from before
http://www.metanetsoftware.com/technique/tutorialA.html
you would have to get the projection vectors (I think) and compare which one is longer, then move it away in that direction.

If this doesn't work then I'm sorry but I can't help you more

Yes, I am aware of that

Got it (my apologies).

I'll say again though that the SAT is more or less the standard solution to this problem, and should be able to give you the information you need to resolve the intersection.

Regarding the problem case shown in your diagram above, one solution is to use a continuous test, which will tell you exactly when and where the two boxes intersect and will remove all ambiguity. Another option is to use a discrete test and just allow there to be a degree of arbitrariness in how the collision is resolved. This will only come into play when the penetration depth is equal in the x and y directions, which is likely to be a rare case anyway. In your image, for example, the SAT would report the red box as colliding with the black box on the left side, which seems like it'd be the desired result.
I will try with "y first then x" method.

I will have to do a bit more reading to understand the SAT method, if you have more links to that subject you are welcome to post them.

@jyk: What do you mean by continuous and discrete test ? Is that connected with SAT ?

This topic is closed to new replies.

Advertisement