当 Sprites 到达特定位置时,我该如何移除它们?
How do I remove Sprites when they go on a specific position?
我的 Sprite 是随机生成的,生成后向上移动,直到它们到达某个位置,然后它们应该被移除。这就是我一直在尝试做的,但我总是遇到错误。
//this method is called at random time
public void newEnemy(){
Sprite enemy= Pools.obtain(Sprite.class);
enemy.set(enemySpr);
enemy.setPosition(200,150);
enemies.add(enemy);
}
//removing the enemy
while (enemyIterator.hasNext()){
Sprite nextEnemy=enemyIterator.next();//<--error here,this is line 66
if(enemySpr.getY()+enemySpr.getHeight()>=treeObj.treeSpr.getY()){
removeEnemy(nextEnemy);
}
}
//removeEnemy method
public void removeEnemy(Sprite sprite){
enemies.remove(sprite);
Pools.free(sprite);
}
//this is the error there I get:
Exception in thread "LWJGL Application" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at com.dreamroad.savethetree.EnemyClass.update(EnemyClass.java:66)
at com.dreamroad.savethetree.MyGdxGame.render(MyGdxGame.java:51)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.run(LwjglApplication.java:120)
Process finished with exit code 0
我认为这是我收到错误的原因,但我不确定:
public void draw(SpriteBatch batch){
for(Sprite drawEnemy:enemies) { //enemies is the ArrayList
drawEnemy.draw(batch);
drawEnemy.translateY(deltaTime * movement);
}
}
问题是你正在尝试删除当前正在迭代的列表中的某些内容,在这种情况下我总是做的事情是创建一个额外的列表,其中包含应该删除的 Sprites,然后在遍历列表后删除它们(或者,在更新方法的末尾,或类似的方法)
一个说明我的想法的简短代码示例:
//removing the enemy
//Initialize a list to store the sprites to be removed
List<Sprite> toBeRemovedSprites = new ArrayList<Sprite>();
while (enemyIterator.hasNext()){
Sprite nextEnemy=enemyIterator.next(); //I get the error here..<--
if(enemySpr.getY()+enemySpr.getHeight()>=treeObj.treeSpr.getY()){
removeEnemy(nextEnemy);
toBeRemovedSprites.add(nextEnemy);
}
}
//Remove the sprites that should be deleted, after iterating over the list
for(Sprite s : toBeRemovedSprites){
enemies.remove(s);
}
//removeEnemy method
public void removeEnemy(Sprite sprite){
//Remove this line that removes the sprite from the list
//enemies.remove(sprite);
Pools.free(sprite);
}
你可以做的另一件事就是使用迭代器的 remove 函数,
想象它看起来像这样:
//removing the enemy
while (enemyIterator.hasNext()){
Sprite nextEnemy=enemyIterator.next(); //I get the error here..<--
if(enemySpr.getY()+enemySpr.getHeight()>=treeObj.treeSpr.getY()){
removeEnemy(nextEnemy, enemyIterator);
}
}
//removeEnemy method
public void removeEnemy(Sprite sprite, Iterator<Sprite> enemyIterator){
//Change the line to remove using the iterator
//enemies.remove(sprite);
enemyIterator.remove();
Pools.free(sprite);
}
正如 Subler 所说,这里的问题是您试图在遍历列表的同时从列表中删除某些内容。
但是,有一个更简单的解决方案。只需在迭代器上调用 remove() 即可。这将删除迭代器的当前元素。
//removing the enemy
while (enemyIterator.hasNext()) {
Sprite nextEnemy = enemyIterator.next();
if(enemySpr.getY() + enemySpr.getHeight() >= treeObj.treeSpr.getY()) {
enemyIterator.remove();
Pools.free(nextEnemy);
}
}
我的 Sprite 是随机生成的,生成后向上移动,直到它们到达某个位置,然后它们应该被移除。这就是我一直在尝试做的,但我总是遇到错误。
//this method is called at random time
public void newEnemy(){
Sprite enemy= Pools.obtain(Sprite.class);
enemy.set(enemySpr);
enemy.setPosition(200,150);
enemies.add(enemy);
}
//removing the enemy
while (enemyIterator.hasNext()){
Sprite nextEnemy=enemyIterator.next();//<--error here,this is line 66
if(enemySpr.getY()+enemySpr.getHeight()>=treeObj.treeSpr.getY()){
removeEnemy(nextEnemy);
}
}
//removeEnemy method
public void removeEnemy(Sprite sprite){
enemies.remove(sprite);
Pools.free(sprite);
}
//this is the error there I get:
Exception in thread "LWJGL Application" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at com.dreamroad.savethetree.EnemyClass.update(EnemyClass.java:66)
at com.dreamroad.savethetree.MyGdxGame.render(MyGdxGame.java:51)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.run(LwjglApplication.java:120)
Process finished with exit code 0
我认为这是我收到错误的原因,但我不确定:
public void draw(SpriteBatch batch){
for(Sprite drawEnemy:enemies) { //enemies is the ArrayList
drawEnemy.draw(batch);
drawEnemy.translateY(deltaTime * movement);
}
}
问题是你正在尝试删除当前正在迭代的列表中的某些内容,在这种情况下我总是做的事情是创建一个额外的列表,其中包含应该删除的 Sprites,然后在遍历列表后删除它们(或者,在更新方法的末尾,或类似的方法)
一个说明我的想法的简短代码示例:
//removing the enemy
//Initialize a list to store the sprites to be removed
List<Sprite> toBeRemovedSprites = new ArrayList<Sprite>();
while (enemyIterator.hasNext()){
Sprite nextEnemy=enemyIterator.next(); //I get the error here..<--
if(enemySpr.getY()+enemySpr.getHeight()>=treeObj.treeSpr.getY()){
removeEnemy(nextEnemy);
toBeRemovedSprites.add(nextEnemy);
}
}
//Remove the sprites that should be deleted, after iterating over the list
for(Sprite s : toBeRemovedSprites){
enemies.remove(s);
}
//removeEnemy method
public void removeEnemy(Sprite sprite){
//Remove this line that removes the sprite from the list
//enemies.remove(sprite);
Pools.free(sprite);
}
你可以做的另一件事就是使用迭代器的 remove 函数, 想象它看起来像这样:
//removing the enemy
while (enemyIterator.hasNext()){
Sprite nextEnemy=enemyIterator.next(); //I get the error here..<--
if(enemySpr.getY()+enemySpr.getHeight()>=treeObj.treeSpr.getY()){
removeEnemy(nextEnemy, enemyIterator);
}
}
//removeEnemy method
public void removeEnemy(Sprite sprite, Iterator<Sprite> enemyIterator){
//Change the line to remove using the iterator
//enemies.remove(sprite);
enemyIterator.remove();
Pools.free(sprite);
}
正如 Subler 所说,这里的问题是您试图在遍历列表的同时从列表中删除某些内容。
但是,有一个更简单的解决方案。只需在迭代器上调用 remove() 即可。这将删除迭代器的当前元素。
//removing the enemy
while (enemyIterator.hasNext()) {
Sprite nextEnemy = enemyIterator.next();
if(enemySpr.getY() + enemySpr.getHeight() >= treeObj.treeSpr.getY()) {
enemyIterator.remove();
Pools.free(nextEnemy);
}
}