Jika dua objek berinteraksi, apa yang menahan kode interaksi?


28

Pikirkan peluru dan musuh, atau pemain dan lantai. Jika objek-objek ini berinteraksi, apa yang menahan kode interaksi?


2
Berinteraksi dengan cara apa? Apakah maksud Anda deteksi tabrakan? Jika demikian maka kemungkinan besar Anda akan mengimplementasikan kelas deteksi tabrakan dan manajer resolusi tabrakan.
CaptainRedmuff

Sebagian ya, saya tertarik pada tabrakan dan apa yang terjadi setelah tabrakan. Apakah peluru memeriksa apakah dekat dengan musuh, atau sebaliknya? Dan apa yang terjadi setelah tabrakan, bisakah benda peluru hanya memberi tahu benda musuh itu terkena? Seperti yang Anda lihat, saya cukup bingung tentang semuanya, dan itu membuat beberapa kode sangat sulit dibaca.
ThatOneGuy

Jawaban:


23

TL; DR:

Objek gim Anda tidak saling mengenal, juga tidak melakukan pengecekan terhadap objek lain. Anda membuat pola deteksi tabrakan dan resolusi tabrakan yang memeriksa objek game Anda dan melakukan tindakan yang tepat untuk mensimulasikan fisika game Anda.

The Good Stuff

Dari upaya sebelumnya dalam menulis deteksi tabrakan dan membaca buku ini , ada dua tahap untuk deteksi tabrakan dan resolusi tabrakan. Tahap pertama (deteksi tabrakan) adalah pass awal keluar di mana Anda menentukan apakah dua objek mungkin memiliki potensi tabrakan. Jika ada dua objek yang membentuk tabrakan potensial, Anda kemudian meneruskan objek-objek ini ke tahap kedua (resolusi tabrakan) untuk menjalankan pemeriksaan berbutir lebih halus terhadap objek dan berusaha menyelesaikan tabrakan.

Di suatu tempat di mesin / game Anda, Anda akan memegang array semua benda di dunia Anda. Pada setiap frame Anda akan mengulang-ulang array dan memeriksa setiap objek terhadap setiap objek lainnya dengan kotak sederhana / deteksi tabrakan bola.

Kodesemu:

dectectCollisions(objects)
{
    for(objectA in objects)
    {
        for(objectB in objects)
        {
            if(objectA != objectB) //ignore self
            {
                if(BoundingSpheresIntersect(objectA, objectB))
                {
                    collisionResolver.addObjects(objectA, objectB);
                }
            }
        }
    }
}

Jenis loop ini agak tidak efisien tetapi tidak memberikan ruang untuk perbaikan melalui penggunaan partisi spasial sebagai awal-keluar untuk objek yang dijamin terlalu jauh untuk bertabrakan.

Setelah memeriksa dua objek untuk tabrakan potensial (yaitu kedua objek cukup dekat untuk bertabrakan), objek dilewatkan untuk melakukan rutin deteksi tabrakan yang lebih tepat.

Bayangkan Anda memiliki dua poligon bentuk dan ukuran acak yang cukup dekat sehingga berpotensi berpotongan tetapi tidak karena geometrinya:

Gambar ditemukan melalui google

Dengan menggunakan bola pembatas, kedua benda ini akan menciptakan false positive untuk tabrakan potensial. Di sinilah Anda kemudian akan melakukan operan yang lebih teliti untuk menentukan apakah kedua objek tersebut benar-benar berpotongan.

Setelah Anda menemukan tabrakan sejati, langkah resolusi tabrakan Anda kemudian akan melakukan tindakan yang tepat untuk menyelesaikan objek dengan menerapkan kekuatan atau momen tergantung pada rincian dan kebutuhan fisika gim Anda.

