当浏览器不在焦点时,HTML5画布游戏不会暂停渲染

时间:2014-08-18 20:08:48

标签: javascript html5 canvas

我的朋友和我正在制作游戏,而且从一些早期的测试中,requestAnimationFrame()会确保游戏在没有聚焦时暂停。在我们当前的游戏here中,您可以看到它即使在没有聚焦时也会继续呈现所有内容。这就是我们用来处理渲染的内容:

//main game loop, updates and renders the game
var main = function(){
        var now = Date.now();
        var delta = now - then;

        update(delta / 1000);
        render();

        then = now;

        requestAnimationFrame(main);
};

//updates the positions of the target and enemy
var update = function(delta){
        target.update(delta, gamecanvas);
        planet.update(delta);

        enemies.forEach(function(enemy){
                enemy.update(delta, gamecanvas)
        });
        defenders.forEach(function(enemy){
                enemy.update(delta, gamecanvas)
        });
};

//clears the screen
var clearScreen = function(){
        gamectx.clearRect(0,0,gamecanvas.width, gamecanvas.height);
};

//clears the screen, and redraws the objects
var render = function(){
        clearScreen();

        planet.draw(gamectx);
        enemies.forEach(function(enemy){
                enemy.draw(gamectx)
        });
        defenders.forEach(function(enemy){
                enemy.draw(gamectx)
        }); 
        target.draw(gamectx);
};

//updates the time, runs the main loop
var then = Date.now();
main();

任何人都知道出了什么问题?

1 个答案:

答案 0 :(得分:4)

我认为你正朝着错误的方向前进。

•当您的应用程序被标记出来时,RequestAnimationFrame 停止触发。
但是真实的'时间一直在运行。因此,当浏览器恢复时,你的三角洲将是巨大的,最有可能使你的动作/物理/ ......变得灰暗。

•首先要做的事情是:将delta钳位。在两个方面。如果它超过50毫秒,你必须被标记出来,所以考虑,比如说,已经过了16毫秒。但是对于非常快速的显示器(如120Hz,有些人有这个),一个太小的三角洲将驱动计算机的风扇疯狂,所以检查它,比如14ms,以避免过热/风扇转动/电池下沉。你可能想要处理一个游戏时间'这将是你游戏中的时间。

var gameTime = 0;

var typicalFrame  = 16;
var smallestFrame = 14;
var longestFrame  = 50;

var main = function(){
    var now = Date.now();
    var delta = now - then;
    if (delta<smallestFrame) return;
    if (delta>longestFrame) delta = typicalFrame;
    gameTime += delta;
    then = now;

    ...

•第二件事:即使上面的建议可能足够,实际上你可能想要在失去焦点时正确暂停游戏。想到的第一个例子就是音乐,你可能想要停下来(做它!当你甚至不知道哪个标签正在播放音乐时,它会很无聊!)。第二个例子是一个网络游戏,服务器想知道玩家不再玩了 这并不难:只需处理window.onblur和window.onfocus事件,并按照您认为合适的方式停止游戏时钟,音乐等......