Я хочу написать простую игру с блочным миром, как в Minecraft. Мой теоретический вопрос заключается в том, как лучше всего обрабатывать информацию этого блока во время игры. Моей первой идеей был огромный массив, но я думаю, что это приведет к нехватке памяти. Возможно, мне нужно загружать блоки только рядом с плеером.
Как я могу справиться с загрузкой необходимой информации блока из файла и хранением только необходимой информации в памяти?
c++
voxels
minecraft-modding
data
Данияр
источник
источник
Ответы:
Есть несколько разных способов хранения данных для игры с блоками вроде 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 новых чанка за время, которое требуется игроку, чтобы пройти от одного конца чанка к другому.
источник
Возможно, у меня нет лучшего способа объяснить это, но я постараюсь.
Я думаю, что лучший способ понять, как сделать его более эффективным, это понять 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
источник
Вы можете попытаться просто визуализировать видимые поверхности, компьютер обрабатывает данные блоков в фоновом режиме, в то время как средство визуализации работает только с тем, что вы видите. Кускам 8х8 было бы легче с ним справиться.
источник