Як поводитися з блоковим світом, як Minecraft


9

Хочу написати просту гру з блоковим світом, як у Minecraft. Моє теоретичне питання - який найкращий спосіб обробляти інформацію про цей блок під час гри. Моя перша ідея була величезним масивом, але це, можливо, вичерпає пам'ять. Можливо, мені доведеться лише завантажувати блоки біля програвача.

Як я можу впоратися із завантаженням потрібної інформації про блок із файлу та зберіганням лише потрібних у пам'яті?


2
Minecraft завантажує світ досить великими кубиками під назвою Chunks, не всі відразу. Я не впевнений у точних подробицях. Джерело Minecraft досить легко здобути, якщо ви хочете ознайомитись з тим, як цього не було.
ratbum

Погляньте на вікі Minecraft: minecraftwiki.net/wiki/Chunk
tom van green

Я вже знав про шматки в Minecraft, але все одно дякую.
danijar

Це складне питання, яке не підходить для обсягу цього блогу.

Відповіді:


9

Існує кілька різних способів зберігання даних для гри з такими блоками, як Minecraft.

Те, як я вважаю, що Minecraft робить це, розбиває світ у чанах 16x16x256. Шматки навколо програвача завантажуються в пам'ять, коли гравець починає гру, тоді фонова нитка завантажується більше, коли ви ходите. Ось відео, яке показує його: http://www.youtube.com/watch?v=oR_ZdJH9eho .

Ще один спосіб зробити це - розбити світ в Октрисі. Майкл Гудфеллоу написав блог про реалізацію світу кубів за допомогою цієї структури даних: http://www.sea-of-memes.com/LetsCode1/LetsCode1.html . Octree приємний тим, що дає вам трохи вбудованого стиснення, але, можливо, буде трохи складніше працювати з тодішнім масивом.

Про збереження в пам’яті «лише потрібних»? Це трохи складніше, оскільки ви повинні запитати, що "потрібно". Якщо у вас є NPC, які живуть в іншій частині світу з AI, який взаємодіє з навколишнім середовищем, тоді вам "потрібно" набагато більше світу, щоб залишитися в пам'яті. Світові дані Voxel можуть отримувати дуже великі дуже швидко, тому найкраще спробувати зберегти якнайменшу кількість пам'яті. (IE, біля програвача є лише NPC).

Графічному двигуну "знадобиться" кожен блок, не повністю оточений іншими непрозорими блоками. Звичайний спосіб відобразити світ - це побудувати єдину сітку, яка містить вершини для кожного видимого блоку. Це зробити набагато швидше, оскільки ви робите лише 1 виклик методів розіграшу для 65,536 блоків (у шматках розміру Minecraft). Оскільки для створення цієї сітки графічному двигуну знадобиться, він, як правило, повинен знати всі куби в шматок. Зауважте, що саме тому, коли ви бачите крізь підлогу в Minecraft, багато світу невидиме. Це тому, що кожен блок, який оточений з усіх шести сторін, пропускається. Я вважаю, що Minecraft також зменшує кількість вершин, поєднуючи горизонтальні сторони одного типу текстури в одне поле з текстурою, що повторюється.

Моя порада - поїхати з шматками 16x16x256. Зберігайте їх у масиві, оскільки вам знадобиться швидка ітерація та редагування завдяки побудові сітки та логіки гри (виявлення зіткнень, додавання / видалення блоків, тощо). Потім завантажте якомога більше шматочків в коло навколо гравця. Масштабуйте кількість шматочків вгору або вниз для кращих або гірших комп'ютерів.

Завантаження Chunks буде величезним хітом у продуктивності, тому поставте його в нитку, яка виконує його з часом. Зробіть так, щоб ви могли повністю завантажувати 3 нових шматки протягом часу, коли гравцеві потрібно пройтися від одного кінця шматка до іншого.


Дякую! Про AI немає нічого, тому що я пишу клієнта для MMO. Розрахунок NPC проводиться сервером. Одне доповнення: не "кожен блок, не повністю оточений іншими непрозорими блоками", потрібен графічному двигуну. Якщо є печери, гравець не може побачити, що вони неважливі. ;-)
danijar

2
Про печери, які гравець не бачить ... Я думаю, що для мальовування печер використовується менша продуктивність, ніж для визначення того, чи була печера повністю заблокована. І якщо ви не намалюєте печер, то, якщо ви видалили блок, потенційно вам доведеться заново створити сітку для декількох шматочків, а не лише одну. Було б круто знайти спосіб виключення печер, я просто не можу придумати спосіб зробити це ефективно: D.
Томас Марнелл

3

У мене може бути не найкращий спосіб пояснити це, але я спробую.

Я думаю, що найкращий спосіб зрозуміти, як зробити це більш ефективним - це зрозуміти Voxels. Minecraft заснований на вокселі, він просто використовує куби замість сфер тощо, тощо.

В основному воксель - це форма 3D, яка може мати динамічно змінений об'єм і коли гучність змінюється, так само і форма. Chunk - це набір вокселів X на X на X. Наприклад, ви можете мати шматок, який має 16x16x16 вокселів, і тоді ви можете мати X кількість шматочків. У вас буде встановлено відстань, що якщо гравець знаходиться на відстані N від будь-яких шматочків, не включайте їх у свої розрахунки. Це свого роду схоже на відстань відсікання, але його потрібно застосувати і до кожного шматка. Таким чином, ви можете мати його так, що ви завжди можете мати свого гравця в центрі куска, скажімо, 3x3 набору Чанків.

Отже, ви б мали клас для обробки окремих Voxels. Ми будемо називати його Voxel_cl. І тоді у вас був би клас для обробки куска вокселів, який називається Chunk_cl. І тоді у вас буде якийсь світовий клас, який генерує всі фрагменти, які б генерували вокселі, звані World_cl.

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

Зверніть увагу, що це досить просте пояснення. Зараз я працюю над чимось, використовуючи вокселі, тож я зрозумів, що буду кидати свій внесок = -)

Щоб дізнатися більше про вокселі, перегляньте http://en.wikipedia.org/wiki/Marching_cubes


3
Marching Cubes - це візуалізація вокселів. І Minecraft навіть не використовує його; він просто малює кубики, що саме не робить маршових кубів .
Нікол Болас

Дякуємо за ваше пояснення! Я ніколи не чув про Voxels раніше, і це здається дуже важливим для мого проекту. Але у мене зараз питання.
danijar

Я розумію, створюючи масив поблизу фрагментів, де кожен елемент містить масив вокселів цього фрагменту. Але тоді мені потрібно обробляти зміни масиву, коли гравець рухається по всьому світу. Чи потрібно мені читати потрібні фрагменти з файлу збереження? Або є хороший спосіб зберегти їх у пам’яті?
danijar

2
@danijar Просто деякі дрібниці, піксель є коротким для "елемента зображення", воксель формується так само, як "елемент гучності". Не те, що це має значення для будь-чого, але оскільки ви раніше не чули термін воксель, я подумав, що він може вас зацікавити.
Даніель Карлссон

1

Ви можете спробувати просто зробити видимі поверхні візуалізацією, комп'ютер обробляє блоки даних у фоновому режимі, тоді як рендерінг працює лише з тим, що ви бачите. 8x8 шматочки було б простіше впоратися.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.