Saya membaca Game Coding Complete dan penulis merekomendasikan komunikasi Event Driven antara objek dan modul game.
Pada dasarnya, semua aktor permainan hidup harus berkomunikasi dengan modul utama (Fisika, AI, Logika Game, Tampilan Game, dll.) Melalui sistem pesan acara internal. Ini berarti harus merancang manajer acara yang efisien. Sistem yang dirancang buruk memakan siklus CPU, terutama yang memengaruhi platform seluler.
Apakah ini pendekatan yang terbukti dan direkomendasikan? Bagaimana saya harus memutuskan apakah akan menggunakannya?
architecture
software-engineering
events
Bunkai.Satori
sumber
sumber
libuv
baru-baru ini muncul sebagai perpustakaan acara yang sukses. (Ada di C. Node.js adalah kasus penggunaannya yang paling terkenal.)Jawaban:
Ini adalah perluasan dari komentar saya menjadi jawaban penuh, seperti yang disarankan.
Ya , sederhana dan sederhana. Komunikasi perlu terjadi dan sementara ada situasi di mana 'Apakah kita sudah sampai?' -jenis polling diperlukan, memeriksa hal-hal untuk melihat apakah mereka harus melakukan sesuatu yang lain umumnya membuang-buang waktu. Alih-alih, Anda bisa membuat mereka bereaksi terhadap hal-hal yang diperintahkan kepada mereka untuk dilakukan. Plus, jalur komunikasi yang didefinisikan dengan baik antara objek / sistem / modul meningkatkan pengaturan paralel secara signifikan.
Saya telah memberikan tinjauan tingkat tinggi tentang sistem pengiriman pesan acara di Stack Overflow . Saya telah menggunakannya dari sekolah menjadi judul-judul game profesional dan sekarang produk-produk non-game, disesuaikan dengan kasus penggunaan setiap saat tentu saja.
EDIT : Untuk menjawab pertanyaan komentar tentang bagaimana Anda tahu objek mana yang harus menerima pesan : Objek itu sendiri harus
Request
diberitahu tentang peristiwa. AndaEventMessagingSystem
(EMS) akan membutuhkanRegister(int iEventId, IEventMessagingSystem * pOjbect, (EMSCallback)fpMethodToUseForACallback)
serta pencocokanUnregister
(membuat entri yang unik untukiEventId
keluar dari pointer objek dan callback). Dengan cara ini, ketika suatu objek ingin tahu tentang suatu pesan, ia dapatRegister()
menggunakan sistem. Ketika itu tidak perlu lagi tahu tentang peristiwa itu, itu bisaUnregister()
. Jelas, Anda ingin kumpulan objek pendaftaran panggilan balik ini dan cara yang efektif untuk menambah / menghapusnya dari daftar. (Saya biasanya menggunakan array pemesanan sendiri; cara yang bagus untuk mengatakan mereka melacak alokasi mereka sendiri antara kumpulan kumpulan objek yang tidak digunakan dan array yang menggeser ukurannya di tempat ketika diperlukan).EDIT : Untuk game yang sepenuhnya berfungsi dengan loop pembaruan dan sistem pesan acara, Anda mungkin ingin memeriksa proyek sekolah lama saya . Posting Stack Overflow yang ditautkan di atas juga merujuk padanya.
sumber
Pendapat saya adalah Anda harus mulai membuat game dan menerapkan apa yang Anda sukai. Ketika Anda melakukan itu, Anda akan menemukan diri Anda menggunakan MVC di beberapa tempat, tetapi tidak di tempat lain; Peristiwa beberapa tempat, tetapi tidak yang lain; komponen beberapa tempat, tetapi warisan lainnya; desain bersih beberapa tempat, dan desain crufty lainnya.
Dan itu tidak masalah, karena ketika Anda selesai Anda akan benar-benar memiliki permainan, dan permainan itu jauh lebih keren daripada sistem penyampaian pesan.
sumber
Pertanyaan yang lebih baik adalah, alternatif apa yang ada? Dalam sistem yang sedemikian kompleks dengan modul yang dibagi dengan baik untuk fisika, AI, dll., Bagaimana lagi Anda dapat mengatur sistem ini?
Pesan lewat tampaknya menjadi solusi "terbaik" untuk masalah ini. Saya tidak bisa memikirkan alternatif sekarang. Tetapi ada banyak contoh pesan yang lewat dalam praktek. Bahkan, sistem operasi menggunakan passing pesan untuk beberapa fungsinya. Dari Wikipedia :
(Komunikasi antarproses adalah komunikasi antar proses (mis. Menjalankan instance program) dalam lingkungan sistem operasi)
Jadi, jika itu cukup baik untuk sistem operasi, itu mungkin cukup baik untuk sebuah game, bukan? Ada manfaat lain juga, tapi saya akan membiarkan artikel Wikipedia tentang pesan yang lewat melakukan penjelasan.
Saya juga mengajukan pertanyaan tentang Stack Overflow, "Struktur data untuk pengiriman pesan dalam suatu program?" , yang mungkin ingin Anda baca.
sumber
Pesan umumnya bekerja dengan baik ketika:
Semakin banyak kebutuhan Anda cocok dengan daftar itu, semakin baik pesan yang cocok. Pada tingkat yang sangat umum, mereka cukup bagus. Mereka melakukan pekerjaan yang baik dengan tidak membuang-buang siklus CPU hanya untuk tidak melakukan apa pun seperti polling atau solusi global lainnya. Mereka fantastis dalam memisahkan bagian-bagian dari basis kode, yang selalu membantu.
sumber
Sejauh ini jawaban yang bagus dari James dan Ricket, saya hanya menjawab untuk menambahkan catatan hati-hati. Komunikasi lewat pesan / event-driven tentu merupakan alat penting dalam gudang pengembang, tetapi dapat dengan mudah digunakan secara berlebihan. Ketika Anda memiliki palu, semuanya terlihat seperti paku, dan sebagainya.
Anda benar-benar, 100%, harus berpikir tentang aliran data di sekitar judul Anda, dan sepenuhnya menyadari bagaimana informasi dilewatkan dari satu subsistem ke yang lain. Dalam beberapa kasus, menyampaikan pesan jelas merupakan yang terbaik; pada yang lain, mungkin lebih tepat untuk satu subsistem untuk beroperasi di atas daftar objek yang dibagikan, memungkinkan subsistem lain untuk juga beroperasi pada daftar bersama yang sama; dan masih banyak lagi metode lainnya.
Setiap saat Anda harus mengetahui subsistem mana yang memerlukan akses ke data mana, dan kapan mereka perlu mengaksesnya. Ini memengaruhi kemampuan Anda untuk memparalelkan dan mengoptimalkan, serta membantu Anda menghindari masalah yang lebih berbahaya ketika berbagai bagian mesin Anda menjadi terlalu dekat. Anda harus berpikir tentang meminimalkan penyalinan yang tidak perlu di sekitar data, dan bagaimana tata letak data Anda memengaruhi penggunaan cache Anda. Semuanya akan memandu Anda ke solusi terbaik dalam setiap kasus.
Karena itu, hampir setiap game yang pernah saya garap memiliki sistem pemberitahuan pesan / event event asynchronous yang solid. Ini memungkinkan Anda untuk menulis kode yang ringkas, efisien dan dapat dipelihara, bahkan dalam menghadapi kebutuhan desain yang kompleks dan cepat berubah.
sumber
Yah, saya tahu bahwa posting ini cukup lama, tetapi saya tidak bisa menolak.
Saya baru-baru ini membangun mesin game. Ini menggunakan perpustakaan pesta 3d untuk rendering dan fisika, tapi saya menulis bagian inti, yang mendefinisikan dan memproses entitas dan logika permainan.
Mesinnya pasti mengikuti pendekatan tradisional. Ada loop pembaruan utama yang memanggil fungsi pembaruan untuk semua entitas. Tabrakan secara langsung dilaporkan melalui panggilan balik pada entitas. Komunikasi antar entitas dibuat menggunakan smart pointer yang dipertukarkan antar entitas.
Ada sistem pesan primitif, Yang memproses hanya sekelompok kecil entitas untuk mesin pesan. Pesan-pesan itu lebih disukai diproses pada akhir interaksi game (contohnya adalah pembuatan entitas atau penghancuran) karena mereka dapat mengacaukan dengan daftar pembaruan. Jadi, di akhir setiap loop game, daftar kecil pesan dikonsumsi.
Meskipun sistem pesan primitif, saya akan mengatakan bahwa sistem ini sebagian besar "pembaruan berbasis loop".
Baik. Setelah menggunakan sistem ini, saya pikir itu sangat sederhana, cepat dan terorganisir dengan baik. Logika permainan terlihat dan mandiri di dalam entitas, tidak dinamis seperti pesan quewe. Saya benar-benar tidak ingin menjadikannya event driven karena menurut saya sistem acara memperkenalkan kompleksitas yang tidak perlu pada logika game, dan membuat kode game sangat sulit untuk dipahami dan didebug.
Tapi, saya juga berpikir bahwa sistem "update loop based" murni seperti milik saya punya beberapa masalah juga.
Misalnya, Dalam beberapa saat, satu entitas mungkin berada pada "keadaan tidak melakukan apa-apa", mungkin sedang menunggu pemain mendekat atau yang lainnya. Dalam sebagian besar kasus, entitas membakar waktu prosesor dengan sia-sia dan lebih baik mematikan entitas, dan menyalakannya saat peristiwa tertentu terjadi.
Jadi, di mesin gim berikutnya, saya akan mengadopsi pendekatan yang berbeda. Entitas akan mendaftarkan diri untuk operasi mesin, seperti pembaruan, gambar, deteksi tabrakan dan sebagainya. Setiap peristiwa ini akan memiliki daftar antarmuka entitas yang terpisah untuk entitas yang sebenarnya.
sumber
Iya. Ini adalah cara yang sangat efisien bagi sistem permainan untuk berkomunikasi satu sama lain. Acara membantu Anda memisahkan banyak sistem dan memungkinkan untuk menyusun berbagai hal secara terpisah tanpa mengetahui keberadaan satu sama lain. Ini berarti kelas Anda dapat lebih mudah di-prototipe dan waktu kompilasi lebih cepat. Lebih penting lagi, Anda berakhir dengan desain kode datar alih-alih kekacauan ketergantungan.
Manfaat besar lainnya dari acara adalah bahwa mereka mudah dialirkan melalui jaringan atau saluran teks lainnya. Anda dapat merekamnya untuk pemutaran nanti. Kemungkinannya tidak terbatas.
Manfaat lain: Anda dapat meminta beberapa subsistem mendengarkan acara yang sama. Misalnya, semua tampilan jauh Anda (pemain) dapat secara otomatis berlangganan ke acara pembuatan entitas dan menelurkan entitas pada setiap klien dengan sedikit pekerjaan di pihak Anda. Bayangkan berapa banyak pekerjaan yang akan terjadi jika Anda tidak menggunakan acara: Anda harus melakukan
Update()
panggilan di suatu tempat atau mungkin meneleponview->CreateEntity
dari logika Game (di mana pengetahuan tentang tampilan dan informasi apa yang diperlukan tidak termasuk). Sulit untuk menyelesaikan masalah itu tanpa kejadian.Dengan acara Anda mendapatkan solusi yang elegan dan terpisah yang mendukung jumlah objek tak terbatas dari jenis tak terbatas yang semuanya dapat dengan mudah berlangganan acara dan melakukan hal mereka ketika sesuatu terjadi dalam permainan Anda. Itu sebabnya acara sangat bagus.
Lebih detail dan implementasinya di sini .
sumber
Dari apa yang saya lihat, sepertinya tidak terlalu umum untuk memiliki mesin yang sepenuhnya berdasarkan pesan. Tentu saja, ada subsistem yang cocok untuk sistem pesan seperti itu, seperti jaringan, GUI, dan mungkin yang lainnya. Namun secara umum, ada beberapa masalah yang dapat saya pikirkan:
Dengan pendekatan pengembang game umum "itu harus seefisien mungkin" sistem pesan seperti itu tidak begitu umum.
Namun, saya setuju bahwa Anda harus melanjutkan dan mencobanya. Tentu ada banyak keuntungan dengan sistem seperti itu dan daya komputasi tersedia dengan murah saat ini.
sumber