2014-01-06 32 views
1

我是新來的JavaScript和一般編程,所以不要以爲我知道很多。Javascript簡單無盡的遊戲,setTimeout問題

我創建一個簡單的JavaScript HTML5遊戲,在高速公路上的車輛下來向你(用帆布矩形表示)。我正在創造車輛產卵和運動。我的目標是讓車輛在他們之間產生一個恆定的空間,無論他們的速度如何。

我什麼時候任何滯後發生,除了工作和當速度變量被設置爲圍繞數字四個下。我做了一些研究,我相信這是因爲setTimeout不考慮滯後。由於我是新手,我不知道很多功能,我不知道如何解決這個問題,也找不到在線解決方案。

你可以看到我的代碼here的工作演示 - 混亂與開放標籤和其他滯後引起的過程,你可以嘗試設置速度變量爲5以下的數字,你會看到我來自哪裏。任何幫助表示讚賞。

<!DOCTYPE html> 
<html> 
<body> 
<canvas id="ctx" width="480" height="320" style="border:1px solid #000000;"></canvas> 
<script> 
     var ctx = document.getElementById("ctx").getContext("2d"); 

      function setIntervalX(callback, delay, repetitions) { 
       var x = 0; 
       var intervalID = window.setInterval(function() { 
        callback(); 
        if (++x === repetitions) { 
         window.clearInterval(intervalID); 
        } 
       }, delay); 
      } 

      var speed = 50 


      function game() { 
       var yAxis 
       var selectType = Math.floor((Math.random()*6)+1) 
       switch (selectType){ 
        case 1: //semi 
        case 2: 
         yAxis = -80 
         var lane = Math.floor((Math.random()*3)+1) 
          switch (lane) 
           { 
            case 1: //left lane 
             setIntervalX(function() { 
             ctx.fillStyle = "white"; 
             ctx.fillRect(200,yAxis,15,80); 
             yAxis = yAxis + 2 
             ctx.fillStyle = "black"; 
             ctx.fillRect(200,yAxis,15,80); 
             }, speed, 400); 
            break; 
            case 2: //middle lane 
             setIntervalX(function() { 
             ctx.fillStyle = "white"; 
             ctx.fillRect(230,yAxis,15,80); 
             yAxis = yAxis + 2 
             ctx.fillStyle = "black"; 
             ctx.fillRect(230,yAxis,15,80); 
             }, speed, 400); 
            break; 
            case 3: //right lane 
             setIntervalX(function() { 
             ctx.fillStyle = "white"; 
             ctx.fillRect(260,yAxis,15,80); 
             yAxis = yAxis + 2 
             ctx.fillStyle = "black"; 
             ctx.fillRect(260,yAxis,15,80); 
             }, speed, 400); 
            break; 
           } 
         setTimeout(function() {game()}, speed * 80) 
        break;  
        case 3: //bike 
         yAxis = -10 
         var lane = Math.floor((Math.random()*3)+1) 
          switch (lane) 
           { 
            case 1: //left lane 
             setIntervalX(function() { 
             ctx.fillStyle = "white"; 
             ctx.fillRect(200,yAxis,10,10); 
             yAxis = yAxis + 2 
             ctx.fillStyle = "black"; 
             ctx.fillRect(200,yAxis,10,10); 
             }, speed, 400); 
            break; 
            case 2: //middle lane 
             setIntervalX(function() { 
             ctx.fillStyle = "white"; 
             ctx.fillRect(230,yAxis,10,10); 
             yAxis = yAxis + 2 
             ctx.fillStyle = "black"; 
             ctx.fillRect(230,yAxis,10,10); 
             }, speed, 400); 
            break; 
            case 3: //right lane 
             setIntervalX(function() { 
             ctx.fillStyle = "white"; 
             ctx.fillRect(260,yAxis,10,10); 
             yAxis = yAxis + 2 
             ctx.fillStyle = "black"; 
             ctx.fillRect(260,yAxis,10,10); 
             }, speed, 400); 
            break; 
           } 
         setTimeout(function() {game()}, speed * 45)  
        break; 
        case 4: //car 
        case 5: 
        case 6: 
         yAxis = -20 
         var lane = Math.floor((Math.random()*3)+1) 
         switch (lane) 
           { 
            case 1: //left lane 
             setIntervalX(function() { 
             ctx.fillStyle = "white"; 
             ctx.fillRect(200,yAxis,10,20); 
             yAxis = yAxis + 2 
             ctx.fillStyle = "black"; 
             ctx.fillRect(200,yAxis,10,20); 
             }, speed, 400); 
            break; 
            case 2: //middle lane 
             setIntervalX(function() { 
             ctx.fillStyle = "white"; 
             ctx.fillRect(230,yAxis,10,20); 
             yAxis = yAxis + 2 
             ctx.fillStyle = "black"; 
             ctx.fillRect(230,yAxis,10,20); 
             }, speed, 400); 
            break; 
            case 3: //right lane 
             setIntervalX(function() { 
             ctx.fillStyle = "white"; 
             ctx.fillRect(260,yAxis,10,20); 
             yAxis = yAxis + 2 
             ctx.fillStyle = "black"; 
             ctx.fillRect(260,yAxis,10,20); 
             }, speed, 400); 
            break; 
           } 
         setTimeout(function() {game()}, speed * 50)   
        break;} 
       }   
      game() 

    </script> 

    </body> 
    </html> 
+0

setInterval只保證**執行之間的**最小**時間。如果其他代碼阻止您的間隔可能會更長。相反,每當間隔被觸發時,檢查時間並根據自上次迭代以來的時間計算出需要完成的工作。 – 2014-01-06 06:47:57

+0

_「將速度變量設置爲低於5的數字」_ - 對於遊戲動畫,您不需要在靠近該小的任何位置使用超時/間隔。我的意思是,5ms延遲相當於200幀/秒,但20ms間隔(50幀/秒)應該足夠快。不管感知幀率如何,如果您嘗試的時間間隔太小,您的代碼將導致其自身的滯後,因爲它無法在每個時間間隔之間完成所有必需的處理。 – nnnnnn

+0

因此,我應該讓車輛每次向下移動兩個以上的像素,以便我可以獲得所需的速度? – tysonsmiths

回答

1

您應該只有1個主setInterval更新所有內容。
延遲不應該是一個問題,特別是對於這個規模的項目。

+0

如果你的意思是對整個函數使用setInterval,這對我不瞭解。每輛車都有不同的長度,所以他們需要自己的計時器,因此每輛車之間的空間相同。我不確定它的滯後是否導致了問題,但是當速度降到這些較低的數字時,遊戲並沒有做到它應該做的事情,我也無法解決它。 (我認爲這是滯後的原因是因爲每次你打開一個標籤,並回到它的全部搞砸了) – tysonsmiths

+0

你的車輛應該是一個對象,具有不同的屬性,如他們的長度/空間/圖像等...所有車輛應該在一個陣列中。通常,遊戲運行在30-60 fps之間。遊戲中的對象都以相同的時間間隔更新。不同的是它們每幀移動多少個像素。 (例如:0.1像素) – RainingChain