HTML5 2D 游戏开发 设置舞台(3)暂停游戏
 
- UID
- 1066743
|

HTML5 2D 游戏开发 设置舞台(3)暂停游戏
暂停游戏HTML5 游戏(尤其是视频游戏)必须能够暂停。在清单 4 中,我已经修改了 Snail Bait 的游戏循环,以便暂停和取消暂停游戏:
清单 4. 暂停和取消暂停1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| var SnailBait = function (canvasId) {
...
this.paused = false,
this.PAUSED_CHECK_INTERVAL = 200; // milliseconds
...
};
SnailBait.prototype = {
animate: function (now) {
if (snailBait.paused) {
// Check again in snailBait.PAUSED_CHECK_INTERVAL milliseconds
setTimeout( function () {
requestNextAnimationFrame(snailBait.animate);
}, snailBait.PAUSED_CHECK_INTERVAL);
}
else {
// The game loop from
snailBait.fps = snailBait.calculateFps(now);
snailBait.draw(now);
requestNextAnimationFrame(snailBait.animate);
}
},
togglePaused: function () {
this.paused = !this.paused;
},
};
|
togglePaused() 方法简单地切换该游戏的 paused 变量。当该变量为 true (意味着游戏已暂停)时,animate() 方法不会执行游戏循环。
每秒检查 60 次(假设帧速率为 60fps),查看是否应该恢复某个暂停的帧,这是没必要的,且效率低下,因此, 中的 animate() 方法只会等待 200ms,然后调用 requestNextAnimationFrame() polyfill,在到时间绘制下一个动画帧时,它就会安排对 animate() 的另一次调用。
当窗口失去焦点时自动暂停W3C 的 Timing control for script-based animations(基于脚本的动画时序控制) 规范对于使用 requestAnimationFrame() 实现的动画具有下列规定:
如果页面目前不可见,可以大幅裁剪该页面上的动画,那么就不会经常更新这些页面,因此只会占用极少的 CPU 资源。 术语大幅节流意味着,浏览器以极低的帧速率(通常介于 1 到 10 fps 之间)调用您的动画回调,如图 1 所示,帧速率在窗口重新获得焦点后立即达到 6fps:
图 1. 在失去焦点和重新获得焦点后的 Snail Bait 大幅节流的帧速率可能对碰撞检测算法造成破坏,该算法通常基于帧速率确定是否发生了(或将发生)碰撞。您可以在游戏的窗口失去焦点时暂停游戏,并在窗口重新获得焦点时重新启动它,避免因大幅节流的帧速率而造成碰撞检测的崩溃。在清单 5 中,您可以看到如何做到这一点:
清单 5. 自动暂停1
2
3
4
5
6
7
8
9
10
11
| window.onblur = function () { // window looses focus
if (!snailBait.paused) {
snailBait.togglePaused();
}
};
window.onfocus = function () { // window regains focus
if (snailBait.paused) {
snailBait.togglePaused();
}
};
|
当窗口失去焦点时,您不仅要暂停游戏,还应该在暂停游戏时冻结 它。 |
|
|
|
|
|