内置更新功能的修改器HTML5 Canvas Game?

时间:2014-03-04 19:08:53

标签: javascript html5 loops canvas

我在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”的结构?

2 个答案:

答案 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;

}