我正在写蛇游戏,所以我制作了一个SnakeLogic类来表示蛇的逻辑模型。

实现如下:蛇由段组成,每个段保持其起始位置,长度和运动方向。这是Segment类(SnakeLogic的内部类)的完整代码:

protected class Segment{

    public Point location;
    public SnakeDirection dir;
    public int length;

    public Segment(Point l, SnakeDirection dir,int length){
        location=l;
        this.dir=dir;
        this.length=length;
    }

}


段用LinkedList保留:

private LinkedList<Segment> nodes;


更改方向后,新段将添加到LinkedList的开头:

public void setDirection(SnakeDirection dir){
    //gets location and direction of first segment
    Point head = nodes.getFirst().location;
    SnakeDirection currentDir = nodes.getFirst().dir;
    //if direction isn't changed, return
    if (currentDir == dir) return;
    //ignores directions that are opposite to current one.
    switch(currentDir){
        case LEFT:
            if (dir==SnakeDirection.RIGHT) return;
            break;
        case RIGHT:
            if (dir==SnakeDirection.LEFT) return;
            break;
        case UP:
            if (dir==SnakeDirection.DOWN) return;
            break;
        case DOWN:
            if (dir==SnakeDirection.UP) return;
            break;
    }
    //adds new segment with 0 length,current first segment's location
    //and given direction
    nodes.addFirst(new Segment(head,dir,0));
}


方法Next()计算蛇的运动。根据运动方向,第一段的位置会改变;如果蛇由多于1个段组成,则第一个段的长度增加给定值(stepSize),而最后一个段的长度减少该值。如果最后一段的长度小于等于0,则删除最后一段(如果长度小于零,则从当前最后一段中减去余数)。

public void Next() {
    SnakeDirection headDir = nodes.getFirst().dir;

    switch(headDir){
        case LEFT:
            nodes.getFirst().location.x-=stepSize;
            break;
        case RIGHT:
            nodes.getFirst().location.x+=stepSize;
            break;
        case UP:
            nodes.getFirst().location.y-=stepSize;
            break;
        case DOWN:
            nodes.getFirst().location.y+=stepSize;
            break;
    }

    if (nodes.size()>1){

        nodes.getFirst().length+=stepSize;
        int newLength = nodes.getLast().length-stepSize;

        if (newLength<=0){
            nodes.removeLast();
            nodes.getLast().length-=newLength;
        }
        else{
            nodes.getLast().length=newLength;
        }

    }
}


当我开始对其进行测试时,我发现由于某些奇怪的原因,其他段的位置会随第一个段的位置而改变,此时它们必须保持在原位。看起来像这样:

java - 蛇游戏:蛇段的错误定位-LMLPHP

其他一切似乎都正常。我的代码有什么问题?

最佳答案

创建新细分时,您将传递第一个细分的位置对象,而不是该位置的COPY。因此,您所有的细分对象都共享非常相同的位置对象。如果您在新段中对其进行修改,则由于它是同一对象,因此也会在所有其他段中对其进行修改。
(传递对象时,传递的是对象的引用,而不是对象的值。)
因此,代替此行:

Point head = nodes.getFirst().location;


用这个:

Point head = new Point(nodes.getFirst().location);

09-03 20:03