使用 PyGame 在 Python 中制作 Flappy Bird 游戏

2025 年 3 月 17 日 | 阅读 31 分钟

Python 是最流行的高级编程语言之一。Python 为不同领域提供了庞大的库,例如人工智能TensorFlowPyTorch)、机器学习PandasNumPyMatplotlib)和游戏开发PygletPyGame)。我们也可以将 Python 视为下一代编程语言,因为它在计算机科学的每个新兴领域都积极展现着它的存在。

在以下教程中,我们将使用 Python 编程语言中的 PyGame 库创建一个名为 Flappy Bird 的游戏。

Flappy Bird 是一款无尽游戏,其中包含一只由玩家控制的鸟。该游戏的目标是防止鸟掉落到地面或与管道等障碍物碰撞。每当鸟穿过管道时,分数就会增加一。当鸟与管道碰撞或因重力掉落到地面时,游戏结束。

但在我们开始构建这个项目之前,让我们简要了解一下 Python PyGame 库。

了解 PyGame 库

PyGame 库是一套跨平台的 Python 模块,用于开发视频游戏。PyGame 主要由计算机图形和声音库组成,旨在与 Python 编程语言一起使用。Pete Shinners 官方编写了这个库以取代 PySDL。它适用于开发客户端应用程序,这些应用程序可以潜在地封装在独立的 exe 文件中。

如何安装 PyGame 库?

可以通过在命令提示符或终端中键入以下命令,使用 PIP 安装程序安装 PyGame 库。

语法

安装完成后,我们可以通过创建一个新的 python 程序文件并导入 pygame 模块来验证 pygame 库是否已正确安装。

以下是说明相同内容的代码片段。

文件:verify.py

现在,让我们保存文件并在命令提示符或终端中运行以下命令。

语法

如果程序没有返回任何导入错误,则表示库已成功安装。如果出现任何异常,请尝试重新安装库并考虑查看其官方文档。

项目先决条件

现在我们已经成功安装了所需的库,让我们简要了解一下项目的前提条件。以下是项目所需的模块

  1. PyGame: 此模块将允许我们开发游戏。
  2. Random: 此模块将允许我们生成随机数、打印列表或字符串的随机值等等。

使用 PyGame 开发 Flappy Bird 游戏

现在我们将开始用 Python 开发 Flappy Bird 游戏。我们创建了一个名为 "Flappy Bird" 的文件夹。在此文件夹中,我们创建了一个名为 "main.py" 的 python 文件,用于编写程序代码,以及另一个名为 "images" 的文件夹,其中包含整个项目所需的所有图像。

可以通过以下链接下载项目资源

点击此处下载

我们已将完整的项目代码分为更小的片段,以便更好地理解。以下是我们开发项目将遵循的步骤

第 1 步: 首先,我们将导入所需的模块。

第 2 步: 然后我们将创建一个滚动背景。

第 3 步: 此步骤涉及向游戏中添加精灵动画。

第 4 步: 然后我们将为游戏添加一些物理特性。

第 5 步: 在此步骤中,我们将向游戏中添加滚动管道。

第 6 步: 然后我们将添加一个分数计数器。

第 7 步: 最后我们将添加游戏结束和重置游戏的功能。

现在,让我们详细了解这些步骤的实现。

导入必要的模块

我们将首先导入游戏开发所需的所有模块。我们将导入 pygame 模块以及 random 模块。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们导入了 pygame 模块。然后我们从 pygame.locals 模块中导入了所有内容。最后,我们导入了 random 模块。

创建滚动背景

现在我们已经导入了项目所需的所有模块,是时候创建一个滚动背景了。为了实现此目标,我们首先初始化 pygame 窗口。我们将设置屏幕大小和要显示的标题。我们还将定义一些必要的函数来执行滚动。然后我们将从目录中加载一些图像以显示背景和底部并执行功能。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们使用了 init() 函数来初始化 pygame 窗口。然后我们创建了 pygame.time 模块的 Clock() 类的对象,并定义了一个变量来存储游戏的 FPS。然后我们定义了宽度和高度,并使用 pygame.display 模块的 set_mode() 函数来设置屏幕大小。然后我们使用 pygame.display 模块的 set_caption() 函数来设置应用程序的标题。然后我们声明并初始化了一些专门用于执行滚动的游戏变量。然后我们使用 pygame.image 模块的 load() 函数来加载图像以显示背景和底部。

