Jump to content
  • Advertisement
Sign in to follow this  
NWalton

Help with vectors please!!!

This topic is 3499 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys, I just a few days ago started to program my own top-down shooter game. However, while programming the destroying of enemies and bullets on collision with each other I have run into some errors:
Debug assertion failed!
...
Expression: ("this->_Has_container()", 0)
...
I believe this is to do with the code:
	for(std::vector<Player>::iterator i = enemies.begin(); i != enemies.end(); i++) {
		for(std::vector<Particle>::iterator j = bullets.begin(); j < bullets.end(); j++) {
			if((*i).ALIVE() && (*j).ALPHA() > 0.0f) {
				if((*j).X() > (*i).X() -(*i).W()/2 && (*j).X() < (*i).X() + (*i).W()/2
					&& (*j).Y() > (*i).Y() - (*i).H()/2 && (*j).Y() < (*i).Y() + (*i).H()/2) {
						if(enemies.size() > 1) {
							std::swap(*i, *(enemies.rbegin()));
						}
						enemies.pop_back();
						if(bullets.size() > 1) {
							std::swap(*j, *(bullets.rbegin()));
						}
						bullets.pop_back();
				}
			}
		}
	}
Please please help!!! Note: I add new elements to the vectors (enemies) and (bullets) at the beginning, not the end. The idea of that code was to loop through checking for collisions of enemies with bullets, and if they collide, move them to the end of the vector and erase them. The error occurs whenever my bullets hit the enemies.

Share this post


Link to post
Share on other sites
Advertisement
Think what happens when the iterator is pointing to the last element of one of the vectors and you try erasing it. The iterator is now pointing to garbage and then you increment it because of the for loop. At this point you've got bad ju-ju because you've tried incrementing an invalidated iterator.

Also, adding elements to the beginning of a vector is fairly inefficient. vectors work best when you add and remove at the end. If you want to add and remove at both ends use a deque.

Share this post


Link to post
Share on other sites
You are modifying the vectors while iterating over them. This will cause your iterators to be invalidated.

There are a number of ways of getting around this. One is to use integers to index the array, they cannot be invalidated (just be sure not to cache the size of the array, as it will change during iteration). Another is to build a collection of the indices you want to remove, and once you have collision detection finished then remove them.

Or something like this:

#include <algorithm>

struct PlayerBulletCollision
{
PlayerBulletCollision(const Player &player)
:
player(&player) {}

bool operator()(const Particle &particle) const
{
// return true if *player hits particle
}
private:
Player *player;
};

typedef std::vector<Particle> Particles;

struct PlayerBulletsCollision
{
PlayerBulletsCollision(Particles &particles)
:
particle(&particles) {}

bool operator()(const Player &player)
{
Particles::iterator end = particles->end();
Particles::iterator it = std::remove_if(particles->begin(), end, PlayerBulletCollision(player));
bool result = (it != end);
particles->erase(it, end);
return result;
}

private:
Particles *particles;
};

typdef std::vector<Player> Players;
void wherever(Players &players, Particles &particles)
{
Particles::iterator end = players->end();
Particles::iterator it = std::remove_if(players->begin(), end, PlayerBulletsCollision(particles));
players->erase(it, end);
}


That is untested, but I think it might work.

Share this post


Link to post
Share on other sites
Hey guys,

Thanks for the very quick replys!
I fixed my problem!!! As I go through the collisions I just set a flag for the enemies and bullets that were hit to say dead. Then I loop through the vectors swapping the dead elements with the end and using pop_back(), then break the loop. Once the loop removes all of the dead elements it seta a flag saying done and exits the entire loop.

Thanks a lot!

-NWalton

EDIT:

BTW, currently I'm not really worried about efficiency as this is my first 2d game (programming with c++, sdl, opengl), and I'm just experimenting. I even made my own image format!!!

Share this post


Link to post
Share on other sites
I will mention that the "remove_if, erase" solution I showed you is idiomatic C++ for removing objects from a vector, while also being quite efficient.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!