Python 制作 Flappy Bird 飞鸟游戏源码深度解析

Python 制作 Flappy Bird 飞鸟游戏源码深度解析

🚀 不用懂 Pygame!3分钟做出能玩的 Flappy Bird 游戏!

装了 Python 却一脸懵,根本不会用 Pygame 做东西

你好不容易装好了 Python 和 Pygame,打开编辑器却不知道从哪下手,连“怎么让一个图形出现在屏幕上”都摸不着头脑,更别说做能玩的游戏——完全卡在“第一步”,连入门的门都找不到。

✅ 别想复杂的!我把所有代码都准备好了,你只需要2步无脑操作:

单击运行 → 直接玩

打开解压后的「FlappyBird」文件夹,找到名为 FlappyBird.py 的文件双击运行;
稍等片刻就会弹出游戏窗口,按空格键小鸟就能飞,撞到管道会自动重启,全程不用调试、不用改代码,5分钟就能玩上你自己做的 Flappy Bird 游戏!

下载完整代码包

我把能直接运行的 Flappy Bird 完整代码包整理好了,你只需要在软件内点击【一键运行】按钮,一键获取所有文件(包含配置、代码、文件夹模板),不用自己写一行代码、加一句注释。

项目简介

基于 Python + Pygame 的 Flappy Bird 练习项目,覆盖游戏循环、精灵管理、碰撞检测、资源加载与帧率控制等机制。

开发环境

三、开发环境

  • Python ==3.10
  • pygame>=2.5.0
  • IDE:建议 PyCharm / VSCode

项目结构

FlappyBird/ ├── cfg.py # 配置文件(常量、路径等) ├── FlappyBird.py # 游戏主程序入口 ├── modules/ # 游戏模块 │ ├── interfaces/ # 游戏界面(开始、结束) │ │ ├── startGame.py │ │ └── endGame.py │ └── sprites/ # 游戏精灵(小鸟、管道) │ ├── Bird.py │ └── Pipe.py └── resources/ # 游戏资源(图片、音频) ├── audios/ └── images/ 

源码目录

抠头助手:下载工具获取源码

安装与运行(一)

1.在「代码社区」中选择「游戏开发」:
代码社区
2.然后点击一键运行
游戏详情

操作与玩法

  • 按键:Space 上升;Esc 退出
  • 目标:穿过不断生成的管道,尽量获得更高分数

核心代码片段

初始化与主循环:

import pygame, sys clock = pygame.time.Clock() screen = pygame.display.set_mode((288,512))whileTrue:for event in pygame.event.get():if event.type== pygame.QUIT: pygame.quit(); sys.exit()elif event.type== pygame.KEYDOWN:if event.key in(pygame.K_SPACE, pygame.K_UP):pass pygame.display.update() clock.tick(60)

资源加载(数字图片):

import pygame, cfg number_images ={k: pygame.image.load(v).convert_alpha()for k, v in cfg.NUMBER_IMAGE_PATHS.items()}

像素级碰撞检测:

if pygame.sprite.collide_mask(bird, pipe): is_game_running =False

管道生成与加入精灵组:

from modules.sprites.Pipe import Pipe pos = Pipe.randomPipe(cfg, top_image) pipe_sprites.add(Pipe(image=top_image, position=pos['top'])) pipe_sprites.add(Pipe(image=bottom_image, position=pos['bottom']))

计分逻辑:

if pipe.rect.centerx < bird.rect.centerx andnot pipe.used_for_score: pipe.used_for_score =True score +=0.5

帧率控制:

clock.tick(cfg.FPS)

三、项目结构

项目的目录结构如下,清晰的分层有助于代码的管理和维护。

