Pygame Zero② フレーム処理とクラス
フレーム処理とクラス
ゲーム開発において基本となる フレーム処理 について学習します. フレーム とは,図形,文字列,画像などが表示されているスクリーンのある時刻の状態のことです. パラパラ漫画の要領でフレームが切り替わることで,映像としてゲームが成立しています. フレームの切り替わりの速度は, フレームレート(fps) として表され,一般的なゲームで必要とされる60fpsは,1秒間に60回フレームが切り替わることを意味しています. また,ゲーム開発において,利用すると便利な クラス についても説明します. クラスは,整数や文字列などを記憶するための変数と,複数の処理を実行する関数を,まとめて管理するための仕組みです. クラスを正しく理解するには, オブジェクト指向を学ぶ必要がありますが,本授業では割愛します.
準備
Muエディタを起動したら,Pygame Zero モードを選択しましょう. 保存用のフォルダを「chapter9」という名前で作成し,ソースファイルを「game.py」という名前でフォルダ内に保存します. また,ゲームを表示するためのウィンドウを作成します. ウィンドウの幅は640px,高さは480px,背景色は白色に設定します.
WIDTH = 640
HEIGHT = 480
def draw():
screen.fill("white")
フレーム処理
Pygame Zeroでフレーム処理を実装するには,draw()
とupdate()
を定義します.
1つのフレームにおいて,最初にdraw()
が実行され,その後でupdate()
が実行されます.
draw()
では図形や画像などの 表示,update()
では図形や画像の移動などの 更新 を記述します.
最初にdraw()
において,filled_circle()
とline()
で赤いリンゴを表示します.
リンゴの位置は変数x
とy
を利用して相対的に決まることに注意してください.
x = 320 # X座標
y = 0 # Y座標
speed = 1 # 落下速度
def draw():
screen.fill("white") # screen.fill((255, 255, 255))でもOK
# 赤いリンゴ
screen.draw.filled_circle((x, y), 10, "red")
screen.draw.line((x, y-5), (x, y-15), "black")
次にupdate()
において,Y座標を速度分だけ増やすことで,赤いリンゴを下方向に移動させます.
変数x
,y
,speed
はグローバル変数として宣言します.
def update():
global x, y, speed # グローバル変数
y = y + speed # 落下速度だけ下方向に移動
例題1
任意の位置に青いリンゴを表示させ,下方向に落下させてください.
例題2
リンゴの落下速度を徐々に速くしてください.
クラスとオブジェクト
上記で実装したリンゴには,位置や速度を表す変数と,表示や落下などの動作が必要です.
これらをまとめて表現するには クラス を利用します.
ここでは次のようにAppleクラスを定義します.
Appleクラスには,4つの変数(x
,y
,speed
,color
)と,2つの関数(paint()
,fall()
)を定義しています.
関数の中で変数を参照するには,引数にself
を宣言し,self.x
やself.y
と記述します.
# Appleクラスを定義
class Apple:
x = 320
y = 0
speed = 1
color = "green"
def paint(self):
screen.draw.filled_circle((self.x, self.y), 10, self.color)
screen.draw.line((self.x, self.y-5), (self.x, self.y-15), "black")
def fall(self):
self.y = self.y + self.speed
self.speed = self.speed + 0.05
Appleクラスはデータの型でしかありません.
このAppleクラスを利用できるようにした状態をオブジェクト(インスタンス)と呼びます.
このオブジェクトからクラスで定義した変数・関数を呼び出すことが可能です.
例えば,Appleクラスのオブジェクトapple
から,変数x
を参照するにはapple.x
,関数paint()
を実行するにはapple.paint()
と記述します.
# Appleクラスのオブジェクトを生成
apple = Apple()
print(apple.x) # -> 320
print(apple.y) # -> 0
def draw():
screen.fill("white")
apple.paint() # paint()を実行する
def update():
apple.fall() # fall()を実行する
クラスの変数(x
やy
など)を,オブジェクトを生成するタイミングで設定するには コンストラクタ を利用します.
コンストラクタは特殊な関数であり,__init__()
という名前で定義します.
オブジェクトの生成の際に,引数に設定した変数を渡すことができます.
例えば,Apple(320, 0, 1, "green")
と設定すると,それぞれx=320
,y=0
,speed=1
,color="green"
が代入されます.
クラスを利用すると,簡単に複数のオブジェクトを生成することが可能です.
ここでは,緑のリンゴと,ピンクのリンゴを,Appleクラスを利用して生成しています.
class Apple:
# コンストラクタ(引数で値を設定)
def __init__(self, x, y, speed, color):
self.x = x
self.y = y
self.speed = speed
self.color = color
def paint(self):
screen.draw.filled_circle((self.x, self.y), 10, self.color)
screen.draw.line((self.x, self.y-5), (self.x, self.y-15), "black")
def fall(self):
self.y = self.y + self.speed
self.speed = self.speed + 0.05
# 引数に値を渡す
apple1 = Apple(320, 0, 1, "green") # 緑色のリンゴ
apple2 = Apple(480, 0, 1, "pink") # ピンク色のリンゴ
def draw():
screen.fill("white")
apple1.paint()
apple2.paint()
def update():
apple1.fall()
apple2.fall()
リストでオブジェクトを管理
リストを利用することで,多くのオブジェクトを管理することができます.
ここでは,for文を利用して,Appleクラスのオブジェクトを100個生成し,リストapple_list
に格納しています.
このときオブジェクトのX座標はランダムに設定しています.
リストapple_list
の要素を,for文で取り出し,paint()
とfall()
を呼び出しています.
この結果,100個のリンゴが同時に落下します.
from random import *
# リストを初期化
apple_list = []
for i in range(100):
x = randint(0, 640) # ランダムにX座標を設定
apple = Apple(x, 0, 1, "red")
apple_list.append(apple) # リストに追加
def draw():
screen.fill("white")
for apple in apple_list:
apple.paint()
def update():
for apple in apple_list:
apple.fall()
リンゴが落下するタイミングをずらすため,Appleクラスにvisible
という変数を新たに追加し,visible
がTrue
のときだけ,リンゴを表示・落下させることにします.
draw()
の中で,乱数を利用して1/1000の確率でvisible
をTrue
に設定することで,一部のリンゴだけが表示・落下することになります.
class Apple:
def __init__(self, x, y, speed, color):
self.x = x
self.y = y
self.speed = speed
self.color = color
self.visible = False # 変数を追加
def paint(self):
if self.visible:
screen.draw.filled_circle((self.x, self.y), 10, self.color)
screen.draw.line((self.x, self.y-5), (self.x, self.y-15), "black")
def fall(self):
if self.visible:
self.y = self.y + self.speed
self.speed = self.speed + 0.05
apple_list = []
for i in range(100):
x = randint(0, 640)
apple = Apple(x, 0, 1, "red")
apple_list.append(apple)
def draw():
screen.fill("white")
for apple in apple_list:
# 1/1000の確率でvisible=Trueに設定
if random() < 0.001:
apple.visible = True
apple.paint()
def update():
for apple in apple_list:
apple.fall()
課題
次の課題に取組んでください.
- 次の動画を参考にリンゴをランダムに3色(赤,青,緑)に塗り分けてください
- 色に応じてリンゴの大きさを変更してください(赤:小,青:中,緑:大)
課題を完成させたらスクリプトを保存し,chapter9フォルダをZIPで圧縮してから,chapter9.zipという名前でファイルを提出してください.