Il modo migliore per creare una mappa per un gioco 2D?


16

Mi scuso per la parola chiave "migliore" soggettiva.

Io e il mio amico abbiamo iniziato la creazione di un gioco di avventura in 2D. Sarà top-down nello stile di pokemon o zelda (solo la prospettiva). Abbiamo discusso dei metodi per creare una grande mappa del mondo che il giocatore può attraversare senza affaticare le capacità di memoria della nostra macchina.

Il nostro primo impulso è stato quello di creare una grande mappa e un cerchio attorno al giocatore in cui verranno caricati i contenuti. Abbiamo pensato che questo non durerà a lungo e abbiamo deciso di dividere la mappa in sezioni. All'inizio avevamo quattro grandi sezioni, ma ci siamo resi conto che potevamo semplicemente scomporle in molte piccole sezioni.

Ho suonato un po 'di Zelda dal SNES e ho visto che, durante lo spostamento di una mappa, il contenuto poteva essere caricato in quel momento. Quello che voglio dire è, invece di controllare semplicemente un'area rettangolare per caricare i dati, semplicemente sezioniamo la mappa in molti piccoli blocchi che caricano e scaricano i dati mentre ci spostiamo da una porzione di mappa a una porzione di mappa.

Oggi, mi ha detto che voleva creare una semplice mappa di array 2D [LARGHEZZA] [ALTEZZA] che contiene dati su ogni griglia del gioco ed è una costante operazione di salvataggio su disco per i dati di cui non abbiamo bisogno.

Non sono sicuro di queste idee e ho pensato che avrei potuto farlo qui. Qualsiasi link, risorse o tutorial sull'argomento sarebbero molto apprezzati, nonché risposte dirette alla nostra domanda su come farlo in modo efficiente.


Quale macchina stai usando?
David Titarenco,

Finestre con C ++ che utilizzano SFML finora (SFML è soggetto a modifiche; C ++ no). Non miriamo alla portabilità atm.
IAE,

2
Se stai andando per la vecchia scuola di Zelda sul NES, utilizza solo mappe a 1 schermo. Le piccole mappe aiutano i giocatori a focalizzare la portata del loro intento (cioè in una prigione, hai a che fare solo con la tua stanza. In diablo, i mostri non si sono mossi su e giù per i piani) e permettono loro di sentirsi completati se hanno cercato per tutta l'area che giochi open-space come FAllout3 e Oblivion non ti danno.
Stephen Furlani,

Risposte:


27

Prima di tutto, stimare la dimensione della mappa. Non dare per scontato che un "grande mondo" non si adatterà alla memoria. Al giorno d'oggi, una mappa che occupa fino a 10 MB in memoria è assolutamente accettabile e puoi riempire MOLTO in 10 Mb in un semplice mondo 2D basato su piastrelle.

Se hai un mondo davvero grande, la soluzione più efficace è in effetti utilizzare blocchi di mappe. Dividi il tuo mondo in blocchi di dimensioni fisse (diciamo 64x64). Carica blocchi al volo mentre il giocatore si muove, mantenendo almeno un pezzo caricato in tutte le direzioni (ovvero carica il pezzo in cui si trova il giocatore e tutti i suoi vicini).

