用 Python 制作飞机大战小游戏

时间:2022-07-26
本文章向大家介绍用 Python 制作飞机大战小游戏,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

这次用Python中的pygame模块来完成一个飞机大战的小游戏;基本思路是通过方向键来控制飞机的左右移动射击飞船。先来看下最后的效果

为了新手也能完成,本文记录了编写的全部流程,也就是每次修改的代码也包括在内,并且给大多数代码都加上了能看懂的注释,看一下最终的的统计字数。

一共敲了4万个字符,希望能帮到感兴趣的读者!

01 安装Pygame

要完成这个项目肯定要安装pygame第三方库,首先通过命令行工具检测系统是否安装的pip工具。

python -m pip --version
小甜是Windows系统,这里只提供Windows系统的检测方法
如果未安装则安装pip工具,安装则请跳过这一步
python get-pip.py

安装完毕以后退回第一步重新检测,现在安装pygame

python -m pip install pygame --user

或者通过pycharm安装第三个库,现在导入pygame即可

import pygame

02 制作小飞机

目标:创建一个可以左右移动的小飞机,用户可以通过空格space键来控制飞机发射子弹。

创建背景

创建一个空背景

首先编写一个空的pygame窗口,文件名为plane_war.py

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame
import sys  # 用于退出游戏


def run_game():
    # 初始化游戏
    pygame.init()
    # 设置屏幕的分辨率
    screen = pygame.display.set_mode((1000, 600))  # 大小为1000px乘以600px

    # 打印其类型
    # print(type(screen))  # <class 'pygame.Surface'>

    pygame.display.set_caption("飞机大战")  # 标题
    # 存储背景的变量
    bg_img = pygame.image.load("./imgs/bg_img.png")  # 相对路径
    print(bg_img)
    # 开始游戏的主循环
    while True:

        # 为了防止游戏窗口启动会立马关闭,在其中增加一个游戏循环(无限循环),
        for event in pygame.event.get():
            # 每次循环都会重新绘制屏幕
            screen.blit(bg_img, [0, 0])  # 绘制图像
            if event.type == pygame.QUIT:  # QUIT用户请求程序关闭
                sys.exit()

        # 将完整显示Surface更新到屏幕
        pygame.display.flip()


run_game()



display.set_mode返回的是一个Surface数据类型

03 创建设置类

一个游戏通常有n多个设置,如果每次想改变其中的某一个值的话在主文件中寻找容易眼花缭乱,现在创建一个新的文件settings.py,专门用来存储这些信息。

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame


class Settings:
    """存储飞机大战的所有设置"""

    def __init__(self):
        # 屏幕设置
        self.screen_width = 1000
        self.screen_height = 600
        self.bg_img = pygame.image.load("./imgs/bg_img.png")


# 现在来改写
plane_war.py"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame
import sys  # 用于退出游戏
from settings import Settings  # 引入settings.py


def run_game():
    # 初始化游戏
    pygame.init()
    # 设置屏幕的分辨率
    setting = Settings()
    screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))
    pygame.display.set_caption("飞机大战")  # 标题
    # 开始游戏的主循环
    while True:

        # 为了防止游戏窗口启动会立马关闭,在其中增加一个游戏循环(无限循环),
        for event in pygame.event.get():
            # 每次循环都会重新绘制屏幕
            screen.blit(setting.bg_img, [0, 0])  # 绘制图像
            if event.type == pygame.QUIT:  # QUIT用户请求程序关闭
                sys.exit()

        # 将完整显示Surface更新到屏幕
        pygame.display.flip()


run_game()

添加小飞机

这里用到的小飞机

04 绘制小飞机

现在图像也有了,来创建一个plane.py模块,其中有一个Plane类,来存储飞机的各种行为。

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame


