Saya membuat game 2D top-down dan saya ingin memiliki banyak tipe serangan yang berbeda. Saya ingin membuat serangan sangat fleksibel dan bisa dikombinasikan seperti cara Binding of Isaac bekerja. Ini dia daftar semua koleksi dalam permainan . Untuk menemukan contoh yang baik, mari kita lihat item Spoon Bender .
Spoon Bender memberi Isaac kemampuan untuk menembakkan air mata di rumah.
Jika Anda melihat bagian "sinergi", Anda akan melihatnya dapat dikombinasikan dengan koleksi lain untuk efek yang menarik namun intuitif. Misalnya, jika digabungkan dengan Mata Bagian Dalam , itu "Akan memungkinkan Ishak untuk menembakkan beberapa tembakan homing sekaligus". Ini masuk akal, karena The Inner Eye
Memberikan Isaac tembakan tiga kali lipat
Apa arsitektur yang baik untuk merancang hal-hal seperti ini? Inilah solusi brute force:
if not spoon bender and not the inner eye then ...
if spoon bender and not the inner eye then ...
if not spoon bender and the inner eye then ...
if spoon bender and the inner eye then ...
Tapi itu akan lepas kendali dengan sangat cepat. Apa cara yang lebih baik untuk merancang sistem seperti ini?
sumber
Jawaban:
Anda sama sekali tidak perlu menggunakan kombinasi kode tangan. Sebagai gantinya, Anda dapat fokus pada properti yang diberikan setiap item kepada Anda. Misalnya, Item A set
Projectile=Fireball,Targetting=Homing
. Item B setFireMode=ArcShot,Count=3
. TheArcShot
logika bertanggung jawab untuk mengirimkanCount
jumlahProjectile
item dalam busur.Dua item ini dapat dikombinasikan dengan item lain yang memodifikasi properti (atau lainnya) ini secara bebas. Jika Anda menambahkan proyektil jenis baru, ia hanya akan bekerja secara otomatis
ArcShot
, dan jika Anda menambahkan mode pembakaran baru, ia akan secara otomatis bekerja denganFireball
proyektil. Demikian juga,Targetting
adalah properti yang mengatur pengontrol untuk proyektil sementaraFireMode
membuat proyektil, sehingga mereka dapat dengan mudah dan sepele dikombinasikan dalam kombinasi apa pun yang masuk akal.Anda juga dapat mengatur dependensi properti dan semacamnya. Misalnya,
ArcShot
mengharuskan Anda memiliki penyediaProjectile
(yang mungkin saja merupakan default). Anda dapat menetapkan prioritas sehingga jika Anda memiliki dua item aktif yang keduanya memberikanProjectile
kode tahu mana yang akan digunakan. Atau Anda dapat menyediakan UI untuk memungkinkan pengguna memilih jenis proyektil mana yang akan digunakan, atau hanya meminta pemain untuk melepaskan item prioritas tinggi yang tidak ia inginkan, atau menggunakan item terbaru, dll. Anda selanjutnya dapat memungkinkan sistem yang tidak kompatibel. , mis. sedemikian rupa sehingga dua item yang baru saja dimodifikasiProjectile
tidak dapat keduanya dilengkapi secara bersamaan.Secara umum, jika mungkin, lebih suka segala jenis pendekatan yang didorong data (atau deklaratif ) daripada pendekatan prosedural (masalah besar jika ada) ketika datang ke objek dan semacamnya dalam game Anda. Logika generik tingkat tinggi yang dapat dikonfigurasi oleh data sederhana jauh lebih disukai daripada daftar hard-coded aturan khusus.
sumber
Jika Anda menggunakan bahasa OOP, ini terdengar seperti tempat yang baik untuk menggunakan Pola Penghias . Saat Anda ingin memodifikasi bagaimana serangan terjadi, hiasi saja dengan augmentasi yang sesuai.
Crude c ++ Contoh:
Metode ini akan lebih baik jika Anda memiliki jumlah serangan yang sangat besar dan Anda harus memiliki mereka semua berperilaku kurang lebih dengan cara yang sama. Jika Anda ingin secara substansial mengubah cara serangan terjadi dengan pengubah (mis. Animasi baru dengan pengubah) maka metode ini bukan untuk Anda.
sumber
Attack
metode objek yang dikumpulkannya. TheTripleAttack
kelas tidak harus tahu tentangTearAttack
kelas. Jika ini benar maka itu akan menyebabkan sakit kepala sebanyakelse-if
blok. Ini berarti bahwa setiap animasi air mata harus berada di dalamTearAttackBehaviour
objek. Objek ini tidak (dan seharusnya tidak) tahu itu telah didekorasi olehTripleAttack
objek. Hasilnya adalah bahwa 3 animasi air mata melanjutkan independen, karena yang independen.Sebagai penggemar Binding of Isaac, saya juga bertanya-tanya bagaimana caranya seperti ini. Sistem dalam permainan cukup kuat di mana perilaku yang muncul muncul dari kombinasi efek (salah satu yang muncul di benak saya adalah mendapatkan cermin, penyok sendok, dan beberapa penguat jangkauan menghasilkan dinding air mata berputar-putar di sekitar Ishak, gaya Magneto ). Jumlah mereka yang banyak akan membuat blok "jika" tidak praktis.
Kesimpulan saya adalah bahwa Ishak dan air matanya adalah dua entitas di tengah Kerangka Kerja Entitas-Entitas besar . Entitas memiliki beberapa statistik dasar (movepeed, life, range, damage, sprite, dll) dan setiap komponen akan membawa pengubah stat dan kata kerja.
Dalam kode, Isaac dan air matanya masing-masing akan memiliki daftar yang akan berisi hal-hal antarmuka. Isaac akan memiliki daftar hal-hal yang berlangganan antarmuka IsaacMutator, dan air matanya tearMutator. IsaacMutator akan memiliki fungsi untuk memodifikasi kesehatan, kecepatan, jangkauan, penampilan, dan beberapa kata kerja khusus Isaacs. TearMutator akan serupa. Sekali per game loop, Isaac akan mengulangi semua IsaacMutators yang dimilikinya, dan semua air mata hidup juga. Untuk menggunakan contoh bahasa Inggris Anda, itu akan berbunyi seperti:
dan seterusnya. Karena jenisnya adalah aditif, Anda dapat menumpuk dan menambah dan menghapus isi hati Anda.
sumber
Saya pikir cara Anda bekerja paling baik. Barang-barang semacam ini masing-masing memberikan kondisi, jika digunakan bersama-sama menghasilkan kondisi yang berbeda, maka Anda akan secara efektif membutuhkan ketiga kondisi yang mungkin ditentukan.
Anda juga bisa melakukannya dengan membuat jenis definisi baru ketika kedua item hadir, tetapi ini sebenarnya menambah konvolusi:
sumber