Mencari beberapa wawasan tentang desain pemrograman untuk tipe menyerang dan menyerang dalam sebuah game

14

Jadi, saya mulai memperkenalkan serangan ke ruang 2D RTS kami (Ini di Unity, jadi komponennya didorong). Awalnya itu sesederhana "musuh dalam jangkauan, kerusakan diterapkan". Namun akan ada beberapa "jenis" senjata / serangan yang terkait dengan kapal atau struktur khusus mereka. Serta faktor-faktor lain yang terlibat di masa lalu hanya kerusakan mentah seperti jenis kerusakan, dan mungkin inersia di masa depan.

Apakah kalian memiliki setiap unit dan tipe struktur memiliki tipe serangan itu sendiri. Berarti Anda membuat skrip untuk setiap unit / struktur yang menentukan jenis serangan, kerusakan, efek, jarak, partikel, sprite ... dll. Dan pasang itu sebagai komponen?

Atau buat skrip yang mendefinisikan jenis serangan, skrip untuk jenis proyektil yang terkait dengan itu ... dll. Dan kemudian perluas itu dan modifikasi itu untuk setiap unit, lampirkan setiap skrip ke unit / struktur.


Saya harap saya masuk akal, saya sudah merenungkan ini begitu lama saya tidak yakin apakah saya memecahkan masalah, atau hanya membuat masalah saya sendiri dan menggali diri saya ke dalam lubang.

Ketika Anda memiliki permainan yang dapat memiliki banyak jenis serangan yang mungkin atau mungkin tidak terbatas pada unit / struktur tertentu, bagaimana Anda mendesain kerangka kerja yang mengikat itu bersama-sama dengan unit / struktur tertentu dalam lingkungan desain yang digerakkan oleh komponen ?

Jika ini tidak cukup jelas, beri tahu saya.

Sunting: Jawaban yang bagus, terima kasih.

Pertanyaan yang Diperluas:

Jawabannya tampaknya bervariasi dari "setiap objek dapat memiliki skrip serangannya sendiri" hingga "Memiliki jenis serangan sebagai skrip mereka sendiri dan menetapkan bahwa untuk setiap objek untuk solusi yang lebih dapat digunakan kembali". Katakanlah saya memiliki serangan "blaster", ia menembakkan proyektil merah pada kecepatan tertentu. Kerusakan, laju kebakaran, dan ukuran proyektil tergantung pada unit yang menembaknya. Apakah lebih baik membuat skrip serangan untuk unit itu, atau mencoba dan memodifikasi "serangan blaster" agar sesuai dengan tujuan setiap unit yang ingin menggunakannya?

Douglas Gaskell
sumber
1
Untuk ide pemrograman game umum, saya ingin merujuk ke spesifikasi lengkap RPG FFV - gamefaqs.com/snes/588331-final-fantasy-v/faqs/30040
Code Whisperer

Jawaban:

12

Yah, sejujurnya saya bukan ahli dalam hal ini tapi ... Saya pikir itu tergantung pada seberapa kompleks dan beragamnya Anda pikir serangan akan terjadi. Karena ini adalah RTS, saya kira Anda akan memiliki unit atau struktur yang mungkin 10-50 atau lebih berbeda dengan tipe serangan mereka sendiri.

Opsi 1: Jika ada jumlah unit yang relatif rendah yang akan memiliki serangan yang agak mirip, saya hanya akan meletakkan semuanya dalam satu skrip besar dan menentukan parameter yang digunakan dalam inspektur.

Opsi 2: Jika, di sisi lain Anda membayangkan sejumlah besar tipe serangan dengan perilaku berbeda, Anda dapat memecah semuanya sehingga setiap unit dan bangunan mendapatkan skrip serangan unik mereka sendiri. Saya berpikir bahwa jika Anda melakukan ini, Anda mungkin ingin membuat skrip "helper" yang mendefinisikan potongan kode yang biasa digunakan yang dapat diambil oleh banyak skrip individual. Dengan cara ini Anda tidak perlu menulis ulang semuanya dan Anda akan tahu di mana semuanya berada.

Opsi 3: Apa yang Anda mungkin tidak boleh lakukan adalah memiliki pengelompokan skrip berbagi unit tertentu, ini akan membingungkan Anda dan akan menjadi berantakan jika kode yang Anda perlukan untuk serangan ada dalam 10 skrip berbeda.

Di sini, saya menggambar Anda.

masukkan deskripsi gambar di sini

