講義メモ

オブジェクト指向演習:仕上げ(継承によるラスボスの生成と登場)
ゲーム開発演習:画像のプロパティ、画像の重ね合わせ、キーが押された情報を得る など

RPG演習9 3人の魔導士 ver.5 継承によるラスボス(大魔道)の生成と登場

・ラスボス(大魔道)はDaimadoクラスで実装する
・Daimadoクラスは機能が重複するMadoshiクラスを継承することで効率的に扱う
・下記はそのまま継承できる
 ① public int HP //HPを返すプロパティ
 ② public int Fight() //魔道士があなたを攻撃し、あなたのダメージ値を返す
 ③ public void Damage() //魔道士があなたからダメージをくらう
・public void DispInfo()はオーバライドして、大魔道用にアレンジしよう
・public static bool isSurvプロパティは、new public bool isSurvプロパティとして隠ぺいし、大魔道用にアレンジしよう
・データメンバはそのままで良い(ただし、int id; //魔導士番号 は用いない)
・コンストラクタは、MPとHPの初期値を40~49にする。mnum、id、survに関する処理は不要
・minimadouクラスのMainメソッドでは、メインループの後に大魔道戦を追記する
・内容は「3人の魔導士」とほぼ同じだが、配列を用いずに、下記をアレンジしよう
 ① 戦闘開始では、プレイヤーのHPを回復(倍増)し、大魔道を生成して情報を表示する
 ②「あなたのHPがあり、生きている魔導士がいる間」は「あなたと大魔道のHPがある間」に
 ③「どれを攻撃しますか?(1/2/3:魔導士を攻撃 0:やめる):」を「攻撃しますか?(1:攻撃 0:やめる)」に
 ④「攻撃対象の魔導士の添字を得る」ことは不要
 ⑤「魔導士の数だけ繰返す」ことは不要
 ⑥「全ての魔道士を倒した!」は「大魔道を倒した」にする

作成例(完成版)

//オブジェクト指向演習 RPG演習9 3人の魔導士 ver.5 継承によるラスボス(大魔道)の生成と登場
using System;
class Madoshi { //魔導士を表すクラス(部品)
    protected int mp; //【変更】MP(継承可能)
    protected int hp; //【変更】HP(継承可能)
    int id; //魔導士番号
    static int mnum = 0; //魔導士が何人生成されたか
    static int surv = 0; //生きている魔導士は何人いるか
    protected static Random rnd = new Random(); //【変更】乱数用のRandomクラスのインスタンスを生成(継承可能)
    public Madoshi () { //コンストラクタ
        mp = rnd.Next(10); //0~9の間のランダムな整数を得てMPの初期値とする
        hp = 10 + rnd.Next(10); //10~19の間のランダムな整数を得てHPの初期値とする
        mnum++; //魔導士が何人生成されたかをカウントアップ
        this.id = mnum; //何人目の魔導士かを得て魔導士番号を設定
        surv = mnum; //生きている魔導士の数に格納
    }
    public int HP { //HPを返すプロパティ
        get { return hp; } //getのみなので外部からのhpの書換を禁止
    }
    public static bool isSurv { //生きている魔導士がいるかを返すプロパティ
        get { return surv > 0; } //生きている魔導士がいればtrue、いなければfalseを返す
    }
    public virtual void DispInfo() { //【変更】魔導士の情報を表示する仮想メソッド
        Console.Write("魔道士{0}(HP={1} MP={2})", id, hp, mp); //表示(改行しない)
    }
    public int Fight() { //魔道士があなたを攻撃し、あなたのダメージ値を返す
        if (hp <= 0) { //すでに倒されていたら
            return 0; //0を返す
        }
        if (rnd.Next(2) == 1) { //確率1/2で魔法攻撃かどうかを選ぶ
            int j = rnd.Next(5) + 1; //消費MPは1~5の乱数
            DispInfo(); // 魔導士の情報を表示する
            Console.WriteLine("は消費MP" + j + "の魔法を唱えた!");
            if (mp < j) { // MP不足?
                Console.WriteLine("MPが足りない!");
                return 0; // あなたのダメージ=0を返す(攻撃終了)
            } else { // MP充足?
                Console.WriteLine("あなたは" + j * 4 + "のダメージを受けた!");
                mp -= j; //MP消費
                return j * 4; //あなたのダメージ=消費MPの4倍を返す(攻撃終了)
            }
        } else { //通常攻撃?
            int k = rnd.Next(5) + 1; //攻撃力は1~5の乱数
            DispInfo(); //魔導士の情報を表示する
            Console.WriteLine("の攻撃!");
            Console.WriteLine("あなたは" + k + "のダメージを受けた!");
            return k; //あなたのダメージ=1~5を返す(攻撃終了)
        }
    }
    public void Damage() { //魔道士があなたからダメージをくらう
        if (hp <= 0) { //すでに倒されている?
            Console.WriteLine("魔道士{0}はもういない", id);
            return; //抜ける
        }
        int k = 5 + rnd.Next(5); //あなたの攻撃力は5~9の乱数
        Console.WriteLine("あなたの攻撃!");
        DispInfo(); //魔導士の情報を表示する(攻撃を受けた後の魔道士のHPを表示)
        Console.WriteLine("に" + k + "のダメージを与えた!");
        hp -= k; //魔道士のHPをダウン
        if (hp <= 0) { //倒された?
            Console.WriteLine("魔道士{0}を倒した!", id);
            surv--; //生きている魔導士の数を減らす
        }
    }
}
class Daimado : Madoshi { //【以下追加】大魔道を表すクラス(魔導士クラスの派生クラス)
    public Daimado () { //コンストラクタ
        mp = 40 + rnd.Next(10); //40~49の間のランダムな整数を得てMPの初期値とする
        hp = 40 + rnd.Next(10); //40~49の間のランダムな整数を得てHPの初期値とする
    }
    new public bool isSurv { //大魔道が生きているかを返すプロパティ
        get { return hp > 0; } //生きていればtrue、いなければfalseを返す
    }
    public override void DispInfo() { //魔導士の情報を表示するオーバライドメソッド
        Console.Write("大魔道(HP={0} MP={1})", hp, mp); //表示(改行しない)
    }
}
class minimadou { //ゲーム本体のクラス
    const int N = 3; //魔導士の数
    static string selection() { //魔導士の数に応じて「1」「1/2」「1/2/3」「1/2/3/4」…の文字列を返す
        string ans = "1"; //返す文字列
        for (int i = 1; i < N; i++) { //魔導士の数だけ繰返す
            ans += "/" + (i + 1); 
        }
        return ans;
    }
    public static void Main() { //ゲームを進行するメソッド
        Random rnd = new Random(); //乱数用のRandomクラスのインスタンスを生成
        string ans; //入力用
        // 戦闘開始
        int myhp = 20 * N; // あなたのHP(20×魔導士の数)
        Madoshi[] m = new Madoshi[N]; //魔導士の配列を生成
        for (int i = 0; i < N; i++) { //魔導士の数だけ繰返す
            m[i] = new Madoshi(); //魔導士[i]を生成
            m[i].DispInfo(); //魔道士[i]の情報を表示する
            Console.WriteLine("が現れた。");
        }
        // 戦闘中(あなたが死ぬか,魔道士が死ぬまで繰り返す)
        while (myhp > 0 && Madoshi.isSurv) { //あなたのHPがあり、生きている魔導士がいる間
            Console.Write("残りHPは{0}です。どれを攻撃しますか?({1}:魔導士を攻撃 0:やめる):", myhp, selection());
            ans = Console.ReadLine(); // 攻撃するかどうかを得る
            if (ans != "0") { //攻撃する?
                int num = int.Parse(ans) - 1; //攻撃対象の魔導士の添字を得る
                m[num].Damage(); //魔道士[num]を攻撃する
                if (Madoshi.isSurv) { //生きている魔導士がいる?
                    for (int i = 0; i < N; i++) { //魔導士の数だけ繰返す
                        myhp -= m[i].Fight(); //魔道士[i]の攻撃!あなたのHPをマイナス
                    }
                } else { //魔道士のHPがもうない?
                    Console.WriteLine("全ての魔道士を倒した!");
                }
            } else { // やめる?
                if (rnd.Next(2) == 0) { //確率50%で
                    Console.WriteLine("逃げられない!");
                    for (int i = 0; i < N; i++) { //魔導士の数だけ繰返す
                        myhp -= m[i].Fight(); //魔道士[i]の攻撃!あなたのHPをマイナス
                    }
                } else {
                    Console.WriteLine("逃げることができた");
                    break; // 繰り返し終了
                }
            }
            if (myhp <= 0) { //あなたのHPがもうない?
                Console.WriteLine("あなたは死にました。");
            }
        }
        //【以下追加】大魔道戦開始
        myhp *= 2; // あなたのHPを回復(倍増)
        Daimado dm = new Daimado(); //大魔道を生成
        dm.DispInfo(); //大魔道の情報を表示する
        Console.WriteLine("が現れた。");
        // 戦闘中(あなたが死ぬか,魔道士が死ぬまで繰り返す)
        while (myhp > 0 && dm.isSurv) { //あなたのHPがあり、生きている魔導士がいる間
            Console.Write("残りHPは{0}です。攻撃しますか?(1:攻撃 0:やめる):", myhp);
            ans = Console.ReadLine(); // 攻撃するかどうかを得る
            if (ans != "0") { //攻撃する?
                dm.Damage(); //大魔道を攻撃する
                if (dm.isSurv) { //大魔道が生きている?
                    myhp -= dm.Fight(); //大魔道の攻撃!あなたのHPをマイナス
                } else { //大魔道のHPがもうない?
                    Console.WriteLine("大魔道を倒した!");
                }
            } else { // やめる?
                if (rnd.Next(2) == 0) { //確率50%で
                    Console.WriteLine("逃げられない!");
                    myhp -= dm.Fight(); //大魔道の攻撃!あなたのHPをマイナス
                } else {
                    Console.WriteLine("逃げることができた");
                    break; // 繰り返し終了
                }
            }
            if (myhp <= 0) { //あなたのHPがもうない?
                Console.WriteLine("あなたは死にました。");
            }
        }
    }
}

補足:テキストの関連ページ

・クラスの継承:p.223
・protected:p.226
・newによる名前の隠ぺい:p.228
・メソッドのオーバライド、virtualによる仮想メソッド、overrideによるオーバーライドメソッド:p.231

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です