Deteksi tabrakan 2D

11

Anggap saya menggunakan karakter ini.

burung
(sumber: iconbug.com )

Bagaimana Anda menerapkan deteksi tabrakan untuk itu? Menggunakan kotak pembatas tampaknya bukan perkiraan yang baik, karena bentuk burung itu tidak jauh dari kotak.

Saya berpikir memiliki semacam struktur data quad tree di dalam objek yang mewakili bagian dari gambar. Setiap daun bisa false(dalam hal itu menutupi ruang putih / transparan di luar burung) atau true(dalam hal itu mewakili area burung yaitu paruh, mata, dll). Kemudian, entah bagaimana, uji satu-satunya kendala di tempat kejadian untuk tabrakan dengan burung itu.

Tapi masalah saya dalam pendekatan saya adalah:

  1. Saya tidak tahu bagaimana menginisialisasi pohon quad.
  2. Setelah pohon quad diinisialisasi, saya tidak yakin bagaimana untuk melintasi & menggunakannya setelah kendala berada dalam koordinat gambar.

Bagaimana Anda akan melakukan deteksi tabrakan dengan karakter non-kuadrat?

LE: Pendekatan lain yang saya lihat adalah menggunakan beberapa kotak pembatas. Misalnya saya punya satu atau beberapa kotak untuk paruh, lalu beberapa untuk rambut atau ekor. Tapi itu bisa membosankan. Jika ini adalah pendekatan yang valid dalam kasus saya, bagaimana saya menghasilkan kotak pembatas itu? Saya ragu saya harus menyimpannya dalam program saya.

LE2: Saya peduli tentang tabrakan yang cukup tepat. Saya tidak bisa membayangkan bagaimana satu kotak atau lingkaran tunggal dapat setidaknya memperkirakan bentuk itu, sehingga pendekatan ini tidak akan berfungsi.

async
sumber
2
Catatan umum: Saya akan menggunakan keduanya, kotak pembatas dan cek yang lebih terperinci: Cek granular akan memiliki penalti kinerja yang lebih tinggi, jadi Anda ingin menjalankannya sesering mungkin. Karena itu pertama-tama centang kotak pembatas dan hanya jika itu mengenai, naiklah ke level yang lebih dalam dan uji pendekatan Anda yang lebih terperinci (apa pun itu).
Philip Allgaier
Terima kasih, saya berencana untuk melakukan itu, tapi saya tidak sepenuhnya yakin akan seperti apa 'granular check' itu. :)
async
1
Satu-satunya detail penting yang hilang: Apa yang ingin Anda lakukan dengannya? Apakah Anda peduli tentang tabrakan yang tepat? Apakah Anda senang memperkirakan karakter dengan lingkaran? Apakah Anda ingin partikel debu bertabrakan dengan mata karakter secara terpisah dari yang lain?
Anko
@Anko Bagaimana Anda bisa memperkirakan bentuk itu dengan lingkaran? Saya peduli tentang tabrakan yang cukup tepat -tidak benar-benar tepat piksel, tetapi sesuatu yang akan terlihat bagus / alami-.
async
1
Seperti ini . Apa artinya "baik" dan "alami"? Apakah ini pertanyaan filosofis?
Anko

Jawaban:

12

Collider lingkaran. Cukup bagus untuk itu saya akan mengatakan kecuali Anda melakukan sesuatu yang mewah dengan bagian-bagian tertentu yang dipengaruhi oleh fisika atau bertabrakan tampak tidak wajar, dan bahkan jika Anda perlu membaginya menjadi beberapa bagian, saya punya satu hal untuk dikatakan kepada Anda:

Jangan terlalu rumit.

Anda tidak perlu struktur pohon quad penuh untuk ini. Hanya memiliki beberapa kotak atau lingkaran dalam larik lurus, dan kemudian berpotongan dengan semuanya. Ini tidak mungkin kinerja cukup kritis dan Anda tidak akan mendapatkan banyak dari menggunakan pohon quad.

Jonkel
sumber
3
Yap, buat saja array kecil beberapa bentuk jika satu bentuk tidak akan menutupinya. Misalnya: i.imgur.com/Dd4yyGN.png
MichaelHouse
Terima kasih Jonkel & @ Byte56. Menggunakan beberapa bentuk tampaknya solusi yang tepat dalam situasi saya. Mudah diterapkan, akurat dan cepat. Tidak percaya saya melompat langsung ke pohon quad tanpa mempertimbangkan ini! Uh.
async
Penumbuk lingkaran untuk tubuh dan empat persegi panjang untuk paruh, untuk akurasi ekstra.
Kroltan
14

