2012-08-13 51 views
15

因此,也许这里总脑f。 setInterval()的语法非常清晰。每x毫秒做一次。如何最好地转换为使用requestAnimationFrame()HTML Canvas Interval vs RequestAnimationFrame

我具有约300的对象,并且每个被认为以一定间隔(每隔8,6,2,等秒)执行动画序列?我怎样才能最好地使用requestAnimationFrame()这个被称为~60次的秒来完成呢?可能有一个简单的答案,我只是,对我来说,无法弄清楚。

回答

10

​​是相当低的水平,它只是做了什么,你已经说过:大致被调用以60fps(假设浏览器能够跟上这样的速度)。所以通常情况下你需要在其上创建一些东西,就像有一个游戏循环的游戏引擎一样。

在我的游戏引擎,我有这个(paraphased /简体这里):

window.requestAnimationFrame(this._doFrame); 

... 

_doFrame: function(timestamp) { 
    var delta = timestamp - (this._lastTimestamp || timestamp); 

    for(var i = 0, len = this.elements.length; i < len; ++i) { 
     this.elements[i].update(delta); 
    } 

    this._lastTimestamp = timestamp; 

    // I used underscore.js's 'bindAll' to make _doFrame always 
    // get called against my game engine object 
    window.requestAnimationFrame(this._doFrame); 
} 

然后在我的游戏引擎的每个元素知道如何自我更新。在你的情况下,每个应该更新单元,每2,6 8秒需要保持多少时间已经过去了跟踪并相应更新:

update: function(delta) { 
    this.elapsed += delta; 

    // has 8 seconds passed? 
    if(this.elapsed >= 8000) { 
      this.elapsed -= 8000; // reset the elapsed counter 
      this.doMyUpdate(); // whatever it should be 
    } 
} 

随着​​是相当低的水平画布API,它们是动画和游戏引擎等构件。如果可能的话,我会尝试使用像cocos2d-js这样的现有软件或者其他任何现有软件。

+0

的感谢!这几乎是我之后的事情。多一点挖掘揭示了这一点:https://gist.github.com/1002116这基本上是你所拥有的。我认为我的错误是试图让它在一个主循环内工作,而不是每个对象的循环。 – 2012-08-14 02:35:55

10

要强制requestAnimationFrame坚持一个特定的FPS,你可以一次使用两个!

var fps = 15; 
function draw() { 
    setTimeout(function() { 
     requestAnimationFrame(draw); 
     // Drawing code goes here 
    }, 1000/fps); 
} 

有点奇怪,但不是世界上最混乱的东西。

您也可以以得出需要根据自上次通话的时间差进行更新对象使用requestAnimationFrame不是FPS,但随时间推移:

var time; 
function draw() { 
    requestAnimationFrame(draw); 
    var now = new Date().getTime(), 
     dt = now - (time || now); 

    time = now; 

    // Drawing code goes here... for example updating an 'x' position: 
    this.x += 10 * dt; // Increase 'x' by 10 units per millisecond 
} 

这两个片段是从this fine article,其中包含其他细节。

顺便说一下这个问题问得好!我不认为我已经看到了这个回答就这样无论是(和我在这里太多)

+0

也谢谢!第二个片段接近我之后的片段。正如我在第一个答案的评论中所述,这看起来像我之后:https://gist.github.com/1002116 – 2012-08-14 02:37:05

+0

这两个答案都非常棒 - 非常感谢! – 2012-08-14 02:43:38

+0

requestAnimationFrame发送一个时间戳作为参数。根据我的经验,创建一个新的Date对象比使用提供的时间戳要昂贵得多。 – 2012-08-14 03:24:00