4-5 Pygameのスプライト
同人誌について
この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで288ページの本になります。ぜひ、こちらもご購入ください(2024-03-10:ver1.0.3 に更新)。
スプライトとは
『Pygame』ではスプライトを利用できます。スプライトは、ゲーム開発でよく出てくる、複数の小さな画像を高速に描画するための仕組みです。
『Pygame』のスプライトでは、複数のスプライトをグループ化して、一括して描画することができます。
Spriteを継承したクラス
スプライトの例「example_pygame/sprite.py」を示します。
import pygame
# キャラクター
class Chara(pygame.sprite.Sprite):
# 初期化
def __init__(self, images: list[pygame.Surface]):
pygame.sprite.Sprite.__init__(self)
self.images = images
self.image = images[0]
self.rect = self.image.get_rect()
# 更新
def update(self):
time = pygame.time.get_ticks() # 経過時間
i = time // 500 % 2 # 0, 1
self.image = self.images[i]
def main():
pygame.init() # Pygameを初期化
screen = pygame.display.set_mode((800, 600)) # 画面作成
running = True # 実行継続フラグ
# スプライト グループの準備と画像の読み込み
sprite_all = pygame.sprite.RenderUpdates() # 描画更新用
image0 = pygame.image.load("image/chara0.png") # 画像読み込み
image1 = pygame.image.load("image/chara1.png") # 画像読み込み
# スプライトの作成と準備
for y in range(8):
for x in range(10):
chara = Chara([image0, image1])
chara.add(sprite_all)
chara.rect.x = x * (64 + 16)
chara.rect.y = y * (64 + 10)
while running:
pygame.display.update() # 画面を更新
screen.fill(pygame.Color(0, 0, 0)) # 画面を塗りつぶす
for event in pygame.event.get(): # イベント
if event.type == pygame.QUIT: running = False # 終了
sprite_all.update() # スプライト更新
sprite_all.draw(screen) # スプライト描画
pygame.display.flip() # 画面フリップ
pygame.quit()
if __name__ == "__main__":
main()
実行した画面です。
まずは、`pygame.sprite.Sprite`を継承した`Chara`クラスを作ります。`Chara`クラスには、コンストラクター`__init__`と、スプライトの処理で必要な`update()`メソッドを書きます。
import pygame
# キャラクター
class Chara(pygame.sprite.Sprite):
# 初期化
def __init__(self, images: list[pygame.Surface]):
pygame.sprite.Sprite.__init__(self)
self.images = images
self.image = images[0]
self.rect = self.image.get_rect()
# 更新
def update(self):
elapse = pygame.time.get_ticks() # 経過時間
i = elapse // 500 % 2 # 0, 1
self.image = self.images[i]
スプライトには、次のメソッドがあります。
スプライトのメソッド
Spriteの利用
次に、`Chara`クラスを利用して、複数のスプライト描画を一括でおこないます。
まずは、スプライト グループの準備と画像の読み込みです。
def main():
pygame.init() # Pygameを初期化
screen = pygame.display.set_mode((800, 600)) # 画面作成
running = True # 実行継続フラグ
# スプライト グループの準備と画像の読み込み
sprite_all = pygame.sprite.RenderUpdates() # 描画更新用
image0 = pygame.image.load("image/chara0.png") # 画像読み込み
image1 = pygame.image.load("image/chara1.png") # 画像読み込み
`pygame.sprite.RenderUpdates()`で、描画一括更新用のスプライト グループを作成します。そして変数`sprite_all`に代入します。また、画像を読み込みます。
次は、スプライトの作成と準備です。
# スプライトの作成と準備
for y in range(8):
for x in range(10):
chara = Chara([image0, image1])
chara.add(sprite_all)
chara.rect.x = x * (64 + 16)
chara.rect.y = y * (64 + 10)
y方向8個、x方向10個、合計80個のスプライトを作ります。スプライトは`Chara()`で作り、変数`chara`に代入します。この`Chara`クラスは、`Sprite`を継承しています。
スプライト`chara`の`add()`メソッドを使い、スプライト グループ`sprite_all`を登録します。また`rect.x` `rect.y`に、描画位置を設定します。
次は、スプライトの一括更新と描画です。
while running:
pygame.display.update() # 画面を更新
screen.fill(pygame.Color(0, 0, 0)) # 画面を塗りつぶす
for event in pygame.event.get(): # イベント
if event.type == pygame.QUIT: running = False # 終了
sprite_all.update() # スプライト更新
sprite_all.draw(screen) # スプライト描画
pygame.display.flip() # 画面フリップ
pygame.quit()
`sprite_all.update()`を実行することで、`sprite_all`が登録されたスプライトが一括更新されます。また、`sprite_all.draw()`を実行することで、一括描画がおこなわれます。
画像を1枚ずつ更新したり描画したりしないので、メインループがすっきりします。キャラクターの描画やマップの描画には、このスプライトの仕組みが便利です。
スプライトには多くの派生クラスがあります。必要に応じて、それらを使うことになります。複雑なことをしないのならば、基本の`Sprite`と`RenderUpdates`を使えば十分です。
また、`pygame.sprite`にはアクションゲーム用の衝突判定の関数もあります。四角形や円を基準とした衝突検出ができます。今回は、衝突判定は使わないので割愛します。
同人誌について
この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで288ページの本になります。ぜひ、こちらもご購入ください(2024-03-10:ver1.0.3 に更新)。
このnoteの記事と、Webページに一部抜粋版を掲載しています。
技術系同人誌など まとめページ
この記事が気に入ったらサポートをしてみませんか?