2017-08-08 55 views
0

我遇到問題。我正在嘗試在JavaScript中進行俄羅斯方塊遊戲(爲了學習)。但是,我不能使用setInterval(或setTimeout)函數。我想要做的是每2000ms更改下一個案例的顏色。使用Javascript的俄羅斯方塊:setInterval setTimeout行爲

HTML代碼:

<!DOCTYPE html> 
<html lang="fr"> 
<head> 
    <meta charset="UTF-8"> 
    <title>PROJET : PROGRAMMATION COTE CLIENT</title> 
    <link rel="stylesheet" type="text/css" href="index.css"> 
</head> 
<body> 
    <div class="all"> 
     <div id="A"> 
      <span id="pos1A"></span> 
      <span id="pos2A"></span> 
      <span id="pos3A"></span> 
      <span id="pos4A"></span> 
      <span id="pos5A"></span> 
      <span id="pos6A"></span> 
      <span id="pos7A"></span> 
      <span id="pos8A"></span> 
      <span id="pos9A"></span> 
      <span id="pos10A"></span> 
     </div> 
    </div> 
    <script src="classes.js"></script> 
    <script src="indexjs.js"></script> 
    </body> 
</html> 

CSS代碼:

.all { 
    display: flex; 
    flex-direction: column; 
} 
.all > div { 
    display: flex; 
    flex-direction: row; 
} 
.all > div > span { 
    width: 20px; 
    height: 20px; 
    border: 1px solid gray; 
} 

JS代碼:

var array = ['pos1A','pos2A','pos3A','pos4A','pos5A','pos6A','pos7A','pos8A','pos9A','pos10A ']; 
function downmove(i) { 
    var element = document.getElementById(array[i]); 
    element.style.backgroundColor = 'green'; 
    console.log(element); 
} 
var i; 
for(i=0;i<10;i++) { 
    setInterval(downmove(i),2000); 
} 

我希望每一個塊一個改變顏色之一,但實際上它的顏色全部連續的行。這就像我的間隔不起作用。

enter image description here

+0

閱讀[該文檔(https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval)總是有用的。你也應該放棄'for'循環,如果你打算使用'setInterval',或者使用'setTimeout'來代替,在這種情況下會出現一個'i'值的關閉問題... – Teemu

+0

謝謝。我還沒有看過關閉,我在想,我不需要這個小項目。 – WaLinke

回答

2

那是因爲你的setInterval電話是錯誤的。

setIntervalsetTimeout都採取Function作爲第一個參數,而(在你的例子),你實際上是在調用你函數立即(這就是爲什麼你看到結果的時候了)。您應該查看文檔,例如MDN:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval

您可以修改您的downmove(i)函數返回將被傳遞到setInterval一個新的功能,或者您也可以使用匿名函數來包裝你喜歡這個區間內downmove電話:

for (i = 0; i<10; i++) { 
    setInterval(
     (function (idx) { downmove(idx); })(i), 
     2000 
    ); 
} 

(請請注意,我正在使用IIFE來正確處理i變量,這可以通過在for循環中使用let i = 0來避免,但爲什麼需要這是另一個需要討論的話題,您可以在這裏閱讀更多信息: JavaScript closure inside loops – simple practical example)。


還有一個問題,您的代碼 - 要依次改變顏色,但你實現(甚至與修訂)將上述2秒的時間後即刻運行的每個顏色變化。爲了解決這個問題,你必須保持以前彩色行的軌跡並每2秒增加一次。

這裏的固定執行一個簡單的例子:

let idx = 0; 

const intervalID = setInterval(function() { 
    if (idx >= 10) { 
     // Maximum row reached, break the loop... 
     clearInterval(intervalID); 

     return; 
    } 

    downmove(idx); 

    idx++; 
}, 2000); 

(沒有必要在這裏使用for-loop)。

+0

非常感謝您的回答。我來自C++,這些是我不熟悉的概念。在我投入這個項目之前,我必須更多地瞭解基礎知識。非常感謝有用的鏈接,祝你有美好的一天。 – WaLinke

1

這就是你如何做到這一點,但我想你將不得不稍後改變它爲你的遊戲。

var array = ['pos1A','pos2A','pos3A','pos4A','pos5A','pos6A','pos7A','pos8A','pos9A','pos10A ']; 

var i = 0, 
    interval; 
    max_i = 9; 

function downmove() { 
    var element = document.getElementById(array[i]); 
    element.style.backgroundColor = 'green'; 
    console.log(element); 
    i++; 

    if (i === max_i) clearInterval(interval); 
} 

interval = setInterval(downmove, 2000); 
+1

我試過這個,它的工作原理,但我不明白你爲什麼要調用setInterval(downmove,2000)而不是setInterval(downmove(),2000) 它適用於第一個,但它不適用於第二個只顯示綠色的第一塊。順便說一句,謝謝你的回答和你的時間。 – WaLinke

+0

@WaLinke第二個不起作用,因爲用「downmove()」調用該函數並將結果(即「null」)傳遞給setInterval。與setInterval(downmove,...)相比,你傳遞函數本身! –