class Plane:
    def __init__(self, screen):
        # 初始化小飞机并设置其初始位置
        self.screen = screen

        # 加载图像,并获得其矩形区域
        self.img_plane = pygame.image.load("./imgs/plane.png")
        self.rect = self.img_plane.get_rect()  # 得到小飞机的的矩形区域
        self.screen_rect = self.screen.get_rect()  # 得到screen的矩形区域

        # 将小飞机放到底部中央
        self.rect.centerx = self.screen_rect.centerx  # 水平居中
        self.rect.bottom = self.screen_rect.bottom  # 底部

    def blitme(self):
        # 在指定位置绘制小飞机
        self.screen.blit(self.img_plane, self.rect)

get_rect会返回Surface的矩形的区域,.centerx和.bottom是其两个属性

改写plane_war.py将小飞机绘制在屏幕上



"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame
import sys  # 用于退出游戏
from settings import Settings  # 引入settings.py
from plane import Plane


def run_game():
    # 初始化游戏
    pygame.init()
    # 设置屏幕的分辨率
    setting = Settings()
    screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))  # 大小为1000px乘以600px
    pygame.display.set_caption("飞机大战")  # 标题

    # 创建小飞机
    plane = Plane(screen)
    # 开始游戏的主循环
    while True:

        # 为了防止游戏窗口启动会立马关闭,在其中增加一个游戏循环(无限循环),
        for event in pygame.event.get():
            # 每次循环都会重新绘制屏幕
            screen.blit(setting.bg_img, [0, 0])  # 绘制图像
            plane.blitme()  # 将飞船绘制到屏幕上
            if event.type == pygame.QUIT:  # QUIT用户请求程序关闭
                sys.exit()

        # 将完整显示Surface更新到屏幕
        pygame.display.flip()


run_game()


05 创建一个存储运行函数的模块

为了不使plane_war.py太长而影响阅读,来创建一个名为game_func.py的模块,用其飞机大战运行的函数,使其逻辑更容易理解

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import sys
import pygame


def check_events():
    # 为了防止游戏窗口启动会立马关闭,在其中增加一个游戏循环(无限循环),
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # QUIT用户请求程序关闭
            sys.exit()


def update_screen(screen, bg_img, plane):
    # 更新屏幕的图像
    # 每次循环都会重新绘制屏幕
    screen.blit(bg_img, [0, 0])  # 绘制图像
    plane.blitme()  # 将飞船绘制到屏幕上
    # 将完整显示Surface更新到屏幕
    pygame.display.flip()



check_events函数用来完成窗口不会关闭的功能,update_screen用来完成更新图像的功能,有3个形参,Surface对象、背景图像、小飞机函数

因为check_events完成了退出游戏的操作,所以plane_war.py就不需要sys模块了,更新后的plane_war.py如下

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame
from settings import Settings  # 引入settings.py
from plane import Plane
import game_func as fg


def run_game():
    # 初始化游戏
    pygame.init()
    # 设置屏幕的分辨率
    setting = Settings()
    screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))  # 大小为1000px乘以600px
    pygame.display.set_caption("飞机大战")  # 标题

    # 创建小飞机
    plane = Plane(screen)
    # 开始游戏的主循环
    while True:

        # 不关闭窗口
        fg.check_events()

        # 绘制图像
        fg.update_screen(screen, setting.bg_img, plane)



run_game()



06 控制小飞机

通过修改小飞机的坐标来完成移动,在用户按下方向键的时候小飞机的坐标进行有规律的变化。

控制小飞机移动

当用户按键时,都会在pygame中注册一个事件,任何一个事件都是通过pygame.event.get()获取的,因此可以在函数体内,为每个按键都注册一个KEYDOWN事件。

现在将check_events函数改写,通过检测按下键位,来对小飞机进行移动

def check_events(plane):
    # 为了防止游戏窗口启动会立马关闭,在其中增加一个游戏循环(无限循环),
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # QUIT用户请求程序关闭
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                # 小飞机往又移动
                plane.rect.centerx += 1

