我试图在碰撞时删除船只和弹丸。 要做到这一点,我正在迭代两个高级的for循环,我尝试在它们相交时删除它们。不幸的是,迭代for循环而迭代它们并不是一个好主意,它会抛出一个ConcurrentModificationException,所以我将它们切换为Iterators,这似乎正在起作用。
public void collision()
{
Iterator<Ship> itShips = Ship.ships.iterator();
Iterator<Projectile> itProj = Projectile.projectiles.iterator();
while (itShips.hasNext()) {
Ship ship = itShips.next();
while (itProj.hasNext()) {
Projectile proj = itProj.next();
if (ship.c != proj.c) {
Rectangle.Float r1 = ship.getBounds();
Rectangle.Float r2 = proj.getBounds();
if (r1.intersects(r2)) {
itProj.remove();
itShips.remove();
break;
}
}
}
}
}
问题是ConcurrentModificationException似乎已移动到我调用更新程序的位置。我尝试将这些for循环交换为迭代器,但它似乎不起作用并抛出相同的异常,但现在在update()方法中。
public void update()
{
Iterator<Ship> it1 = Ship.ships.iterator();
while (it1.hasNext()) {
Ship s = it1.next();
s.update(game);
}
Iterator<Projectile> it2 = Projectile.projectiles.iterator();
while (it2.hasNext()) {
Projectile p = it2.next();
p.update(game);
}
}
我是否应该更改我更新游戏对象的方式或保存方式?或者我是以错误的方式删除对象?
答案 0 :(得分:2)
您可以保存碰撞到某个变量的那些,然后在完成循环后,从列表中删除它们:
Ship shipToRemove = null;
Projectile projToRemove = null;
Iterator<Ship> itShips = Ship.ships.iterator();
Iterator<Projectile> itProj = Projectile.projectiles.iterator();
while (itShips.hasNext()) {
Ship ship = itShips.next();
while (itProj.hasNext()) {
Projectile proj = itProj.next();
if (ship.c != proj.c) {
Rectangle.Float r1 = ship.getBounds();
Rectangle.Float r2 = proj.getBounds();
if (r1.intersects(r2)) {
shipToRemove = ship;
projToRemove = proj;
break;
}
}
}
}
Projectile.projectiles.remove(projToRemove);
Ship.ships.remove(shipToRemove);
应该做什么。
答案 1 :(得分:0)
Iterator在迭代时不支持添加。在集合迭代器中使用expectedModCount来检查它是否被其他人修改。当你使用set reference modCount值进行一些add时,并且expectModCount没有改变导致异常。
您应该在最后跟踪并执行更新操作。
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
public interface Iterator {
boolean hasNext();
E next();
void remove();
}
答案 2 :(得分:0)
解决问题的一种有效方法是filter
非碰撞船只和射弹。这种方法避免了同时改变多个对象所引起的问题。我假设Ship.ships
和Projectile.projectiles
是List
个对象,并且可以使用这些对象代替它们的迭代器:
List<Ship> ships = Ship.ships;
List<Projectile> projs = Projectile.projectiles;
Stream<Rectangle.Float> shipBounds = ships.stream().map(s -> s.getBounds());
Stream<Rectangle.Float> projBounds = projs.stream().map(p -> p.getBounds());
List<Ship> safeShips = ships
.stream()
.filter(s -> !projBounds.anyMatch(p -> p.intersects(s.getBounds())))
.collect(Collectors.toList());
List<Projectile> safeProjs = projs
.stream()
.filter(p -> !shipBounds.anyMatch(s -> s.intersects(p.getBounds())))
.collect(Collectors.toList());
答案 3 :(得分:0)
由于我的update()方法仍然出错,我将collidedObjects存储在数组中。使用这些数组我可以从原始的Ship和Projectile数组中删除它们。我这样做是通过调用update()方法中的另一个方法来比较和删除对象。
[
{
"id": 1,
"name": "name",
"description": "description",
"tag": [
"tag1",
"tag2",
"tag3"
]
}
]