Каков наилучший способ представления уровней в 2D боковой скроллер? - PullRequest
15 голосов
/ 16 июля 2009

У меня нет знаний по программированию игр, и я часто задавался вопросом, как хранятся уровни в 2D играх, таких как Mario и Sonic (и т. Д.).

«Сохраняется», как в том, как хранятся данные (земля, платформы, кнопки, подъемники и т. Д.).

т.е. Очевидно, что уровень в Марио это не какое-то очень широкое изображение, которое перемещается слева направо.

Ответы [ 12 ]

23 голосов
/ 16 июля 2009

Благодаря сцене взлома ПЗУ формат файла для Super Mario World (и я полагаю, что большинство других популярных игр той эпохи) хорошо известен и в основном полностью понят. Есть также документы, которые описывают все это до мельчайших деталей. К сожалению, потому что это означает посещение сайтов, не имеющих юридической силы, я не могу предоставить вам ссылки с работы, но если вы воспользуетесь расширением файла .MWL и приложением для редактирования под названием Lunar Magic, оно может указать вам верное направление .

Основной принцип довольно прост. Сначала вам нужна ваша графика, поэтому вы создаете одно изображение с плитками для ландшафта определенного размера - чем меньше, тем эффективнее память, чем больше, тем больше деталей, поэтому предположим, что у нас 32 х 32 пикселя. Таким образом, вы получите что-то вроде этого (символы, представляющие разные плитки):

    ! " £ $ %
    ^ & * ( )

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

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

   fireworld.img
   2 2 2 2 2 2 2 2
   3 3 2 2 2 2 3 3
   3 3 3 3 3 3 3 3

Объединено с набором плиток выше, который у вас будет (в зависимости от того, как вы нумеруете плитки)

   " " " " " " " "
   £ £ " " " " £ £
   £ £ £ £ £ £ £ £

Очевидно, что тогда вам нужно наложить больше информации поверх этого: какие плитки сплошные, какие смертельные и т. Д. Это можно сделать на уровне изображения (3 всегда сплошная) или, для большей гибкости, но больших файлов, на уровне карты. Подойдут битовые флаги, первое число сплошное, второе смертельное:

   fireworld.img
   200 200 200 200 200 200 200 200
   310 310 200 200 200 200 310 310
   310 310 310 310 310 310 310 310

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

Как только все это будет сделано, вы можете посмотреть на сжатие. Есть несколько способов сэкономить место, и, очевидно, сейчас это не так важно, как это было в 16 и 8-битных эпохах, но даже в этом случае наш формат, приведенный выше, является чрезвычайно расточительным.

Как всегда, это только основные принципы. Ваши результаты могут отличаться ...

9 голосов
/ 16 июля 2009

Не совсем актуально, но знаете ли вы, что облака в Марио такие же спрайтовые, как кусты, только со смещенной цветовой палитрой? Память тогда была действительно дорогой!

На самом деле невозможно узнать, как они хранятся, но, вероятно, с подходом «объекты на сетке» с несколькими хитростями экономии памяти здесь + там. Реализация должна сильно варьироваться от игры к игре и в значительной степени полностью зависит от разработчика - на самом деле стандартного подхода не существует.


Обновление: я представляю, что представление всего уровня в виде (очень широкой) сетки будет лучшим подходом. В каждом окне сетки вы должны разместить спрайт со свойствами (икру, земля, стена, сундук, злодей, шипы и т. Д.). Движок будет рисовать спрайт в правильном месте, но также иметь свойства, связанные с ним. Если вы поставите 10 частей пола подряд, вам придется кодировать движок, чтобы распознать соединение, и где разместить правильную конечную часть и т. Д. Очевидно, что все, что не является сеткой, будет небом!

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

5 голосов
/ 22 июля 2009

Все те, кто утверждает, что игры Mario хранят свои уровни в некоторой структуре 2D-массива, имеют способ выключен: кроме первых двух игр GB Mario (и, возможно, третьей), игры Super Mario на основе объекта .

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

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

Специфика этой системы различается в разных играх.

Кроме этого, Мартин Харрис совершенно прав.

3 голосов
/ 16 июля 2009

Я полагаю, что для большинства 2D-игр уровень хранится как растровое изображение плиток.

