我在HTML5,Canvas游戏的更新功能中看到了这种结构,带有“修饰符”变量:
function update(modifier) {
obj.x += obj.speed * modifier
obj.y += obj.speed * modifier
}
function main() {
var thisLoop = new Date
var delta = thisLoop - lastLoop
update(delta / 1000)
render()
var lastLoop = new Date
}
var lastLoop = new Date
setInterval(main, 1)
现在我用自己的结构:
function update() {
obj.x += obj.speed
obj.y += obj.speed
render()
window.requestAnimationFrame(update)
}
第一个结构中应该做的“修饰符”是什么?
其中哪一个最好用,或者是否也有“modifier”和“requestAnimationFrame”的结构?
答案 0 :(得分:1)
如果您需要将动画锁定到时间,那么您需要一种方法来补偿例如可变帧速率,当然每帧之间也有可变时间。
修饰符可以(因为它没有显示如何计算)用于通过补偿这种变化来微调速度/运动。
但有一些事情是:不要使用诸如短时间间隔(1),因为这可能会产生整体负面影响 - 你无法以比帧率更快的速度更新任何东西,所以不要使用比16毫秒。
尝试使用requestAnimationFrame(rAF),因为这是唯一能够实际同步到监视器更新的机制。 rAF还传递了一个高分辨率的时间戳,可用于补偿器。
例如:
在60 FPS时,您可以预期帧数持续约16.67毫秒。
因此修饰符可以设置为:
modifier = timeElapsed / 16.67;
如果帧能够按时运行,理论上该值将为1。
modifier = 16.67 / 16.67 = 1;
现在,如果由于某种原因的帧迭代需要更多时间,例如double,那么你将获得2作为修饰符的值。
modifier = 33.34 / 16.67 = 2;
这在实践中如何体现?
如果你需要每帧移动100个像素,那么在我们准时的第一种情况下:
modifier = 16.67 / 16.67 = 1;
vx = 100 * modifier = 100; // @ 1 frame = 100 pixels / frame
在第二种情况下,我们花了两个帧,这意味着我们需要它移动200个像素,但由于我们之间没有得到那个帧,我们需要使用修饰符来补偿:
modifier = 33.34 / 16.67 = 2;
vx = 100 * modifier = 200; // @ 2 frames = 100 pixels / frame
所以在这里你可以看到,即使帧速率是变化的,我们也会移动我们预期会移动的东西。
要计算经过的时间,只需使用rAF参数:
var oldTime = 0 // old time
frameTime = 1000 / 60; // frame time, based on 60 FPS, in ms
function loop(time) {
var timeElapsed = time - oldTime; // get difference
oldTime = time; // store current time as old time
var modifier = timeElapsed / frameTime; // get modifier based on FPS
...
requestAnimationFrame(loop);
}
现在,所说的一切 - 修饰符也只是用来控制速度的值......: - )
答案 1 :(得分:0)
较新版本的requestAnimationFrame将返回自动画开始以来经过的时间。
您可以使用此经过时间来确定应重绘动画对象的位置。
例如,假设您有一个具有x
属性的球对象,表示它是x坐标。
如果你想让球每1000毫秒移动10个像素就可以做到这一点(未经测试!):
// set the starting x-coordinate of the ball
var ballStartingX=50;
ball.x=ballStartingX;
// get the time when the animation is started
var startingTime = performance.now();
// start the animation
requestAnimationFrame(update);
// update() is the animation loop function
function update(timestamp){
// request another frame
requestAnimationFrame(update);
// reposition the ball
// (timestamp-startTime) is the milliseconds elapsed
ball.x = ballStartingX + 10 * (timestamp-startTime)/1000;
}