HTML5 2D 游戏开发 图形和动画(2)HTML5 动画
 
- UID
- 1066743
|

HTML5 2D 游戏开发 图形和动画(2)HTML5 动画
HTML5 动画从根本上讲,实现动画很简单:您反复绘制一个图像序列,看起来就象对象在以某种方式运动。这意味着您必须实现一个定期绘制图像的循环。
传统上,会使用 setTimeout() 或如清单 4 所示的 setInterval() 在 JavaScript 中实现动画循环:
清单 4. 使用 setInterval() 实现动画1
2
3
| setInterval( function (e) { // Don't do this for time-critical animations
animate(); // A function that draws the current animation frame
}, 1000 / 60); // Approximately 60 frames/second (fps)
|
最佳实践对于时间要求苛刻的动画,永远不要使用 setTimeout() 或 setInterval()。
毫无疑问, 中的代码通过反复调用一个绘制下一个动画帧的 animate() 函数来生成一个动画;然而,您可能会得到不满意的结果,因为 setInterval() 和 setTimeout() 完全不知道如何制作动画。(注:您必须实现 animate() 函数;它不属于 Canvas API。)
在 中,我将时间间隔设置为 1000/60 毫秒,这相当于大约每秒 60 帧。这个数字是我对最佳帧速率的最佳估值,它可能不是一个很好的值,但是,因为 setInterval() 和 setTimeout() 完全不了解动画,所以由我指定帧速率。浏览器肯定比我更了解何时绘制下一个动画帧,因此,如果改为由浏览器指定帧速率,会产生更好的结果。
使用 setTimeout 和 setInterval() 甚至有一个更严重的缺陷。虽然您传递以毫秒为单位指定的这些方法的时间间隔,但这些方法没有精确到毫秒;事实上,根据 HTML 规范,这些方法(为了节约资源)慷慨地拉长您指定的时间间隔。
为了避免这些缺陷,对于时间要求苛刻的动画,不应使用 setTimeout() 和 setInterval();而是应该使用 requestAnimationFrame()。
requestAnimationFrame()在 Timing control for script-based animations 规范(请参阅 )中,W3C 在 window 对象上定义了一个名称为 requestAnimationFrame() 的方法。与 setTimeout() 或 setInterval() 不同,requestAnimationFrame() 是专门用于实现动画的。因此,它不会具有与 setTimeout() 和 setInterval() 有关的任何缺点。而且它简单易用,如 所示:
清单 5. 使用 requestAnimationFrame() 实现动画1
2
3
4
5
6
| function animate(time) { // Animation loop
draw(time); // A function that draws the current animation frame
requestAnimationFrame(animate); // Keep the animation going
};
requestAnimationFrame(animate); // Start the animation
|
您可以将 requestAnimationFrame() 作为一个参考传递给回调函数,当浏览器准备好绘制下一个动画帧时,它就会调用这个回调函数。为了维持动画,回调函数还会调用 requestAnimationFrame()。
正如您在 中所见,浏览器会将一个 time 参数传递给您的回调函数。您可能会疑惑该 time 参数究竟有何意义。它是当前时间,还是浏览器绘制下一个动画帧的时间?
令人惊讶的是,这个时间并没有固定的定义。您惟一可以肯定的是,对于任何给定的浏览器,它试着代表着同样的事情;因此,您可以使用它来计算两帧之间的时间间隔,我会在 中说明这一点。 |
|
|
|
|
|