Friday, July 31, 2015

c++ - 2D AABB collision response


I'm making a simple platformer, and I wanted simple collision handling. So I gave all my objects an AABB hitbox and tried to resolve collisions. However, I can't get it to work.


My main character has a 32x32 hitbox and my walls have a 16x16 hitbox. I've used the separating axes solution to resolve the collision, like so (unoptimized):


Vec2 Box::Collides(Box* a_Other)
{
Vec2 sum_extents;
sum_extents.x = (m_Max.x - m_Min.x) + (a_Other->GetMax().x - a_Other->GetMin().x);

sum_extents.y = (m_Max.y - m_Min.y) + (a_Other->GetMax().y - a_Other->GetMin().y);

Vec2 double_center_to_center;
double_center_to_center.x = (a_Other->GetMin().x + a_Other->GetMax().x) - (m_Min.x + m_Max.x);
double_center_to_center.y = (a_Other->GetMin().y + a_Other->GetMax().y) - (m_Min.y + m_Max.y);

bool result = (fabsf(double_center_to_center.x) < sum_extents.x) && (fabsf(double_center_to_center.y) < sum_extents.y);

if (result)
{

return (
Vec2(
((sum_extents).x - (double_center_to_center).x) / 2.f,
((sum_extents).y - (double_center_to_center).y) / 2.f
)
);
}

return (Vec2(0.f, 0.f));
}


My character just falls down onto the floor. I check the object I want to check against every other object and just see which one has the smallest intersection area.


Object* Scene::Collides(Object* a_Test, Vec2& a_Difference)
{
float smallest_area = 10000.f;
Object* closest = NULL;
Vec2 final;

std::vector check;


for (uint32 i = 0; i < s_ObjectTotal; i++)
{
if (a_Test == s_Objects[i]) { continue; }

Vec2 test = a_Test->GetCollision()->Collides(s_Objects[i]->GetCollision());
float area = test.x * test.y;
if (area > 0.f)
{
check.push_back(test);


if (area < smallest_area)
{
smallest_area = area;
final = test;
closest = s_Objects[i];
}
}
}

if (closest)

{
a_Difference = final;
}

return closest;
}

The hitbox for the player is (32, 229.999995)(64, 261.999994) and the hitbox for the floor is (48, 256)(64, 272). So, the resulting movement (to resolve the collision) is (16, 5.9999930). The y is correct, the x is not. As a result, the player character hits the floor, stays above it and slides to the right very fast.


How do I resolve this collision?




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...