Hello… So, I’ve been developing a 2D game in SFML 2.0 in C++. I got to
the part where there is a collision between the player laser and the
enemies. Both, the lasers and the enemies are declared as lists. When
the laser hits the enemy, the collision check must be performed and if
there is a collision, the laser and the enemy are erased from the list.
I managed to find what is causing the problem in the collision code, but
I am not able to find a solution for it. Here’s my code.
std::list<sf::Sprite>::iterator enemyit = enemy.begin(), next;
std::list<sf::Sprite>::iterator greenlaserit = greenlaser.begin(), reload;
while(enemyit != enemy.end())
next = enemyit;
while(greenlaserit != greenlaser.end())
reload = greenlaserit;
greenlaserit = reload;
enemyit = next;
Here, there are two while loops and what I am doing is I am using the
inner loop to check for collision and if collision occurs, I am erasing
the enemy iterator. And after doing that, the inner loop will keep
looping until the while condition stops being satisfied. It won’t enter
the outer loop until it finishes that. Problem is, the enemy iterator is
being erased in the inner loop and I am not incrementing it until the
program goes back to the outer loop. How do I do that so that the enemy
iterator is incremented in the inner loop as soon as it is erased. I’ve
tweaked around a lot moving code around inside and outside the loops,
adding new variables, still nothing. Please help me. Thanks.
Please log in or register to post a reply.
You could just use a bool flag to keep track of whether you’ve
incremented the enemy iterator. It would be initialized to false in the
outer loop, then in the inner loop, if you erase an enemy you increment
the iterator and set the flag to true. After the inner loop exits, you
would increment the iterator only if the flag was still set to false.
BTW, you also need to reset greenlaserit to the beginning of the laser
list each time you start the inner loop. Currently it will iterate all
the way through the laser list on the first enemy, then it will skip all
the lasers for each subsequent enemy, as greenlaserit is still at the
end of the list.
OK… Now I get it. I think it’ll work with the boolean flag. Thanks,
One thing though… Should I reset the greenlaserit to the begin of the
laser list? Because, the laser list is of indefinite size. As long as I
keep the shoot key pressed, the laser sprite will be pushed back to the
list to create new lasers. The laser list keeps on expanding as long as
I shoot. Just clear this one thing for me, please. Thank you.
Yes, you should still reset it to the beginning of the laser list,
because you still want to check all existing lasers against all enemies
in case there are multiple collisions in one frame. Like I said, the way
you have it now, only the first enemy will be tested against all lasers,
then no more enemies will be tested in that frame. So you can currently
only kill one enemy per frame.
It may appear to work correctly despite this problem if you don’t have
too many enemies and the lasers don’t move too fast, because if a
collision is missed on one frame it may be detected the next frame, or a
few frames later. But if you have too many enemies or the lasers move
too fast, you will see problems.
OK, OK… Now I understood the problem. I modified the code as you
suggested and it worked perfectly. Thank you very much. :)
By the way, did I tell you…
YOU… ARE… AWESOME… Period! Seriously, is there anything you don’t
know about C++ game programming? I racked my brains on this for weeks.
Couldn’t find a solution with all the source material I have. I wish I
had your innovative thinking and problem solving skills. Thanks a lot,
P. S. : You don’t know this, but you actually saved me from losing 40
marks. Well… Now you know! ;)