我正在尝试制作一个小游戏,但我却陷入了这个错误。 我在互联网上搜索,我能找到的就是使用
List<Entity> entity = Collections.synchronizedList(new LinkedList<Entity>());
不幸的是,这并没有帮助我,我试图绕着for循环工作,但我仍然找不到修复。有人知道如何摆脱这个错误。
处理程序类
public List<Entity> entity = Collections.synchronizedList(new LinkedList<Entity>());
public List<Tile> tile = Collections.synchronizedList(new LinkedList<Tile>());
public void render(Graphics g){
for(Entity entity : entity){
entity.render(g);
}
for(Tile tile : tile){
tile.render(g);
}
}
public void update(){
for(Entity entity : entity){
entity.update();
}
for(Tile tile : tile){
tile.update();
}
}
public void addEntity(Entity entity){
this.entity.add(entity);
}
public void removeEntity(Entity entity){
this.entity.remove(entity);
}
public void addTile(Tile tile){
this.tile.add(tile);
}
public void removeTile(Tile tile){
this.tile.remove(tile);
}
抽象实体类(由每个实体扩展)
public int x,y,width,height;
public boolean solid;
public Id id;
public Handler handler;
public int velX,velY;
public boolean falling = true;
public boolean jumping = false;
public double gravity = 0.0;
public double health;
public boolean damageable = true;
public long damageTimer = System.currentTimeMillis();
public Entity(int x, int y, int width, int height, boolean solid, Id id,Handler handler){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.solid = solid;
this.id = id;
this.handler = handler;
if(id==Id.Zombie) health=3.0;
if(id==Id.Player) health=5.0;
}
public abstract void render(Graphics g);
public abstract void update();
public void die(){
handler.removeEntity(this);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public boolean isSolid() {
return solid;
}
public Id getId() {
return id;
}
public int getVelX() {
return velX;
}
public void setVelX(int velX) {
this.velX = velX;
}
public int getVelY() {
return velY;
}
public void setVelY(int velY) {
this.velY = velY;
}
public Rectangle getBounds(){
return new Rectangle(x,y,width,height);
}
public Rectangle getBoundsTop(){
return new Rectangle(x,y-6,width,6);
}
public Rectangle getBoundsBottom(){
return new Rectangle(x,y+height,width,6);
}
public Rectangle getBoundsLeft(){
return new Rectangle(x-6,y,6,height);
}
public Rectangle getBoundsRight(){
return new Rectangle(x+width,y,6,height);
}
public double getHealth() {
return health;
}
public void setHealth(double health) {
this.health = health;
}
错误:
Exception in thread "Thread-2" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:966)
at java.util.LinkedList$ListItr.next(LinkedList.java:888)
at Main.Handler.update(Handler.java:26)
at Main.GUI.update(GUI.java:100)
at Main.GUI.run(GUI.java:56)
at java.lang.Thread.run(Thread.java:745)
第26行是:
for(Entity entity : entity){
只有在有多个敌人的情况下被杀死时才会出现这个错误。 (特别是当有东西被杀死而另一个敌人真的非常非常接近时)
添加:Zombie类(Entity.update();应该为使用此类创建的每个对象执行此类update()方法)
public Zombie(int x, int y, int width, int height, boolean solid, Id id, Handler handler) {
super(x, y, width, height, solid, id, handler);
}
@Override
public void render(Graphics g) {
g.setColor(Color.RED);
g.fillRect(x, y, width, height);
}
@Override
public void update() {
x+=velX;
y+=velY;
if(x<=0) x=0;
if(x+width >= GUI.WIDTH*GUI.SCALE+10) x = GUI.WIDTH*GUI.SCALE-width+10;
if(y+height >= GUI.HEIGHT*GUI.SCALE+10) y = GUI.HEIGHT*GUI.SCALE-height+10;
for(Tile tile: GUI.handler.tile){
if(tile.getId()==Id.Stone){
if(getBoundsTop().intersects(tile.getBounds())){
y = tile.getY()+tile.height;
}
if(getBoundsBottom().intersects(tile.getBounds())){
y = tile.getY()-height;
gravity=0.0;
falling=true;
jumping=false;
}
if(getBoundsLeft().intersects(tile.getBounds())){
x = tile.getX()+tile.width;
}
if(getBoundsRight().intersects(tile.getBounds())){
x = tile.getX()-width;
}
}
}
for(Entity entity: GUI.handler.entity){
if(entity.getId()==Id.Player){
if(System.currentTimeMillis()-damageTimer>1000){
damageable=true;
entity.damageable = true;
damageTimer+=1000;
}
if(new Rectangle(x-6,y-6,width+12,6).intersects(entity.getBounds())){
entity.damageable = false;
if(damageable){
if(entity.gravity>=0){
setHealth(getHealth()-1.0);
entity.falling = false;
entity.jumping = true;
entity.gravity = -10.0;
entity.setVelY((int) entity.gravity);
}
damageable=false;
}
}
if(getBoundsBottom().intersects(entity.getBounds())){
if(entity.damageable){
entity.setHealth(entity.getHealth()-1.0);
entity.damageable = false;
}
}
if(getBoundsLeft().intersects(entity.getBounds())){
if(entity.damageable){
entity.setHealth(entity.getHealth()-1.0);
entity.damageable = false;
}
}
if(getBoundsRight().intersects(entity.getBounds())){
if(entity.damageable){
entity.setHealth(entity.getHealth()-1.0);
entity.damageable = false;
}
}
}
}
if(jumping){
gravity+=0.2;
setVelY((int)gravity);
if(gravity>=0.5){
gravity+=0.1;
}
}
if(falling){
gravity+=0.3;
setVelY((int) gravity);
}
for(Entity entity : GUI.handler.entity){
if(entity.getId()==Id.Player){
if(entity.getY()<y&&!jumping&&getVelY()<=0){
if(entity.getY()<y-10){
if(entity.getX()<x){ velX = -3; }else{ velX = 3; }
gravity = -10.0;
jumping = true;
falling = false;
velY = (int)gravity;
} else {
if(entity.getX()<x){ velX = 3; }else{ velX = -3; }
}
}
}
}
if(health<=0) die();
}
答案 0 :(得分:1)
你的问题出在你的骰子方法中。您正在尝试编辑当前正在迭代的列表实体。这会导致你的错误。
不要修改其中的列表,而是尝试使用辅助列表来告诉您哪些实体已经死亡。在所有更新之后,您应该删除所有这些实体。
答案 1 :(得分:0)
ConcurrentModificationException
表示在迭代时修改了集合。
Collections.synchronizedList
无法保护您免受ConcurrentModificationException
。
有两种解决方案。
CopyOnWriteArrayList
那样抛出此异常的集合。但它只是隐藏问题。例如,如果你迭代实体集合,同时有人删除其中一个实体,你仍然会处理被移除的实体(这可能会造成像死僵尸一样的伤害仍然可以攻击)。