Dengan pemikiran ini, Anda dapat mengabstraksi seluruh proses deteksi dan resolusi tabrakan sehingga objek Anda tidak perlu tahu apa pun tentang satu sama lain, maupun proses yang diperlukan untuk menentukan dan menyelesaikan tabrakan. Dua kelas / manajer yang menangani ini untuk Anda hanya perlu mengetahui sifat dasar dari setiap objek untuk melakukan pemeriksaan cepat dan kotor untuk tabrakan dan kemudian pemeriksaan yang lebih menyeluruh jika diperlukan.


2
Secara khusus, pola desain Mediator akan sesuai. Pola Observer akan menjadi alternatif yang baik, yang memiliki maksud yang sangat berbeda. Anda bisa mendapatkan ringkasan yang cukup bagus di pos Stackoverflow ini .
kurtzbot

12

Salah satu cara Unreal Engine 3 menanganinya:

Peluru mendapat pesan tabrakan mengatakan itu mengenai sesuatu, dengan argumen mengatakan apa yang ditabraknya. Kemudian dapat memanggil objectHit.takeDamage (mandiri). Target kemudian mendapat pesan TakeDamage, dengan sebuah penunjuk ke benda yang menabraknya, dan mengambil tindakan yang sesuai.

Saya pribadi suka pendekatan ini karena itu berarti peluru dapat mengambil tindakan khusus (seperti membuat semacam efek ledakan tergantung pada jenis benda yang terkena) dan target dapat mengambil tindakan khusus tergantung pada jenis peluru.

Mungkin juga peluru itu tahu apa yang dilakukannya terhadap target, dan dapat memanggil fungsi di atasnya, seperti objectHit.freeze (self). Kemudian target tahu itu terkena sesuatu yang membekukannya, dan objek seperti apa itu.

EDIT: Jawaban ini dimaksudkan sebagai gambaran umum tentang cara kerjanya, karena Anda mungkin tidak bekerja dengan UE3. :)


10

Pencuri melakukan ini dengan sangat baik di Dark Engine dengan Sumber dan Receptrons. Objek dapat memiliki kedua properti ini, dengan tipe yang berbeda. Misalnya, panah Air akan memiliki Sumber untuk WaterStim pada kontak. Sebuah ledakan akan memiliki FireStim AoE.

Ketika panah air menyentuh objek, objek target kemudian mencari Receptrons untuk mencari sesuatu WaterStim dengan nilai intensitas yang sesuai. Kemudian ia menjalankan perintah apa pun yang terkait dengannya (dalam hal ini, mengubah obor yang menyala menjadi obor off, dan mengeluarkan kepulan asap.)

Karena mesin yang sama digunakan dalam SystemShock2 ini adalah bagaimana semua jenis kerusakan yang berbeda ditangani, peluru yang berbeda memiliki set Stims yang berbeda, dan monster yang berbeda kemudian memiliki Receptrons untuk jenis Stim yang berbeda dan melakukan kerusakan yang sama dengan 1 *, 2 *, 1 / 2 intensitas tergantung pada apakah jenis amunisi "super efektif" atau tidak.

Itu tampak seperti sistem yang sangat fleksibel karena Anda dapat menambahkan sumber dan receptrons ke objek di editor level, (untuk membuat pintu satu kali yang terbuka jika terkena api, katakanlah.) Sementara Anda juga bisa memberi tahu receptron untuk "mengirim skrip untuk" mengirim skrip message "jika objek memiliki skrip khusus yang terkait dengannya.

Yang tidak ingin Anda lakukan adalah membuat hardcode sebuah matriks interaksi nXn dari semua objek yang mungkin bertabrakan dengan semua objek yang mungkin! DENGAN generalisasi interaksi melalui pesan standar, Anda menyederhanakan prosesnya.


Dari sudut pandang scripting, pendekatan ini tampaknya paling fleksibel dan paling ekspresif. Sangat keren.
drhayes

-2

Salah satu solusinya adalah menjaga wadah peluru dan pemain di kelas yang terpisah, dan kemudian memiliki fungsi utama () yang membuat frame loop bertanggung jawab untuk interaksi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.