2017-08-08 23 views
0

問題があります。私はJavaScriptのテトリスゲームをしようとしています(学習のため)。しかし、私はsetInterval(またはsetTimeout)関数を使用することはできません。私がしたいのは、2000msごとに次のケースの色を変えることです。テトリス・イン・ジャバスクリプト:setInterval setTimeoutの動作

HTMLのCODE:

<!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 CODE:

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); 
} 

は、私はすべてのブロックを一つの色1を変更したいのですが、実際に色すべて行の行。それは私の間隔がうまくいかないようです。あなたのsetInterval呼び出しが間違っているためです

enter image description here

+0

リーディング[ドキュメント](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval)は常に有用です。 'setInterval'を使う場合は' for'ループを削除するか、代わりに 'setTimeout'を使います。この場合、' i'の値にクロージャーの問題があります... – Teemu

+0

ありがとう。私は閉鎖についてまだ読んでいないが、私はこの小さなプロジェクトには必要ないと考えていた。 – WaLinke

答えて

2

setIntervalsetTimeout両方(あなたの例では)あなたが実際に(あなたは結果を見ている理由はすぐだ)あなたはすぐに機能呼び出している間に、最初のパラメータとしてFunctionを取ります。 MDN:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setIntervalなどのドキュメントをご覧ください。 (してください

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

あなたはsetIntervalに渡される新しい関数を返すために、あなたのdownmove(i)機能を変更することができますか、あなたはこのような間隔の内側にあなたdownmove呼び出しをラップするために無名関数を使用することができますi変数を適切に処理するためにIIFEを使用していることに注意してください。これはforループでlet i = 0を使用することで回避できますが、なぜこれが必要かは別の話題です。 JavaScript closure inside loops – simple practical example)。


あなたのコードとの1つの以上の問題があります - あなたは順番に色を変更したいのですが、(でも修正して)あなたの実装では、時間の言った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 2番目の関数は動作しません。なぜなら、 "downmove()"では、関数を呼び出して結果( "null")をsetIntervalに渡すからです。 setInterval(downmove、...)と比較して、関数自体を渡します! –

関連する問題