CODE Python RPG

独学でPythonでRPGを作成する(第32回)マップに移動制限をつける

投稿日:

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

前回はマップ(エリア)ごとに出現するモンスターを変えました。

今回はマップの場所によって移動できない制限をつけます。
あと、その他にもモンスターエリアを複数追加したり、
先制攻撃の時は逃げられるように変更します。

目次

  1. 移動の制限
  2. モンスターエリアを複数に
  3. 先制攻撃
  4. 最後に

移動の制限

マップによって移動できたり、できなかったりと
制限をつけます。

例えば、今までは海を歩けたりしましたが
歩けないようにします。

今は以下のようなマップチップを
利用させて頂いています。
緑\('ω')/箱さんの画像です。
当ブログ(第29回)

 

このマップチップをリストimgmapに格納しています。

imgmap = []
for i in range(31):
    imgmap.append(pygame.image.load("map/" + str(i) + ".png"))

 

なので、
imgmap[0]は「0.png」
imgmap[1]は「1.png」
になります。

そして、移動できないようにするのは
16.png〜30.png
にしますので、
imgmapのインデックスが16以上の時は
移動できないようにします。

 

imgmapは以下のようにして使っていますので
インデックスはリストn_mapの値のうち
後ろの2文字([2:]です。
※詳細は前回

bg.blit(imgmap[int(n_map[dy+y_range][dx+x_range][2:])], [X, Y])

 

リストn_mapはmaps.pyの
リストmapsです。
maps = [["0000", "0101",......]]

ということで、n_mapの後ろ2文字が
16以上の場合は移動できないようにします。

 

move.py

変更前

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

    if key[K_UP] == 1:
        player.d = 0
        if n_map[player.y-1][player.x] != 9:
            player.y = player.y - 1
    if key[K_DOWN] == 1:
        player.d = 1
        if n_map[player.y+1][player.x] != 9:
            player.y = player.y + 1
    if key[K_LEFT] == 1:
        player.d = 2
        if n_map[player.y][player.x-1] != 9:
            player.x = player.x - 1
    if key[K_RIGHT] == 1:
        player.d = 3
        if n_map[player.y][player.x+1] != 9:
            player.x = player.x + 1

 

変更後

(省略)
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:]) < 16:
                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:]) < 16: # player.y+1なので、player.y=map_h-1の時out of rangeになる
                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:]) < 16:
                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:]) < 16:
                player.x = player.x + 1

 

n_mapの後ろ2文字が16以上は移動できないので
16未満(<16)で移動できるようにしています。

また、今回のマップは海で囲まれるので、
端には移動できないですが、
マップから出ないように制限を追加しました。
※端に行ったら逆の端から出るようにしたいですが
 なんかおかしくなったので、制限つけます(^_^;)
 いずれ、修正したいと思います。

if player.y > 0:
if player.x > 0:
などのことです。

 

これで海には移動不可にできました。

 

 

モンスターエリアを複数に

前回、モンスターエリアを追加しましたが
1モンスターに付与できるのは1つのエリアのみでした。

 

出現するマップは1つに限らせたくないので
1モンスターにいくつもエリアを追加できるようにします。

エリアを複数にする場合は以下のように
「,」で区切ります。
※「0,2,3」はエリアが0か2か3のいずれかの場合に
 出現する可能性がある。

 

そしてbattle.pyでfindを使います。
前回、変更した箇所です。

変更前

list_land = [i for i, tmp in enumerate(list_mon_area) if tmp == str(mon_area)]

 

変更後

list_land = [i for i, tmp in enumerate(list_mon_area) if tmp.find(str(mon_area)) != -1]

 

findは指定した引数の文字列(mon_area)が
元の文字列(tmp)に含まれているかを
検索してくれます。
※詳細はこちら

あれば最初の位置、無ければ-1を返しますので
-1でなければ(!=-1)、
そのモンスターの出現エリアとなります。

これで、1モンスターが複数のエリアに
出現できるようになりました。

 

尚、findは該当の文字列が含まれているか確認するので
エリアで区切るのは「,」である必要はなく、
「/」でも「-」でも何でも同じ結果となります。

 

 

先制攻撃

戦闘についてです。

先制攻撃では100%逃げられるように
変更します。
※テストしていて気が付いたのですが、
 先制攻撃なのに逃げられないのは
 何となく違和感があり。。

battle.py

(省略)
ESCAPE_RATE = 60 # 逃げられる確率(100は100%逃げる)
(省略)

def main(screen, clock, font, fontS, player, area):
(省略)
    btl_start = 0 # 0:通常、1:先制攻撃、2:不意打ち

(省略)

        elif idx == 14: # 逃げられる?
            draw_battle(screen, fontS, turn_obj, player)
            if tmr == 1:
                set_message(player.name + " は逃げ出した!")
            if tmr == 5:
                if btl_start == 1 or random.randint(0, 99) < ESCAPE_RATE: # 変更
                    btl_exp = 0 # 逃げたら0
                    idx = 22 # 戦闘終了
                else:
                    set_message("しかし、まわりこまれてしまった!")

 

先制攻撃はbtl_startが1の時なので
逃げられる条件を以下に変更しました。
※btl_start == 1を追加

if btl_start == 1 or random.randint(0, 99) < ESCAPE_RATE:

これで先制攻撃の時は逃げられるようになりました(^_^)

 

あと、逃げられる確率を定数にしました。
ESCAPE_RATE = 60

プレイヤーのレベルやモンスター側の条件によって
逃げられる確率を変更できたらな、と思っています。
いずれ・・

 

ついでに、モンスターの出現確率も定数にしました。
APPEAR_RATE = 20

こちらもエリアによって、出現確率を変更できたらな、
と思っています。
いずれ・・

(省略)
APPEAR_RATE = 20 # モンスターの出現確率(0は0%)
(省略)

def move_player(key, player): # 主人公の移動
    global tmr, food, potion, blazegem, treasure

    if random.randint(0, 99) < APPEAR_RATE: # 敵出現

 

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

 

 

最後に

今回はマップの場所によって
移動できない制限をつけました。

ただ、変えた後に気が付いたのですが、
5.pngの山も歩けなくするつもりでした。
※赤枠
 プレイヤーがいる場所も5.pngの山

が、今回はこのままにしました(^_^;)

そのうち、また町のマップとかも作りますが、
その時に移動の制限とかも
まとめて変えようかと思っています(^_^)

 

次回はまた戦闘に戻って呪文を変更しようと思います。
今は攻撃呪文の対象がモンスター1匹のみですが
グループもしくは全体に攻撃できるようにしたいと思います。

まとめサイトへ

 

 

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

 

 

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

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