Структура данных для уровней в играх - PullRequest
6 голосов
/ 27 сентября 2010

Я создаю платформенную игру на JavaScript, используя canvas, полностью основанную на плитках. Каков наилучший способ хранения блоков предметов в игре (стены, полы, предметы)? Дело в том, что каждая плитка может быть уничтожена или создана.

В настоящее время у меня есть 2D-массив, поэтому я могу быстро проверить, находится ли элемент в определенной позиции X & Y. Проблема в том, что когда пользователь перемещается и карта должна прокручиваться, мне нужно переназначить каждый блок. А что происходит, когда предмет находится на x = 0? Я не могу использовать отрицательные индексы.

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

Еще один момент, который я должен упомянуть, это то, что он также будет многопользовательским. Так что разбиение экрана - отличная идея до тех пор, пока кэшированные данные не станут грязными и не понадобятся последние данные из базы данных. Ха, я так новичок во всем этом; кажется невозможным, любая помощь очень ценится.

Ответы [ 3 ]

4 голосов
/ 27 сентября 2010

Поскольку у вас есть бесконечные уровни, я бы предложил структуру, похожую на ту, что у вас уже есть, с небольшим изменением.

Вместо того, чтобы хранить все в одном большом массиве и перемещать вещи внутри этого массива каждый раз, когда пользователь перемещает (ой), вместо этого сохраняйте 9 фрагментов карты (каждый размером, примерно равным удвоенному размеру экрана), когда пользователь приближается к краю текущего чанка, расположите чанки за кадром, переместите все левые чанки и загрузите новые в промежуток.

Надеюсь, это было понятно, но на всякий случай вот диаграмма:

Chunking

Буквенные квадраты - это куски карты, а красный квадрат - это окно просмотра (я нарисовал его немного слишком большим, помните, что окно просмотра меньше черных квадратов). Когда окно просмотра перемещается вправо, вы выгружаете фрагменты A B и C, перемещаете все остальные влево и загружаете новые данные в самые правые. Поскольку чанк в два раза больше ширины экрана, у вас есть время, необходимое пользователю, чтобы пересечь экран, чтобы сгенерировать / загрузить уровень в эти чанки. Если пользователь быстро перемещается по миру, у вас может быть набор фрагментов 4x4 для дополнительной буферизации.

Для решения возврата к предыдущим фрагментам карты. Есть несколько способов сделать это:

  • Запишите куски на жесткий диск, когда они больше не используются (или что-либо подобное в javascript)
  • Расширяйте свой блок бесконечно в памяти. Вместо массива чанков есть ассоциативный массив, который занимает х / у позицию чанка и возвращает чанк (или ноль, что указывает на то, что пользователь никогда не был здесь раньше, и его нужно сгенерировать).
  • Процедурно генерируйте свои уровни, это сложно, но это означает, что, как только чанк уходит с экрана, вы можете просто утилизировать его и быть уверенным, что позже сможете восстановить тот же самый чанк снова
1 голос
/ 07 января 2011

Однажды я определил эту самую вещь в XML и JSON ... Я думаю, что сериализация JSON была бы намного быстрее и эффективнее (не говоря уже о простоте) для работы в JavaScript, тем более, что JSON так хорошо подходит для переменной длины списки, необходимые для уровней "N" в каждой игре.

Использование стандартного формата также сделало бы его более пригодным для повторного использования и (в идеале) способствовало бы расширению сотрудничества (если это то, что вы ищете). Вы можете проверить мою первую попытку создать схему видеоигры для структуры уровней .

Как говорит fileoffset, есть много способов сделать это, но я настоятельно рекомендую хранить данные вашего уровня (то есть концепции) отдельно от вашего рендеринга (то есть объекты в движении, пути, скорость, время, х / у / z позиционирование по ординате и т.д ...).

Опять же, поскольку в статье говорилось, что область меняется наиболее быстро, и неясно, будет ли для вас лучшим вариантом WebGL, SMIL + SVG, Canvas + Javascript, хороший старый Flash / Actionscript или что-то еще, в зависимости от того, о ваших потребностях и типе игры, которую вы разрабатываете.

1 голос
/ 27 сентября 2010

Существует множество способов сделать это.

Если их уровни не слишком велики, вы можете сохранить исходный дизайн двухмерного массива и использовать переменную для хранения текущей позиции прокрутки x / y. Это означает, что вы постоянно храните всю информацию о карте в памяти и получаете доступ только к тем частям, которые необходимо отобразить на экране.

При рисовании вы определяете, какая плитка видна в текущей позиции прокрутки x / y, сколько плиток умещается на экране с текущей шириной экрана и раскрашивает только те, которые вам нужны.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...