ゲーム開発入門③ タイトル・プレイ・ゲームオーバーを切り替えよう
状態管理の考え方を使い、タイトル、プレイ中、ゲームオーバーの画面と処理を整理する方法を解説します。
小さなゲームでも、タイトル、プレイ中、ゲームオーバーなど、役割の違う画面があります。
すべての処理を同時に動かすと、タイトル画面で敵が動いたり、ゲームオーバー後も得点が増えたりします。現在の状態を1つ決め、処理を切り替えましょう。
状態を名前で表す
まず、現在の画面を変数へ保存します。
scene = "TITLE"
sceneはシーン、つまりゲーム内のまとまった画面や場面を表しています。名前は自由ですが、表記を統一することが大切です。
if文で処理を分ける
ゲームループの中で、現在のシーンに合う処理だけを実行します。
if scene == "TITLE":
update_title()
elif scene == "PLAYING":
update_game()
elif scene == "GAME_OVER":
update_game_over()
update_titleなどは、それぞれの画面を更新する関数です。関数に分けると、1つの場所へ処理が集中するのを防げます。
操作をきっかけに切り替える
タイトル画面で決定キーが押されたら、プレイ中へ移ります。
if scene == "TITLE" and enter_pressed:
scene = "PLAYING"
体力が0になったらゲームオーバーへ移します。
if scene == "PLAYING" and hp <= 0:
scene = "GAME_OVER"
このように、状態と切り替えの規則をまとめた考え方をステートマシンと呼びます。
切り替え時に初期化する
ゲームを再開するときは、シーン名だけでなく必要なデータも戻します。
def start_game():
global scene, score, hp
score = 0
hp = 3
scene = "PLAYING"
実際の規模が大きくなったら、globalへ頼りすぎずクラスなどにまとめます。最初は「開始時に何を初期化するか」を一覧にするだけでも、再開時の不具合を減らせます。
練習:一時停止を追加する
プレイ中にPキーを押すとPAUSEへ移り、もう一度Pキーを押すとPLAYINGへ戻る条件を書いてください。
模範解答
if scene == "PLAYING" and p_pressed:
scene = "PAUSE"
elif scene == "PAUSE" and p_pressed:
scene = "PLAYING"
解説
同じキーでも、現在のシーンによって移動先が変わります。PAUSE中にはプレイヤーや敵の更新を呼ばず、一時停止画面の入力と描画だけを行います。
小さな完成形を目指そう
最初の作品では、シーンを増やしすぎないことが大切です。
タイトル、プレイ、ゲームオーバーの3つだけでも、開始と終了があるゲームになります。そこへ座標と当たり判定を組み合わせ、コインを集める短いゲームから作ってみましょう。