canvas 小游戏,奔跑吧!忍者!
源码位置:https://github.com/condorheroblog/My-Second/tree/master/Canvas
今天这个游戏是我学习 canvas 以来动手写的第一个游戏,第一次动手我感觉写的还不错,有鉴于此,保守打算要写三个 canvas 游戏。其他类型的游戏可能不写出来但弄懂主要业务逻辑还是要的。可能是我构造函数学的好,这次使用 canvas 加上面向编程写这个游戏很顺新,不会的地方,停下来想一想,时间可长可短但问题也就解决了。可能也是游戏的业务并不是太难吧。
参照效果
Running Ninja : http://flash.7k7k.com/cms/cms10/20171212/1002107071/2/games/Running-Ninja/index.html
实现的思路分析
-
先从最基础的写,一个背景房子,背景房子是不动的,然后是暗树,暗树再上面是明树,明树和暗树都在运动只不过暗树的速度低于明树。明树下面有草地,草地的速度不是很快大约和暗树的速度相同。
-
画面底部的黑色区域,因为图片大小的原因,我们的用 canvas 画笔,手动绘制一个矩形进行填充。
-
继续写下来就是障碍物了,一共上下两个。上下障碍物之间的距离是固定的,画面有色的部分距离也是固定的,我们让上面的障碍物随机产生一个随机数来表示上障碍物的位置,从而改变上障碍物出现的长度,然后让固定总长(除黑布以外有色区域)减去固定障碍物之间的长度和现在上障碍物的长度就是现在下障碍物的长度。
-
障碍物之间的星星:根据上一个步骤我们已经知道上方障碍物的随机长度和障碍物之间的固定长度,星星出现的地方就是障碍物的中心,canvas 移动左上角的坐标系,移动的距离 x 即是障碍物距离左边框在加上障碍物宽度的一半,距离的 y 值就是上障碍物的随机出现长度加上两障碍物之间固定长度的一半。
-
星星出现的位置:这个问题也是值得思考的,当时写的时候真是才思如泉涌,瞬间想到让星星和障碍物一起出现,没错每个障碍物之间其实都有星星,至于随机留到后面解决。怎么解决的?很简单随机产生一个随机数,范围小点0~5,在障碍物出现的时候,判断星星随机的这个数是否恒等于1(零到五随便选一个数)条件为真,星星出现,条件为假,星星就不出现。
-
星星的旋转,用到 canvas 的旋转rotate 这个 API。
-
忍者的效果,忍者看着是在一直跑,其实一直在原地更换背景,进行原地奔跑。真正运动的是后面的背景图。
忍者这个地方有两个难点:
- 第一个难点就是入场动画,需要保持画面整体静止,忍者从左边跑入画面,然后进行原地奔跑,画面也同时进行运动。这个我是在定时器那个地方进行控制的,游戏一开始就让忍者运动,当忍者距离左边框一定距离,打开其他类的控制。整个画面同时运动了。
- 第二个难点就是二级跳,解决方案如下:
完美解决忍者二级跳的功能:
因为之前写这个游戏只写了一个框架,整体上和原游戏大差不差,细节来不及琢磨,游戏最能难道我的地方就是忍者的二级跳功能。刚开始写的时候,一级跳很快实现了,二级跳也没多久就完成了,等测试的时候发现忍者并不是简单的点一下跳一下,双击可以连跳两次,但原游戏的忍者厉害的地方就是忍者可以在一级跳的过程中还没落地的时候,再点击一下,可以在原基础上在起跳一次。而我当时想了好多办法,但只有两个办法是半成功,因为这两个办法只能各自独立完成实际游戏效果的一半。
- 只能完成双击二级跳,单击一级跳,单击过程中不能实现二级跳。
- 双击二级跳失效,变成双击单击都是一级跳,但单击过程中可以实现二级跳。
- 正是这种情况造成,一级二级跳的时候的音乐也加不上。。。
想了几天没思路,到这时思路有点混乱了,后来其他功能写完了,才回来慢慢的去盘这个地方的思路,还是用条件判断来控制鼠标点击次数的不同来给不同的条件,这次就完美解决了单击跳,单击下落未落地二级跳,双击二连跳的问题,这个地方是整个游戏对我来讲最大的难点,就是糊弄不出来。整的你没脾气。就得就得静下心来想逻辑,用命去盘思路,盘着盘着就盘出来了。
- 死亡画面采用的是延迟清除定时器,在这个空隙,更换死亡图片,当完成 die 动作最后才清除定时器。
- 开场的指引跳跃图片,只需要放置一张。更新完就没了。
- 使用本地存储来记录最高分数和吃到星星的数量。其中五个星星用来复活一次。
- canvas 事件绑定,这个是除二级跳我认为第二个难得地方,这个 canvas 画布上如何进行事件绑定。因为 canvas 画布就一个 DOM 级标签,点的地方都是 canvas 画上去的图。这就比较让人头疼了。为此专门写了一篇文章。提供了两种思路:
canvas 上添加事件绑定: https://www.jianshu.com/p/013d910b2f94
- js 刷新当前页面 参考: https://www.runoob.com/w3cnote/js-refresh-current-page.html
- 最后把音乐加上就大功告成了。
代码思路
- 中介者模式控制 game 类来调控全部类的通信
- 接下来就是各个类之间的通信
多余文件
- line.html 是 Promise 阻止 animate 异步练习
- particle.html 是网站常见的动态粒子连线
另外,images 里面的图片没有用完,只用了部分,除了这些其他文件均是有用的。
图片是动图所以听不见声音,真实是有音效的