JS中DeltaTime函数的不稳定结果



我正在创建一个HTML5画布游戏,使用requestAnimationFrame渲染画布中的每一帧。为了基于秒而不是帧率移动动画,我正在构建一个类似于Unity中使用的deltaTime函数:

var startTime = new Date().getTime();
var lastTime = null;
function deltaTime()
{
    if (lastTime == null)
    {
        lastTime = new Date().getTime();
    }
    var dt = new Date().getTime() - lastTime;
    lastTime = new Date().getTime();
    return dt;
}

然而,当我将这个值乘以动画速度时,它会导致一个不稳定的结果,而不是一个平滑的动画。看来毫秒级的精度是不够的。我如何改进这个函数以产生一个平滑的结果?

查看更新版本的requestAnimationFrame,它发送精确到亚毫秒级的运行时间

http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision

但这可能不是你不高兴的原因。

使用带有delta-time的requestAnimationFrame(又名RAF)会导致被动画的对象出现在精确位置

如果你在天空中绘制太阳动画,那么RAF+deltaTime将确保无论何时绘制太阳,它都将绘制在天空中的正确位置。它将以太阳波动为代价来保证精度。

RAF+deltaTime为了定位精度牺牲了平滑的动画。

你没有给出一个代码示例,但解决方案是确保你的代码足够有效,可以在RAF时间范围内完全绘制。

或者,你可以让移动量更小,这样跳过的帧对用户来说就不会很明显了。

requestAnimationFrame是高度优化的,因为它在系统最准备好更新显示时更新。这意味着,如果你想要避免janky动画,你需要让动画发生在requestAnimationFrame循环中。我不确定您的代码是否正在这样做,但这里是如何使用requestAnimationFrame将帧率设置为15 fps:

var fps = 15,
    startTime = 0,
    frameDuration = 1000 / fps;
//Start the game loop
update();
function update() {
  requestAnimationFrame(update, canvas);
  //Check whether the current time matches the start time
  if (Date.now() >= startTime || startTime === 0){
      //... run the game code ...
      //Set the new start time for the next frame, 
      //which will be 66 milliseconds ahead of the current time
      startTime = Date.now() + frameDuration;
  }
}

但是显示的最大瓶颈通常是渲染:如果你可以使用WebGL,它比画布快得多。像PixiJs这样好的渲染框架可以帮助你优化这一点:

https://github.com/GoodBoyDigital/pixi.js/

最新更新