Javascript 中的俄罗斯方块:setInterval setTimeout 行为

Tetris in Javascript : setInterval setTimeout behavior

我有问题。我正在尝试在 javascript 中玩俄罗斯方块游戏(为了学习)。但是,我不能使用 setInterval(或 setTimeout)函数。我想做的是每 2000 毫秒更改下一个案例的颜色。

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

我希望每个块都一个一个地改变颜色,但实际上它为一行中的所有行着色。好像我的间歇不起作用。

那是因为你的setInterval调用有误。

setIntervalsetTimeout 都将 Function 作为第一个参数,而(在你的例子中)你实际上是在立即调用你的函数(这就是你看到结果的原因马上)。您应该查看文档,例如 MDN:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval.

您可以将您的 downmove(i) 函数修改为 return 一个将传递给 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)。

这就是你可以做到的,但我想你以后必须为你的游戏改变它。

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