利用python和pygame模块实现飞机大战

背景提要

我学习Python三天了,基础的语法和面向对象已经有了初步的了解,下一步急需一个实践项目来检验学习的成果,因此选择了很多人做过的飞机大战项目,这个项目我最终做完只写了200行不到的代码,在入门中算是比较轻松的了。

软硬件版本

win10
pycharm pro 2018 win版本

项目流程

初步框架准备

首先导入pygame模块,如果你还没有安装,可以在网上查一下如何安装
然后写出基本的main函数框架

import pygame
if __name__ == '__main__':
	# 创建游戏对象
	#TODO
	# 开始游戏
	#TODO

数字常量化

在导入模块后,添加一些全局变量,去替换之后要用到的一些魔法数字

# 屏幕大小的常量
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
# 刷新的帧率
UPDATE_FPS = 60
# 创建敌人飞机的事件
CREATE_ENEMY_EVENT = pygame.USEREVENT

游戏对象的框架

python的完全面向对象的语言,因此游戏本身也是一个对象,因此整个main函数中,先创建游戏对象,再调用该对象的开始游戏方法即可
首先定义一个游戏类,继承自祖先类,然后再明确初始化过程要做什么工作
重写父类的初始化方法,按照套路,先初始化python的所有模块,然后再把游戏窗口给整出来

# 定义一个游戏类
class GameClass(object):
# 游戏的初始化
    def __init__(self):
        pygame.init()                       # 初始化所有的 pygame 模块
        self.__screen_init()                # 窗口初始化

# 游戏窗口初始化
    def __screen_init(self):
        # 创建游戏窗口
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)
        pygame.display.set_caption("飞机大战")

值得一提的是,创建游戏窗口的时候,需要传入一个窗口的长*宽,它是一个元祖对象
另外就是可以设置窗口的名字“飞机大战”
实现窗口初始化函数后,接下来就是如何调用,让程序运行时生成一个游戏界面
再写一个开始游戏函数,这个函数中,用while True做游戏循环,保证程序不会运行完就关闭

# 启动游戏
def start_game(self):
    while True:
        pass

这样一个初步的框架就已经实现了,我们先看一下效果,运行后效果如下图,windows会提示游戏界面没有响应,要不要关闭,这是正常的,在pycharm的右上角点击红色的停止方块即可
游戏界面实现

背景的绘制

游戏界面已经有了,接下来需要我们把背景图片放进去
在一般的其它的游戏中,背景一般不是一成不变的,因此在这里,我们用图片的滚动,来实现即使飞机不动,你也会感觉一直往前飞的效果
实现的原理是用两张图片,在y轴上贴合到一起,组成一张长图片,在游戏开始的时候,一张图片完全与游戏框重合,另外一张在游戏框上面,当图片持续下移,最终有一张图片完全跑到游戏框下面的时候,我们立马把它放到游戏框的上方,这样用户就无法分辨其实背景其实是两张图片一直滚动播放了
滚动背景实现
整个游戏中的要显示的对象,有以下几种,背景、英雄飞机、敌人飞机、英雄子弹,(暂时没有做敌人子弹,因此实现起来稍微复杂一点) 他们的共同特征是,能移动有速度,需要加载图片,因此,先做一个父类,然后根据需求的不同,派生出不同的子类,再去创建背景、飞机对象
该类的代码如下,继承自pygame提供的精灵类,然后一定要先调用父类的init方法,然后加载指定路径的图片,通过get_rect函数,我们可以从加载的图片中获取它的尺寸数据
然后需要指定该对象的速度(默认值设置为1),然后实现它的更新方法,就是在y轴上,根据速度值,改变它的y坐标

# 定义一个游戏精灵类,继承自模块的精灵类
class GameSprite(pygame.sprite.Sprite):
    # 重写init方法
    def __init__(self, image_path, speed=1):
        super().__init__()    							# 先调用父类的方法
        self.image = pygame.image.load(image_path)      # 加载指定路径的图片
        self.rect = self.image.get_rect()               # 获取图片的尺寸
        self.speed = speed                              # 指定精灵对象的速度

    # 更新方法
    def update(self):
        self.rect.y += self.speed                       # 每次更新时,精灵对象在y方向移动

