最近打算写一个基于canvas动画的射击游戏,看完教程觉得万事具备只欠东风。然而实际操作起来并没有那么简单。
设计目标:在屏幕上显示一架飞机,能随键盘输入←→键进行左右移动
最初的思路:
1、写一个animate方法,擦除画布,根据飞机对象的横坐标属性重绘飞机,然后requestAnimationFrame调用自身来实现动画实时反映飞机位置变化。
2、监听document上的keydown事件,用户按下相应按钮,飞机对象的横坐标就会对应的加10或减10。
存在的问题:
1、每次按下按钮,飞机的坐标就会发生变化,当这个变化数值过大时,动画的连贯性就会大幅下降,直观的看就是移动物体在“闪烁”。测试得到的结果,键盘一直按下某个按键的时候,每次keydown事件之间的时间间隔大约可以触发两次requestAnimationFrame 重绘,也就是说,在这两次重绘中,飞机对象的横坐标变化了10,但是这个变化是在一次重绘中完成的,中间没有变化5来过渡,这极大的影响了动画的流畅性。
2、按上述思路,只使用keydown方法,带来的第二个问题是,物体移动有停顿。具体表现为,按下按键时先动一下,然后停顿,接着再开始连续运动。这极大的破坏了用户的游戏体验,会带来转向不灵敏等问题。
解决思路:
使用keydown+keyup组合,比如keydown将飞机移动的方向属性改为“left”,keyup将飞机的移动方向改为“stop”,animate方法运行时,先根据方向属性的值来进行5单位的偏移,然后再擦除重绘,这样就实现了有过度的,反应灵敏的canvas游戏操作。
对于实际情况的进一步优化:
当用户←键还没放开的时候已经按下了→键,这会导致放开←键时重新给方向属性赋值“stop”,导致动画出现短暂停滞。这个问题,可以通过判断用户放开←键的时候方向属性是否为“left”来解决。→键同理。
至此,丝般顺滑的canvas游戏操作完美的得到了实现!撒花✿✿ヽ(°▽°)ノ✿