Каков наилучший способ представления уровней в 2D-скроллере?

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

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

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

Ответы

Ответ 1

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

Основной принцип, однако, довольно прост. Сначала вам нужна ваша графика, поэтому вы создаете единое изображение с плитками для пейзажа с определенным размером - меньший объем памяти эффективнее, больше дает вам больше деталей, так что давайте скажем, что у нас 32 X 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 бит, но даже в этом случае наш формат выше массово расточительно.

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

Ответ 2

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

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


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

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

Ответ 3

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

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

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

Особенности этой системы различаются между играми.

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

Ответ 4

Для большинства 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-игр используется какой-либо вариант технологии игровой карты с черепицей.

Ответ 6

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

Ответ 7

Это слишком широко.

Хранилище игрового уровня варьируется WIDELY на основе движка.

Ответ 8

Обычно в каком-то настраиваемом формате файла, который анализирует игра.

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

Посмотрите на модные сайты для своей игры, и вы найдете больше.

Ответ 9

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

Ответ 10

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

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

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

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

Ответ 12

Я очень часто видел используемые массивы со значениями, привязанными к типам рельефа/заливки. Здесь -great-учебник от Tony Pa о создании флеш-плитки:

Хранилище карт памяти

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