5-2 初期化
同人誌について
この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで288ページの本になります。ぜひ、こちらもご購入ください(2024-03-10:ver1.0.3 に更新)。
init.py
「init.py」は、「main.py」の補助的なモジュールです。行数が多い初期化処理を、関数にまとめています。
このファイルでは、次のことをおこなっています。
カレント ワーキング ディレクトリの初期化
ゲームの初期化
データの初期化
シーンの追加
最初のシーンのセット
それでは「src/init.py」を示します。
import os, sys
import mymod as m
from mymod.image import font
from mymod.data import game, audio, scene
from mymod.game.scene import Manager
# CWD(カレント ワーキング ディレクトリ)の初期化
def init_cwd():
#print(os.getcwd()) # CWDの表示
app_path = __file__
if getattr(sys, 'frozen', False): app_path = sys.executable # EXE化時
app_dir = os.path.dirname(os.path.dirname(app_path)) # 親の親
os.chdir(app_dir) # CWDの移動
#print(os.getcwd()) # CWDの表示
# ゲームの初期化
def init_game():
# データの初期化
font.init() # フォントの初期化
game.data = game.Game.from_blank() # データ作成
audio.load_all() # 音声のロード
# シーンの追加
Manager.add_scene(m.SceneTitle)
Manager.add_scene(m.SceneMap)
Manager.add_scene(m.SceneBattle)
# 最初のシーンのセット
Manager.set_next(scene.TITLE)
#Manager.set_next(scene.MAP)
#Manager.set_next(scene.BATTLE)
インポート部分
まずは、インポート部分です。多くのものを読み込んでいます。
import os, sys
import mymod as m
from mymod.image import font
from mymod.data import game, audio, scene
from mymod.game.scene import Manager
標準ライブラリの`os`と`sys`を読み込みます。また、`mymod`パッケージを`m`として読み込みます。
その他に`font` `game` `audio` `scene`といったモジュールを読み込みます。
また、`mymod.game.scene`モジュールの`Manager`クラスも読み込みます。
カレント ワーキング ディレクトリの初期化
`init_cwd()`関数では、カレント ワーキング ディレクトリ(CWD)の調整をおこないます。
# CWD(カレント ワーキング ディレクトリ)の初期化
def init_cwd():
#print(os.getcwd()) # CWDの表示
app_path = __file__
if getattr(sys, 'frozen', False): app_path = sys.executable # EXE化時
app_dir = os.path.dirname(os.path.dirname(app_path)) # 親の親
os.chdir(app_dir) # CWDの移動
#print(os.getcwd()) # CWDの表示
「main.py」から実行したときと、『PyInstaller』で作ったEXEファイルから実行したときでは、パスの得方が違うので、その分岐をします。そして、次の図の「root/」のところをカレント ワーキング ディレクトリに変更します。
root/ …… ここをカレント ワーキング ディレクトリにする。
src/
main.py
init.py …… 「main.py」から実行したとき。
dist/
main.exe …… EXE化したとき。
audio
font
image
「main.py」から実行したときは、`file`を使って「init.py」の絶対パスを得ます。
「main.exe」から実行したときは、`sys.executable`を使ってEXEファイルのパスを得ます。
分岐は次の行でおこないます。
app_path = __file__
if getattr(sys, 'frozen', False): app_path = sys.executable # EXE化時
`getattr()`関数は、オブジェクトの属性の値を得る関数です。第1引数がオブジェクト、第2引数が属性名、第3引数は属性が存在しなかったときのデフォルト値です。
第3引数がなく、属性がなかったときは`AttributeError`が発生します。ここでは第3引数に`False`を設定しているのでエラーは発生しません。
上のプログラムでは、`sys`オブジェクトに`frozen`の値があり、かつ`True`だったときに、`app_path = sys.executable`の処理を実行します。
「root/」を、カレント ワーキング ディレクトリに変更しているのは、次の部分です。
app_dir = os.path.dirname(os.path.dirname(app_path)) # 親の親
os.chdir(app_dir) # CWDの移動
`os.path.dirname()`関数を2回使い、親ディレクトリの親ディレクトリを得ます。そして`os.chdir()`関数で、カレント ワーキング ディレクトリを設定します。
`init_cwd()`関数で使用している関数と、その説明をまとめておきます。
関数の説明
ゲームの初期化
ゲームの初期化をおこなう`init_game()`関数の処理は、3つのブロックに分かれます。「データの初期化」「シーンの追加」「最初のシーンのセット」です。
# ゲームの初期化
def init_game():
# データの初期化
font.init() # フォントの初期化
game.data = game.Game.from_blank() # データ作成
audio.load_all() # 音声のロード
# シーンの追加
Manager.add_scene(m.SceneTitle)
Manager.add_scene(m.SceneMap)
Manager.add_scene(m.SceneBattle)
# 最初のシーンのセット
Manager.set_next(scene.TITLE)
#Manager.set_next(scene.MAP)
#Manager.set_next(scene.BATTLE)
最初が「データの初期化」です。ここではフォントの初期化と、ゲーム データの作成と、音声の事前ロードをおこないます。
次が「シーンの追加」です。タイトル、マップ、バトルの3つのシーンを、自作のシーンマネージャーに登録します。シーンのあつかいについては、のちほど説明します。
最後が「最初のシーン」のセットです。ここではタイトル シーンを次のシーンとしてセットしています。そして、他のシーンはコメントアウトしています。
コメント部分を切り替えると、起動時に開くシーンを変えられます。これは、開発時に効率よく各シーンを実装していけるようにするためです。
こうした、起動時のシーンの切り替えができないと、プログラムの確認をしたいシーンまで移動するのが大変です。開発が終わり、本番になったら、タイトル シーンに戻すことを忘れないようにします。
それでは次の章から、ゲームの中身を作っていきます。
次の内容については省略します。こちらは同人誌をご覧ください。
5-3 実行のバッチファイル
同人誌について
この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで288ページの本になります。ぜひ、こちらもご購入ください(2024-03-10:ver1.0.3 に更新)。
このnoteの記事と、Webページに一部抜粋版を掲載しています。
技術系同人誌など まとめページ