python带你成功复刻热门手机游戏——飞翔的小鸟
前言
大家早好、午好、晚好吖 ❤ ~欢迎光临本文章

飞翔的小鸟(游戏英文名:Flappy Bird)

一款由越南独立开发者开发的手机游戏,是之前非常流行的一款手机游戏
小游戏目标:让小鸟穿过管子,不要碰到任何物体,挑战更远距离

今天,就让我们一起用python来复刻一下这款游戏吧!!!
完整源码、素材皆可点击文章下方名片获取此处跳转
环境使用:
-
Python 3.8
–> 解释器 <执行python代码>
-
Pycharm
–> 编辑器 <写python代码的>
所需素材
音效素材

图片素材

效果展示


背景啊其他素材啊也是可以修改的
给你们看看博主魔改的背景

代码展示
(完整源码、素材皆可点击此处+获取)
‘’‘配置文件’‘’
导入模块
import os
# FPS
FPS = 60
屏幕
SCREENWIDTH = 288
SCREENHEIGHT = 512
管道之间的空隙
PIPE_GAP_SIZE = 100
图片
NUMBER_IMAGE_PATHS = {'0': os.path.join(os.getcwd(), 'resources/images/0.png'),'1': os.path.join(os.getcwd(), 'resources/images/1.png'),'2': os.path.join(os.getcwd(), 'resources/images/2.png'),'3': os.path.join(os.getcwd(), 'resources/images/3.png'),'4': os.path.join(os.getcwd(), 'resources/images/4.png'),'5': os.path.join(os.getcwd(), 'resources/images/5.png'),'6': os.path.join(os.getcwd(), 'resources/images/6.png'),'7': os.path.join(os.getcwd(), 'resources/images/7.png'),'8': os.path.join(os.getcwd(), 'resources/images/8.png'),'9': os.path.join(os.getcwd(), 'resources/images/9.png')
}
BIRD_IMAGE_PATHS = {'red': {'up': os.path.join(os.getcwd(), 'resources/images/redbird-upflap.png'),'mid': os.path.join(os.getcwd(), 'resources/images/redbird-midflap.png'),'down': os.path.join(os.getcwd(), 'resources/images/redbird-downflap.png')},'blue': {'up': os.path.join(os.getcwd(), 'resources/images/bluebird-upflap.png'),'mid': os.path.join(os.getcwd(), 'resources/images/bluebird-midflap.png'),'down': os.path.join(os.getcwd(), 'resources/images/bluebird-downflap.png')},'yellow': {'up': os.path.join(os.getcwd(), 'resources/images/yellowbird-upflap.png'),'mid': os.path.join(os.getcwd(), 'resources/images/yellowbird-midflap.png'),'down': os.path.join(os.getcwd(), 'resources/images/yellowbird-downflap.png')}
}
BACKGROUND_IMAGE_PATHS = {'day': os.path.join(os.getcwd(), 'resources/images/background-day.png'),'night': os.path.join(os.getcwd(), 'resources/images/background-night.png')
}
PIPE_IMAGE_PATHS = {'green': os.path.join(os.getcwd(), 'resources/images/pipe-green.png'),'red': os.path.join(os.getcwd(), 'resources/images/pipe-red.png')
}
OTHER_IMAGE_PATHS = {'gameover': os.path.join(os.getcwd(), 'resources/images/gameover.png'),'message': os.path.join(os.getcwd(), 'resources/images/message.png'),'base': os.path.join(os.getcwd(), 'resources/images/base.png')
}
音频路径
AUDIO_PATHS = {'die': os.path.join(os.getcwd(), 'resources/audios/die.wav'),'hit': os.path.join(os.getcwd(), 'resources/audios/hit.wav'),'point': os.path.join(os.getcwd(), 'resources/audios/point.wav'),'swoosh': os.path.join(os.getcwd(), 'resources/audios/swoosh.wav'),'wing': os.path.join(os.getcwd(), 'resources/audios/wing.wav')
}
主运行文件
导入模块
import cfg
import sys
import random
import pygame
from modules import *
‘’‘游戏初始化’‘’
def initGame():pygame.init()pygame.mixer.init()screen = pygame.display.set_mode((cfg.SCREENWIDTH, cfg.SCREENHEIGHT))pygame.display.set_caption('Bird Q群261823976')return screen
‘’‘显示当前分数’‘’
def showScore(screen, score, number_images):digits = list(str(int(score)))width = 0for d in digits:width += number_images.get(d).get_width()offset = (cfg.SCREENWIDTH - width) / 2for d in digits:screen.blit(number_images.get(d), (offset, cfg.SCREENHEIGHT*0.1))offset += number_images.get(d).get_width()
‘’‘主函数’‘’
def main():screen = initGame()# 加载必要的游戏资源# --导入音频sounds = dict()for key, value in cfg.AUDIO_PATHS.items():sounds[key] = pygame.mixer.Sound(value)# --导入数字图片number_images = dict()for key, value in cfg.NUMBER_IMAGE_PATHS.items():number_images[key] = pygame.image.load(value).convert_alpha()# --管道pipe_images = dict()pipe_images['bottom'] = pygame.image.load(random.choice(list(cfg.PIPE_IMAGE_PATHS.values()))).convert_alpha()pipe_images['top'] = pygame.transform.rotate(pipe_images['bottom'], 180)# --小鸟图片bird_images = dict()for key, value in cfg.BIRD_IMAGE_PATHS[random.choice(list(cfg.BIRD_IMAGE_PATHS.keys()))].items():bird_images[key] = pygame.image.load(value).convert_alpha()# --背景图片backgroud_image = pygame.image.load(random.choice(list(cfg.BACKGROUND_IMAGE_PATHS.values()))).convert_alpha()# --其他图片other_images = dict()for key, value in cfg.OTHER_IMAGE_PATHS.items():other_images[key] = pygame.image.load(value).convert_alpha()# 游戏开始界面game_start_info = startGame(screen, sounds, bird_images, other_images, backgroud_image, cfg)# 进入主游戏score = 0bird_pos, base_pos, bird_idx = list(game_start_info.values())base_diff_bg = other_images['base'].get_width() - backgroud_image.get_width()clock = pygame.time.Clock()# --管道类pipe_sprites = pygame.sprite.Group()for i in range(2):pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top'))pipe_sprites.add(Pipe(image=pipe_images.get('top'), position=(cfg.SCREENWIDTH+200+i*cfg.SCREENWIDTH/2, pipe_pos.get('top')[-1])))pipe_sprites.add(Pipe(image=pipe_images.get('bottom'), position=(cfg.SCREENWIDTH+200+i*cfg.SCREENWIDTH/2, pipe_pos.get('bottom')[-1])))# --bird类bird = Bird(images=bird_images, idx=bird_idx, position=bird_pos)# --是否增加pipeis_add_pipe = True# --游戏是否进行中is_game_running = Truewhile is_game_running:for event in pygame.event.get():if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):pygame.quit()sys.exit()elif event.type == pygame.KEYDOWN:if event.key == pygame.K_SPACE or event.key == pygame.K_UP:bird.setFlapped()sounds['wing'].play()# --碰撞检测for pipe in pipe_sprites:if pygame.sprite.collide_mask(bird, pipe):sounds['hit'].play()is_game_running = False# --更新小鸟boundary_values = [0, base_pos[-1]]is_dead = bird.update(boundary_values, float(clock.tick(cfg.FPS))/1000.)if is_dead:sounds['hit'].play()is_game_running = False# --移动base实现小鸟往前飞的效果base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg)# --移动pipe实现小鸟往前飞的效果flag = Falsefor pipe in pipe_sprites:pipe.rect.left -= 4if pipe.rect.centerx < bird.rect.centerx and not pipe.used_for_score:pipe.used_for_score = Truescore += 0.5if '.5' in str(score):sounds['point'].play()if pipe.rect.left < 5 and pipe.rect.left > 0 and is_add_pipe:pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top'))pipe_sprites.add(Pipe(image=pipe_images.get('top'), position=pipe_pos.get('top')))pipe_sprites.add(Pipe(image=pipe_images.get('bottom'), position=pipe_pos.get('bottom')))is_add_pipe = Falseelif pipe.rect.right < 0:pipe_sprites.remove(pipe)flag = Trueif flag: is_add_pipe = True# --绑定必要的元素在屏幕上screen.blit(backgroud_image, (0, 0))pipe_sprites.draw(screen)screen.blit(other_images['base'], base_pos)showScore(screen, score, number_images)bird.draw(screen)pygame.display.update()clock.tick(cfg.FPS)endGame(screen, sounds, showScore, score, number_images, bird, pipe_sprites, backgroud_image, other_images, base_pos, cfg)
‘’‘run’‘’
if __name__ == '__main__':while True:main()
代码太多,我就没放完啦,完整源码、素材皆可点击文章下方名片获取此处跳转
尾语 💝
好了,今天的分享就差不多到这里了!
完整代码、更多资源、疑惑解答直接点击下方名片自取即可。
对下一篇大家想看什么,可在评论区留言哦!看到我会更新哒(ง •_•)ง
喜欢就关注一下博主,或点赞收藏评论一下我的文章叭!!!