现在按一下小飞机移动一个像素,一般的游戏都是通过按下不送则一直移动,Pygame中的pygame.KEYUP可以检测用户是否松开按键 现在结合KEYDOWN和KEYUP来完成一个持续移动

控制小飞机持续移动

来定义一个标志位,来判断用户是否按下按键,默认为Flase一旦检测到用户按下俺家则为True,小飞机就可以持续移动

由于小飞机是通过plane.py文件来控制的,对这个文件进行改写

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame


class Plane:
    def __init__(self, screen):
        # 初始化小飞机并设置其初始位置
        self.screen = screen

        # 加载图像,并获得其矩形区域
        self.img_plane = pygame.image.load("./imgs/plane.png")
        self.rect = self.img_plane.get_rect()  # 得到小飞机的的矩形区域
        self.screen_rect = self.screen.get_rect()  # 得到screen的矩形区域
        # print(self.screen_rect)

        # 将小飞机放到底部中央
        self.rect.centerx = self.screen_rect.centerx  # 水平居中
        self.rect.bottom = self.screen_rect.bottom  # 底部
        
        # 标志位
        self.mv_right = False
        
    # 定义一个调整小飞机位置的方法
    def update(self):
        # 根据标志位的调整小飞机的位置
        if self.mv_right:
            self.rect.centerx += 1

    def blitme(self):
        # 在指定位置绘制小飞机
        self.screen.blit(self.img_plane, self.rect)

update方法是标志位为True时,小飞机就开始移动

改写game_func.py中的check_events函数

def check_events(plane):
    # 为了防止游戏窗口启动会立马关闭,在其中增加一个游戏循环(无限循环),
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # QUIT用户请求程序关闭
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                # 当用户按下键位时标志位为True
                plane.mv_right = True

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                # 当用户松开键位为false
                plane.mv_right = False

最后只要在plane_war.py中调用update方法就可以完成持续移动的操作

完成左右移动

用同样的方法完成向左移动

改写后的plane.py文件

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame


class Plane:
    def __init__(self, screen):
        # 初始化小飞机并设置其初始位置
        self.screen = screen

        # 加载图像,并获得其矩形区域
        self.img_plane = pygame.image.load("./imgs/plane.png")
        self.rect = self.img_plane.get_rect()  # 得到小飞机的的矩形区域
        self.screen_rect = self.screen.get_rect()  # 得到screen的矩形区域
        # print(self.screen_rect)

        # 将小飞机放到底部中央
        self.rect.centerx = self.screen_rect.centerx  # 水平居中
        self.rect.bottom = self.screen_rect.bottom  # 底部

        # 标志位
        self.mv_right = False
        self.mv_left = False

    # 定义一个调整小飞机位置的方法
    def update(self):
        # 根据标志位的调整小飞机的位置
        if self.mv_right:
            self.rect.centerx += 1

        if self.mv_left:
            self.rect.centerx -= 1

    def blitme(self):
        # 在指定位置绘制小飞机
        self.screen.blit(self.img_plane, self.rect)

改写后的game_func.py中的check_events函数

def check_events(plane):
    # 为了防止游戏窗口启动会立马关闭,在其中增加一个游戏循环(无限循环),
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # QUIT用户请求程序关闭
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                # 当用户按下键位时标志位为True
                plane.mv_right = True
            elif event.key == pygame.K_LEFT:
                plane.mv_left = True

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                # 当用户松开键位为false
                plane.mv_right = False
            elif event.key == pygame.K_LEFT;
             plane.mv_left = False



07 调整速度

现在的小飞机一次是按1px来移动的,那速度是相当的缓慢,修改一下小飞机的移动速度。

首先在setting.py中添加一行

self.plane_speed = 2.5

现在对plane.py做修改

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame


