Bagaimana cara menangani tabrakan dengan benar dalam game berbasis komponen?


11

Mencoba membungkus kepala saya di sekitar cara untuk menangani tabrakan dengan benar dalam permainan yang dirancang di sekitar komponen.

Saya melihat banyak contoh memiliki semacam PhysicsComponentyang ditambahkan ke daftar komponen entitas tetapi implementasi sebenarnya membingungkan saya.

Agar ini berfungsi, PhysicsComponenttentu perlu akses ke dunia di sekitarnya. Ini tidak masuk akal bagi saya. Bukankah seharusnya suatu komponen tidak menyadari tidak hanya wadahnya (entitas), tetapi wadah kontainernya (dunia)?

Bagi saya, kedengarannya seperti level atau adegan harus mempertahankan daftar entitas ini dan setiap pembaruan game, loop melalui entitas untuk menentukan yang bertabrakan.

Pertanyaan saya adalah pertama, apakah ini desain yang bagus atau tidak, dan kedua, bagaimana menentukan entitas mana yang dapat bertabrakan. Saya kira entitas yang solid dapat mengimplementasikan antarmuka IRigidBody kosong sehingga level dapat menentukan entitas mana dalam daftar yang mendukung tabrakan. Tetapi apakah ini melanggar desain komponen?

Sebaliknya, haruskah mereka mengandung komponen RigidBody kosong? Ini mungkin sebenarnya lebih baik karena tidak selalu kosong dan pendekatan ini lebih tahan masa depan. Satu-satunya masalah dengan ini adalah kompleksitasnya. Adegan harus melewati tidak hanya setiap entitas, tetapi juga komponen setiap entitas untuk menentukan apakah memiliki komponen RigidBody ini.

Ketiga, ketika mereka bertabrakan, kedua entitas harus diberitahu entah bagaimana dan saya tidak yakin bagaimana untuk mencapai ini.

Katakanlah kedua entitas mengandung HealthComponent dan ketika mereka bertabrakan, kesehatan mereka akan menurun dengan nilai sewenang-wenang, 5. Saya kira itu akan menjadi tanggung jawab TKP untuk menangani hal ini ketika mendeteksi tabrakan antara dua entitas?

Tapi apakah adegan terlalu banyak bertanggung jawab? Saya bisa melihat ini mungkin keluar dari tangan dan menjadi sulit ketika adegan bertanggung jawab atas banyak hal yang seharusnya tidak dimiliki entitas (?).

Sunting: Pertanyaan diperbarui dengan lebih detail.


4
Jawaban ini tampaknya tepat untuk ditautkan ke: gamedev.stackexchange.com/questions/13797/…
Andrew Russell

Jawaban terkait Andrew, jawaban James, dan jawaban Nick Wiggill semuanya layak +1. Pikirkan komponen lebih sebagai data daripada sebagai kelas tipikal dengan data dan metode (bukan bahwa mereka tidak akan memiliki metode, tetapi mereka tidak seharusnya diberi banyak tanggung jawab). Lihatlah sistem komponen Artemis ( piemaster.net/2011/07/07/entity-component-artemis ) untuk contoh kerangka komponen yang baik.
michael.bartnett

Jawaban:


5

Jujur saja, dari sisi desain komponen, komponen saya tidak tahu satu sama lain kecuali mereka harus (Dan itu sangat jarang). Bahkan kemudian saya biasanya lebih suka komponen berbicara ke beberapa sistem pengelolaan komponen mengatakan daripada komponen secara langsung. (Antarmuka skrip terlihat seperti objek ke objek, tetapi tidak di mesin yang sebenarnya, hehe).

Untuk itu saya akan berpihak pada apa yang pertama kali Anda katakan dan pergi dengan komponen fisika yang ada di mana saja benda perlu diuji untuk tabrakan mereka. Sekarang jelas objek-objek ini mungkin harus menginformasikan komponen lain dari diri mereka sendiri pada resolusi tabrakan tetapi, seperti yang disebutkan, ini adalah di mana saya lebih suka acara itu sendiri untuk pergi ke objek melalui antarmuka lain (baik ke manajer atau melalui sistem pesan acara jika Anda memiliki salah satunya misalnya).

Saya pikir Anda berada di jalur yang benar dan hanya perlu lebih banyak dari 'Ya, itu terdengar benar' Jadi .. Ya, itu terdengar benar.

