我有2个arraylists,一个用于子弹,另一个用于敌人,两个都有各自的类别('Enemy'和'Bullet')。
我正在尝试进行碰撞检查以查看子弹是否击中了敌人,如果有,它会移除子弹和一些敌人的健康状况。如果屏幕上一次只有一颗子弹,如果一次射击多次射击,一旦第一颗子弹击中敌人,就会出现“索引越界异常”并崩溃,此方法目前效果很好。这是我的代码:
private void checkBulletCollisions() {
int len = bullets.size();
int enemyLen = enemies.size();
for (int i = 0; i < len; i++) {
Bullet bullet = bullets.get(i);
for (int j = 0; j < enemyLen; j++) {
Enemy enemy = enemies.get(j);
if (bullet.bounds.overlaps(enemy.bounds)) {
bullets.remove(bullet);
enemy.health--;
if (enemy.health <= 0) {
enemies.remove(enemy);
break;
}
}
}
}
}
通过评论bullets.remove line和enemy.health - ,没有错误。
我猜它是因为当子弹被移除时,指数会在剩余的子弹上发生变化。我不确定问题是否按照代码的顺序存在,或者是否需要完全不同的方法。感谢您的帮助
答案 0 :(得分:2)
你是对的,问题是你从列表中删除一个条目而不更新用于迭代条目的列表大小。例如,如果列表在开头有三个条目并且您删除了一个条目,则只剩下两个条目。不过,您尝试访问循环中的第三个条目。
通常,修改迭代它的for
或foreach
循环中的列表并不是一个好主意。请改为使用while
循环和Iterator
,如this answer中所述。
例如:
Iterator<Bullet> bulletIterator = bullets.iterator();
while (bulletIterator.hasNext()) {
Bullet bullet = bulletIterator.next();
Iterator<Enemy> enemyIterator = enemies.iterator();
while (enemyIterator.hasNext()) {
Enemy enemy = enemyIterator.next();
if (/* check if you have to remove the bullet */) {
bulletIterator.remove();
}
if (/* check if you have to remove the enemy */) {
enemyIterator.remove();
}
}
}