CODE Python RPG

初心者がPythonでRPGを作成する(第11回)モンスター名を表示

更新日:

こんにちは。
「Pythonでつくる ゲーム開発 入門講座」のChapter11,12(本格RPGを作ろう!全編・後編)を基にRPGを作っていきます。

前回は新しい戦闘コマンドから「ぼうぎょ」を選択できるようにして、
「こうげき」のダメージは防御力を考慮する計算方法に変えました。

今回はコマンドを選択する時にモンスターの名前を表示するようにします。

目次

  1. モンスター名の表示
  2. ミスした時のエフェクトを変更
  3. 戦闘メッセージ
  4. 最後に

モンスター名の表示

今はコマンドを選択する画面は以下になっていますが、
右側の空いているところにモンスター名を表示させます。

変更前

変更後

 

それでは変えて行きます。
戦闘画面の変更なので、draw_battle関数です。

def draw_battle(bg, fnt): # 戦闘画面の描画
(省略)
    if idx == 11: # プレイヤーの入力待ち
        # コマンド表示
(省略)
        if tmr%5 != 0:
            draw_text(bg, "▶︎", x_i+btl_cmd_x*x_w/2, y_i+70+btl_cmd_y*60, fnt, col)

        ###追加###
        # 敵の名前表示
        x_i = bg.get_width()*0.4 + 60 # x座標の開始位置
        x_w = bg.get_width()*0.6 - 100 # 100は両端の50の合計
        y_i = bg.get_height()*0.6 + 40
        y_h = bg.get_height()*0.1 - 10 # 高さ(敵の名前1個分の高さ:62)
        x_i_t = x_i + 50 # テキストのx座標の開始位置
        y_i_t = y_i + 21
        pygame.draw.rect(bg, col, [x_i, y_i, x_w, y_h], 2, 5)
        draw_text(bg, "{}".format(monster.name), x_i_t, y_i_t, fnt, col) # font:20(20+21+21=62)

 

プレイヤーの入力待ちの時に表示するので、
コマンド表示のタイミングと同じidx=11のところに追加します。

draw.rectは
pygame.draw.rect(bg, 色, [x座標, y座標, 横幅, 高さ], 線の太さ, 四隅の丸み)
です。枠なので線の太さなどを指定します。
詳しくはこちら

左側の大体4割にコマンド表示、右側の大体6割にモンスター名を表示させます。
モンスター名の高さは大体1割くらいにしました。
少しゴチャっとした図になりましたが、以下のような感じです。

 

これでモンスター名が表示されました。

あと、「こうげき」「ぼうぎょ」「にげる」で戦闘は進めることが
できるようになったので、元々のコマンドを消します。

 

変数の整理です。
以下のコメント文のように変数を修正します。
(変数COMを使っている箇所は全てCOMMANDに変更します)

# btl_cmd = 0 # バトルコマンド(1:攻撃 2:ポーション 3:blaze 4:逃げる) 使わないので消す
btl_cmd_x = 0
btl_cmd_y = 0

COMMAND = [["こうげき", "どうぐ"], ["じゅもん", "そうび"], ["ぼうぎょ", "にげる"]] # COM → COMMANDに変更
# COMMAND = ["[A]ttack", "[P]otion", "[B]laze gem", "[R]un"]  使わないので消す

 

次に、battle_command関数から消します。
(コメントアウトしたところを消しています)