Semoga ini membantu!


3

Biasanya mesin game menggunakan perpustakaan pihak ke-3 untuk mendeteksi tabrakan antar entitas. Dalam skenario itu seseorang membuat atau mendaftarkan entitas yang memiliki Komponen Fisika ke dalam dunia "fisika". Dan setiap kali mendeteksi tabrakan antara dua entitas (A dan B), biasanya akan memanggil callback ke entitas A yang menginformasikan bahwa ia telah bertabrakan dengan entitas B dan sama untuk entitas B, yang menginformasikan bahwa ia telah bertabrakan dengan entitas A.

Untuk 2D, perpustakaan fisika gratis yang terkenal adalah Box2D. Juga ada baiknya melihat Chipmunk. Untuk 3D, Bullet gratis (mungkin yang gratis terbaik yang dapat Anda temukan). Havok dan PhysX terkenal karena digunakan dalam banyak triple A Games.


2

Masalah yang Anda hadapi adalah dalam melihat bahwa pendeteksian tabrakan (yang merupakan satu-satunya alasan Anda memerlukan satu entitas yang mengandung komponen fisika untuk merujuk yang lain) dilakukan pada tingkat yang lebih tinggi, biasanya dengan loop game Anda secara langsung, atau dengan fungsi pembantu / kelas yang melakukan ini. Jawaban saya kepada seseorang beberapa minggu yang lalu berbicara tentang penghapusan entitas dengan alasan yang sama, dan mengingat bahwa jika tabrakan menyebabkan salah satu entitas Anda hancur, jawaban yang sama, dalam konteks yang diberikan, akan sangat relevan bagi Anda , karena "kekuatan yang lebih tinggi" masih harus mengelola pembersihan mayat ... untuk berbicara.

Melakukan semua ini di antara entitas saja, umumnya tidak layak. Hampir selalu ada proksi untuk hal-hal seperti itu, dalam arsitektur yang solid, apakah itu melalui manajemen langsung seperti dengan deteksi tabrakan, atau kiriman peristiwa seperti misalnya di sistem pesan pemain di mana manajer perpesanan sisi klien mendengarkan pesan yang dikirim dari pemain, dan mengirimkannya ke server untuk disiarkan ulang ke semua orang.


2

Saya menghadapi masalah yang sama persis seperti Anda dalam sebuah proyek sekarang. Cara saya memutuskan untuk mengatasinya adalah dengan memiliki "ColliderComponent" yang memegang tubuh dari mesin fisika. Bodys didefinisikan secara eksternal (definisi bentuk yang dimuat saat runtime) dan kemudian ditambahkan ke dunia fisika dan ke entitas game milik mereka.

Saya menggunakan Box2D di mana Anda dapat melampirkan "collision-listener" yang akan diberi tahu oleh collision. Karena saya menambahkan pointer ke "ColliderComponent" saya ke data pengguna bodys, saya bisa mendapatkan dua ColliderComponents saya yang merupakan bagian dari collision.

Jadi hal yang terjadi ketika tabrakan terjadi adalah sebagai berikut: Komponen Collider yang merupakan bagian dari tabrakan akan mengirim pesan ke objek-pemiliknya (entitas-game) yang pada gilirannya akan menyiarkan pesan itu ke semua komponennya.

Setiap komponen kemudian dapat bereaksi terhadap pesan itu, sehingga "komponen kesehatan" Anda dapat menghilangkan 5 poin dari kesehatan, dll.


+1: Saya menggunakan pendekatan yang sangat mirip. Bagaimana Anda menentukan jumlah kerusakan yang disebabkan tergantung pada jenis entitas yang bertabrakan?
Den

@Den Saya mengirim pesan yang berbeda (atau data pesan) sesuai dengan tabrakan yang terjadi. Ini berfungsi dengan baik bagi saya, karena saya tidak memiliki banyak kasus yang berbeda untuk ditangani.
bummzack

0

Buat sistem tumbukan yang tahu tumbukan "dunia". Kemudian pada komponen tumbukan Anda beri tahu sistem tumbukan untuk melemparkan sinar dari titik A ke B dan merespons jika bertabrakan atau tidak.

Semoga berhasil. Saya menemukan sistem tabrakan menjadi salah satu bagian yang lebih membosankan dari mesin game.

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.