我正在写蛇游戏,所以我制作了一个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()
计算蛇的运动。根据运动方向,第一段的位置会改变;如果蛇包含多于一个的段,则第一个段的长度增加给定值(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;
}
}
}
当我开始对其进行测试时,我发现由于某些奇怪的原因,其他段的位置会随第一个段的位置而改变,此时它们必须保持在原位。看起来像这样:
其他一切似乎都正常。我的代码有什么问题?
答案 0 :(得分:0)
没有MCVE不可能知道问题出在哪里,但是设计似乎过于复杂。代替使用线段,而使用点。
假设您的观点是
class Point {
int x, y;
// getters/setters if you want
}
然后用点和方向列表表示蛇:
class Snake {
List<Point> body = new LinkedList<>();
Point head; // easier to separate the head, but you can do with including it in the list
Direction dir;
}
您可以向其中添加next()
方法以计算蛇的表示形式:
void next() {
int temp1x = head.x;
int temp1y = head.y;
switch(dir) {
case LEFT:
head.x -= stepSize;
break;
//...
}
int temp2x, temp2y;
for (Point point : points) {
temp2x = point.x;
temp2y = point.y;
point.x = temp1x;
point.y = temp1y;
temp1x = temp2x;
temp1y = temp2y;
}
}
我将留给您简化实施(如果扩展Point
类以允许它,则可以使用int
而不是单独的x和y Point
)
注释:
LinkedList
确实是列表实现的不错选择。next
而不是Next
开头。答案 1 :(得分:0)
创建新的细分时,您将传递第一个细分的位置对象,而不是该位置的COPY。因此,您所有的细分对象都共享非常相同的位置对象。如果您在新段中对其进行修改,则由于它是同一对象,因此也会在所有其他段中对其进行修改。 (当您传递对象时,您将传递对象的引用,而不是对象的值。) 因此,代替此行:
Point head = nodes.getFirst().location;
使用此:
Point head = new Point(nodes.getFirst().location);