CODE Python RPG

独学でPythonでRPGを作成する(第59回)移動中のじゅもん

更新日:

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

前回は移動中のコマンド「じゅもん」を選択した時にキャラの名前が表示されるようにしました。

今回はそのキャラを選択したら覚えている呪文を表示するようにします。

目次

  1. charaの変更
  2. battleの変更
  3. moveの変更
  4. 呪文の表示
  5. 最後に

charaの変更

呪文を表示しますが、
全ての呪文ではなく
移動中に使える呪文のみを
表示するようにします。
※戦闘中のみに使う呪文は
 表示しません。

最初にchara.pyを変更します。

・移動中のみ使える
・戦闘中のみ使える
・移動中・戦闘中の両方とも使える
の3種類に分けます。

 

 

呪文シートの変更

呪文シートを以下のように
変更しました。

G列を追加しました。

・移動中のみ使える →0
・戦闘中のみ使える →1
・移動中・戦闘中の両方とも使える →2
としました。

 

 

インスタンス変数の変更

chara.pyを変更します。

キャラが覚えた呪文を
格納する変数を変更します。

変更前:mas_spell
変更後:mas_move_spell、mas_bat_spell

mas_move_spell:移動中に使える呪文
mas_bat_spell:戦闘中に使える呪文
の2つに分けました。
※移動中・戦闘中の両方で使える呪文は
 両方の変数に格納します。

spell_scene = ws_spell.col_values(7) # G列 いつ使うか(0:移動中のみ、1:戦闘のみ、2:両方) # 追加
spell_blink = ws_spell.col_values(8) # H列 呪文のいろ # 7(G列)から8(H列)に変更

spell_usemp_dict = {}
spell_lo_dict = {}
spell_up_dict = {}
spell_explain_dict = {}
spell_target_dict = {}
spell_scene_dict = {} # 追加
spell_blink_dict = {}

for i, tmp in enumerate(spell_name[1:], 1): # 呪文の性能を辞書型で取得 index 1から始める(0のカラムは不要)
    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_scene_dict.setdefault(tmp, int(spell_scene[i])) # 追加
    spell_blink_dict.setdefault(tmp, spell_blink[i])

コメントに「追加」を記載した
行を追加しました。

 

class Brave(Chara):
    def __init__(self, name):
        super(Brave, self).__init__()
(省略)

        # self.mas_spell = [] # 削除
        self.mas_move_spell = [] # 追加 
        self.mas_bat_spell = [] # 追加

        if brave_spell[self.lv] != "": # レベル1で覚える呪文があるなら
            if spell_scene_dict[brave_spell[self.lv]] == 0: # 移動中のみに使う呪文
                self.mas_move_spell.append(brave_spell[self.lv])
            elif spell_scene_dict[brave_spell[self.lv]] == 1: # 戦闘中にみに使う呪文
                self.mas_bat_spell.append(brave_spell[self.lv])
            elif spell_scene_dict[brave_spell[self.lv]] == 2: # 戦闘中/移動中に使う呪文
                self.mas_move_spell.append(brave_spell[self.lv])
                self.mas_bat_spell.append(brave_spell[self.lv])
(省略)

    def master_spell(self):
        if brave_spell[self.lv] != "": # レベルアップして覚える呪文があるなら
            if spell_scene_dict[brave_spell[self.lv]] == 0: # 移動中のみに使う呪文
                self.mas_move_spell.append(brave_spell[self.lv])
            elif spell_scene_dict[brave_spell[self.lv]] == 1: # 戦闘中にみに使う呪文
                self.mas_bat_spell.append(brave_spell[self.lv])
            elif spell_scene_dict[brave_spell[self.lv]] == 2: # 戦闘中/移動中に使う呪文
                self.mas_move_spell.append(brave_spell[self.lv])
                self.mas_bat_spell.append(brave_spell[self.lv])
            return brave_spell[self.lv]
        return ""

mas_spellを
mas_move_spellと
mas_bat_spell
に変更しました。

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

 

 

battleの変更

インスタンス変数が変わったので
battle.pyも変更しておきます。

mas_spellを
mas_bat_spellへ
変更するのみです。

def draw_battle(bg, fnt, obj, player):
(省略)

                if idx == 25:
                    spell_target_no = -1
                    if len(player[btl_player].mas_bat_spell) != 0:
                        spell_target_no = chara.get_spell_target(player[btl_player].mas_bat_spell[sel_spell_i])

