この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)
「src/mymod/image/chara.py」の説明です。
このモジュールで作るChara
クラスは、pygame.sprite.Sprite
を継承します。Chara
クラスは、キャラクターを描画するためのスプライトです。
このクラスには、コンストラクター__init__()
とupdate()
以外に、次のようなメソッドを作ります。
Charaクラスのメソッド
メソッド | 説明 |
---|---|
set_pos(x, y) |
位置をx y に移動。 |
shake(size) |
size の範囲で画像を揺らす。 |
end_shake() |
揺らすのをやめて初期位置に戻す。 |
set_size(rate) |
比率rate で拡大縮小する。 |
キャラクターの画像は、次の用途で利用します。
import pygamefrom ..data.app import U, IMAGE_CHARAfrom .util import load_chip
imgs: list[pygame.Surface] = []
# キャラクターclass Chara(pygame.sprite.Sprite): # 初期化 def __init__(self, img_nums: list[int]): super().__init__() global imgs if len(imgs) == 0: imgs = load_chip(IMAGE_CHARA, True) # 画像読み込み self.images = list(map(lambda n: imgs[n], img_nums)) # 抜粋 self.image = self.images[0] self.rect = pygame.Rect(0, 0, U, U) self.is_shake = False self.base_x = 0 self.base_y = 0
# 位置 def set_pos(self, x: int, y: int): self.base_x = self.rect.x = x self.base_y = self.rect.y = y
# サイズ def set_size(self, rate: int): self.rect.width = int(U * rate) self.rect.height = int(U * rate)
# 揺らす def shake(self, is_shake: bool): self.is_shake = is_shake
# 更新 def update(self): t = pygame.time.get_ticks() # 経過時間 i = t // 500 % len(self.images) image = self.images[i] size = (self.rect.width, self.rect.height) self.image = pygame.transform.scale(image, size)
self.rect.x = self.base_x self.rect.y = self.base_y if self.is_shake: t2 = t // 40 self.rect.x += - U // 2 + int(U * (t2 * 11 % 13 / 13)) self.rect.y += - U // 2 + int(U * (t2 * 11 % 17 / 17))
まずは、インポート部分を示します。
import pygamefrom ..data.app import U, IMAGE_CHARAfrom .util import load_chip
data.app
から、描画単位U
と、キャラクター画像のパスIMAGE_CHARA
を読み込みます。
画像を分割して読み込むので、util
のload_chip
を読み込みます。
読み込んだ画像を保持する変数imgs
です。
imgs: list[pygame.Surface] = []
キャラクターの画像は最初に1度だけ読み込んで分割して、この変数imgs
に代入します。
クラスの作成からコンストラクターまでを示します。
# キャラクターclass Chara(pygame.sprite.Sprite): # 初期化 def __init__(self, img_nums: list[int]): super().__init__() global imgs if len(imgs) == 0: imgs = load_chip(IMAGE_CHARA, True) # 画像読み込み self.images = list(map(lambda n: imgs[n], img_nums)) # 抜粋 self.image = self.images[0] self.rect = pygame.Rect(0, 0, U, U) self.is_shake = False self.base_x = 0 self.base_y = 0
コンストラクターではまず、親クラスSprite
の__init__()
関数を実行します。
続いて、global imgs
で、関数外の変数imgs
に値を設定可能にします。そして変数imgs
の要素数が0
なら、画像を読み込んで分割して、変数imgs
に代入します。
この変数imgs
の画像から、img_nums
の参照位置の画像を抜き出して、キャラクターで使う画像のリストを作り、self.images
に代入します。
次に、コンストラクター内で重要なのはself.image
とself.rect
です。これらの値は、Sprite
クラスの処理で利用されます。
self.is_shake
は、画像を揺らしているかのフラグです。
self.base_x
self.base_y
の値は、画像を揺らしたあと、元の位置に戻すのに使います。
位置を設定するset_pos()
関数です。
# 位置 def set_pos(self, x: int, y: int): self.base_x = self.rect.x = x self.base_y = self.rect.y = y
self.rect.x
self.rect.y
の値と、self.base_x
self.base_y
の値を変更します。
サイズを変えるset_size()
関数です。
# サイズ def set_size(self, rate: int): self.rect.width = int(U * rate) self.rect.height = int(U * rate)
ここでは数値のみ変えて、実際の拡大縮小はupdate()
関数の中でおこないます。
shake()
関数にbool値を与えることで、揺らす状態を変えます。
# 揺らす def shake(self, is_shake: bool): self.is_shake = is_shake
更新をおこなうupdate()
関数です。
# 更新 def update(self): t = pygame.time.get_ticks() # 経過時間 i = t // 500 % len(self.images) image = self.images[i] size = (self.rect.width, self.rect.height) self.image = pygame.transform.scale(image, size)
self.rect.x = self.base_x self.rect.y = self.base_y if self.is_shake: t2 = t // 40 self.rect.x += - U // 2 + int(U * (t2 * 11 % 13 / 13)) self.rect.y += - U // 2 + int(U * (t2 * 11 % 17 / 17))
経過時間に応じて、取り出す画像を変えてアニメーションをおこないます。500
ミリ秒ごとに、画像を切り替えます。
また、self.images
から取り出した画像をpygame.transform.scale()
関数でサイズを変えて、self.image
に代入します。
描画位置は、いったんself.base_x
self.base_y
に設定します。
その後、self.is_shake
がTrue
のときは、描画位置をガタガタと揺らします。
次の内容については省略します。こちらは同人誌をご覧ください。
この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)