Saya mencoba untuk membuat fungsi pixel to coord untuk hex map tapi saya tidak mendapatkan matematika dengan benar, semua yang saya coba tampaknya sedikit tidak aktif, dan contoh yang saya temukan didasarkan pada peta berpusat yang dilingkari.
Dengan 'berdasarkan array' Maksud saya cara hexes dipesan, lihat pic.
Hasil paling akurat yang saya dapatkan adalah dengan kode berikut, tetapi masih tidak aktif, dan semakin buruk nilainya semakin meningkat:
public HexCell<T> coordsToHexCell(float x, float y){
final float size = this.size; // cell size
float q = (float) ((1f/3f* Math.sqrt(3) * x - 1f/3f * y) / size);
float r = 2f/3f * y / size;
return getHexCell((int) r, (int) q);
}
Layar dimulai dengan 0,0 di kiri atas, setiap sel tahu pusatnya.
Yang saya butuhkan adalah cara untuk menerjemahkan koordinat layar menjadi koordinat hex. Bagaimana saya bisa melakukan itu?
sumber
Menurut saya, ada dua cara untuk mengatasi masalah ini.
Gunakan sistem koordinat yang lebih baik. Anda dapat membuat matematika lebih mudah pada diri Anda sendiri jika Anda pandai tentang bagaimana Anda menghitung bilangan. Amit Patel memiliki referensi definitif pada kisi heksagonal. Anda akan ingin mencari koordinat aksial pada halaman itu.
Pinjam kode dari seseorang yang sudah menyelesaikannya. Saya memiliki beberapa kode yang berfungsi, yang saya angkat dari sumber Battle for Wesnoth . Perlu diingat bahwa versi saya memiliki bagian datar dari heks di atas, sehingga Anda harus menukar x dan y.
sumber
Saya pikir jawaban Michael Kristofik benar, terutama karena menyebutkan situs web Amit Patel, tetapi saya ingin membagikan pendekatan pemula saya ke kisi-kisi Hex.
Kode ini diambil dari proyek yang saya kehilangan minat dan ditinggalkan ditulis dalam JavaScript, tetapi posisi mouse ke hex tile bekerja dengan baik. Saya menggunakan * artikel GameDev ini * untuk referensi saya. Dari situs web itu penulis memiliki gambar yang menunjukkan bagaimana secara matematis mewakili semua sisi dan posisi Hex.
Di kelas render saya, saya mendefinisikan ini dalam metode yang memungkinkan saya untuk mengatur panjang sisi Hex yang saya inginkan. Ditampilkan di sini karena beberapa nilai ini direferensikan dalam pixel ke kode koordinat hex.
Di kelas input mouse, saya membuat metode yang menerima koordinat layar x dan y, dan mengembalikan objek dengan koordinat Hex yang berada di dalam piksel. * Perhatikan bahwa saya punya "kamera" palsu sehingga offset untuk posisi render juga disertakan.
Akhirnya di sini adalah tangkapan layar proyek saya dengan debug render dihidupkan. Ini menunjukkan garis merah di mana kode memeriksa sel TypeA vs TypeB bersama dengan koordinat Hex dan sel menguraikan
Semoga ini bisa membantu beberapa.
sumber
Saya benar-benar menemukan solusi tanpa hex matematika.
Seperti yang telah saya sebutkan dalam pertanyaan, setiap sel menyimpannya sendiri coord tengah, dengan menghitung pusat hex terdekat dengan pixel coords saya dapat menentukan hex cell yang sesuai dengan ketepatan pixel (atau sangat dekat dengannya).
Saya tidak berpikir itu adalah cara terbaik untuk melakukannya karena saya harus beralih ke setiap sel dan saya bisa melihat bagaimana hal itu dapat membebani tetapi akan meninggalkan kode sebagai solusi alternatif:
sumber
0…cols-1
dan semua baris0…rows-1
, Anda dapat memindaicol_guess - 1 … col_guess+1
danrow_guess - 1 … row_guess + 1
. Itu hanya 9 heks jadi cepat dan tidak tergantung pada ukuran peta.Berikut adalah nyali implementasi C # dari salah satu teknik yang diposting di situs web Amit Patel (saya yakin menerjemahkan ke Jawa tidak akan menjadi tantangan):
Sisa proyek tersedia di sini sebagai Open Source, termasuk kelas MatrixInt2D dan VectorInt2D yang dirujuk di atas:
http://hexgridutilities.codeplex.com/
Meskipun implementasi di atas adalah untuk hexa datar, perpustakaan HexgridUtilities termasuk opsi transposing grid.
sumber
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: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 dariy
).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: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.
sumber