来自JS的DeltaTime函数的糟糕结果

时间:2014-03-09 05:21:53

标签: javascript html5 canvas html5-canvas requestanimationframe

我正在构建一个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;
}

然而,当我将此值乘以动画速度时,会导致一个不稳定的结果,而不是平滑的动画。似乎毫秒精度是不够的。如何改进此功能以产生平滑的结果?

2 个答案:

答案 0 :(得分:1)

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/

答案 1 :(得分:1)

查看较新版本的requestAnimationFrame,该版本以精确到亚毫秒的经过时间发送

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

但这可能不是你的不稳定的原因。

使用带有增量时间的requestAnimationFrame(aka RAF)会使动画对象显示在准确位置中。

如果你在天空中为太阳制作动画,那么RAF + deltaTime将确保无论何时绘制太阳,它都将被绘制在天空中的正确位置。它将确保以太阳波动不定为代价的准确性。

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

您没有提供代码示例,但解决方案是确保您的代码足够高效,以便在RAF时间内完全绘制。

或者,您可以使移动量更小,以便跳过的帧对用户来说不会非常明显。