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...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...