上篇中,我们实现了游戏背景滚动以及敌机随机出现的效果,在上次的基础上,来创建英雄飞机以及实现英雄飞机发射子弹和游戏中的碰撞检测。

 

目标

1、创建英雄飞机以及实现方向键控制移动

2、英雄飞机发射子弹

3、游戏中碰撞检测

 

一、创建英雄飞机

要求:

1、英雄飞机位于屏幕中心,且距底部100个像素

# 创建英雄飞机类
class Hero(GameSprite):
    def __init__(self):
        super(Hero, self).__init__("./image/me1.png", 0)

        # 设置英雄飞机初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom - 100

 

2、左右方向键可控制英雄移动

在__event_handler()中使用pygame.key.get_pressed()来捕获按键,并且返回一个按键元组,然后通过该元组来判断某一个按键是否按下,若是,则返回1,然后设置移动速度,实现左右移动

# 检测控制英雄移动的按键
        key_pressed = pygame.key.get_pressed()
        if key_pressed[pygame.K_RIGHT]:
            self.hero.speed = 4
        elif key_pressed[pygame.K_LEFT]:
            self.hero.speed = -4
        else:
            self.hero.speed = 0

 

3、实现英雄左右移动不出屏幕

在定义的Hero类中的update方法中检测是否移出屏幕

当英雄移动到屏幕最左侧,即self.hero.rect.x<0时,设置其为0;

当英雄移动到屏幕最右侧,即self.hero.rect.x=屏幕右边缘时,设置其等于屏幕右边缘

 

def update(self):
        self.rect.x += self.speed

        # 当移动到屏幕最左边时
        if self.rect.x < 0:
            self.rect.x = 0
        # 当移动到屏幕最右边时
        elif self.rect.right > SCREEN_RECT.right:
            self.rect.right = SCREEN_RECT.right

 

二、英雄飞机发射子弹

1、首先创建一个子弹类,即Bullets()类

class Bullets(GameSprite):
    def __init__(self):
        super(Bullets, self).__init__("./image/bullet1.png", -2)

    def update(self):
        super(Bullets, self).update()

        if self.rect.bottom < 0:
            self.kill()

    def __del__(self):
        print("子弹销毁...")

 

2、在Hero类中在定义一个发射子弹方法,即hero_fire(),一次三连发子弹

def hero_fire(self):
        # print("英雄正在开火...")

        for i in (0, 1, 2):
            # 创建子弹精灵
            bullet = Bullets()

            bullet.rect.bottom = self.rect.y - i * 20
            bullet.rect.centerx = self.rect.centerx

            self.bullets.add(bullet)

 

3、先定义一个发射子弹的定时器常量,再在之前定义的PlaneGame类中__init_()方法中设置一个英雄发射子弹的定时器

# 创建英雄发射子弹定时器
        pygame.time.set_timer(HERO_FIRE_EVENT, 500)

 

4、在之前定义的__event_handler_()中监听该事件,若事件发生,则调用英雄发射子弹方法

def __event_handler(self):
        """事件监听"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                PlaneGame.__game_over()
            elif event.type == ENEMY_EVENT:
                print("敌机出场...")
                # 创建敌机
                enemy = Enemy()
                self.enemy_group.add(enemy)

            elif event.type == HERO_FIRE_EVENT:
                self.hero.hero_fire()

 

三、游戏中的碰撞检测

在pygame中有两种碰撞检测方式:

1、两个精灵组间的碰撞检测

      pygame.sprite.groupcollide()

2、精灵与精灵组间的碰撞检测

      pygame.sprite.spritecollide()

 

在PlaneGame中的__check_collide()中使用第1种方式实现子弹精灵组与敌机精灵组间的碰撞检测,使用第2种方式实现英雄精灵与敌机精灵组间的碰撞检测

def __check_collide(self):
        # 英雄子弹精灵组与敌机精灵组碰撞检测
        pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)

        # 英雄精灵与敌机精灵组的碰撞检测
        enemy_list = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
        if len(enemy_list) > 0:
            self.hero.kill()
            PlaneGame.__game_over()