ниже приведен фрагмент кода из игры, которую я пишу на C++ с использованием SFML.
if (Keyboard::isKeyPressed(Keyboard::Space)) {
if (fireClock.getElapsedTime().asMilliseconds() > 150) {
Bullet vecBullet(Vector2f(player->getPosition()), player->angle);
bulletVector.push_back(vecBullet);
sleep(milliseconds(5));
fireClock.restart();
}
}
if (Keyboard::isKeyPressed(Keyboard::A)) {
Enemy vecEnemy;
enemyVector.push_back(vecEnemy);
}
for (int i = 0; i < bulletVector.size(); i++) {
bulletVector[i].fire();
bulletVector[i].draw();
}
for (int i = 0; i < enemyVector.size(); i++) {
enemyVector[i].draw();
}
for (int i = 0; i < bulletVector.size(); i++) {
if (bulletVector[i].getPosition().x > 2000 || bulletVector[i].getPosition().x < -100 ||
bulletVector[i].getPosition().y > 1100 || bulletVector[i].getPosition().y < -100) {
bulletVector.erase(bulletVector.begin() + i);
}
}
for (int y = 0; y < bulletVector.size(); y++) {
for (int x = 0; x < enemyVector.size(); x++) {
if (enemyVector.size() > 0 && bulletVector.size() > 0) {
if (enemyVector[x].checkColl(Bullet(bulletVector[y]))) {
bulletVector.erase(bulletVector.begin() + y);
enemyVector.erase(enemyVector.begin() + x);
}
}
}
}
cout << enemyVector.size() << " " << bulletVector.size() << endl;
Что происходит, так это то, что после выстрела пуля попадает во врага, а иногда падает и выдает следующую ошибку:
program: C:\WINDOWS\SYSTEM32\MSVCP140D.dll File: c:\program files (x86)\microsoft visualstudio\2017\community\vc\tools\msvc\14.13.26128\include\vector Line: 1806
Expression: vector subscript out of range
Любые идеи, которые вы можете мне дать, были бы очень признательны, Спасибо.
@IgorTandetnik Спасибо за быстрый ответ
Как отметил @Igor Tandetnik, вы могли бы быть удаление элемента из вашего массива во время итерации с bulletVector.erase(bulletVector.begin() + y);
Есть множество из Примеры на SO о этотема, и я, вероятно, не буду объяснять это лучше.
Я хотел бы выделить кое-что еще в вашем коде. В этой секции:
for (int y = 0; y < bulletVector.size(); y++) {
for (int x = 0; x < enemyVector.size(); x++) {
if (enemyVector.size() > 0 && bulletVector.size() > 0) {
if (enemyVector[x].checkColl(Bullet(bulletVector[y]))) {
bulletVector.erase(bulletVector.begin() + y);
enemyVector.erase(enemyVector.begin() + x);
}
}
}
}
там, где вы ищете коллизии, это предложение излишне:
if (enemyVector.size() > 0 && bulletVector.size() > 0) {
Если какой-либо из обоих векторов пуст, по крайней мере, один из циклов for
не будет повторять ни один цикл, поэтому вы можете удалить эту проверку и сохранить некоторые вычисления и строки кода.
На этом этапе вы гарантируете, что оба вектора имеют внутри как минимум 1 элемент.
Если
bulletVector.erase(bulletVector.begin() + y)
стирает последний элемент,bulletVector[y]
на следующей итерации цикла получит доступ к индексу за пределы. В любом случае, даже если индексy
все еще действителен, обратите внимание, что вы фактически пропускаете элемент, следующий за удаленным.