Catatan: Saya memprogram ini dalam Javascript, tetapi harus agnostik bahasa di sebagian besar.
Saya sedang berpikir tentang mengubah mesin saya ke yang berbasis ECS.
Saya mendapatkan ide dasarnya ( catatan: ini salah, lihat jawaban saya ):
Entitas adalah objek game.
Komponen adalah bit fungsionalitas ( reactToInput()
) atau state ( position
) yang bisa "direkatkan" ke entitas.
Sistem memiliki daftar entitas yang mereka kelola dan perbarui.
Tapi, saya tidak begitu yakin bahwa saya mendapatkan implementasi dan beberapa detail ...
Pertanyaan: dapatkah sistem beroperasi pada berbagai jenis entitas? Saya biasanya memberikan contoh kelas yang disebut Scene
di mesin saya, dan itu akan melayani tujuan ini sekarang juga. Adegan adalah wadah dari semua objek yang dapat dirender, diperbarui, memengaruhi rendering (lampu), dan mungkin, di masa depan, bahkan 2DSoundEmitter
objek. Ini memiliki antarmuka tingkat tinggi sehingga pengguna tidak perlu khawatir tentang jenis objek yang sedang scene.add()
dikerjakannya, dan semua hal semacam itu.
Saya menyadari bahwa itu Scene
bisa menjadi suatu sistem. Dibutuhkan dalam entitas, menyimpannya, dan kemudian dapat memanggil metode pembaruan mereka, dan bahkan mungkin melakukan beberapa perubahan status. Tapi, ada masalah: seperti yang saya jelaskan di atas, Scene
bisa diberi makan berbagai jenis objek! Apa yang harus saya lakukan, katakanlah, situasi di mana sebuah adegan memiliki objek yang dapat diurai ("dapat digambar") dan lampu di dalamnya? Haruskah saya membuatnya memeriksa entitas sebelum berinteraksi? Atau, haruskah saya menyelesaikannya pada level yang lebih rendah lagi: membuat LightSource
komponen yang dapat ditambahkan ke objek apa pun , dan cahayanya akan menjadi entitas LightSource
dan Position
komponen. Apakah itu dapat diterima?
Juga, apakah itu praktik yang baik untuk tetap menggunakan warisan tradisional dan kelas tradisional? Misalnya, saya tidak tahu apa yang akan saya Renderer
menjadi! Ini bukan sistem, karena satu-satunya fungsi adalah untuk mengambil kamera dan pemandangan, membuat semuanya dan menerapkan efek (seperti bayangan). Itu juga mengelola konteks, lebar dan tinggi permainan, membuat terjemahan ... Tapi itu masih bukan sistem!
Sunting: dapatkah Anda menautkan sumber daya apa pun yang Anda temukan di ECS? Saya kesulitan menemukan yang bagus.
Jawaban:
Biarkan saya melihat apakah dengan mencoba memahami sebagai web / UI JS dev, saya dapat membantu. Juga, jangan melangkah terlalu jauh dalam agnostisisme bahasa. Banyak pola yang dibuat dalam bahasa lain layak dipelajari tetapi dapat diterapkan sangat berbeda di JS karena fleksibilitasnya atau sebenarnya tidak diperlukan karena sifat bahasa yang mudah ditempa. Anda dapat menghancurkan beberapa peluang jika Anda menulis kode yang menganggap JS memiliki batas yang sama dengan bahasa berorientasi OOP yang lebih klasik.
Pertama-tama, pada faktor "jangan gunakan OOP", ingat bahwa objek JavaScript seperti playdough dibandingkan dengan bahasa lain dan Anda benar-benar harus pergi keluar dari cara Anda untuk membangun mimpi buruk skema warisan-cascading karena JS bukan kelas Berbasis dan pengomposisian datang secara alami. Jika Anda menerapkan beberapa kelas konyol atau prototipe sistem hand-down di JS Anda, pertimbangkan membuangnya. Di JS kami menggunakan penutupan, prototipe, dan kami melewati fungsi seperti permen. Itu menjijikkan dan kotor dan salah tetapi juga kuat, ringkas dan itulah cara kami menyukainya.
Pendekatan berat warisan sebenarnya dieja sebagai anti-pola dalam Pola Desain dan untuk alasan yang baik sebagai siapa saja yang telah berjalan 15+ level senilai kelas atau struktur kelas-seperti untuk mencoba dan mencari tahu di mana sih versi rusak dari suatu metode datang dari dapat memberitahu Anda.
Saya tidak tahu mengapa begitu banyak programmer suka melakukan ini (terutama orang-orang java menulis JavaScript untuk beberapa alasan), tapi itu mengerikan, tidak terbaca, dan benar-benar tidak dapat dipelihara bila digunakan secara berlebihan. Warisan baik-baik saja di sana-sini, tetapi tidak terlalu diperlukan di JS. Dalam bahasa yang merupakan jalan pintas yang lebih memikat, itu harus benar-benar dicadangkan untuk masalah arsitektur yang lebih abstrak daripada skema pemodelan yang lebih literal seperti frankensteining implementasi zombie melalui rantai pewarisan yang menyertakan BunnyRabbit karena kebetulan bekerja. Itu bukan kode yang baik digunakan kembali. Ini adalah mimpi buruk pemeliharaan.
Sebagai JS dev Entity / Component / System engine engine menyerang saya sebagai sistem / pola untuk decoupling masalah desain dan kemudian mengomposit objek untuk implementasi pada level yang sangat granular. Dengan kata lain, permainan anak dalam bahasa seperti JavaScript. Tapi biarkan saya melihat apakah saya grokking ini dengan benar terlebih dahulu.
Entity - Hal spesifik yang Anda rancang. Kita berbicara lebih banyak ke arah kata benda yang tepat (tapi tentu saja tidak sebenarnya). Bukan 'Scene', tapi 'IntroAreaLevelOne'. IntroAreaLevelOne mungkin duduk di dalam kotak sceneEntity dari beberapa jenis tetapi kami fokus pada sesuatu yang spesifik yang bervariasi dari hal-hal terkait lainnya. Dalam kode tersebut, suatu entitas benar-benar hanya sebuah nama (atau ID) yang diikat ke banyak hal yang harus diimplementasikan atau dibuat (komponen) agar bermanfaat.
Komponen - jenis hal yang dibutuhkan entitas. Ini adalah kata benda umum. Seperti WalkingAnimation. Dalam WalkingAnimation kita bisa mendapatkan yang lebih spesifik, seperti "Shambling" (pilihan yang baik untuk zombie dan monster tanaman), atau "ChickenWalker" (bagus untuk tipe robot reverse-joint ed-209ish). Catatan: Tidak yakin bagaimana itu bisa lepas dari rendering model 3D seperti itu - jadi mungkin contoh omong kosong tapi saya lebih dari pro JS daripada pengembang game yang berpengalaman. Di JS saya akan meletakkan mekanisme pemetaan dalam kotak yang sama dengan komponen. Komponen dalam hak mereka sendiri cenderung ringan pada logika dan lebih dari peta jalan memberitahu sistem Anda apa yang harus diterapkan jika sistem bahkan diperlukan (dalam upaya saya di ECS beberapa komponen hanya kumpulan set properti). Setelah komponen terbentuk, itu '
Sistem - Daging program yang sebenarnya ada di sini. Sistem AI dibangun dan dihubungkan, Rendering tercapai, sekuens animasi dibuat, dll ... Saya menghabiskan sebagian besar ini untuk imajinasi tetapi dalam contoh System.AI mengambil banyak properti dan mengeluarkan fungsi yang digunakan untuk menambahkan event handler ke objek yang akhirnya akan digunakan dalam implementasi. Kuncinya tentang System.AI adalah bahwa ia mencakup beberapa jenis komponen. Anda bisa memilah-milah semua barang AI dengan satu komponen tetapi untuk melakukannya adalah salah paham tentang titik pembuatan barang-barang granular.
Pikirkan Tujuan: Kami ingin membuatnya mudah untuk menyambungkan beberapa jenis antarmuka GUI untuk non-desainer untuk dengan mudah mengubah berbagai jenis barang dengan memaksimalkan dan mencocokkan komponen dalam paradigma yang masuk akal bagi mereka, dan kami ingin menjauh dari skema kode arbitrer populer yang jauh lebih mudah untuk ditulis daripada harus dimodifikasi atau dipelihara.
Jadi di JS, mungkin kira-kira seperti ini. Game devs, tolong beri tahu saya jika saya salah:
Sekarang kapan pun Anda membutuhkan NPC, Anda bisa membuatnya
npcBuilders.<npcName>();
GUI dapat menyambung ke objek npcEntities dan komponen dan memungkinkan desainer untuk mengubah entitas lama atau hanya dengan mencampur dan mencocokkan komponen (meskipun tidak ada mekanisme di sana untuk komponen non-standar tetapi komponen khusus dapat ditambahkan dengan cepat di kode selama ada komponen yang ditentukan untuk itu.
sumber
Saya telah membaca tentang Entity Systems di artikel yang diberikan orang-orang baik di komentar, tetapi saya masih memiliki beberapa keraguan, jadi saya mengajukan pertanyaan lain .
Pertama, definisi saya salah. Entitas dan Komponen hanyalah pemegang data yang bodoh, sementara sistem menyediakan semua fungsionalitas.
Saya cukup belajar untuk menutupi sebagian besar pertanyaan saya di sini, jadi saya akan menjawabnya.
The
Scene
kelas I bicarakan seharusnya tidak menjadi sebuah sistem. Namun, itu harus menjadi manajer pusat yang dapat menampung semua entitas, memfasilitasi pesan, dan bahkan mungkin mengelola sistem. Itu juga dapat berfungsi sebagai semacam pabrik untuk entitas, dan saya telah memutuskan untuk menggunakannya seperti itu. Itu dapat mengambil semua jenis entitas, tetapi kemudian harus memberi makan entitas itu ke sistem yang sesuai (yang, karena alasan kinerja, tidak boleh melakukan pemeriksaan tipe apa pun, kecuali bitwise).Saya seharusnya tidak menggunakan OOP saat mengimplementasikan ES, saran Adam, tetapi saya tidak menemukan alasan untuk tidak memiliki objek dengan metode untuk kedua entitas dan komponen, bukan hanya pemegang data bodoh.
Ini
Renderer
hanya dapat diimplementasikan sebagai suatu sistem. Itu akan memelihara daftar objek yang dapat digambar dan memanggildraw()
metode komponen render mereka masing-masing 16 ms.sumber
Pengantar manajemen ketergantungan 101.
Kursus ini mengasumsikan Anda memiliki pengetahuan dasar tentang injeksi ketergantungan dan desain repositori.
Ketergantungan injeksi hanyalah cara mewah untuk objek untuk berbicara satu sama lain (melalui pesan / sinyal / delegasi / apa pun) tanpa langsung digabungkan.
Itu berjalan dengan ungkapan: "
new
adalah lem."Saya akan menunjukkan ini dalam C #.
Ini adalah sistem dasar untuk Input, Gerakan, dan Rendering. The
Player
kelas entitas dalam kasus ini dan komponen adalah Interfaces. ThePlayer
kelas tahu apa-apa tentang internal bagaimana betonIRenderSystem
,IMovementSystem
atauIInputSystem
pekerjaan. Namun, antarmuka menyediakan cara untukPlayer
mengirim sinyal (misalnya memanggil Draw di IRenderSystem) tanpa tergantung pada bagaimana hasil akhir dicapai.Sebagai contoh, ambil implementasi IMovementSystem saya:
MovementSystem
dapat memiliki dependensinya sendiri danPlayer
bahkan tidak akan peduli. Dengan menggunakan antarmuka, mesin status permainan dapat dibuat:Dan itu adalah awal dari permainan yang indah (itu juga bisa diuji unit).
Dan dengan beberapa tambahan dan beberapa polimorfisme:
Kami sekarang memiliki sistem entitas / komponen primitif yang didasarkan pada antarmuka agregasi dan warisan yang longgar.
sumber