问题描述
所以我有一台 120hz 显示器和一台 60hz 显示器。如果我在第一个显示器上运行我的游戏,它运行得非常快,但是当我在第二个显示器上运行它时,它会变慢。而且我知道那里也有很多 30hz 显示器,它们会更慢(还有一点点 240hz 显示器,它会快如闪电)。有什么办法可以把游戏的帧率锁定在60fps(这是最常见的),这样问题就不会发生?
解决方法
不,requestAnimationFrame
应该在下一次屏幕刷新之前触发,这使得它与屏幕刷新率相关联。
您需要的是 delta-time。
不要在每次滴答时将对象位置增加一个静态值,而是测量自上次滴答以来已经过去了多长时间,并根据经过的时间和预设的持续时间更新您的值。
这样,无论显示器的刷新率如何,或者即使页面受到计算机等的限制,您的动画对象将在任何地方以相同的速度移动给定的距离。
这里有一个例子,说明即使我们“暂停”动画,当我们“恢复”它时,对象也会在它应该没有暂停的地方。
const it = document.getElementById( "it" );
const checkbox = document.querySelector( "input" );
const maxLeft = window.innerWidth - 50;
const duration = 2000; // time to traverse the screen (ms)
const start = performance.now();
function anim( now ) {
// 'now' passed by rAF is the time the last VSync event has been sent by the monitor
// it may not be the real "now" time,for this one could use
// performance.now() instead
const delta = ((now - start) % duration) / duration;
// determine if we should go to left or to right
const direction = Math.sign( ((now - start) % (duration * 2)) - duration );
let position;
if( direction < 0 ) {
position = delta * maxLeft;
}
else {
position = maxLeft - (delta * maxLeft);
}
it.style.transform = `translateX(${ position }px)`;
if( checkbox.checked ) {
requestAnimationFrame( anim );
}
}
requestAnimationFrame( anim );
checkbox.oninput = anim;
#it {
width: 50px;
height: 50px;
background: red;
border-radius: 50%;
position: fixed;
top: 50px;
will-change: transform;
}
<div id="it"></div>
<label>pause/resume<input type="checkbox" checked></label>
Kaiido 的方法非常适合简单的动画和游戏,但如果您需要更复杂的功能,还可以采用其他一些方法。
假设某种操作需要每秒发生 n
次;我们称之为勾号。一种方法是为可能需要在帧之间发生的任务使用 requestAnimationFrame
和 setInterval
。例如:
var tick_rate = 50; // This is the ideal number of ticks per second
function draw_frame(now) {
// This code only handles the graphics
requestAnimationFrame(now);
}
function run_tick() {
// This is where you handle things that don't happen "smoothly"
// (i.e.,can't be calculated at a varying rate)
}
requestAnimationFrame(now);
setInterval(run_tick,1000 / tick_rate);
对于某些事情,这绝对不是理想的方法,但在某些情况下,在已知时间间隔内更容易发生特定事件或计算的情况下,它可以使事情变得更容易。