《Python 飞机大战》(九)音效爆炸

当子弹和敌机碰撞,我们并不想仅将飞机和子弹消失,应该在其发生碰撞的位置播放一组爆炸动画,播放爆炸音效,游戏效果更为逼真一些。

1. Bomb 类

爆炸动画实现思路很简单,我们将一组图片按照一定的时间间隔,将其按顺序绘制到屏幕上,即可显示为动画效果。

class Bomb:

    def __init__(self, scene):
        # 加载爆炸素材
        self.images = [ pygame.image.load(f'source/bomb/bomb-{index + 1}.png') for index in range(7)]
        # 爆炸位置
        self.position = [0, 0]
        # 帧播放间隔
        self.interval = 5
        self.interval_index = 0
        # 当前绘制的图像
        self.draw_index = 0
        # 爆炸是否可见
        self.visible = False
        # 持有场景对象
        self.scene = scene

    def set_used(self, start_x, start_y):
        self.visible = True
        self.draw_index = 0
        self.position[0] = start_x
        self.position[1] = start_y

    def set_unused(self):
        self.visible = False
        self.draw_index = 0
        self.position[0] = -1000
        self.position[1] = -1000

    def switch_frame(self):
        if not self.visible:
            return
        self.interval_index += 1
        if self.interval_index < self.interval:
            return
        self.interval_index = 0

        self.draw_index += 1
        if self.draw_index >= len(self.images):
            self.set_unused()

    def draw_element(self):
        if not self.visible:
            return
        self.scene.blit(self.images[self.draw_index], self.position)

测试 Bomb 类:

if __name__ == '__main__':

    pygame.init()
    window = pygame.display.set_mode([512, 768])
    clock = pygame.time.Clock()

    # 初始化爆炸对象
    bomb = Bomb(window)
    bomb.set_used(200, 450)

    while True:
        window.fill((0, 0, 0))

        # 切换爆炸图片
        bomb.switch_frame()
        # 绘制爆炸图片
        bomb.draw_element()

        if not bomb.visible:
            bomb.set_used(200, 450)

        pygame.event.get()
        pygame.display.update()
        clock.tick(60)

2. 敌机爆炸动画

当敌机被击中时,我们会调用敌机的 set_unused 函数,此时我们就启动爆炸动画的播放。

class EnemyPlane:

    def __init__(self, scene, speed=10):
        # 游戏主场景
        self.scene = scene
        # 敌机资源
        self.image = pygame.image.load(f'source/plane/enemy-{random.randint(1, 7)}.png')
        # 敌机边框
        self.bbox = self.image.get_rect()
        # 移动速度
        self.speed = speed
        # 是否可见
        self.visible = False
        # 初始化子弹
        self.bullet = Bullet(scene, is_enemy=True)

        # -----------爆炸效果----------
        # 初始化爆炸
        self.bomb = Bomb(self.scene)
        # ----------------------------

    def set_used(self, start_x, start_y):
        self.bbox[0] = start_x
        self.bbox[1] = start_y
        self.speed = random.randint(4, 8)
        self.visible = True


    def calc_position(self):

        # 计算飞机位置
        if self.visible:
            self.bbox.move_ip(0, self.speed)
            if self.bbox[1] > SCENE_H:
                self.set_unused()

        # 计算子弹位置
        if self.bullet.visible:
            self.bullet.move(0, self.speed + 5)

        # -----------爆炸效果----------
        # 切换爆炸帧
        self.bomb.switch_frame()
        # ----------------------------


    def draw_element(self):
        # 绘制飞机
        if self.visible:
            self.scene.blit(self.image, self.bbox)
        # 绘制子弹
        if self.bullet.visible:
            self.bullet.draw_element()

        # -----------爆炸效果----------
        # 绘制爆炸图片
        self.bomb.draw_element()
        # ----------------------------

    def set_unused(self):
        self.visible = False
        self.bbox[0] = -1000
        self.bbox[1] = -1000

    def shoot(self):
        if self.bullet.visible:
            return
        start_x = self.bbox[0] + self.bbox[2]/2 - self.bullet.bbox[2]/2
        start_y = self.bbox[1] + self.bbox[3] - 10
        self.bullet.set_used(start_x, start_y)

接下来,在碰撞检测适当的位置调用 Bomb 对象的 set_used 方法即可实现。

3. 爆炸音效和背景音乐

首先,在 Bomb 类的 init 方法中初始化爆炸音效:

class Bomb:

    def __init__(self, scene):
    	
    	...
        
        # 加载爆炸音效
        self.sound = pygame.mixer.Sound('source/music/bomb.wav')
        self.sound.set_volume(0.1)

在 Bomb 类的 set_used 函数中播放爆炸音效,如下代码:

    def set_used(self, start_x, start_y):
        
        ...
        
        # 播放爆炸音效
        self.sound.play()

接下来,添加游戏背景音乐。在 MainScene 的 init 方法中加载背景音乐并设置循环播放,如下:

class MainScene:

    # 初始化主场景
    def __init__(self):

    	...

        # 游戏背景音乐
        pygame.mixer.music.load('source/music/bg.wav')
        pygame.mixer.music.set_volume(0.05)
        pygame.mixer.music.play(-1)

至此,我们 v1.0 版本的飞机大战开发完毕,希望同学们通过这个案例能有所收获。

未经允许不得转载:一亩三分地 » 《Python 飞机大战》(九)音效爆炸
评论 (0)

7 + 8 =