C++ Delete An Enemy from a Vector

Started by
11 comments, last by Alberth 3 years ago

Hi i wrote this code for creating multiple enemies from enemy class

int number = 10;

std::vector<std::unique_ptr<enemy> > enemies1;

for (unsigned i = 0; i < number; ++i) {
    enemies1.emplace_back(std::unique_ptr<enemy>(new enemy(sf::Vector2f(100 * i + 1500, 1000), sf::Vector2f(15, 10), sf::Color(255, 255, 255, 0))));
}
    //update
    for (unsigned i = 0; i < number; ++i) {
            enemies1[i]->update();
        }
    //render
    for (unsigned i = 0; i < number; ++i) {
            window.draw(enemies1[i]->enemysprite);
        }

everything is ok. Multiple Sprites are drawing on screen and moving and such. But my problem is i cant erase a single enemy from enemies1 vector. I learnt this code from a site and there is a sample code like this:

if (!items1.empty())

enemies1.erase(std::remove_if(items1.begin(), enemies1.end(), [sprite](const std::unique_ptr <enemy> &e) { return e->rect.getGlobalBounds().intersects(sprite.getGlobalBounds()); }), enemies1.end());

but it doesnt work and program is stopping to work. Basically i tried this code for another array like this:

std::vector<int> vect_array(10);

std::vector<int>::iterator it = vect_array.begin() + 2;-

vect_array.insert(it, 66);//add

vect_array.push_back(21);

vect_array.erase(std::remove(vect_array.begin(), vect_array.end(), 5), vect_array.end());

and it works.

My question is what's wrong on top code? it works with numbers but i want to do same things with another array for spawn and delete sprites.

I appreciate for every advice.

Advertisement
enemies1.erase(std::remove_if(items1.begin(), enemies1.end(), [sprite](const std::unique_ptr <enemy> &e) { return e->rect.getGlobalBounds().intersects(sprite.getGlobalBounds()); }), enemies1.end());

If thats the actual code, then you need to pass “enemies1.begin()” to remove_if, instead of “Item1.begin()". But since you didn't tell us what “doesn't work” exactly, thats my only guess (since this code should probably not even compile.

Mismatched iterators, as Juliean noticed, are a great way to stomp beyond the end of the vector (you won't reach enemies1.end() from items1.begin()) and there's also the traditional pitfall of deleting the current item of a live iterator, skipping or miscounting items in the following iteration steps.

Assuming your code compiles, this seems a great opportunity to use a debugger (and to learn how to use it): the problem appears localized to a simple data structure and a few lines of code, so it shouldn't be too difficult to see pointers and indices go wrong.

Omae Wa Mou Shindeiru

Find the index of the enemy you want to delete and then this

enemies1.erase(enemies1.begin() + index);

A (possibly not so) small optimization: if the order of the enemies in the vector does not matter, then instead of removing it using erase() you could replace it with the last element and then call pop_back():

template<typename Vector>
void quick_erase(Vector& vec, size_t index) {
  if(index < vec.size()) {
   vec[index] = vec.back();
   vec.pop_back();
   }
 }

This will avoid moving the entire array after the removed element each time you erase something.

thanks for all answers

i want to delete enemies and i changed some part of code like this
std::vector <enemy*> enemies;

for (unsigned i = 0; i < 5; ++i) {

enemies.push_back(new enemy(sf::Vector2f(100 * i + 800, 500), sf::Vector2f(15, 10), sf::Color(255, 255, 255, 0)));

}

enemies.erase(std::remove_if(enemies.begin(), enemies.end(), [](const auto &itr) {return itr->touch; }), enemies.end());

now it is partly working i mean i can erase enemies 1,2,3,4 but not last value of array, it doesnt erase last enemy.

Try to turn that code into a small, complete, self-contained program that we can run on our own computers to see what the problem is. You might discover the problem in the process of producing such a program. And if you don't, you'll have something to post here that will get you much better answers.

alvaro said:

Try to turn that code into a small, complete, self-contained program that we can run on our own computers to see what the problem is. You might discover the problem in the process of producing such a program. And if you don't, you'll have something to post here that will get you much better answers.

im using this code:

//enemy class

class enemy {

public:

sf::RectangleShape rect;

float bottom, left, right, top;

bool touch = false;

sf::Sprite itemss;

sf::Texture enemyt;

enemy(sf::Vector2f position, sf::Vector2f size, sf::Color color) {

rect.setPosition(position);

rect.setSize(size);

rect.setFillColor(color);

enemyt.loadFromFile("inv/invpouch.png");

enemys.setTexture(enemyt);

}

void kill()

{

std::cout << "Killing Enemy >> " << std::endl;

}

~enemy() {

}

void update() {

bottom = rect.getPosition().y + rect.getSize().y;

left = rect.getPosition().x;

right = rect.getPosition().x + rect.getSize().x;

top = rect.getPosition().y;

if (right > recx && left < recx + 30 && top < recy + 30 && bottom > recy) {

enemys.setColor(sf::Color(255, 255, 255, 155));

}

}

bool collision(enemy e) {

if (right < e.left || left > e.right || top > e.bottom || bottom < e.top) {

return false;

}

return true;

}

};

//create enemies

std::vector <enemy*> enemies1;

for (unsigned i = 0; i < 5; ++i) {

enemies1.push_back(new enemy(sf::Vector2f(100 * i + 800, 500), sf::Vector2f(15, 10), sf::Color(255, 255, 255, 0)));

}

//update

for (unsigned i = 0; i < 5; ++i) {

enemies1[i]->update();

}

if (!enemies1.empty()){

enemies1.erase(std::remove_if(enemies1.begin(), enemies1.end(), [](const auto &itr) {return itr->touch; }), enemies1.end());

}

//render

for (unsigned i = 0; i < 5; ++i) {

window.draw(enemies1[i]->enemys);

}

That's not at all the kind of thing I was talking about. Is the sf:: stuff important for your question? Can you make a tiny program that outputs something to standard out and still exhibits the relevant problem? Can you then post the entire program here so we can reproduce the problem ourselves?

This topic is closed to new replies.

Advertisement