Di mana seharusnya logika pendeteksian tabrakan ditempatkan?

19

Saya sedang mengembangkan mesin game 2D kecil. Karakter memiliki metode cat yang saat ini melakukan hal berikut:

  1. Hitung posisi karakter baru sesuai kecepatannya, dll.
  2. Perbarui sel jaringan tabrakan **
  3. Gambar karakter di posisi baru

** Saya telah membuat collision grid untuk mengurangi jumlah pemeriksaan persimpangan

Sekarang algoritma dasar yang saya pikirkan untuk mendeteksi tabrakan adalah:

For Each Character
    Check intersection with characters in surrounding 8 cells

Saya hanya bisa menempatkan kode ini dalam metode cat. Tapi inilah masalah yang saya antisipasi.

Misalkan dua karakter A dan B terletak di sel yang berdekatan di grid tabrakan. Sekarang sesuai dengan algoritma di atas dalam iterasi karakter A ia akan mendeteksi bahwa ia telah bertabrakan dengan B. Dalam iterasi untuk karakter B itu akan mendeteksi bahwa ia telah bertabrakan dengan A.

Tapi saya punya ide bahwa ketika A mendeteksi bahwa ia bertabrakan dengan B, itu harus memberitahu B bahwa ia bertabrakan dengan A. Ini akan menghemat banyak perbandingan ketika ada lebih dari 2 aktor bertabrakan. Tapi saya tidak yakin bagaimana menangani ini. Saya pikir alih-alih setiap karakter memeriksa tabrakannya, saya harus memeriksa tabrakan di dalam loop game.

Apakah pendekatan ini benar? Bagaimana Anda menangani masalah seperti ini? Saya memikirkan hal tabrakan sendiri. Apakah ada alternatif selain logika tabrakan?

Kerupuk
sumber
Saya minta maaf kepada nitpick, tetapi di perpustakaan fisika 2D khusus. Fisika gim biasanya sangat aproksatif, jadi solusi apa pun yang tidak membuat gim tidak dapat dimainkan tidak masalah, tetapi jika Anda ingin menyelesaikannya dengan benar, gunakan saja fisika khusus seperti Box2D ... :-D
user712092

Jawaban:

14

Pendekatan yang biasa untuk deteksi tabrakan adalah tidak memiliki A atau B mendeteksi tabrakan sendiri.

Sebagai gantinya, Anda pertama-tama memindahkan semua objek, kemudian memiliki sistem tumbukan yang terpisah mencari tumbukan antara semua pasangan objek, memberi tahu setiap objek tentang hal-hal yang telah bertabrakan, dan akhirnya membuat semua objek.

Jadi pada dasarnya, alih-alih melakukan "pindah, periksa tabrakan, gambar" di dalam fungsi Paint () Anda, Anda membagi "bergerak" dan "menggambar" menjadi fungsi terpisah yang Anda panggil secara terpisah ("langkah" pertama untuk setiap objek, lalu "gambar" untuk setiap objek). Dan di antara itu, periksa tabrakan.

Catatan lanjutan: Jika ada objek Anda yang bergerak sendiri sebagai reaksi terhadap tabrakan yang terdeteksi, maka Anda mungkin perlu mengulangi langkah "cari tabrakan di antara semua pasangan objek", seandainya respons tabrakan objek menyebabkan benturan lain.

Trevor Powell
sumber
Ini adalah cara yang tepat untuk melakukan sesuatu. Biarkan objek menangani tanggung jawab mereka dan sistem tumbukan harus memutuskan apa yang terjadi ketika mereka menemui hambatan. Anda juga dapat memiliki collision rectangle / cylinder (2d / 3d) di sekitar karakter Anda sebagai semacam pemicu awal.
James P.
Bagus! Sehubungan dengan catatan lanjutan, bukankah seharusnya tabrakan diperiksa ulang hanya untuk benda-benda yang bergerak sendiri sebagai reaksi terhadap tabrakan dan benda-benda yang bertabrakan dengan mereka di posisi yang baru? Akan ada rantai pemeriksaan tetapi itu akan menghindari memeriksa tabrakan untuk semua objek.
Cracker
Cara menangani ini - gamedev.stackexchange.com/questions/13076/…
Cracker
1

Saya menjalankan loop untuk semua karakter saya di loop game seperti yang Anda katakan.

Cara saya melakukannya adalah dengan menyatakan pada masing-masing karakter saya, jadi jika A dan B bertabrakan saat A sedang memeriksa tabrakan A dan B diatur untuk memukul. pada awal loop B ia memeriksa untuk melihat apakah sudah terkena, jika id tidak menjalankan loop.

Saya meletakkan kode afeksi di loop sehingga setiap tindakan yang harus diambil pada B telah terjadi di loop A sehingga tidak boleh ada alasan untuk B untuk memeriksa karena ini akan mengacaukan hasil dari tabrakan, ini mungkin berbeda untuk Anda sekalipun .

Skeith
sumber
Tetapi dalam kasus ini ketika A mendeteksi persimpangan dengan B, B.hit akan disetel ke true sehingga B tidak akan memeriksa persimpangan APAPUN. Tetapi jika karakter C lain berpotongan dengan B, B tidak akan mendeteksinya?
Cracker
Maaf, mengerti. Karena A tidak bersinggungan dengan C, C.hit masih akan salah. B tidak akan memeriksa tabrakan. Tapi C akan memeriksa dan akan meneruskan informasi ke B bahwa ada tabrakan antara B dan C. Keren!
Cracker
Tapi saya kira jika semua A, B dan C bersinggungan satu sama lain akan ada masalah. A akan mengatur B.hit dan C.hit menjadi true. B dan C akan tahu bahwa mereka telah bertabrakan dengan A. Tetapi karena properti hit mereka benar, mereka tidak akan memeriksa tabrakan. Tabrakan antara B dan C akan luput dari perhatian.
Cracker
Anda dapat menyelinap dalam metode yang sama dengan menempatkan setiap objek tabrakan yang layak dalam koleksi semacam, kemudian hanya memeriksa tabrakan dengan hal-hal yang datang setelah objek dalam koleksi. IE: A memeriksa vs B, C, D; B memeriksa vs C, D; C memeriksa vs D. Masing-masing di belakang tidak perlu diperiksa karena sudah diperiksa dari giliran di belakang. Tidak secepat melompat dari tabrakan elemen sepenuhnya, tetapi tetap berguna.
Lunin