人工知能に関する断創録

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

爆発エフェクト

ミサイルがエイリアンに当たったときに爆発エフェクトが出るようにします。爆発エフェクトもスプライトとして実装するのでエイリアンやミサイルと作り方はほとんど同じです。

invader06.zip
f:id:aidiary:20100807235532p:plain

爆発アニメーション

f:id:aidiary:20100808000024p:plain

爆発には上の画像を使います。キャラクターアニメーション(2008/5/18)でも書きましたが、アニメーションは次々に画像を切り替えることで動いているように見せかけています。爆発が起きたときに上の画像を左から右へ次々切り替えることで爆発しているように見えます。爆発エフェクトもほとんど同じ仕組みです。上の画像は発色弾というソフトで作成しました。このソフトはいろいろな爆発エフェクトの画像を簡単に生成できます。ただし、Windows専用です。

爆発クラス

今回のメインの爆発クラスです。

class Explosion(pygame.sprite.Sprite):
    """爆発エフェクト"""
    animcycle = 2  # アニメーション速度
    frame = 0
    def __init__(self, pos):
        # imagesとcontainersはmain()でセット
        pygame.sprite.Sprite.__init__(self, self.containers)
        self.image = self.images[0]
        self.rect = self.image.get_rect()
        self.rect.center = pos
        self.max_frame = len(self.images) * self.animcycle  # 消滅するフレーム
    def update(self):
        # キャラクターアニメーション
        self.image = self.images[self.frame/self.animcycle]
        self.frame += 1
        if self.frame == self.max_frame:
            self.kill()  # 消滅

imagesは、爆発エフェクトの一枚絵を分割した画像リストでmain()で下のように与えています。

 Explosion.images = split_image(load_image("explosion.png"), 16)

split_image()は、キャラクターアニメーション(2008/5/18)で使った関数ですが、何枚絵に分割するか引数で指定できるようにしてあります(これはけっこう使える関数です)。爆発アニメーションは、imagesの画像をフレームごとに切り替えて描画することで実現します。update()でself.frameの値によって異なる画像をself.imageに代入してます。

def split_image(image, n):
    """横に長いイメージを同じ大きさのn枚のイメージに分割
    分割したイメージを格納したリストを返す"""
    image_list = []
    w = image.get_width()
    h = image.get_height()
    w1 = w / n
    for i in range(0, w, w1):
        surface = pygame.Surface((w1,h))
        surface.blit(image, (0,0), (i,0,w1,h))
        surface.set_colorkey(surface.get_at((0,0)), RLEACCEL)
        surface.convert()
        image_list.append(surface)
    return image_list

爆発アニメーションが終了したら爆発は消えるようにします。そのため、self.max_frameになったらkill()で自分自身を消滅するようにしてます。爆発の絵は16枚(=len(self.images))あって各絵は2フレーム(self.animcycle)の間描画するので self.max_frameは32になっています。つまり、32フレーム経過したら爆発オブジェクトはアニメーションが終わって消去されます。

爆発エフェクトの表示

ミサイルがエイリアンに当たったときに爆発を表示したいので衝突判定のcollision_detection()に爆発エフェクト処理を追加します。

def collision_detection(player, aliens, shots, beams):
    """衝突判定"""
    # エイリアンとミサイルの衝突判定
    alien_collided = pygame.sprite.groupcollide(aliens, shots, True, True)
    for alien in alien_collided.keys():
        Alien.kill_sound.play()
        Explosion(alien.rect.center)  # エイリアンの中心で爆発
    # プレイヤーとビームの衝突判定
    beam_collided = pygame.sprite.spritecollide(player, beams, True)
    if beam_collided:  # プレイヤーと衝突したビームがあれば
        Player.bomb_sound.play()
        # TODO: ゲームオーバー処理

エイリアンとミサイルが当たったら、Explosionオブジェクトを作成します。Explosionの引数にエイリアンの座標を与えるとその位置に爆発が描画されます。先ほど言ったように32フレーム経つと自動的にオブジェクトは消えます。