我正在写蛇游戏,所以我制作了一个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;
}
}
}
当我开始对其进行测试时,我发现由于某些奇怪的原因,其他段的位置会随第一个段的位置而改变,此时它们必须保持在原位。看起来像这样:
其他一切似乎都正常。我的代码有什么问题?
最佳答案
创建新细分时,您将传递第一个细分的位置对象,而不是该位置的COPY。因此,您所有的细分对象都共享非常相同的位置对象。如果您在新段中对其进行修改,则由于它是同一对象,因此也会在所有其他段中对其进行修改。
(传递对象时,传递的是对象的引用,而不是对象的值。)
因此,代替此行:
Point head = nodes.getFirst().location;
用这个:
Point head = new Point(nodes.getFirst().location);