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

HTML5 2D 游戏开发 图形和动画(4)游戏循环
游戏循环既然图形和动画的先决条件已经得到满足,那么现在是时候让 Snail Bait 动起来了。首先,我在游戏的 HTML 中让 requestNextAnimationFrame() 包含 JavaScript,如清单 7 所示:
清单 7. HTML1
2
3
4
5
6
7
8
9
10
| <html>
...
<body>
...
<script src='js/requestNextAnimationFrame.js'></script>
<script src='game.js'></script>
</body>
</html>
|
清单 8 显示了游戏的动画循环,一般将该循环称为游戏循环:
清单 8. 游戏循环1
2
3
4
5
6
7
8
9
10
11
| var fps;
function animate(now) {
fps = calculateFps(now);
draw();
requestNextAnimationFrame(animate);
}
function startGame() {
requestNextAnimationFrame(animate);
}
|
startGame() 函数由背景图像的 onload 事件处理器调用,该函数通过调用 requestNextAnimationFrame() polyfill 启动游戏。在绘制游戏的第一个动画帧时,浏览器会调用 animate() 函数。
animate() 函数根据当前时间计算动画的帧速率。(参见 ,了解有关 time 值的更多信息。)在计算帧速率之后,animate() 会调用一个 draw() 函数来绘制下一个动画帧。然后,animate() 调用 requestNextAnimationFrame() 来保持动画。
以 fps 计算动画速率清单 9 显示了 Snail Bait 如何计算其帧速率,以及如何更新在 中显示的帧速率值:
清单 9. 计算 fps 并更新 fps 元素1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| var lastAnimationFrameTime = 0,
lastFpsUpdateTime = 0,
fpsElement = document.getElementById('fps');
function calculateFps(now) {
var fps = 1000 / (now - lastAnimationFrameTime);
lastAnimationFrameTime = now;
if (now - lastFpsUpdateTime > 1000) {
lastFpsUpdateTime = now;
fpsElement.innerHTML = fps.toFixed(0) + ' fps';
}
return fps;
}
|
帧速率只是自上一个动画帧开始计算的时间量,所以您也可以认为它是 frame per second(帧每秒)而不是 frames per second(每秒的帧数),这使得它不太像是一个速率。您可以采用更严格的方法,在几个帧中保持平均帧速率,但我还没有发现这样做的必要性,事实上,自最后一个动画帧起所用的时间就正是我在 中所需要的。
还演示了一个重要的动画技术:执行任务的速率不同于动画速率。如果我在每一个动画帧都更新帧/秒值,则无法读取速率,因为它总是在不断变化;我将该设置改为每秒更新一次。
设置好了游戏循环和帧速率之后,我现在就准备开始滚动背景了。 |
|
|
|
|
|