【勉強日記】クラスを使ってRPGを作ろう③【第19回】

プログラミング

はじめに

今回の記事では、クラスやオブジェクト指向を使って簡単なRPGをつくる演習を引き続き行います。ポイントを解説しながら、数回にわたって記事を掲載していきます。つまずきやすい部分(実際に筆者がつまずいた部分)を中心に、初心者にもわかりやすく順を追って説明していきます。

もくじ

  • はじめに
  • もくじ
  • 今回やること・・・メインプログラムを作成する
    • 大まかな流れを確認しよう
  • RPGの開始① 入力用の関数を作っておく
  • RPGの開始② 魔法使いか騎士かを選択する ~インスタンスを生成する~
  • RPGの開始③ バトルを開始する ~whileループを使おう~
  • 残りのプログラムを書く ~最後にmain関数を呼び出そう!~
  • まとめ

今回やること・・・メインプログラムを作成する

前回のブログでは、RPGプログラムで動かしていくキャラクターのクラスを作成しました。今回は、作ったキャラクタークラスからインスタンスを作成し、実際にキャラクターを動かしていきます。

☆大まかな流れを確認

メインプログラムの大まかな流れは以下になります。

RPGがスタート

  1. 名前の入力と職業の選択  
  2. プレイヤー、モンスターのインスタンス(キャラクター)が作成される
  3.  ~以下ループ~
  4.  ☆どちらかのHPが0になった時点でループから抜け、RPGが終了
  5. プレイヤーの行動 
  6. モンスターの行動

※行動ごとにプレイヤーとモンスターのHPが表示される

これをもう少し細分化して表にしてみます。

  • 名前の入力と職業の選択 正しく入力と選択が行われた場合次へすすむ
  • 魔法使いなら1 騎士なら2 どちらかのプレイヤーインスタンスを作成する 
  • モンスターが現れる モンスターのインスタンスを作成する
  • ~以降繰り返し~ ☆どちらかのHPが0になったらループを抜けて勝敗を表示 プログラム終了
  • 攻撃か防御を選択 プレイヤーの行動
  • ダメージ表示
  • モンスターの攻撃
  • ダメージ表示
  • ~~~~~~~~ 繰り返しの範囲

これをもとにして作成していきます。

入力チェック用の関数をつくる

RPGが開始すると、まず名前の入力と職業の選択が求められます。今回はコマンドラインで入力するため、正しく入力されたときのみ次に進めるようにプログラムを書いていきます。正しく入力がチェックされているかどうかを判別するため、今回は入力チェック用の関数を作ってみます。

input_name 入力が正しい場合入力した名前を返す 正しくない場合falseを返す

input_job 入力が正しい場合1(魔法使い)か2(騎士)を返す 正しくない場合falseを返す

このように関数を作成し、どちらも入力が正しくなるまでは入力を求められるプログラムしていきます。

▼入力チェック用関数のプログラム

def input_name():
    player_name = input("あなたの名前を教えてください :")

    if player_name == '':  # 入力がない場合
        print("")
        print("正しく名前を入力してください")
        print("")
        return False

    elif len(player_name) > 20:  # 20文字以上の場合には名前が長いものとする
        print("")
        print("名前が長すぎます")
        print("")
        return False

    else:
        return player_name


def input_job():
    player_job = input("あなたの職業を教えてください 1: 魔法使い 2: 騎士 :")

    if player_job == '':
        print("")
        print("職業を入力してください")
        print("")
        return False

    elif player_job == str(1) or str(2):
        return player_job

    else:
        print("正しく職業を入力してください")
        return False

▼main関数内で呼び出し時のプログラム 

どちらの関数からもfalseが返らない(入力が正しい)場合に、whileループを抜ける

def main(): #RPGゲーム
    # ゲームスタート
    # 主人公か敵のどちらかの体力が0になったら終了
    print("")
    print("「これは勇者様!モンスターが現れて大変困っているのです。」")

    input_check = False

    while input_check is False:
        print("")
        name = input_name()
        if name is not False:
            job = input_job()
            if job is not False:
                input_check = True

魔法使いか騎士を選択する ~インスタンスを作成する~

選択された職業によって魔法使いクラスか騎士クラスどちらかのインスタンス、モンスターのインスタンスが生成されるようにします。物語上では、ここでモンスターが現れることとします。