Proses pemeriksaan dua langkah

Pada langkah pertama, Anda mencentang kotak pembatas , dan jika tidak ada tabrakan di sana, maka tes selesai. Jika ada tabrakan, Anda pindah ke lintasan kedua

Pada lintasan kedua , jika Anda menginginkan lebih presisi, dan Anda menginginkan solusi pixel sempurna yang sebenarnya, maka Anda dapat melakukan hal itu, lintasan periksa sempurna pixel

Karena gambar Anda adalah PNG (atau format file lainnya yang berisi saluran alfa), ini akan lebih mudah

  1. Hitung area persimpangan antara satu objek dalam adegan dan burung, menghasilkan persegi panjang simpang sederhana pada kedua gambar
  2. Di dalam persimpangan itu, periksa bahwa setiap piksel memiliki nilai alfa> 0 pada KEDUA gambar
  3. Jika ada piksel seperti itu, Anda dapat tabrakan. Kalau tidak, tidak

Jika Anda melihat saluran alpha gambar Anda, Anda dapat melihat bagaimana itu sudah memiliki semua informasi yang Anda butuhkan untuk tabrakan pixel sempurna

saluran alfa dari gambar

Tabrakan pixel sempurna biasanya mahal, jadi melakukan perkiraan kasar pada awalnya dengan kotak pembatas atau angka tabrakan yang lebih rinci (Seperti yang disarankan Anko) dapat menghemat waktu Anda yang berharga

Kotak "boundary" collision bounding terperinci yang lebih halus menyarankan:

kotak berlari lebih rinci

PS: Jika gambar Anda memiliki halo, efek atau saluran non-0 alpha lain di sekitarnya yang tidak ingin Anda tabrak, ambang algoritme dapat dengan mudah disesuaikan untuk mengakomodasi itu

codemonkey
sumber
1
Terima kasih! Tapi saya tidak membutuhkan ketepatan pixel yang sempurna. Jawaban yang sangat baik, akan berguna di kemudian hari.
async
tentu saja sobat, yeah, tabrakan pixel sempurna hampir selalu berlebihan, kecuali dalam game yang benar-benar membutuhkannya (seperti pejuang 2D)
codemonkey
3

Saya akan menggunakan lingkaran untuk tubuh dan satu persegi panjang untuk paruh, tapi itu hanya pendapat saya. Terlalu rumit geometri tabrakan Anda dapat memperlambat aplikasi Anda, Anda praktis menggandakan (atau lebih) jumlah karakter di layar.

igrad
sumber
0

Mungkin Anda bisa menggunakan semacam collider / poligon yang tidak enak.

Tidak yakin bagaimana ini akan bekerja, tetapi:

dua objek: objek 1: burung (o1), objek 2: benda yang mungkin menabrak burung (o2)

1) Tentukan bentuk pembatas yang merupakan poligon yang cocok dengan objek pertama (o1) yang dimaksud.

2) Dapatkan tepi o1, o2 yang bisa dibayangkan bertabrakan tanpa bisa dibayangkan bertabrakan tanpa lewat o2 melalui o1 atau sebaliknya.

Dengan posisi dan ukuran bentuk (o2) Anda mungkin dapat mengisolasi tepi (dari o1) yang tidak dapat dipukul, apakah itu karena mereka "di belakang" tepi lain (o1) yang lebih dekat ke o2. Jika Anda memiliki segitiga siku-siku yang sisi miringnya menghadap ke atas dan kanan dan sebuah persegi panjang mendekatinya lurus (dengan sisi panjang di sepanjang sumbu x) maka Anda dapat menentukan tepi mana yang harus dihilangkan karena mereka mulai dan berakhir nilai y keduanya baik di atas atau di bawah persegi panjang.

3) Tentukan apakah salah satu titik di tepi o2 sama dengan titik di salah satu tepi o1 yang Anda pilih pada langkah 2.

konsep ini mungkin bekerja paling baik untuk bertabrakan poligon (yaitu benda-benda dengan tepi yang jelas), tetapi mungkin Anda dapat memperlakukan lingkaran sebagai satu tepi panjang (misalnya jika o2 adalah lingkaran).

Jeremy Harton
sumber