Bagaimana cara merancang kelas serangan dalam game RPG?

37

Saya sedang dalam tahap perencanaan gim gaya RPG kecil.

Karakter akan memiliki seperangkat atribut, seperti kekuatan, kelincahan, dll yang direpresentasikan sebagai bilangan bulat. Karakter juga akan memiliki seperangkat serangan yang direpresentasikan sebagai kelas serangan.

Pada setiap serangan saya ingin melakukan kerusakan berdasarkan atribut karakter, misalnya: serangan "pedang slash" akan melakukan 10 dmg + nilai kekuatan karakter.

Cara saya berpikir untuk melakukan ini adalah memiliki kelas serangan abstrak, yang memiliki metode Serangan abstrak, dan untuk setiap serangan saya membuat satu kelas yang menerapkan metode Serangan.

public class SwordSlash:Attack
{
    public void Attack(Character attacker, Character defender)
    {
        defender.DoDamage(10 + attacker.Strength);
    }
}

Saya melihat bahwa ini akan membuatnya menjadi mimpi buruk untuk dipertahankan.

Adakah yang tahu bagaimana saya bisa mencapai ini dengan cara yang lebih baik?

Apa yang saya pikirkan adalah masalah utama adalah bagaimana cara memasukkan atribut yang benar, berdasarkan serangan.

eflles
sumber

Jawaban:

34

Anda mungkin harus menggunakan desain berbasis data di sini.

Buat kelas Serangan umum yang berisi parameter yang ingin Anda kerjakan - kerusakan dasar, yang statistik memengaruhi kerusakan, serangkaian efek status potensial ... hal-hal seperti itu:

public enum AttackStat
{
  Strength,
  Agility,
  Intellect
  // etc.
}

public class Attack
{    
  private int baseDamage;
  private AttackStat stat;
  private double damageMultiplier;
  // ...and so on

  public void Attack(Character attacker, Character defender)
  {
    defender.DoDamage(baseDamage + attacker.GetStatValue(stat) * damageMultiplier);
  }    
}

// Put a method on Character to fetch the appropriate value given an AttackStat:
public int GetStatValue(AttackStat s)
{
  switch(s)
  {
    case AttackStat.Strength:
      return strength;
    case AttackStat.Agility:
      return agility;
    // etc.
  }
}

Lalu, tempatkan serangan Anda di file, mis. File XML, dan muat data dari sana:

<Attacks>
  <Attack name="Sword Slash" damage="10" stat="Strength" multiplier="1" />
  <!-- More attacks here -->
</Attacks>

Anda bahkan dapat memperluas ini untuk menarik nilai dari beberapa statistik, katakanlah, bola api di mana kerusakan dihitung dari kedua Intellect dan stat Api:

<Attack name="Fireball" damage="20">
  <StatModifier stat="Intellect" multiplier="0.4" />
  <StatModifier stat="Fire" multiplier="0.8" />
</Attack>

Jika Anda tidak ingin menggunakan rumus kerusakan dasar yang sama untuk semuanya (mis. Menghitung kerusakan sihir secara berbeda dari kerusakan fisik), buat subkelas Serangan untuk setiap rumus yang Anda butuhkan dan timpa Serangan, dan tentukan jenis yang Anda inginkan dalam file XML Anda.

Michael Madsen
sumber
1
+1, tapi saya bahkan akan mengganti GetStatValue dengan tabel pencarian semacam untuk menghindari mempertahankan pernyataan beralih itu.
1
Masalah dengan metode ini adalah bahwa Anda hanya dapat memiliki serangan data-driven generik - Anda tidak dapat memiliki apa pun yang menggunakan logika khusus. Anda akan berakhir dengan satu set barang yang sangat umum (seperti yang Anda dapatkan di warcraft
Iain
2
@ Iain: Itu sangat mudah diselesaikan dengan hanya menambahkan lebih banyak data untuk memungkinkan ini. Misalnya, Anda mungkin memiliki subclass SpecialAttack yang melakukan lebih banyak hal, atau menghitung kerusakan dengan cara yang sama sekali berbeda. Ini hanya masalah mengidentifikasi perilaku yang Anda butuhkan, dan kemudian menyatakannya sebagai data.
Michael Madsen
2
@ Iain: Selain hanya menambahkan lebih banyak bidang, Anda juga dapat menyelesaikannya dengan beberapa bidang data menjadi ekspresi atau blok kode di misalnya Lua. Penggunaan komponen orthogonal yang baik juga membuat hasil yang lebih menarik.
1
+1 untuk gagasan umum yang didorong oleh data. Saya tidak setuju dengan menyarankan xml. Ada format yang lebih baik di luar sana - yaml, json atau file .lua biasa jika Anda menanamkan Lua.
egarcia
2

Saya akan memiliki kelas senjata yang memiliki metode serangan yang Anda timpa dengan perilaku yang Anda inginkan. Anda kemudian dapat juga menangani bagaimana senjata terlihat dalam game, dalam inventaris, berapa banyak yang dijual untuk dll di kelas yang sama.

Iain
sumber
6
-1, ini bukan saja bukan data-driven, ini hierarki yang dalam daripada komponen-driven. Ini solusi terburuk yang mungkin.
4
Hanya karena metode khusus ini tidak didorong oleh data tidak menjadikannya pilihan yang buruk dan hierarki tidak akan sedalam itu. Ini sederhana namun tetap kuat (UnrealEngine adalah contoh sempurna dari ini) jika dilakukan dengan benar (mis. Tidak ada nilai yang dikodekan). Tentu ini memiliki kelemahan, tetapi lebih jauh ke bawah siklus pengembangan sistem berbasis data, saya yakin kelemahannya akan ditampilkan. Saya pikir desain OOP dasar Anda masih merupakan solusi yang valid dalam hal ini dan jika ia ingin mengedit nilai default dengan cepat, itu dapat diimplementasikan di atas sistem hierarki dengan mudah.
Dalin Seivewright
6
Tidak semuanya harus berbasis data - itu tergantung pada skala gim. Mungkin agak sombong untuk berpikir bahwa jawaban saya "salah", tetapi terima kasih atas kejujuran Anda. Saya pikir ini hanyalah benturan gaya antara apa yang berhasil bagi saya, membuat game Flash setiap hari, dan model pengembangan yang lebih tradisional. Saya dapat memberitahu Anda bahwa pendekatan saya jauh lebih cepat untuk diterapkan dan Anda harus memeriksa waktu kompilasi dengan lebih baik. Komentar Anda kembali. Lua mengasumsikan si penanya bekerja pada platform yang akan mendukung itu.
Iain
2
Menjadi game RPG, mungkin tidak praktis untuk mengimplementasikan setiap item seperti itu.
Vaughan Hilts
1

Saya benar-benar baru dalam hal ini, tetapi cara saya akan melakukannya adalah membuat kelas serangan generik.

Ketika satu instance karakter ingin menyerang instance karakter lain, ia akan membuat instance dari kelas serangan, diisi dengan data yang diperlukan, dan ID karakter yang membuatnya. Penyesuaian dari gir kemudian akan diterapkan ke objek serangan, menggunakan data yang bisa dimasukkan dalam dokumen xml atau serupa.

Contoh kelas ini kemudian akan dibungkus di dalam kelas lain, untuk menyediakan kait bagi lingkungan untuk menentukan kisaran atau serupa. Jika serangan itu valid, instance serangan akan diteruskan ke karakter yang diserang, siapa yang akan menerapkan efek.

Harapan itu masuk akal.

Dave
sumber