接下来就要去实现一个背景类,该类负责实现背景的交替显示
先重写父类GameSprite的init方法,然后调用父类的方法,加载背景图片,然后根据是第几张图片,判断是放在游戏框之中,还是之上,然后重写更新方法,当背景对象的y值超过范围,也就是图片向下移动到场外时,需要及时移动到游戏画面最上面

# 定义一个背景类,继承自精灵类
class BackGround(GameSprite):
    def __init__(self, isAlt = False):
        # 调用父类方法完成加载图片、尺寸获取、速度指定
        super().__init__("./image/background.png")
        # 判断是不是第二张图片
        if isAlt:
            self.rect.y = -self.rect.height

    # 通过两张图片的滚动播放实现动画效果
    def update(self):
        super().update()
        if self.rect.y >= SCREEN_RECT.height:          # y值移动到边界时
            self.rect.y = -SCREEN_RECT.height           # 让该图片重新回到游戏界面上方

实现了这两个类之后,就要在游戏初始化的方法中,实现背景初始化了
由于继承自pygame的精灵类,所以无论背景、还是飞机,都属于精灵类,因此,需要一个初始化函数,去显示这些精灵
在创建背景精灵后,将这两个背景精灵添加进背景精灵组,通过精灵组,可以对组内的对象统一操作

# 创建初始时的精灵
def __create_sprites(self):
    # 创建背景精灵
    self.bg1 = BackGround(False)
    self.bg2 = BackGround(True)

    # 创建精灵组
    self.back_group = pygame.sprite.Group(self.bg1, self.bg2)

由于需要不断的滚动,因此还要实现更新位置的方法,通过精灵组,调用两个方法,即可实现位置的更新

# 更新精灵
def __update_sprites(self):
     # 更新坐标
     self.back_group.update()
     # 绘制
     self.back_group.draw(self.screen)

位置更新后,还要调用update方法,才能显示出来

# 启动游戏
def start_game(self):
    while True:
        # 更新位置
        self.__update_sprites()
        # 更新显示
        pygame.display.update()

最终的代码如下:

import pygame

# 定义一个游戏精灵类,继承自模块的精灵类
class GameSprite(pygame.sprite.Sprite):

    # 重写init方法
    def __init__(self, image_path, speed=1):
        super().__init__()    # 先调用父类的方法
        self.image = pygame.image.load(image_path)      # 加载指定路径的图片
        self.rect = self.image.get_rect()              # 获取图片的尺寸
        self.speed = speed                              # 指定精灵对象的速度

    # 更新方法
    def update(self):
        self.rect.y += self.speed                      # 每次更新时,精灵对象在y方向移动


# 定义一个背景类,继承自精灵类
class BackGround(GameSprite):
    def __init__(self, isAlt = False):
        # 调用父类方法完成加载图片、尺寸获取、速度指定
        super().__init__("./image/background.png")
        # 判断是不是第二张图片
        if isAlt:
            self.rect.y = -self.rect.height

    # 通过两张图片的滚动播放实现动画效果
    def update(self):
        super().update()
        if self.rect.y >= SCREEN_RECT.height:          # y值移动到边界时
            self.rect.y = -SCREEN_RECT.height          # 让该图片重新回到游戏界面上方



# 定义一个游戏类
class GameClass(object):

# 游戏的初始化
    def __init__(self):
        pygame.init()                      # 初始化所有的 pygame 模块
        self.__screen_init()                # 窗口初始化
        self.__create_sprites()            # 创建初始时的精灵

# 游戏窗口初始化
    def __screen_init(self):
        # 创建游戏窗口
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)
        pygame.display.set_caption("飞机大战")

# 创建初始时的飞机精灵
    def __create_sprites(self):
        # 创建背景精灵
        self.bg1 = BackGround(False)
        self.bg2 = BackGround(True)

        # 创建精灵组
        self.back_group = pygame.sprite.Group(self.bg1, self.bg2)

# 更新精灵
    def __update_sprites(self):
        # 更新坐标
        self.back_group.update()
        # 绘制
        self.back_group.draw(self.screen)

# 启动游戏
    def start_game(self):
        while True:
            # 更新位置
            self.__update_sprites()
            # 更新显示
            pygame.display.update()


if __name__ == '__main__':
    # 创建游戏对象
    game = GameClass()
    # 开始游戏
    game.start_game()

游戏时钟的实现

