我需要帮助来调试记忆游戏的代码

问题描述 投票:2回答:3

我正在用我正在网页上的JavaScript制作记忆游戏。我有3个分别标记为1、2和3的按钮,它们应该按一定顺序先变绿再变白。顺序是随机的,每转增加1。然后应该假定播放器以正确的顺序单击按钮。问题是,当我将按钮的颜色更改为绿色时,而不是每个按钮都以正确的顺序先变绿再变白,而是一次变绿。这是JavaScript逻辑:

function lightUp() {
  var arrayOrder = gameOrder.split("");
  for(let i = 0; i < arrayOrder.length; i++) {
    document.getElementById("but" + arrayOrder[i]).style.backgroundColor = "green";
    setTimeout(function() {
      document.getElementById("but" + arrayOrder[i]).style.backgroundColor = "white";
    }, 1000);
  }
}

[gameOrder是数字顺序的字符串(例如“ 12331232123”)

我认为游戏由于setTimeout的工作方式而无法正常工作,我相信它会在后台暂停,并允许for循环继续运行,而不是暂停整个过程一秒钟(这就是我正在尝试的方法要做)。

我希望每个按钮先打开然后关闭,然后再下一个按钮更改颜色。因此,如果顺序是1 2 3,我希望按钮1变成绿色,然后白色,然后按钮2变成绿色,然后白色,最后让按钮3变成绿色,然后白色。

javascript
3个回答
2
投票

正如espacarello指出的那样,JS不是同步的。您可以使函数异步并等待setTimeout

这是我使用JS“动画化”事物的首选方式:

async function lightUp() {
  const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
  for (const i of gameOrder.split('')) {
    const el = document.getElementById(`but${i}`);
    el.style.backgroundColor = 'green';
    await sleep(1000);
    el.style.backgroundColor = 'white';
  }
}

这保持简单优雅,而不会因大量回调,递归或嵌套setTimeout而使您的代码混乱。它只是一个功能。


Edit:重要的是要注意IE不支持Promises或Arrow Function语法。请参阅其他两个答案以获得更广泛的支持。


2
投票

您的代码存在的问题是for循环可以立即运行,而不会延迟。您在编写代码时认为间隔会导致循环等待执行。问题是,它会立即运行而无需等待。

使用队列类型的系统在其中运行步骤,完成后将运行下一个,直到您用尽所有要做的事情。

var steps = [1,2,3,2,1,3,1]
var delay = 1000
var step = 0

function next () {
  var button = document.getElementById('btn' + steps[step])
  button.classList.add("on")
  window.setTimeout( function () {
    button.classList.remove("on")
    step++
    if(step<steps.length) next()
  }, delay)  
}

next()
.on {
  background-color: green;
}
<button id="btn1">One</button>
<button id="btn2">Two</button>
<button id="btn3">Three</button>

1
投票

您可以按照以下步骤做...

function lightUp() {
  var arrayOrder = gameOrder.split("");
  for (let i = 0; i < arrayOrder.length; i++) {
    (function(i) {
       setTimeout(function() {
         document.getElementById("but" + arrayOrder[i]).style.backgroundColor = "green";
       }, 1000 * i - 1000);
      setTimeout(function() {
        document.getElementById("but" + arrayOrder[i]).style.backgroundColor = "white";
      }, 1000 * i); // schedules excution increasingly for each iteration
    })(i);
  }
}

要了解有关其工作原理的更多信息,请参阅this answer

© www.soinside.com 2019 - 2024. All rights reserved.