• 締切済み

RPGの主人公、町人、敵キャラのクラス関係

・町人は移動処理のみ ・主人公は移動処理とステータス ・敵キャラはステータス をもっているクラスとします。 この場合、どのように抽象クラスと継承を設計するべきでしょうか? 町人と主人公は共通の親、主人公と敵キャラは共通の親をもつべきかと思いますが 主人公が多重継承になってしまいます。 また、町人と主人公の親を作り、主人公から敵キャラへ継承すると 敵キャラに不要なメソッドを多く引き継がせることになってしまいます。

みんなの回答

  • hatimiti
  • ベストアンサー率68% (26/38)
回答No.4

No.3です。 ご認識されている構成です。 ただあくまでも私自身のゲームに合わせて構成しているので、 適宜修正していくのが良いと思います。

  • hatimiti
  • ベストアンサー率68% (26/38)
回答No.3

私も今Javaでゲームを作っていますが、 全てのゲームオブジェクト(Entityと呼んでいる)に BaseEntity(クラス)を継承させ、 移動処理や攻撃処理などは必要に応じて Movable(移動インタフェース)、Attackable(攻撃インタフェース)を用意し実装させています。 共通のインタフェースを実装しているオブジェクト同士は、 継承と同様まとめて操作できるので。 ※BaseEntityより上位でも、さらに共通部分があればBase(クラス)を用意していますが。 ステータスはまだ未実装ですが、No.1さんのように、委譲する形で実装しようとは考えています。

oxfax
質問者

お礼

やはり機能の追加はインターフェースなのですね。 >Movable(移動インタフェース)、Attackable(攻撃インタフェース) 私もこのように実装してみようと思います。 すべてBaseEnityを継承といっても、さらにその下に複数の親がいるのだと思いますが 以下のようなイメージで合っていますか? BaseEntity | |-BattleChara-|-Friend (Movable, Attackable) |         |-Enemy (Attackable) |-NonPlayerv(Movable) | |-OtherObject

  • world99
  • ベストアンサー率64% (20/31)
回答No.2

戦闘に関する処理を親クラスで定義する必要はありません。 戦闘処理を管理するクラスを用意することでもできます。 6.戦闘管理クラス;BattleManager 戦闘処理を管理するクラス。 public class BattleManager { public static int attack (Status status, char chara) { return 0; } public static int guard (Status status, int damage) { status.hp = status.hp - damage; return status.hp; } public static int magic (Status status, char chara) { return 0; } } 7.戦闘インターフェース:BattleInterface 人クラスと敵クラスに実装させるインターフェース。 public interface BattleInterface { int attack (char chara); int guard (int damage); int magic (char chara); } 4’.主人公クラス:Hero public class Hero extends Person implements BattleInterface { private Status status = null; public Hero() { this.status = new Status(); } public Status getStatus() { return this.status; } public int attack(char chara) { return BattleManager.attack(this.status, chara); } public int guard(int damage) { return BattleManager.guard(this.status, damage); } public int magic(char chara) { return BattleManager.magic(this.status, chara); } } 5’.敵キャラ・クラス:Monster public class Monster implements BattleInterface { private Status status; public Status getStatus() { return this.status; } public int attack(char chara) { return BattleManager.attack(this.status, chara); } public int guard(int damage) { return BattleManager.guard(this.status, damage); } public int magic(char chara) { return BattleManager.magic(this.status, chara); } } 先の回答で移動処理を人・抽象クラスに定義しましたが、 戦闘処理クラスを抽象クラスにして、 移動処理を管理するクラスとして実装してもいいかもしれません。 もし移動処理、戦闘処理のほかに、修行処理とか新しい機能を追加したくなった時に 継承だけでクラスを設計しようとすると無理があります。 全体の仕様を考慮しながら柔軟なクラス設計を心がけましょう。

oxfax
質問者

お礼

戦闘のオブジェクトはステータスだけではキャラクターを特定できないので 何らかのオブジェクトで渡す必要があるかと思うのですが (this.status, chara)などのパラメータだけで様々な戦闘処理を網羅できるのでしょうか? BattleManagerに関してはご指摘通りインターフェースを介して実装してみようと思います。

  • world99
  • ベストアンサー率64% (20/31)
回答No.1

以下のクラス構成では如何でしょうか。 1.人・抽象クラス:Person 移動処理を実装する。町人クラスと主人公クラスで継承。 public abstract class Person { public int walk() { return 0; } public int run() { return 0; } } 2.ステータス・クラス:Status 主人公クラスと敵キャラクラスがメンバ変数として利用。 public class Status { public int hp; public int mp; public int power; public int physical; public int speed; public int knowledge; } 3.町人クラス:Resident 人・抽象クラスを継承。 public class Resident extends Person { } 4.主人公クラス:Hero 人・抽象クラスを継承。ステータスクラスをメンバ変数として定義。 public class Hero extends Person { private Status status; public Status getStatus() { return this.status; } } 5.敵キャラ・クラス:Monster ステータスクラスをメンバ変数として定義。 public class Monster { private Status status; public Status getStatus() { return this.status; } }

oxfax
質問者

お礼

ありがとうございます。 ステータスを構造体のように扱おうとは思っていました。 しかし、主人公と敵キャラは戦闘中に共通の抽象クラスで処理したいのです。 int attack(Chara chara) のようなメソッドでは親クラスとして扱う必要があるので。 インターフェースを使おうとも思いましたが、どうすれば綺麗に使えるのかわかりません。

関連するQ&A

専門家に質問してみよう