Skip to main content
GameDev.net gamedev.net
🔒 Locked

Handling collisions

Started by Svenjamin Dec 14, 2005 at 4:09 PM 9 replies 1k views
Original Post
Svenjamin
Svenjamin
Hey everybody I am working on a bomberman clone and I am almost finished. One thing I having trouble with though is handling collisions between the blocks and players. right now I have it so that if you try to walk through an indestructible block, you slide to a side to get you around it, (which is what I want because otherwise its hard to move around the blocks) and if you try to move through a destructible block, I want it just to keep you where you are and not slide you anywhere. so my problem is, when I try to move through a destructible block, it still slides me to a side, and ends up pushing me through other blocks, and I end up 20 blocks away from where I was. I cant figure out how to make the player just stay where he is! I know this is probably fixed using some really basic technique and I just havent thought about it enough or should have learned it a while ago, but I havent done too many games where collsion handling like this was a big issue. anyways, Any help is greatly appreciated!
haphazardlynamed
haphazardlynamed
Quote:
Original post by Svenjamin
so my problem is, when I try to move through a destructible block, it still slides me to a side, and ends up pushing me through other blocks, and I end up 20 blocks away from where I was.

Hmmmh
If the problem is, that when you run into a block it pushes the player to one side and through other blocks.
Then maybe the best solution is to Not push the player to one side if you are about to push him through other blocks.
Yeah, then you won't end up pushing him through other blocks.

Quote:
Original post by Svenjamin
I cant figure out how to make the player just stay where he is!

Maybe when the player is about to run into a block, instead of having him move. You could have him stay where he is (ie: don't move him). That should result in him just staying where he is.

[Edited by - haphazardlynamed on December 14, 2005 5:13:54 PM]
Svenjamin
Svenjamin
Thanks for the prompt reply.

I should have stated this before, but I understand that the problem is that the player is being told to move to the side, and I am trying to figure out how to code the collsion handling so that that doesn't happen.
Here is my pseudocode:

if (player collides with block)
{
if (player X > block X)
player X += 1;
if (player Y > block Y)
player Y += 1;
if (player X < block X)
player X -= 1;
if (player Y < block Y)
player Y -= 1;
}

so that is how Im handling the collisions right now. Im sure that there is a million different ways to handle collsions and they are all better than this one, so please help!

by the way, Im not a beginning programmer, I just stink when it comes to collision handling, so don't hesitate to tell me about a method you think might be to complicated.
Thanks.
Zakwayda
Zakwayda
With axis-aligned boxes (that aren't moving too fast), you can get excellent results with a simple application of the separating axis theorem. The characters will stop or slide naturally depending on the angle of their motion relative to the obstacle, which I gather is what you want. The implementation is really only a few lines of code; I remember typing it up for a post a couple of months ago, but I wouldn't know how to find it now. If you need further help, I can explain the algorithm, or maybe just write out the code again.
Svenjamin
Svenjamin
Thanks for your reply, I checked out the Separating Axis Theorem stuff, and it seemed a little too complicated for my purposes.

All that is happening in my game, is the player walks straight into a block, and then depending on which side of the block they are on, they are moved away from the block, but for some reason, there is a problem with my collision handling code (see above for pseudocode) that causes the player to also slide parallel to the side of the block it hit, and then when it slides, it is pushed through other blocks. If you (jyk) could show me how to apply the Separating axis theorem to this, it would be greatly appreciated. Ask if you have any questions about this problem, Im not sure that the way I explain it makes sense.

Oh yeah, to haphazardlynamed, how can I check if the player is about to run into a block?

Thanks

Zakwayda
Zakwayda
Quote:
Original post by Svenjamin
I checked out the Separating Axis Theorem stuff, and it seemed a little too complicated for my purposes.
It's not. It's just like a lot of algorithms: when you present it in its most general form it seems complex, but when applied to certain very restricted problem domains, it simplifies drastically. The SAT can be just about as complicated or as simple as you need. Robust, fast swept intersections between arbitrary convex polyhedra in 3d with contact points and normals: complicated. Static collision detection and resolution for axis-aligned boxes in 2d (which is what you want): super-easy.

I'll try to sketch out some code for you and post it later today...
Zakwayda
Zakwayda
Here, you might give this a try:

// This function takes two 2d axis-aligned boxes in min-max form, and returns// a boolean result indicating whether they are intersecting. If they are,// the vector 'resolve' is set so that adding it to the position of the first// of the two boxes will resolve the intersection. This is based on the// assumption that the first box is a character (or other moving object) and// the second is an imobile obstacle. (You can also treat both objects as// moving by moving each by half of the resolve vector in opposite// directions.)// Note that this test is for relatively slow-moving objects that won't pass// through each other or intersect too deeply in one timestep. For most// types of game characters, this is a reasonable assumption; otherwise, a// more complicated swept test may be required.bool IntersectBoxes(    Vector2  min0,    Vector2  max0,    Vector2  min1,    Vector2  max1,    Vector2& resolve){    float diff,minDiff;    int axis,side;        // Left    diff = max0[0]-min1[0];    if (diff < 0.0f) {        return false;    }    minDiff = diff;    axis = 0;    side = -1;        // Right    diff = max1[0]-min0[0];    if (diff < 0.0f) {        return false;    }    if (diff < minDiff) {        minDiff = diff;        side = 1;    }        // Down    diff = max0[1]-min1[1];    if (diff < 0.0f) {        return false;    }    if (diff < minDiff) {        minDiff = diff;        axis = 1;        side = -1;    }        // Up    diff = max1[1]-min0[1];    if (diff < 0.0f) {        return false;    }    if (diff < minDiff) {        minDiff = diff; // [Edit: This line was missing]        axis = 1;        side = 1;    }        // Intersection occurred    resolve.Zero(); // Zero() just sets all components to 0    resolve[axis] = (float)side*minDiff;    return true;}

That's untested, so there's no guarantee it's correct. Let me know though if you try it and it does work for you.

[Edit: Someone found this post while searching the archives, and alerted me to an error in the example code. I've corrected the error, so the code should work correctly now.]

[Edited by - jyk on March 12, 2007 2:08:00 PM]
haphazardlynamed
haphazardlynamed
Quote:
Original post by Svenjamin
Oh yeah, to haphazardlynamed, how can I check if the player is about to run into a block?


Look into the future.

Use whatever you were doing for your collision detection, but check the Future player location before you let him move there.
Svenjamin
Svenjamin
Thanks a lot to both of you (jyk and haphazardlynamed) I'll try the IntersectBoxes Function and see if that works and tell you later.
Svenjamin
Svenjamin
I tried the IntersectBoxes function and that did not work, I may have done something wrong though. thanks anyways.
I ended up testing for a collision one pixel ahead of the players current direction, and if there was a collision, dont let them move. this works very well and I haven't found any bugs with it yet.

Many thanks to jyk and haphazardlynamed.
Zakwayda
Zakwayda
Sorry the function didn't work for you. There could be a mistake in it (I didn't test it - I just typed it into the post - but it does look right), or you might have been using it incorrectly. But since your pixel method works, it sounds like you're good to go.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.