相关文章:
python带你成功复刻热门手机游戏——飞翔的小鸟
前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 飞翔的小鸟(游戏英文名:Flappy Bird) 一款由越南独立开发者开发的手机游戏,是之前非常流行的一款手机游戏 小游戏目标:让小鸟穿过管子,不要碰到任何物体…...
YOLOv8初体验:检测、跟踪、模型部署
安装 YOLOv8有两种安装方式,一种是直接用pip命令安装: pip install ultralytics另外一种是通过源码安装: git clone https://github.com/ultralytics/ultralytics cd ultralytics pip install -e .[dev]安装完成后就可以通过yolo命令在命令…...
Vue 监听(watch handler)
普通监听 缺点:不能深度监听(对象属性的改变),刷新或首次加载不能执行。 watch: { carts: function (val, oldVal) { console.log(new: %s, old: %s, val, oldVal) } } 高级监…...
前端代码质量-圈复杂度原理和实践
1. 导读 你们是否也有过下面的想法? 重构一个项目还不如新开发一个项目…这代码是谁写的,我真想… 你们的项目中是否也存在下面的问题? 单个项目也越来越庞大,团队成员代码风格不一致,无法对整体的代码质量做全面的…...
汽车微控制器芯片F280039CPZRQ1、F280039CSPM、F280039CSPN规格参数
F280039CPZRQ1、F280039CSPM、F280039CSPN是C2000实时微控制器系列中的一款器件。C2000微控制器是可扩展、超低延迟器件,旨在提高电力电子设备的效率,包括但不限于:高功率密度、高开关频率,并支持使用 GaN和SiC技术。F280039CPZRQ…...
禾观科技三面经历
智力题 一天中时针和分钟重合多少次 由于时针1分钟旋转的圆心角度数为0.5度(30/60min) 分针1分钟旋转的圆心角度为6度(30/5min) 当两针第一次重合时后到第二次重合,分针比时针多旋转过的圆心角度数为360度。(快的比慢的多跑一圈,也就是360度) 这类问题实际上是分针追时…...
Spring Boot 实现接口幂等性的 4 种方案
一、什么是幂等性 幂等是一个数学与计算机学概念,在数学中某一元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同。 在计算机中编程中,一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数或幂…...
Android Studio开发APP
1.下载Android Studio 官网下载:Android Studio for Window ... 百度云下载:android-studio-bundle-141.1903250-windows.exe Android Studio 是谷歌推出的一个Android集成开发工具,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的 Android 开发工具用…...
Spring之实例化Bean _ @Resource和@Autowired实现原理(3)
目录 1. 搜集注解信息 applyMergedBeanDefinitionPostProcessor(*) 2. 将实例化的Bean放入3级缓存中 addSingletonFactory(***)为循环依赖做准备 3. 根…...
华为HCIE学习之Openstack Cinder组件(cinder对接glusterfs)
文章目录一、MQ的作用二、cinder架构图三、各组件的作用四、cinder对接glusterfs一、MQ的作用 服务内各组件交互通过MQ进行 二、cinder架构图 IET,Linux用软件做存储,CNA识别过去就是IETTGT,物理存储,CNA识别过去就是TGT 三、…...
关于Go语言的底层,你想知道的都在这里!
文章目录1. GoLang语言1.1 Slice1.2 Map1.3 Channel1.4 Goroutine1.5 GMP调度1.6 垃圾回收机制1.7 其他知识点2. Web框架Gin和微服务框架Micro2.1 Gin框架2.2 Micro框架2.3 Viper2.4 Swagger2.5 Zap2.6 JWT文章字数大约1.95万字,阅读大概需要65分钟,建议…...
每日一问-ChapGPT-20230308-关于技术与思考的问题
文章目录每日一问-ChapGPT系列起因每日一问-ChapGPT-20230308-关于技术与思考的问题matplotlib_venn 中 venn2函数调用时,subsets传入A list (or a tuple) containing two set objects,怎么理解plt.pie() 包含哪些参数,以及每个参数的意义mat…...
Oracle表分区的创建、新增、拆分
Oracle中为了方便管理、查询数据当数据量大于500w或者2G时最好用分区表,常见的一种是使用时间作为分区。 分区表添加新的分区有 2 种情况: (1) 原分区里边界是 maxvalue 或者 default。 这种情况下,我们需要把边界分区 drop 掉,加…...
如何快速升级Java 8 到Java11
老板让我把一个项目从 Java 8 迁移到 Java 11,我该怎么办呢? 最简单的办法,当然是直接强行升级,遇到一个错就改一个错,别看它 low,但是对于一个小型且非核心的项目来说,已经足够了。 当然,对于比较重要的项目,且代码行数不少的情况,最标准的姿势就是对着官方文档进…...
内卷把同事逼成了“扫地僧”,把Git上所有面试题整理成足足24W字Java八股文
互联网大厂更多的是看重学历还是技术?毫无疑问,是技术,技术水平相近的情况下,肯定学历高/好的会优先一点,这点大家肯定都理解。说实话,学弟学妹们找工作难,作为面试官招人也难呀!&am…...
【计组】主存储器有关知识梳理
一、主存储器 主存储器可以直接和CPU进行通信,但是只能保存临时数据,在断电后数据就消失。还有一个特点是,主存储器的容量小,速度快,造价高。 1.构成 2.主存中存储体的构造 最小的存储单位是存储元,存储元…...
QT对象树
对象模型(对象树) 在Qt中创建对象的时候会提供一个Parent对象指针,下面来解释这个parent到底是干什么的。 l QObject是以对象树的形式组织起来的。 n 当你创建一个QObject对象时,会看到QObject的构造函数接收一个QObject指针作…...
什么是B+树
B树是一种树数据结构。B树索引是B树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。 先来了解一下什么是索引? 一、索引 数据都是存储在硬盘上的,查询数据不可避免的需要进行IO操作。 索引是一种数据结构,…...
【Unity游戏破解】外挂原理分析
文章目录认识unity打包目录结构游戏逆向流程Unity游戏攻击面可被攻击原因mono的打包建议方案锁血飞天无限金币攻击力翻倍以上统称内存挂透视自瞄压枪瞬移内购破解Unity游戏防御开发时注意数据安全接入第三方反作弊系统外挂检测思路狠人自爆实战查看目录结构用il2cpp dumper例子…...
windows 关闭指定端口进程
1、首先打开cmd 注意要用管理员身份打开cmd,否则可能出现无权访问的提示。 2、输入以下命令(以端口号9098为例) 查看端口信息 netstat -ano | findstr 90983、输入以下命令关闭这个进程 taskkill -PID 39716 -F...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