Per quanto riguarda i blocchi di scarico, puoi scegliere tra diverse strategie. Scaricarsi con impazienza significa scaricare e salvare su disco tutti i blocchi nel momento in cui il giocatore si sposta sufficientemente lontano; ma puoi anche ritardare lo scarico per migliorare le prestazioni (il salvataggio di blocchi, come qualsiasi accesso al disco, è un'operazione costosa).


6
Alcuni calcoli illustrativi: 10 MB di Tile * s ti danno un quadrato con 1619 tessere per lato. Le mappe originali di Zelda erano 256 tessere sul lato lungo e meno della metà sul lato corto - quindi la tua mappa potrebbe essere più di 36 volte più grande delle prime Zelda con quell'uso di memoria. Sei davvero pronto a creare così tanti contenuti ? (No.)

@ user744 Questo commento è incredibilmente fuorviante. Per creare una mappa hai bisogno di qualcosa di più dei semplici puntatori alle tessere. È necessario archiviare anche i dati contenuti nei riquadri. Non tutti i giochi 2D hanno un numero prestabilito di tessere fisse predefinite.
Jeroen,

5

Personalmente, costruivo la mappa usando un editor di tessere designato come TileEd . Questo approccio offre numerosi vantaggi:

  • Utilizza meno risorse. Devi solo caricare un foglio di piastrelle e un file di dati con indici per creare una mappa potenzialmente infinita.
  • Dal momento che la tua mappa sarà divisa in blocchi molto piccoli (a seconda delle dimensioni della piastrella), puoi facilmente aggiungere / rimuovere righe / colonne mentre il personaggio si muove attraverso il mondo.
  • Avere un file di dati che descrive la tua mappa ti consente anche di aggiungere facilmente informazioni sul terreno. Ciò consente diversi tipi di tessere come muri o laghi (cioè ostacoli) o una palude in cui il movimento del personaggio potrebbe essere rallentato ...
  • Infine, una mappa basata su riquadri è anche molto più semplice da modificare e modificare in seguito perché è sempre possibile avviare l'editor, modificare alcune cose e salvare un nuovo file di dati.

Ti consiglio di evitare di caricare bit della mappa durante il gioco per evitare ritardi. Come accennato in precedenza, questo non dovrebbe essere necessario in quanto probabilmente sarai in grado di mantenere il foglio di piastrelle in memoria. Quando il personaggio entra in un'altra parte del "mondo", puoi scambiare il foglio con un altro (es. Tessere da neve sostituite con tessere da deserto).

Blitting i riquadri sullo schermo è probabilmente il modo più veloce per visualizzare la tua mappa. Non conosco SFML, ma dai documenti sul loro sito dovresti guardare la Spriteclasse o usare la Copyfunzione della Imageclasse.

Aggiornamento: ho appena letto alcuni dei documenti SFML e dovresti assolutamente usare Drawableo Spriteinvece di manipolare le immagini per motivi di prestazioni. Apparentemente c'è un caricatore SFML piastrellato là fuori. Questo è probabilmente un buon modo per far funzionare qualcosa velocemente.


1

Inizia facendo della mappa le dimensioni necessarie per raccontare la storia che desideri che il gioco racconti. Prova sulla macchina con le specifiche minime richieste per consentire alle persone di giocare. Se è troppo lento, profila e ottimizza.


0

L'uso di una matrice 2D di singole tessere è la cosa migliore secondo me. Puoi avere l'intera intera mappa di grandi dimensioni come un array 2D e disegnare solo la parte di essa che deve essere visualizzata in un dato momento. Il seguente è un esempio dell'uso di un array di mappe 2D con la libreria di giochi HTML5 tabageos (tbgs.js); http://actiontad.com/tabageosHTML5/Examples/BlitMathCameraAndTravelers/


-3

A meno che tu non stia pianificando di ricostruire l'ultima-online (Fallout 3 o Oblivion), non c'è motivo per cui il mondo debba essere senza soluzione di continuità. Baldur's Gate e Icewind Dale sono due giochi che vengono in mente e che implementano mappe efficaci che non riducono il gameplay.

Certo, hai una potenza di calcolo molto maggiore rispetto a loro, quindi il caricamento delle schermate dovrebbe essere minimo, ma anche Fallout e Oblivion hanno schermate di caricamento per alcune cose.

Tutto quello che posso dirti è che per me sto scrivendo una piccola libreria Obj-C per iPhone che prende un set di tessere 32x32 e lo disegna in un NSImage. In questo modo ottengo circa 10 fps e probabilmente dovrei usare OpenGL, ma ho bisogno di ridisegnare solo se il personaggio esce dal rettangolo.

Dovresti dividere la mappa in 9 dimensioni dello schermo (per me sono 960x640 blocchi) quindi se il personaggio si sposta dal blocco centrale, ridisegno le 9 schermate in un'immagine grande (circa 1,2 MB - dà un sacco di spazio inferiore al limite di 20 MB su iPhone 3G). Ciò accade abbastanza lentamente (molto più lentamente di 10 fps), quindi il ridisegno non è evidente durante il gioco.

Probabilmente passerò a OpenGL ES ad un certo punto, ma per ora funziona bene.


[MODIFICARE]

Mi permetta di chiarire.

L'algoritmo di disegno per lo sfondo a 9 schermate richiede 0,1 secondi (10fps flat-out). A meno che il tuo giocatore non possa attraversare un intero schermo in meno di un decimo di secondo, il ridisegno dovrebbe essere impercettibile durante il gioco.


Solo perché 10 fps è accettabile per il tuo gioco non lo rende una buona idea, soprattutto su un dispositivo con vincoli di potenza come un iPhone. Potresti fare zero ridisegni, lasciare che la GPU gestisca la rasterizzazione e in realtà permetta al programma di passare un po 'di tempo a dormire, in modo che il telefono non si surriscaldi o non si esaurisca la durata della batteria.

@Joe Wreschnig ... ??? Ho detto che si basa su richiesta, quando il giocatore sposta lo schermo, altrimenti l'immagine di sfondo per UIImageView non viene ridisegnata , risparmiando così potenza di elaborazione. Il tuo commento non ha senso.
Stephen Furlani,

Non sto avanzando alcuna richiesta riguardo al fps richiesto dal tuo gioco. Sto dicendo che OpenGL può fornire banalmente 60 fps per una cosa del genere (davvero, non parli nemmeno di "ridisegni" con scene statiche e OpenGL) - se hai solo bisogno di 10 fps, allora usando OpenGL non sprechi la batteria per altri "50 frame". Il tuo metodo di disegno è dispendioso in un mondo con accelerazione GPU. Probabilmente va bene su un PC, ma non quando stai scaricando una batteria.

@Joe, non sono ancora sicuro di quello che stai dicendo. Disegna un'immagine. Quindi l'immagine viene lasciata sola fino a quando il giocatore non raggiunge un limite, quindi disegna una nuova immagine. In che modo spreca la durata della batteria? "Disegna" solo su richiesta e per il resto del tempo la vista viene disegnata usando l'algoritmo di disegno nativo di UIImageView.
Stephen Furlani,
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.