2012-05-25 74 views
2

我似乎有一些意想不到的結果與javascript中的幀率計數器。直到最近,櫃檯一直很好,我一直在30fps運行我的小js應用程序。Javascript setTimeout和幀速率

它使用setTimeout()(通過時間調整來抵消系統'落後')。

window.requestAnimFrame = (function() 
{ 
    return function (callback) { 
     time += FPS; 
     Heartbeat._eTime = (new Date().getTime() - Heartbeat._start); 
     var diff = Heartbeat._eTime - time; 

     Heartbeat._delta = FPS - diff; 
     Heartbeat._deltaS = Heartbeat._delta/1000; 

     window.setTimeout(callback, FPS - diff); 
    }; 
})(); 

心跳只是一個包含幀頻信息的對象。

* 這裏是我的問題:*

_MainLoopHandler: function() { 

    timer = new Date().getTime(); 
    counter = timer; 

    while (this._messages.length > 0 && (counter - timer) < 5) 
    { 
     // process messages from _messages array 
    } 

    counter = new Date().getTime(); 
    // THE ABOVE IS HAPPY AT 30 FPS 


    while ((counter - timer) < 6) { 
     1 + 1; 
    } 
    // THE ABOVE WHILE IS VERY UNHAPPY :(

} 

所以上面的代碼塊是從setTimeout的每33.33毫秒(每秒30幀)調用的函數。如果我在循環播放時進入底部,FPS計數器將以30fps的速度愉快地坐下。但是,如果我放棄它,FPS櫃檯會變得瘋狂。它達到200FPS 300FPS然後突然變爲-200FPS -10FPS 0.01FPS。它完全離開了牆壁。 while循環每個「幀」只能運行10次。

還要注意,硬編碼的值5和6只是一個檢查,看看在處理循環(用於負載平衡)時是否經過了5或6毫秒。

這是簡單的JavaScript無法處理的信息量或有任何其他人有類似的問題。

謝謝!

回答

0

我真的不知道發生了什麼,但我認爲您應該使用本地變量來控制您的時間,不斷重新評估counter並一次處理1條消息。另外,我真的不明白,最後的循環(我也改名爲變量):

_MainLoopHandler: function() { 

    var start = new Date().getTime(); 
    var current; 

    do { 
    if (this._messages.length === 0) break; 
    // process 1 message 
    current = new Date().getTime(); 
    } while (current - start < 5); 

} 

您也可以封裝在一個對象(未顯示)時機關注精簡代碼:

_MainLoopHandler: function() { 

    var timing = new Timing(); 

    do { 
    if (this._messages.length === 0) break; 
    // process 1 message 
    } while (timing.elapsed() < 5); 

} 
+0

最後一個循環只是一個「做某事」的例子。在我更新的代碼中,它實際上按節點處理SVG節點的流(因此,我只在每個循環中逐位構建SVG)。無論如何,我發現問題的原因在於如何生成幀速率計數器。 –

+0

但是,上面的代碼比我的代碼好,所以我已經做到了! –