Mir
sumber
2
Terimakasih banyak untuk balasannya. Untuk beberapa alasan saya mulai condong ke opsi 3, dan saya kesulitan menemukan cara untuk membenarkannya. Saya mungkin akan menuju rute ke-2, setiap unit mendapatkan skrip penyerang kustomnya sendiri dengan kode umum dibagikan dengan kode umum diserang sebagai komponen dari setiap unit / bangunan. Saya tidak yakin ke mana saya akan pergi dengan kereta pemikiran yang membawa saya ke opsi 3, terima kasih. Saya membiarkan ini terbuka sampai saya bangun di pagi hari kalau-kalau ada poster lain yang ingin berpadu.
Douglas Gaskell
Tidak masalah, itu bukan jawaban yang pasti tetapi harap ini membantu.
Mir
1
Anda dapat melakukan hibridisasi 1 dan 2 dengan meletakkan serangan serupa dalam satu skrip besar dan memisahkan serangan berbeda
ratchet freak
4
Saya terkejut # 3 direkomendasikan untuk dilawan? Bukankah seluruh poin dari kelas modular / generik sehingga setiap unit tidak harus mendefinisikan tipenya sendiri? Jika sebuah game adalah RTS, dan Siege damage (biasanya "long range") adalah tipe damage, Anda ingin mendefinisikannya sekali dan memiliki beberapa unit bergaya artileri yang merujuknya saat melakukan calcs damage mereka, sehingga jika Siege damage pernah perlu nerfed (rebalanced), Anda hanya perlu memperbarui satu kelas?
HC_
1
"Here, I drew you a picture."mengingatkan saya pada ini
FreeAsInBeer
4

Saya tidak tahu banyak tentang Unity dan saya belum melakukan pengembangan game untuk sementara waktu, jadi izinkan saya memberi Anda jawaban pemrograman umum untuk pertanyaan ini. Saya telah mendasarkan jawaban saya pada pengetahuan yang saya miliki tentang sistem entitas-komponen secara umum, di mana entitas adalah angka yang dikaitkan dengan N banyak komponen, komponen hanya berisi data, dan sistem beroperasi pada set komponen yang terkait dengan entitas yang sama.

Ruang masalah Anda adalah ini:

  • Ada beberapa cara untuk menyerang musuh dalam game secara keseluruhan.
  • Setiap kapal, struktur, dll, mungkin memiliki beberapa cara menyerang (masing-masing ditentukan dengan cara tertentu)
  • Setiap serangan mungkin memiliki efek partikelnya sendiri.
  • Serangan harus memperhitungkan beberapa faktor (seperti inersia, atau armor, misalnya), yang ada pada target dan pada pengguna.

Saya akan menyusun solusi seperti berikut:

  • Serangan memiliki pengidentifikasi - ini bisa berupa string.
  • Entitas 'tahu' bahwa ia dapat menggunakan serangan (berdasarkan pengidentifikasi serangan).
  • Ketika serangan digunakan oleh entitas, komponen tampilan yang sesuai ditambahkan ke tempat kejadian.
  • Anda memiliki beberapa logika yang tahu tentang target serangan, penyerang, dan serangan yang digunakan - logika ini harus memutuskan berapa banyak kerusakan yang Anda lakukan (dan memiliki akses ke inersia atau apa pun dari kedua entitas).

Penting bahwa titik kontak antara serangan dan entitas setipis mungkin - ini akan membuat kode Anda dapat digunakan kembali dan mencegah Anda harus membuat kode duplikat untuk setiap jenis entitas yang berbeda yang menggunakan jenis serangan yang sama . Dengan kata lain, inilah beberapa kode pseudo JavaScript untuk memberi Anda ide.

// components
var bulletStrength = { strength: 50 };
var inertia = { inertia: 100 };
var target = { entityId: 0 };
var bullets = {};
var entity = entityManager.create([bulletStrength, inertia, target, bullets]);

var bulletSystem = function() {
  this.update = function(deltaTime, entityId) {
    var bulletStrength = this.getComponentForEntity('bulletStrength', entityId);
    var targetComponent = this.getComponentForEntity('target', entityId);
    // you may instead elect to have the target object contain properties for the target, rather than expose the entity id
    var target = this.getComponentForEntity('inertia', targetComponent.entityId);

    // do some calculations based on the target and the bullet strength to determine what damage to deal
    target.health -= ....;
  }
};

register(bulletSystem).for(entities.with(['bullets']));

