2015-07-18 54 views
0

我正在創建一個使用javascript的fps遊戲,並且我遇到了requestAnimationFrame()的一些問題。requestAnimationFrame()javascript

,所以這是我的代碼片段,我認爲問題:

var animate=window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || 
      function(callback){ 
       window.setTimeout(callback, 1000/60); 
      }; 

function reset(){ 
    allFood=[]; 
    animationId=[]; 
    init(); 
} 

var step = function(){ 
    animationId.push(animate (step)); 
    update(); 
    render(); 
} 

function update(){ 
    if (play && !gameOver){ 
     for (var i=0; i<allFood.length; i++){ 
      allFood[i].update(); 
     } 
     for(var i=0; i<allFood.length; i++){ 
      if(allFood[i].y>HEIGHT) allFood.splice(i, 1); 
     } 
     player.update(); 
     MAX_FOOD_LENGTH=player.width*0.8; 
     MIN_FOOD_LENGTH = player.width * 0.05; 
    } 
    else if(!gameOver){ 
     mainMenu.update(); 
    } 

} 

function render(){ 
    context.clearRect(0, 0, WIDTH, HEIGHT); 
    context.fillStyle = backgroundColor; 
    context.fillRect(0, 0, WIDTH, HEIGHT); 
    if(play || gameOver){ 
     for (var i=0; i<allFood.length; i++){ 
      allFood[i].render(); 
     } 
     player.render(); 
     context.font ="40px serif"; 
     context.strokeText(score, WIDTH-200, 100); 
    } 
    else if(!gameOver){ 
     mainMenu.render(); 
    } 
    animationId.shift(); 
} 

所以問題是,當我第一次打開它運行在60fps的這工作(我測試了這一點利用的getTime(遊戲)函數和一個計數器),但是在它的遊戲結束後,我調用重置函數,並且用戶再次單擊遊戲,它開始以更高的fps運行(首先是110 fps,然後是200 ...),這與代碼混淆。有什麼我必須重置涉及我的動畫功能。我試圖把所有的東西都放在setTimeout()函數裏面,以60 fps的速率提供給用戶來控制fps,但它仍然不起作用,並且每次按下replay時fps都會不斷增加。

+0

請張貼你如何計算fps。這只是計算中的一個錯誤,它不會以超過60fps的速度運行。或者可能你有多個遊戲循環同時運行。 –

+1

使用'animationIds'清除數組不會計劃您的回調。你必須在你的'reset'函數中明確調用'cancelAnimationFrame' /'clearTimeout'。 – Bergi

+0

你可能想在這篇文章中加入'animate','update'和'render'。除此之外,我們無法幫到你。 – Joseph

回答

0

你很可能運行多個遊戲循環。 解決方案是運行一次循環,並簡單地保留一個標誌,確定是否應該呈現或更新任何東西。

var isAlive = true; 
var step = function(){ 
    animate(step); 
    if(isAlive) { 
     update(); 
     render(); 
    } 
} 
step(); 

或者明確從堆棧中的所有動畫幀復位:

function reset(){ 
    allFood=[]; 
    for(var i = 0; i < animationId.length; i++) { 
     cancelAnimationFrame(animationId[i]); 
    } 
    animationId = []; 
    init(); 
} 

然而,那麼你需要跟蹤的元素是否是animationframe,再取消。我不會將animationframe推送到該animationId數組以開始。這實際上沒有好處。相反,你可以做這樣的事情:

var rafId = 0; 

var step = function(){ 
    rafId = animate(step); 
    update(); 
    render(); 
} 

function reset(){ 
    cancelAnimationFrame(rafId); 
    allFood=[]; 
    animationId = []; 
    init(); 
} 
+0

謝謝,取消了動畫幀的工作。 –