Ho trovato un approccio semplice e alternativo che utilizza la stessa logica di una normale scacchiera. Crea un effetto snap-to-grid con punti al centro di ogni riquadro e ad ogni vertice (creando una griglia più stretta e ignorando i punti alternati).
Questo approccio funziona bene per giochi come Catan, in cui i giocatori interagiscono con tessere e vertici, ma non è adatto a giochi in cui i giocatori interagiscono solo con tessere, in quanto restituisce il punto centrale o il vertice a cui le coordinate sono più vicine, anziché quale tessera esagonale il le coordinate sono all'interno.
La geometria
Se si posizionano punti in una griglia con colonne di un quarto della larghezza di una piastrella e righe che sono la metà dell'altezza di una piastrella, si ottiene questo modello:
Se poi modifichi il codice per saltare ogni secondo punto in uno schema a scacchiera (salta if column % 2 + row % 2 == 1
), finisci con questo schema:
Implementazione
Con questa geometria in mente, puoi creare un array 2D (proprio come faresti con una griglia quadrata), memorizzando le x, y
coordinate per ciascun punto della griglia (dal primo diagramma) - qualcosa del genere:
points = []
for x in numberOfColumns
points.push([])
for y in numberOfRows
points[x].push({x: x * widthOfColumn, y: y * heightOfRow})
Nota: come al solito, quando si crea una griglia attorno ai punti (anziché posizionare i punti sui punti stessi), è necessario sfalsare l'origine (sottraendo metà della larghezza di una colonna x
e metà dell'altezza di una riga day
).
Ora che hai il tuo array 2D ( points
) inizializzato, puoi trovare il punto più vicino al mouse proprio come faresti su una griglia quadrata, dovendo ignorare ogni altro punto per produrre il modello nel secondo diagramma:
column, row = floor(mouse.x / columnWidth), floor(mouse.y / rowHeight)
point = null if column % 2 + row % 2 != 1 else points[column][row]
Funzionerà, ma le coordinate vengono arrotondate al punto più vicino (o nessun punto) in base al rettangolo invisibile in cui si trova il puntatore. Volete davvero una zona circolare attorno al punto (quindi l'intervallo di snap è uguale in ogni direzione). Ora che sai quale punto controllare, puoi facilmente trovare la distanza (usando il Teorema di Pitagora). Il cerchio implicito dovrebbe comunque adattarsi all'interno del rettangolo di delimitazione originale, limitando il suo diametro massimo alla larghezza di una colonna (un quarto della larghezza di una piastrella), ma è ancora abbastanza grande da funzionare bene nella pratica.