Pygameでキャラクターを動かそう
今回は3つのパターンの画像を使って、キャラクターが動くようにみえるプログラムを作ります。
以下の画像を使用していますが、プログラムの中で利用するのは、1段目の正面を向いている3つの画像です。
なお、この画像ファイルは、以下のサイトよりダウンロードしています。
参考
Pythonスクリプト
今回のスクリプトは、以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
### インポート import sys import pygame from pygame.locals import * ### 定数 WIDTH = 200 # 画面横サイズ HEIGHT = 200 # 画面縦サイズ C_SIZE = 32 # キャラクターサイズ F_POSE = 20 # ポーズフレーム F_RATE = 60 # フレームレート ### 画面定義(X軸,Y軸,横,縦) SURFACE = Rect(0, 0, WIDTH, HEIGHT) ############################ ### キャラクタークラス ############################ class Character(pygame.sprite.Sprite): ### クラス変数 frame = 0 # フレーム flag = 0 # 切り替えフラグ images = [] # 画像リスト ############################ ### 初期化メソッド ############################ def __init__(self, name, x, y): pygame.sprite.Sprite.__init__(self) ### ファイル読み込み all_image = pygame.image.load(name).convert_alpha() ### キャラクターパターン格納 for i in range(0, all_image.get_width(), C_SIZE): c_pattern = pygame.Surface((C_SIZE, C_SIZE)) c_pattern.blit(all_image, (0,0), (i,0,C_SIZE,C_SIZE)) self.images.append(c_pattern) ### キャラクター初期設定 self.image = self.images[0] self.rect = self.image.get_rect(center=(x,y)) ############################ ### キャラクター更新 ############################ def update(self): ### 画像切り替え self.image = self.images[int(self.frame / F_POSE)] if self.flag == 0: self.frame += 1 else: self.frame -= 1 ### 繰り返し(images[0]→[1]→[2]→[1]→[0]→[1]...) if self.frame >= len(self.images) * F_POSE: self.frame = F_POSE * 2 - 1 self.flag = 1 elif self.frame < 0: self.frame = F_POSE self.flag = 0 ############################ ### キャラクター描画 ############################ def draw(self, surface): surface.blit(self.image, self.rect) ############################ ### メイン関数 ############################ def main(): ### 画面初期化 pygame.init() surface = pygame.display.set_mode(SURFACE.size) ### キャラクター作成 char = Character("pipo-charachip030b.png", int(WIDTH/2), int(HEIGHT/2)) ### 時間オブジェクト生成 clock = pygame.time.Clock() ### 無限ループ while True: ### フレームレート設定 clock.tick(F_RATE) ### 背景色設定 surface.fill((0,0,0)) ### スプライト更新 char.update() ### スプライト描画 char.draw(surface) ### 画面更新 pygame.display.update() ### 終了処理 for event in pygame.event.get(): if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): pygame.quit() sys.exit() ############################ ### メイン関数呼び出し ############################ if __name__ == "__main__": ### 処理開始 main() |
スクリプト解説
9行目
表示するキャラクターの一辺のサイズです。
今回使用した画像の1キャラ分のサイズが32ドットなので、32に設定しています。
10行目
何フレームごとに画像を切り替えるかの値です。
今回は60フレーム中20フレームごとに画像を切り替えています。
60フレームは1秒間に60コマ描画するので、20フレームの場合は約1/3秒ごとに画像が切り替わることになります。
19~70行目
PygameのSpriteクラスを継承したキャラクタークラスです。
画像ファイルを読み込んで、画面にキャラクターを描画するクラスです。
33行目
画像ファイル全体を読み込みます。
36~39行目
キャラクター画像の1段目を1キャラ分(32ドット)ずつリストに格納します。
51行目
リストに格納された画像の中から、描画する画像を描画領域にコピーします。
self.frame変数は0~59の範囲の値を取ります。
20フレーム間隔で画像を切り替えたいので、self.frame変数を20で割ると、self.frame変数が0~19の時はリスト[0]、20~39の時はリスト[1]、40~59の時はリスト[2]に格納されている画像が取得できます。
リストの番号をint型で指定しているので、小数は切り捨てられます。
59~64行目
キャラクターを滑らかに動かしたいので、画像の描画順をリストの0→1→2→1→0→1→2→1... としています。
82行目
キャラクターを画面の中央に描画したいので、画面の縦横のそれぞれ半分の値をキャラクタークラスに渡しています。