Sign in to follow this  
Hanksha

2D Collision Reponses

Recommended Posts

Hanksha    575

Hi,

I understand without problem when 2 rectangles are colliding, (I'm talking here of a really basic collision system, with one static object and one dynamic) my problem is more about what do we do once we know there is collision.

I know basically that we cancel a part of the movement to bring the dynamic object the closest to the static object.

Here is an image to illustrate my question:

collis10.png

How do we know if we should bounce the dynamic object vertically or horizontally to correct the movement (e.g Falling on a platform, running the feet against a small wall)

I've been able to do algorithm that worked but they were to specific to special case and velocity.

I've read that we can check what is the shortest way to move the dynamic object out of collision, but what if we have a very small vertically velocity and a high horizontal velocity.... 

I hope I made the explanation of my problem clear.

Share this post


Link to post
Share on other sites
BeerNutts    4400

There are different ways to solve this, but my suggestion is to use the simplest method.

 

Move your object on a single axis 1st, then check for collision (for example, y-axis 1st).  If collision, then you know it happened because of vertical movement, and you can perform your response using only the y-axis (either it stops, or it bounces if it has elasticity).

 

Then you move the object in the x-axis and check for collisions and do the same.

 

This handles many general problems in platform games, like a player jumping and hitting a wall.  You don't want your player to stop moving up and down when it hits a wall, but only stop moving on the x-axis.

 

Good luck and have fun!

Share this post


Link to post
Share on other sites
Horscht    270

The problem with that approach is that it doesn't really take into account on which axis the collision happened first, meaning the player can be pushed out of a platform sideways instead of landing on top, depending if you check the X or Y axis first.

You probably won't notice it most of the time, except when you move diagonally onto a corner.

A way to fix this is to calculate the overlap first, then divide that by the objects velocity to find out which axis collided first, and then push it out in that direction.

float timeOfImpactX = std::numeric_limits<float>::infinity();
float timeOfImpactY = std::numeric_limits<float>::infinity();

if(dynamicBody.velocity.x != 0.0f) timeOfImpactX = GetRECTOverlapX(staticBodyRect, dynamicBodyRect) / dynamicBody.velocity.x;
if(dynamicBody.velocity.y != 0.0f) timeOfImpactY = GetRECTOverlapY(staticBodyRect, dynamicBodyRect) / dynamicBody.velocity.y;
if(timeOfImpactX < timeOfImpactY)
{
    // Solve X first
}
else
{
    // Solve Y
}

Something like that. I'm not sure myself if this is the best way but it's something to think about when your collision resolution feels weird when trying to land on the edge of a platform/tile.

 

Share this post


Link to post
Share on other sites
flyslasher    311

This is just a thought, but it should do what you need to do if the math in my mind isn't hazed over from last night.

Using vectors you can calculate the distance from object 1 to object 2 and subtract the two distances from the origins of the objects to their respective edges. If it's less than 0, it means you are colliding and then use the overlapping vector components to calculate where you need to push the object away.

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