Sign in to follow this  
LeeWalker

Basic 2D square collision

Recommended Posts

LeeWalker    107
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:

[CODE]
//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;
}
[/CODE]

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 [url="http://www.youtube.com/watch?v=GoWpasJOd90"]here[/url]

Share this post


Link to post
Share on other sites
jefferytitan    2523
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.

Share this post


Link to post
Share on other sites
LeeWalker    107
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.

Share this post


Link to post
Share on other sites
jefferytitan    2523
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:
[url="http://www.metanetsoftware.com/technique/tutorialA.html"]http://www.metanetsoftware.com/technique/tutorialA.html[/url] (may be much more complex than you need)
[url="http://devmaster.net/forums/topic/8653-2d-collision-detection/"]http://devmaster.net/forums/topic/8653-2d-collision-detection/[/url] (talks about similar issues but with circles)
[url="http://www.gamedev.net/topic/500831-2d-collision-detection-and-response---support-for-fast-moving-objects/"]http://www.gamedev.net/topic/500831-2d-collision-detection-and-response---support-for-fast-moving-objects/[/url] (talks about same problem but without a 100% solution)

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