然后我们将 game_run 变量的值设置为 True,并使用 while 循环来运行游戏。在此循环中,我们使用 tick() 函数将游戏时钟设置为我们之前定义的 FPS。然后我们使用 blit() 函数绘制背景。然后我们使用 blit() 函数绘制底部,并通过从底部滚动值中减去滚动速度来设置其滚动,如果底部滚动的绝对值大于 70 像素,则将底部滚动值设置回 0。然后我们使用 for 循环遍历游戏事件,如果事件类型是 pygame 模块的 QUIT 常量,则将 game_run 变量的值设置为 False。然后我们使用 update() 函数来更新游戏中的事件。最后,我们使用 quit() 函数退出游戏。

创建小鸟的精灵动画

现在我们将使用 Sprite() 类创建小鸟的精灵动画来显示小鸟。在这个类中,我们将从目录中导入所需的精灵小鸟图像,并将导入的图像一个接一个地放置以执行动画。

让我们考虑以下演示相同内容的代码片段。

文件:main.py

说明

在上述代码片段中,我们创建了一个名为 FlappyBird 的类,使用 pygameSprite() 类来显示小鸟。我们定义了一个初始化函数来初始化此函数中的一些变量。我们创建了一个空列表并将 indexcounter 值设置为 0。然后我们使用 for 循环遍历我们使用 pygame.image 模块的 load() 函数加载到程序中的小鸟图像。然后我们使用 append() 函数将这些导入的图像添加到我们之前创建的列表中。然后我们设置了游戏开始时要显示的初始图像。然后我们使用 get_rect() 函数为小鸟在屏幕上的位置创建了一个矩形,并将其坐标设置为小鸟像素的坐标。然后我们定义了另一个函数来处理动画。在此函数中,我们通过将 counter 变量的值增加 1 来更新它,并定义了另一个变量来显示精灵冷却时间。如果 counter 值超过冷却时间值,我们将 counter 值设置回 0。然后我们通过将 index 值增加 1 来更新它,如果该值大于图像列表中的元素数量,则将其设置回 0。然后我们根据索引值更新图像列表中的当前图像。然后我们创建了 pygame.sprite 模块的 Group() 类的对象。最后,我们实例化了 FlappyBird() 类,并使用 add() 函数将此实例添加到 Group() 类的对象中。

现在我们已经成功创建了用于显示小鸟的 Sprite() 类,是时候在背景上绘制小鸟并调用必要的函数来实现其动画了。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们通过添加语句来绘制小鸟并实现动画,从而更新了 while 循环。我们使用带有包含小鸟的 Group() 类对象的 draw() 函数将其显示在主屏幕上。然后我们调用 update() 函数来为小鸟制作动画。

为游戏添加物理特性

现在我们将为游戏添加一些物理特性。这将有助于小鸟因重力而下落并在鼠标点击时跳跃。我们还将尝试对小鸟精灵本身进行一些调整,使其看起来更具吸引力。

我们将从声明和初始化一些游戏变量开始。这些变量将包含表示小鸟是否飞行和游戏结束的布尔值。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们声明了一些游戏变量并将其初始化为 False

现在我们将更新 FlappyBird() 类。这些更新包括实现鸟的速度、检查鼠标键是否被按下以及鸟的旋转。

让我们考虑以下演示相同内容的代码片段。

文件:main.py

说明

在上述代码片段中,我们通过添加一些变量来更新 FlappyBird() 类,这些变量表示小鸟的初始速度和描述鼠标键状态的布尔值。在类的 update() 函数内部,我们包含了实现自由落体和每次鼠标点击时跳跃功能的代码。为了实现自由落体功能,我们创建了一个检查点以查看小鸟是否正在飞行,并添加了一些语句,例如将小鸟的速度增加 0.5,如果小鸟达到 8.5 或更高的速度,则将最终速度设置为 8.5。我们还检查了小鸟图像矩形的位置是否小于 576,并将其值增加了速度。同样,为了实现每次鼠标点击时的跳跃,我们借助 if-else 条件语句创建了一个检查点,以查看游戏是否未结束。然后我们检查鼠标是否被按下且初始按下值为 False,并将按下值设置为 True,速度等于 -10 以使小鸟向上移动。然后我们检查鼠标是否被释放并将按下值设置回 False。然后我们使用 pygame.transform 模块的 rotate() 函数将小鸟旋转一定角度,使其看起来像在移动。如果游戏结束,我们再次使用 rotate() 函数将小鸟旋转 -90 以使其看起来已死亡。

