SFML奇怪的射击错误
SFML weird shooting bug
我正在用C++和SFML制作游戏。我有一个奇怪的错误,每当屏幕上正好有 1 个敌人和 3 个射击并且子弹与敌人相撞时,游戏就会崩溃。我得到的错误是:
Expression: vector subscript out of range
这是我检查射击和敌人之间碰撞的方式:
for (int i = 0; i < enemies.size(); i++)
{
for (int s = 0; s < shots.size(); s++) {
if (Collision::PixelPerfectTest(enemies[i].getSprite(), shots[s].getSprite())) {
enemies[i].setHealth(enemies[i].getHealth() - player.getDamage());
if (enemies[i].getHealth() <= 0) {
enemies.erase(enemies.begin() + i);
}
shots.erase(shots.begin() + s);
}
}
}
">敌人"和"射击"是我在主循环中每 x 秒插入一次的向量。这是代码:
if (enemySpawner.getElapsedTime().asSeconds() >= 1.5f) {
enemies.push_back(Enemy(spriteManager.enemySprite));
std::cout << enemies.size() << " enemies" << std::endl;
enemySpawner.restart();
}
if (shotSpawner.getElapsedTime().asSeconds() >= 0.3f && sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
shots.push_back(Shot(spriteManager.shotSprite, player.getPosition(), *window));
std::cout << shots.size() << " shots" << std::endl;
shotSpawner.restart();
}
正如我所说,这只发生在我有 1 个敌人和 3 个射击时才会发生,否则它似乎工作正常。
编辑:现在,当第一个敌人生成时,游戏会冻结。以下是更新的代码:
//Shot vs enemy
for (auto eit = enemies.begin(); eit != enemies.end();)
{
for (auto sit = shots.begin(); sit != shots.end();) {
if (Collision::PixelPerfectTest((*eit).getSprite(), (*sit).getSprite())) {
(*eit).setHealth((*eit).getHealth() - player.getDamage());
if ((*eit).getHealth() <= 0) {
enemies.erase(eit);
shots.erase(sit);
}
shots.erase(sit);
eit = eit++;
sit = sit++;
}
}
}
@moka的回答解释了你的代码的核心问题,他/她的代码使用迭代器将解决你的问题。 但是,还有另一种方法可以解决此问题:将代码拆分为"计算传递"和"数组修改传递"。 代码如下所示:
for (int i = 0; i < enemies.size(); i++)
{
for (int s = 0; s < shots.size(); s++) {
if (!enemies[i].alive || !shots[s].active) {
continue;
}
if (Collision::PixelPerfectTest(enemies[i].sprite(), shots[s].sprite())) {
shots[s].active = false;
enemies[i].setHealth(enemies[i].getHealth() - player.getDamage());
if (enemies[i].getHealth() <= 0) {
enemies[i].alive = false;
}
}
}
}
enemies.erase(std::remove_if(enemies.begin(), enemies.end(),
[](Enemy const &e) { return !e.alive; }), enemies.end());
shots.erase(std::remove_if(shots.begin(), shots.end(),
[](Shot const &s) { return !s.active; }), shots.end());
这种风格也很好,因为它将游戏逻辑与实现分开了一点。 例如,如果你想让一个射击伤害多个敌人,无论如何你都必须对射击阵列使用这样的方法。
优秀的《游戏编程模式》一书中关于双缓冲的章节进行了更深入的介绍。
你不能
只是从向量中删除东西,同时按照你正在做的方式迭代它们,因为它会产生不再在向量范围内的 i 值(在它的大小被调用减小后擦除(,这基本上会导致尝试索引一个不再存在的数组值。如果需要该行为,最好使用迭代器:
auto eit = enemies.begin();
for (; eit != enemies.end(); )
{
if((*eit).isDead())
{
eit = enemies.erase(eit);
}
else
{
eit++;
}
}
您将对镜头阵列执行相同的操作。
相关文章:
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 在某些循环内使用vector.push_back时出现分段错误
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- SFML奇怪的射击错误