修改器内部更新功能HTML5画布游戏?

人气:1,130 发布:2022-09-19 标签: javascript html5 loops canvas

问题描述

我在HTML5,Canvas游戏的update函数中看到了这种类型的结构,它有一个修饰符变量:

  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)}   

第一个结构中修饰符应该是什么?

其中哪一个是最好的使用,或者是也有结构与修饰符和requestAnimationFrame?

解决方案

如果你需要你的动画被锁定到时间,那么你需要一种方法来补偿例如可变帧速率,当然也可以在每个帧之间有可变的时间。

修改器可以(因为它未显示如何计算)用于通过补偿此变化来微调速度/运动。

A几件事情:不要使用如短时间间隔(1),因为这可能有一个整体的负面影响 - 你将无法更新任何更快的帧速率无论如何,所以使用不超过16毫秒。 / p>

尝试使用requestAnimationFrame(rAF),因为这是唯一能够实际同步到监视器更新的机制。

b $ b

在60 FPS,你会期望一个框架持续约16.67ms。

所以修改器可以设置为:

  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; //帧时间,基于60 FPS,在ms  函数循环(时间){  var timeElapsed = time  -  oldTime; // get difference  oldTime = time; //将当前时间存储为旧时间  var modifier = timeElapsed / frameTime; //获取基于FPS的修饰符  ...   requestAnimationFrame(loop); }   

现在,所有说的修饰符可以 >只是用于控制速度的值...: - )

I've seen this kinda structure inside the update function in HTML5, Canvas games, with a "modifier" variable:

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)

Now I use myself this structure:

function update() {
    obj.x += obj.speed
    obj.y += obj.speed

    render()

    window.requestAnimationFrame(update)
}

What is the "modifier" supposed to do in the first structure?

And which one of them is the best to use, or is there maybe structure with both "modifier" and "requestAnimationFrame" too?

解决方案

If you need your animation to be locked to time then you need a way to compensate for for example variable frame rates which of course then also have variable time between each frame.

A modifier could (as it's not shown how it is calculated) be used to fine-tune the speed/movement by compensating for this variation.

A couple of things though: don't use such as short time interval (1) as this could have an overall negative effect - you won't be able to update anything faster than the frame rate anyways so use nothing less than 16 ms.

Try to use requestAnimationFrame (rAF) instead as this is the only mechanism able to actually synchronize to the monitor update. rAF also passes a high-resolution timestamp which you can use for the compensator.

For example:

At 60 FPS you would expect a frame to last about 16.67ms.

So a modifier could be set as:

modifier = timeElapsed / 16.67;

If frame was able to run on time the value would be 1 in theory.

modifier = 16.67 / 16.67 = 1;

Now, if a frame iteration for some reason took more time, for example the double, you would get 2 as value for modifier.

modifier = 33.34 / 16.67 = 2;

How does this manifest in practical terms?

If you needed to move 100 pixels per frame then in the first situation when we were on time:

modifier = 16.67 / 16.67 = 1;
vx = 100 * modifier = 100;     // @ 1 frame  = 100 pixels / frame

In the second case we spent two frames which means we needed it to move 200 pixels but since we didn't get that frame in between we need to use the modifier to compensate:

modifier = 33.34 / 16.67 = 2;
vx = 100 * modifier = 200;     // @ 2 frames = 100 pixels / frame

So here you see even if the frame rate was variant we moved what we expected to move anyways.

To calculate time elapsed simply use the rAF argument:

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);
}

Now, all that being said - modifier could also be just a value used to control speed... :-)

218