Mengenali clickbox heksagonal

17

Saya sedang mengerjakan game yang akan melibatkan hexagon terkesiap .

Saat ini, saya memiliki gambar segi enam yang saya gunakan (semua sisi memiliki panjang yang sama ... cocok menjadi 50px dengan gambar 50px).

Saya agak baru untuk C # dan benar-benar baru untuk XNA, tetapi apakah ada semacam metode mudah yang dapat saya panggil daripada melakukan pernyataan berbelit-belit jika didasarkan pada titik dan sudut?

engkau
sumber
Lihat gamedev.stackexchange.com/questions/6382/… yang mengimplementasikan deteksi klik hex.
Tim Holt
4
Aku benar-benar mencari Google "segi enam terengah-engah" Aku seperti, "segi enam macam apa itu ?!" Kira saya mengalami hari yang lambat.
MichaelHouse
2
Hmm apa yang terjadi jika Anda mengklik di napas bukannya di segi enam?
Tim Holt
1
Tergantung pada kebutuhan Anda, lingkaran sederhana akan dilakukan jika hanya untuk area klik. Kalau tidak, Anda harus menggunakan titik pada teknik poligon seperti jumlah berliku atau jumlah.
PhilCK
Kecuali jika peta hex diputar secara sewenang-wenang, titik pada poligon adalah berlebihan. Apa yang Anda lakukan dengan peta yang 1000x1000 heks? Periksa semuanya? RE: Lingkaran, mereka tidak akan bekerja. Di dekat simpul persimpangan antara tiga heks, Anda akan memiliki tiga lingkaran yang tumpang tindih. Lingkaran kecil yang terletak sepenuhnya di dalam heks akan memiliki celah di mana klik yang sah tidak akan ada di lingkaran mana pun.
Tim Holt

Jawaban:

18

Hexagon adalah kotak dengan sudut terpotong. Cara saya melihat ini dilakukan, dan saya pernah mendengar seri Civilization melakukannya dengan peta ortogonal, adalah membuat bitmap dengan spasi putih (ortogonal atau heksagonal), dan merah, hijau, biru, dan kuning sudut. (Atau warna apa pun yang Anda suka.)

Heksagonal: Topeng hexataumasukkan deskripsi gambar di sini

Orthogonal: masukkan deskripsi gambar di sini

Kemudian, tentukan saja persegi panjang mana yang kursornya sudah berakhir, dan uji warna pixel di lokasi itu. Jika putih, mereka melayang di atas ruang itu. Setiap warna lain dipetakan ke offset, dan mereka melayang di atas hexagon itu. Cara ini efisien, membutuhkan sedikit geometri, dan dapat digunakan untuk ruang tessellating sewenang-wenang.

dlras2
sumber
Sekadar catatan: Segi enam memiliki 6 sisi panjang yang sama. Tak satu pun dari gambar yang Anda sajikan sebenarnya mengandung segi enam. Sebaliknya, mereka mengandung 6 poligon sisi. Selain itu, metode ini berfungsi. Ini mungkin lebih lambat daripada menghitung batas-batas segi enam, untuk segi enam yang lebih besar, karena metode ini membutuhkan lebih banyak ruang untuk segi enam yang lebih besar (jika Anda ingin menjaga akurasi per piksel). Untuk segi enam kecil (dan tergantung pada perangkat keras), metode ini mungkin lebih cepat daripada menghitung batas.
Olhovsky
9
Hexagon adalah 6 sisi poligon. Apa yang Anda pikirkan adalah segi enam sama sisi (sebenarnya, Anda mungkin berpikir tentang segi enam biasa , yang merupakan jenis segi enam sama sisi dan sisi )
Random832
Harap dicatat bahwa saya tidak mengatakan bahwa jawaban Anda buruk. Saya pikir itu adalah jawaban yang baik dan solusi yang memiliki tempatnya. Yang mengatakan, saya tidak akan memilih metode ini daripada menghitung batas segi enam, seperti menghitung batas segi enam pada platform modern, karena menghitung batas adalah cara yang jauh lebih mudah untuk melakukannya. Misalnya katakanlah Anda ingin mengubah ukuran segi enam - sekarang Anda harus membangun kembali gambar? Memproduksi pixel hexagon perfect mask adalah suatu hal yang menyakitkan. Fakta bahwa Anda belum membuat satu di sini adalah bukti untuk itu, saya pikir.
Olhovsky
2
@Olhovsky - Saya belum menghasilkan topeng segi enam yang sempurna di sini karena saya menjawab pertanyaan sebagai layanan komunitas selama beberapa menit istirahat saya saat bekerja, dan tidak benar-benar menulis video game. OP sedang mencari solusi dengan sedikit matematika, dan saya pikir ini rapi jadi saya pikir saya akan berbagi, karena itu sesuatu yang saya pasti tidak akan memikirkannya sendiri.
dlras2
18

Tidak ada metode XNA yang melakukan uji hit segi enam.

Artikel ini menjelaskan cara menulis fungsi yang melakukan tes, dan memberi Anda fungsi:

Cara Memeriksa apakah suatu Titik ada di Dalam Segi Enam

Berikut ringkasan dari artikel itu: kotak klik segi enam

Dan fungsi yang melakukan tes berjalan seperti ini:

  1. Tes kotak pembatas di sekitar segi enam, awal jika tidak memotongnya.
  2. Ubah titik menjadi kuadran lokal seperti yang ditunjukkan di atas.
  3. Lakukan isInsidetes berikut untuk kuadran lokal.

public function isInside(pos:Vec2Const):Boolean
{
    const q2x:Number = Math.abs(pos.x - _center.x);       
    const q2y:Number = Math.abs(pos.y - _center.y);
    if (q2x > _hori || q2y > _vert*2) 
        return false;
    return 2 * _vert * _hori - _vert * q2x - _hori * q2y >= 0;
}

Lihat artikel untuk detail lengkap.


Berikut adalah beberapa sumber terkait lainnya yang berguna:

Olhovsky
sumber
1

Di sini saya mendapatkan metode yang dapat digunakan untuk mendeteksi klik di dalam poligon apa pun:

public bool PointInPolygon( Vector2 p, Vector2[] poly )
    {
        Vector2 p1, p2;
        bool inside = false;

        if( poly.Length < 3 )
        {
            return inside;
        }

        Vector2 oldPoint = new Vector2( poly[poly.Length - 1].X, poly[poly.Length - 1].Y );

        for( int i = 0; i < poly.Length; i++ )
        {
            Vector2 newPoint = new Vector2( poly[i].X, poly[i].Y );

            if( newPoint.X > oldPoint.X )
            {
                p1 = oldPoint;
                p2 = newPoint;
            }
            else
            {
                p1 = newPoint;
                p2 = oldPoint;
            }

            if( ( newPoint.X < p.X ) == ( p.X <= oldPoint.X )
                && ( (long)p.Y - (long)p1.Y ) * (long)( p2.X - p1.X )
                 < ( (long)p2.Y - (long)p1.Y ) * (long)( p.X - p1.X ) )
            {
                inside = !inside;
            }

            oldPoint = newPoint;
        }

        return inside;
    }

Anda perlu memberikan sudut hexagon Anda dalam array vektor2 (poli) dan posisi yang diklik (p) untuk metode ini.

chr1s1202
sumber