现在我们已经对 FlappyBird() Sprite 类进行了必要的调整,是时候更新游戏循环了。我们将对游戏进行检查点,以查看小鸟是否已触地。我们还将添加一条语句,以便在游戏结束时暂停底座的滚动。此外,我们还将添加一条语句,以便在用户点击屏幕时开始游戏。

现在让我们考虑以下代码片段来演示这一点。

注意:每当我们在游戏中添加新内容时,while 循环都会更新,直到游戏完全正常运行。因此,建议用以下代码替换之前的 while 循环。

文件:main.py

说明

在上面的代码片段中,我们通过添加一个 if 条件语句来检查小鸟是否没有撞到地面,从而更新了 while 循环。如果撞到了地面,游戏将结束,小鸟将不再飞行。同样,我们添加了 if 条件语句来检查游戏是否没有结束并设置底座滚动。我们在遍历事件的 for 循环中添加了另一个 if 条件语句,以检查鼠标点击、小鸟未飞行以及游戏未结束,并设置小鸟飞行以开始游戏。

向游戏中添加滚动管道

现在我们已经将背景、底部和鸟添加到游戏中,是时候添加滚动管道了。我们将首先声明并初始化一些游戏变量来存储值,例如管道之间的间隙和管道的频率。我们将创建一个 Sprite() 类来显示管道并更新游戏循环。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们声明了一些游戏变量,如 pipeGappipeFrequencylastPipe,并分别用一些值初始化它们。

现在我们将使用 pygameSprite() 类创建一个类来显示管道。此类将频繁地在游戏中生成不同的管道。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们创建了一个 pygameSprite() 类的类。在此类中,我们定义了一个初始化函数来声明一些所需的变量并从目录中加载管道图像。然后我们创建了一个矩形来放置导入的管道图像。然后我们将其放置在顶部和底部,彼此相对。然后我们定义了一个函数来处理管道的动画和内存。在此函数中,我们使用与底部相同的滚动速度设置管道滚动。我们还使用 kill() 函数在管道离开屏幕后释放内存。最后,我们创建了一个 Group() 类的对象来存储管道。

现在我们已经创建了用于显示管道的 Sprite() 类,我们将更新我们的游戏循环以查看游戏中管道的实现。

让我们考虑以下说明相同内容的代码片段。

注意:每当我们在游戏中添加新内容时,while 循环都会更新,直到游戏完全正常运行。因此,建议用以下代码替换之前的 while 循环。

文件:main.py

说明

在上述代码片段中,我们通过向游戏添加管道来更新了 while 循环。我们使用了 draw() 方法在游戏屏幕上绘制管道。然后我们使用了 groupcollide() 函数来检查小鸟和管道之间是否有任何碰撞并结束游戏。然后我们生成了高度变化的新的管道。然后我们将这些管道添加到地板和天花板上。

创建分数计数器

现在我们将向游戏中添加一个分数计数器。每当小鸟成功穿过管道时,此分数计数器将奖励玩家 1 分。

为了使此机制正常工作,我们将创建一个标志来检查小鸟是否已通过管道,以及一个计数器来存储分数。我们将标志的初始值设置为 False,计数器设置为 0。然后我们将检查小鸟是否已通过管道的左侧但未通过右侧,并将标志值设置为 True。一旦小鸟通过管道的右侧,我们将把标志值设置回 False 并将计数器值增加 1。每当小鸟穿过管道时,此过程将继续。

Flappy Bird Game using PyGame in Python

现在让我们通过以下代码片段来理解这一点。

文件:main.py

说明

在上面的代码片段中,我们定义了一些变量来存储字体样式和颜色。然后我们声明了一些游戏变量来存储分数和标志值,并分别将其初始化为 0False