从实际的效果中,背景图片已经能滚动了,但是速度特别快,因为现在的游戏循环速度太快了,一般的游戏,游戏循环速度一般是60FPS或者144FPS,因此我们再调用时钟对象,去实现60帧的更新速度
我们在GameClass类中,增加一个时钟初始化方法,然后在其游戏初始化方法中,调用时钟初始化方法

# 时钟初始化
def __clock_init(self):
    # 创建时钟对象
    self.clock = pygame.time.Clock()

# 游戏的初始化
def __init__(self):
    pygame.init()              # 初始化所有的 pygame 模块
    self.__screen_init()       # 窗口初始化
    self.__clock_init()        # 时钟初始化
    self.__create_sprites()    # 创建初始时的精灵

然后在游戏循环中,去设置刷新帧率为60

# 启动游戏
def start_game(self):
    while True:
        # 设置刷新帧率
        self.clock.tick(UPDATE_FPS)
        # 更新位置
        self.__update_sprites()
        # 更新显示
        pygame.display.update()

再次启动,可以看出图片的运动速度已经没有那么快了

敌人飞机的实现

我们需要定义一个敌人飞机类,它出现的位置是随机的,但是是一直往下飞的
为了让敌人飞机的出现不要显得太突兀,因此,设置它的y坐标在游戏框外,然后缓缓飞进游戏界面
飞到屏幕外后,要及时销毁该飞机对象,释放内存空间
另外敌人飞机的x坐标也是随机的,在x方向是没有速度的
另外敌人飞机的速度值也是随机的
因为要利用到随机值,首先要导入random

import random

# 定义一个敌人飞机类,继承自精灵类
class Enemy(GameSprite):

    def __init__(self):
        # 调用父类的方法,创建敌人飞机,指定图片
        super().__init__("./image/enemy1.png")
        # 指定初始随机速度
        self.speed = random.randint(1, 3)
        # 指定初始随机位置
        self.rect.x = random.randint(0, SCREEN_RECT.width - self.rect.width)
        self.rect.bottom = 0

    def update(self):
        # 调用父类方法,保持垂直方向的飞行
        super().update()
        # 判断是否飞出屏幕
        if self.rect.y >= SCREEN_RECT.height:
            self.kill()

敌人飞机类实现后,就要在之前做的精灵初始化中,去初始化敌人飞机和敌人飞机精灵组

# 创建初始时的精灵
def __create_sprites(self):
    # 创建背景精灵
    self.bg1 = BackGround(False)
    self.bg2 = BackGround(True)
    # 创建敌人飞机
    self.enemy = Enemy()
    # 创建精灵组
    self.back_group = pygame.sprite.Group(self.bg1, self.bg2)
    self.enemy_group = pygame.sprite.Group(self.enemy)

另外在更新精灵坐标,也要加入敌人飞机的更新

# 更新精灵
    def __update_sprites(self):
        # 更新坐标
        self.back_group.update()
        self.enemy_group.update()
        # 绘制
        self.back_group.draw(self.screen)
        self.enemy_group.draw(self.screen)

再次运行,发现初始化的一个敌人飞机,已经能出现在屏幕中了
接下来,要实现每隔500ms,就出现一架敌人飞机
实现这个功能需要利用pygame提供的定时方法
首先在GameClass中加一个新增敌人飞机方法,创建飞机对象,加入敌人飞机精灵组

# 创建敌人飞机精灵
def __create_enemy_sprites(self):
    self.enemy = Enemy()
    self.enemy_group.add(self.enemy)

然后在时钟初始化的时候,设置定时器的时间

# 时钟初始化
def __clock_init(self):
     # 创建时钟对象
     self.clock = pygame.time.Clock()
     # 设置敌人飞机定时器事件
     pygame.time.set_timer(CREATE_ENEMY_EVENT, 500)

然后添加一个事件监听函数,去监听定时器事件或者键盘/鼠标操作

# 时钟初始化
# 事件监听
def __event_handler(self):
    # 捕获事件列表
    for event in pygame.event.get():
        if event.type ==CREATE_ENEMY_EVENT:
            self.__create_enemy_sprites()

最后,启动游戏后,需要去调用监听方法

# 时钟初始化
# 启动游戏
def start_game(self):
    while True:
        # 设置刷新帧率
        self.clock.tick(60)
        # 事件监听
        self.__event_handler()
        # 更新位置
        self.__update_sprites()
        # 更新显示
        pygame.display.update()

