CODE Python RPG

独学でPythonでRPGを作成する(第51回)仲間を追加(移動)

更新日:

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

前回はソースコードの公開しましたが、
また今回から追加・修正していきます。

前々回は移動中のコマンドを表示するようにしました。

今まではプレイヤー1人でしたが、仲間を追加します。

目次

  1. 仲間追加
  2. one_hour_dungeonの変更
  3. mapsの変更
  4. moveの変更
  5. 最後に

仲間追加

今回から仲間を追加していきます。

追加すると言っても
仲間は最大で3人(全員で4人)まで
にします。とりあえず。

また、フィールドマップの
表示キャラは先頭のみにします。
※全員表示は難しそうなので・・(^_^;)

以下のような感じにします。

名前も含めて
全員が同じパラメータですが
徐々に変えていこうと思います。
徐々に。

 

ちなみに前々回の画像です。

 

今回は移動中のみ変更して
戦闘などは次回以降に
変更していきます。

 

 

one_hour_dungeonの変更

最初に
one_hour_dungeon.py
の変更です。

# 変更前
# player = chara.Brave()

# 変更後
player = []
player.append(chara.Brave())
player.append(chara.Brave())
player.append(chara.Brave())
player.append(chara.Brave())

「player」を
変数からリストに変更して
オブジェクトを追加します。

※仲間はイベントとかで
 追加するようにしたいですが
 とりあえず最初から追加します。

 

playerをリストにしたので
初期化のところを変えます。

変更前

def main():
(省略)

        if idx == 0: # タイトル画面
(省略)

            if key[K_SPACE] == 1:
                player.reset()
                player.spell_reset()

変更後

def main():
(省略)

        if idx == 0: # タイトル画面
(省略)

            if key[K_SPACE] == 1:
                for p in player:
                    p.reset()
                    p.spell_reset()

 

今回の変更はほとんど
こんな感じになります(^_^;)

 

one_hour_dungeon.py
は以上です。

 

 

mapsの変更

続いて、maps.py
の変更です。

変更前

class Maps():
    def get_map(self, num, player):
        if num == 0:
            maps = [
(省略)
            ]
            player.d = 1 # プレイヤーの向き
            player.a = 2 # プライヤーの画像
            player.x = 29 # マップの最初のx座標
            player.y = 34 # マップの最初のy座標
        if num == 1:
            maps = [
(省略)
            ]
            player.d = 1 # プレイヤーの向き
            player.a = 2 # プライヤーの画像
            player.x = 4 # マップの最初のx座標
            player.y = 23 # マップの最初のy座標
        return maps

変更後

class Maps():
    def get_map(self, num, player):
        if num == 0:
            maps = [
(省略)
            ]
            player[0].d = 1 # プレイヤーの向き
            player[0].a = 2 # プライヤーの画像
            player[0].x = 29 # マップの最初のx座標
            player[0].y = 34 # マップの最初のy座標
        if num == 1:
            maps = [
(省略)
            ]
            player[0].d = 1 # プレイヤーの向き
            player[0].a = 2 # プライヤーの画像
            player[0].x = 4 # マップの最初のx座標
            player[0].y = 23 # マップの最初のy座標
        return maps

 

変更前は「player」が
変数でしたが、
リストになったので
「player[0]」にしています。

※繰り返しになりますが
 フィールドマップで
 表示するキャラは
 先頭のみです。

 

maps.pyは以上です。

 

 

moveの変更

最後にmove.py
を変更します。

ここでも変数だった「player」を
「player[0]」に変更します。

が、大量にあるので、
それ以外のところを
先に変更します。

 

変更前

def move_player(key, player, people):
(省略)

    if player.x != x or player.y != y: # 移動したら食料の量と体力を計算
        if food > 0:
            food = food - 1
            if player.hp < player.maxhp:
                player.hp = player.hp + 1
        else:
            player.hp = player.hp - 5
            if player.hp <= 0:
                player.hp = 0
                tmr = 0
                return 9
(省略)

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

        elif idx == 2: # 画面切り替え
(省略)

            if tmr == 5:
(省略)
                    player.rest()

変更後

def move_player(key, player, people):
(省略)

    if player.x != x or player.y != y: # 移動したら食料の量と体力を計算
        if food > 0:
            food = food - 1
            for p in player:
                if p.hp < p.maxhp:
                    p.hp = p.hp + 1
        else:
            for p in player:
                p.hp = p.hp - 5
                if p.hp <= 0:
                    p.hp = 0
                    tmr = 0
                    area = 0 # 追加
                    return 9
(省略)

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

        elif idx == 2: # 画面切り替え
(省略)

            if tmr == 5:
(省略)
                    for p in player:
                        p.rest()

 

といっても似たような変更です。

変数「player」が
リスト「player」に
なるので、
1オブジェクトずつ
設定していきます。

 

あと、以下を追加しました。

area = 0 # 追加

これがないと、町の中など
areaが0以外でゲームオーバーになると
areaの不一致が起きてしまう為です。

move.pyでareaが1(町)でゲームオーバー
move.pyのarea:1
one_hour_dungeon.pyのarea:0
maps.pyのarea:0

のようにマップ画面は
フィールド(area:0)ですが、
move.pyでは町(area:1)を
歩くことになってしまいます。

areaを増やす時は
注意が必要です・・

 

文字の色

次に文字の色ですが
移動中もプレイヤーの
残りHPによって変更します。

WHITE = (255, 255, 255)
WARNING = (255, 191, 0)
DANGER = (255, 101, 101)
(省略)

