【Python】使用Pygame做一个Flappy bird小游戏(三)
最终效果:
1. 添加随机管道
本节文章介绍如何在游戏中添加随机生成的管道。下面我们来理一理思路。
玩过Flappy bird的同学都知道,这个游戏随机生成长短不一的上下管道,上下管道之间存在着一定间距,并且每隔一定距离就会有新的管道生成。管道素材的长度当然是固定的,所以我们随机生成管道的坐标y来实现随机生成一定长度的管道。下面我们来算一算如何计算两个管道之间的距离。
1.1 上下管坐标关系
整个窗口的高度是512像素。我们设两个管道之间的距离为50像素。管道图像的高度为320像素。
因为y值坐标对应的是图像的上端,所以上下管子之间的关系是:下管y坐标=上管y坐标+320+50
pipe_y的范围为-320~0,负的越多,上管长度越短。为了保证适当长度,我把pipe_y的范围设为-270~-20。
1.2 随机生成不同长度的管子
在这里我们使用random模块里的randint(-270,-10)生成一定范围内的随机整数并将整个整数赋给pipe_y。这样就实现了随机产生不同高度但间距相同的随机管道。
import random
pipe_y = random.randint(-270,-20)
为了让效果更明显,我添加了空格控制随机数生成。
效果如下:
1.3 让管道动起来
在游戏中,管道的运动和绿砖的运动速度是相同的,所以我们使用相同的速度,每帧移动距离仍然取决于每帧时间。管道的左边界对应着x值,管子本身的宽度为52像素。所以x值的范围应该是-52~288。
pipe_x = 288
#进入循环:
time_passed = clock.tick()
time_passed_seconds = time_passed / 1000
#计算每一帧的时间
distance_moved = time_passed_seconds * speed
pipe_x -=distance_moved
if(pipe_x<0):
pipe_x+=288
pipe_y = random.randint(-270,-20)
实现效果如下,为了效果更明显,我加快了管子的移动速度。
下面我们根据刚才的思路,把这些代码整合到之前的程序中。
首先是初始化,需要初始化的变量有pipe_y和pipe_x
pipe_y = random.randint(-270,-20)
pipe_x = 288
其次是由pipe_y(上管道坐标)计算出pipe_dy(下管道坐标)的值。
def calculation(pipe_y):
pipe_dy = pipe_y+370
return pipe_dy
然后修改游戏界面的start_updatexy()函数,将管道更新的部分加入。
def start_updatexy(time_passed_seconds,base_x,base_y,dirx):
distance_moved = time_passed_seconds * speed
bird_distance = time_passed_seconds * bird_speed
base_y = base_y + dirx*bird_distance
base_x -= distance_moved
pipe_x -=distance_moved
if(pipe_x<0):
pipe_x+=288
pipe_y = random.randint(-270,-20)
if base_x<-40:
base_x += 40
if 490>base_y >20:
dirx = 2
elif base_y >490:
dirx = 0
elif base_y <0:
base_y = 0
return base_x,base_y,dirx
最后修改一下显示界面,将管道绘制到窗口。
def start():
screen.blit(background,(0,0))
screen.blit(top,(pipe_x,pipe_y))
pipe_dy = calculation(pipe_y)
screen.blit(bottom,(pipe_x,pipe_dy))
screen.blit(green_base,(base_x,400))
1.4 添加多个管子
添加管道最重要的是把握两组管道之间的距离。首先我们假设管道移动的总长度为600,窗口(288像素)位于中间,得到第一个管道起始位置坐标为444,结束位置坐标为-156;但是第二个管道不能在一开始就出现,因此讲第二个管道第一周期起始位置设置为744,但结束位置为-156。
程序实现:
#首先初始化起始位置
pipe_x = 444
pipe_x1 = 744
#更改start()函数
def start():
screen.blit(background,(0,0))
screen.blit(top,(pipe_x,pipe_y))
pipe_dy = calculation(pipe_y)
screen.blit(bottom,(pipe_x,pipe_dy))
screen.blit(top,(pipe_x1,pipe_y1))
pipe_dy1 = calculation(pipe_y1)
screen.blit(bottom,(pipe_x1,pipe_dy1))
screen.blit(green_base,(base_x,400))
#更改start_updatexy()函数
pipe_x -=distance_moved
pipe_x1 -=distance_moved
if(pipe_x1<-156):
pipe_x1+=600
pipe_y1 = random.randint(-270,-20)
if(pipe_x<-156):
pipe_x+=600
pipe_y = random.randint(-270,-20)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- LinkedList - 92. Reverse Linked List II
- LinkedList - 328. Odd Even Linked List
- LinkedList - 25. Reverse Nodes in k-Group
- LinkedList - 24. Swap Nodes in Pairs
- LinkedList - 141. Linked List Cycle
- LinkedList - 206. Reverse Linked List
- Array - 188. Best Time to Buy and Sell Stock IV
- Tree - 112. Path Sum
- 首个无tricks的情况下将ResNet-50提高到80%+!CMU开源MEAL V2
- Tree - 257. Binary Tree Paths
- Tree - 226. Invert Binary Tree
- Tree - 101. Symmetric Tree
- Tree - 100. Same Tree
- Tree - 102. Binary Tree Level Order Traversal
- Dynamic Programming - 91. Decode Ways