效果如下,屏幕中已经有了好多架飞机了
敌人飞机

退出处理

现在去点叉应该是关不掉程序的,因此还需要对退出的操作进行监听
首先需要实现一个退出方法,它没有参数,因此可以用静态方法实现

# 退出处理
@staticmethod
def __game_over():
    pygame.quit()  # 卸载所有的 pygame 模块
    exit()

另外在监听中,加入对退出的监听

# 事件监听
def __event_handler(self):
    # 捕获事件列表
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            GameClass.__game_over()
        elif event.type == CREATE_ENEMY_EVENT:
            self.__create_enemy_sprites()

现在应该能实现退出功能了

英雄飞机和子弹的实现

英雄有x和y方向的速度,并且不能跑到屏幕外面
英雄有发射子弹的方法,子弹飞出屏幕应该及时销毁
下面两个类的注解应该来说算比较详尽了

# 定义一个英雄飞机类,继承自精灵类
class Hero(GameSprite):
    def __init__(self):
        # 调用父类方法,设置图片,尺寸和速度
        super().__init__("./image/me2.png",0)
        # 设置英雄精灵的初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom - 150
        # 新增垂直方向y的速度
        self.speedy = 0
        # 创建一个子弹精灵组
        self.hero_bullets_group = pygame.sprite.Group()

    def update(self, speed, speedy):
        # 英雄在水平方向上移动
        self.rect.x += speed
        # 英雄在垂直方向上移动
        self.rect.y += speedy

        # 判断英雄的位置,不能超出屏幕范围
        if self.rect.x < 0:
            self.rect.x = 0
        elif self.rect.x > SCREEN_RECT.width - self.rect.width:
            self.rect.x = SCREEN_RECT.width - self.rect.width
        elif self.rect.y < 0:
            self.rect.y= 0
        elif self.rect.y > SCREEN_RECT.height - self.rect.height:
            self.rect.y = SCREEN_RECT.height - self.rect.height

    def fire(self):
        # 创建子弹精灵
        bullet = HeroBullet()
        # 设置精灵的位置
        bullet.rect.bottom = self.rect.y - 20
        bullet.rect.centerx = self.rect.centerx
        # 将精灵添加到精灵组
        self.hero_bullets_group.add(bullet)


# 定义一个子弹类,继承自精灵类
class HeroBullet(GameSprite):

    def __init__(self):
        super().__init__("./image/bullet1.png", -5)

    def update(self):
        # 让子弹按照垂直方向飞行
        super().update()
        # 判断子弹位置是否需要销毁
        if self.rect.bottom < 0:
            self.kill()

创建了这两个类后,需要在初始化精灵时,把英雄飞机也一起初始化

# 创建初始时的精灵
def __create_sprites(self):
    # 创建背景精灵
    self.bg1 = BackGround(False)
    self.bg2 = BackGround(True)
    # 创建敌人飞机
    self.enemy = Enemy()
    # 创建英雄飞机
    self.hero = Hero()
    # 创建精灵组
    self.back_group = pygame.sprite.Group(self.bg1, self.bg2)
    self.enemy_group = pygame.sprite.Group(self.enemy)
    self.hero_group = pygame.sprite.Group(self.hero)

更新精灵的时候,把英雄精灵和子弹精灵一起更新

# 更新精灵
def __update_sprites(self):
     # 更新坐标
     self.back_group.update()
     self.enemy_group.update()
     self.hero_group.update(self.hero.speed, self.hero.speedy)
     self.hero.hero_bullets_group.update()
     # 绘制
     self.back_group.draw(self.screen)
     self.enemy_group.draw(self.screen)
     self.hero_group.draw(self.screen)
     self.hero.hero_bullets_group.draw(self.screen)

运行的时候,画面中已经有了英雄飞机,但是现在无法操作,无法发射子弹
英雄飞机
因此还需要对按键操作添加响应
上下左右按键,可以更改英雄精灵的速度,如果没有按键,则英雄速度为0
空格键发射子弹

