Лучший способ создать карту для 2D-игры?


16

Я прошу прощения за субъективное "лучшее" ключевое слово.

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

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

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

Сегодня он сказал мне, что хочет создать простую карту двумерного массива [WIDTH] [HEIGHT], которая содержит данные о каждой сетке в игре и является постоянной операцией сохранения на диск для данных, которые нам не нужны.

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


Какую машину вы используете?
Дэвид Титаренко

До сих пор Windows с C ++ использует SFML (SFML может быть изменен; C ++ - нет). Мы не стремимся к мобильности.
IAE

2
Если вы едете на олдскульную Зельду на РЭШ, используйте только 1-экранные карты. Маленькие карты помогают игрокам сфокусировать сферу своих намерений (то есть в темнице, когда вы имеете дело только со своей комнатой. В Diablo монстры не двигались вверх и вниз по этажам) и позволяют им чувствовать завершенность, если они обыскали всю область что игры в открытом космосе, такие как FAllout3 и Oblivion, не дают вам.
Стивен Фурлани

Ответы:


27

Прежде всего, оцените размер вашей карты. Не просто предполагайте, что «большой мир» не уместится в памяти. В настоящее время карта, занимающая в памяти более 10 мегабайт, является абсолютно приемлемой, и вы можете набрать ЛОТ в 10 мб в простом 2D-мире на основе тайлов.

Если у вас действительно большой мир, самое надежное решение - использовать куски карты. Разделите ваш мир на куски фиксированного размера (скажем, 64x64). Загружайте куски на лету, когда игрок перемещается, сохраняя, по крайней мере, один кусок загруженным во всех направлениях (т.е. загружайте блок, в котором находится игрок, и всех его соседей).

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


6
Немного иллюстративной математики: 10 МБ Tile * s дают вам квадрат с 1619 плитками на сторону. Оригинальные карты Zelda были 256 плитами на длинной стороне и менее чем в два раза меньше, чем на короткой стороне, так что ваша карта могла быть более чем в 36 раз больше, чем первая Zelda с таким использованием памяти. Вы действительно готовы сделать столько контента ? (№)

@ user744 Этот комментарий невероятно вводит в заблуждение. Чтобы создать карту, вам нужно больше, чем просто указатели на плитки. Вы должны хранить данные, которые содержат плитки также. Не каждая 2D игра имеет заданное количество предопределенных фиксированных плиток.
Йерун

5

Лично я бы построил карту, используя специальный редактор плиток, такой как TileEd . Этот подход дает несколько преимуществ:

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

Я советую вам избегать загрузки битов карты во время игры, чтобы избежать задержки. Как упоминалось ранее, в этом не должно быть необходимости, поскольку вы, вероятно, сможете хранить лист плитки в памяти. Когда персонаж входит в другую часть "мира", вы можете поменять лист плитки другим (например, снежные плитки заменены пустынными).

Размывание плиток на экране, вероятно, самый быстрый способ визуализации вашей карты. Я не знаю SFML, но из документации на их сайте вы должны заглянуть в Spriteкласс или использовать Copyфункцию Imageкласса.

Обновление: я только что прочитал некоторые документы SFML, и вам определенно следует использовать Drawableили Spriteвместо манипулирования изображениями для повышения производительности. По-видимому, есть загрузчик Tiled SFML . Это, вероятно, хороший способ быстро запустить что-то.


1

Начните с создания карты, размер которой необходим, чтобы рассказать историю, которую вы хотите рассказать в игре. Проведите тестирование на машине с минимальными требованиями, необходимыми для того, чтобы люди могли играть в вашу игру Если это слишком медленно, профилируйте и оптимизируйте.


0

На мой взгляд, лучше всего использовать 2D-массив отдельных плиток. Вы можете иметь всю большую большую карту в виде одного 2D-массива и рисовать только ту ее часть, которая должна отображаться в любой момент времени. Ниже приведен пример использования массива 2D-карт с библиотекой игр HTML5 tabageos (tbgs.js); http://actiontad.com/tabageosHTML5/Examples/BlitMathCameraAndTravelers/


-3

Если вы не планируете перестроить Ultima-Online (Fallout 3 или Oblivion), нет никаких причин, по которым мир должен быть цельным. Baldur's Gate и Icewind Dale - две игры, которые приходят на ум и реализуют эффективные карты, которые не отвлекают от игрового процесса.

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

Все, что я могу вам сказать, это то, что я пишу небольшую библиотеку Obj-C для iPhone, которая берет набор плиток 32x32 и рисует его в NSImage. Я получаю около 10 кадров в секунду таким образом, и мне, вероятно, следует использовать OpenGL, но мне нужно перерисовать только, если персонаж выходит из прямоугольника.

Вы должны разбить карту на 9 размеров экрана (для меня это 960x640 блоков), поэтому, если персонаж выходит из центрального блока, я перерисовываю 9 экранов в большое изображение (около 1,2 МБ - дает много комната под лимитом 20 МБ на iPhone 3G). Это происходит довольно медленно (намного медленнее, чем 10 кадров в секунду), поэтому перерисовка не заметна во время игры.

Я, скорее всего, перейду на OpenGL ES в какой-то момент, но сейчас он работает нормально.


[РЕДАКТИРОВАТЬ]

Позвольте мне уточнить.

Алгоритм рисования для 9-экранного фона занимает 0,1 секунды (10 кадров в секунду). Если ваш игрок не может пройти весь экран менее чем за одну десятую секунды, перерисовка должна быть незаметной во время игры.


Тот факт, что 10 к / с приемлемо для вашей игры, не делает ее хорошей идеей, особенно для устройств с ограничением мощности, таких как iPhone. Вы могли бы делать нулевые перерисовки, позволить стороне графического процессора обрабатывать растеризацию, и фактически позволить программе провести некоторое время в спящем режиме, чтобы телефон не перегрелся или не разрядился от батареи.

@ Джо Рэшниг ... ??? Я сказал, что он рисует по требованию, когда игрок перемещает экран, в противном случае фоновое изображение для UIImageView не перерисовывается , тем самым экономя вычислительную мощность. Ваш комментарий не имеет смысла.
Стивен Фурлани

Я не претендую на фпс, который требует ваша игра. Я говорю, OpenGL может обеспечить 60fps для такой вещи тривиально (на самом деле, вы даже не говорите о «перерисовках» со статическими сценами и OpenGL) - если вам нужно только 10fps, то использование OpenGL позволит вам не тратить заряд батареи на другие "50 кадров". Ваш метод рисования является расточительным в мире с ускорением графического процессора. Это, вероятно, нормально на ПК, но не когда вы разряжаете батарею.

@ Джо, я все еще не уверен, что ты говоришь. Это рисует изображение. Затем изображение остается в одиночестве, пока игрок не достигнет границы, а затем повторно рисует новое изображение. Как это тратит время автономной работы? Он «рисует» только по требованию, а в остальное время вид рисуется с использованием собственного алгоритма рисования UIImageView.
Стивен Фурлани
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.