140行Python代码实现Flippy Bird
140行代码实现Flippy Bird
话说这游戏中文名叫什么来着,死活想不起来了,算了话不多说,140行实现小游戏系列第二章,依然是简单小游戏,与数独游戏相比,在游戏界面显示上更难一些,但是在逻辑方面更简单一些,需要处理的无非是速度、加速度、时间、位置、碰撞检测,界面方面则要实现整个动态的显示;
依旧在最后会给出全部代码,不过依然可以从我的Github仓库Fork下来直接运行,图片资源也在那里,have fun.
运行以及玩法:
- python main.py运行游戏;
- 鼠标点击是暂停,再点击则是继续;
- 空格键进行跳跃;
后续扩展:
- 管道的出现可以更加随机,包括位置和长度等,目前是很简单的方式出现;
- 游戏速度可以越来越快,目前是固定的;
- 小鸟的自由落体速度、跳跃速度等需要优化,目前操作感觉没有那么流畅;
- 增加计分系统、开始、重来等按钮;
小鸟图,需要的自取

游戏截图
进行中

暂停时

死亡时

关键代码分析
随时间移动的管道
可以看到对于这个游戏,实际上移动的是管道而不是小鸟,因此这里主要是处理管道绘制的位置变化,以及整个一个循环的过程,如果屏幕上显示的管道是N个,那么可以想象是N+2个管道在不停地转圈圈出现在我们的界面上就行了;
tunnel_list = [x-speed if x-speed>-200 else 2100 for x in tunnel_list ]
def draw_tunnel():
for x in tunnel_list:
pygame.draw.rect(screen,COLORS['darkgreen'],(x,0,100,350),0)
pygame.draw.rect(screen,COLORS['darkgreen'],(x+100,550,100,350),0)
自由落体的小鸟和点击空格后跳起
不操作的情况下,小鸟的上下移动是做自由落体,也就是越来越快的下降的过程,而当我们点击空格进行跳跃后,实际上改变的就是小鸟的当前速度,因此小鸟会向上越来越慢的跳跃,直到速度为0后,继续下降,符合基本的物理规则;
G = 9.8*30 # g
JUMP_V = -300
bird_x,bird_y = 700,450
bird_v = 0
if not jump:
bird_v += G*frame
else:
bird_v = JUMP_V
jump = False
bird_y += frame*bird_v
def draw_bird():
screen.blit(birdImg,[bird_x,bird_y])
碰撞检测
检测小鸟是否碰到管道或者是掉到地上,这么说是只无脚鸟咯,实际上就是检测两个矩形是否有重叠的部分;
def rect_cover(rect1,rect2,up=True):
# bird
left_up1 = (rect1[0],rect1[1])
left_down1 = (rect1[0],left_up1[1]+rect1[3])
right_up1 = (left_up1[0]+rect1[2],rect1[1])
right_down1 = (left_up1[0]+rect1[2],left_up1[1]+rect1[3])
# tunnel
left_up2 = (rect2[0],rect2[1])
left_down2 = (rect2[0],left_up2[1]+rect2[3])
right_up2 = (left_up2[0]+rect2[2],rect2[1])
right_down2 = (left_up2[0]+rect2[2],left_up2[1]+rect2[3])
# check
if (left_up2[0]<=right_up1[0]<=right_up2[0]): # x,肯定是右侧线接触,因此判断bird的right即可
if up and (left_up2[1]<=right_up1[1]<=left_down2[1]):
return True
elif (not up) and (left_up2[1]<=right_down1[1]<=left_down2[1]):
return True
return False
pygame绘制rect不支持透明度下实现的透明图层
看到,实际上是借助了Surface,将其设置为想要的透明度后blit到我们的screen上即可,直接draw rect是不支持RGBA的A设置alpha的,不知道为啥这么坑爹的设计;
def draw_dead():
s = pygame.Surface(SIZE, pygame.SRCALPHA)
s.fill((255,255,255,240))
screen.blit(s, (0,0))
txt = font120.render('YOU DEAD',True,COLORS['black'])
x,y = 450,400
screen.blit(txt,(x,y))
全部代码
import sys
import pygame
from pygame.color import THECOLORS as COLORS
def draw_background():
# white background
screen.fill(COLORS['lightblue'])
pygame.draw.rect(screen,COLORS['black'],(-100,902,3000,200),5)
def draw_tunnel():
for x in tunnel_list:
pygame.draw.rect(screen,COLORS['darkgreen'],(x,0,100,350),0)
pygame.draw.rect(screen,COLORS['darkgreen'],(x+100,550,100,350),0)
def draw_bird():
screen.blit(birdImg,[bird_x,bird_y])
def draw_context():
txt = font50.render('Count time: '+str(int(count_time))+' S',True,COLORS['black'])
x,y = 10,920
screen.blit(txt,(x,y))
def draw_pause():
s = pygame.Surface(SIZE, pygame.SRCALPHA)
s.fill((255,255,255,220))
screen.blit(s, (0,0))
txt = font120.render('PAUSE',True,COLORS['darkgray'])
x,y = 550,400
screen.blit(txt,(x,y))
def draw_dead():
s = pygame.Surface(SIZE, pygame.SRCALPHA)
s.fill((255,255,255,240))
screen.blit(s, (0,0))
txt = font120.render('YOU DEAD',True,COLORS['black'])
x,y = 450,400
screen.blit(txt,(x,y))
def rect_cover(rect1,rect2,up=True):
# bird
left_up1 = (rect1[0],rect1[1])
left_down1 = (rect1[0],left_up1[1]+rect1[3])
right_up1 = (left_up1[0]+rect1[2],rect1[1])
right_down1 = (left_up1[0]+rect1[2],left_up1[1]+rect1[3])
# tunnel
left_up2 = (rect2[0],rect2[1])
left_down2 = (rect2[0],left_up2[1]+rect2[3])
right_up2 = (left_up2[0]+rect2[2],rect2[1])
right_down2 = (left_up2[0]+rect2[2],left_up2[1]+rect2[3])
# check
if (left_up2[0]<=right_up1[0]<=right_up2[0]): # x,肯定是右侧线接触,因此判断bird的right即可
if up and (left_up2[1]<=right_up1[1]<=left_down2[1]):
return True
elif (not up) and (left_up2[1]<=right_down1[1]<=left_down2[1]):
return True
return False
def check_dead():
bird_rect = (bird_x,bird_y,70,70)
if bird_rect[1]+bird_rect[3]>900:
return True
for x in tunnel_list:
up_rect = (x,0,100,350)
down_rect = (x+100,550,100,350)
if rect_cover(bird_rect,up_rect) or rect_cover(bird_rect,down_rect,up=False):
return True
return False
if __name__ == "__main__":
# init pygame
pygame.init()
# contant
SIZE = [1500,1000]
font50 = pygame.font.SysFont('Times', 50)
font120 = pygame.font.SysFont('Times', 120)
G = 9.8*30 # g
JUMP_V = -300
# brid
birdPath = 'bird.png'
birdImg = pygame.image.load(birdPath)
# tunnel
tunnel_list = [100,600,1100,1600,2100]
# create screen 500*500
screen = pygame.display.set_mode(SIZE)
# variable parameter
bird_x,bird_y = 700,450
bird_v = 0
count_time = 0
# level
speed = 5
frame = 0.02
# main loop
running = True
pause = False
jump = False
dead = False
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
break
elif event.type == pygame.MOUSEBUTTONDOWN:
pause = not pause
elif event.type == pygame.KEYUP:
if chr(event.key) == ' ':
jump = True
# update data
if not pause and not dead:
count_time += frame
tunnel_list = [x-speed if x-speed>-200 else 2100 for x in tunnel_list ]
if not jump:
bird_v += G*frame
else:
bird_v = JUMP_V
jump = False
bird_y += frame*bird_v
# background
draw_background()
# tunnel
draw_tunnel()
# choose item
draw_bird()
# point
draw_context()
# pause
if not dead and pause:
draw_pause()
# dead
if dead:
draw_dead()
# flip
pygame.display.flip()
# pause 20ms
pygame.time.delay(int(frame*1000))
# check win or not
if check_dead():
#print('You dead, dumb ass!!!')
#break
dead = True
pygame.quit()
最后
数独和FlippyBird都在这里,欢迎大家Fork下来直接运行,后续会不定期更新其他小游戏,目前以简单的动作小游戏、棋牌类为主,想到啥做啥,或者大家有什么想做想玩的可以评论区告诉我哈,搞得定的我会尽快完成;
最后的最后
大家可以到我的Github上看看有没有其他需要的东西,目前主要是自己做的机器学习项目、Python各种脚本工具、有意思的小项目以及Follow的大佬、Fork的项目等:
https://github.com/NemoHoHaloAi
140行Python代码实现Flippy Bird的更多相关文章
- 一个 11 行 Python 代码实现的神经网络
一个 11 行 Python 代码实现的神经网络 2015/12/02 · 实践项目 · 15 评论· 神经网络 分享到:18 本文由 伯乐在线 - 耶鲁怕冷 翻译,Namco 校稿.未经许可,禁止转 ...
- 200行Python代码实现2048
200行Python代码实现2048 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面 ...
- 40多行python代码开发一个区块链。
40多行python代码开发一个区块链?可信吗?我们将通过Python 2动手开发实现一个迷你区块链来帮你真正理解区块链技术的核心原理.python开发区块链的源代码保存在Github. 尽管有人认为 ...
- 15行python代码,帮你理解令牌桶算法
本文转载自: http://www.tuicool.com/articles/aEBNRnU 在网络中传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送,令牌桶算法 ...
- 30行Python代码实现人脸检测
参考OpenCV自带的例子,30行Python代码实现人脸检测,不得不说,Python这个语言的优势太明显了,几乎把所有复杂的细节都屏蔽了,虽然效率较差,不过在调用OpenCV的模块时,因为模块都是C ...
- 21行python代码实现拼写检查器
引入 大家在使用谷歌或者百度搜索时,输入搜索内容时,谷歌总是能提供很好的拼写检查,比方你输入 speling,谷歌会立即返回 spelling. 前几天,看到http://norvig.com/spe ...
- vim中凝视多行python代码
在vim中凝视多行python代码比較麻烦,主要由下面几种方法: (1)将须要凝视的代码以文档字符串的形式呈现 (2)将须要凝视的代码以函数的形式呈现 (3)使用vim自身快捷键 我们主要使用第三种方 ...
- 几行python代码解决相关词联想
日常生活中经常会遇到相关词联想的问题,也就是说输入一个词汇,把相关的词汇查询出来,听起来这个做法也不是太难,但如何去积累那么多的词汇,再用好的算法将相关内容联系起来,本身还是不简单的.笔者认为最简单的 ...
- 10 行 Python 代码实现模糊查询/智能提示
10 行 Python 代码实现模糊查询/智能提示 1.导语: 模糊匹配可以算是现代编辑器(如 Eclipse 等各种 IDE)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的 ...
随机推荐
- 关于Sprites的一些理解
今天做测试,遇到一道选择题. 瞬间一脸懵逼,sprites是什么?通过对各选项的分析,大致明白了几点:1.它是css属性.2.它与图片有关.3.它是背景图片.然后就选了一个大概不靠谱的,成功的选错了. ...
- python正则表达式之re模块方法介绍
python正则表达式之re模块其他方法 1:search(pattern,string,flags=0) 在一个字符串中查找匹配 2:findall(pattern,string,flags=0) ...
- 学习Java技术哪家强
https://github.com/CyC2018/CS-Notes https://github.com/Snailclimb/JavaGuide SpringBoot 之 配置文件优先级 htt ...
- Linux基本操作及常用指令
今天复习了下Linux的基本操作及常用指令,上学期大数据云计算课一直也在用linux系统还是比较熟悉的,并在centos6.7虚拟机上部署了前几天做的web项目,了解了Nginx的反向代理与负载均衡, ...
- 最全Redis基础知识
NoSQL概述 什么是NoSQL NoSQL不仅仅是SQL,它是Not Only SQL 的缩写,也是众多非关系型数据库的统称NoSQL和关系型数据库一样,也是用来存储数据的仓库. 为什么需要NoSQ ...
- 蓝牙技术 A2DP AVRCP BlueZ
BlueZ 做为 linux 标准的协议栈,提供非常多的 profile ,各种的支持,ble , 蓝牙网络,文件传输,a2dp 音频传输. A2DP——Advanced Audio Distribu ...
- video标签加载视频有声音却黑屏
问题 昨天用户上传了一个视频文件,然而发现虽然有声音但是黑屏. 解释 因为原视频的编码是用 mp4v 格式的,它需要专用的解码器.而 chrome 并不支持,所以无法播放. 然后如果用转码功能转成用 ...
- chrome 和 chromeDriver
在写selenium的时候,发现很简单的case也报错 package com.lv.test; import org.junit.Test; import org.openqa.selenium.W ...
- Drf(DjangoRestFramewok)
第一部分 问题 1.前后端分离? vue.js 后端给前段返回json数据 2.移动端盛行. app 后端给app返回json数据 3.PC端应用? crm项目,前段后端一起写,运行在浏览器上. 一般 ...
- Linux 文件系统及 ext2 文件系统
linux 支持的文件系统类型 Ext2: 有点像 UNIX 文件系统.有 blocks,inodes,directories 的概念. Ext3: Ext2 的加强版,添加了日志 ...