CODE Python RPG

独学でPythonでRPGを作成する(第18回)経験値を貯めてレベルアップ

更新日:

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

前回は親クラスであるCharaクラスを作り、
元々あったBraveクラスとMonsterクラスをCharaクラスを継承させました。

今回はモンスターを倒すと経験値を獲得していき、一定の経験値が貯まると
プレイヤーのレベルを上げるようにします。

また、プレイヤーの位置や画像はグローバル変数にしていましたが
Braveクラスに持たせるようにします。

目次

  1. クラスに経験値のパラメータを追加
  2. 経験値を貯めてレベルアップ
  3. プレイヤーの変数
  4. 最後に

クラスに経験値のパラメータを追加

レベルアップは以下のような動きにします。
・1から2へレベルアップ

 

それではまず、モンスターのパラメータに経験値を追加します。
倒した時に獲得する経験値です。

chara.py

(省略)
mon_dfs = ws_mon.col_values(10) # J列
mon_exp = ws_mon.col_values(11) # K列 (←追加)
(省略)
class Monster(Chara):
    def __init__(self, num):
(省略)
        self.dfs = int(mon_dfs[num])
        self.exp = int(mon_exp[num]) # 追加
(省略)

 

プレイヤーにも経験値のパラメータを追加します。
次にレベルアップする経験値の値です。

以下の例ですと、レベル1の時に経験値が累計で10(以上)になると
レベルアップすることにします。

chara.py

(省略)
chara1_name = ws_chara.acell('C2').value
chara1_maxhp = ws_chara.col_values(5) # E列
chara1_maxmp = ws_chara.col_values(7) # G列
chara1_quick = ws_chara.col_values(9) # I列
chara1_atk = ws_chara.col_values(10) # J列
chara1_dfs = ws_chara.col_values(11) # K列
chara1_exp = ws_chara.col_values(12) # L列(←追加)

(省略)
class Brave(Chara):
    def __init__(self):
        self.name = chara1_name
        self.lv = 1
        self.maxhp = int(chara1_maxhp[self.lv]) # レベル1の値
        self.maxmp = int(chara1_maxmp[self.lv]) # レベル1の値
        self.hp = self.maxhp # 変更
        self.mp = self.maxmp # 変更
        self.quick = int(chara1_quick[self.lv]) # レベル1の値
        self.atk = int(chara1_atk[self.lv]) # レベル1の値
        self.dfs = int(chara1_dfs[self.lv]) # レベル1の値
        self.lv_exp = int(chara1_exp[self.lv]) # 追加 レベル1の値
        self.exp = 0 # 追加(累計の経験値)
(省略)
    def reset(self):
        self.hp = self.maxhp
        self.mp = self.maxmp
(省略)

self.expは累計の経験値です。
この累計の経験値がself.lv_expの値(以上)になると
レベルアップします。
※self.lv_expはスプレッドシートのL列の値です。

 

ついでに以下のところを変えています。
self.hp = self.maxhp
self.mp = self.maxmp