def battle_command(bg, fnt, key): # コマンドの入力と表示
    # global btl_cmd
    global btl_cmd_x, btl_cmd_y
    ent = False # Trueで返すと選択したコマンド(btl_cmd)を実行する
    # if key[K_a]: # Aキー
    #     btl_cmd = 0
    #     ent = True
    # if key[K_p]: # Pキー
    #     btl_cmd = 1
    #     ent = True
    # if key[K_b]: # Bキー
    #     btl_cmd = 2
    #     ent = True
    # if key[K_r]: # Rキー
    #     btl_cmd = 3
    #     ent = True
    if key[K_UP] and btl_cmd_y > 0: # ↑キー
        btl_cmd_y -= 1
    if key[K_DOWN] and btl_cmd_y < 2: # ↓キー
        btl_cmd_y += 1
    if key[K_LEFT] and btl_cmd_x > 0: # ←キー
        btl_cmd_x -= 1
    if key[K_RIGHT] and btl_cmd_x < 1: # →キー
        btl_cmd_x += 1
    if key[K_SPACE] or key[K_RETURN]: # 決定s
        ent = True
    # for i in range(4):
    #     c = WHITE
    #     if btl_cmd == i:
    #         c = BLINK[tmr%6]
    #     draw_text(bg, COMMAND[i], 20, 160+i*60, fnt, c)
    return ent

 

最後に、main関数のpotion,blazegemも消します。

def main(): # メイン処理
(省略)
        elif idx == 11: # プレイヤーのターン(入力待ち)
            player.re_defense() # ぼうぎょを元に戻す(ぼうぎょ効果を消す)(呪文効果が残っているか確認)
            draw_battle(screen, fontS)
            if tmr == 1:
                set_message(player.name + " のターン")
            if battle_command(screen, font, key) == True:
                if COMMAND[btl_cmd_y][btl_cmd_x] == "こうげき":
                    idx = 12
                    tmr = 0
                # if btl_cmd == 1 and potion > 0: # ポーション
                #     idx = 20
                #     tmr = 0
                # if btl_cmd == 2 and blazegem > 0: # blaze
                #     idx = 21
                #     tmr = 0
                if COMMAND[btl_cmd_y][btl_cmd_x] == "ぼうぎょ":
                    idx = 18
                    tmr = 0
                if COMMAND[btl_cmd_y][btl_cmd_x] == "にげる":
                    idx = 14
                    tmr = 0

                # コマンドの位置のリセット
                btl_cmd_x = 0
                btl_cmd_y = 0
(省略)
        # idx=20と21は消す
        # elif idx == 20: # Potion
        #     draw_battle(screen, fontS)
        #     if tmr == 1:
        #         set_message("Potion!")
        #         # se[2].play()
        #     if tmr == 6:
        #         player.hp = player.maxhp
        #         potion = potion - 1
        #     if tmr == 11:
        #         idx = 13 # 敵のターン
        #         tmr = 0

        # elif idx == 21: # Blaze gem
        #     draw_battle(screen, fontS)
        #     img_rz = pygame.transform.rotozoom(imgEffect[1], 30*tmr, (12-tmr)/8)
        #     X = 440-img_rz.get_width()/2
        #     Y = 360-img_rz.get_height()/2
        #     screen.blit(img_rz, [X, Y])
        #     if tmr == 1:
        #         set_message("Blaze gem!")
        #         # se[1].play()
        #     if tmr == 6:
        #         blazegem = blazegem - 1
        #     if tmr == 11:
        #         dmg = 1000
        #         idx = 12 # プレイヤーの攻撃(tmr=11の時にダメージ計算)
        #         tmr = 4

 

これで完了です。

 

 

ミスした時のエフェクトを変更

今回は他に細々したことを、2つほど変えます。

1つ目はモンスターから受けるダメージが0の時です。
今はモンスターから攻撃を受けると画面が揺れるようなエフェクトになっています。

def draw_battle(bg, fnt): # 戦闘画面の描画
    global emy_blink, dmg_eff
    bx = 0
    by = 0
    if dmg_eff > 0:
        dmg_eff = dmg_eff - 1
        bx = random.randint(-20, 20)
        by = random.randint(-10, 10)
    bg.blit(imgBtlBG, [bx, by])

 

これはダメージが0の時も同様に画面が揺れるのですが、
0の時は揺れないようにします。
揺れる条件はdmg_effが0より大きい時なので、
ダメージ0の時はdmg_effを0にするだけです。

(変更前)
                if dmg > 0:
                    set_message(player.name + "は " + str(dmg) + "ポイントのダメージを受けた!")
                else:
                    set_message("ミス!" + player.name + " はダメージを受けない!")
                dmg_eff = 5

