我用c ++和sfml构建太空射击游戏。 现在我有一个子弹类,它只是一个带有一些运动逻辑的圆形。我需要一种方法来存储子弹对象,绘制它们,并且一旦它们击中某些东西或超出范围,它们也会取消/删除它们。我将它们添加到列表中,每个项目符号对象都有一个名为alive的bool属性,我根据行进的距离或与其他对象的碰撞不断更新。每当碰撞或超出范围时,我都会将其设置为false。然后我遍历列表以删除其alive属性为false的所有对象。这听起来像是一个可怕的方法,并且在我从列表中删除后,子弹对象甚至会被释放?
到目前为止,这是我的代码:
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());
}
我每次按T都会创建一个新的子弹对象并将其添加到bulletList中,但它实际上并没有将新的子弹添加到列表中,因为bulletList.size()始终打印0。有什么想法我怎么能有效地做到这一点?
答案 0 :(得分:1)
代码中存在一些错误。
您应该为erase()
重新读取list
,它将返回下一个迭代器。
当你没有摧毁子弹时,你也不知道在列表中前进了。
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());
}