分分钟教你用Axure制作《Flappy Bird》
【文章摘要】技术大神教你分分钟做个Flappy Bird。
向来不想扯任何犊子来引入正题,有感于Axure实在是太拖累工作效率以及受到某篇打飞机的文章@陈斌琳的启发,决心做个《Flappy Bird》无聊下自己,之后默默成为Sketch脑残粉。作为入门工具Axure,功能着实强大,很复杂的逻辑结构以及交互基本都能以低配的形式实现,但是对于快速原型产出的出发点来说,Axure其实相当影响效率,除非自定义自己的组件库,能够时常复用。我需要的仅仅是拼积木,你却给了我一堆木头。不扯淡,先来瞄一瞄效果:
一、基本功能需求
- 萌鸟的飞行与自由落体:
- 触摸界面后能够上升并且变换为抬头姿势,不做任何操作的情况下自由落体下落,姿势变为下坠状态。
- 初始状态下若不进行任何操作则在一段时间后自由落体
- 背景的推进:原版的《Flappy Bird》中背景为静态,此处做成动态效果,实现背景的动态推荐,然并卵。
- 水管的推进与显示:水管和背景墙一样,能够循环推进,并且中间间隙能够随机变换位置,但宽度一致。
- 胜负规则:当萌鸟与水管、地面触及时游戏结束,并弹出面板。
- 数据采集:能够采集到鼠标点击数字以及跨越过的水管数量。
- 难度系数:随着时间的推移增加水管推进速率(实在懒得算,设置对数函数分分钟实现)。
二、思路拆解和实现
- 萌鸟飞行动作的拆解:
方案A:使用动态面板,命名为bird:设定三种状态的萌鸟state,分别为初始状态,上扬以及下坠,初始状态水平线夹角0°,上下飞行状态下各自为45°以及-45° 。
方案B:image组件自带的enable以及select功能变换图片(这个水深,触及到image组件的某些机制,很不幸最初我尝试了下这个坑爹的东西)
(分别为上升、初始、下降状态下的萌鸟)
- 萌鸟动作的实现:
- 注意:起飞之后,状态的变化仅仅是上升与下降的状态变化,当然也可以不要下降的动作,这样会更萌。
- 起飞:
动作实现:设置全部界面的onPageclick事件,绑定上升的动作,这里经过多次尝试最终选择了:move by(0,-70)swing 200ms,亲测数值和交互效果着实感人,如果用linear线性效果去实现我也不拦着你,这里会遇到Axure中自带交互动画的缺点:所有时间经由一个队列按序进行,只要进入程序队列就得强制执行,没有中断机制的引入,于是以下场景就会时常出现:啪啪啪地一顿操作之后,呵呵哒,你会发现这笨鸟升天了!关键是还下不来!所以只能把这款Flappy Bird当作是低配版demo,娱乐自己。
上下文动作:附带上升buff,记得设置动态面板状态为up,保证能够正常仰望天空。
- 自由落体:当笨鸟升天后,由于受到重力的影响只能啪啪啪往下掉,设置之前的bird动态面板为down状态,并且设置bird的onMove事件为:move This by (0,15) swing 70ms,注意啦:此处onMove事件在move过程中不断触发,只需设置步进就可实现连续的动画效果,这也是Axure制作小游戏的关键!这时候你就不禁感概:不学点编程还玩个球互联网?就算是名cv工程师也得会点前端,创业公司搬砖没有不会的。
(上升动作交互)
(页面初始及初始不操作时的下坠)
(下坠动作与游戏结束判定)
- 背景墙的推进逻辑:
方案A:采用最为土的动态面板轮播效果,设置repeat属性,设置两个相同背景的state,不断轮播,注意设置切换时间为15000ms,大概是缓慢移动的概念,勉强实现一个低配版的推进效果:会称之为低配版,是因为Axure自带的动画效果在切换过程的动画不是线性平滑地移动,而是带有加速效果的。
方案B:另一种做法是准备两张一样的背景计为A和B,然后不断向左移动A图片,当A完全划出界面的左边界时自动将A移动到界面的右边界,同理B也是一样的逻辑,循环推进,完美实现推进效果。
- 前台水管的推进逻辑和缺口实现:
水管的推进过程:采用了上述推进方式的PlanB,即队尾到队头循环重现的做法,这里有几点要说明:
- 初始情况下所有水管均是隐身的状态(set invisible),当水管的左边界触及界面右侧边界后show出来,不断推进;当水管的右边界触及界面的左边界时,隐藏起来。
- 实现了基本的推进后要实现循环推进还得依靠onShow和onHide两个事件,这里就需要tip了:新建一个辅助面板来承接Show和Hide的动作变化状态,承担一个小型控制器的责任,当水管是由show的状态变为hide的状态(水管移动到界面左侧啦)则触发onHides事件,这时候我们要做的是将上下水管挪到右侧边界,之后再将它show出来触发onShow事件,实现了循环的效果。
- 注意水管数量的问题:这里顾及到游戏难度以及界面宽度,同屏水管数量为3个,每次水管运行时同屏最多显示3个水管,并且需要顾及到出场间隔的问题:假设有A、B、C三个水管,则当A水管消失后C水管刚刚进入屏幕,需要A水管再继续移动一段距离才重置到界面右侧或者可以设置等待时间。水管的移动速度推荐设置:move This by (-5,0) linear 100ms,感觉棒棒哒。BTW,每个上下水管的组合分别由一个简易控制器实现循环。
(水管移动的交互设置)
缺口的实现:想想也知道肯定需要动用随机数啦,搬出JavaSript的函数:Math.random()生成一个介于0到1的随机数,缺口的宽度我们设定为某个数值,这里我选择100,可以根据需要调整,我们要做的是让上下水管根据这个随机数调整出一定的缺口,方案由很多种,这里我选择最土的办法:选定一个随机数A=0~99,将均匀分布在屏幕上下的两个水管分别移动A以及(100 – A)的距离,其实是为了降低难度,降低水管缺口的波动,但是实际上游戏难度真心呵呵哒,玩了你就知道啦!具体随机数生成的公式为:Math.floor(Math.random()*100),用个floor取随机数的下边界,得到0~99中的某个数值。BTW,每个水管有不同的缺口,所以你懂的,在之前的水管onShow事件中就要重新更新这个随机数啦。
(控制器设置)
- 胜负判定与弹窗
当笨鸟触及水管、地面时,游戏结束,水管停止推进,笨鸟不再动弹,并弹出game over面板并且出现retry选项,点击可以重新开始:首先铺好地面,在bird面板中的onMove事件中设置前置条件:if This is not over XXX && XXX && XXX…逻辑上是如果没触碰到地面或是水管,则可以移动,否则,设置一个标志位用作控制信号,提示各个部件游戏玩完啦,这里我用isOver来判定,如果为0则游戏进行中,为1则游戏结束。游戏结束时需要告知以下组件,一个是笨鸟的上升动作,一个是水管的推进动作,当isOver为1时就都憋动啦,老实呆着,实现的方式也是设置前置条件,这里就不赘述啦。
- 数值记录:
点击计数可做可不做,在onPageClick事件中设置一个计数器采集click发生的次数即可;另一个跨越水管的计数方案是这样的:每个水管的右侧边界添加一条垂线用作FinishLine,当笨鸟触及这条线后计数+1,这里需要让垂线跟随水管同步移动和重置循环,并且存在3条。
三、唠叨几句
至此,《Flappy Bird》总算完成了90%,还有些剩余的工作小野实在懒得动了,回顾下所需要的知识:
对各种JS函数的了解,事件驱动机制的了解,动态面板的了解,Axure交互机制的了解。好像也没啥嘛,你也可以的!顺便说一句,Axure这尼玛什么鬼碰撞机制,作者到现在也没通关过一次,一次都没!