スプライトの使い方

スプライトとは、背景と別に描画される画像のことです。

スプライトの使い方

Pygameでは、Spriteモジュールを使うことでオブジェクトをまとめて管理することができます。

Spriteとは背景と別に描画される画像のことで、プレイヤーや敵キャラクター、発射したミサイルなどがSpriteにあたります。

Spriteオブジェクトはグループに追加することで、更新の管理だけでなく当たり判定などにも使うことができ、ゲームを作るうえで必須のテクニックです。

スプライトの作り方

スプライトを作成するには、PygameのSpriteクラスを継承して作ります。

さっそく、これまで画像を背景にぺたんと貼っていたラビップルをスプライトにしてみましょう。

import pygame
from pygame.locals import *

import tools

class Player(pygame.sprite.Sprite):
    speed = 5
    frame = 0
    animecycle = 24

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.images = tools.split_image(tools.load_image("data", "rabipple.png"), 2, 2)
        self.image = self.images[0]
        # 画像のRect値を取得
        self.rect = self.image.get_rect()
        self.rect.center = (288, 200)
        self.direction = 0

    def update(self):
        self.frame += 1
        self.image = self.images[(self.direction * 2) + int(self.frame / self.animecycle % 2)]
        pressed_keys = pygame.key.get_pressed()
        if pressed_keys[K_LEFT]:
            self.frame += 1
            self.direction = 0
            self.rect.move_ip(-self.speed, 0)
        if pressed_keys[K_RIGHT]:
            self.frame += 1
            self.direction = 1
            self.rect.move_ip(self.speed, 0)
        if pressed_keys[K_UP]:
            self.frame += 1
            self.rect.move_ip(0, -self.speed)
        if pressed_keys[K_DOWN]:
            self.frame += 1
            self.rect.move_ip(0, self.speed)
        # 画面の外に出ないようにする
        self.rect.clamp_ip(Rect(0, 0, 640, 480))

    def draw(self, screen):
        screen.blit(self.image, self.rect)

新たにSpriteクラスを継承したPlayerクラスを作成します。

これまでMainクラスに書いていたキー操作やアニメーションなどの処理はこちらに移しておきます。

Rect値というのは、画像の描画範囲を四角形で取得したものです。

これまではx座標やy座標の値を変更して画像を動かしていましたが、Rect値を取得しmove_ip()で直接画像を動かすようにしました。

clamp_ip()を使うことで、画面の外に出てしまわないような処理も追加しています。

作成したスプライトはMainクラス内で、インスタンス化しておきましょう。

#!/usr/bin/env python
import pygame
from pygame.locals import *
import sys

import cursor, tools, player

SCR_RECT = Rect(0, 0, 640, 480)

class Main():
    def __init__(self):
        pygame.init()
        pygame.display.set_caption("sample")
        screen = pygame.display.set_mode(SCR_RECT.size)

        # プレイヤーをインスタンス化
        self.player = player.Player()

        self.bg = tools.load_image("data", "bg.png")

        clock = pygame.time.Clock()
        while True:
            clock.tick(30)
            self.update()
            self.draw(screen)
            pygame.display.update()
            self.key_handler()

    def update(self):
        self.player.update()

    def draw(self, screen):
        screen.blit(self.bg, (0, 0))
        self.player.draw(screen)

    def key_handler(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

if __name__ == "__main__":
    Main()

このままでは敵キャラなどSpriteが増えれば、結局その分だけ処理を記述する必要がありますよね。

次回は、スプライトグループを利用してまとめて更新・描画を行ってみます。

(本当は一回で全部やるつもりでしたが、思ったより分量が増えてしまったので分割します…)