上記の他にも何箇所かありますが
全て変更します。

エディタがVSCodeの場合は
こちらのショートカットキーが便利です。

battle.pyは以上です。

 

 

moveの変更

今回メインとなる
move.pyの変更です。

chara.pyで追加した
インスタンス変数を使って
移動中に使える呪文を
表示します。

 

 

変数の変更

ここでもまず変数を変更します。
※変数をリストに変更します。

# spell_flag = False # フィールドで呪文画面を表示するか # 削除
# sel_p_y = 0 # コマンドのじゅもん選択時の"▶︎"のy位置(横には動かない) # 削除

spell_flag = [False, False, False] # フィールドで呪文画面を表示するか [true:呪文の使用者選択画面,false:コマンド選択画面、true:呪文の選択画面,false:呪文の使用者選択画面]
sel_p_y = [0, 0, 0] # コマンドの"▶︎"のy位置(横には動かない)

前回のさいごに記載しましたが
・呪文を使うキャラを選択して
・使う呪文を選択して
・対象のキャラを選択して
・呪文を使う
の流れにしますので
各工程のflagをリストにしました。
※"▶︎"の位置も同様です。

なお、要素は3つにしていますが
今後、増えると思います。

 

spell_flag[0]がTrue:コマンド「じゅもん」を選択済
spell_flag[1]がTrue:呪文を使うキャラを選択済

sel_p_y[0]:呪文を使うキャラの位置
sel_p_y[1]:呪文を使うキャラが覚えている呪文の位置
です。

以下のような感じです。

spell_flag = [False, False, False]
 「じゅもん」を選択していない

 

spell_flag = [True, False, False]
 「じゅもん」を選択済
 呪文を使うキャラを選択中(▶は点滅)

 

spell_flag = [True, True, False]
 呪文を使うキャラを選択済
 使う呪文を選択中(▶は点滅)

 

 

「▶」の位置

続いて、上下キーを
押下することで「▶」の位置を
変更します。

変更前

def move_player(key, player, people): # 主人公の移動
(省略)

    if not talk_flag: # 会話中でない時は動ける、会話できる
        if key[K_UP] == 1:
            if cmd_flag: # コマンド選択中
                if spell_flag: # じゅもん選択時
                    if sel_p_y > 0:
                        sel_p_y -= 1
                else: # どれでもない時はコマンドを選択
                    if cmd_y > 0:
                        cmd_y -= 1

変更後

def move_player(key, player, people): # 主人公の移動
(省略)

    if not talk_flag: # 会話中でない時は動ける、会話できる
        if key[K_UP] == 1:
            if cmd_flag: # コマンド選択中
                if spell_flag[0]: # コマンドのじゅもん選択時
                    if spell_flag[1]: # 呪文の選択画面
                        if sel_p_y[1] > 0:
                            sel_p_y[1] -= 1
                    else: # じゅもんの使用者選択時
                        if sel_p_y[0] > 0:
                            sel_p_y[0] -= 1
                else: # どれでもない時はコマンドを選択
                    if cmd_y > 0:
                        cmd_y -= 1
(省略)

spell_flagとsel_p_yを
変数からリストに変更しています。

if spell_flag[1]: # 呪文の選択画面
    if sel_p_y[1] > 0:
        sel_p_y[1] -= 1
else: # じゅもんの使用者選択時
    if sel_p_y[0] > 0:
        sel_p_y[0] -= 1

spell_flagは後ろから確認します。
spell_flag[0]、spell_flag[1]の順ではなく
 spell_flag[1]、spell_flag[0]の順で確認

if - elif - else
は該当する条件があれば
それ以降は判定しない為です。
※ifが該当(True)なら、
 それ以降のelifやelseは判定しない
spell_flag = [True, True, False]のとき、
 呪文を使うキャラは選択済みなので
 sel_p_y[0]は動かさない

 

下(↓)キーも同様です。

変更後

def move_player(key, player, people): # 主人公の移動
(省略)

        elif key[K_DOWN] == 1:
            if cmd_flag: # コマンド選択中
                if spell_flag[0]: # コマンドのじゅもん選択時
                    if spell_flag[1]: # 呪文の選択画面
                        if sel_p_y[1] < len(player[sel_p_y[0]].mas_move_spell)-1: # 選択されたプレイヤーが覚えている呪文の数
                            sel_p_y[1] += 1
                    else: # じゅもんの使用者選択時
                        if sel_p_y[0] < len(player)-1:
                            sel_p_y[0] += 1
                else: # どれでもない時はコマンドを選択
                    if cmd_y < 2:
                        cmd_y += 1
