Sign in to follow this  

Simple 2D BB vs BB response

Recommended Posts

Hey everyone, I got myself in a nasty problem, which I cannot get fixed properly. While, in fact, it is probably extremely easy. The problem is this: I got a nice collision detection. I simply check if bounding boxes intersect. The player/monster vs. the static geometry. This is all fine. But, the actual collision response is giving me a problem. It's as if I cannot properly find the correct side of the collision, and react properly. I'm on a very tight time schedule, and have no time for implementing new complex collision detection code. All that matters right now is the correct handling of the collision. The player should be able to stay on top of most tiles. The problem is that the player can also stay on "Wall tiles" if he/she lands on a 'bad position'. I have googled a lot,tried newsgroups, this forum, but I cannot find an easy solution to this problem, while in fact it should be rediculously easy? what I have is: BB of object1 BB of object2 Velocity of the player/monster Note that the player can stay on two tiles at one time. Can anyone here offer me some help? Thanks.

Share this post

Link to post
Share on other sites
Is this just for a collision between a character and the geometry (i.e., does the response only apply to one of the colliding objects)? And you don't want a physical 'bounce' response, right, just a 'get me out of the wall' response?

If that is correct, the collision will have occured in the (pre-collision) direction of the moving object's velocity. You can just move the object back in that direction until it no longer collides. If they're AABBs the distance is pretty easy (you find how far the most penetrating corner of one BB is penetrating the other BB). If they're OBBs I think you transform one BB into the space of the other and then do the same thing.

Share this post

Link to post
Share on other sites
A simple method:

How about deflecting the player in the direction of (position of the player) - (position of the monster)?

Also, test for collisions (including walls and other monsters) against the new path. If there is a collision, then move the player in the direction of (position of player) - (position of monster)/2 - (position of 2nd object)/2.

1. Check for collision
2. Determine new path based on (player position) - (average position all colliding objects)

If the player becomes unmovable (surrounded by walls, perhaps), then fix his position and move the monsters.

Share this post

Link to post
Share on other sites
Bob, that's what I tried, unfortunately the problems start to happen when the tile is crossing two tiles at once, and, if the player has a collision with an object, it will always be inside the object by both sides.

So, assuming I have a box of:

128 width, 64 height (all tiles are AABB, never rotated!), the tile being centered on 64,32. Then, if I have the player stand on the top left corner, it would intersect Y, with a value of 1 or so, but the X axis is also colliding, giving avalue of something near -64 or 64, depending which side the player is standing on the tile.

And that's the whole problem all the time, I just need the player to stay on top of the tile, and 'stop' against all others.

Original post by oliii
I'll point you towards a tutorial that seems to do what you need

I tried that an hour ago, but it didn't work for me, the player kept moving back to the top-left or bottom-right corner. My tiles aren't grid based, btw.

Any more suggestions? My best working efforts have been with this:

if (bounds1.xMin > bounds2.xMin)
//Collision object is LEFT of player.
diffx = bounds2.xMax - bounds1.xMin;
left = true;

else //if (bounds1.xMax > bounds2.xMin)
//Collision object is right of player.
diffx = bounds2.xMin - bounds1.xMax;

if (bounds1.yMin > bounds2.yMin)
//Collision object is above of player.
diffy = bounds2.yMax - bounds1.yMin;

istop = [0];
else (bounds1.yMax > bounds2.yMin)
//Collision object is below of player.
//trace("top ");
diffy = bounds2.yMin - bounds1.yMax;

istop = [1];

it's getting a bit messy, but I have a deadline very very soon, and this problem is making me pull my hair out :(.

Share this post

Link to post
Share on other sites
oh ok, I misunderstood the problem...

One way to do it, is to find the MTD, and push the player away from the tile along the MTD.

in simple terms, the MTD is the Minimal Translation Distance.

Say you have a 1 pixel penetration along Y, and a 64 pixel penetration along X. The MTD would be vector (0, 1).

If you had, for example, a collision with a wall on the right side, and -3 pixels along X, and 32 pixels along Y, then the MTD will simply be vector (-3, 0).

to find the MTD, it's simple, with bounding boxes.

Say you have box A defined by corners MinA, MaxA, and B by MinB, MaxB.

float dx1 = MaxA.x - MinB.x;
float dx2 = MaxB.x - MinA.x;
if(dx1 < 0 || dx2 < 0) return false;
float dx = -dx1;
if (dx1 < dx2) dx = dx2;

float dy1 = MaxA.y - MinB.y;
float dy2 = MaxB.y - MinA.y;
if(dy1 < 0 || dy2 < 0) return false;
float dy = -dy1;
if (dy1 < dy2) dy = dy2;

if(fabs(dx) < fabs(dy)) dy = 0.0f; else dx = 0.0f;

Vector MTD(dx, dy);
MinA += MTD * 0.5f;
MaxA += MTD * 0.5f;
MinB -= MTD * 0.5f;
MaxB -= MTD * 0.5f;

Note that, it will not slide nicely. You will 'bump' into things when you slide along a bunch of tiles.

But that can be bodged, using 'step up' code, and things like that.

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