この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)
『Pygame』ではスプライトを利用できます。スプライトは、ゲーム開発でよく出てくる、複数の小さな画像を高速に描画するための仕組みです。
『Pygame』のスプライトでは、複数のスプライトをグループ化して、一括して描画できます。
スプライトの例「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]
スプライトには、次のメソッドがあります。
スプライトのメソッド
メソッド | 説明 |
---|---|
update() |
更新処理。オーバーライド用。 |
add(groups) |
スプライトをグループに追加。 |
remove(groups) |
スプライトをグループから削除。 |
kill() |
スプライトを全てのグループから削除。 |
alive() |
真偽値を返す。いずれかのグループに属しているか。 |
groups() |
所属しているグループのリストを返す。 |
次に、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で290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)