(変更後)
                if dmg > 0:
                    set_message(player.name + "は " + str(dmg) + "ポイントのダメージを受けた!")
                    dmg_eff = 5
                else:
                    set_message("ミス!" + player.name + " はダメージを受けない!")
                    dmg_eff = 0

 

前回、ダメージが0の時のメッセージを変えたのですが、
エフェクトは変えていませんでした。(∀`*ゞ)

 

 

戦闘メッセージ

2つ目は戦闘メッセージで区切りが付いたらリセットするようにします。
今はメッセージを次々に表示しています。

これを、区切りのいいところ(プレイヤーの行動、モンスターの行動)で
リセットするように変更します。

 

まず、メッセージをリセットする関数を作ります。
メッセージ変数(message)を空にすることで、リセットします。

def init_message():
    for i in range(5):
        message[i] = "" # messageを空にする

 

このinit_message関数を使うとメッセージがリセットされるので
区切りのいいところに入れて行きます。(入れる箇所は全てmain関数)

        elif idx == 10: # 戦闘開始
            if tmr == 1:
                # pygame.mixer.music.load("sound/ohd_bgm_battle.ogg")
                # pygame.mixer.music.play(-1)
                init_battle(screen)
                init_message() # 追加
            elif tmr <= 4:
                bx = (4-tmr)*220
                by = 0
                screen.blit(imgBtlBG, [bx, by]) # バトル画面を右から左へ挿入していく
                draw_text(screen, "Encounter!", 350, 200, font, WHITE)
            elif tmr == 5:
                set_message(monster.name + " が現れた!")
            elif tmr <= 16:
                draw_battle(screen, fontS)
                # draw_text(screen, monster.name+" appear!", 300, 150, font, WHITE)
            else:
                init_message() # 追加
                idx = 11
                tmr = 0
        elif idx == 12: # プレイヤーの攻撃
(省略)
            if tmr == 16:
                init_message() # 追加
                idx = 13
                tmr = 0

        elif idx == 13: # 敵のターン、敵の攻撃
(省略)
            if tmr == 20:
                init_message() # 追加
                idx = 11
                tmr = 0

        elif idx == 14: # 逃げられる?
(省略)
            if tmr == 10:
                init_message() # 追加
                idx = 13 # 敵のターン
                tmr = 0

        elif idx == 18: # ぼうぎょ
(省略)
            if tmr == 5:
                init_message() # 追加
                idx = 13
                tmr = 0

 

基本的に1つの行動が終わるとリセットするようにしました。

あと唐突ですが、「○○のターン」のメッセージはなんとなく、いらないので消します。

        elif idx == 11: # プレイヤーのターン(入力待ち)
            player.re_defense() # ぼうぎょを元に戻す(ぼうぎょ効果を消す)
            draw_battle(screen, fontS)
            # if tmr == 1: 消す
            #     set_message(player.name + " のターン") 消す
(省略)
        elif idx == 13: # 敵のターン、敵の攻撃
            draw_battle(screen, fontS)
            # if tmr == 1: 消す
            #     set_message(monster.name + " のターン") 消す

  

という感じで、今回は以上です!(`・ω・´)

 

 

最後に

今回は主にコマンド選択時にモンスター名を表示するように変更しました。
そのうち表示されたモンスター名を選択して、
どのモンスターを攻撃するか指定できるようにしたいと思います。

でも、出現するモンスターが今のように1匹だけならあまり意味がないですね。
というわけで、次回は出現するモンスターを1匹から複数に変更します。

まとめサイトへ

 

 

【ご注意】
プログラムやデータなどは著作権法により保護されています。
著作者の許諾を得ずに、プログラムおよびデータそのものまたは改変したものを
配布したり販売したりすることはできません。
また、これらを利用して発生した損害などに関して、著作者は一切責任を負いません。

 

 

-CODE, Python, RPG
-, , , , ,

Copyright© kerublog , 2021 All Rights Reserved Powered by STINGER.