Come gestire un mondo a blocchi come Minecraft


9

Voglio scrivere un gioco semplice con un mondo a blocchi come in Minecraft. La mia domanda teorica è qual è il modo migliore per gestire le informazioni di questo blocco durante il gioco. La mia prima idea è stata una vasta gamma, ma credo che questo finirà la memoria. Forse devo solo caricare i blocchi vicino al giocatore.

Come posso gestire il caricamento delle informazioni di blocco necessarie da un file e la conservazione solo di quelle necessarie in memoria?


2
Minecraft carica il mondo in cubi abbastanza grandi chiamati Chunks, non tutti in una volta. Non sono sicuro dei dettagli esatti. La fonte di Minecraft è abbastanza facile da ottenere se vuoi dare un'occhiata a come è andata.
ratbum,

Dai un'occhiata al wiki di minecraft: minecraftwiki.net/wiki/Chunk
tom van green

Conoscevo già pezzi di Minecraft, ma grazie comunque.
danijar,

Questa è una domanda complessa non adatta allo scopo di questo blog.

Risposte:


9

Esistono un paio di modi diversi per archiviare i dati di un gioco con blocchi come Minecraft.

Il modo in cui credo che Minecraft lo faccia è rompere il mondo nei pezzi 16x16x256. I pezzi attorno al giocatore vengono caricati in memoria quando il giocatore inizia il gioco, quindi un filo di sfondo carica di più mentre cammini. Ecco un video che lo mostra: http://www.youtube.com/watch?v=oR_ZdJH9eho .

Un altro modo per farlo è quello di spezzare il mondo in un Octree. Michael Goodfellow ha scritto un blog sull'implementazione di un mondo cubo con questa struttura di dati: http://www.sea-of-memes.com/LetsCode1/LetsCode1.html . Octree è bello perché ti dà un po 'di compressione integrata, ma probabilmente sarà un po' più difficile lavorare con un array.

A proposito di mantenere in memoria solo "quelli necessari?" Questo è un po 'più difficile poiché devi chiedere cosa è "necessario". Se hai NPC che vivono in un'altra parte del mondo con l'intelligenza artificiale che interagisce con l'ambiente, allora "hai bisogno" di molto più mondo di essere nella memoria. I dati del mondo Voxel possono diventare molto grandi molto velocemente, quindi è meglio cercare di mantenere la minima quantità possibile in memoria. (IE, hanno solo NPC vicino al giocatore).

Il motore grafico "avrà bisogno" di ogni blocco non completamente circondato da altri blocchi non trasparenti. Il solito modo per rendere il mondo è costruire una singola mesh che contenga i vertici di ogni blocco visibile. Questo è molto più veloce da disegnare poiché stai effettuando solo 1 chiamata ai metodi di disegno per 65.536 blocchi (in blocchi di dimensioni Minecraft). Poiché il motore grafico dovrà creare questa mesh, in genere deve conoscere tutti i cubi in un blocco. Nota che questo è il motivo per cui quando vedi attraverso il pavimento in Minecraft, gran parte del mondo è invisibile. Questo perché ogni blocco circondato da tutti e sei i lati viene saltato. Credo che Minecraft riduca anche il numero di vertici combinando i lati orizzontali dello stesso tipo di trama in una casella con la trama ripetuta.

Il mio consiglio sarebbe di andare con i pezzi 16x16x256. Conservali in un array poiché avrai bisogno di iterazione e modifica rapide grazie alla costruzione della mesh e della logica di gioco (rilevamento delle collisioni, aggiunta / rimozione di blocchi, ecc.). Quindi carica quanti più pezzi in un cerchio attorno al giocatore che puoi. Ridimensiona il numero di blocchi su o giù per computer migliori o peggiori.

Il caricamento di Chunks sarà un grande successo per le prestazioni, quindi inseriscilo in un thread che lo esegue nel tempo. Fallo in modo da poter caricare completamente 3 nuovi pezzi durante il tempo impiegato da un giocatore a camminare da un'estremità all'altra.


