Hello I am trying to handle some simple box collision (axis-aligned) in my top-down 2d game, but running into a problem.
My game is running at a fixed time step, and checks for player-wall collision on each iteration. It retrieves some collision data (if it collided & what side of the bounding box) and adds some offset (dir) to the players position depending on the overlap amount.
// Check player with walls
CollisionData col = testBoxCollision(m_player->getCollider(), wall.getCollider());
if (col.isCollided){
Vec2f dir(0.0f, 0.0f);
if (col.left)
dir.x -= (m_player->getCollider().getPosition().x + m_player->getCollider().getHalfSize().x) - (wall.getPosition().x - wall.getHalfSize().x);
else if (col.right)
dir.x += (wall.getPosition().x + wall.getHalfSize().x) - (m_player->getCollider().getPosition().x - m_player->getCollider().getHalfSize().x);
if (col.top)
dir.y -= (m_player->getCollider().getPosition().y + m_player->getCollider().getHalfSize().y) - (wall.getPosition().y - wall.getHalfSize().y);
else if (col.bottom)
dir.y += (wall.getPosition().y + wall.getHalfSize().y) - (m_player->getCollider().getPosition().y - m_player->getCollider().getHalfSize().y);
m_player->GameObject::setPosition(m_player->GameObject::getPosition() + dir);
}
The testBoxCollision function:
CollisionData testBoxCollision(const Collider& a, const Collider& b)
{ CollisionData c{ false, false, false, false, false };
float w = a.getHalfSize().x + b.getHalfSize().x;
float h = a.getHalfSize().y + b.getHalfSize().y;
float dx = a.getPosition().x - b.getPosition().x;
float dy = a.getPosition().y - b.getPosition().y;
if (abs(dx) <= w && abs(dy) <= h)
{
c.isCollided = true;
float wy = w * dy;
float hx = h * dx;
if (wy > hx)
{
if (wy > -hx)
c.bottom = true;
else
c.left = true;
}
else
{
if (wy > -hx)
c.right = true;
else
c.top = true;
}
}
return c;
}
The Problem
When two walls produce a corner, and I push my player up to the corner, the player goes through the wall. Not Ideal!
Clearly I've overlooked something and another set of eyes would be very helpful. Thanks.
Below is a snapshot of what's happening.
EDIT: I'm led to believe this is a math error, because it only happens on some corners at a consistent frame rate.