在java中从子类调用子类

在java中从子类调用子类,java,class,subclass,Java,Class,Subclass,在我的代码中,我有一个player类,从这个player类中,我想调用一个射弹,但每当我在游戏中尝试调用射弹时,我都会得到这个错误 Exception in thread "Thread-2" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Sourc

在我的代码中,我有一个player类,从这个
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)
我认为这可能与暴徒和抛射者都调用实体之类的事实有关,但我不确定如何解决这个问题。如果有人能帮忙,那就太好了

球员级别:

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;
}

}

编辑:添加了完整的stacktrace

我猜Level类的addEntity方法会将Fireball添加到集合中。 Player类中的“tick”方法可能重写了“Mob”类中的tick方法,该方法是从循环addEntity要添加到的同一集合的某个对象调用的

看一下迭代器的文档,它会告诉您,如果有人在对集合进行迭代时修改集合,它会抛出“ConcurrentModificationException”

我可以想出几种方法来解决这个问题

  • 勾选完成后,将火球添加到要添加到收藏的物品列表中
  • 保留对迭代器的某种引用,可以调用迭代器进行加法。(感觉像是一个复杂的解决方案,因为您可能需要以不同的方式处理“inTick”和“outsideTick”
  • 使用旧式的“getAt”遍历集合以检索值。这意味着您自己负责并发性

我希望这能有所帮助。

您在哪一行得到错误?这是您在对集合进行迭代时修改集合时遇到的异常情况,例如使用“for each”。请使用迭代器来迭代和修改集合,而不是使用完整的stacktrace。请发布堆栈跟踪和导致错误的行。还请注意可以调用方法,但不能调用类。
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;
}

}