Reputation: 281
Update
Changed the collision code again and made a Component for AABB, now it seems that the problem is only on Horizontal collision, it doesn't push the object enought it think but is the same code as Y axis so it shouldn't be a problem.
(It do detects the horizontal Collision the resolution is the problem)
void Hermes_Player::Collision(GameObject * other)
{
if (other->GetTag() == "wall") {
AABB* myAABB = dynamic_cast<AABB*>(this->GetComponent("aabb"));
AABB* otherAABB = dynamic_cast<AABB*>(other->GetComponent("aabb"));
if (abs(myAABB->lastCenter.x - otherAABB->lastCenter.x) < myAABB->halfCenter.x + otherAABB->halfCenter.x) {
std::cout << "y" << std::endl;
if (myAABB->center.y < otherAABB->center.y) {
int distance = (myAABB->halfCenter.y + otherAABB->halfCenter.y) - (otherAABB->center.y - myAABB->center.y);
this->Position.y -= distance;
myAABB->center.y = (myAABB->center.y - distance);
}
if (myAABB->center.y > otherAABB->center.y) {
int distance = (myAABB->halfCenter.y + otherAABB->halfCenter.y) - (myAABB->center.y - otherAABB->center.y);
this->Position.y += distance;
myAABB->center.y = (myAABB->center.y + distance);
}
}
else
{
std::cout << "x" << std::endl;
int dist = myAABB->halfCenter.x + otherAABB->halfCenter.x;
int dif = (this->Size.x + other->Size.x) /2- abs(dist);
if (myAABB->center.x < otherAABB->center.x) {
int distance = (myAABB->halfCenter.x + otherAABB->halfCenter.x) - (otherAABB->center.x - myAABB->center.x);
this->Position.x -= distance;
myAABB->center.x = (myAABB->center.x - distance);
}
if (myAABB->center.x > otherAABB->center.x) {
int distance = (myAABB->halfCenter.x + otherAABB->halfCenter.x) - (myAABB->center.x - otherAABB->center.x);
this->Position.x += distance;
myAABB->center.x = (myAABB->center.x + distance);
}
std::cout << this->Position.x << std::endl;
}
}
}
Upvotes: 1
Views: 831
Reputation: 485
This might not be what you are looking for but trying to resolve both the X and Y axis at the same time can be rather complicated.
One solution might be to step each axis independently and resolve their collisions separately.
You have to perform collision detection twice but it makes resolution much simpler, IE instead of checking whether the collision resolution results in more collisions you just stop the movement along the edge of the first object collided with.
This is an article which assisted me when I was developing my own 2D platformer and it recommends this practice:
http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/
Upvotes: 1
Reputation: 11430
I didn't debug/read you whole code, but this looks like a classic problem. Once you detect a collision, you resolve it with a single direction and penetration.
What happens is that after a move and a collision, resolving on one axis might leave the other one with a collision still present. And from there, it all breaks down.
Or it might be that you collide with two objects, resolving the second one puts you back into one you already adjusted out of.
At least, after adjusting back the position, you need to check it is all clear, for all objects.
Upvotes: 1