Menciptakan Entitas sebagai agregasi


10

Baru-baru ini saya bertanya tentang cara memisahkan entitas dari perilaku mereka dan jawaban utama yang ditautkan ke artikel ini: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

Konsep utama yang ditulis di sini adalah: OBJEK SEBAGAI AGREGASI MURNI.

Saya ingin tahu bagaimana cara membuat entitas game sebagai agregasi murni menggunakan C #. Saya belum memahami konsep bagaimana ini bisa bekerja. (Mungkin entitas adalah array objek yang mengimplementasikan antarmuka atau tipe basis tertentu?)

Pemikiran saya saat ini masih melibatkan memiliki kelas konkret untuk setiap jenis entitas yang kemudian mengimplementasikan antarmuka yang relevan (IMoveable, ICollectable, ISpeakable dll).

Bagaimana saya bisa membuat entitas murni sebagai agregasi tanpa memiliki tipe konkret untuk entitas itu?


Jika Anda masih tertarik, saya dapat mengirimkan Anda sistem entitas kecil di C #. Itu tidak luar biasa , tetapi berhasil.
Bebek Komunis

Jawaban:


6

Pendekatan "agregasi murni" yang dijelaskan oleh Barat dalam artikel terkait itu menghindari objek "entitas" sama sekali. Ada beberapa komponen, melayang-layang di memori, tetapi mereka diikat hanya oleh hubungan implisit, jika sama sekali.

Salah satu cara untuk melakukan ini adalah apa yang disebut pendekatan tempel . Dalam sistem seperti itu, komponen dipegang oleh sistem yang mengelola atau mengendalikannya (saya menggunakan istilah "kelola" di sini, tetapi Anda tidak boleh menganggap ini sebagai maksud saya menyarankan Anda memiliki banyak kelas * Manajer untuk dipegang tipe komponen). Sebagai contoh, sistem fisika Anda mungkin berpegang pada banyak hal yang mewakili setiap benda tegar di dunia simulasi, dan dapat mengekspos hal-hal tersebut sebagai komponen Physics. Komponen dapat berupa objek aktual yang ditangani oleh subsistem yang bersangkutan, atau mereka dapat menjadi proksi untuk objek tersebut, sesuai kebutuhan.

Dalam sistem seperti itu tidak perlu kelas "Entity" untuk menyimpan koleksi referensi ke komponen yang menyusunnya; sebagai gantinya pemberitahuan dimunculkan berkenaan dengan penciptaan atau penghancuran "entitas" dan setiap subsistem yang menangani komponen melihat deskripsi entitas yang dibuat / dihancurkan (yang biasanya dimuat dari beberapa data) dan menentukan apakah suatu komponen diperlukan untuk itu.

Salah satu keuntungan dari pendekatan ini adalah Anda mendapatkan referensi lokal yang sangat baik untuk setiap komponen. Sayangnya itu agak aneh, secara keseluruhan, dan bukan rasa paling ramah dari entitas berbasis komponen yang saya temui. Kadang-kadang benar-benar nyaman untuk memiliki objek nyata yang mewakili suatu entitas, bahkan jika objek itu tidak lebih dari agregat referensi lemah untuk komponen yang masih dipegang oleh subsistem lain (jika tidak ada yang lain itu memberikan cara mudah untuk merutekan pesan antar komponen) .

Ada beberapa cara yang baik untuk menerapkan sistem objek game berorientasi komponen; itu sangat, sangat, sangat membantu jika Anda memiliki gagasan yang kuat tentang persyaratan yang Anda inginkan dari sistem Anda - Anda dapat melihat apa yang dilakukan kerangka kerja populer seperti Unity sebagai contoh. Tanpa menetapkan persyaratan ketat untuk Anda sendiri, Anda dapat mengalami masalah tanpa henti "mendesain" sistem tanpa pernah benar-benar membangunnya, mencoba dengan sia-sia untuk menemukan implementasi yang sempurna. Untuk alasan apa pun saya sering melihat ini dengan sistem komponen.


3

Cara Unity melakukannya adalah semua skrip (dalam kasus Anda, kode gim yang khusus untuk jenis objek gim) berasal dari kelas dasar MonoBehaviour, yang berasal dari Componentkelas kasus yang lebih relevan dengan kasus Anda . Anda tidak pernah mengedit (dan tidak memiliki akses ke kode) kelas GameObject.

Objek game bertugas memuat semua Componentitu. Ini juga seolah-olah bertugas memanggil fungsi yang relevan pada mereka (yaitu Update). Unity menggunakan refleksi untuk menentukan fungsi apa yang harus dipanggil (lihat bagian "Fungsi yang Dapat Digantikan" pada halaman ini ), tetapi Anda mungkin ingin membuatnya menjadi virtual.

Jadi salah satu mekanisme yang Anda gunakan di Unity adalah mendapatkan komponen pada objek game Anda saat ini (atau anak-anaknya) berdasarkan jenis. Ada beberapa properti pembantu yang membungkus beberapa hal umum. Misalnya, jika Anda ingin mengakses Transformkomponen objek game (untuk mengontrol posisi / rotasi / skala objek game), Anda biasanya harus melakukan sesuatu seperti this.GetComponent<Transform>().position, tetapi mereka membungkusnya menjadi this.transform.positionpanggilan pembantu . Pola umum lainnya adalah mengakses Rendererkomponen objek game saat ini . Jadi jika Anda ingin melakukan sesuatu seperti mengubah materi objek game saat ini, dari skrip lain Anda mungkin melakukan sesuatu seperti this.renderer.material = someOtherMaterial, dan pembaruan objek game Anda dengan tepat.

Salah satu cara ini bekerja di Unity adalah editor mereka diatur sedemikian rupa sehingga Anda dapat membuat objek game di adegan Anda yang komponennya sudah terhubung. Dalam kasus Unity, semua objek game memiliki Transformkomponen, tetapi juga dapat berisi tipe bawaan seperti AudioListeneratau Renderer, yang melakukan apa yang Anda harapkan. Atau Anda dapat menambahkan komponen Anda sendiri yang melakukan apa pun yang Anda inginkan. Editor juga memperlihatkan bidang publik / serializable pada komponen Anda sehingga Anda tidak harus membuat skrip yang berbeda jika Anda ingin menggunakan kode dasar yang sama tetapi mengubah beberapa angka ajaib di sekitar.

Secara keseluruhan, ini cukup apik, dan saya sarankan mengunduh versi gratis Unity dan bermain-main dengan bagaimana sistem scripting mereka diatur sebagai bukti konsep yang cukup baik tentang apa yang ingin Anda capai.


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.