I started making a shooter game where enemies appear randomly and you have to shoot them. Everything works fine except sometimes whenever a bullet hits an enemy an error comes up that says "Expression: vector subscript out of range". It doesn't happen every time there is a collision, which confuses me. Here is the collision of the bullets with enemies.
1 2 3 4 5 6 7 8 9 10
for (unsignedint i = 0; i < bullets.size(); i++) {
if (bullets[i].type == 1) {
for (unsignedint j = 0; j < enemies.size(); j++) {
float distance = sqrt(pow(bullets[i].x - enemies[j].x, 2) + pow(bullets[i].y - enemies[j].y, 2));
if (distance < bullets[i].radius + enemies[j].radius) {
bullets.erase(bullets.begin() + i);
enemies.erase(enemies.begin() + j);
}
}
}
You're erasing bullets from the inner for loop. So you're probably iterating through the inner loop erasing bullets without ever updating i. The bullet vector gets smaller and smaller but i stays the same value and eventually you access an element out of range of the vector. If the enemies vector is larger than the bullets vector then you're almost guaranteed to get an access out of bounds error.
I believe the correct way to do this is to use iterators for these vectors and use the return result of erase() to figure out where the next element to check is. In the case where you don't erase something, just do the normal increment.
A quick example showing how to remove the elements in a vector matching some criteria:
1 2 3 4 5 6 7
for(auto i = enemies.begin(); i != enemies.end; /*increment is handled in body*/) {
if(i->some_enemy_method() || some_other_check(*i)) {
i = enemies.erase(i);
} else {
++i;
}
}
This will remove the elements of the vector 'enemies' where 'some_enemy_method()' of the enemy class returns true or some_other_check() that takes an enemy returns true.