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<Vec2> 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?