嘿,我带着小恐龙回来了!
在上次对canvas的初探之后,我迅速地整起了Chrome小恐龙。当然,如果只是在上次的基础上做少量修改,那就没意思啦,所以这次用了些不同的方法去实现。最主要的区别是,这次用了ES6的Class语法,将所有组件按类分开进行表示,在一定程度上实现了解耦,这样看起来就舒服多了。除此之外还有一些其他方面的改变,下面就写些值得记录的小点。
代码结构
1 | ├───index.html |
这下每个元素都有自己的类了,按照字母排列顺序依次为:
- 地面
- 仙人掌
- 云朵
- 幕布
- 恐龙
- 整个画布
- (主函数)
- 分数
- 无需刷新的内容
- (工具函数)
sprite图
所有图片资源被放在了一张大图内,因此需要通过截取相应位置来获得相应图片。
通过这篇DRAW IMAGES AND SPRITE ANIMATIONS发现了如何在画布上显示部分图片:context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height)
,其中img
为原始sprite图,sx
和sy
表示所需区域起始点在原始sprite图上的坐标,swidth
和sheight
表示所需区域在原始sprite图上的大小,后四个参数则为将所需区域放置在canvas上的位置和大小信息(“s” is for “source”)。
通过这个工具SVG Sprite Position Finder Tools可以获取sprite图中某部分的sx
、sy
、swidth
、sheight
。
动画实现
跳跃
这次的跳跃和上次Flappy Bird跳跃的不同之处在于,这次有地面的支持,因此需要设置“只在空中受重力加速度影响”,触发条件也需要仔细看看。
我差不多是这样得出判断条件的,左下角情况跳变为-20(或其它合适的负数),右下角情况跳变为0,写成代码的话就是:
眨眼
仔细看的话,会发现在恐龙会在等待页眨眼。我最开始是用everyInterval()
来实现的,每隔指定帧数就切换恐龙图片,但发现它的结果是1s闭眼、1s睁眼、1s闭眼、1s睁眼…而不是想要的1s闭眼、5s睁眼、1s闭眼、5s睁眼。于是想到这种方法:
起始动画
在等待画面中敲空格键会触发开场动画,小恐龙跳起、地面向右展开。向右展开的动画是还是思考了一会儿的:可以先绘制完整的地面,再拿一块白色的幕布挡住,当敲空格键时让幕布不断向右移动,来实现向右“展开”的过程。
注意点
在Class内部的函数内调用同级的内部函数时要注意丢失this的问题,解决办法可以是let that = this
再传递that
、用箭头函数获取外部this
。
比如这样写是会出错的:
可以改写成这样:
好了,我们的小游戏就告一段落,之后如果有空并且有想法的话,我再来开发自己的小游戏吧!