スプレッドシートから取得していましたが、意味がなかったので。。(∀`*)ゞ
もっともゲームスタートする時に
player.reset()
を実行しているので、最初に何を設定しても同じです。

 

あと、プレイヤーのシートの形式をシレッと変えています。
レベルごとにパラメータを変える為です。
変更後はレベル1の値を最初に取得しています。

変更前

chara1_name = ws_chara.acell('C2').value
chara1_lv = ws_chara.acell('D2').value
chara1_maxhp = ws_chara.acell('E2').value
chara1_hp = ws_chara.acell('F2').value
chara1_maxmp = ws_chara.acell('G2').value
chara1_mp = ws_chara.acell('H2').value
chara1_quick = ws_chara.acell('I2').value
chara1_atk = ws_chara.acell('J2').value
chara1_dfs = ws_chara.acell('K2').value

 

 

経験値を貯めてレベルアップ

経験値のパラメータを追加したので、
これを使ってレベルアップするように変更します。

one_hour_dungeon.py

def main(): # メイン処理
(省略)
    turn_obj = ""
    btl_exp = 0 # 戦闘で獲得した経験値(追加)
(省略)
        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 # 追加

戦闘中に獲得する経験値を変数btl_expに入れます。
プレイヤーがモンスターに攻撃をして
倒したらbtl_expに追加していきます。

btl_exp += monster[btl_enemy].exp

最初から累計の経験値(self.exp)に追加しないのは、
戦闘の途中で全滅したり、逃げたりすると獲得する経験値を0にする為です。

と、いうわけで全滅したり、逃げたりした時に
btl_expを0にします。

def main(): # メイン処理
(省略)
        if idx == 0: # タイトル画面
(省略)
            if key[K_SPACE] == 1:
(省略)
                btl_exp = 0 # 全滅したらタイトル画面に戻るのでここで0にする(追加)
(省略)
        elif idx == 14: # 逃げる
(省略)
            if tmr == 5:
                if random.randint(0, 99) < 60: # 逃げた時
                    idx = 22 # 戦闘終了
(省略)
        elif idx == 22: # 戦闘終了
            idx = 1
            monster.clear()
            dead_monster.clear()
            btl_exp = 0 # 追加

全滅したらidx=0になるので、idx0でbtl_expを0にします。

また、逃げたら戦闘終了になるので、戦闘終了(idx22)で
btl_expを0にしました。
戦闘に勝利した時もidx22に来ますのでちょうど良いです。

 

戦闘に勝利したら獲得した経験値を
累計の経験値(self.exp)に追加します。

この時に一定の値以上になるとレベルアップします。
一定の値とはself.lv_expです。

def main(): # メイン処理
(省略)
        elif idx == 16: # 勝利
            draw_battle(screen, fontS, turn_obj)
            if tmr == 1:
                set_message(player.name + " は 魔物の群れ をやっつけた!")
# =====追加ここから=====
                player.exp += btl_exp # 累計の経験値に加える
                if player.exp >= player.lv_exp: # レベルアップ
                    idx = 17
                    tmr = 0
# =====追加ここまで=====
            if tmr == 28:
                idx = 22 # 戦闘終了

 

レベルアップしたらパラメータを変えますが
そのメソッドを作成します。

chara.py

class Brave(Chara):
(省略)
    def lv_up(self):
        self.lv += 1 # レベルを1追加
        self.maxhp = int(chara1_maxhp[self.lv])
        self.maxmp = int(chara1_maxmp[self.lv])
        self.quick = int(chara1_quick[self.lv])
        self.atk = int(chara1_atk[self.lv])
        self.dfs = int(chara1_dfs[self.lv])
        self.lv_exp = int(chara1_exp[self.lv])

レベルを1追加して、各パラメータを変更します。
レベル1から2になった時は以下のように変わります。

self.maxhp:30 → 32(最大HP)
self.maxmp:10 → 12(最大MP)
self.quick:10 → 12(素早さ)
self.atk:1000 → 1001(攻撃力)
self.dfs:20 → 22(防御力)
self.lv_exp:10 → 20(経験値)

 

このlv_upメソッドを使ってパラメータを変えます。
idx17はほぼ全部変更なので、変更前の記載は省きます。

one_hour_dungeon.py

def main(): # メイン処理
(省略)
        elif idx == 17: # レベルアップ
            draw_battle(screen, fontS, turn_obj)
            if tmr == 1:
                set_message(player.name + " はレベルが上がった!")
                player.lv_up() # パラメータを変更
            if tmr == 21:
                init_message()
                set_message("最大HP:"+str(player.maxhp))
            if tmr == 26:
                set_message("素早さ:"+str(player.quick))
            if tmr == 30:
                set_message("攻撃力:"+str(player.atk))
            if tmr == 34:
                set_message("防御力:"+str(player.dfs))
            if tmr == 40:
                if player.exp >= player.lv_exp: # 1度の戦闘で2レベル以上アップする場合
                    idx = 17
                    tmr = 0
            if tmr == 50:
                idx = 22 # 戦闘終了

1度の戦闘で複数レベルアップする場合もある(かもしれない)ので
idx17の中でもレベルアップしていないか確認しています。
if player.exp >= player.lv_exp:

以上で冒頭のような動きになりました(^_^)

 

 

プレイヤーの変数

次にプレイヤーの変数をクラスに持たせるように変更します。
具体的には画像、マップ上の位置(xy座標)、向きです。
他に、戦闘コマンドの行動も持たせます。(idxに入れる値です)

以下、クラスに追加した変数です。
chara.py

class Brave(Chara):
    def __init__(self):
(省略)
        self.act = 0 # 戦闘のコマンド(行動)12:攻撃、18:防御(数字はidxの値)
        self.img = [
                pygame.image.load("image/mychr0.png"), # 上
                pygame.image.load("image/mychr1.png"), # 上
                pygame.image.load("image/mychr2.png"), # 下
                pygame.image.load("image/mychr3.png"), # 下
                pygame.image.load("image/mychr4.png"), # 左
                pygame.image.load("image/mychr5.png"), # 左
                pygame.image.load("image/mychr6.png"), # 右
                pygame.image.load("image/mychr7.png"), # 右
                pygame.image.load("image/mychr8.png") # 倒れた
            ]
        self.x = 0 # プレイヤーのx座標
        self.y = 0 # プレイヤーのy座標
        self.d = 0 # プレイヤーの向き 0:上 1:下 2:左 3:右
        self.a = 0 # imgPlayerの添字

 

one_hour_dungeon.py
から不要になった変数を削除します。

(全て削除)
imgPlayer = [
    pygame.image.load("image/mychr0.png"), # 上
    pygame.image.load("image/mychr1.png"), # 上
    pygame.image.load("image/mychr2.png"), # 下
    pygame.image.load("image/mychr3.png"), # 下
    pygame.image.load("image/mychr4.png"), # 左
    pygame.image.load("image/mychr5.png"), # 左
    pygame.image.load("image/mychr6.png"), # 右
    pygame.image.load("image/mychr7.png"), # 右
    pygame.image.load("image/mychr8.png") # 倒れた
]

pl_x = 0 # プレイヤーのx座標
pl_y = 0 # プレイヤーのy座標
pl_d = 0 # プレイヤーの向き 0:上 1:下 2:左 3:右
pl_a = 0 # imgPlayerの添字

変更前

def draw_dungeon(bg, fnt): # ダンジョンを描画する
(省略)
            dx = pl_x + x
            dy = pl_y + y
(省略)
            if x == 0 and y == 0: # 主人公キャラの表示
                bg.blit(imgPlayer[pl_a], [X, Y-40])
(省略)
def put_event(): # 床にイベントを配置する
    global pl_x, pl_y, pl_d, pl_a # 削除する
    # 階段の配置
    while True:

変更後

def draw_dungeon(bg, fnt): # ダンジョンを描画する
(省略)
            dx = player.x + x
            dy = player.y + y
(省略)
            if x == 0 and y == 0: # 主人公キャラの表示
                bg.blit(player.img[player.a], [X, Y-40])
(省略)
def put_event(): # 床にイベントを配置する
    # 階段の配置
    while True:

他にもたくさんありますが、同じように変更していきます。
エディタにVSCodeを利用している場合、
複数箇所を同じ変更するのは、こちらのショートカットが便利です。

あと、クラスの変数にself.actを追加しましたが
この変数については次回にします。。

 

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

 

 

最後に

今回は経験値のパラメータを追加して、
一定の経験値を貯めるとレベルアップするようにしました。

また、プレイヤーの変数をクラスに持たせるようにしました。

次回はact変数を利用して、戦闘の行動に移せるように
していこうと思います。

まとめサイトへ

 

 

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

 

 

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

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