gomoblie flappy 源码分析:游戏逻辑
本文主要讨论游戏规则逻辑,具体绘制技术请参看相关文章:
gomoblie flappy 源码分析:图片素材和大小的处理
http://www.cnblogs.com/ghj1976/p/5222289.html
绘制时间间隔控制
绘制是按照 60 FPS 的节奏绘制的(即每秒钟 60 帧), FPS : frames per second(帧率)
代码中的控制注意是通过 golang.org/x/mobile/exp/sprite/clock 下的 Time 控制的。
- Time实际是 int32 的别名
- type Time int32
- 应用程序初始化好,可以开始绘图时 这个值初始化成 FPS 的时间间隔。
这里 now 计算的是到现在为止, 有多少个 1/60 秒(time for 60 FPS)。
然后在 game.update 中传入
只有满足 FPS 时才重新计算, 否则不重新计算。
g.lastCale 也是 clock.Time 类型。
至于 paint.Event 事件被调起的频率,请参考这篇文字: http://www.cnblogs.com/ghj1976/p/5230576.html
简单来说,屏幕分辨率为60Hz, 那每秒钟 scan 60 次, 每次轮到时,就是下面的逻辑。
场景绘制
整个场景是绘制在 19*16 个地砖的区域, 地鼠是 2*2 地砖大小, 每个地砖是 16pt*16pt。 这样绘图区域就是 304pt*256pt 。
要能在手机上显示下完整高度, 屏幕的高度需要是 305pt/72*2.54 = 10.76 cm , 宽度由于不足,可以显示部分,但是美观期间,不应该大于 256pt/72*2.54 = 9.03 cm ,否则会屏幕里有部分没有绘图。
注意, Android 设备的 pt 值,并不是精准的 1/72 英寸, 有关原因请看: http://www.cnblogs.com/ghj1976/p/5238193.html
整个绘制的逻辑如下图:
从上到下是逻辑顺序:
整个场景以 初始化速度为每 1/60 秒 1pt,每次增加 0.001 的速度在不断加速移动。
如下图, 每次 reset 游戏时, 卷轴速度为 1pt;
游戏没结束前, 每次加速 0.001,这样游戏卷轴越来越快, 难度越来越难。
每当卷轴距离超过一个瓷砖的长度, 触发产生新瓷砖的逻辑。
注意, g.scroll.x 这个值最大是一个瓷砖的长度, 再长就自动减去,见如下代码:
精灵的位置绘制
flappy 这个游戏有三类元素需要绘制,他们绘制的位置逻辑信息如下:
gopher 精灵的初始位置
gopher 的大小是 32pt*32pt , 它的位置代码是在下面函数中定义的:
- func (g *Game) Scene(eng sprite.Engine) *sprite.Node {
X轴坐标
gopher 的左上角点的x轴坐标是固定的: 2pt 的位置,计算公式如下:
- tileWidth*(gopherTile-1) + tileWidth/8
其中的参数说明如下:
- gopherTile: Gopher站在那块砖上,注意这是从0开始的索引,1代表第二块。 地鼠显示的位置,判断地鼠是否被撞死了、地鼠跳起来后在落地的位置等信息都依赖这个全局常量进行计算。
- tileWidth : 每块地砖的宽度。
从上可知,地鼠站在第一块地砖的 1/8 处。
Y轴坐标:
- 绘地鼠图的y轴坐标计算公式为: g.gopher.y - tileHeight + tileHeight/4
- g.gopher.y
- 游戏初始时,地鼠的 y 轴被定义在 0 这个位置。 func (g *Game) reset() {
- g.gopher.y = 0
- tileHeight 地砖的高度。
- 地鼠站的位置需要减去地砖的 3/4 的高度,这样看起来地鼠是站在草上。
- 注意:减去 3/4 的地砖高度,只是绘制的时候绘效果用的, 跟计算精灵的高度无关。
精灵跳起相关
每当有触屏事件或者空格键按下时,触发精灵跳起。
当这个动作发生时,如果精灵在地面, 则起跳加速度为 –5 ,
如果精灵在飞起状态, 则 加速度为 -1.5(这个每次蹦起只能触发一次,蹦起时用过一次后 g.gopher.flapped = true, 在落地时 g.gopher.flapped = false) 。
注意,不按时,加速度立即变成 0 。
而每次计算精灵信息时, 则需要根据重力减少 加速度, 重力的值为 0.1 。
按照这个逻辑, 如果只按一次的话, 最高能蹦 5+4.9+4.8+…+0.2+0.1 = 127.5 pt 高。 如果最牛操作,在蹦到顶点时再次按下,会再蹦起 1.5+1.4+1.3+…+0.2+0.1=12 pt
是否落地的判断
注意:绘制时,会在精灵高度上减去 3/4 的地砖高度,只是绘制的时候绘效果用的, 跟计算精灵的高度无关。而且绘制时,不管是不是在地面,都会减去的。
精灵死亡的判断
精灵是否死亡,是在背景转换时判断的,而不是精灵自身跳起、落地时判断的。
每次需要新加一块地砖时,先做地砖增加逻辑,然后判断是否死亡。
死亡后,卷轴速度逐步降低到停止。
- 当精灵撞到高于地砖 1/3 高度时,触发死亡。
- climbGrace = tileHeight / 3
精灵死亡的动画
每次完成判断死亡后, 精灵标志死亡,然后让精灵跳起做死亡动画,跳起速度是之前正常跳起速度的 1.5 倍。
精灵的跳起 y 轴变换逻辑跟之前一样,只是加速度变大。
显示时,显示死亡图片, 同时做死亡旋转动画。
具体的旋转动画, 先按照时间逐步放大,同时移动中心点,然后旋转,然后移动回之前坐标系。
从死亡开始, 4秒后 游戏 reset。
gomoblie flappy 源码分析:游戏逻辑的更多相关文章
- gomoblie flappy 源码分析:图片素材和大小的处理
flappy的源码可以在 https://github.com/golang/mobile 看到.具体在 https://github.com/golang/mobile/tree/master/ex ...
- 前端Vue 源码分析-逻辑层
Vue 源码分析-逻辑层 预期的效果: 监听input的输入,input在输入的时候,会触发 watch与computed函数,并且会更新原始的input的数值.所以直接跟input相关的处理就有3处 ...
- Spring JPA实现逻辑源码分析总结
1.SharedEntityManagerCreator: entitymanager的创建入口 该类被EntityManagerBeanDefinitionRegistrarPostProcesso ...
- 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象
前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...
- vscode源码分析【三】程序的启动逻辑,性能问题的追踪
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 启动追踪 代码文件:src\main.js 如果指定了特定的启动参 ...
- Springboot中mybatis执行逻辑源码分析
Springboot中mybatis执行逻辑源码分析 在上一篇springboot整合mybatis源码分析已经讲了我们的Mapper接口,userMapper是通过MapperProxy实现的一个动 ...
- YII 的源码分析(二)
上一篇简单分析了一下yii的流程,从创建一个应用,到屏幕上输出结果.这一次我来一个稍复杂一点的,重点在输出上,不再是简单的一行"hello world",而是要经过view(视图) ...
- bigworld源码分析(3)——dbMgr分析
dbMgr主要是玩家数据的读取和保存的,例如在bigworld源码分析(3)中,玩家在认证的时候,loginApp需要通过dbMgr来验证玩家数据是否合法,这就是针对玩家的账号数据进行查询.本篇中,我 ...
- Go Mobile 例子 audio 源码分析
看这个源码分析前,建议先看更简单地例子 basic 的源码分析(http://www.cnblogs.com/ghj1976/p/5183199.html), 一些基础知识本篇将不再提及. audio ...
随机推荐
- mysql将字符转换成数字
在操作mysql时,经常需要将字符转换成数字,这一步虽然简单,但不常用的话也很容易忘记,现将在网上找到的方法记录如下: 1.将字符的数字转成数字,比如'0'转成0可以直接用加法来实现例如:将pony表 ...
- 将war文件解压到指定目录
问:如何将.war文件解压到指定目录? 答:jar命令没有这样的选项. eg:将abc.war解压到当前文件夹? 答:进入目标文件即abc.war文件所在的文件夹,按住shift键并在该文件夹空白处点 ...
- Java自带工具jstack故障分析的一个案例
公司的一个web应用项目运行了很长一段时间,达半年之久,前段时间突然出现了服务不可用的情况,所有的请求都不可达,服务彻底挂了.查看tomcat进程还在,cpu使用率低,一时没找着问题,重启了服务.过了 ...
- DW(二):SqlServer PDW
当微软发布第一个SQL Server并行数据仓库R2时(SQL ServerParallel Data Warehouse,即PDW),已正式将产品的名称修改为分析服务平台(APS),但在一些非正式场 ...
- C++中的Overload、Override和Overwrite
在C++语言中有一组基础的概念一直都容易混淆:Overload.Override和Overwrite分别表示什么意思?下面把这三个概念整理一下: 1. Overload(重载) 重载的概念最好理解,在 ...
- Winform用匿名方法新建线程的方法
作用:1.将耗时的操作放在单独的线程,加快UI的响应速度.Thread t = new Thread(delegate() { parse.ParseDay(StockCode, FileName); ...
- [转]UOS 中的虚拟网络设备
随着网络技术,虚拟化技术的发展,越来越多的高级网络设备被加入了到了 Linux 中,这些设备在 UOS 中起到了广泛而关键的作用,包括 Open vSwitch.TAP 设备.Veth 设备等等,梳理 ...
- python使用random函数生成随机数
python使用random函数来生成随机数,常用的方法有: import random #生成0-1之间的数(不包括0和1) random.random() #生成1-5之间的随机整数(包括1和5) ...
- Python 处理多层嵌套列表
>>> movies =[ "the holy grail", 1975,"terry jones",91, ["graham ch ...
- 拒绝了对对象 '**' (数据库 'db',架构 'dbo')的 SELECT 权限
操作次数据库的用户的权限不够,因此只需要赋予相应的权限即可 MSSQL2005:具体数据库(xxx) --- 安全性---- 架构---- dbo(属性)--- 权限--- 添加--- 浏览-- [p ...