# SDL 2D Collision Response

This topic is 5174 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I am writing a 2D game using Ruby and SDL with a couple guys from rubyforums.com and I've become stuck on a particular problem. SDL has built in collision detection (bounding box checks) and it works beautifully. But now I'm trying to have a moving object (controlled by the user) collide with a "solid" object. Problem is I can't figure out a way to have an accurate response, i.e. if the moving object hits the left side of the solid it can't pass through. I don't want the moving object to bounce or else I would just reverse the velocity, I want the moving object to just stop and not be able to move. I hope I have been clear enough as this problem has frustrated me for some time. If you want to take a look at the source I can post a link. Thanks, Steve

##### Share on other sites
If you know your objects are moving a relatively small fraction (<.4 or so) of their dimensions each frame, you can get very nice stopping/sliding collision response using penetration resolution and the separating axis test. If your boxes are oriented, it will take a little work; if they're axis-aligned, it's dead simple.

I don't know if SDL has any built-in support for this, but if not it should be pretty easy to write yourself.

Let me know if you need more details.

##### Share on other sites
Hi,

Thanks for the quick reply. From what I can tell the seperating axis test is used for collision detection, which I do not need, although I can't seem to find a decent tutorial. I'm not exactly sure what you mean by oriented. One box can be rotated 0-360 degrees and moved while the other one is perfectly stationary, i.e. 0 degrees. I can't seem to find any articles on penetration resolution, do you think you could point me to some?

Thanks.

EDIT: I just found a site that showed axis-aligned objects and I think my objects are aligned, is there an easy way to test?

##### Share on other sites
Quote:
 From what I can tell the seperating axis test is used for collision detection, which I do not need...
I assume you're saying you don't need collision detection because SDL provides it? That may be so, but if you want collision information that SDL doesn't provide, you may have to do the collision detection yourself.
Quote:
 I'm not exactly sure what you mean by oriented. One box can be rotated 0-360 degrees and moved while the other one is perfectly stationary, i.e. 0 degrees.
By oriented I mean it can be oriented at any angle. It sounds like you have one oriented box and one axis-aligned box, so the SAT test will be a little more complex than with two axis-aligned boxes. But it's still not too hard.

One question. Could you get by with using a circle rather than an oriented box? If so, all you need is a circle/axis-aligned box test, and you're back to dead simple.

Here is a good article on the SAT. I don't know that it covers your case specifically, but it explains the theory in some detail.

##### Share on other sites
I guess I could get by with a circle, If I make it tight enough players wouldn't notice much difference than if I went with oriented+aligned.

That article you linked to was interesting but it didn't seem to get into the math aspect as much, do you think you could point me to maybe a source code example (I can get the gist of C++, but it would be incredible if there was a Ruby example) as I don't have Flash and can't check out the source code of that demo.

Thank you very much.

##### Share on other sites
Here is another SAT article which may be helpful. And, if you'd like to give circles a try, here's some c++ code for finding the penetration depth and direction between a circle and an axis-aligned box:

// Note: this code has not been tested.// This function will only work reliably if the circle displacement is// small enough that it will not go from not intersecting the AABB,// to its center being on or inside the AABB, in one timestep. For// relatively slow moving objects this should be a safe assumption to// make.bool IntersectCircleAABB(    const Vector2& center, // Circle center    float          radius, // Circle radius    const Vector2& min,    // AABB min bounds    const Vector2& max,    // AABB max bounds    Vector2&       normal, // Direction of least penetration    float&         depth,  // Depth of least penetration{    Vector2 closest;    for (int i = 0; i < 2; ++i)    {        if (center < min)            closest = min;        else if (center > max)            closest = max;        else            closest = center;    }        normal = center - closest;    float length = normal.LengthSquared();    if (length > radius * radius)        return false;        length = sqrtf(length);    normal /= length;    depth = radius - length;    return true;}// If the function returns true, simply update the circle position like this:center += normal * depth;

##### Share on other sites
save old positions;
test collision pr vertices, (user sdl rutine or write your own quadtree thing).
if collision then use old position and set speed to zero;

:: have fun

##### Share on other sites
I got it working, thank you so much guys.

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 11
• 15
• 21
• 26
• 11