【pygame】チャプター1-2:ゲームループの基本をマスターしよう
一つ前のページではpygameの導入方法について学習しました。
今回は ゲームループの基本 について見ていきましょう。
Chapter1:pygame入門|画面を表示しよう
・Chapter1-1:pygameを導入しよう
・Chapter1-2:ゲームループの基本を理解しよう ◁今回はここ
・Chapter1-3:画面に画像を表示しよう
・Chapter1-4:画面に文字を表示しよう
・Chapter1-5:画面上の画像を動かそう
Chapter2:簡単なノベルゲームを作ろう
Chapter3:簡単なアクションゲームを作ろう
Chapter4:ブロック崩しを作ろう
Chapter5:シューティングゲームを作ろう
Extra1:横スクロールのアクションゲームを作ろう
ゲーム開発において、「ゲームループ」はゲームの動作を支える重要な仕組みの一つです。
ゲームではキャラクターを動かしたり、敵の出現を管理したり、スコアを更新したりといったさまざまな処理を常に繰り返し行う必要があります。これらの処理をまとめて制御するのが「ゲームループ」です。
例えばテレビゲームをプレイするとき、プレイヤーがボタンを押すとキャラクターが移動し、それに応じて背景や敵も変化します。
このような「画面を更新し続ける仕組み」がなければ、ゲームは静止画のままで動くことはありません。つまりゲームループがなければ、ゲームは成立しないのです。
この章ではまずゲームループの仕組みを学び、実際にコードを動かしてその動作を理解していきます。
プログラムを作成しながら、ゲーム開発の第一歩を踏み出してみましょう!
ゲームループとは何か|仕組みと重要性
ゲームループとは、ゲームが動作している間、常に繰り返される一連の処理 のことを指します。
ゲームがリアルタイムで動作し続けるためには、以下のような処理を繰り返し行う必要があります。
基本の流れと構成要素|入力→更新→描画
ゲームの基本的な動作は、以下のような流れになっています。
- 初期化:ゲームの準備をする
- メインループ:以下の5つの動作を繰り返す
- 入力処理:ユーザーの操作を受け取る
- ゲームの更新:キャラクターの動き、当たり判定、スコア更新など
- 描画処理:画面の更新(最新の画面を作成)
- 画面の表示:最新の画面を表示
- 終了判定:ゲームを終了するかどうかを判定
②のメインループの中の処理を 1秒間に何十回も繰り返す ことで、ゲームはリアルタイムに動作します。
ゲームループが必要な理由と役割
ゲームは普通のプログラムとは異なり、「常に動き続ける」 ことが求められます。
たとえば普通のPythonプログラムでは、処理が終わればプログラムも終了します。しかしゲームではユーザーが操作している間、ずっと動き続けなければなりません。
もしゲームループがなかったら、キャラクターが一度だけ動いて止まったり、ボタンを押しても画面が変化しなかったりと、ゲームとして成り立たなくなってしまいます。
ゲームループを使ってリアルタイムで処理を繰り返すことが重要 なのです。
実際にゲームループを作ってみよう
ゲームループの仕組みを理解するために、簡単なPygameプログラムを実装して実際に動作を確認してみましょう。
このプログラムでは、「白い背景に赤い円を表示する」だけのシンプルなゲームループを作成します。
ゲームループを実装するコード例
以下のコードをエディタに書き込んで実行してください。
コピーして貼り付けることもできますが、このコードはゲームループの基礎中の基礎であるため、覚えるためにもぜひ手打ちすることを推奨します。
import pygame, sys # pygameとsysモジュールをインポート pygame.init() # pygameを初期化 screen = pygame.display.set_mode((800,600)) # 画面のサイズを設定(幅800px、高さ600px) # 無限ループでゲームを動作させる while True: # 画面を白色で塗りつぶす(毎フレームの更新) screen.fill(pygame.Color("WHITE")) # 赤い円を描画(座標(100,100)から幅100、高さ100の楕円) pygame.draw.ellipse(screen, pygame.Color("RED"), (100, 100, 100, 100)) # 画面の更新(描画した内容を反映) pygame.display.update() # イベント処理(ウィンドウの閉じるボタンが押されたら終了) for event in pygame.event.get(): if event.type == pygame.QUIT: # 閉じるボタンが押されたか確認 pygame.quit() # pygameを終了 sys.exit() # プログラムを終了
このコードを実行すると、以下のような動作をします。
- ウィンドウが開き、白い背景に赤い円が表示される。
- ×ボタン(ウィンドウの閉じるボタン)を押すと、プログラムが終了する。
While文の中に書いてある、
- 白い背景と赤い円を表示する
- 閉じるボタンが押されたか確認する
- 押されていたらプログラムを終了する
という作業を、1秒間に何十回もループしています。
今後、学習を進めていくと、
- 移動ボタンが押されていたらキャラクターの座標を変更する
- 自機と敵の衝突判定がTrueだったらゲームオーバー画面を表示する
などの処理を追加できるようになります。
まずは、このシンプルなゲームループコードの詳細を見ていきましょう。
コードを分解して詳しく解説
先ほどの ウィンドウに赤い円を表示するコード を詳しく分解し、各部分の役割を細かく解説していきます。
最初なので初めて見る内容ばかりになるでしょうが、ここでしっかりと記憶しておけば後々楽になりますので、頑張りましょう!
(1) 初期化|importとpygame.init()
import pygame, sys # pygameライブラリとsysライブラリをインポート pygame.init() # pygameライブラリのinit関数を呼び出して、Pygameを初期化
- import pygame はライブラリを使用するためのインポート文。これを使ってウィンドウを作成し、図形を描画できる。
- sys はプログラムの終了処理に使用する標準ライブラリ。コンマ「,」で区切ってpygameと一緒にインポートしている。
- pygame.init()関数はPygameのすべての機能を使えるようにするための初期化処理。この1行がないとPygameの機能を使えない。
Python学習のLesson1-6でRandomモジュールをインポートして乱数生成しましたが、それと同じことをしています。
(2) 画面の作成|display.set_mode()関数
screen = pygame.display.set_mode((800,600)) # 幅800px、高さ600pxのウィンドウを作成 # pygameライブラリのdisplayモジュールのset_mode関数を呼び出して、変数screenに代入
- 幅 800px、高さ 600px のウィンドウを作成する。
-
(800, 600)
の部分を変更すれば、好きなサイズのウィンドウを作ることができる。
display.set_mode()関数 は ウィンドウや描画画面を作成するための関数で、pygameプログラムではほぼ必ず最初に呼ばれる関数のひとつです。
ここまでが、最初に紹介したゲームループの基本的な流れの中の「① 初期化(ゲームの準備をする)」に該当します。
(3) ループ作成|whileによる無限ループ
while True:
- 無限ループ を使い、ゲームが動作し続けるようにする。
- ゲームが終了しない限り、このループがずっと実行される。
ここから、ゲームループの基本的な流れの中の「② メインループ(以下の5つの動作を繰り返す)」に入ります。
(4) 背景の塗りつぶし|screen.fill()関数
screen.fill(pygame.Color("WHITE")) # 画面を白色で塗りつぶす # 変数screenを、fill(色)関数を用いて塗りつぶす # pygameライブラリのcolorクラスを使用する
- 画面全体を白色 (
WHITE
) にする。 - メインループの中の最初に実施することで、前のフレームの描画が残ってしまうことを防ぐ。
screen.fill()関数 はこれはSurfaceオブジェクト(画面)全体または一部を指定した色で塗りつぶす関数です。
ゲーム画面をクリアするときや背景色を設定するときに使います。
また、塗りつぶす色はRGB値か pygame.Colorクラス を用いて指定します。
白のRGB値は(255, 255, 255)なので、上記のコードは以下のように書くこともできます。
screen.fill(255, 255, 255)
pygame.Colorクラスを使えば直接色名で指定できるので、初心者の内はこちらがお勧めです。
(5) 図形の描画|draw.ellipse()関数
pygame.draw.ellipse(screen, pygame.Color("RED"), (100, 100, 100, 100)) # pygameライブラリのdrawモジュールのellipse関数(円を描写する関数)を呼び出す
- (100,100) の位置に、幅100px、高さ100pxの赤い円(楕円)を描画 する。
- 座標を変えると、円の位置を変更できる。
draw.ellipse()関数 は画面上に図形を描写するための関数の一種です。
これに関しては、次のチャプターで詳細に学習します。
(6) 画面の更新|display.update()関数
pygame.display.update() # pygameライブラリのdisplayモジュールのupdate関数を呼び出し
- 最新の描画内容を画面に表示する処理。
- これを実行しないと、画面に何も表示されない。
display.update()関数 は画面に描画内容を反映させる関数です。
直前までの処理で作成した画面データを、実際に表示する際に使用します。
(7) ゲームの終了処理|QUITイベント
for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() # pygameライブラリのquit関数を呼出し sys.exit() # sysライブラリのexit関数を呼び出し
pygame.event.get()
:発生したイベント(ユーザーの操作)を取得 する。event.type == pygame.QUIT
:ウィンドウの閉じるボタン(×ボタン)が押されたらゲームを終了する処理。pygame.quit()
:Pygameを終了する処理。sys.exit()
:Pythonプログラムを完全に終了する処理。
こちらはウィンドウの×ボタンが押されたらゲームを終了させるためのコードです。
この部分の詳細は追々学習していきますので、現時点では暗記してしまいましょう。
ゲームループ関数一覧と使い方まとめ
ここでは、ゲームループのコード内で使用した関数を一覧にまとめました。
これらの関数を理解すると、ゲームの仕組みがより明確になります。
(表の中にない関数は次回以降のChapterで詳細の解説があります)
ライブラリ | モジュール | 関数 | 内容 |
---|---|---|---|
pygame | – | init() | Pygameの機能を利用するための初期化を行う |
display | set_mode() | 指定したサイズのウィンドウを作成する | |
update() | 最新の描画内容を画面に反映する | ||
– | Color(“色”) | 指定した色のRGBデータを取得する (正確には関数ではなくコンストラクタ) | |
event | get() | ユーザーの入力やウィンドウ操作などのイベントを取得 | |
– | quit() | Pygameのすべてのモジュールを終了する | |
sys | – | exit() | Pythonのスクリプトを強制終了する |
ゲームプログラムを作成するとき、Pygameの基本的な関数を 自然に使えるようになる ことがとても重要です。
上記の関数は特に、ゲームループ内で頻繁に出てきますので、使いながら覚えていきましょう。
まとめ|ゲームループは基本中の基本
このチャプターでは、ゲーム開発の基本となる 「ゲームループ」 について学びました。
ゲームループはリアルタイムに画面を更新し、ユーザーの操作を受け付けるために必要不可欠な仕組みです。
ここまで学習を進めてきたことで、皆さんは ゲーム開発の第一歩 を踏み出しました!
最初は単純な図形の描画でしたが、これが キャラクターや敵を動かす基盤 になります。
ぜひ次の学習に進んでみてください!お疲れさまでした!
- サイト改善アンケート|ご意見をお聞かせください(1分で終わります)
-
本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、みなさまの「プログラミングを学習する理由」などをアンケート形式でお伺いしています。1分だけ、ご協力いただけますと幸いです。
【pygame】サイト改善アンケート
ゲームループの疑問解消|FAQとよくあるトラブル
初心者がつまずきやすいポイントをFAQとしてまとめ、またよくあるトラブルとその解決法をわかりやすく整理しました。
理解を深めたいときや、ふと疑問に感じたときに役立ててください。
FAQ|ゲームループの基本に関するよくある質問
今回の記事に関する「よくある質問」とその解答について、以下の内容を参考にしてください。
- Q1. ゲームループを使う理由は何ですか?
-
ゲームループは、ゲーム画面の更新やプレイヤーの操作処理など、ゲームを動かし続けるための繰り返し処理を担当します。
毎フレームで描画やイベント処理が必要なため、ゲーム開発では必須の仕組みです。
- Q2. ゲームループ内で処理を分けて書くにはどうすればいいですか?
-
ゲームループでは、入力処理・ゲーム状態の更新・画面描画などをそれぞれ関数やブロックに分けて記述するのが一般的です。
これにより、コードが整理されて読みやすくなり、保守性も向上します。
- Q3. ゲームループの「フレームレート」を調整するにはどうしたら良いですか?
-
フレームレートの調整には、
pygame.time.Clock()
クラスを使い、ループの最後でclock.tick(フレーム数)
を呼び出します。これにより、指定したフレームレートでゲームが動作します。
ゲームループの基本についてよくあるトラブルと解決法
今回の記事に関する「よくあるトラブル」とその原因、解決法について、以下の内容を参考にしてください。
ゲーム画面がすぐに閉じてしまう
- トラブルの原因と対処法を見る
-
トラブルの原因
イベント処理が正しく書かれていない、または「pygame.QUIT」イベントを正しく検知できていない場合によく発生します。
トラブルの解決法
イベントループ内で
for event in pygame.event.get():
と書き、if event.type == pygame.QUIT:
の部分が正しく記述されているか確認してください。特に、インデントやスペルミスがないかも注意して見直しましょう。
ウィンドウが反応しなくなる(強制終了しないと閉じられない)
- トラブルの原因と対処法を見る
-
トラブルの原因
ゲームループ内で
pygame.event.get()
を呼んでいない場合や、ループが止まらなくなる無限ループが原因の場合があります。トラブルの解決法
ループ内でイベント処理(
pygame.event.get()
の記述)が抜けていないか確認してください。また、終了条件となるフラグや
break
文が正しく働いているかもコード全体をチェックしましょう。