I have a problem with AABB collision.
I am making a top down rougelike in SFML and my collision algorithm does't quite work properly.
It mostly works, except for when you're against the corner of the block and hold the direction towards the block for a second. For some reason, after about a second, the player is clipped through the block to the adjacent side.
I think the problem is caused when, for example, the x
axis needs to be resolved as the player is approaching the object from the left, but the y
penetration ends up being more than the x
and thus the collision is resolved incorrectly.
This is my collision code:
sf::FloatRect collisionRect;
std::vector<Entity*> activeEntities;
for each (Entity* e in entities)
if (e->otype == Dynamic)
activeEntities.push_back(e);
for each (Entity* dynamicEntity in activeEntities)
{
for each (Entity* target in entities)
{
if (dynamicEntity->sprite.getGlobalBounds().intersects(target->sprite.getGlobalBounds(), collisionRect) && dynamicEntity != target)
{
dynamicEntity->velocity = sf::Vector2f(0, 0);
if (collisionRect.width > collisionRect.height)
{
if (collisionRect.contains(collisionRect.left, dynamicEntity->sprite.getPosition().y))
dynamicEntity->sprite.setPosition(dynamicEntity->sprite.getPosition().x, dynamicEntity->sprite.getPosition().y + collisionRect.height);
else
dynamicEntity->sprite.setPosition(dynamicEntity->sprite.getPosition().x, dynamicEntity->sprite.getPosition().y - collisionRect.height);
}
else if (collisionRect.height > collisionRect.width)
{
if (collisionRect.contains(dynamicEntity->sprite.getPosition().x + dynamicEntity->sprite.getGlobalBounds().width - 1.f, collisionRect.top + 1.f ))
dynamicEntity->sprite.setPosition(dynamicEntity->sprite.getPosition().x - collisionRect.width, dynamicEntity->sprite.getPosition().y);
else
dynamicEntity->sprite.setPosition(dynamicEntity->sprite.getPosition().x + collisionRect.width, dynamicEntity->sprite.getPosition().y);
}
}
}
}
EDIT: I have tried making only one call to getPosition() getSprite() etc., and that only makes it glitchier.
EDIT2: I made a gfy of the problem. Sorry for the low res.