Memorizzare una griglia esadecimale


10

Ho creato un piccolo framework a griglia esadecimale per Unity3D e sono arrivato al seguente dilemma. Questo è il mio sistema di coordinate (preso da qui ):

inserisci qui la descrizione dell'immagine

Funziona abbastanza bene, tranne per il fatto che non ho idea di come conservarlo. Inizialmente intendevo archiviarlo in un array 2D e utilizzare immagini per generare le mie mappe.

Un problema era che aveva valori negativi (questo era facilmente risolto compensando un po 'le coordinate).

Tuttavia, a causa di questo sistema di coordinate, tale immagine o bitmap dovrebbe essere a forma di diamante - e poiché queste strutture sono di forma quadrata, ciò causerebbe molti mal di testa anche se hackerassi qualcosa insieme. C'è qualcosa che mi manca che potrebbe risolvere questo problema? Ricordo di aver visto un post sul forum riguardo a questo nei forum di unità, ma non riesco più a trovare il link.

Scrivere un set di traduttori di coordinate è la migliore soluzione qui?

Se pensate che sarebbe utile, posso pubblicare codice e immagini del mio problema.


1
Non puoi semplicemente salvare immagini PNG trasparenti attorno agli esagoni?
Markus von Broady,

Il mio problema principale con il salvataggio in png e array è la quantità di "spazi bianchi" che dovrebbero contenere per mantenere intatto questo sistema di coordinate.
PeeC,

1
Se "spazio bianco" significa pixel trasparenti, perché la sua quantità è un problema?
Markus von Broady,

Questo è un ottimo punto. La maggior parte dei formati di immagine non spreca molta memoria per la memorizzazione di schemi ripetuti. Ma ancora, un po 'mi infastidisce che per memorizzare questa mappa sto usando questa quantità di memoria (pixel grigi sono lo spazio vuoto, altri colori sono validi coordinate esadecimali).
PeeC,

1
Oh, stai memorizzando i dati della griglia, non le immagini dei riquadri! Perché non vuoi semplicemente salvare le tue strutture di dati (griglia) in un file binario, o codificarlo usando ad esempio JSON e salvarlo in un file di testo? Tuttavia, non conosco le capacità di Unity. Inoltre, potresti voler confermare questo, ma credo che un'area dello stesso colore sia ottimizzata (compressa) in formato PNG.
Markus von Broady,

Risposte:


9

Le coordinate del parallelogramma che stai usando sono più facili da lavorare, ma hanno lo svantaggio di essere strane per le mappe rettangolari. Un approccio è quello di memorizzarlo con le coordinate di offset, ma in realtà utilizzare le coordinate del parallelogramma nella logica di gioco.

Osservazione: in ogni riga della mappa, i dati della griglia sono contigui. Tutto lo spazio sprecato è a sinistra e a destra.

Soluzione: all'interno di quella riga, archiviare i dati iniziando dalla colonna più a sinistra anziché dalla colonna contrassegnata con 0. Calcolare la prima colonna della mappa rettangolare nel sistema di coordinate , quindi sottrarla dalla coordinata della colonna per determinare dove va nell'array. Questo funziona anche per coordinate di colonna negative.

Esegui la conversione nel getter e nel setter per la mappa, con qualcosa del genere:

inline function get(q, r) {
    first_column_in_this_row = -floor(q/2);
    return array[r][q - first_column_in_this_row];
}

Dovrai modificarlo per lavorare con la tua scelta di coordinate e mappa (presta attenzione a una differenza). In alcuni layout dovrai compensare le colonne per riga anziché viceversa.

Puoi usare lo stesso trucco per creare mappe di altre forme; non è limitato ai rettangoli.

Se stai usando C o C ++ puoi usare l'aritmetica del puntatore per renderlo più veloce. Invece di memorizzare una matrice di puntatori in matrici, memorizzare una matrice di puntatori che sono stati regolati da first_column_in_row. (Potrebbe non essere portatile)


Questo funziona per quanto posso dire, tuttavia la matematica era davvero strana. Dopo aver provato diverse equazioni che avevano senso nella mia testa, mi sono accontentato yIndex = y-((x%2==0)?(x/2-x):(-x/2)-1)dopo alcune prove ed errori. Non ho idea di come funzioni duro.
PeeC,

Fallo yIndex = y-((x%2==0)?(-x/2):(-x/2)-1). x / 2 è tutto basato su numeri interi tra cui quindi non è necessario eseguire il floor.
PeeC,

6

Personalmente, preferirei la semplicità piuttosto che risparmiare memoria. Non ottimizzare fino a quando non è necessario!

Se sei ancora intenzionato a salvare qualche byte, ecco come puoi farlo:

inserisci qui la descrizione dell'immagine

  1. Taglia il parallelogramma a metà per formare due triangoli retti
  2. Riorganizza i due triangoli per formare un rettangolo.
  3. (Nota: ho aggiunto la striscia di buffer verde in modo che la matematica funzioni bene.)

Codice Python per mappare le coordinate rettangolari alle coordinate del parallelogramma e ritorno:

# Height of rectangle
H = 15

def r2p(x, y):
"rectangle to parallelogram"
if y < -x/2 + H:
    y = y + H
return (x - 1, y)

def p2r(x,y):
"parallelogram to rectangle"
if y >= H:
    y = y - H
return (x + 1, y)

2
potresti anche spostare i pixel verticalmente verso il basso - sull'immagine che sarebbeoffsetY = Math.floor ( (x+1)/2 )
Markus von Broady,

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.