class Plane:
    def __init__(self, screen, setting):
        # 初始化小飞机并设置其初始位置
        self.screen = screen
        self.setting = setting  # 实例化属性

        # 加载图像,并获得其矩形区域
        self.img_plane = pygame.image.load("./imgs/plane.png")
        self.rect = self.img_plane.get_rect()  # 得到小飞机的的矩形区域
        self.screen_rect = self.screen.get_rect()  # 得到screen的矩形区域
        # print(self.screen_rect)

        # 将小飞机放到底部中央
        self.rect.centerx = self.screen_rect.centerx  # 水平居中
        self.rect.bottom = self.screen_rect.bottom  # 底部

        # 将其修改为浮点数
        self.center = float(self.rect.centerx)

        # 标志位
        self.mv_right = False
        self.mv_left = False

    # 定义一个调整小飞机位置的方法
    def update(self):
        # 根据标志位的调整小飞机的位置
        if self.mv_right:
            self.center += self.setting.plane_speed  # settings中的属性

        if self.mv_left:
            self.center -= self.setting.plane_speed

        # 根据self.center的值来更新self.rect.centerx
        self.rect.centerx = self.center

    def blitme(self):
        # 在指定位置绘制小飞机
        self.screen.blit(self.img_plane, self.rect)

将plane_war.py中的plane增加一个属性
plane = Plane(screen, setting)

08 限制小飞机的活动范围

现在小飞机已经可以飞呀飞,但是没有东西限制他,很容易就飞出了屏幕。现在将其限制在屏幕中,避免飞出去。

只需要修改plane.py中的update方法,重构game_func.py中的check_events函数。

随着小飞机的功能愈来愈多,现在将check_events重构为3个函数,捕捉用户按键和用户松开键分别定义两个函数。

重构后的check_events

def check_keydown_events(event, plane):
    # 捕捉用户按下
    if event.key == pygame.K_RIGHT:
        # 当用户按下键位时标志位为True
        plane.mv_right = True
    elif event.key == pygame.K_LEFT:
        plane.mv_left = True


def check_keyup_events(event, plane):
    # 捕捉用户松开
    if event.key == pygame.K_RIGHT:
        # 当用户松开键位为false
        plane.mv_right = False
    elif event.key == pygame.K_LEFT:
        plane.mv_left = False


def check_events(plane):
    # 为了防止游戏窗口启动会立马关闭,在其中增加一个游戏循环(无限循环),
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # QUIT用户请求程序关闭
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event, plane)

        elif event.type == pygame.KEYUP:
            check_keyup_events(event, plane)

09 完成射击功能

通过玩家按下空格来发射子弹(一小小小的矩形)

添加子弹的设置

在settings.py中的__init__方法中添加以下数据

# 子弹的设置
self.bullet_speed = 3  # 速度
self.bullet_width = 3  # 子弹的宽
self.bullet_height = 15  # 子弹的高
self.bullet_color = 100, 100, 100  # 子弹的颜色


创建Bullet类

创建存储子弹的Bullet类的bullet.py文件

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame
from pygame.sprite import Sprite


class Bullet(Sprite):  # 继承pygame.sprite中的Sprite类
    """子弹的管理"""

    def __init__(self, setting, screen, plane):
        super().__init__()
        self.screen = screen
        # 在(0,0)处创建一个表示子弹的矩形
        # pygame.Rect
        # 用于存储直角坐标的pygame对象
        self.rect = pygame.Rect(0,0, setting.self.bullet_width, setting.self.bullet_height)
        # 设置显示的位置
        self.rect.centerx = plane.rect.centerx
        self.rect.top = plane.rect.top
        # 让子弹的位置跟小飞机重叠,当子弹飞出了以后,就显得跟从小飞机里面射出来一样

        # 将子弹的坐标转换为浮点数
        self.y = float(self.rect.y)

        # 子弹的颜色
        self.color = setting.bullet.color
        # 子弹的速度
        self.speed = setting.bullet.speed

    def update(self):
        # 向上移动子弹
        self.y -= self.speed
        # 根据self.y的值更新self.rect.y
        self.rect.y = self.y

    def draw_bullet(self):
        """绘制子弹"""
        # pygame.draw.rect()画一个矩形的形状
        pygame.draw.rect(self.screen, self.color, self.rect)

