Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to detect collision between two list of bullets and asteroids. The code works fine, but when the bullet intersects with an asteroid, and that bullet passes through another asteroid, the code gives an assertion, and it says about it can't increment the iterator. I'm sure there is a small bug in that code, but I can't find it.

for (list<Bullet>::iterator itr_bullet = ship.m_Bullets.begin();
     itr_bullet!=ship.m_Bullets.end();)
{
    for (list<Asteroid>::iterator itr_astroid = asteroids.begin();
         itr_astroid!=asteroids.end();
         itr_astroid++)
    {
        if(checkCollision(itr_bullet->getCenter(),itr_astroid->getCenter(),
           itr_bullet->getRadius(), itr_astroid->getRadius()))
        {
            itr_astroid = asteroids.erase(itr_astroid);
        }
    }
    itr_bullet++;
}
share|improve this question
    
There are lots of collision detection questions on the site. Did you really not find what you were looking for with those? –  Byte56 Sep 1 '12 at 1:35
    
I did, but it seems I have a problem with iterating through the list and erasing an item from it –  Ahmed Saleh Sep 1 '12 at 1:36
add comment

1 Answer 1

up vote 1 down vote accepted

The problem is that you're removing an asteroid from the list, and then incrementing the iterator without first checking whether you're already at the end of the list.

The usual approach, when iterating over a container, is to remove the 'increment' step from the for clause, and instead to either do the erase (which implicitly does a safe increment), or else increment inside the code inside the for loop:

for (list<Asteroid>::iterator itr_astroid = asteroids.begin(); itr_astroid!=asteroids.end();)
{
    if(checkCollision(itr_bullet->getCenter(),itr_astroid->getCenter(), itr_bullet->getRadius(), itr_astroid->getRadius()))
    {
        itr_astroid = asteroids.erase(itr_astroid);
    }
    else
    {
        itr_asteroid++;
    }
}
share|improve this answer
    
I want to remove the bullet also when the collision occurs, so that it can't pass through other asteroids –  Ahmed Saleh Sep 1 '12 at 1:28
    
Then I'd do something similar to what you're already doing; when checkCollision() returns true, you want to set a "this bullet hit something" variable, and then break out of the for loop which is iterating over asteroids. Then you check to see whether the "this bullet hit something" variable is set, and if so, erase the bullet. If not, iterate the bullet iterator, as you are already doing in your code. –  Trevor Powell Sep 1 '12 at 1:35
    
Thanks!. As you are a professional game programmer, What do you suggest more for reading to not fall in those simple situations again ? –  Ahmed Saleh Sep 1 '12 at 1:41
    
There's really no simple thing I can point you to, to eliminate these sorts of issues.. it's really just experience, and learning to read man pages (and STL documentation, in this instance) when something goes wrong. And Google sometimes helps a lot, too. :) –  Trevor Powell Sep 7 '12 at 11:17
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.