CODE Python RPG

初心者がPythonでRPGを作成する(第5回)スプレッドシートと連携

更新日:

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

前回はスプレッドシートと連携してそこから値を取得するようにしました。
今回は続いてモンスターのパラメータをスプレッドシートから取得します。
モンスターの追加・更新・削除が楽になると思います。

 

目次

  1. スプレッドシートに追加
  2. 変更(chara.py)
  3. 変更(one_hour_dungeon.py)
  4. 最後に

スプレッドシートに追加

まずはスプレッドシートです。(連携方法はこちら
モンスターのパラメータは以下のようにしました。
シート名はそのまま「モンスター」です。

パラメータは関係ないのもたくさん作ってしまいましたが、今回使うのは「名前(B列)」「最大HP(D列)」「攻撃力(H列)」です。

 

 

変更(chara.py)

プログラムの変更です。
まずはchara.pyです。

シートを取得します。

wb = gc.open_by_key(SPREADSHEET_KEY)
ws_chara = wb.worksheet("キャラ")
ws_mon = wb.worksheet("モンスター")

 

続いてスプレッドシートの値を取得します。

chara1_name = ws_chara.acell('B2').value
chara1_lv = ws_chara.acell('B3').value
chara1_maxhp = ws_chara.acell('B4').value
chara1_hp = ws_chara.acell('B5').value
chara1_maxmp = ws_chara.acell('B6').value
chara1_mp = ws_chara.acell('B7').value
chara1_atk = ws_chara.acell('B8').value
chara1_dfs = ws_chara.acell('B9').value

 

前回と同じキャラのパラメータですが、int型をクラスの方で指定しました。
特に意味はありません。。(*´∀`)

    def __init__(self):
        self.name = chara1_name
        self.lv = int(chara1_lv)
        self.maxhp = int(chara1_maxhp)
        self.hp = int(chara1_hp)
        self.maxmp = int(chara1_maxmp)
        self.mp = int(chara1_mp)
        self.atk = int(chara1_atk)
        self.dfs = int(chara1_dfs)

 

今回本題のモンスターのパラメータです。

(省略)
chara1_dfs = ws_chara.acell('B9').value

mon_name = ws_mon.col_values(2) # B列
mon_maxhp = ws_mon.col_values(4) # D列
mon_atk = ws_mon.col_values(8) # H列

 

「名前(B列)」「最大HP(D列)」「攻撃力(H列)」を列で取得している為、変数(mon_name、mon_maxhp、mon_atk)は以下のようにリストになっています。(コメントアウトが結果です)
スプレッドシートの列の値の取得方法についてはこちらにも記載していますのでご参考までに。

print(f"名前:{mon_name}")
print(f"最大HP:{mon_maxhp}")
print(f"攻撃力:{mon_atk}")

# mon_name:['名前', 'Green slime', 'Red slime', 'Axe beast', 'Ogre', 'Sword man', 'Death hornet', 'Signal slime', 'Devil plant', 'Twin killer', 'Hell']
# mon_maxhp:['最大HP', '120', '180', '240', '300', '360', '420', '480', '540', '600', '660']
# mon_atk:['素早さ', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19']

 

そしてモンスタークラスです。

class Monster():
    def __init__(self, num):
        self.img = pygame.image.load("image/enemy"+str(num)+".png")
        self.name = mon_name[num]
        self.maxhp = int(mon_maxhp[num])
        self.hp = self.maxhp
        self.atk = int(mon_atk[num])

 

コンストラクタに1つ引数を作りました。
どのモンスターかを指定する為です。
ここでちょっと、先程のリストの結果をもう一度。

# mon_name:['名前', 'Green slime', 'Red slime', 'Axe beast', 'Ogre', 'Sword man', 'Death hornet', 'Signal slime', 'Devil plant', 'Twin killer', 'Hell']
# mon_maxhp:['最大HP', '120', '180', '240', '300', '360', '420', '480', '540', '600', '660']
# mon_atk:['素早さ', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19']

 

リストの1つ目がそれぞれ、「名前」「最大HP」「攻撃力」になっていますが、これはカラムですね。
スプレッドシートの以下の部分です。

 

ここは使いません。
なので、mon_name、mon_maxhp、mon_atkのリストは2つ目から使います。
要するにコンストラクの引数numは1以上になります。(リストの添字は0始まりだから)

# 再掲
class Monster():
    def __init__(self, num): # numは1以上
        self.img = pygame.image.load("image/enemy"+str(num)+".png")
        self.name = mon_name[num]
        self.maxhp = int(mon_maxhp[num])
        self.hp = self.maxhp
        self.atk = int(mon_atk[num])

 

と、なるとself.imgです。("image/enemy"+str(num)+".png")
今は画像のファイル名が以下のようになっていますが、numが1以上ですと、ボタンの掛け違いが起きてしまいます。(赤枠の部分がnumに相当)

 

この為、画像の名前を変更しました。
(num-1にしても良いと言えば良いんですけど、分かりやすいと思ったので・・)

 

その他のパラメータも引数numが指定するリストの値を取得します。
例えばnumが5の場合、以下の赤枠の値を取得します。

class Monster():
    def __init__(self, num):
        self.img = pygame.image.load("image/enemy"+str(num)+".png")
        self.name = mon_name[num]
        self.maxhp = int(mon_maxhp[num])
        self.hp = self.maxhp
        self.atk = int(mon_atk[num])

monster = Monster(5) # numを5
print(f"名前:{monster.name}")
print(f"最大HP:{monster.maxhp}")
print(f"攻撃力:{monster.atk}")

# 名前:Sword man
# 最大HP:360
# 攻撃力:45

 

こんな感じです。
chara.pyは以上で、続いてone_hour_dungeon.pyです。

 

 

変更(one_hour_dungeon.py)

それではまず、不要になった変数の削除です。

敵(モンスター)の名前、最大体力(HP)、体力(HP)、攻撃力はchara.pyで取得するので消します。

# 変更前
emy_name = "" # 敵の名前
emy_lifemax = 0 # 敵の最大体力 敵やレベルによって異なる
emy_life = 0 # 敵の体力
emy_str = 0 # 敵の攻撃力 最大体力で決まる(最大体力が大きいほど攻撃力が大きい)

EMY_NAME = [
"Green slime", "Red slime", "Axe beast", "Ogre", "Sword man",
"Death hornet", "Signal slime", "Devil plant", "Twin killer", "Hell"
]

# (省略)

def init_battle(): # 戦闘に入る準備をする
    global imgEnemy, emy_name, emy_lifemax, emy_life, emy_str, emy_x, emy_y

 

代わりにインスタンスを作成する時の変数を用意します。(グローバル変数にしておきます)

# 変更後
monster = ""

# (省略)

def init_battle(): # 戦闘に入る準備をする
    global monster, emy_x, emy_y

 

次に出現するモンスターの指定です。
random.randint(a, b)の範囲は「a<= typ <= b」でaとbを含みますので、このままですと0が出る可能性があります。

# 変更前
typ = random.randint(0, floor)
if floor >= 10:
    typ = random.randint(0, 9)

 

でも、モンスタークラスのコンストラクで指定するのは1からです。

# 再掲
class Monster():
    def __init__(self, num): # numは1以上

 

なので、モンスターの指定は1からに変更します。

# 変更後
typ = random.randint(1, floor+1)
if floor >= 11:
    typ = random.randint(1, 10)

 

次にパラメータの指定ですが、以下は先ほど削除した変数なのでここでも削除します。

# 変更前
imgEnemy = pygame.image.load("image/enemy"+str(typ)+".png")
emy_name = EMY_NAME[typ] + " LV" + str(lev)
emy_lifemax = 60*(typ+1) + (lev-1)*10
emy_life = emy_lifemax
emy_str = int(emy_lifemax/8)

 

代わりにインスタンスを作成します。
これでモンスタークラスのコンストラクタの引数numに渡されて、指定のモンスターが作成されます。

# 変更後
# lev = random.randint(1, floor)
monster = chara.Monster(typ)

 

ここでシレっとモンスターのレベル(lev)をコメントアウトしていますが、モンスターのレベルの概念は都合により消します。(復活するかもしれませんが今は都合により消します)

後は削除した変数を以下に変更します。

imgEnemy → monster.img
emy_name → monster.name
emy_lifemax → monster.maxhp
emy_life → monster.hp
emy_str → monster.atk
※VSCodeですとこちらのショートカットが便利です。

 

今回は以上です!(`・ω・´)

 

 

最後に

今回もRPGの仕様が何か変わったわけではないです。(モンスターのレベルの概念は都合により無くなりました)
ただ、モンスタークラスを作ってパラメータをスプレッドシート管理にしたことで、今後モンスターの追加や変更・削除がだいぶ楽になりました!

次回は日本語のフォントに変えてみます。

まとめサイトへ

 

 

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

 

 

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

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