【pygame】チャプター1-5:画像を動かそう|アニメーションの第一歩

一つ前のページでは画面に文字を表示する方法について学習しました。
今回は 画面上の画像を動かす方法 について見ていきましょう。
Chapter1:pygame入門|画面を表示しよう
・Chapter1-1:pygameを導入しよう
・Chapter1-2:ゲームループの基本を理解しよう
・Chapter1-3:画面に画像を表示しよう
・Chapter1-4:画面に文字を表示しよう
・Chapter1-5:画面上の画像を動かそう ◁今回はここ
Chapter2:簡単なノベルゲームを作ろう
Chapter3:簡単なアクションゲームを作ろう
Chapter4:ブロック崩しを作ろう
Chapter5:シューティングゲームを作ろう
Extra1:横スクロールのアクションゲームを作ろう
ゲーム開発において、キャラクターやオブジェクトを動かすことは非常に重要な要素の一つです。
プレイヤーが操作するキャラクターを動かしたり、敵キャラクターが動き回ったりすることで、ゲームはダイナミックになり、より楽しいものになります。
今回は Pygameを使って画面上の画像を動かす方法 を学んでいきます。
本記事を学ぶことで、次のようなスキルを身につけることができます。
- 画像(オブジェクト)の位置を管理する方法
pygame.Rect
を利用した座標の変更- 一定の速度でスムーズに移動させるためのフレームレート制御
これらの基礎を身につければ、キャラクターを動かすアクションゲームや、障害物が移動するゲームなど、さまざまな応用が可能になります。
それでは、実際に画像を動かす方法について学んでいきましょう!
Rectで位置とサイズを管理|座標更新で画像を動かす
Pygameで画面上の画像を動かすには、オブジェクトの位置情報を管理する必要があります。
そのために、Pygameでは pygame.Rect()
というクラスを使用します。
Rect
は矩形(四角形)の位置とサイズを保持するデータ構造であり、これを利用すると簡単にオブジェクトの位置を変更することができます。
Rectの基本|位置(x,y)とサイズ(w,h)生成
Pygameの Rect
クラスは、次の4つの情報を管理するために使われます。
- X座標(図形の左上の横位置)
- Y座標(図形の左上の縦位置)
- Width(図形の幅)
- Height(図形の高さ)
Rect
オブジェクトは、次のように作成できます。
import pygame # Rect(開始X座標, 開始Y座標, 幅, 高さ) myrect = pygame.Rect(100, 100, 100, 100) # Rectクラスに4つの引数を渡してインスタンス生成
このコードでは、myrect
という名前の四角形を (100, 100) の位置に作成し、幅100ピクセル、高さ100ピクセルのサイズに設定しています。
座標を変更して画像を動かす方法
Pygameでは、画面の座標は 左上が (0, 0) で、右に進むほど X座標が増加 し、下に進むほど Y座標が増加 します。
(0,0) →→→→→ (+X方向) ↓ ↓ ↓ (+Y方向)
つまり、オブジェクトを右に動かしたい場合は X座標
を増やし、上に動かしたい場合は Y座標
を減らします。
Pygameの Rect
オブジェクトは、x
や y
の値を直接変更することで移動できます。
# 右に1ピクセル移動 myrect.x += 1 # marectのx座標に1を足す # 下に1ピクセル移動 myrect.y += 1 # marectのy座標に1を足す
このように、x
または y
の値を増減することで、オブジェクトを移動させることができます。
Rectの可視化|pygame.draw.rect()の使い方
Chapter1-3で学習したように、Pygameの draw.rect()
関数を使ってRect
オブジェクトを画面に描画できます。
pygame.draw.rect(画面, 色, (X, Y, 幅, 高さ))
この中の (X, Y, 幅, 高さ) の部分を、先ほど定義したmyrectに置き換えましょう。
pygame.draw.rect(screen, pygame.Color("GREEN"), myrect)
このコードでは、緑色の四角形を myrect
の位置に描画します。
フレーム制御と座標更新|アニメーションの基礎
前章ではPygameの Rect
オブジェクトを使用して、画面上のオブジェクトの位置を管理する方法を学びました。
本章ではその Rect
を実際に移動させ、スムーズな動きを実現する方法について学びます。
ゲームループ内で座標変更|オブジェクトを動かそう
ゲームでは、オブジェクトの移動は メインループ(ゲームループ) 内で行われます。
例えば、次のようなコードで、四角形を右方向に動かすことができます。
while True: # メインループ screen.fill(pygame.Color("BLACK")) # 画面を黒く塗りつぶす myrect.x += 1 # 右に移動 pygame.draw.rect(screen, pygame.Color("GREEN"), myrect) # 四角形を描画 pygame.display.update() # 画面更新
このコードでは、myrect.x += 1
によって Rect
の x
座標が毎フレーム1ピクセルずつ増加します。
そのためメインループが終了しない限り、四角形は右に移動していきます。
FPS(フレームレート)制御の仕組み|.tick()関数の使い方
このままでは、コンピュータの性能によってオブジェクトの移動速度が異なってしまいます。
そこでPygameの pygame.time.Clock()
クラス を使用して、ゲームのフレームレートを一定に保つ 必要があります。
フレームレートとは、1秒間に何回画面を更新するか(Whileループを何回繰り返すか)を示す値で、「FPS(Frames Per Second)」と呼ばれます。
一般的なゲームでは 60FPS(1秒間に60回更新)が標準的な設定です。
今回は .tick(60)
と書いて、フレームレートを60FPSに固定できます。
# フレームレートを管理するためのClockオブジェクトを作成(インスタンス生成) clock = pygame.time.Clock() # フレームレートを60FPSに固定 clock.tick(60)
ゲームの更新速度が1秒間に60回に固定され、オブジェクトの移動速度が一定になります。
実践コード|画像を動かす最小テンプレート
ここまで学習した知識を活かして、実際にオブジェクトを動かしてみましょう。
以下のコードは、画面上の四角形が右に動き続ける Pygameのプログラムです。
#1.初期化(ゲームの準備をする) import pygame, sys pygame.init() screen = pygame.display.set_mode((800, 600)) # 四角形の作成(初期位置 (100, 100)、幅100、高さ100)200200 myrect = pygame.Rect(100, 100, 100, 100) # フレームレート制御用のClockオブジェクト clock = pygame.time.Clock() # メインループ while True: screen.fill(pygame.Color("BLACK")) # 画面を黒でクリア myrect.x += 1 # 四角形を右に移動 pygame.draw.rect(screen, pygame.Color("GREEN"), myrect) # 四角形を描画(緑色) pygame.display.update() # 画面の更新 clock.tick(60) # 60FPSに設定(フレームレート制御) # 終了判定(ゲームを終了するかどうかを判定) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()
コードの詳細解説
このコードの重要な部分について詳しく説明していきます。
移動する四角形(オブジェクト)の作成
# 四角形の作成(初期位置 (100, 100)、幅100、高さ100) myrect = pygame.Rect(100, 100, 100, 100)
pygame.Rect(x, y, 幅, 高さ)
を使って、(100,100) の位置に 100×100 ピクセルの四角形を作成します。
フレームレート制御
# フレームレート制御用のClockオブジェクト clock = pygame.time.Clock()
pygame.time.Clock()
を使って、フレームレートを管理するオブジェクトを作成します。
オブジェクトの移動
# 四角形を右に移動 myrect.x += 1
毎フレーム、myrect.x
の値を 1
増やすことで、四角形が右に移動します。
オブジェクトの描画
# 四角形を描画(緑色) pygame.draw.rect(screen, pygame.Color("GREEN"), myrect)
pygame.draw.rect()
を使って、四角形を myrect
の位置に緑色で描画します。
フレームレートの設定
# 60FPSに設定(フレームレート制御) clock.tick(60)
clock.tick(60)
を使って、1秒間に60回(60FPS)のペースでゲームを更新します。
練習問題:任意の画像を動かしてみよう
ただの四角形が動くだけでは面白くありません。キャラクターの画像を用意し、それを画面上で動かしてみましょう。
画像は↓↓の勉強猫を保存して使用してください。
Chapter1-3で学習した内容を思い出し、「1.初期化(ゲームの準備をする)」の部分で画損を読み込んで100×100程度の大きさにしておき、myrectで最初の位置を大きさを指定します。
動きは右下から右上に行くなど、先ほどとは違った方向やスピードに設定しましょう。
まとめ|最小実装から一歩ずつアニメーションへ
5つのチャプターを通して、ようやく画面が動きました。
これがPygameを使ったゲーム開発の第一歩です。
「ゲーム開発は難しそう」と感じるかもしれませんが、基本を一つずつ理解しながら進めていけば、必ず面白いゲームを作れるようになります。
ぜひこの知識を活かして、自分なりの動くオブジェクトを作成してみてください。
これからもPygameを使って、どんどん楽しいゲームを作っていきましょう!
- サイト改善アンケート|ご意見をお聞かせください(1分で終わります)
-
本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、みなさまの「プログラミングを学習する理由」などをアンケート形式でお伺いしています。1分だけ、ご協力いただけますと幸いです。
【pygame】サイト改善アンケート
アニメーション入門の疑問解消|FAQとよくあるトラブル
初心者がつまずきやすいポイントをFAQとしてまとめ、またよくあるトラブルとその解決法をわかりやすく整理しました。
理解を深めたいときや、ふと疑問に感じたときに役立ててください。
FAQ|画像を動かす方法に関するよくある質問
今回の記事に関する「よくある質問」とその解答について、以下の内容を参考にしてください。
- Q1. pygame.Rectクラスを使う理由は何ですか?
-
pygame.Rect
クラスは、画像やオブジェクトの位置やサイズを簡単に管理できるため、移動や当たり判定などゲーム開発で頻繁に利用されます。座標やサイズの更新も直感的に行えるため、コードがシンプルになりやすいです。
- Q2. フレームレートを制御する方法はどうすればいいですか?
-
フレームレートの制御には
pygame.time.Clock()
クラスを使い、ループ内でclock.tick(フレーム数)
と記述します。これにより描画の滑らかさを一定に保つことができ、動きが速くなりすぎたりバラバラになったりするのを防げます。
- Q3. 複数の画像を同時に動かしたい場合はどうすればいいですか?
-
各画像ごとに
pygame.Rect
オブジェクトを作成し、ループ内で個別に座標を更新します。リストや辞書などを使ってまとめて管理する方法もおすすめです。
これにより複数オブジェクトの一括処理が可能になります。
画像を動かす方法についてよくあるトラブルと解決法
今回の記事に関する「よくあるトラブル」とその原因、解決法について、以下の内容を参考にしてください。
画像が動かない
- トラブルの原因と対処法を見る
-
トラブルの原因
画像の座標を更新する処理が正しく書かれていない、もしくは座標の更新がループ外に記述されている。
トラブルの解決法
画像の位置を変更している処理がゲームループ(while文など)の中にあるか確認しましょう。
ループの外で一度だけ座標を更新しても、画面には動きが反映されません。
コード全体を見直して、座標の変更処理がループごとに毎回実行されているか確認してください。
画像が画面の外に消えてしまう
- トラブルの原因と対処法を見る
-
トラブルの原因
移動処理の際に、画像の座標が画面サイズの範囲を超えてしまっている。
トラブルの解決法
移動後の画像の座標が「0以上、画面の幅未満」や「0以上、画面の高さ未満」になるように条件分岐を入れて制御しているか確認しましょう。
特にpygame.Rectの値が負や画面サイズを超えないよう、if文やmin/max関数などを使って確認してください。
移動速度が異常に速くなったり遅くなったりする
- トラブルの原因と対処法を見る
-
トラブルの原因
フレームレート(FPS)制御が正しくできていない、または
clock.tick()
の値が適切でない。トラブルの解決法
ゲームループ内でpygame.time.Clock()の
clock.tick(数値)
を正しく呼んでいるか確認しましょう。また、tickに指定する値(例えば60など)が適切か見直してください。
複数回呼び出していないか、呼び出し位置がループ外になっていないかも確認してみてください。