Работает так:

  • Во-первых, у вас есть целое множество плиток с фиксированным размером, скажем, 16x16 пикселей. Эти плитки похожи на кусочки мозаики. Вы можете соединить их вместе всеми возможными способами, чтобы сформировать уровень. Например, здесь представлен набор тайлов, хотя, похоже, что для какой-то игры типа сверху-вниз принципы одинаковы: http://silveiraneto.net/wp-content/uploads/2009/04/free_tileset_version_9.png

  • Как только ваш набор плиток известен, вы присваиваете каждой плитке номер. Вы можете сохранить это число в байте, если у вас меньше 256 плиток, или в слове или слове, если у вас больше. Также полезно добавить немного семантики к этим числам. Скажем, например, что плитки 1-100 представляют собой «препятствия», через которые вы не можете пройти. Это пригодится позже.

  • Теперь пришло время определить карту. Мы можем просто сделать это, поместив кусочки головоломки на большую сетку! Мы определяем максимальный размер для карты. Для бокового скроллера, скажем, карта имеет ширину 1000 плиток и высоту 50 плиток. Вы можете выбрать все, что вы хотите. Теперь вы можете представить карту в памяти (и на диске) как матрицу двоичных чисел width * height чисел. Каждая «ячейка» в сетке содержит число, представляющее плитку, которая должна быть нарисована в этом месте.

Рисовать карту теперь легко:

for (y = 0; y < height; y++) {
   for (x = 0; x < width; x++) {
      draw_tile(x * 16, y * 16, map[y][x]);
   }
} 

Как и другие вещи. Помните, что мы определили плитки 1-100 как препятствия? Мы можем использовать карту для определения возможности перемещения игрока в определенную позицию:

bool moveable(int x, int y) {
   return map[y / 16][x / 16] > 100;
}

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

  • несколько слоев, чтобы представить объекты поверх фона
  • параллакс-прокрутка для классных фоновых эффектов

Я вполне уверен, что большинство 2D-игр используют какой-либо вариант техники мозаичных игровых карт.

1 голос
/ 16 июля 2009

Я использовал сценарии Lua для создания уровней для Физкультурных игр . Они загружаются не так быстро, как бинарный формат, но это значительно облегчает отладку и интеграцию с другими инструментами Уровни загрузки также обычно не там, где скорость действительно окупается.

1 голос
/ 16 июля 2009

Как сохранено структуры данных .

Задайте слишком широкий вопрос, получите слишком широкий ответ. :)

0 голосов
/ 16 июля 2009

Я очень часто видел используемые массивы со значениями, привязанными к типам ландшафта / заливки. Вот краткое руководство Тони Па по созданию игр на основе флеш-плитки:

Хранение игровой карты

Затем создатель уровня просматривает и создает файл. Посмотрите на Kongregate для игр, которые позволяют создание на уровне пользователя; они хранят целый уровень, который передается в виде переменных POST, когда вы ссылаетесь на игру. Это прозрачный процесс, который не часто кодируется, поэтому его легко изучить (и есть много типов игр, которые делают это)

0 голосов
/ 16 июля 2009

В некотором родственном сообщении от одного из наших уважаемых лидеров есть Почему форматы файлов Microsoft Office такие сложные? (И некоторые обходные пути)

0 голосов
/ 16 июля 2009

Я не знаю, как что-то вроде Марио будет хранить свои уровни, и я никогда не делал это сам, но так я бы подошел.

Я бы создал простой формат файла, основанный на XML. В этом я, вероятно, определил бы размер игровой зоны и другие метаданные, такие как имя и ограничение по времени. Тогда у меня будет список объектов, которые будут отображаться в игровой зоне с их координатами x / y и типом объекта, например, Стартовая позиция игрока, выход с уровня и т. д.). У меня может быть даже раздел, в котором хранится информация о том, когда в игре происходят события.

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

Надеюсь, это поможет.

0 голосов
/ 16 июля 2009

В случае (предположительно старых и 2D) игр Mario и Sonic, о которых вы упомянули, возможно, существует какой-то таинственный сжатый и оптимизированный формат, чтобы обойти ограничения хранения и обработки консолей, для которых они были созданы.

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