Basic 2D square collision

Started by
2 comments, last by jefferytitan 11 years, 12 months ago
I've developed my game to a point where I'm now starting to notice that my current approach to box collisions is wrong.

The code is as follows:


//if the block's origin is within 32px of the actor
if(collision[r][c]->GetPosition().x >= (a.x + av.x) - 32 &&
collision[r][c]->GetPosition().x <= (a.x + av.x) + 32 &&
collision[r][c]->GetPosition().y >= (a.y + av.y) - 32 &&
collision[r][c]->GetPosition().y <= (a.y + av.y) + 32)
{

MyRect b = collision[r][c]->GetPosition();

//Actor collision left
if(a.left() + av.x < b.right() &&
a.right() > b.left() &&
(a.top() < b.bottom() &&
a.bottom() > b.top()) &&
av.x < 0)
{
MyRect newVel = av;
newVel.x = 0;
act->SetVelocity(&newVel);
MyRect newPos = a;
newPos.x = (b.x + b.w);
act->Move(&newPos);
}
//Actor collision right
if(a.right() + av.x > b.left() &&
a.left() < b.right() &&
(a.top() < b.bottom() &&
a.bottom() > b.top()) &&
av.x > 0)
{
MyRect newVel = av;
newVel.x = av.x - av.x;
act->SetVelocity(&newVel);
MyRect newPos = a;
newPos.x = (b.x - a.w);
act->Move(&newPos);
}
//Actor collision Top
if(a.top() + av.y < b.bottom() &&
a.bottom() > b.top() &&
a.left() < b.right() &&
a.right() > b.left() &&
av.y < 0)
{
act->jumping = false;
MyRect newVel = av;
newVel.y = 1;//-(av.y < 0 ? av.y/2 : -1);
act->SetVelocity(&newVel);
MyRect newPos = a;
newPos.y = (b.y + b.h);
act->Move(&newPos);
}
//Actor collision Bottom
if(a.bottom() + av.y > b.top() &&
a.top() + av.y < b.bottom() &&
a.left() < b.right() &&
a.right() > b.left() &&
av.y > 0)
{
MyRect newVel = av;
newVel.y = 0;
act->SetVelocity(&newVel);
MyRect newPos = a;
newPos.y = (b.y - a.h);
act->Move(&newPos);
groundCollided = true;
act->jumping = false;
}
}


if(!groundCollided)
{
act->isOnGround = false;
}
else {
act->isOnGround = true;
}


Where a = the actor's current rectangle
Where av = the actor's velocity
Where b = the collision tile's rectangle

What happens currently is that the actors warp inside walls when moving into corners, which causes them to accelerate very fast until the character is out of the wall. Which often leads to the character is off the screen and then killed.

I've tried several different things but I'm not entirely sure how to fix it, any help would be greatly appreciated!

A video of the problem can be found here
Follow me on twitter! @lwalkeruk
Watch me on youtube! LeeWalkerGM
Advertisement
Don't have time to read the code, but my bet is that if your objects somehow do intersect (e.g. object A is travelling very fast, in one frame goes from being wholly outside object B to wholly inside object B) then the collision code ejects it in the wrong direction. The direction of movement needs to be taken into account, and ideally the area swept by the object during movement rather than a moment in time position.
Thanks! As it's my first real attempt at collision, would you be able to point me in the direction of any code to get me started off? Even Pseudo code would be fine.
Follow me on twitter! @lwalkeruk
Watch me on youtube! LeeWalkerGM
Once again, not an expert. Off the top of my head, to fix the fast moving object problem (assuming your boxes are always axis-aligned) I might try the following:

1. Consider X and Y axes separately.
2. Find what period of time during the timestep there is an overlap of X coordinates, e.g. based on X positions, widths and X component of velocity.
3. Do the same for Y coordinates.
4. If there is an overlap in these time periods for X and Y, then there is a collision, e.g. their X coordinates and Y coordinates overlap at the same time.
5. The earliest common moment of these time periods is the collision time, from which you can determine the collision location.

If I'm right steps 2 and 3 can be done with simple algebra, so results will be exact and relatively fast.

If that doesn't help, here are a few links I found that address similar problems:
http://www.metanetsoftware.com/technique/tutorialA.html (may be much more complex than you need)
http://devmaster.net/forums/topic/8653-2d-collision-detection/ (talks about similar issues but with circles)
http://www.gamedev.net/topic/500831-2d-collision-detection-and-response---support-for-fast-moving-objects/ (talks about same problem but without a 100% solution)

This topic is closed to new replies.

Advertisement