(省略)

 

あと、左右(←→)キーも
spell_flagをリストにしておきます。

変更後

def move_player(key, player, people): # 主人公の移動
(省略)

        elif key[K_LEFT] == 1:
            if cmd_flag: # コマンド選択中
                if spell_flag[0]: # じゅもん選択時 
                    pass # 横には動かない
(省略)

        elif key[K_RIGHT] == 1:
            if cmd_flag: # コマンド選択中
                if spell_flag[0]: # じゅもん選択時 
                    pass # 横には動かない

 

 

決定・取消

決定(aキー)、
取消(bキー)を変更します。

変更前

def move_player(key, player, people): # 主人公の移動
(省略)

        elif key[K_a] == 1:
            if cmd_flag: # コマンド選択中
                if cmd_x == 1 and cmd_y == 0: # じゅもんの位置
                    spell_flag = True
            talk_flag, talk_mes = talk_judge(player, people)
            if not talk_flag:
                cmd_flag = True
        elif key[K_b] == 1:
            if cmd_flag:
                if spell_flag:
                    spell_flag = False
                    sel_p_y = 0
                else:
                    cmd_flag = False
                    cmd_x = 0
                    cmd_y = 0

変更後

def move_player(key, player, people): # 主人公の移動
(省略)

        elif key[K_a] == 1:
            if cmd_flag: # コマンド選択中
                if not spell_flag[0]: # じゅもんが選択されていない
                    if cmd_x == 1 and cmd_y == 0: # じゅもんの位置でaを押下
                        spell_flag[0] = True # じゅもんを選択
                elif not spell_flag[1]:
                    spell_flag[1] = True
            talk_flag, talk_mes = talk_judge(player, people)
            if not talk_flag:
                cmd_flag = True
        elif key[K_b] == 1:
            if cmd_flag:
                if spell_flag[0]:
                    if spell_flag[2]:
                        spell_flag[2] = False
                        sel_p_y[2] = 0
                    elif spell_flag[1]:
                        spell_flag[1] = False
                        sel_p_y[1] = 0
                    else:
                        spell_flag[0] = False
                        sel_p_y[0] = 0
                else:
                    cmd_flag = False
                    cmd_x = 0
                    cmd_y = 0

spell_flagの各要素の状態によって
値を変更します。

今回はspell_flag[1]までで
spell_flag[2]は次回以降にします。

 

 

呪文の表示

必要なものをそろえたので
呪文を表示します。

変更前

def draw_para(bg, fnt, player): # 主人公の能力を表示
(省略)

    if spell_flag:
(省略)

    x_b = bg.get_width()*0.15 # 一人分の幅

変更後

def draw_para(bg, fnt, player): # 主人公の能力を表示
(省略)

    if spell_flag[0]: # コマンドで「じゅもん」が選択された
(省略)

    else: # いずれのコマンドも選択されていない時はステータスを表示
        x_b = bg.get_width()*0.15 # 一人分の幅
(省略)
if spell_flag[0]:

spell_flagをリストに変更しています。

else: # いずれのコマンドも選択されていない時はステータスを表示
    x_b = bg.get_width()*0.15 # 一人分の幅

あと、コマンドを選択したら
右下に表示するステータスを
消すことにしました。

コマンドを選択していない

コマンドを選択している

 

呪文の表示です。

変更後

