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

同人誌について

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

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

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


5-1 プログラムの開始場所

公開:2024-03-12

 ここからは、レトロ風RPGのプログラムに入っていきます。同人誌の内容から、いくつかの場所を抜粋して掲載していきます。


説明

 プログラムの基本的な方針としては、辞書ではなくクラスをなるべく使います。辞書では静的解析ができず、『mypy』で効率的にバグを発見することができません。クラスならば、誤字脱字で属性名が違えばバグとして検出できます。辞書では、キー名に誤字脱字があってもバグとして検出できません。

 また、機能ごとになるべくファイルを分割してモジュール化します。これは、プログラムの見通しをよくするためです。また、本として説明する際に、あまり長いコードでは読者が読み取りにくいためです。

 コードの書き方については、横が80文字を越えないように書いています。現在のプログラムは横に長くなる傾向があります。しかし本として読む場合には、横に長すぎると読みにくいです。そのためプログラムの途中でも改行を入れるようにしています。

main.py

 まずは「src/main.py」を示します。

import pygame, asyncio
from mymod.image import screen
from mymod.game import event, scene
import init
# メイン
async def main():
# 初期化
init.init_cwd() # CWDの初期化
pygame.init() # Pygameを初期化
screen.init_win() # ウィンドウの初期化
init.init_game() # ゲームの初期化
# ゲームループ
while True:
screen.update_pre() # 更新の前処理
screen.clear() # 画面の消去
e = event.exec() # イベント実行
if e.running == False: break # ゲームの終了
b = screen.get_buffer() # バッファ取得
await scene.Manager.update(b, e) # シーンの更新
screen.update_post() # 更新の後処理
# 終了
pygame.quit()
# 実行
if __name__ == "__main__":
asyncio.run(main())

 『Pygame』を使った基本的な構造は同じです。そこから実際に使うプログラムとして、いくつか改良している点があります。

async/await

 まず、1行目でasyncioをインポートしています。6行目のmain()にはasyncを付けています。29行目の最初の実行はasyncio.run(main())にしています。

import pygame, asyncio
async def main():
asyncio.run(main())

 これは、23行目のawait scene.Manager.update(b, e)でシーンの更新をawait付きでおこなっているためです。

await scene.Manager.update(b, e) # シーンの更新

 各シーンのupdate()では、await付きのプログラムを使います。具体的にはダイアログの表示で使います。ダイアログを表示しているあいだ、メイン ループの処理を待ちます。そのため、asyncmain()関数を実行しています。

 それでは、main()関数の処理を順番に見ていきましょう。

初期化

 まずは初期化の部分です。

# 初期化
init.init_cwd() # CWDの初期化
pygame.init() # Pygameを初期化
screen.init_win() # ウィンドウの初期化
init.init_game() # ゲームの初期化

 次のような初期化をおこないます。

描画とイベント処理

 次は描画とイベント処理です。

# ゲームループ
while True:
screen.update_pre() # 更新の前処理
screen.clear() # 画面の消去
e = event.exec() # イベント実行
if e.running == False: break # ゲームの終了
b = screen.get_buffer() # バッファ取得
await scene.Manager.update(b, e) # シーンの更新
screen.update_post() # 更新の後処理

 ここでは隠蔽されていますが、描画処理はscreenに直接おこなうのではなく、ドット絵用の小さなSurfaceb バッファ)に描画したあと、画面に相当するSurfacescreen)に描画しています。

バッファの利用(小さく描画して表示時に拡大)

 こうすることで、ドット絵風の画面を、ウィンドウのサイズに自動で拡大表示できるようにしています。

 イベントについては、event.exec()関数で、イベントの情報をまとめたオブジェクトを得ています。e.runningFalseならゲームは終了します。それ以外の場合は、シーンの更新をおこないます。

 シーンの更新をおこなうscene.Manager.update()関数は、screen.get_buffer()関数で得たbと、イベントのオブジェクトeを引数にします。


同人誌について

 この連載は、同人誌『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
ご意見・お問い合わせはサイト情報 弊社への連絡までお願いします
個人情報の取り扱い、利用者情報の外部送信について