FlappyBird/ ├── cfg.py # 配置文件(常量、路径等) ├── FlappyBird.py # 游戏主程序入口 ├── modules/ # 游戏模块 │ ├── interfaces/ # 游戏界面(开始、结束) │ │ ├── startGame.py │ │ └── endGame.py │ └── sprites/ # 游戏精灵(小鸟、管道) │ ├── Bird.py │ └── Pipe.py └── resources/ # 游戏资源(图片、音频) ├── audios/ └── images/ 

详细机制解析

配置文件 (cfg.py)

cfg.py 文件主要用于存储游戏中的常量配置和资源路径,方便统一管理。

  • 屏幕设置:定义了屏幕的宽高 (SCREENWIDTH, SCREENHEIGHT) 和帧率 (FPS)。
  • 资源路径:使用 os.path.join 拼接路径获取图片和音频文件。
  • 游戏参数:如管道之间的空隙大小 (PIPE_GAP_SIZE)。

小鸟类 (modules/sprites/Bird.py)

Bird 类继承自 pygame.sprite.Sprite,是游戏的主角。

  • 初始化 (__init__)
    • 加载小鸟的三种状态图片(翅膀上扬、平展、下压)。
    • 初始化位置、速度(up_speed, down_speed)和状态标志(is_flapped)。
    • 利用 itertools.cycle 实现翅膀扇动的循环动画。
  • 更新状态 (update)
    • 物理模拟:根据 is_flapped 状态处理上升和下落。上升时速度递减,下落时速度递增(模拟重力)。
    • 边界检测:检查小鸟是否撞到天花板或地面。
    • 动画更新:通过计数器控制图片切换频率,实现扇翅膀的动画效果。
  • 动作控制
    • setFlapped():玩家点击时调用,给予小鸟向上的速度。
    • unsetFlapped():上升动力耗尽时调用,转为自由落体。

管道类 (modules/sprites/Pipe.py)

Pipe 类同样继承自 pygame.sprite.Sprite,负责管道的生成和属性。

  • 随机生成 (randomPipe)
    • 这是一个静态方法,计算管道的垂直位置。
    • 保证上下管道之间留有固定的空隙 (PIPE_GAP_SIZE)。
    • 返回上管道和下管道的坐标字典。

游戏界面 (modules/interfaces/)

  • 开始界面 (startGame.py)
    • 显示背景、地面、小鸟(带动画)和提示信息。
    • 通过 while True 循环等待玩家按下空格键或向上键开始游戏。
    • 地面会不断滚动,营造动态感。
开始游戏
  • 结束界面 (endGame.py)
    • 小鸟死亡后调用。
    • 显示最终得分和游戏画面。
    • 等待玩家按键重新开始或退出。
在这里插入图片描述

主程序 (FlappyBird.py)

这是游戏的入口,负责组装各个模块并运行主循环。

  1. 初始化 (initGame):初始化 Pygame 和音频混合器,设置屏幕大小。
  2. 资源加载:读取 cfg.py 中的路径,加载所有图片和声音资源。
  3. 游戏主循环 (main)
    • 事件处理:监听退出事件 (QUIT) 和按键事件 (KEYDOWN)。空格键触发小鸟飞翔。
    • 碰撞检测:使用 pygame.sprite.collide_mask 进行像素级精确碰撞检测(小鸟撞管道)。同时检测小鸟是否落地。
    • 游戏逻辑更新
      • 调用 bird.update() 更新小鸟位置。
      • 移动地面和管道,实现向左移动的效果。
      • 管道管理
        • 当管道移出屏幕左侧时移除。
        • 当管道移动到一定位置时生成新管道。
        • 计分:当小鸟通过管道(pipe.rect.centerx < bird.rect.centerx)且该管道未被计分过时,增加分数。
    • 画面渲染:按照背景 -> 管道 -> 地面 -> 分数 -> 小鸟 的顺序绘制画面 (screen.blit)。
    • 帧率控制:使用 clock.tick(cfg.FPS) 锁定游戏帧率。

Read more

Effective Modern C++ 条款37:使std::thread在所有路径最后都不可结合