def draw_para(bg, fnt, player): # 主人公の能力を表示
(省略)

    if spell_flag[0]: # コマンドで「じゅもん」が選択された
        y_c_h = 50 * (1+len(player)) + 30 # 高さ 1+は「じゅもん」 50=30(枠内の開始位置or文字間隔)+20(文字の大きさ) 30=最後の間隔
        pygame.draw.rect(bg, BLACK, [x_c_i+x_c_w/2, y_c_i, x_c_w/2, y_c_h], 0, 5) # 枠
        pygame.draw.rect(bg, col, [x_c_i+x_c_w/2, y_c_i, x_c_w/2, y_c_h], 2, 5) # 枠
        pygame.draw.line(bg, col, [x_c_i+x_c_w/2, y_c_i+65], [x_c_i+x_c_w, y_c_i+65], 2) # 線 65=30(枠内の開始位置)+20(文字の大きさ)+15(文字間隔の半分)
        draw_text(bg, COMMAND[cmd_y][cmd_x], x_c_i_t+cmd_x*x_c_w/2, y_c_i_t+cmd_y*50, fnt, col) # cmd_x=1,cmd_y=0
        for i, p in enumerate(player):
            draw_text(bg, p.name, x_c_i_t+cmd_x*x_c_w/2, y_c_i_t+(i+1)*50, fnt, col) # i=0は「じゅもん」
        
        if spell_flag[1]: # 使用者が選択された(選択されたプレイヤーの添字:sel_p_y[0])
            if len(player[sel_p_y[0]].mas_move_spell) == 0: # 移動中の呪文を覚えていないなら
                x_i = bg.get_width()*0.1/2 # x座標の開始位置
                x_w = bg.get_width()*0.9 # 横幅
                y_i = bg.get_height()*0.6 # y座標の開始位置
                y_h = bg.get_height()*0.4-10 # 高さ
                x_i_t = x_i + 30 # テキストのx座標の開始位置
                y_i_t = y_i + 30 # テキストのy座標の開始位置
                pygame.draw.rect(bg, BLACK, [x_i, y_i, x_w, y_h], 0, 5) # 枠
                pygame.draw.rect(bg, col, [x_i, y_i, x_w, y_h], 2, 5) # 枠
                draw_text(bg, f"{player[sel_p_y[0]].name}は 移動中の呪文を覚えていない", x_i_t, y_i_t, fnt, col)
            else:
                y_c_h = 50 * len(player[sel_p_y[0]].mas_move_spell) + 30 # 50=30(枠内の開始位置or文字間隔)+20(文字の大きさ) 30=最後の間隔
                pygame.draw.rect(bg, BLACK, [x_c_i+x_c_w, y_c_i, x_c_w/2, y_c_h], 0, 5) # 枠
                pygame.draw.rect(bg, col, [x_c_i+x_c_w, y_c_i, x_c_w/2, y_c_h], 2, 5) # 枠
                pygame.draw.line(bg, col, [x_c_i+x_c_w, y_c_i+65], [x_c_i+x_c_w, y_c_i+65], 2) # 線 65=30(枠内の開始位置)+20(文字の大きさ)+15(文字間隔の半分)
                for i, s in enumerate(player[sel_p_y[0]].mas_move_spell):
                    draw_text(bg, s, x_c_i_t+cmd_x*x_c_w, y_c_i_t+i*50, fnt, col)

                draw_text(bg, "▶︎", x_c_i_t-50+x_c_w/2, y_c_i_t+(sel_p_y[0]+1)*50, fnt, col) # 呪文使用者を選択した後は常に名前の左に▶︎
                if tmr%5 != 0:
                    draw_text(bg, "▶︎", x_c_i_t-50+x_c_w, y_c_i_t+(sel_p_y[1])*50, fnt, col) # 呪文選択中は呪文の左に▶︎を点滅
        else:
            if tmr%5 != 0:
                draw_text(bg, "▶︎", x_c_i_t-50+x_c_w/2, y_c_i_t+(sel_p_y[0]+1)*50, fnt, col) # 呪文使用者を選択中は名前の左に▶︎を点滅
if spell_flag[1]: # 使用者が選択された(選択されたプレイヤーの添字:sel_p_y[0])
    if len(player[sel_p_y[0]].mas_move_spell) == 0: # 移動中の呪文を覚えていないなら

呪文を使うキャラを選択したら
呪文を表示しますが、
移動中に使える呪文を覚えていない場合は
「覚えていない」と表示します。

 

移動中に使える呪文を覚えている場合は
それを表示します。

 

draw_text(bg, "▶︎", x_c_i_t-50+x_c_w/2, y_c_i_t+(sel_p_y[0]+1)*50, fnt, col) # 呪文使用者を選択した後は常に名前の左に▶︎

選択済みの「▶」は
常に表示するようにします。

if tmr%5 != 0:
    draw_text(bg, "▶︎", x_c_i_t-50+x_c_w/2, y_c_i_t+(sel_p_y[0]+1)*50, fnt, col) # 呪文使用者を選択中は名前の左に▶︎を点滅

選択中の「▶」は
点滅するようにします。

 

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

 

 

最後に

今回はコマンド「じゅもん」を選択した後、
キャラを選択したら
覚えている呪文を表示するようにしました。

次回もコマンド「じゅもん」に
手を加えていきたいと思います。

まとめサイトへ

 

 

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

 

 

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

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