CODE Python RPG

独学でPythonでRPGを作成する(第28回)呪文発動の整理

更新日:

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

前回は攻撃呪文を使えるように変更しました。
今回は呪文を発動した時の動作を少し変えます。

呪文を使った時に点滅しますが
呪文ごとに色を変えます。

あと、「こうげき」と「じゅもん」で攻撃した時の
モンスターへのダメージ計算を関数にします。

目次

  1. 呪文の色を追加
  2. 追加した色を使う
  3. ダメージ計算の関数
  4. if文の順番
  5. 最後に

呪文の色を追加

呪文を使った時に点滅させていましたが
呪文ごとに色を変えます。

BLINK = [(224,255,255), (192,240,255), (128,224,255), (64,192,255), (128,224,255), (192,240,255)]

if 2 <= tmr and tmr <= 4:
    pygame.draw.rect(screen, BLINK[tmr%6], [0, 0, screen.get_width(), screen.get_height()])

今は全て呪文でBLINKを使っていますが、
呪文ごとに値を変えます。

 

最初にスプレッドシートに色の列を追加します。

呪文シートのG列に追加しました。

['#e0ffff', '#c0f0ff', '#80e0ff']
のようにリストして使います。

tmrが2〜4の時に順番に
画面全体の色にします。


 

次にchara.pyで追加した色の列を取得します。

(省略)
spell_name = ws_spell.col_values(1) # A列
spell_usemp = ws_spell.col_values(2) # B列 # 消費MP
spell_lo = ws_spell.col_values(3) # C列 # 上限
spell_up = ws_spell.col_values(4) # D列 # 下限
spell_explain = ws_spell.col_values(5) # E列 呪文の説明
spell_target = ws_spell.col_values(6) # F列 ターゲット
spell_blink = ws_spell.col_values(7) # G列 呪文の色

spell_usemp_dict = {}
spell_lo_dict = {}
spell_up_dict = {}
spell_explain_dict = {}
spell_target_dict = {}
spell_blink_dict = {} # 追加(色を入れる)

for i, tmp in enumerate(spell_name[1:], 1):
    spell_usemp_dict.setdefault(tmp, int(spell_usemp[i]))
    spell_lo_dict.setdefault(tmp, int(spell_lo[i]))
    spell_up_dict.setdefault(tmp, int(spell_up[i]))
    spell_explain_dict.setdefault(tmp, spell_explain[i])
    spell_target_dict.setdefault(tmp, int(spell_target[i]))
    spell_blink_dict.setdefault(tmp, spell_blink[i]) # 追加(呪文ごとの色)

class Chara():
(省略)

    def get_spell_target(self, str_spell):
        return spell_target_dict[str_spell]
    def get_spell_blink(self, str_spell): # 追加(色を返す)
        return spell_blink_dict[str_spell]

 

chara.pyの変更は以上です。

 

 

追加した色を使う

chara.pyに追加した色をbattle.pyで使います。

変更前

(省略)
def main(screen, clock, font, fontS, player):
(省略)

        elif idx == 26: # 呪文発動
            draw_battle(screen, fontS, turn_obj, player)
            if tmr == 1:
                set_message(turn_obj.name + " は " + turn_obj.mas_spell[sel_spell_i] + " となえた!")
                dmg = turn_obj.spell(turn_obj.mas_spell[sel_spell_i]) # 仲間の概念を追加した時は回復対象のobjを追加(今は自分のみ)
            if 2 <= tmr and tmr <= 4:
                pygame.draw.rect(screen, BLINK[tmr%6], [0, 0, screen.get_width(), screen.get_height()])
(省略)
def main(screen, clock, font, fontS, player):
(省略)

    dmg = 0 # プレイヤーが与えるダメージ、受けるダメージ
    spell_blink = "" # 呪文の色
