2014-02-15 66 views

回答

6

要控制你的遊戲的幀速率:

  • 使用​​(在window LIB)。
  • 衡量兩次通話之間的時間。
  • 如果實際幀速率太高,則丟棄該幀。
  • 如果自上一幀以來經過的時間過長,只考慮一個幀。如果遊戲被標籤出來/應用程序被操作系統閒置,就會發生這種情況。

requestAnimationFrame(callback)將在瀏覽器準備好繪製時觸發回調權。
所以它會觸發屏幕的所有fps速率(只要你的繪圖/計算不需要太多時間)。回調需要一個時間參數,根據瀏覽器的不同,這個時間參數是高分辨率(Dart VM,Chrome js)或低分辨率(FF,Sf)的當前時間。

關於幀速率的唯一選擇是讓幀速率低於或等於屏幕的速率。
所以,如果你想要一個25Hz的,並且你在一個50Hz的屏幕上,那麼通過將一個幀放在兩個幀上,你將會達到25Hz。精細。
但是,如果您在60Hz屏幕上要求25Hz,則30 fps仍然過高,所以大多數時候您將獲得15 fps。 (也許一個好主意不會將fps限制爲常數,而是計算所需fps所需的比率(對於> = 100Hz屏幕爲1/2或1/3或甚至1/4或更大)

無論如何,這裏是一個遊戲循環,它將控制遊戲的fps(具有恆定的限制),並處理遊戲時間,這意味着遊戲已經過去的時間(如果用戶退出,這將與實時不同,其停止requestAnimationFrame以及定時器):

class Game { 

    num gameTime = 0 ; // actual time elapsed within game since game started. 

    num minFrameTime = 20 ; // limit to 50 fps. 

    num maxFrameTime = 200 ; // consider game was tabbed out after 200ms 

    num get currentFrameRate => (_lastdt == 0) ? -1 : 1000/_lastdt ; 

    void launchAnimation() { 
     window.requestAnimationFrame(_getAnimateTime);  
    } 

    void _animate(num animateCallTime) { 
     window.requestAnimationFrame(_animate); // keep animating. 
     // ---- time handling 
     num dt = animateCallTime - _lastAnimateTime ; // time elapsed since last frame. 
     if (dt<minFrameTime) return; // frame rate too high, drop this frame. 
     if (dt>maxFrameTime) dt = minFrameTime ; // consider just one frame elapsed if game tabbed out. 
     gameTime += dt ; 
     _lastdt = dt ; 
     _lastAnimateTime = animateCallTime ; 
     // ---- actual animation 
     // draw : must be done first (we're on sync with screen) 

     // update 
    } 

    void _getAnimateTime(num animateCallTime) { 
     _lastAnimateTime = animateCallTime ; // now we have start time with right resolution 
     window.requestAnimationFrame(_animate); // start animating 
    } 

    num _lastAnimateTime = 0; 

    num _lastdt = 0; // last valid frame duration. 
} 

的Rq:我建議限制到60幀爲桌面,每秒30幀的移動
RQ2:代碼中的bove實際上是我使用的遊戲循環的簡化版本,它比3倍大,可以解決動畫循環的所有問題(全部......或者至少是我看到的:-))。