Какую структуру данных я должен использовать для игры змеи?

У меня есть некоторая домашняя работа для моей школы, и я должен сделать игру змеи, как Nokia, в Delphi. Интересно, какое решение является лучшим. Я хочу свою змею быть классом, и тело является массивом точек (родительский класс) или связанный список точек. Что является лучшим? Массив или связанный список?

9
задан Bill the Lizard 18 September 2012 в 03:16
поделиться

5 ответов

Скомпонованный список лучше. (Каждый узел может указывать на предыдущий и следующий) Проще добавить узлы в конец связанного списка.

Если вы используете массив, вам нужно либо изменить его размер, либо инициализировать его до Максимально возможной длины змейки, для начала с которой можно расточительно расходовать память.

UPDATE Эта статья рассказывает об указателях в Delph и даже предлагает простое определение узла delphi article

7
ответ дан 4 December 2019 в 10:04
поделиться

В 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, вы должны открыть список свойств ... Для этого просто определите свой класс тела змеи следующим образом:

  TSnakeBody = class(TObjectQueue)
  public
    property List;  //Expose the list
  end;
2
ответ дан 4 December 2019 в 10:04
поделиться

Простым решением является создание массива [горизонтального] [вертикального] типа, чтобы на экране было по одному элементу для каждой координаты. Каждый тип может быть змеиным, пищевым, ядовитым, настенным или пустым. Это означает, что нужно только запомнить положение головы и хвоста змеи, а также количество еды и ядов, и массив описывает, как выглядит экран.

Это снимает хлопоты по обращению с элементами змеи и облегчает размещение на экране новой еды или яда, гарантируя, что вы не поместите их в место, которое уже занято.

Когда вам нужно удалить элемент хвоста змеи, получите направление хвоста, используя direction:=array[tailx,taily]; а затем установите array[tailx,taily]:=пустую. После этого обновляйте хвост и ежедневно в зависимости от направления. Вот так.

8
ответ дан 4 December 2019 в 10:04
поделиться

Вот несколько хороших исходных пунктов для вас... поскольку я не хочу делать домашнее задание:

Псевдокод для игры в змею, чтобы получить идею

Тема с немецким примером... может быть, этот код поможет вам

Если в процессе программирования возникнут ошибки, не стесняйтесь открывать новый вопрос.

2
ответ дан 4 December 2019 в 10:04
поделиться

У меня очень старая программа турбоваскальных змей. Она использует массив для тела.

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;
0
ответ дан 4 December 2019 в 10:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: