我正在构建一个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;
}
然而,当我将此值乘以动画速度时,会导致一个不稳定的结果,而不是平滑的动画。似乎毫秒精度是不够的。如何改进此功能以产生平滑的结果?
答案 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可以帮助您优化这个:
答案 1 :(得分:1)
查看较新版本的requestAnimationFrame,该版本以精确到亚毫秒的经过时间发送
http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision
但这可能不是你的不稳定的原因。
使用带有增量时间的requestAnimationFrame(aka RAF)会使动画对象显示在准确位置中。
如果你在天空中为太阳制作动画,那么RAF + deltaTime将确保无论何时绘制太阳,它都将被绘制在天空中的正确位置。它将确保以太阳波动不定为代价的准确性。
RAF + deltaTime牺牲了平滑动画的定位精度。
您没有提供代码示例,但解决方案是确保您的代码足够高效,以便在RAF时间内完全绘制。
或者,您可以使移动量更小,以便跳过的帧对用户来说不会非常明显。