Scegli tessera in base alle tessere adiacenti


10

Sto lavorando a un editor di mappe piastrellato e devo scegliere automaticamente i riquadri, in base ai riquadri adiacenti. Ad esempio, quando si posiziona una tessera strada, accanto a un'altra tessera strada, i due devono essere orientati in modo da formare una strada continua. Se ci sono altre strade intorno a loro, potremmo aver bisogno di usare le tessere d'angolo o di intersezione.

Qualcuno può raccomandare alcuni algoritmi per farlo? Il gioco utilizza una mappa piastrellata quadrata a 8 direzioni.


Non puoi semplicemente esaminare tutte le 8 tessere circostanti ogni volta che l'utente mette una nuova tessera e orientare di conseguenza la nuova tessera? Ovviamente dovrai memorizzare alcune informazioni extra su ogni riquadro come orientamento e tipo.
XiaoChuan Yu,

Sto esaminando tutte le tessere circostanti, ma non sapevo come gestire tutte le combinazioni di tessere. Ad esempio, hai sette possibili tessere tra cui scegliere (orizzontale, verticale, quattro angoli e una croce). Ho pensato di usare complicate istruzioni switch, ma mi è sembrato sbagliato.
alekop,

Risposte:


18

Forse è così che viene fatto in genere. Hai la tua lista di tessere diverse che rappresentano una tessera stradale in tutti i loro possibili orientamenti. Da sinistra a destra, tutti e quattro gli angoli, dall'alto verso il basso, qualunque cosa. Ora indicizzerai tutte quelle tessere con un byte ciascuna. 8 bit, uno per ogni direzione. Questo potrebbe essere in una hashmap o in base al nome del file ... comunque tu voglia farlo.

Quindi hai questo:

inserisci qui la descrizione dell'immagine

Il codice byte per il riquadro sopra è 00000000 . Quindi la tua tessera che va da sinistra a destra (o da destra a sinistra) è così:

inserisci qui la descrizione dell'immagine

Il codice byte per quel riquadro è 10001000 o 136. Come altro esempio, diamo un'occhiata a un incrocio a tre vie:

inserisci qui la descrizione dell'immagine

Il codice byte per quel riquadro è 10101000 .

Probabilmente vedi dove sto andando. Si impostano le posizioni dei bit nel byte che rappresentano le connessioni. Questo è molto meglio che provare a fare qualche grande catena if / else che ho visto prima. Quando stai cercando di posizionare una tessera, esamina le tessere attorno a essa e crea un byte lungo la strada. Imposta 1 per le tessere che hanno strade (o qualunque cosa tu stia cercando di connettere) e 0 per le tessere che non hanno. Al termine, avrai il codice byte per il riquadro esatto di cui hai bisogno.

Si noti che quando si creano gli asset è possibile riutilizzarli molti semplicemente ruotando e assegnando il codice byte corretto ad esso.

EDIT : immagini aggiornate per essere meno schifose. Sì, quelli sono meglio di prima.


Molto bella! Semplice ed efficiente L'unica cosa che non capisco è come stai ottenendo quelle maschere bit. Ad esempio, come si ottiene una maschera di bit di 17 dai numeri 3 e 7?
alekop,

Non importa, vedo cosa stai facendo. Stai impostando i bit 3 e 7, ma stai contando da sinistra, anziché da destra.
alekop,

Oh wow, che imbarazzo. Ho fatto confondere la mia Endianness . È stato un incidente, lo risolverò!
MichaelHouse

Ottimo, ora il mio commento non ha senso! : p Sto scherzando, grazie per la risposta. Questo è esattamente quello che stavo cercando.
alekop,

1
Buona spiegazione Ho un post sul blog che copre la stessa tecnica con il codice effettivo e la risoluzione delle piastrelle: kitsu.github.io/2016/07/18/roguelike-project-05
kitsu.eb

3

Ti consiglio di dare un'occhiata a questa utile pagina per ulteriori informazioni, in quanto fornisce molti dettagli su praticamente ogni aspetto di ciò che stai facendo, nonché alcune potenziali ottimizzazioni: http://www.angryfishstudios.com / 2011/04 / avventure-in-bitmasking /

Il tldr è che si esegue una query su ciascuna cella adiacente e si memorizza la combinazione in un bitfield / byte, quindi si passa attraverso una mappa che converte un numero da 0 ~ 255 in un valore da 0 ~ 47, che corrisponde a un'immagine unica.

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.