今回は魔法使いを選んだ場合のプログラムから書いていきますが、騎士を選んだ場合でもプログラムの流れは変わりません。

  if job == str(1):  # 魔法使いクラスの場合 魔法使いインスタンスを生成
        caster = Caster(name)
        print("")
        print("「あなたは魔法使いなのですね。 是非私のお力になってください!」")
        print("")

        # モンスターが現れたのでインスタンスを生成
        enemy = Enemy()
        monster = enemy.monster[0] # モンスターの種類(スライムなど)を取り出す
        print(f"{monster}があらわれた!")

    # 今回戦うモンスターの体力とプレイヤーの体力をHPの変数に代入
        enemy_HP = int(enemy.monster[1])
        player_HP = int(caster.HP)

プレイヤーとモンスターの行動を書いていく ~whileループを使おう~

いよいよプレイヤーとモンスターのバトル部分を書いていきます。バトルの順番はプレイヤー → モンスターの順で、どちらかのHPが0になるまでは①プレイヤーの行動②モンスターの行動が続く(ループする)ことになります。

××するまでは~し続けるループの場合はwhile文を使います。今回は「どちらかのHPが0になったらループを終了してプログラムが終わる」ため、break文を使用していきます。

     while True:

            if player_HP <= 0 or enemy_HP <= 0:
                if player_HP <= 0:
                    print(f"{caster.name}は{monster}に負けてしまった・・・")
                elif enemy_HP <= 0:
                    print(f"{monster}を倒した!おめでとう、{caster.name}!")

                break

つぎに、プレイヤーのターンを書いていきます。まずは攻撃か防御のどちらを選ぶか判断するために、プレイヤーとモンスターの体力を表示させます。

攻撃を選んだ場合は攻撃メソッドを呼び出し、モンスターに与えるダメージを返り値として持ちます。その後、モンスターの体力から与えるダメージを引くことで「モンスターにダメージを与える」プログラムになりました。

防御を選んだ場合は防御メソッドを呼び出します。魔法使いの場合防御するとHPが回復するため、防御したあとのHPを返り値として持ち、プレイヤーの体力に代入します。

攻撃でも防御でもない値を入力した場合、もう一度入力を促したいためcontinueを用います。

      print(f"{caster.name}のHP:{player_HP}")
            print(f"{monster}のHP:{enemy_HP}")
            # プレイヤーのターン
            print("")
            caster_attack = input("あなたの行動を選んでください 1:攻撃 2:防御")

            if caster_attack == str(1):  # 攻撃を選んだ場合

                print("")
                print(f"{caster.name}の攻撃!")
                monster_damage = caster.attack()
                print(f"{monster}に{monster_damage}のダメージ!")
                enemy_HP = enemy_HP-monster_damage
                print(f"{caster.name}のHP:{player_HP}")
                print(f"{monster}のHP:{enemy_HP}")
                print("")
                if enemy_HP <= 0:
                    print(f"{monster}を倒した!おめでとう、{caster.name}!")
                    break

            elif caster_attack == str(2):  # 防御を選んだ場合5回復する

                print(f"{caster.name}は防御した!")
                player_HP = caster.defence(player_HP)

            else:
                continue

つぎに、モンスターのターンを書いていきます。前回のターンでプレイヤーが防御していた場合とそうでない場合で分岐させ、防御していない場合のみ攻撃メソッドを呼び出しダメージを与えます

# モンスターのターン

            print(f"{monster}の攻撃!")

            if caster.is_defenced is True:
                print(f"{caster.name}は防御している!")

            elif caster.is_defenced is False:
                player_damage = enemy.attack()
                print(f"{caster.name}に{player_damage}のダメージ!")
                player_HP = player_HP - player_damage

以上でバトル部分の記述は完了になります。

残りのプログラムを書いていく  ~最後にmain関数を呼び出そう!~

つぎに、騎士を選んだ場合のプログラムを書いていきます。基本的には魔法使いで記述したものと変わらず、説明文と生成するインスタンスを変更することで騎士用のプログラムにすることができます。

説明文・・・「騎士」にする

インスタンス・・・「騎士インスタンス」を作成し、メソッドを呼び出す

騎士クラスを選んだ部分を書きあげたら、main関数を呼び出します。

if __name__ == "__main__":

    main()

これでRPGプログラムの完成です!

まとめ

前回クラスを作成しておいたことで、実際にキャラクターができあがり、そのキャラクターが行動していく部分をインスタンス生成→メソッド呼び出しという形で記述することができました。このように、クラスを用いてプログラムを作成すると感覚的に分かりやすいコードを書くことができます。

RPGゲームプログラムの場合はまず仕様を確認し、どのような流れでゲームが進んでいくのか大きな流れを捉えてから、実際の処理を細かく把握していくことで詰まることなく作業を進めることができます。

次回は作成したRPGを実際に遊んでみて、クラスを用いたプログラムの振り返りをしていきます。

ここまで読んでくださってありがとうございました!

コメント

タイトルとURLをコピーしました