Chrine Chrine - 4 months ago 6
C++ Question

Creating a new object upon key press and adding it to a list

I'm building a space shooter game with c++ and sfml.
Right now I have a bullet class which is just a circleshape with some movement logic to it. I need a way to store the bullet objects, draw them, and also undraw/delete them once they hit something or goes out of range. I'm adding them to a list and each bullet object has a bool attribute called alive which I constantly update based on distance traveled or collision with other objects. I set alive to false whenever it collides or goes out of range. I then iterate through the list to remove all objects whose alive attribute is false. This sounds like a horrible method though, and would the bullet objects even be freed after i delete them from the list?

Here is my code so far:

if (Keyboard::isKeyPressed(sf::Keyboard::T)) {
Bullet newBullet(mySub.getSprite().getPosition().x + 64, mySub.getSprite().getPosition().y + 20);
bulletList.push_back(newBullet);
}
list<Bullet>::iterator it = bulletList.begin();
while (it != bulletList.end()) {
if (it->getNoDraw() == true) {
bulletList.erase(it++);
}
else {
it->update();
if (it->getBulletSprite().getPosition().x > mySub.getSprite().getPosition().x + 1200) {
it->setNoDraw();
}
}
}

cout << "list size " << bulletList.size() << endl;
for (list<Bullet>::iterator it = bulletList.begin(); it != bulletList.end(); ++it) {
window.draw(it->getBulletSprite());
}


I'm creating a new bullet object and adding it to the bulletList each time I press T, but it's not actually adding the new bullet to the list since bulletList.size() always prints 0. Any thoughts how I can do this effectively?

Answer

There are some faults in the code. You should reread erase() for list, it returns the next iterator. Also your missing advancing in the list when you do not destroy a bullet.

if (Keyboard::isKeyPressed(sf::Keyboard::T)) {
        Bullet newBullet(mySub.getSprite().getPosition().x + 64,
                         mySub.getSprite().getPosition().y + 20);
        bulletList.push_back(newBullet);
}
list<Bullet>::iterator it = bulletList.begin();
while (it != bulletList.end()) {
    if (it->getNoDraw() == true) {
        it = bulletList.erase(it); // erase already advance it to the next
    } else {
        it->update();
        if (it->getBulletSprite().getPosition().x >
                mySub.getSprite().getPosition().x + 1200) {
            it->setNoDraw();
        }
        it++; // move on to the next position
    }
}

cout << "list size " << bulletList.size() << endl;
for (list<Bullet>::iterator it = bulletList.begin(); 
     it != bulletList.end(); ++it) {
    window.draw(it->getBulletSprite());
}