我为学校做了一些功课,我必须在德尔福做一个像诺基亚一样的蛇游戏。我想知道哪种解决方案是最好的。我希望我的蛇是一个类,主体是一个点数组(父类)或点链接列表。什么是最好的?数组或链表?
答案 0 :(得分:8)
一个简单的解决方案是创建一个类型的数组[水平] [垂直],这样屏幕上的每个坐标都有一个项目。每种类型都可以是蛇方向,食物,毒药,墙壁或空洞。这意味着你只需要记住蛇的头部和尾部位置,以及食物和毒药的数量,并且阵列描述了屏幕的样子。
这消除了处理蛇元素的麻烦,并且可以轻松地将新食物或毒物放置在屏幕上,确保您不会将其放入已占用的地方。
当你需要移除蛇的尾部元素时,使用方向获取尾部的方向:= array [tailx,taily];然后设置数组[tailx,taily]:= empty。然后,根据方向更新tailx和taily。就是这样。
答案 1 :(得分:7)
链接列表更好。 (每个节点都可以指向上一个节点和下一个节点)将节点添加到链接列表的末尾更容易。
如果你使用一个数组,你需要调整它的大小或者将它初始化为最大可能的蛇长度,这可能会浪费在内存上。
<强>更新强> 本文讨论Delph中的指针,甚至建议一个简单的节点定义delphi article
答案 2 :(得分:2)
以下是一些很好的起点...因为我不想做你的作业:
Pseudo Code for Snake Game to get an Idea
Thread with a german example...maybe this code helps you
如果在编程过程中出现错误,请随时打开一个新问题。
答案 3 :(得分:2)
在Delphi中,我使用了一个TQueue,这是在Contnrs单元中定义的。 你可以将你的新坐标“推”到它(蛇头),当达到最大蛇的大小时,你只需要打“pop”来释放蛇尾。
lp := new(PPoint);
lp^.X := x;
lp^.X := y;
Body.Push(lp);
if Body.count > iSnakeLength then
Dispose(Body.Pop); // Free the last TCoord that is pop'ed.
然后,您需要做的就是绘制TObjectQueue中的内容。要访问TQueue的List,你必须公开属性List ...要做到这一点,只需像那样定义你的蛇体类;
TSnakeBody = class(TObjectQueue)
public
property List; //Expose the list
end;
答案 4 :(得分:2)
我为Snake实现使用了不同的东西。想法是你存储
这非常有效,不是像简单阵列那样愚蠢的解决方案,而且可以很容易地用来绘制“发烧的”蛇,例如:圆角。
答案 5 :(得分:0)
我有一个非常古老的turbopascal蛇计划。它为身体使用一个数组。
const MaxBodyLength = 100;
type
TSnake = record
Dir : (nord,sud,est,oest);
Head : tpoint;
BodyLength : integer;
Body : array[1..MaxBodyLength] of tPoint;
Tail : tpoint;
end;
var
Snake : TSnake;
Fruit : tPoint;
以及将蛇移动的代码......
procedure Slither;
var i : integer;
npos,lpos : tPoint;
hasEaten:boolean;
begin
npos:=Snake.Head;
lpos:=Snake.Tail;
case Snake.dir of
East : inc(npos.x);
West : dec(npos.x);
South : inc(npos.y);
North : dec(npos.y);
end;
hasEaten:=(npos.x=fruit.x) and (npos.y=fruit.y);
if hasEaten then
inc(Snake.BodyLength)
else
Snake.Tail:=Snake.Body[Snake.BodyLength];
for i:=Snake.BodyLength downto 2 do
Snake.Body[i]:=Snake.Body[i-1];
Snake.Body[1]:=Snake.Head;
if not hasEaten then
Snake.Head:=npos;
writeP(idHead,Snake.Head);
writeP(idBody,Snake.Body[1]);
if not hasEaten then
begin
writeP(idTail,Snake.Tail);
writeP(idResidual,lPos);
end;
if hasEaten then
NewFruit;
end;
答案 6 :(得分:0)
您可以使用circular buffer。详细说明:
获得一个足够大的阵列来容纳最大的蛇。建立两个指针,一个用于头部,一个用于尾部。
开始时,尾部将位于单元格#1中,单元格位于单元格#3中。当蛇移动时,将头指针移动到右侧并写入新坐标。然后,如果没有食用,也可以将尾指针移到右边。如果其中一个指针试图超出数组的最右端,请将它们包装到开头。