1

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)

image

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;
        }
    }
}
HalloweenJack
  • 281
  • 2
  • 15
  • 2
    Not related to the issue, but `GetComponent::DoCollision()` is calling `Collider->DoCollision()` multiple times with the same input objects. You should call it only one time, and cache the result into a local variable to use as needed, eg: `CollisionData cd = Collider->DoCollision(*object1, *object2); ... std::get<2>(cd) ... std::get<0>(cd) ... std::get<1>(cd) ...` And your `if` statements can be simplified a bit: `if (std::get<0>(cd)) { if (object2->Solid) { ... return SOLID; } else { return TRIGGER; } } else { return NO_COLLISION; } }` – Remy Lebeau Sep 27 '18 at 01:29
  • Your animation makes it look as though it's bouncing (as it should), but the new location is also a collision, so it bounces back. Also, this is *way* more complicated than AABB collision code needs to be. – 3Dave Sep 27 '18 at 01:29
  • @3Dave Actually this is just as simplified as I can do, cause I need to know where the object is colliding, so I can push him into the oposite direction. Any idea how could I make it better? – HalloweenJack Sep 27 '18 at 02:34

2 Answers2

1

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.

Jeffrey
  • 11,063
  • 1
  • 21
  • 42
  • You are right, what is happening is that it's only resolving collision on one axis and leaves the other collision still present. Updated the question, if you could help me to determine when to use each collision I would really appreciate it, thanks. – HalloweenJack Sep 28 '18 at 03:46
1

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/

Fooble
  • 485
  • 2
  • 14
  • Thanks, got inspired and Updated / Simplified the code, but now I'm on a major dilema, when to use Vertical or Horizontal detection functions? (Post Updated) – HalloweenJack Sep 28 '18 at 03:23
  • There is a section called "Type #2: Tile Based (Smooth)" which looks like it would apply to your game. Under that there is a sub section "How it works" which gives a description of the steps you should go through along each axis. It says you should treat each axis independently and the order you process them doesn't matter unless you are adding sloped surfaces, in which case process the X axis first. – Fooble Sep 28 '18 at 03:27
  • actually I was trying to implement that, but not quite understood it without any pseudocode... – HalloweenJack Sep 28 '18 at 03:29