在我的代码中,我有一个玩家类,我希望在一个弹丸中调用Player
类,但每当我尝试在游戏中调用射弹时,我都会收到此错误
Exception in thread "Thread-2" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at ca.runner.level.Level.tick(Level.java:127)
at ca.runner.game.Game.tick(Game.java:149)
at ca.runner.game.Game.run(Game.java:118)
at java.lang.Thread.run(Unknown Source)
我认为它可能与Mob和Projectile都称为Entity或类似的事实有关,但我不确定如何解决这个问题。如果有人能提供帮助那就太棒了。
玩家等级:
package ca.runner.game.entities;
import ca.runner.game.Game;
import ca.runner.game.InputHandler;
import ca.runner.gfx.Colours;
import ca.runner.gfx.Screen;
import ca.runner.level.Level;
import ca.runner.game.InputHandler;
import ca.runner.gfx.Colours;
import ca.runner.gfx.Screen;
import ca.runner.level.Level;
public class Player extends Mob{
private InputHandler input;
private int colour = Colours.get(-1, 111, 145, 543);
private int scale = 1;
protected boolean isSwimming = false;
private int tickCount = 0;
private int health = 10;
public Player(Level level, int x, int y, InputHandler input) {
super(level, "Player", x, y, 1);
this.input = input;
this.health = health;
}
public void tick() {
int xa = 0;
int ya = 0;
if(input.up.isPressed()) {ya--;}
if(input.down.isPressed()) {ya++;}
if(input.left.isPressed()) {xa--;}
if(input.right.isPressed()) {xa++;}
if(input.space.isPressed()) {
BasicAttack Fireball = new BasicAttack(level, false, "Fireball", 10, 10, 1, 1, 1, getPlayerMoveDir());
level.addEntity(Fireball);
}
if (xa != 0 || ya != 0) {
move(xa, ya);
isMoving = true;
}else {
isMoving = false;
}
if (level.getTile(this.x >> 3, this.y >> 3).getId() == 4) {
isSwimming = true;
}
if (isSwimming && level.getTile(this.x >> 3, this.y >> 3).getId() != 4) {
isSwimming = false;
}
tickCount++;
}
public void render(Screen screen) {
int xTile = 0;
int yTile = 28;
int walkingSpeed = 4;
int flipTop = (numSteps >> walkingSpeed) & 1;
int flipBottom = (numSteps >> walkingSpeed) & 1;;
if (movingDir == 1) {
xTile += 2;
} else if (movingDir > 1) {
xTile += 4 + ((numSteps >> walkingSpeed) & 1) * 2;
flipTop = (movingDir - 1) % 2;
}
int modifier = 8 * scale;
int xOffset = x - modifier / 2;
int yOffset = y - modifier / 2 - 4;
if (isSwimming) {
int waterColour = 0;
yOffset += 4;
if (tickCount % 60 < 15) {
waterColour = Colours.get(-1, -1, 225, -1);
} else if (15 <= tickCount % 60 && tickCount % 60 < 30) {
yOffset -= 1;
waterColour = Colours.get(-1, 225, 115, -1);
} else if (30 <= tickCount % 60 && tickCount % 60 < 45) {
waterColour = Colours.get(-1, 115, -1, 225);
} else {
yOffset -= 1;
waterColour = Colours.get(-1, 225, 115, -1);
}
screen.render(xOffset, yOffset+3, 0 + 27 * 32, waterColour, 0x00, 1);
screen.render(xOffset + 8, yOffset+3, 0 + 27 * 32, waterColour, 0x01, 1);
}
//Upper Body
screen.render(xOffset + (modifier * flipTop), yOffset, xTile + yTile * 32, colour, flipTop, scale);
screen.render(xOffset + modifier - (modifier * flipTop), yOffset, (xTile + 1) + yTile * 32, colour, flipTop, scale);
if (!isSwimming) {
//Lower Body
screen.render(xOffset + (modifier * flipBottom), yOffset + modifier, xTile + (yTile+1) * 32, colour, flipBottom, scale);
screen.render(xOffset + modifier - (modifier * flipBottom), yOffset + modifier, (xTile+1) + (yTile+1) * 32, colour, flipBottom, scale);
}
}
public boolean hasCollided(int xa, int ya) {
int xMin = 0;
int xMax = 7;
int yMin = 3;
int yMax = 7;
for (int x = xMin; x < xMax; x++) {
if (isSolidTile(xa, ya, x, yMin)) {
return true;
}
}
for (int x = xMin; x < xMax; x++) {
if (isSolidTile(xa, ya, x, yMax)) {
return true;
}
}
for (int y = yMin; y < yMax; y++) {
if (isSolidTile(xa, ya, xMin, y)) {
return true;
}
}
for (int y = yMin; y < yMax; y++) {
if (isSolidTile(xa, ya, xMax, y)) {
return true;
}
}
return false;
}
public int getPlayerHealth() {
return health;
}
public int getPlayerMoveDir() {
return movingDir;
}
}
弹丸类:
package ca.runner.game.entities;
import ca.runner.level.Level;
import ca.runner.level.tiles.Tile;
public abstract class Projectile extends Entity{
protected String name;
protected int speed;
protected int numSteps = 0;
protected boolean isMoving;
protected int movingDir = 1;
protected int scale;
protected int damage;
protected boolean emitter;
protected int moveDir;
public Projectile(Level level, boolean isEmitter, String name, int x, int y, int speed, int damage, int scale, int MoveDir) {
super(level);
this.name = name;
this.x = x;
this.y = y;
this.speed = speed;
this.damage = damage;
this.emitter = isEmitter;
this.scale = scale;
this.moveDir = moveDir;
}
public boolean isEmitter() {
return emitter;
}
public void move(int xa, int ya) {
//if(!hasCollided(xa, ya)) {
x+= xa * speed;
y += ya * speed;
//} else {
// level.removeEntity(this);
//}
}
//public abstract boolean hasCollided(int xa, int ya);
protected boolean isSolidTile(int xa, int ya, int x, int y) {
if (level == null) { return false;}
Tile lastTile = level.getTile((this.x + x) >> 3, (this.y + y) >> 3);
Tile newTile = level.getTile((this.x + x + xa) >> 3, (this.y + y + ya) >> 3);
if (!lastTile.equals(newTile) && newTile.isSolid()) {
return true;
}
return false;
}
public String getName() {
return name;
}
}
编辑:添加了完整的堆栈跟踪
答案 0 :(得分:1)
我猜想Level类的addEntity方法会将Fireball添加到集合中。 &#34; tick&#34;您的Player类中的方法可能会覆盖&#34; Mob&#34;中的tick方法。从循环于addEntity想要添加的同一集合的东西调用的类。
看看你的迭代器的文档,它会告诉你它会抛出&#34; ConcurrentModificationException&#34;如果有人在迭代时修改了这个集合。
我可以想出几种解决问题的方法。
我希望这会有所帮助。