今天学习《前端篇》第3章 编写一个简单的HTML5小游戏:完成交互功能 第7课 实现动画:让小球动起来,这节课将实现动画,让小球动起来。
学习目标
- 学习使用定时器实现动画;
- 学习JavaScript的异步执行机制;
- 了解JS的13种复合赋值运算符;
- 学习清屏;
- 学习实现简单的碰撞检测;
- 复习使用if else if 语句;
- 学习使用requestAnimationFrame函数实现动画;
主要知识点/技能点
- 在 JS 语言中,有两个定时器方法可以让小球动起来,一个是 setInterval,另一个是 setTimeout,前者用于实现每隔一段时间就执行某一段代码,后者用于实现延时执行某一段代码。
- setInterval 以指定毫秒数为间隔,不停地执行回调函数;setTimeout 在暂停指定毫秒数后,执行回调函数,且仅执行一次。
- JS 是单线程,同一时间只能执行一个任务,同步任务在主线程中会依次执行。在主线程上发起的异步操作,会交给另外一个看不见的异步线程执行和管理,不会阻塞主线程的执行。
- 当主线程空闲的时候(例如每个帧渲染周期的空隙),它会去异步线程那里询问,有没有可被执行的异步代码。如果某个异步操作(例如 Ajax 网络请求的回调函数,或者某个定时器的回调函数)可以执行了,便会被放到主线程队列中排队执行。
- 定时器是一种异步任务。在浏览器宿主环境中有一个独立的定时器模块,定时器的延迟时间是由定时器模块管理的,如果某个定时器时间到了,它的回调函数就会被加入主线程队列中。
- JS 有 13 种复合赋值运算符,复合赋值运算符等于先运算,再以运算结果赋值。
- 在 Canvas API中,clearRect 方法可以清空画布上给定矩形区域内的像素。
- 如果分支足够多,可以有许多个 else if 存在。一般将出现概率最高的条件分支放在最上面,这样可以减少条件检查的次数。
实践疑难点
- 在实际动画时,不但变化的小球需要重绘,其它静止对象也需要重绘。
- 挡板不见了,原因在于我们以500毫秒的间隔执行render函数,这个时间太短,不足以让img的onload回调函数(第4行)在每帧都得到执行。
- 我们可以将画布四周看作墙壁,当小球触达四周边线时,让其反弹。反弹涉及的变化,是速度方向的变化。当球触及顶边或底边时,x 轴方向速度不变,y轴方向速度取反;当触及左右边界时依此类推,均是在边线垂直的方向改变运动方向。
- 每次小球在碰到边界时,有半个球几乎都会陷入墙壁中。这是由于碰撞检测的坐标是以小球的圆心为准的,如果以圆弧边界进行检测,或者将画布的四周边界值都减少一个小球半径的宽度,问题应该就会解决。
小结
这节课主要使用擦除重绘的方法让小球动了起来,并让小球与四壁之间实现了简单的碰撞检测,在实践过程中我们学习了JS的定时器、异步执行机制、复合赋值运算符、if else逻辑控制语句及优化动画性能的requestAnimationFrame全局函数。