PythonとPygameで作る レトロ風RPG 全コード

同人誌について

 この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。

 同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。

(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)


10-3 移動

公開:2024-06-04

説明と全体コード

 「src/mymod/scene_map/move.py」の説明です。マップ上での移動を管理するモジュールです。上下左右のキーを押すことで、主人公を移動(マップをスクロール)させます。

import pygame
from .. import data, game, image
from . import event
MOVE_CYCLE = 250
last_move = 0
# 初期化
def init():
global last_move
last_move = pygame.time.get_ticks()
# 移動管理
async def manage_move(key_keep: str):
global last_move
d = data.game.data
time = pygame.time.get_ticks()
if time < last_move + MOVE_CYCLE:
# 移動中処理
d.move_rate = (time - last_move) / MOVE_CYCLE
return
else:
# 到着処理
last_move = time
move_goal(d) # 到着処理
# イベント発生判定
res = event.try_exec(d.x, d.y)
if res.type != event.NONE:
await image.dialog.a_show(res.text)
if res.type == event.BATTLE:
game.scene.Manager.set_next(data.scene.BATTLE)
return
move_next(key_keep, d) # 次回移動処理
# 到着処理
def move_goal(d: data.game.Game):
d.move_rate = 0
d.x = d.next_x
d.y = d.next_y
# 次回移動処理
def move_next(key_keep: str, d: data.game.Game):
k = key_keep; e = game.event
if k == e.K_LEFT and d.x > 0: d.next_x = d.x - 1
if k == e.K_RIGHT and d.x + 1 < d.map_w: d.next_x = d.x + 1
if k == e.K_UP and d.y > 0: d.next_y = d.y - 1
if k == e.K_DOWN and d.y + 1 < d.map_h: d.next_y = d.y + 1
# 水なら戻す
i = d.next_x + d.next_y * d.map_w
if d.data_map.map[i] == data.map.WATER:
d.next_x = d.x
d.next_y = d.y

インポート部分

 まずはインポート部分を示します。

import pygame
from .. import data, game, image
from . import event

定数と変数

 MOVE_CYCLEは、1マス歩くのにかかるミリ秒です。

 last_moveは、最終移動時間です。この時間からMOVE_CYCLEのミリ秒が経過したら、次のマスに移動します。

MOVE_CYCLE = 250
last_move = 0

変数と初期化

 変数と、初期化をおこなうinit()関数です。

# 初期化
def init():
global last_move
last_move = pygame.time.get_ticks()

 初期化では、last_moveに、pygame.time.get_ticks()関数を使って「ゲーム開始時点からの経過時間」を代入します。

移動管理

 次は移動管理をおこなうmanage_move()関数です。キー押しっぱなしの状態を表すkey_keepを引数にとります。

# 移動管理
async def manage_move(key_keep: str):
global last_move
d = data.game.data
time = pygame.time.get_ticks()
if time < last_move + MOVE_CYCLE:
# 移動中処理
d.move_rate = (time - last_move) / MOVE_CYCLE
return
else:
# 到着処理
last_move = time
move_goal(d) # 到着処理
# イベント発生判定
res = event.try_exec(d.x, d.y)
if res.type != event.NONE:
await image.dialog.a_show(res.text)
if res.type == event.BATTLE:
game.scene.Manager.set_next(data.scene.BATTLE)
return
move_next(key_keep, d) # 次回移動処理

 前回移動からの経過時間がMOVE_CYCLE未満なら、移動中処理として、GameDatamove_rateを更新します。

 前回移動からの経過時間がMOVE_CYCLE以上なら、到着と見なして、到着処理をおこないます。

 次のマスに到着したときは、last_moveを更新します。そして、到着処理move_goal()をおこない、イベント発生判定をおこなうevent.try_exec()関数を実行します。そして結果をresに代入します。

 res.typeevent.NONEでない、つまりイベントが発生したときは、ダイアログを表示します。イベントの種類が戦闘のときは、バトル シーンに移動します。戦闘でも、そうでなくても、return文で処理を打ち切ります。

 イベントが発生しなかったときは、次回移動処理move_next()関数を実行します。

到着処理

 到着処理move_goal()を示します。

# 到着処理
def move_goal(d: data.game.Game):
d.move_rate = 0
d.x = d.next_x
d.y = d.next_y

 GameDatamove_rate0にリセットして、x yを更新します。

次回移動処理

 次回移動処理move_next()を示します。

# 次回移動処理
def move_next(key_keep: str, d: data.game.Game):
k = key_keep; e = game.event
if k == e.K_LEFT and d.x > 0: d.next_x = d.x - 1
if k == e.K_RIGHT and d.x + 1 < d.map_w: d.next_x = d.x + 1
if k == e.K_UP and d.y > 0: d.next_y = d.y - 1
if k == e.K_DOWN and d.y + 1 < d.map_h: d.next_y = d.y + 1
# 水なら戻す
i = d.next_x + d.next_y * d.map_w
if d.data_map.map[i] == data.map.WATER:
d.next_x = d.x
d.next_y = d.y

 key_keepの状態によって、次の移動マスnext_x next_yを決定します。また、移動先が水のマス(侵入不可マス)の場合は、移動先を直前のマスに戻します。


 次の内容については省略します。こちらは同人誌をご覧ください。


同人誌について

 この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。

 同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。

(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)

 技術系同人誌など まとめページ


トップページに戻る
Cronus Crown(クロノス・クラウン)のトップページに戻る
(c)2002-2024 Cronus Crown (c)1997-2024 Masakazu Yanai
ご意見・お問い合わせはサイト情報 弊社への連絡までお願いします
個人情報の取り扱い、利用者情報の外部送信について