開始プログラムと各画面のファイル
続いて、開始プログラムと各画面のファイルを作ります。開始プログラムはmain.py
です。各画面のファイルは、s_battle
フォルダー、s_map
フォルダー、s_title
フォルダー内に配置したmain.py
とします。
main.py s_battle/ main.py s_map/ main.py s_title/ main.py
まずは、各画面のファイルです。まだ処理は未実装なので、全て同じ内容にします。初期化をおこなうinit()
関数と、更新をおこなうupdate()
関数を用意します。処理は未実装なのでpass
だけ書きます。
# 初期化 def init(): pass # 更新 def update(): pass
続いて開始プログラムのmain.py
を書きます。基本的にはPygameの基本コードと同じなのですが、ボリュームが大きくなっています。そのため、いくつかに分割して説明を加えます。
import pygame, data pygame.init() # Pygameを初期化 data.screen = pygame.display.set_mode((data.W, data.H)) # 画面作成 import s_title.main, s_map.main, s_battle.main # ゲームループ running = True # 実行継続フラグ while running: # キーの受け付け data.key = {"down": None, "keep": pygame.key.get_pressed()} for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: # キー押し下げ data.key["down"] = event.key # キー種類 pygame.display.update() # 画面を更新 data.screen.fill((0, 0, 0)) # 画面を塗りつぶす # シーン変更 if data.scene != data.scene_next: data.scene = data.scene_next # シーン変更 if data.scene == "title": s_title.main.init() # タイトル初期化 if data.scene == "map": s_map.main.init() # マップ初期化 if data.scene == "battle": s_battle.main.init() # バトル初期化 # シーン更新 if data.scene == "title": s_title.main.update() # タイトル更新 if data.scene == "map": s_map.main.update() # マップ更新 if data.scene == "battle": s_battle.main.update() # バトル更新 pygame.display.flip() # 画面フリップ # 終了 pygame.quit()
インポート部分
まずはインポート部分です。
import pygame, data pygame.init() # Pygameを初期化 data.screen = pygame.display.set_mode((data.W, data.H)) # 画面作成 import s_title.main, s_map.main, s_battle.main
一度にインポートせずに、pygame, data
と、s_title.main, s_map.main, s_battle.main
を分けてインポートしています。重要なのはpygame.init()
です。Pygameの処理の中には、pygame.init()
をおこなう前に使うとエラーになるものがあります。そのため、pygame.init()
をおこなったあとに、各画面のモジュールを読み込みます。
キーの受け付け
次はキーの受け付けです。
# キーの受け付け data.key = {"down": None, "keep": pygame.key.get_pressed()} for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: # キー押し下げ data.key["down"] = event.key # キー種類
まずは、data.key
(data.py
の変数key
)に、辞書{"down": None, "keep": pygame.key.get_pressed()}
を代入します。この結果、各要素がどのようになるのかを示します。
要素 | 値 |
---|---|
data.key["down"] | None(値なし) |
data.key["keep"] | pygame.key.get_pressed()の戻り値 |
for event in pygame.event.get():
のループの中で、何かキーが押し下げられたら、data.key["down"]
にevent.key
の値を代入します。
こうすることで、data.key
を利用して、キーの押し下げと押しっぱなしの情報に手軽にアクセスできるようにします。
シーン変更
次はシーン変更です。
# シーン変更 if data.scene != data.scene_next: data.scene = data.scene_next # シーン変更 if data.scene == "title": s_title.main.init() # タイトル初期化 if data.scene == "map": s_map.main.init() # マップ初期化 if data.scene == "battle": s_battle.main.init() # バトル初期化
data.scene
(data.py
の変数scene
)と、data.scene_next
(data.py
の変数scene_next
)の値が異なるときは、data.scene
の値をdata.scene_next
の値に更新します。また、更新したdata.scene
の値により、各画面の初期化処理をおこないます。
data.sceneの値 | 実行する関数 | 処理の内容 |
---|---|---|
"title" | s_title.main.init() | タイトル画面の初期化 |
"map" | s_map.main.init() | マップ画面の初期化 |
"battle" | s_battle.main.init() | バトル画面の初期化 |
シーン更新
次はシーン更新です。
# シーン更新 if data.scene == "title": s_title.main.update() # タイトル更新 if data.scene == "map": s_map.main.update() # マップ更新 if data.scene == "battle": s_battle.main.update() # バトル更新
data.scene
の値により、各画面の更新処理をおこないます。
data.sceneの値 | 実行する関数 | 処理の内容 |
---|---|---|
"title" | s_title.main.update() | タイトル画面の更新 |
"map" | s_map.main.update() | マップ画面の更新 |
"battle" | s_battle.main.update() | バトル画面の更新 |
それでは次は、タイトル画面の初期化と更新を見ていきましょう。
タイトル画面
ここではタイトル画面を作ります。タイトル画面の処理は、s_title/main.py
モジュール1つだけです。
s_title/ main.py
タイトル画面の初期化と更新
タイトル画面の初期化と更新をおこなうs_title/main.py
モジュールのプログラムを示します。
import pygame, data, img, audio from data import U, COL_W def init(): audio.play(audio.FIELD) # BGM再生 # 更新 def update(): # 文字描画 img.font.render_to(data.screen, (U, U), "ZineQuest", COL_W, size = img.fsz * 5.5) img.font.render_to(data.screen, (U * 6, U * 11), " PRESS SPACE KEY ", COL_W) img.font.render_to(data.screen, (U * 6, U * 12), "Key: ↑ ← ↓ → Space", COL_W) img.font.render_to(data.screen, (U * 6, U * 13), "(c)2024 Masakazu Yanai", COL_W) # 画像描画 image = pygame.transform.scale(img.chara[0], (U * 4, U * 4)) # 拡大画像生成 data.screen.blit(image, (U * 8, U * 6)) # 画像描画 # SPACEキー押し下げでマップに移動 if data.key["down"] == pygame.K_SPACE: data.scene_next = "map"
冒頭のインポート部分では、pygame, data, img, audio
を読み込みます。またdata
モジュールから、描画単位U
と、白色COL_W
を読み込みます。
初期化をおこなうinit()
関数では、フィールドのBGMを再生します。
更新をおこなうupdate()
関数では3つのことをおこないます。文字の描画と、画像の描画と、キー操作の処理です。
文字の描画では、上から順番にタイトルと、説明文3種を描画します。タイトルだけsize = img.fsz * 5.5
として文字サイズを大きくしています。
画像の描画では、pygame.transform.scale()
関数を使い、描画単位U
の4倍に拡大してからblit()
関数で描画します。
キー操作の処理では、data.key["down"]
の値が、pygame.K_SPACE
([スペース]キー)だったときに、次の画面data.scene_next
を"map"
にします。こうすることでマップ画面に移動します。
この時点では、マップ画面のプログラムはまだ実装していないので、黒一色の状態になります。