Effective Modern C++ 条款37:使std::thread在所有路径最后都不可结合

Effective Modern C++ 条款37:使std::thread在所有路径最后都不可结合 * 引言:线程生命周期的关键问题 * 线程的两种状态:可结合与不可结合 * 可结合(Joinable)状态的特征 * 不可结合(Unjoinable)状态的四种情况 * 为什么可结合性如此重要? * 两种被拒绝的替代方案 * RAII拯救方案:ThreadRAII类 * ThreadRAII实现详解 * 关键设计决策 * 实际应用案例 * 高级讨论:何时选择join或detach * 性能考量与最佳实践 * 结论:让线程管理无忧 BiliBili上对应的视频为:https://www.bilibili.com/video/BV1iZZgBiE9j 引言:线程生命周期的关键问题 在多线程程序设计中,std::thread的管理是一个看似简单实则暗藏玄机的话题。想象一下,你精心设计的并发程序在大多数情况下运行良好,却在某些边缘情况下突然崩溃——这正是许多开发者在使用原生线程时遇到的噩梦场景。本文将深入探讨std::thread对象

By Ne0inhk
《C++ 动态规划》第001-002题:第N个泰波拉契数,三步问题

《C++ 动态规划》第001-002题:第N个泰波拉契数,三步问题

🔥个人主页:Cx330🌸 ❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》 《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔 《Git深度解析》:版本管理实战全解 🌟心向往之行必能至 🎥Cx330🌸的简介: 目录 前言: 01.第N个泰波拉契数 算法原理(动态规划): 思路: 解法代码(C++): 博主手记(字体还请见谅哈): 02.三步问题 算法原理(动态规划): 思路: 解法代码(C++): 博主手记(字体还请见谅哈): 结尾: 前言: 聚焦算法题实战,系统讲解三大核心板块:“精准定位最优解”——优选算法,“简化逻辑表达,系统性探索与剪枝优化”——递归与回溯,“以局部最优换全局高效”——贪心算法,讲解思路与代码实现,帮助大家快速提升代码能力 01.

By Ne0inhk
【C++】AVL树的底层以及实现

【C++】AVL树的底层以及实现

个人主页 文章目录 * ⭐一、AVL树的概念 * 🎉二、AVL树的性质 * 🏝️三、AVL树的实现 * 1. 树的基本结构 * 2. 树的插入 * 3. 树的旋转 * • 左单旋 * • 右单旋 * • 左右双旋 * • 右左双旋 * 🎡四、AVL树的其它功能 * 1. 树的查找 * 2. 树的遍历 * 3. 树的高度 * 4. 树的大小 * 🚀五、总结 * 1. AVL树的优缺点 * 2. 完整代码 ⭐一、AVL树的概念 AVL树是一种高度平衡的平衡二叉树,相比于搜索二叉树,它的特点在于左右子树都为AVL树且树的高度差的绝对值不超过1。 这里我们会引入一个新的概念叫做平衡因子。平衡因子也就是左右子树的高度差,我们可以通过平衡因子方便我们后续去观察和控制树是否平衡。 🎉二、AVL树的性质 AVL树主要有三大性质: 1.每棵树的左右子树都是AVL树。 2.左子树和右子树的高度之差的绝对值不超过1。 3.

By Ne0inhk
Java选择结构全解析:if与switch实战

Java选择结构全解析:if与switch实战

1.选择结构:根据条件,选择执行某一部分代码 (1).单分支if选择结构 执行规则:判断条件,如果条件为true,执行{}中的代码块m,执行完代码块结束if结构,继续往下执行if结构后面的代码,如果条件为false,直接跳过if结构,执行if结构后面的代码。注意事项:条件不管是多么简单还是多么复杂,结果都只能是一个布尔值,要么为true,要么为false。 import java.util.Scanner; public class Demo12 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入一个整数"); int num = scanner.nextInt(

By Ne0inhk