2015-08-13 30 views
0

我試圖實現使用delta時間的gameloop。我從this article得到了以下代碼,但是我覺得它並沒有很好地解釋這種類型的gameloop。我已經研究過requestAnimationFrame,並且沒有任何的補充似乎是有用的。有人可以簡單地分解這個循環的工作原理嗎?Javascript - 使用delta時間的gameloop

function timestamp() { 
    return window.performance && window.performance.now ? window.performance.now() : new Date().getTime(); 
}, 

var now, 
dt = 0, 
last = timestamp(), 
step = 1/60; 

function frame() { 
    now = timestamp(); 
    dt = dt + Math.min(1, (now - last)/1000); 
    while(dt > step) { 
    dt = dt - step; 
    update(step); 
    } 
    render(dt); 
    last = now; 
    requestAnimationFrame(frame); 
} 

requestAnimationFrame(frame); 

回答

3

​​是一個特殊的計時器。與setInterval在給定的最小毫秒後重復執行回調不同,​​可變地執行以實現平滑的幀率。

問題是如何​​達到這一點。根據情況,它可能運行得更快或更慢。這意味着如果你的更新邏輯直接綁定到​​,那麼當一個字符以「每更新一步」運行時,將在一秒鐘內運行60個步驟,當​​以60fps運行時,但是當它降低到40fps的。

爲了抵消定時器的突然加速/減速,我們使用「增量時間」。而不是取決於每次迭代​​調用更新,而是檢查幀之間的時間,以確定是否是調用更新的正確時間。

因此可以說你的角色應該每隔100ms做一步。如果遊戲以60fps運行,則100ms大致每6幀。這意味着對於每次迭代,您的代碼都會檢查是否已經過了100ms。在第6幀左右,它會調用更新。現在,如果計時器以40fps運行,100ms大約是4幀。如此相同的邏輯,在每次迭代時,它會檢查是否經過了100ms。在第四幀,它會調用更新。有了這個,你可以確保不管波動情況如何,都會一直調用更新。

+2

upvote ...還提到當前版本的requestAnimationFrame會自動給動畫函數提供一個時間戳。您可以使用該時間戳來計算自上次進入動畫循環以來經過了多長時間。重要的是:經過的時間可以用來移動你的角色基於經過的時間,而不是(可能是不規則的)動畫循環計數 – markE