一个新对象似乎改变了以前对象的字段

时间:2014-06-27 14:34:55

标签: java object

我正在写一个包含电梯作为障碍的游戏。电梯在屏幕的左侧或右侧产生并且随机有机会成为上升电梯或下行电梯。它看起来像这样:

public class Elevator extends WorldObject {

    public static boolean ascending;

    public Elevator(int screenHeight, int xPos) {
        super(xPos, screenHeight, 0, 0);
        ascending = new Random().nextBoolean();
    }

    static public boolean isAscending(){
        return ascending;
    }

}

它扩展的WorldObject如下所示:

public class WorldObject {

    protected float posX;
    protected float posY;
    protected float velX, velY;

    public float getPosX() {
        return posX;
    }

    public void setPosX(float posX) {
        this.posX = posX;
    }

    public float getPosY() {
        return posY;
    }

    public void setPosY(float posY) {
        this.posY = posY;
    }

    public float getVelX() {
        return velX;
    }

    public void setVelX(float velX) {
        this.velX = velX;
    }

    public float getVelY() {
        return velY;
    }

    public void setVelY(float velY) {
        this.velY = velY;
    }

    public WorldObject(float posX, float posY, float velX, float velY) {
        this.posX = posX;
        this.posY = posY;
        this.velX = velX;
        this.velY = velY;
    }

}

每隔5秒就会创建一个电梯并将其添加到Elevator的数组列表中,如下所示:

    if (timeToElevator > 5.0f) {
        timeToElevator = 0;
        Elevator elevator = new Elevator((int) screenHeight, (int) generateElevatorXPos());
        Sprite eSprite = new Sprite(elevatorTexture);
        eSprite.setOrigin(0, 0);
        elevators.add(elevator);
        elevatorSprites.add(eSprite);
    }

然后我检查每个电梯与播放器的碰撞,如果它超出范围则将其移除,如果这些都不发生我更新电梯对象的位置:

public static void calculateElevatorCollisions() {
    int counter = 0;
    for (Iterator<Elevator> i = elevators.iterator(); i.hasNext(); ) {
        Elevator item = i.next();
        if (item.getPosY() < -100) {
            //remove elevator
        } else if (..collision..) {
            //collision
        } else {
            item.setVelY(item.isAscending() ? -5 : 5);
            item.setPosY(item.getVelY() + item.getPosY());
            elevatorSprites.get(counter).setPosition(item.getPosX(),
                    item.getPosY());
            counter++;
        }

我的问题是,每当创建新Elevator时,所有当前Elevator都会将其方向更改为新Elevator的方向。因此,假设我有两个上升的电梯被绘制,每当我的第三个电梯被创建为下降时,另外两个先前上升的电梯现在上升!

造成这种情况的原因是什么?

3 个答案:

答案 0 :(得分:3)

这是你的问题:

public static boolean ascending;
       ^^^^^^

static表示“这是字段,所有对象共享”。因此,如果您从一个对象更改了该字段,则会在该类型的所有对象中注意到该字段。

删除它以使ascending实例字段意味着Elevator的每个实例都将拥有其自己的副本,它可以自行修改而不会更改其他实例的副本。

答案 1 :(得分:0)

更改

public static boolean ascending;

public boolean ascending;

当您将变量设置为静态时,它是class变量,而不是instance变量。类变量是在对象的所有instances内共享的变量,而instance变量特定于对象的instance

答案 2 :(得分:0)

由于我还没有评论(代表),我想再说一遍:

您正在使用getter进行封装以进行升序,isAscending();但是,您封装的字段为public,可以从所有范围访问。

最好保留封装字段private

此外,似乎每个人都只是声明该字段被更改为非静态变量;但是,该方法仍然是静态的,即使它实际上也是一个实例方法!

所需的更改:

public static boolean ascending;
private boolean ascending;

...和...

static public boolean isAscending()
public boolean isAscending()