人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

パドルの移動

これから数回にわたってブロック崩しを作ろうと思います。今回は、ボールを跳ね返すラケット(パドル)をマウスで動かせるところまで作ります。ブロック崩しの素材は、FLYING YOGI(リンク切れ)さんからお借りしています。

breakout01.zip
f:id:aidiary:20100807230706p:plain

パドルスプライト

まずパドルを表すPaddleクラスから見ていきます。PaddleはSpriteクラスを継承しているのでスプライトになります。スプライトの説明は、スプライトの使い方(2008/5/17)とスプライトグループの使い方(2008/5/17)を見てください。

class Paddle(pygame.sprite.Sprite):
    """ボールを打つパドル"""
    def __init__(self):
        # containersはmain()でセットされる
        pygame.sprite.Sprite.__init__(self, self.containers)
        self.image, self.rect = load_image("paddle.png")
        self.rect.bottom = SCR_RECT.bottom  # パドルは画面の一番下
    def update(self):
        self.rect.centerx = pygame.mouse.get_pos()[0]  # パドルの中央のX座標=マウスのX座標
        self.rect.clamp_ip(SCR_RECT)  # SCR_RECT内でしか移動できなくなる

Paddleのコンストラクタを見るとわかるようにデフォルトスプライトグループを利用しています。containersがPaddleのデフォルトスプライトグループです。containersは下のコードのようにmain()で外部から登録しています。ちょっと違和感がありますが、この方法はPygameの定石らしいです。

    # スプライトグループを作成して登録
    all = pygame.sprite.RenderUpdates()
    Paddle.containers = all

デフォルトスプライトグループを登録しておくとPaddleオブジェクトを作成すると同時にallグループに追加されます。update()では、Paddleの中心のX座標(self.rect.centerx)をマウスの座標に合わせています。こうするとパドルがマウスに合わせて移動します。マウス座標の取得方法は、マウスイベント(2008/5/6)で解説したようにpygame.mouse.get_pos()を使います。今回は、X座標しか使わない(Y座標は画面の一番下で固定)ので[0]だけ調べています。またパドルが画面の外に出ては困るのでclamp_ip()を使って画面内(SCR_RECT)からはみ出さないようにしています。コメントアウトしてみるとどういう役割かよくわかると思います。

パドルの更新と描画

パドルの作成、更新、描画はすべてmain()です。

def main():
    pygame.init()
    screen = pygame.display.set_mode(SCR_RECT.size)
    pygame.display.set_caption(u"Breakout 01 パドルを動かす")
    
    # スプライトグループを作成して登録
    all = pygame.sprite.RenderUpdates()
    Paddle.containers = all
    # パドルを作成
    paddle = Paddle()
    
    clock = pygame.time.Clock()
    while True:
        clock.tick(60)
        screen.fill((0,0,0))
        all.update()
        all.draw(screen)
        pygame.display.update()
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN and event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()

Paddle()でパドルオブジェクトを作成すると同時にスプライトグループallに追加されます。スプライトの更新と描画はグループ単位で行うのでallに対してupdate()とdraw()を実行します。今はスプライトはPaddleが1つしかないのでスプライトグループのありがたみが実感できませんが、スプライトが増えてくるとスプライトをまとめて描画、更新できるスプライトグループの便利さが実感できてきます。 RenderUpdates()というスプライトグループは主に描画用に使います。あとで衝突検出用に他のスプライトグループも使っていく予定です。