Как обращаться с Блочным Миром, как Minecraft

9

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

Как я могу справиться с загрузкой необходимой информации блока из файла и хранением только необходимой информации в памяти?

Данияр
источник
2
Minecraft загружает мир довольно большими кубами, называемыми чанками, причем не все сразу. Я не уверен в точных деталях. Источник Minecraft довольно легко достать, если вы хотите посмотреть, как все прошло.
ratbum
Взгляните на майнкрафт вики: minecraftwiki.net/wiki/Chunk
Том ван Грин
Я уже знал о кусках в Minecraft, но все равно спасибо.
Данияр
Это сложный вопрос, который не подходит для данного блога.

Ответы:

9

Есть несколько разных способов хранения данных для игры с блоками вроде Minecraft.

То, как Майнкрафт делает это, разделяет мир на куски размером 16x16x256. Куски вокруг игрока загружаются в память, когда игрок запускает игру, затем фоновая нить загружается больше, когда вы ходите вокруг. Вот видео, которое показывает это: http://www.youtube.com/watch?v=oR_ZdJH9eho .

Еще один способ сделать это - разбить мир на октри. Майкл Гудфеллоу написал блог о реализации мира кубов с такой структурой данных: http://www.sea-of-memes.com/LetsCode1/LetsCode1.html . Octree хорош тем, что дает вам некоторую встроенную компрессию, но работать с Array, вероятно, будет немного сложнее.

О хранении "только необходимых в памяти?" Это немного сложнее, так как вы должны спросить, что "нужно". Если у вас есть неигровые персонажи, которые живут в другой части мира с ИИ, который взаимодействует с окружающей средой, то вам «нужно» гораздо больше мира, чтобы быть в памяти. Данные о мире вокселов могут быть очень большими и очень большими, поэтому лучше постараться сохранить в памяти как можно меньше данных. (IE, только NPC рядом с игроком).

Графическому движку «понадобится» каждый блок, не полностью окруженный другими непрозрачными блоками. Обычный способ визуализации мира - это создание единой сетки, которая содержит вершины для каждого видимого блока. Рисовать это намного быстрее, поскольку вы делаете только 1 вызов методов рисования для 65 536 блоков (в кусках размера Minecraft). Так как графический движок должен будет построить эту сетку, он обычно должен знать все кубы в чанке. Обратите внимание, что именно поэтому, когда вы видите сквозь пол в Minecraft, большая часть мира невидима. Это потому, что каждый блок, который окружен со всех шести сторон, пропускается. Я полагаю, что Minecraft также уменьшает количество вершин, объединяя горизонтальные стороны одного и того же типа текстуры в одну рамку с повторением текстуры.

Мой совет - использовать куски 16x16x256. Храните их в массиве, так как вам потребуется быстрая итерация и редактирование из-за построения сетки и игровой логики (обнаружение столкновений, добавление / удаление блоков и т. Д.). Затем загрузите как можно больше кусков в круг вокруг игрока. Увеличьте или уменьшите количество фрагментов для лучшего или худшего компьютера.

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

Томас Марнелл
источник
Спасибо! В AI нет ничего, потому что я пишу клиент для MMO. Расчет NPC осуществляется сервером. Одно дополнение: графическому движку не требуется «каждый блок, не полностью окруженный другими непрозрачными блоками». Если есть пещеры, игрок не может видеть, что они не важны. ;-)
Данияр
2
О пещерах, которые игрок не может увидеть ... Я думаю, что он использует меньше производительности, чтобы просто нарисовать пещеры, чем определить, была ли пещера полностью заблокирована. И если вы не рисуете пещеры, то, если вы удалите блок, вам, возможно, придется заново сгенерировать сетку для нескольких кусков вместо одного. Было бы здорово найти способ исключить пещеры, я просто не могу придумать, как сделать это эффективно: D.
Томас Марнелл
3

Возможно, у меня нет лучшего способа объяснить это, но я постараюсь.

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

По сути, воксел - это трехмерная фигура, которая может иметь динамически изменяемый объем, а при изменении объема - и форма. Чанк - это набор вокселей «X за X за X». Так, например, у вас может быть чанк с 16x16x16 вокселями, а затем у вас может быть X чанков. У вас будет установлено расстояние, которое, если игрок находится дальше, чем N, от любых кусков, не включайте их в свои расчеты. Это похоже на расстояние отсечения, но также должно применяться к каждому фрагменту. Таким образом, вы можете сделать так, чтобы ваш игрок всегда находился в центре Chunk набора, скажем, 3x3 Chunks.

Итак, у вас есть класс для работы с отдельными Voxels. Мы назовем это Voxel_cl. И тогда у вас будет класс для обработки фрагментов вокселей, который называется Chunk_cl. И тогда у вас будет некоторый мировой класс, который генерирует все чанки, которые будут генерировать воксели, называемый World_cl.

Так что теперь вместо огромного массива всего, у вас будет массив из 9 блоков в любой момент времени, а в классе блоков вы получите массив из 4096 вокселей.

Обратите внимание, что это довольно простое объяснение. В настоящее время я работаю над чем-то, используя воксели, поэтому я решил добавить свои данные = -)

Для получения дополнительной информации о вокселях, проверьте http://en.wikipedia.org/wiki/Marching_cubes

Mungoid
источник
3
Марширующие кубики - это визуализация вокселей. И Minecraft даже не использует его; он просто рисует кубики, а это именно то, чего не делают Марширующие кубы .
Никол Болас
Спасибо за ваше объяснение! Я никогда не слышал о Voxels прежде, и это кажется очень важным для моего проекта. Но у меня остался вопрос.
Данияр
Я понимаю создание массива близких чанков, где каждый элемент содержит массив вокселей этого чанка. Но тогда мне нужно справиться с изменением массива чанков, когда игрок перемещается по миру. Нужно ли читать нужные фрагменты из файла сохранения? Или есть хороший способ сохранить их в памяти?
Данияр
2
@danijar Просто некоторые мелочи, пиксель является сокращением от «элемента изображения», воксель формируется так же, как «элемент объема». Не то чтобы это что-то значило, но так как вы не слышали термин «воксель» до того, как я подумал, он может вас заинтересовать.
Даниэль Карлссон
1

Вы можете попытаться просто визуализировать видимые поверхности, компьютер обрабатывает данные блоков в фоновом режиме, в то время как средство визуализации работает только с тем, что вы видите. Кускам 8х8 было бы легче с ним справиться.

Гэндальф
источник