我的朋友和我正在制作游戏,而且从一些早期的测试中,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();
任何人都知道出了什么问题?
答案 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事件,并按照您认为合适的方式停止游戏时钟,音乐等......