现在我们将定义一个函数,将文本作为图像绘制到屏幕上,因为 Pygame 不提供直接向应用程序添加文本的灵活性。此函数将接受多个参数,例如要显示的文本、字体样式、字体颜色以及将显示此文本的坐标。我们将使用 render() 函数将所需文本渲染为图像。然后我们将使用 blit() 函数在屏幕上显示图像。

文件:main.py

说明

在上述代码片段中,我们定义了一个名为 drawText() 的函数,它接受文本、字体样式、文本颜色以及 x 轴和 y 轴坐标作为其参数。在该函数中,我们使用 render() 函数将文本渲染为图像。然后我们使用 blit() 函数在屏幕上显示渲染的图像。

我们将再次更新游戏循环,将分数计数器的配置添加到游戏中。

让我们考虑以下说明相同内容的代码片段。

注意:每当我们在游戏中添加新内容时,while 循环都会更新,直到游戏完全正常运行。因此,建议用以下代码替换之前的 while 循环。

文件:main.py

说明

在上面的代码片段中,我们再次更新了 while 循环,添加了分数计数器。为此,我们检查了小鸟是否在管道上方并已通过其左侧但未通过右侧,并将标志值设置为 True。然后我们检查了标志是否为 True,以及小鸟是否已通过管道的右侧,并将分数增加了 1 并将标志设置回 False。然后我们调用了 drawText() 函数以在屏幕上显示计算出的分数。

添加游戏结束和重新开始游戏的功能

现在我们将添加一些函数来显示游戏结束屏幕并重新开始游戏。我们可以通过导入游戏结束时需要显示的图像来实现此目标。然后我们将定义一个类来将图像显示为按钮并与其交互的功能。

那么,让我们从导入所需的图像开始。以下是演示此操作的代码片段。

文件:main.py

说明

在上面的代码片段中,我们使用 pygame.image 模块的 load() 函数从目录中导入所需的图像。

现在我们将定义一个类来显示按钮。让我们考虑以下代码片段来演示这一点。

文件:main.py

说明

在上面的代码片段中,我们定义了一个名为 Button() 的类。在该类中,我们定义了一个初始化函数来初始化一些用于处理导入图像的变量。然后我们定义了一个名为 draw() 的函数来在屏幕上绘制图像。我们定义了一个标志并最初将其值初始化为 False。然后我们使用 pygame.mouse 模块的 get_pos() 函数检索鼠标位置。然后我们检查鼠标是否点击了按钮并将标志设置为 True。然后我们使用 blit() 函数在屏幕上绘制导入的图像并返回标志。最后,我们实例化了 Button() 类。

现在我们将定义一个函数来重置游戏。此函数会将小鸟的位置设置回其初始状态,将分数设置回 0,并从屏幕上移除管道。

让我们考虑以下说明相同内容的代码片段。

文件:main.py

说明

在上面的代码片段中,我们定义了一个名为 resetGame() 的函数。在该函数中,我们调用了 empty() 函数以移除 pipeGroup 组中的所有精灵。然后我们设置了小鸟放置的坐标。我们还将玩家分数设置为 0 并返回。

现在我们将再次更新游戏循环,以查看 Button() 类和 resetGame() 函数的实现。

让我们考虑以下说明相同内容的代码片段。

注意:每当我们在游戏中添加新内容时,while 循环都会更新,直到游戏完全正常运行。因此,建议用以下代码替换之前的 while 循环。

文件:main.py

说明

在上面的代码片段中,我们检查了游戏是否结束以及按钮是否显示。然后我们将 gameOver 标志值设置回 False,调用 resetGame() 函数,并使用 playerScore 变量存储分数的初始值,即 0

现在项目代码终于完成了,是时候看看结果了。我们将保存项目文件,并在命令shell或终端中使用以下命令运行程序。

语法

在我们继续之前,让我们简要看看 "使用 Pygame 的 Flappy Bird" 的完整项目代码。

完整的项目代码

现在我们将看到“使用 Pygame 在 Python 中实现的 Flappy Bird”项目的完整代码片段。

文件:main.py

输出

图片 1:Flappy Bird 游戏

Flappy Bird Game using PyGame in Python

图片 2:游戏正在运行

Flappy Bird Game using PyGame in Python

图片 3:游戏结束

Flappy Bird Game using PyGame in Python