Monday, February 22, 2016

xna - Resolving 2D Collision with Rectangles


For about a week I've been trying to grasp the basics of collision, but I've been driven to the point of wanting to just give up on everything when it comes to collision. I just don't understand it. Here's my code so far:



 public static void ObjectToObjectResponseTopDown(GameObject actor1, GameObject actor2)
{
if (CollisionDetection2D.BoundingRectangle(actor1.Bounds.X, actor1.Bounds.Y, actor1.Bounds.Width, actor1.Bounds.Height,
actor2.Bounds.X, actor2.Bounds.Y, actor2.Bounds.Width, actor2.Bounds.Height)) //Just a Bounding Rectangle Collision Checker
{
if (actor1.Bounds.Top > actor2.Bounds.Bottom) //Hit From Top
{
actor1.y_position += Rectangle.Intersect(actor1.Bounds, actor2.Bounds).Height;
return;
}

if (actor1.Bounds.Bottom > actor2.Bounds.Top) //Hit From Bottom
{
actor1.y_position -= Rectangle.Intersect(actor1.Bounds, actor2.Bounds).Height;
return;
}
if (actor1.Bounds.Left > actor2.Bounds.Right)
{
actor1.x_position += Rectangle.Intersect(actor1.Bounds, actor2.Bounds).Width;
return;
}

if (actor1.Bounds.Right > actor2.Bounds.Left)
{
actor1.x_position -= Rectangle.Intersect(actor1.Bounds, actor2.Bounds).Width;
return;

}
}
}

Essentially what it does so far is correctly collides when the bottom of the first rectangle collides with the top of the second rectangle, but with the left an right sides it corrects it either above or below the tile, and when the top of the first rectangle collides with the bottom of the second rectangle, it slides right through the second rectangle.



I'm really not sure what to do at this point.



Answer



Your collision detection code looks like it's working fine, however your collision response appears to be causing the issue. This is evident if you step through how you are actually resolving two colliding bodies.


Let's take a look at the following example (assume the blue rectangle is actor1 and moving left): Colliding bodies


As your code checks the top and bottoms bounds first, these are the first to be resolved and actor1's y position is adjusted like so: enter image description here


The two bodies are now no longer colliding, but the collision wasn't resolved in the best way. This will almost always happen (unless the two rectangles' top and bottom bounds are perfectly in line) and the last two if statements will never be checked.


A primitive way to handle collision response would be to offset the rectangles by the smallest overlap; this would solve the problem in the above example, but you would still find some problems. A better approach would take an object's velocity into consideration, such as the answer found here.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...