Ich habe einen einfachen, alternativen Ansatz gefunden, der dieselbe Logik wie ein normales Schachbrett verwendet. Es wird ein Rastereffekt mit Punkten in der Mitte jeder Kachel und an jedem Scheitelpunkt erstellt (indem ein engeres Raster erstellt und abwechselnde Punkte ignoriert werden).
Dieser Ansatz eignet sich gut für Spiele wie Catan, bei denen Spieler mit Kacheln und Scheitelpunkten interagieren. Er eignet sich jedoch nicht für Spiele, bei denen Spieler nur mit Kacheln interagieren, da er zurückgibt, welchem Mittelpunkt oder Scheitelpunkt die Koordinaten am nächsten liegen und nicht welcher sechseckigen Kachel Koordinaten sind innerhalb.
Die Geometrie
Wenn Sie Punkte in einem Raster mit Spalten platzieren, die viertel der Breite einer Kachel entsprechen, und Zeilen, die die halbe Höhe einer Kachel haben, erhalten Sie folgendes Muster:
Wenn Sie dann den Code so ändern, dass jeder zweite Punkt in einem Schachbrettmuster übersprungen wird (Überspringen if column % 2 + row % 2 == 1
), erhalten Sie folgendes Muster:
Implementierung
Unter Berücksichtigung dieser Geometrie können Sie ein 2D-Array erstellen (genau wie bei einem quadratischen Raster) und die x, y
Koordinaten für jeden Punkt im Raster (aus dem ersten Diagramm) speichern - ungefähr so:
points = []
for x in numberOfColumns
points.push([])
for y in numberOfRows
points[x].push({x: x * widthOfColumn, y: y * heightOfRow})
Hinweis: Wenn Sie ein Raster um die Punkte erstellen (anstatt Punkte an den Punkten selbst zu platzieren), müssen Sie wie gewohnt den Ursprung versetzen (indem Sie die Hälfte der Breite einer Spalte von x
und die Hälfte der Höhe einer Zeile von subtrahieren y
).
Nachdem Sie Ihr 2D-Array ( points
) initialisiert haben, können Sie den Punkt finden, der der Maus am nächsten liegt, genau wie in einem quadratischen Raster. Sie müssen nur jeden anderen Punkt ignorieren, um das Muster im zweiten Diagramm zu erstellen:
column, row = floor(mouse.x / columnWidth), floor(mouse.y / rowHeight)
point = null if column % 2 + row % 2 != 1 else points[column][row]
Das wird funktionieren, aber die Koordinaten werden auf den nächsten Punkt (oder keinen Punkt) gerundet, basierend auf dem unsichtbaren Rechteck, in dem sich der Zeiger befindet. Sie möchten wirklich eine kreisförmige Zone um den Punkt (also ist der Fangbereich in jeder Richtung gleich). Nachdem Sie nun wissen, welchen Punkt Sie überprüfen müssen, können Sie die Entfernung leicht ermitteln (mithilfe des Satzes von Pythagoras). Der implizite Kreis müsste immer noch in das ursprüngliche Begrenzungsrechteck passen und seinen maximalen Durchmesser auf die Breite einer Säule (Viertel der Breite einer Kachel) beschränken, aber das ist immer noch groß genug, um in der Praxis gut zu funktionieren.