(省略)

        elif idx == 26: # 呪文発動
            draw_battle(screen, fontS, turn_obj, player)
            if tmr == 1:
                # 2行追加
                spell_blink = player.get_spell_blink(player.mas_spell[tmp_sel_spell_i]) # 呪文演出(いろ)
                spell_blink = spell_blink.split(",")
                set_message(turn_obj.name + " は " + turn_obj.mas_spell[sel_spell_i] + " となえた!")
                dmg = turn_obj.spell(turn_obj.mas_spell[sel_spell_i])
            if 2 <= tmr and tmr <= 4:
                # BLINKからspell_blinkに変更
                pygame.draw.rect(screen, spell_blink[tmr%3], [0, 0, screen.get_width(), screen.get_height()]

 

呪文の色を入れる変数spell_blinkを追加しました。

色を取得する為に2行追加しています。

spell_blink = player.get_spell_blink(player.mas_spell[tmp_sel_spell_i])
spell_blink = spell_blink.split(",")

最初のspell_blinkは
spell_blink = e0ffff,#c0f0ff,#80e0ff
のような値が入ります。

splitを使って","で区切ってリストにします。
splitの詳細はこちら

2つ目のspell_blinkは
spell_blink = ['#e0ffff', '#c0f0ff', '#80e0ff']
のような値が入ります。

 

このspell_blinkを使って、
tmrが2〜4の間、画面全体の色にします。

pygame.draw.rect(screen, spell_blink[tmr%3], [0, 0, screen.get_width(), screen.get_height()])

 

呪文ごとにspell_blinkの値が変わるので
呪文ごとに色を変えることが出来ました。

 

 

ダメージ計算の関数

モンスターにダメージを与えた時に
モンスターの残りダメージを計算する
関数を作ります。

前回、少し書いたのですが、
「こうげき」と「じゅもん」で
モンスターにダメージを与える時の動作が
似ているので、一つの関数にします。

 

以下の箇所を一つの関数にします。
・与えたダメージ分だけモンスターのHPから引く
・0以下になったらHPを0にする
・倒したモンスターの経験値を獲得
・倒したモンスターのリストに加える
・生存モンスターのリストから消す
・生存モンスターのリストが空になったら勝利

 

変更前

(省略)
def main(screen, clock, font, fontS, player):
(省略)

        elif idx == 12: # プレイヤーの攻撃
(省略)

            if tmr == 11:
                monster[btl_enemy].hp = monster[btl_enemy].hp - dmg
                if monster[btl_enemy].hp <= 0:
                    monster[btl_enemy].hp = 0
                    set_message(turn_obj.name + " は " + monster[btl_enemy].name + " をやっつけた!")
                    btl_exp += monster[btl_enemy].exp
                    del_battle_turn(monster[btl_enemy]) # ターンオブジェクトから消す(倒したモンスターは攻撃しない)
                    dead_monster.append(monster[btl_enemy]) # 先に加えて消す
                    monster.pop(btl_enemy)

                if not monster:
                    idx = 16 # 勝利
                    tmr = 0
            if tmr == 16:
                init_message()
                idx = 24 # ターンの確認
                tmr = 0
(省略)

        elif idx == 26: # 呪文発動
(省略)

            if turn_obj.get_spell_target(turn_obj.mas_spell[sel_spell_i]) == 1:
                if tmr == 5:
                    if dmg != -1:
                        monster[spell_target_i].hp -= dmg
                        set_message(monster[btl_enemy].name + "に " + str(dmg)+"ポイントのダメージを与えた!")
                        if monster[spell_target_i].hp <= 0:
                            monster[spell_target_i].hp = 0
                            set_message(turn_obj.name + " は " + monster[spell_target_i].name + " をやっつけた!")
                            btl_exp += monster[spell_target_i].exp
                            del_battle_turn(monster[spell_target_i]) # ターンオブジェクトから消す(倒したモンスターは攻撃しない)
                            dead_monster.append(monster[spell_target_i]) # 先に加えて消す
                            monster.pop(spell_target_i)
                    else:
                        set_message("しかし MPがたりない!")

                if not monster:
                    idx = 16 # 勝利
                    tmr = 0
            if tmr == 8:
                init_message()
                idx = 24 # ターンの確認
                tmr = 0

 

関数追加
獲得した経験値を返します。

def do_attack(target, dmg, obj):
    global idx, tmr
    tmp_exp = 0
    monster[target].hp -= dmg
    if monster[target].hp <= 0:
        monster[target].hp = 0
        set_message(obj.name + " は " + monster[target].name + " をやっつけた!")
        tmp_exp += monster[target].exp
        del_battle_turn(monster[target]) # ターンオブジェクトから消す(倒したモンスターは攻撃しないように)
        dead_monster.append(monster[target]) # 先に加えて消す
        monster.pop(target)
        if not monster:
            idx = 16 # 勝利
            tmr = 0
    return tmp_exp

 

この関数を使います。

変更後

        elif idx == 12: # プレイヤーの攻撃
(省略)

            if tmr == 11:
                btl_exp += do_attack(btl_enemy, dmg, turn_obj)
            if tmr == 16:
                init_message()
                idx = 24 # ターンの確認
                tmr = 0
(省略)

            if turn_obj.get_spell_target(turn_obj.mas_spell[sel_spell_i]) == 1:
                if tmr == 5:
                    if dmg != -1:
                        set_message(monster[btl_enemy].name + "に " + str(dmg)+"ポイントのダメージを与えた!")
                        if monster[spell_target_i].hp <= 0:
                            btl_exp += do_attack(btl_enemy, dmg, turn_obj)
                    else:
                        set_message("しかし MPがたりない!")
            if tmr == 16:
                init_message()
                idx = 24 # ターンの確認
                tmr = 0

モンスターへのダメージ計算と勝利確認が
1行になったのスッキリしました(^_^)

btl_exp += do_attack(btl_enemy, dmg, turn_obj)

 

 

if文の順番

呪文発動のところでif文の順番を少し変えます。

変更前

        elif idx == 26: # 呪文発動
(省略)
            if 2 <= tmr and tmr <= 4:
                pygame.draw.rect(screen, BLINK[tmr%6], [0, 0, screen.get_width(), screen.get_height()])

            if turn_obj.get_spell_target(turn_obj.mas_spell[sel_spell_i]) == 0:
                if tmr == 5:
                    if dmg != -1:
                        player.hp += dmg
                        if player.hp > player.maxhp:
                            player.hp = player.maxhp
                        set_message(player.name + " の キズが かいふくした!")
                    else:
                        set_message("しかし MPがたりない!")

            if turn_obj.get_spell_target(turn_obj.mas_spell[sel_spell_i]) == 1:
                if tmr == 5:
                    if dmg != -1:
                        set_message(monster[btl_enemy].name + "に " + str(dmg)+"ポイントのダメージを与えた!")
                        if monster[spell_target_i].hp <= 0:
                            btl_exp += do_attack(btl_enemy, dmg, turn_obj)
                    else:
                        set_message("しかし MPがたりない!")
            if tmr == 16:
                init_message()
                idx = 24 # ターンの確認
                tmr = 0

以下のif文が2回(回復と攻撃)
出てくるのでこれを先にします。

if tmr == 5:
  if dmg != -1:

 

変更後

        elif idx == 26: # 呪文発動
(省略)
          if 2 <= tmr and tmr <= 4:
                pygame.draw.rect(screen, spell_blink[tmr%3], [0, 0, screen.get_width(), screen.get_height()])

            if tmr == 5:
                if turn_obj.get_spell_target(turn_obj.mas_spell[sel_spell_i]) == 1:
                    set_message(monster[spell_target_i].name + "に " + str(dmg)+"ポイントのダメージを与えた!")
            if tmr == 11:
                if dmg != -1:
                    if turn_obj.get_spell_target(turn_obj.mas_spell[sel_spell_i]) == 0:
                        player.hp += dmg
                        if player.hp > player.maxhp:
                            player.hp = player.maxhp
                        set_message(player.name + " の キズが かいふくした!")
                    if turn_obj.get_spell_target(turn_obj.mas_spell[sel_spell_i]) == 1:
                        btl_exp += do_attack(spell_target_i, dmg, turn_obj)
                else:
                    set_message("しかし MPがたりない!")
            if tmr == 16:
                init_message()
                idx = 24 # ターンの確認
                tmr = 0

 

先程のif文がどちらも1回になったので
なんとなくスッキリしました(^_^)

 

順番一つで違いますね。
センスが問われるところでしょうか・・

  

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

 

 

最後に

今回は呪文を使った時の色を変えるなど
発動した時の動作を少し変えました。

次回は何も決めていませんが
呪文とは違うことをしようと思います。

まとめサイトへ

 

 

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

 

 

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

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