Bullet类继承于pygame.sprite中的Sprite类,此类可以将游戏中的元素进行编组,可以同时操作编组中的所有元素

将子弹存储到编组中

首先在plane_war.py中创建一个编组,用于存储所有有效的子弹,以便能够管理发射出去的子弹;这个编组是pygame.sprite.Group类的一个实例;pygame.sprite.Group类类似于列表,但是提供了有助于开发游戏的额外功能。在主循环中,我们将使用这个编组在屏幕上绘制子弹,以及更新没颗子弹的位置。

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame
from settings import Settings
from plane import Plane
import game_func as fg
from pygame.sprite import Group


def run_game():
    # 初始化游戏
    pygame.init()
    # 设置屏幕的分辨率
    setting = Settings()
    screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))  # 大小为1000px乘以600px
    pygame.display.set_caption("飞机大战")  # 标题

    # 创建一个存储子弹的编组
    bullets = Group()

    # 创建小飞机
    plane = Plane(screen, setting)
    # 开始游戏的主循环
    while True:
        # 不关闭窗口
        fg.check_events(plane, setting, screen, bullets)

        # 调用小飞机移动的方法
        plane.update()

        bullets.update()

        # 绘制图像
        fg.update_screen(screen, setting.bg_img, plane, bullets)



run_game()
开火

通过修改game_func.py中的函数来完成发射子弹的操作

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import sys
from bullet import Bullet
import pygame


def check_keydown_events(event, plane, setting, screen, bullets):
    # 捕捉用户按下
    if event.key == pygame.K_RIGHT:
        # 当用户按下键位时标志位为True
        plane.mv_right = True
    elif event.key == pygame.K_LEFT:
        plane.mv_left = True
    elif event.key == pygame.K_SPACE:
        # 创建一个子弹,并将其加入到编组bullets中
        new_bullet = Bullet(setting, screen, plane)
        bullets.add(new_bullet)


def check_keyup_events(event, plane):
    # 捕捉用户松开
    if event.key == pygame.K_RIGHT:
        # 当用户松开键位为false
        plane.mv_right = False
    elif event.key == pygame.K_LEFT:
        plane.mv_left = False


def check_events(plane, setting, screen, bullets):
    # 为了防止游戏窗口启动会立马关闭,在其中增加一个游戏循环(无限循环),
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # QUIT用户请求程序关闭
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event, plane, setting, screen, bullets)

        elif event.type == pygame.KEYUP:
            check_keyup_events(event, plane)


def update_screen(screen, bg_img, plane, bullets):
    # 更新屏幕的图像
    # 每次循环都会重新绘制屏幕
    screen.blit(bg_img, [0, 0])  # 绘制图像
    # 绘制子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()  # 绘制子弹
    plane.blitme()  # 将飞船绘制到屏幕上
    # 将完整显示Surface更新到屏幕
    pygame.display.flip()



用户按下空格之后会创建一个子弹(一个名为new_bullet的Bullet实例),并使用add追加到编组中 方法bullets.sprites返回一个列表,包含了编组中的所有精灵,遍历编组中的精灵,并通过draw_bullet()绘制到屏幕上

现在已经完成基本的射击功能了,虽然子弹到达屏幕顶端后消失了,这仅仅是因为pygame无法绘制屏幕外面的东西,这些子弹实际还是存在的,他们的y坐标为负数且越来越少,会继续消耗内存。

删除已经消失的子弹

这里通过.copy进行浅拷贝,然后检测子弹是否消失,然后再将其删除

对plane_war.py中的while语句中添加下面这一句。

# 删除已经消失的子弹
for bullet in bullets.copy():
    if bullet.rect.bottom <= 0:
        bullets.remove(bullet)

# print(len(bullets))  # 用于测试子弹是否删除

注意:在fg.update_screen之前进行添加

