CODE Python RPG

独学でPythonでRPGを作成する(第43回)町へ移動する

投稿日:

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

前回はフィールドマップを作りました。

今回は町のマップも作って、フィールドマップから町のマップへ移動できるようにします。

目次

  1. 町のマップ
  2. モンスターの出現
  3. 町へ移動
  4. 最後に

町のマップ

町のマップを作成します。

class Maps():
    def get_map(self, num, player):
        if num == 0: # フィールド
(省略)

        if num == 1: # 町
            maps = [
                ["99118", "99101", "99101", "99101", "99101", "99101", "99101", "99101", "99101", "99101", 
(省略)

            ]
            player.d = 1 # プレイヤーの向き
            player.a = 2 # プライヤーの画像
            player.x = 4 # マップの最初のx座標
            player.y = 23 # マップの最初のy座標
        return maps

「99118」の後半3桁がマップ情報で
前半の2桁はモンスターエリアです。
前回も記載した通りです。
 マップの画像も前回に作成したものを
 そのまま利用します。

maps.pyは以下です。

 

以下のような感じです。

なお、モンスターエリアは
全て99にしています。
99:モンスターエリア
118:マップ情報(画像のファイル名)

町の中ではモンスターは
出現しないようにします。

なので、モンスターエリアが99の時は
モンスターが出現しないように変更します。

 

 

モンスターの出現

モンスターエリアが99の時は
モンスターが出現しないようにしますが
その前にモンスター出現の判定位置を
変更します。

変更前

def move_player(key, player): # プレイヤーの移動
    global tmr, food, potion, blazegem, treasure

    if tmr == 1:
        if random.randint(0, 99) < appear_rate: # モンスター出現
            tmr = 0
            return 10
(省略)

    if player.x != x or player.y != y: # 移動したら食料の量と体力を計算
        player.a = player.a + tmr%2 # 移動したら足踏みのアニメーション
        # n_map[y][x] = 0 # いた場所を0にする
        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
                pygame.mixer.music.stop()
                tmr = 0
                return 9
    return 1

変更後

def move_player(key, player): # プレイヤーの移動
(省略)

    if player.x != x or player.y != y: # 移動したら食料の量と体力を計算
        player.a = player.a + tmr%2 # 移動したら足踏みのアニメーション
        # n_map[y][x] = 0 # いた場所を0にする
        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
                pygame.mixer.music.stop()
                tmr = 0
                return 9

        #####移動#####
        if random.randint(0, 99) < appear_rate: # モンスター出現
            tmr = 0
            return 10
    return 1

モンスター出現の判定は
move_player関数の最初にしていましたが
プレイヤーが移動した後に
判定することにしました。

今まで移動していないのに
モンスターが出現していました。

これは何となくおかしいので、
これからはプレイヤーが移動したら
モンスターが出現するようにしました。

 

そして、モンスターエリアが99の時は
モンスターが出現しないようにします。

def move_player(key, player): # プレイヤーの移動
(省略)

    if player.x != x or player.y != y: # 移動したら食料の量と体力を計算
        # player.a = player.a + tmr%2 # 移動したら足踏みのアニメーション
        # n_map[y][x] = 0 # いた場所を0にする
        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
                pygame.mixer.music.stop()
                tmr = 0
                return 9

        if int(n_map[player.y][player.x][:2]) != 99: # モンスターエリアが99は敵が出ない
            if random.randint(0, 99) < appear_rate: # 敵出現
                tmr = 0
                return 10
    return 1
if int(n_map[player.y][player.x][:2]) != 99:

この1行を追加しただけです。

 

 

町へ移動

フィールドから町へ
移動できるようにします。

move.py

area = 0 # マップ番号
(省略)

def move_player(key, player): # プレイヤーの移動
    global tmr, food, potion, blazegem, treasure, area # areaを追加
(省略)

        if int(n_map[player.y][player.x][:2]) != 99: # モンスターエリアが99は敵が出ない
            if random.randint(0, 99) < appear_rate: # 敵出現
                tmr = 0
                return 10
    #####追加#####
    if int(n_map[player.y][player.x][2:]) == 13 or int(n_map[player.y][player.x][2:]) == 14:
        area = 1 # 町
        return 11
    return 1

最初にグローバル変数areaを
追加します。

areaにはマップの番号を入れます。

これはmaps.pyの番号(num)です。

class Maps():
    def get_map(self, num, player):
        if num == 0: # フィールド
(省略)

        if num == 1: # 町

area が0の場合はフィールド、
area が1の場合は町
です。

if int(n_map[player.y][player.x][2:]) == 13 or int(n_map[player.y][player.x][2:]) == 14:
    area = 1 # 町
    return 11

マップ情報の13と14は以下の位置です。

maps.py

13か14にプレイヤーが移動したら
町へ移動します。
※町ではなく城ですね・・(^_^;)
※フィールド上の
 城のモンスターエリアは99にして
 モンスターが出ないようにしています。
※マップの画像ファイル名は
 13.png、14.png です。

 

マップ情報が13か14の位置に移動したら
area を1(町)にして
idx を11にします。
※main関数にidx11を返す。

main関数にidx11が無いので
idx11を追加します。

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

        if idx == 1:
            idx = move_player(key, player) # 町へ移動する時はidx 11
            draw_map(screen, fontS, player)
(省略)

        elif idx == 11: # マップ遷移
            return 2, area
elif idx == 11: # マップ遷移
    return 2, area

one_hour_dungeon.pyのidxへ
2を返します。

今までmove.pyから返す時は
モンスターエリアのみでしたが
これからはマップ情報も返します。

※モンスターエリアを返す時
 idxは10を返します。

def move_player(key, player): # プレイヤーの移動
(省略)

        if int(n_map[player.y][player.x][:2]) != 99: # モンスターエリアが99は敵が出ない
            if random.randint(0, 99) < appear_rate: # 敵出現
                tmr = 0
                return 10 # move.pyのmain関数のidxに10を返す
(省略)

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

        if idx == 1:
            idx = move_player(key, player) # 戦闘(モンスター出現)の時はidx 10
            draw_map(screen, fontS, player)
(省略)

        elif idx == 10: # 戦闘(モンスター出現) モンスターエリアを返す
            return 10, int(n_map[player.y][player.x][:2]) # one_hour_dungeon.pyのidxへ10を返す

 

次に、町へ移動する為に
one_hour_dungeon.pyを変更します。

変更前

def main(): # メイン処理
(省略)
    mon_area = 99

(省略)
        elif idx == 1:
            tmr = 0
            idx, mon_area = move.main(screen, clock, font, fontS, n_map, player)
        elif idx == 2: # マップの設定
            n_map = maps.get_map(0, player)
            idx = 1

        elif idx == 10: # 戦闘開始
            tmr = 0
            idx = battle.main(screen, clock, font, fontS, player, mon_area)

変更後


def main(): # メイン処理
(省略)

    area = 0 # マップ番号、モンスターエリア
(省略)

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

            if key[K_SPACE] == 1:
                player.reset()
                player.spell_reset()
                floor = 1
                idx = 2 # マップの設定
                area = 0 # 追加
        elif idx == 1:
            tmr = 0
            idx, area = move.main(screen, clock, font, fontS, n_map, player) # mon_area → area
        elif idx == 2: # マップの設定
            n_map = maps.get_map(area, player) # 0 → area
            idx = 1
        elif idx == 10: # 戦闘開始
            tmr = 0
            idx = battle.main(screen, clock, font, fontS, player, area) # mon_area → area

変数をmon_areaからareaに変更して
タイトル画面(idx0)で必ずareaを0 にします。
※全滅した時もです。

elif idx == 1:
    tmr = 0
    idx, area = move.main(screen, clock, font, fontS, n_map, player) # mon_area → area

マップ遷移する時は
idxが2、
areaが遷移先のマップ番号
になります。
※遷移先が町の場合はマップ番号:1

elif idx == 2: # マップの設定
    n_map = maps.get_map(area, player) # 0 → area
    idx = 1

マップ番号をもとに(引数で渡す)
遷移先のマップ情報を取得して
move.pyのmain関数へ移ります。

 

これでフィールドから町へ
移動できるようになりました。

ただ、町へ移動した後は
一歩も動けません。

これはmove.pyの判定が
おかしい為です。

変更前

def move_player(key, player): # プレイヤーの移動
(省略)

    if key[K_UP] == 1:
        player.d = 0
        if player.y > 0:
            if int(n_map[player.y-1][player.x][2:]) < 15:
                player.y = player.y - 1
    if key[K_DOWN] == 1:
        player.d = 1
        if player.y < map_h-1: # map_hになるとout of rangeになる
            if int(n_map[player.y+1][player.x][2:]) < 15:
                player.y = player.y + 1
    if key[K_LEFT] == 1:
        player.d = 2
        if player.x > 0:
            if int(n_map[player.y][player.x-1][2:]) < 15:
                player.x = player.x - 1
    if key[K_RIGHT] == 1:
        player.d = 3
        if player.x < map_w-1:
            if int(n_map[player.y][player.x+1][2:]) < 15:
                player.x = player.x + 1

マップ情報が15未満は移動できません。
この条件を変更します。

変更後

def move_player(key, player): # プレイヤーの移動
(省略)

    if key[K_UP] == 1:
        player.d = 0
        if player.y > 0:
            if int(n_map[player.y-1][player.x][2:]) < 101: # 15 → 101
                player.y = player.y - 1
    if key[K_DOWN] == 1:
        player.d = 1
        if player.y < map_h-1: # map_hになるとout of rangeになる
            if int(n_map[player.y+1][player.x][2:]) < 101: # 15 → 101
                player.y = player.y + 1
    if key[K_LEFT] == 1:
        player.d = 2
        if player.x > 0:
            if int(n_map[player.y][player.x-1][2:]) < 101: # 15 → 101
                player.x = player.x - 1
    if key[K_RIGHT] == 1:
        player.d = 3
        if player.x < map_w-1:
            if int(n_map[player.y][player.x+1][2:]) < 101: # 15 → 101
                player.x = player.x + 1

マップ情報の移動条件を
15から101に変更しました。

前回、マップ情報が
31個から129個になり、
移動可能なマップ画像が増えた為、
条件を変える必要がありました。
※町では15以上のマップ画像を
 使っています。

 

これで町でも移動できるように
なりました。

 

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

 

 

最後に

今回はフィールドから町へ移動できるようにしました。

次回は町に人を追加しようと思います。

まとめサイトへ

 

 

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

 

 

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

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