首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

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

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();
   }
};




当窗口失去焦点时,您不仅要暂停游戏,还应该在暂停游戏时冻结 它。
返回列表