限制子弹的数量

为了不使这个小游戏跟开挂似得,肯定要限制一下发射子弹的数量,在settings.py中添加一行

# 限制子弹的数量
self.bullet_allowed = 5

在check_keydown_events函数体中增加一个判断即可

简化plane_war.py中的while语句

将发射子弹移步到game_func.py文件中并创建一个update_bullets

def update_bullets(bullets):
    # 将编组中的每个子弹调用bullet.update()
    bullets.update()
    # 删除已经消失的子弹
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)



此时的while语句中就4行代码

while True:
    fg.check_events(plane, setting, screen, bullets)  # 不关闭窗口
    plane.update()  # 调用小飞机移动的方法
    fg.update_bullets(bullets)  # 绘制子弹
    fg.update_screen(screen, setting.bg_img, plane, bullets) 
      # 绘制图像


小飞机添加完毕的效果

10 制作飞船

现在小飞机也创建完成了,现在就该创建小飞机的敌人了,同样通过一个类来控制其所有行为,先来看看这个卡哇伊的飞船

目标:创建好非常让其随意移动,可以射杀飞船、当飞船碰到小飞机GAMEOVER,飞船碰到地面也GAMEOVER

创建飞船

创建Spaceship类

创建一个名为spaceship.py的文件来存储Spaceship类

"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/4
"""
import pygame
from pygame.sprite import Sprite


class Spaceship(Sprite):
    '''表示飞船的类'''
    def __init__(self, setting, screen):
        super().__init__()
        self.screen = screen
        self.setting = setting
        
        # 添加飞船图像
        self.img = pygame.image.load("./imgs/enemy.png")
        # 获取rect属性
        self.rect = self.img.get_rect()
        
        # 每个飞船最初都在屏幕左上角附近
        self.rect.x = self.rect.width  # 飞船图像的左边距等于图像的宽度

        self.rect.y = self.rect.height  # 飞船图书的上边距等于图像的高度
        

        self.x = float(self.rect.x)
    def blitme(self):
        # 绘制飞船图像
        self.screen.blit(self.img, self.rect)


这里除了位置基本与Plane类相同

实例化Spaceship类在plane_war.py中添加Spaceship实例"""
-*- coding:uft-8 -*-
author: 小甜
date:2020/6/3
"""
import pygame
from settings import Settings  # 引入settings.py
from plane import Plane
import game_func as fg
from pygame.sprite import Group
from spaceship import Spaceship


def run_game():
    # 初始化游戏
    pygame.init()
    # 设置屏幕的分辨率
    setting = Settings()
    screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))  # 大小为1000px乘以600px
    pygame.display.set_caption("飞机大战")  # 标题
    # 创建一个存储子弹的编组
    bullets = Group()
    # 创建小飞机
    plane = Plane(screen, setting)
    # 创建飞船
    spaceship = Spaceship(setting, screen)
    # 开始游戏的主循环
    while True:
        # 不关闭窗口
        fg.check_events(plane, setting, screen, bullets)
        # 调用小飞机移动的方法
        plane.update()
        # 绘制子弹
        fg.update_bullets(bullets)
        # 绘制图像
        fg.update_screen(screen, setting.bg_img, plane, bullets, spaceship)



run_game()

这里导入了一下新创建的Spaceship类,在while循环外创建一个实例,给update_screen传递一个飞船的实例

让飞船出现在屏幕上

修改update_screen函数

def update_screen(screen, bg_img, plane, bullets, spaceship):
    # 更新屏幕的图像
    # 每次循环都会重新绘制屏幕
    screen.blit(bg_img, [0, 0])  # 绘制图像
    # 绘制子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()  # 绘制子弹
    plane.blitme()  # 将飞船绘制到屏幕上

    # 绘制飞船
    spaceship.blitme()
    # 将完整显示Surface更新到屏幕
    pygame.display.flip()

这就是创建飞机大战地图的过程,实施的过程后续在发~