Làm thế nào để thiết kế lớp tấn công trong một game RPG?


37

Tôi đang trong giai đoạn lập kế hoạch của một trò chơi RPG nhỏ.

Nhân vật sẽ có một tập hợp các thuộc tính, như sức mạnh, sự nhanh nhẹn, v.v ... được thể hiện dưới dạng số nguyên. Nhân vật cũng sẽ có một tập hợp các cuộc tấn công được thể hiện dưới dạng một lớp tấn công.

Trên mỗi đòn tấn công, tôi muốn nó gây sát thương dựa trên các thuộc tính của nhân vật, ví dụ: đòn tấn công "kiếm chém" sẽ gây ra 10 dmg + giá trị sức mạnh của nhân vật.

Cách tôi nghĩ để làm điều này là có một lớp tấn công trừu tượng, có một phương thức Tấn công trừu tượng và với mỗi cuộc tấn công tôi tạo ra một lớp thực hiện phương thức Tấn công.

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

Tôi thấy rằng điều này sẽ làm cho nó trở thành một cơn ác mộng để duy trì.

Có ai có ý tưởng làm thế nào tôi có thể thực hiện điều này một cách đẹp hơn không?

Điều tôi nghĩ là vấn đề chính là làm thế nào để nhập thuộc tính chính xác, dựa trên cuộc tấn công.

Câu trả lời:


34

Bạn có lẽ nên đi cho một thiết kế dựa trên dữ liệu ở đây.

Tạo một lớp Tấn công chung chứa các tham số bạn muốn làm việc với - sát thương cơ bản, chỉ số này ảnh hưởng đến sát thương, một tập hợp các hiệu ứng trạng thái tiềm năng ... đại loại như thế:

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.
  }
}

Sau đó, đặt các cuộc tấn công của bạn vào một tệp, ví dụ: tệp XML và tải dữ liệu từ đó:

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

Bạn thậm chí có thể mở rộng điều này để rút ra các giá trị từ nhiều chỉ số, giả sử, một Quả cầu lửa trong đó thiệt hại được tính từ cả Trí tuệ và Chỉ số Lửa:

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

Nếu bạn không muốn sử dụng cùng một công thức sát thương cơ bản cho mọi thứ (ví dụ: tính toán sát thương phép khác với sát thương vật lý), hãy tạo các lớp con Tấn công cho mỗi công thức bạn cần và ghi đè Tấn công và chỉ định loại bạn muốn trong tệp XML của mình.


1
+1, nhưng tôi thậm chí sẽ thay thế GetStatValue bằng một bảng tra cứu nào đó để tránh duy trì câu lệnh chuyển đổi đó.

1
Vấn đề với phương pháp này là bạn chỉ có thể có các cuộc tấn công dựa trên dữ liệu chung - bạn không thể có bất cứ điều gì sử dụng logic đặc biệt. Bạn sẽ kết thúc với một bộ vật phẩm rất chung chung (như bạn nhận được trong warcraft
Iain

2
@Iain: Điều đó rất dễ giải quyết bằng cách thêm nhiều dữ liệu để cho phép điều này. Ví dụ, bạn có thể có một lớp con SpecialAttack thực hiện nhiều việc hơn hoặc tính toán thiệt hại theo một cách hoàn toàn khác. Đó chỉ là vấn đề xác định hành vi bạn cần, và sau đó thể hiện đó là dữ liệu.
Michael Madsen

2
@Iain: Ngoài việc chỉ thêm nhiều trường, bạn cũng có thể giải quyết điều đó bằng một số trường dữ liệu là biểu thức hoặc khối mã trong ví dụ Lua. Sử dụng tốt các thành phần trực giao cũng làm cho kết quả thú vị hơn.

1
+1 cho ý tưởng chung là được điều khiển dữ liệu. Tôi không đồng ý với đề xuất xml. Có các định dạng tốt hơn ngoài kia - yaml, json hoặc tệp .lua đơn giản nếu bạn đang nhúng Lua.
egarcia


2

Tôi sẽ có một lớp vũ khí có phương thức tấn công mà bạn ghi đè lên hành vi bạn muốn. Sau đó, bạn cũng có thể xử lý vũ khí trông như thế nào trong trò chơi, trong kho, bao nhiêu nó được bán với giá vv trong cùng một lớp.


6
-1, không chỉ điều này không dựa trên dữ liệu, đó là hệ thống phân cấp sâu chứ không phải theo thành phần. Đó là giải pháp tồi tệ nhất có thể.

4
Chỉ vì phương pháp đặc biệt này không dựa trên dữ liệu sẽ không làm cho nó trở thành một lựa chọn tồi và hệ thống phân cấp sẽ không sâu sắc. Nó đơn giản nhưng vẫn mạnh mẽ (UnrealEngine là một ví dụ hoàn hảo về điều này) nếu được thực hiện chính xác (nghĩa là không có giá trị mã hóa cứng). Chắc chắn rằng nó có nhược điểm của nó, nhưng tiếp tục chu kỳ phát triển của một hệ thống dựa trên dữ liệu, tôi chắc chắn rằng những nhược điểm của nó được thể hiện. Tôi nghĩ rằng thiết kế OOP cơ bản của bạn vẫn là một giải pháp hợp lệ trong trường hợp này và nếu anh ta muốn chỉnh sửa các giá trị mặc định, nó có thể được thực hiện trên một hệ thống phân cấp dễ dàng như vậy.
Dalin Seivewright

6
Không phải mọi thứ đều phải dựa trên dữ liệu - nó phụ thuộc vào quy mô của trò chơi. Có lẽ hơi kiêu ngạo khi nghĩ rằng câu trả lời của tôi là "sai", nhưng cảm ơn vì sự trung thực của bạn. Tôi nghĩ rằng đây chỉ là sự kết hợp giữa các phong cách giữa những gì phù hợp với tôi, tạo ra các trò chơi Flash mỗi ngày và mô hình phát triển truyền thống hơn của bạn. Tôi có thể nói với bạn cách tiếp cận của tôi nhanh hơn nhiều để thực hiện và bạn có kiểm tra thời gian biên dịch tốt hơn. Nhận xét của bạn lại. Lua giả định rằng người hỏi đang làm việc trên một nền tảng sẽ hỗ trợ điều đó.
Iain

2
Là một game RPG, có lẽ việc thực hiện mọi mục như vậy là không thực tế.
Vaughan Hilts

1

Tôi thực sự mới với điều này, nhưng cách tôi làm là tạo ra một lớp tấn công chung.

Khi một thể hiện ký tự muốn tấn công một thể hiện ký tự khác, nó sẽ tạo một thể hiện của lớp tấn công, chứa đầy dữ liệu cần thiết và ID của ký tự đã tạo ra nó. Điều chỉnh từ thiết bị sau đó sẽ được áp dụng cho đối tượng tấn công, sử dụng dữ liệu có thể được nhập trong tài liệu xml hoặc tương tự.

Ví dụ lớp này sau đó sẽ được bọc bên trong một lớp khác, để cung cấp các hook cho môi trường để xác định phạm vi hoặc tương tự. Nếu cuộc tấn công là hợp lệ, trường hợp tấn công sẽ được chuyển cho nhân vật bị tấn công, người sẽ áp dụng các hiệu ứng.

Hy vọng rằng có ý nghĩa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.