Grazie! Non c'è nulla sull'intelligenza artificiale perché sto scrivendo un client per un MMO. Il calcolo degli NPC viene eseguito dal server. Un'aggiunta: non "ogni blocco non completamente circondato da altri blocchi non trasparenti" è necessario al motore grafico. Se ci sono delle caverne il giocatore non può vedere che non sono importanti. ;-)
danijar,

2
Informazioni sulle grotte che il giocatore non può vedere ... Penso che utilizzi meno prestazioni per disegnare le caverne piuttosto che per determinare se la caverna è stata completamente bloccata. E se non disegni grotte, se rimuovi un blocco potresti potenzialmente rigenerare la mesh per più blocchi anziché solo uno. Sarebbe bello trovare un modo per escludere le grotte, non riesco proprio a pensare a un modo per farlo in modo efficiente: D.
Thomas Marnell,

3

Potrei non avere il modo migliore di spiegarlo, ma ci proverò.

Penso che il modo migliore per capire come renderlo più efficiente sia capire Voxels. Minecraft è basato su voxel, usa solo cubi invece di sfere, ecc., Ecc.

Fondamentalmente un voxel è una forma 3D che può avere un volume modificato dinamicamente e quando il volume cambia, così fa la forma. Un pezzo è un insieme di voxel X per X per X. Ad esempio, puoi avere un blocco che ha 16x16x16 voxel e quindi puoi avere un numero X di blocchi. Avrai una distanza impostata, che se il giocatore è più lontano di N da qualsiasi blocco, non includerli nei tuoi calcoli. Questo è un po 'simile alle distanze di ritaglio, ma dovrebbe applicarsi anche a ciascun pezzo. In questo modo, puoi averlo in modo da poter avere sempre il tuo giocatore al centro di un gruppo di, diciamo, 3x3 set di pezzi.

Quindi quello che avresti è una classe per gestire i singoli Voxel. Lo chiameremo Voxel_cl. E poi avresti una classe per gestire il pezzo di voxel, chiamato Chunk_cl. E poi avresti qualche classe mondiale che genera tutti i blocchi che genererebbero i voxel, chiamati World_cl.

Quindi ora invece di una vasta gamma di tutto, avresti una serie di 9 blocchi in qualsiasi momento e nella classe chunk, avresti una matrice di 4096 voxel.

Questa è una spiegazione piuttosto semplice. Attualmente sto lavorando a qualcosa usando voxel, quindi ho pensato che avrei inserito il mio input = -)

Per ulteriori informazioni sui voxel, consultare http://en.wikipedia.org/wiki/Marching_cubes


3
Marching Cubes riguarda la visualizzazione di voxel. E Minecraft non lo usa nemmeno; disegna solo cubi, che è esattamente ciò che Marching Cubes non sta facendo.
Nicol Bolas,

Grazie per la tua spiegazione! Non avevo mai sentito parlare di Voxels prima e sembra molto importante per il mio progetto. Ma ho ancora una domanda.
danijar,

Comprendo la creazione di una matrice di blocchi vicini in cui ogni elemento contiene una matrice dei voxel di questo blocco. Ma poi ho bisogno di gestire la modifica dell'array di pezzi quando il giocatore si sposta in giro per il mondo. Devo leggere i blocchi necessari dal file di salvataggio? O c'è un buon modo per tenerli in memoria?
danijar,

2
@danijar Solo qualche curiosità, pixel è l'abbreviazione di "elemento immagine", voxel è formato allo stesso modo da "elemento volume". Non che abbia importanza per nulla, ma dal momento che non avevi mai sentito il termine voxel prima che pensassi che potesse interessarti.
Daniel Carlsson,

1

Potresti provare a rendere solo le superfici visibili, il computer gestisce i dati dei blocchi in background, mentre il renderer funziona solo con ciò che vedi. Pezzi 8x8 sarebbero più facili da gestire.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.