# 事件监听
def __event_handler(self):
   # 监听键盘操作
   keys_pressed = pygame.key.get_pressed()
   if keys_pressed[pygame.K_UP]:
       self.hero.speedy = -3
   elif keys_pressed[pygame.K_DOWN]:
       self.hero.speedy = 3
   elif keys_pressed[pygame.K_LEFT]:
       self.hero.speed = -3
   elif keys_pressed[pygame.K_RIGHT]:
       self.hero.speed = 3
   else:
       self.hero.speed = 0
       self.hero.speedy = 0
   # 捕获事件列表
   for event in pygame.event.get():
       if event.type == pygame.QUIT:
           GameClass.__game_over()
       elif event.type == CREATE_ENEMY_EVENT:
           self.__create_enemy_sprites()
       elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
           self.hero.fire()

碰撞检测的实现

目前已经能发射子弹了,但是无法子弹销毁敌人飞机
因此调用pygame给出的方法,去解决这个问题
子弹精灵组和敌人飞机精灵组碰撞时,两个碰撞的精灵均销毁,设置为True
英雄飞机碰撞敌人飞机精灵组时,均销毁,根据返回值,判断是否结束游戏
最后在游戏循环中,加入碰撞检测,代码就已经完成了

# 碰撞检测
def __check_collide(self):
    pass
    # 子弹摧毁敌人飞机
    pygame.sprite.groupcollide(self.hero.hero_bullets_group, self.enemy_group, True, True)
    # 英雄碰撞敌人飞机
    enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
    # 英雄碰到敌人飞机则游戏结束
    if len(enemies):
        self.hero.kill()
        self.__game_over()

最终的代码

import random
import pygame

# 屏幕大小的常量
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
# 刷新的帧率
UPDATE_FPS = 60
# 创建敌人飞机的事件
CREATE_ENEMY_EVENT = pygame.USEREVENT


# 定义一个游戏精灵类,继承自模块的精灵类
class GameSprite(pygame.sprite.Sprite):

    # 重写init方法
    def __init__(self, image_path, speed=1):
        super().__init__()    # 先调用父类的方法
        self.image = pygame.image.load(image_path)      # 加载指定路径的图片
        self.rect = self.image.get_rect()              # 获取图片的尺寸
        self.speed = speed                              # 指定精灵对象的速度

    # 更新方法
    def update(self):
        self.rect.y += self.speed                      # 每次更新时,精灵对象在y方向移动


# 定义一个背景类,继承自精灵类
class BackGround(GameSprite):
    def __init__(self, isAlt = False):
        # 调用父类方法完成加载图片、尺寸获取、速度指定
        super().__init__("./image/background.png")
        # 判断是不是第二张图片
        if isAlt:
            self.rect.y = -self.rect.height

    # 通过两张图片的滚动播放实现动画效果
    def update(self):
        super().update()
        if self.rect.y >= SCREEN_RECT.height:          # y值移动到边界时
            self.rect.y = -SCREEN_RECT.height          # 让该图片重新回到游戏界面上方

# 定义一个敌人飞机类,继承自精灵类
class Enemy(GameSprite):

    def __init__(self):
        # 调用父类的方法,创建敌人飞机,指定图片
        super().__init__("./image/enemy1.png")
        # 指定初始随机速度
        self.speed = random.randint(1, 3)
        # 指定初始随机位置
        self.rect.x = random.randint(0, SCREEN_RECT.width - self.rect.width)
        self.rect.bottom = 0

    def update(self):
        # 调用父类方法,保持垂直方向的飞行
        super().update()
        # 判断是否飞出屏幕
        if self.rect.y >= SCREEN_RECT.height:
            self.kill()
# 定义一个英雄飞机类,继承自精灵类
class Hero(GameSprite):
    def __init__(self):
        # 调用父类方法,设置图片,尺寸和速度
        super().__init__("./image/me2.png",0)
        # 设置英雄精灵的初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom - 150
        # 新增垂直方向y的速度
        self.speedy = 0
        # 创建一个子弹精灵组
        self.hero_bullets_group = pygame.sprite.Group()

    def update(self, speed, speedy):
        # 英雄在水平方向上移动
        self.rect.x += speed
        # 英雄在垂直方向上移动
        self.rect.y += speedy

        # 判断英雄的位置,不能超出屏幕范围
        if self.rect.x < 0:
            self.rect.x = 0
        elif self.rect.x > SCREEN_RECT.width - self.rect.width:
            self.rect.x = SCREEN_RECT.width - self.rect.width
        elif self.rect.y < 0:
            self.rect.y= 0
        elif self.rect.y > SCREEN_RECT.height - self.rect.height:
            self.rect.y = SCREEN_RECT.height - self.rect.height

    def fire(self):
        # 创建子弹精灵
        bullet = HeroBullet()
        # 设置精灵的位置
        bullet.rect.bottom = self.rect.y - 20
        bullet.rect.centerx = self.rect.centerx
        # 将精灵添加到精灵组
        self.hero_bullets_group.add(bullet)


