J'ai trouvé une approche simple et alternative qui utilise la même logique qu'un damier ordinaire. Il crée un effet d'accrochage à la grille avec des points au centre de chaque tuile et à chaque sommet (en créant une grille plus serrée et en ignorant les points alternés).
Cette approche fonctionne bien pour des jeux comme Catan, où les joueurs interagissent avec les tuiles et les sommets, mais n'est pas adaptée aux jeux où les joueurs n'interagissent qu'avec les tuiles, car elle renvoie le point central ou le sommet dont les coordonnées sont les plus proches, plutôt que la tuile hexagonale les coordonnées sont à l'intérieur.
La géométrie
Si vous placez des points dans une grille avec des colonnes qui font le quart de la largeur d'une tuile et des lignes qui font la moitié de la hauteur d'une tuile, vous obtenez ce modèle:
Si vous modifiez ensuite le code pour ignorer chaque deuxième point dans un motif en damier (sauter if column % 2 + row % 2 == 1
), vous vous retrouvez avec ce motif:
la mise en oeuvre
Avec cette géométrie à l'esprit, vous pouvez créer un tableau 2D (comme vous le feriez avec une grille carrée), en stockant les x, y
coordonnées de chaque point de la grille (à partir du premier diagramme) - quelque chose comme ceci:
points = []
for x in numberOfColumns
points.push([])
for y in numberOfRows
points[x].push({x: x * widthOfColumn, y: y * heightOfRow})
Remarque: Comme d'habitude, lorsque vous créez une grille autour des points (plutôt que de placer des points sur les points eux-mêmes), vous devez décaler l'origine (en soustrayant la moitié de la largeur d'une colonne x
et la moitié de la hauteur d'une ligne y
).
Maintenant que votre tableau 2D ( points
) est initialisé, vous pouvez trouver le point le plus proche de la souris comme vous le feriez sur une grille carrée, n'ayant qu'à ignorer tous les autres points pour produire le motif dans le deuxième diagramme:
column, row = floor(mouse.x / columnWidth), floor(mouse.y / rowHeight)
point = null if column % 2 + row % 2 != 1 else points[column][row]
Cela fonctionnera, mais les coordonnées sont arrondies au point le plus proche (ou aucun point) en fonction du rectangle invisible dans lequel se trouve le pointeur. Vous voulez vraiment une zone circulaire autour du point (donc la plage d'accrochage est égale dans toutes les directions). Maintenant que vous savez quel point vérifier, vous pouvez facilement trouver la distance (en utilisant le théorème de Pythagore). Le cercle implicite devrait toujours tenir à l'intérieur du rectangle de délimitation d'origine, limitant son diamètre maximal à la largeur d'une colonne (un quart de la largeur d'une tuile), mais qui est toujours assez grand pour bien fonctionner en pratique.