Maaf jawaban ini agak 'berair'. Saya hanya memiliki istirahat makan siang setengah jam dan sulit untuk datang dengan sesuatu tanpa mengetahui sepenuhnya tentang Persatuan :(

Dan Pantry
sumber
3

Ketika sebuah unit / struktur / senjata menyerang, saya mungkin akan membuat Serangan (subklas dengan semua detail menyenangkan Anda) yang mengambil penyerang dan pembela (atau pembela). Serangan kemudian dapat berinteraksi dengan target / bek (lambat, racun, kerusakan, ubah status), gambar sendiri (sinar, sinar, peluru), dan buang sendiri ketika sudah selesai. Saya dapat meramalkan beberapa masalah seperti beberapa serangan racun, jadi mungkin target Anda akan mengimplementasikan antarmuka Damageable yang berinteraksi dengan Serangan, tapi saya pikir itu adalah pendekatan yang bisa diterapkan yang modular dan fleksibel untuk diubah.

Expanded Answer
Ini adalah bagaimana saya akan mendekati serangan blaster dengan pendekatan ini . Saya akan membiarkan yang lain menjawab sendiri.

Saya ingin unit saya mengimplementasikan antarmuka IAttacker atau kelas dengan statistik serangan dasar / metode. Ketika IAttacker menyerang IDamageable, ia menciptakan Serangan spesifik yang melewati dirinya sendiri dan targetnya (IAttacker dan IDamageable, atau mungkin kumpulan IDamageable). Serangan mengambil statistik yang dibutuhkan dari IAttacker (untuk menghindari perubahan selama peningkatan atau semacamnya - kami tidak ingin Serangan mengubah statistiknya setelah diluncurkan) dan jika perlu statistik khusus, kirimkan IAttacker ke tipe yang diperlukan (mis. IBlasterAttacker) dan mendapatkan statistik khusus seperti itu.

Dengan pendekatan ini, BlasterAttacker hanya perlu membuat BlasterAttack, dan BlasterAttack menangani sisanya. Anda dapat mensubklasifikasikan BlasterAttack atau membuat FastBlasterAttacker yang terpisah, MegaBlasterAttacker, SniperBlasterAttacker, dll, dan kode serangan untuk masing-masing adalah sama (dan mungkin diwarisi dari BlasterAttack): Buat BlasterAttack dan sampaikan diri saya dan target saya di. BlasterAttack menangani rinciannya. .

ricksmt
sumber
Pada dasarnya, unit mewarisi dari antarmuka IAttacker (saya sudah punya ini), dan ada antarmuka IDamageable untuk "musuh" (punya ini juga). Ketika serangan penyerang, BlasterAttack (atau kelas turunan) dipanggil. "Serangan" ini akan mengambil data yang dibutuhkan dari IAttacker, dan menerapkannya pada IDamageable ketika proyektil mengenai? Apakah proyektil itu sendiri berisi kelas BlasterAttack, sehingga setelah dipecat, ia tidak lagi dipengaruhi oleh perubahan pada IAttacker, dan dapat menerapkan kerusakan / efek pada IDamageable hanya jika proyektilnya benar-benar mengenai.
Douglas Gaskell
Ketika Anda mengatakan "BlasterAttack (atau turunan kelas) disebut" Saya akan mengatakan BlasterAttack dibuat. Contoh BlasterAttack yang baru dibuat ini mewakili balok (atau peluru atau ray atau apa pun), jadi itu adalah proyektil. BlasterAttack menyalin statistik apa pun yang dibutuhkannya dari IAttacker dan objek yang dapat diidentifikasikan: posisi, statistik penyerang, dll. BlasterAttack kemudian melacak posisinya sendiri dan, jika ada, berlaku kerusakan pada "kontak." Anda harus mencari tahu apa yang harus dilakukan jika meleset atau mencapai tujuannya (posisi lama target). Bakar tanahnya? Menghilang? Panggilanmu.
ricksmt
Untuk Serangan area-of-effect, Anda mungkin ingin akses ke koleksi global (musuh) unit karena siapa yang berada dalam jangkauan dan di luar jangkauan dapat berubah antara tembakan dan dampak. Tentu saja, argumen yang sama dapat dibuat untuk BlasterAttack: Anda kehilangan target awal Anda, tetapi pukul pria di belakangnya. Satu-satunya kekhawatiran saya adalah bahwa Anda bisa memiliki banyak Serangan berulang melalui banyak Musuh yang mencoba mencari tahu apakah dan apa yang mereka kena. Itu masalah kinerja.
ricksmt
Ah, itu masuk akal. Untuk serangan yang tidak terjawab, proyektil akan memiliki rentang / masa pakai sendiri. Jika benda itu mengenai sesuatu yang lain sebelum akhir masa itu ia akan menerima referensi ke benda apa pun yang memiliki benda tegar yang bertabrakan dengannya, dan kerusakan akan diterapkan dengan cara itu. Sebenarnya begitulah cara semua proyektil akan bekerja, mereka tidak tahu "apa" yang mereka tuju, hanya saja mereka bepergian (tidak termasuk proyektil homing seperti rudal). Efek AEO hanya bisa mengaktifkan spider collider pada tujuan dan mendapatkan semua objek yang ada di dalamnya. Terima kasih untuk bantuannya.
Douglas Gaskell
Tidak masalah. Senang saya bisa. Lupa bahwa Persatuan membuat semua hal tabrakan ini lebih mudah.
ricksmt