# 定义一个子弹类,继承自精灵类
class HeroBullet(GameSprite):

    def __init__(self):
        super().__init__("./image/bullet1.png", -5)

    def update(self):
        # 让子弹按照垂直方向飞行
        super().update()
        # 判断子弹位置是否需要销毁
        if self.rect.bottom < 0:
            self.kill()

# 定义一个游戏类
class GameClass(object):

# 游戏的初始化
    def __init__(self):
        pygame.init()                      # 初始化所有的 pygame 模块
        self.__screen_init()                # 窗口初始化
        self.__clock_init()                # 时钟初始化
        self.__create_sprites()            # 创建初始时的精灵

# 游戏窗口初始化
    def __screen_init(self):
        # 创建游戏窗口
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)
        pygame.display.set_caption("飞机大战")

# 时钟初始化
    def __clock_init(self):
        # 创建时钟对象
        self.clock = pygame.time.Clock()
        # 设置敌人飞机定时器事件
        pygame.time.set_timer(CREATE_ENEMY_EVENT, 500)

# 创建初始时的精灵
    def __create_sprites(self):
        # 创建背景精灵
        self.bg1 = BackGround(False)
        self.bg2 = BackGround(True)
        # 创建敌人飞机
        self.enemy = Enemy()
        # 创建英雄飞机
        self.hero = Hero()
        # 创建精灵组
        self.back_group = pygame.sprite.Group(self.bg1, self.bg2)
        self.enemy_group = pygame.sprite.Group(self.enemy)
        self.hero_group = pygame.sprite.Group(self.hero)

# 创建敌人飞机精灵
    def __create_enemy_sprites(self):
        self.enemy = Enemy()
        self.enemy_group.add(self.enemy)

# 更新精灵
    def __update_sprites(self):
        # 更新坐标
        self.back_group.update()
        self.enemy_group.update()
        self.hero_group.update(self.hero.speed, self.hero.speedy)
        self.hero.hero_bullets_group.update()
        # 绘制
        self.back_group.draw(self.screen)
        self.enemy_group.draw(self.screen)
        self.hero_group.draw(self.screen)
        self.hero.hero_bullets_group.draw(self.screen)

# 事件监听
    def __event_handler(self):
        # 监听键盘操作
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_UP]:
            self.hero.speedy = -3
        elif keys_pressed[pygame.K_DOWN]:
            self.hero.speedy = 3
        elif keys_pressed[pygame.K_LEFT]:
            self.hero.speed = -3
        elif keys_pressed[pygame.K_RIGHT]:
            self.hero.speed = 3
        else:
            self.hero.speed = 0
            self.hero.speedy = 0
        # 捕获事件列表
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                GameClass.__game_over()
            elif event.type == CREATE_ENEMY_EVENT:
                self.__create_enemy_sprites()
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                self.hero.fire()

# 碰撞检测
    def __check_collide(self):
        pass
        # 子弹摧毁敌人飞机
        pygame.sprite.groupcollide(self.hero.hero_bullets_group, self.enemy_group, True, True)
        # 英雄碰撞敌人飞机
        enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
        # 英雄碰到敌人飞机则游戏结束
        if len(enemies):
            self.hero.kill()
            self.__game_over()


# 退出处理
    @staticmethod
    def __game_over():
        pygame.quit()  # 卸载所有的 pygame 模块
        exit()

# 启动游戏
    def start_game(self):
        while True:
            # 设置刷新帧率
            self.clock.tick(UPDATE_FPS)
            # 事件监听
            self.__event_handler()
            # 碰撞检测
            self.__check_collide()
            # 更新位置
            self.__update_sprites()
            # 更新显示
            pygame.display.update()


if __name__ == '__main__':
    # 创建游戏对象
    game = GameClass()
    # 开始游戏
    game.start_game()

需要用的图片

我放几张图片在这里,大家可以右键保存后转化为png格式自己用
背景
英雄
敌人
子弹

猜你喜欢

转载自blog.csdn.net/whitefish520/article/details/97116587