def draw_map(bg, fnt, player, people): # ダンジョンを描画する
(省略)

    if talk_flag:
        draw_message(bg, fnt, player) # playerを追加
    if cmd_flag:
        draw_para(bg, fnt, player) # playerを追加
(省略)

def draw_message(bg, fnt, player): # playerを追加
    global talk_line, talk_end, talk_yesno, rest_flag

    col = WHITE
    for p in player:
        if p.hp < p.maxhp/4:
            col = DANGER
            break
        elif p.hp < p.maxhp/2:
            col = WARNING
(省略)

def draw_para(bg, fnt, player): # playerを追加
    col = WHITE
    for p in player:
        if p.hp < p.maxhp/4:
            col = DANGER
            break
        elif p.hp < p.maxhp/2:
            col = WARNING

MAXHPの1/4未満が1人でもいる:DANGER
MAXHPの1/2未満が1人でもいる:WARNING

です。

 

パラメータ表示

そして移動中の
パラメータの表示です。

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

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

    # x座標の開始位置 + 横幅 = 0.95にする(右端を0.05空ける)
    if len(player) == 1:
        x_p_i = bg.get_width()*0.8 # x座標の開始位置
        x_p_w = x_b # 横幅
    if len(player) == 2:
        x_p_i = bg.get_width()*0.65 # x座標の開始位置
        x_p_w = x_b * 2 # 横幅
    if len(player) == 3:
        x_p_i = bg.get_width()*0.5 # x座標の開始位置
        x_p_w = x_b * 3 # 横幅
    if len(player) == 4:
        x_p_i = bg.get_width()*0.35 # x座標の開始位置
        x_p_w = x_b * 4 # 横幅
    y_p_i = bg.get_height()*0.75 # y座標の開始位置
    y_p_h = bg.get_height()*0.25-20 # 高さ
    x_p_i_t = [] # テキストのx座標の開始位置
    y_p_i_t = y_p_i + 20 # テキストのy座標の開始位置
    pygame.draw.rect(bg, BLACK, [x_p_i, y_p_i, x_p_w, y_p_h], 0, 5) # 枠
    pygame.draw.rect(bg, col, [x_p_i, y_p_i, x_p_w, y_p_h], 2, 5) # 枠
    pygame.draw.line(bg, col, [x_p_i, y_p_i+48], [x_p_i+x_p_w, y_p_i+48], 2) # 枠
    for i, p in enumerate(player):
        x_p_i_t.append(x_p_i + x_b*i + 20) # テキストのx座標の開始位置
        draw_text(bg, "{}".format(p.name), x_p_i_t[i], y_p_i_t, fnt, col)
        if len(str(p.hp)) == 3:
            draw_text(bg, mojimoji.han_to_zen("H{}".format(p.hp)), x_p_i_t[i], y_p_i_t+36, fnt, col)
        elif len(str(p.hp)) == 2:
            draw_text(bg, mojimoji.han_to_zen("H {}".format(p.hp)), x_p_i_t[i], y_p_i_t+36, fnt, col)
        elif len(str(p.hp)) == 1:
            draw_text(bg, mojimoji.han_to_zen("H  {}".format(p.hp)), x_p_i_t[i], y_p_i_t+36, fnt, col)

        if len(str(p.mp)) == 3:
            draw_text(bg, mojimoji.han_to_zen("M{}".format(p.mp)), x_p_i_t[i], y_p_i_t+66, fnt, col)
        elif len(str(p.mp)) == 2:
            draw_text(bg, mojimoji.han_to_zen("M {}".format(p.mp)), x_p_i_t[i], y_p_i_t+66, fnt, col)
        elif len(str(p.mp)) == 1:
            draw_text(bg, mojimoji.han_to_zen("M  {}".format(p.mp)), x_p_i_t[i], y_p_i_t+66, fnt, col)
        
        if len(str(p.lv)) == 2:
            draw_text(bg, mojimoji.han_to_zen("L:{}".format(p.lv)), x_p_i_t[i], y_p_i_t+96, fnt, col)
        elif len(str(p.lv)) == 1:
            draw_text(bg, mojimoji.han_to_zen("L: {}".format(p.lv)), x_p_i_t[i], y_p_i_t+96, fnt, col)

 

仲間の数によって変えています。

 

 

プレイヤーをリストに

最後に
変数だった「player」を
「player[0]」に変更します。

変更前

def draw_map(bg, fnt, player, people): # ダンジョンを描画する
(省略)
    for y in range(-8, 10): # 高さの分割数に合わせる 18
        for x in range(-10, 12): # 幅の分割数に合わせる 22
            if player.x < 10:
                X = (x+player.x)*M_WIDTH

変更後

def draw_map(bg, fnt, player, people): # ダンジョンを描画する
(省略)
    for y in range(-8, 10): # 高さの分割数に合わせる 18
        for x in range(-10, 12): # 幅の分割数に合わせる 22
            if player[0].x < 10:
                X = (x+player[0].x)*M_WIDTH

こんな感じで全て変更します。

VSCodeの場合は
以下のショートカットキー
でまとめて変更するのが便利です。

Windows:Ctrl+D
Mac:⌘D

Windows:Ctrl+K Ctrl+D
Mac:⌘K ⌘D

一応、ご参考までにmove.pyを添付します。

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

 

 

最後に

今回は仲間を追加しました。

ただ、変更したのは
移動中のみの変更のため、
戦闘になるとエラーに
なってしまいます。

とうわけで、
次回は戦闘(battle.py)を
変更します。

まとめサイトへ

 

 

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

 

 

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

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