重力与长时间步长(使用javascript)
我想用gravity创建一个简单的动画(在chrome和firefox中测试)。我正在用Javascript和canvas做这件事。重力和速度通过使用(:46)的可变时间步长计算: 每个球都有计算速度和位置的代码(:148): 现在,当您查看窗口时,这个原型可以正常工作 但是,如果隐藏当前窗口(切换到浏览器的另一个选项卡),window.requestAnimationFrame将停止。如果等待5秒钟,然后打开窗口,window.requestAnimationFrame将继续。问题是realDelta现在是5秒,速度太大了 我可以添加一个不允许realDelta大于一秒的检查(:46): 但这并不能真正解决问题 现在我不明白如何真正解决这个问题。我应该检查窗口是否隐藏并暂停计时器(当窗口再次可见时恢复计时器)。还是我的速度计算有误?其他html5游戏如何解决“dt”太大的问题重力与长时间步长(使用javascript),javascript,html,canvas,Javascript,Html,Canvas,我想用gravity创建一个简单的动画(在chrome和firefox中测试)。我正在用Javascript和canvas做这件事。重力和速度通过使用(:46)的可变时间步长计算: 每个球都有计算速度和位置的代码(:148): 现在,当您查看窗口时,这个原型可以正常工作 但是,如果隐藏当前窗口(切换到浏览器的另一个选项卡),window.requestAnimationFrame将停止。如果等待5秒钟,然后打开窗口,window.requestAnimationFrame将继续。问题是realD
感谢使用这些jQuery事件来启动/停止帧计算: (你可以尝试不用jQuery——纯javascript,但是X浏览器的东西会让你发疯的!)
唯一的问题是在某些浏览器中,这些事件会被多次触发,因此您可能还需要设置一个开/关标志,以便只对第一次触发作出反应。在draw函数中,您可以通过多次运行函数来弥补错过的帧:
var TIME_INTERVAL = 1000/60;
var timeElapsed = 0;
requestAnimFrame(draw, TIME_INTERVAL);
function draw() {
timeElapsed += now - this.prevTime;
this.prevTime = now;
while(timeElapsed > TIME_INTERVAL)
{
timeElapsed -= TIME_INTERVAL;
// Run Draw
}
requestAnimFrame(draw, TIME_INTERVAL);
}
当然,如果用户在选项卡上停留的时间太长,他们可能会返回大量计算。还可以考虑在RequestAnimFrame不可用的情况下运行备份:
var TIME_INTERVAL = 1000/60;
var timeElapsed = 0;
var backup = setInterval(draw, TIME_INTERVAL*5);
requestAnimFrame(draw, TIME_INTERVAL);
function draw() {
clearInterval(backup);
timeElapsed += now - this.prevTime;
this.prevTime = now;
while(timeElapsed > TIME_INTERVAL)
{
timeElapsed -= TIME_INTERVAL;
// Run Draw
}
backup = setInterval(draw, TIME_INTERVAL*5);
requestAnimFrame(draw, TIME_INTERVAL);
}
选择一些最大(或固定)时间步长。如果实际经过的时间间隔大于最大时间步长,请多次运行物理函数。我还不太熟悉canvas,但我想可能会有类似于on_resume事件的情况。如果继续,只需将时间设置为上次使用的增量。你认为这样的事情是可能的吗?谢谢,这是一个快速和简单的黑客来修复问题,这是一个很好的方式来处理这个问题!对不起,我不能投你一票,我的声望很低:D
this.realDelta = (now - this.prevTime) / 1000;
if (this.realDelta > 1) {
this.realDelta = 1;
}
this.realTime += this.realDelta;
$(window).blur(function(e) {
// User has changed tabs away from your window
// So freeze your incrementing until the user returns
});
$(window).focus(function(e) {
// User has returned to your tab
// So begin your incrementing again
});
var TIME_INTERVAL = 1000/60;
var timeElapsed = 0;
requestAnimFrame(draw, TIME_INTERVAL);
function draw() {
timeElapsed += now - this.prevTime;
this.prevTime = now;
while(timeElapsed > TIME_INTERVAL)
{
timeElapsed -= TIME_INTERVAL;
// Run Draw
}
requestAnimFrame(draw, TIME_INTERVAL);
}
var TIME_INTERVAL = 1000/60;
var timeElapsed = 0;
var backup = setInterval(draw, TIME_INTERVAL*5);
requestAnimFrame(draw, TIME_INTERVAL);
function draw() {
clearInterval(backup);
timeElapsed += now - this.prevTime;
this.prevTime = now;
while(timeElapsed > TIME_INTERVAL)
{
timeElapsed -= TIME_INTERVAL;
// Run Draw
}
backup = setInterval(draw, TIME_INTERVAL*5);
requestAnimFrame(draw, TIME_INTERVAL);
}