Saya menemukan pendekatan alternatif sederhana yang menggunakan logika yang sama dengan kotak-kotak biasa. Ini menciptakan efek snap-to-grid dengan titik-titik di pusat setiap ubin dan di setiap titik (dengan membuat kotak yang lebih ketat dan mengabaikan titik-titik bergantian).
Pendekatan ini bekerja dengan baik untuk permainan seperti Catan, di mana pemain berinteraksi dengan ubin dan simpul, tetapi tidak cocok untuk permainan di mana pemain hanya berinteraksi dengan ubin, karena mengembalikan titik pusat atau titik koordinat yang paling dekat dengan koordinat, daripada ubin heksagonal mana yang koordinat ada di dalam.
Geometri
Jika Anda menempatkan titik di kotak dengan kolom yang seperempat lebar ubin, dan baris yang setengah tingginya ubin, Anda mendapatkan pola ini:
Jika Anda kemudian memodifikasi kode untuk melewati setiap titik kedua dalam pola kotak-kotak (lewati if column % 2 + row % 2 == 1
), Anda berakhir dengan pola ini:
Penerapan
Dengan mengingat geometri itu, Anda dapat membuat array 2D (seperti yang Anda lakukan dengan kotak persegi), menyimpan x, y
koordinat untuk setiap titik dalam kotak (dari diagram pertama) - sesuatu seperti ini:
points = []
for x in numberOfColumns
points.push([])
for y in numberOfRows
points[x].push({x: x * widthOfColumn, y: y * heightOfRow})
Catatan: Seperti biasa, saat Anda membuat kisi di sekitar titik (alih-alih menempatkan titik pada titik itu sendiri), Anda harus mengimbangi titik asal (mengurangi setengah lebar kolom dari x
dan setengah ketinggian baris dari y
).
Sekarang setelah Anda memiliki array 2D ( points
) yang diinisialisasi, Anda dapat menemukan titik terdekat ke mouse seperti yang Anda lakukan pada kotak persegi, hanya harus mengabaikan setiap titik lainnya untuk menghasilkan pola pada diagram kedua:
column, row = floor(mouse.x / columnWidth), floor(mouse.y / rowHeight)
point = null if column % 2 + row % 2 != 1 else points[column][row]
Itu akan bekerja, tetapi koordinat sedang dibulatkan ke titik terdekat (atau tidak ada titik) berdasarkan persegi panjang yang tidak terlihat dari pointer. Anda benar-benar menginginkan zona melingkar di sekitar titik (sehingga rentang jepretan sama di setiap arah). Sekarang Anda tahu titik mana yang harus diperiksa, Anda dapat dengan mudah menemukan jarak (menggunakan Teorema Pythagoras). Lingkaran tersirat masih harus masuk ke dalam persegi panjang pembatas asli, membatasi diameter maksimumnya dengan lebar kolom (seperempat lebar ubin), tetapi itu masih cukup besar untuk bekerja dengan baik dalam praktiknya.