Search code examples
c++listsdlcollision-detection

Weird behaviour in my collision Detection


I'm trying to detect a collision between multiple Objects. But my list iteration seems to work wrong and I can't figure out why. It has to be a simple problem.

I got a "Collision Manager" which have a method "checkCollision"

The Collision Manager got a pointer of the GameObject Manager, which has a list with every collideable Object.

I feel like im doing something wrong with my list Iteration.

Maybe you are able to see my problem?

void collisionManager::checkCollision()
{
    this->aIT = this->goManager->GBList.begin();
    this->bIT = this->goManager->GBList.begin();

    SDL_Rect * result = new SDL_Rect();

    while (this->aIT != this->goManager->GBList.end())
    {
        GameObject * a = *this->aIT;

        while (this->bIT != this->goManager->GBList.end())
        {
            GameObject * b = *this->bIT;

            if (a != b)
            {               
                SDL_Rect * result = new SDL_Rect();
                if (SDL_IntersectRect(a->collider->collisionBox, b->collider->collisionBox, result))
                {
                    a->onCollide(b);
                    b->onCollide(a);
                }
                else {

                }
            }
            else
            {
                a->onCollide(b);
            }

            this->bIT++;
        }
        this->aIT++;
    }

Solution

  • Your problem comes from the fact that the iterator bIt never gets reset when the outer loop (the one with aIt) is iterated. Let's decompose your code in steps :

    • you initialize the iterators to the beginning of the list before the two nested loops.
    • You enter the outer loop (the one with aIt) and select a as the first object of the list
    • You enter the inner loop and your iterator bIt goes through the list of all objects.
    • At the end of the inner loop, your iterator bItdoes not get reset to the beginning of the list of game objects and stay at its last value : the end of the list.

    Therefore you never enter the inner loop a second time.

    The solution is to move the line:

    this->bIT = this->goManager->GBList.begin();
    

    inside the outer loop, so after the first while.