Hi everyone,
I have a problem erasing two elements when they collide. I go thru the 2 vectors of sprites and check if they have intersected with each other, if true, then I erase the two elements from the two vectors (bullets & enemies).
My problem is the following: I can erase one, but how can I erase the second one?
That is how the function looks like so far.
void collision()
{
for (auto e = enemies.begin(); e != enemies.end(); e++)
{
for (auto i = bullets.begin(); i != bullets.end(); i++)
{
sf::FloatRect enemiez = e->getGlobalBounds();
sf::FloatRect bulletz = i->getGlobalBounds();
if (bulletz.intersects(enemiez))
{
bullets.erase(i);
//enemies.erase(e); <-- if i uncomment this line i get a "vector iterator not incrementable!" exception.
break;
}
}
}
}
I understand that it is a problem with the size and the index in the vector and erasing won't work in the same iteration of the loop. I tried also to erase the enemies(e) in the outer loop, but no good.
I have no idea how else I can solve this? Should I try a totally different approach or am I on the right track?
Thank you for your help in advance!
PS This is my first project with SFML (newest version of SFML and Visual Studio 2013).
Reading the documentation of vector::erase (http://www.cplusplus.com/reference/vector/vector/erase/) always helps.
Return value: An iterator pointing to the new location of the element that followed the last element erased by the function call.
So in the context of your code...
void collision()
{
for (auto e = enemies.begin(); e != enemies.end(); /* don't increment here */ )
{
bool collides = false;
for (auto i = bullets.begin(); i != bullets.end(); i++)
{
sf::FloatRect enemiez = e->getGlobalBounds();
sf::FloatRect bulletz = i->getGlobalBounds();
if (bulletz.intersects(enemiez))
{
bullets.erase(i);
// assign the return value and set the flag that a collision happened
e = enemies.erase(e);
collides = true;
break;
}
}
// only increment if no collision happened
if (!collides)
e++;
}
}
Notice how I assigned your iterator to the return value of erase()? This is because once you erase an element your previous iterator is invalidated. Also I added a boolean so if you remove an element you don't increment the iterator and skip the collision check for the next element.