在循环内的特定时间之后调用函数

时间:2016-07-03 15:24:48

标签: javascript jquery

我正在尝试创建一个名为Simon(https://en.wikipedia.org/wiki/Simon_(game)

的记忆游戏

我已经完成了一切。唯一的问题是,每当必须显示一个完整的序列时(当播放器按下错误的按钮,或者如果添加了新的序列),所有的声音都会同时播放,而按钮只会闪烁第二。如何制作它以便首先显示一个按钮,播放它的声音然后继续播放下一个按钮? 我尝试在for循环中设置setTimeout,但它给出了一个错误,说'btn'未定义。

这是我的代码:

$(document).ready(function(){
var button = $(".buttons");
var redbtn = $("#red");
var bluebtn = $("#blue");
var greenbtn = $("#green");
var yellowbtn = $("#yellow");
var allButtons = [redbtn, bluebtn, greenbtn, yellowbtn];
var sequence, playerTurn, wins, strict, seqPosition;

startGame();

function startGame() {
    console.log("Starting game...");
    strict = confirm("Would you like to play the difficult mode?");
    sequence = [];
    playerTurn = false;
    wins = 0;
    computerTurn();
}

function computerTurn() {
    seqPosition = 0; // position of player in sequence
    $("#count").html(wins);
    console.log("It's the computer's turn");
    if (wins === 20) {
        alert("You win!");
        startGame();
    } else {
        sequence.push(Math.floor(Math.random() * 4));
        console.log("Picked new button");
        playSequence();
    }
}

function playSequence() {
    setTimeout(function(){
        console.log("Playing the sequence... " + sequence.toString());
        playSound(allButtons[sequence[0]]);
        var progress = false;
        for (var i = 1; i < sequence.length; i++){
            console.log(i);
            playSound(allButtons[sequence[i]])
        }
        playerTurn = true;
    }, 1000)
}

function playSound(btn) {
    btn.toggleClass("act");
    console.log("Playing the sound...");
    var link;
    switch (parseInt(btn.attr("val"))) {
            case 0:
                link = "https://s3.amazonaws.com/freecodecamp/simonSound1.mp3";
                break;
            case 1:
                link = "https://s3.amazonaws.com/freecodecamp/simonSound2.mp3";
                break;
            case 2:
                link = "https://s3.amazonaws.com/freecodecamp/simonSound3.mp3";
                break;
            case 3:
                link = "https://s3.amazonaws.com/freecodecamp/simonSound4.mp3";
                break;
    }
    var audio = new Audio(link);
    audio.play();
    setTimeout(function(){
        btn.toggleClass("act")
    }, 700);
}

button.on("click", function(){
    if (playerTurn) {
        var btnVal = parseInt($(this).attr("val"));
        if (btnVal === sequence[seqPosition]) {

            console.log("Correct button pressed!");
            playSound(allButtons[sequence[seqPosition]]);
            seqPosition++;
            console.log("seq position is " + seqPosition);
            setTimeout(function(){
                if (seqPosition === sequence.length) {
                    playerTurn = false;
                    wins++;
                    computerTurn();
                }
            }, 1000);

        } else {
            playerTurn = false;
            if (strict) {
                alert("You lose!");
                startGame();
            } else {
                console.log("Incorrect button pressed!");
                seqPosition = 0;

                var audio = new Audio("horn.mp3");
                audio.play();
                playSequence();
            }
        }
    }
});

});

小提琴:https://jsfiddle.net/otep6yx0/

2 个答案:

答案 0 :(得分:3)

使用setTimeout不会中断for循环:for循环将以毫秒为单位循环到终点,无论setTimeout如何。

另一种方法是使用在setTimeout中调用自身的IIFE:

function playSequence() {

        console.log("Playing the sequence... " + sequence.toString());
        playSound(allButtons[sequence[0]]);

        var i = 0
        var progress = false;

        (function loop(){
            if(i++ == sequence.length) return;

            setTimeout(function(){
                playSound(allButtons[sequence[i]])
                loop();
        },1000);    

        })();
        playerTurn = true;

}

这是您更新的小提琴:https://jsfiddle.net/gerardofurtado/oz2gjved/

答案 1 :(得分:2)

我建议你:

所以代码是:

$(document).ready(function () {
  var button = $(".buttons");
  var redbtn = $("#red");
  var bluebtn = $("#blue");
  var greenbtn = $("#green");
  var yellowbtn = $("#yellow");
  var allButtons = [redbtn, bluebtn, greenbtn, yellowbtn];
  var sequence, playerTurn, wins, strict, seqPosition;

  startGame();

  function startGame() {
    console.log("Starting game...");
    strict = confirm("Would you like to play the difficult mode?");
    sequence = [];
    playerTurn = false;
    wins = 0;
    computerTurn();
  }

  function shuffleArray(array) {
    for (var i = array.length - 1; i > 0; i--) {
      var j = Math.floor(Math.random() * (i + 1));
      var temp = array[i];
      array[i] = array[j];
      array[j] = temp;
    }
    return array;
  }

  function sleep(milliseconds) {
    var start = new Date().getTime();
    for (var i = 0; i < 1e7; i++) {
      if ((new Date().getTime() - start) > milliseconds) {
        break;
      }
    }
  }

  function computerTurn() {
    seqPosition = 0; // position of player in sequence
    $("#count").html(wins);
    console.log("It's the computer's turn");
    if (wins === 20) {
      alert("You win!");
      startGame();
    } else {
      sequence = shuffleArray([0, 1, 2, 3]);
      console.log("Picked new button");
      playSequence();
    }
  }

  function playSequence() {
    for (var i = 0; i < sequence.length; i++) {
      (function (i) {
        setTimeout(function () {
          console.log("Playing the sequence... " + sequence.toString());
          playSound(allButtons[sequence[0]]);
          var progress = false;
          console.log(i);
          playSound(allButtons[sequence[i]]);
          if ((i + 1) == sequence.length) {
            setTimeout(function () {
              $(".buttons.act").removeClass('act');
              playerTurn = true;
            }, 1000);
          }
        }, i * 1000);
      })(i);
    }
  }

  function playSound(btn) {
    $(".buttons.act").removeClass('act');
    btn.toggleClass("act").show();
    console.log("Playing the sound...");
    var link;
    switch (parseInt(btn.attr("val"))) {
      case 0:
        link = "https://s3.amazonaws.com/freecodecamp/simonSound1.mp3";
        break;
      case 1:
        link = "https://s3.amazonaws.com/freecodecamp/simonSound2.mp3";
        break;
      case 2:
        link = "https://s3.amazonaws.com/freecodecamp/simonSound3.mp3";
        break;
      case 3:
        link = "https://s3.amazonaws.com/freecodecamp/simonSound4.mp3";
        break;
    }
    var audio = new Audio(link);
    audio.play();
  }

  button.on("click", function (e) {
    if (playerTurn) {
      var btnVal = parseInt($(this).attr("val"));
      if (btnVal === sequence[seqPosition]) {
        console.log("Correct button pressed!");
        playSound(allButtons[sequence[seqPosition]]);
        seqPosition++;
        console.log("seq position is " + seqPosition);
        if (seqPosition === sequence.length) {
          playerTurn = false;
          wins++;
          computerTurn();
        }
      } else {
        playerTurn = false;
        if (strict) {
          alert("You lose!");
          startGame();
        } else {
          console.log("Incorrect button pressed!");
          seqPosition = 0;
          var audio = new Audio("horn.mp3");
          audio.play();
          playSequence();
        }
      }
    }
  });
});
h1 {
  font-size: 3em;
}

.buttons {
  cursor: pointer;
  height: 200px;
  width: 200px;
  display: inline-block;
  vertical-align: middle;
}

.act {
  background-color: black !important;
}

#red {
  background-color: red;
}

#red:active {
  background-color: black;
}

#blue {
  background-color: blue;
}

#blue:active {
  background-color: black;
}

#green {
  background-color: green;
}

#green:active {
  background-color: black;
}

#yellow {
  background-color: yellow;
}

#yellow:active {
  background-color: black;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>


<div class="container-fluid">
    <h1>Simon Game</h1>

    <div class="buttons" id="red" val="0"></div>
    <div class="buttons" id="blue" val="1"></div>
    <div class="buttons" id="green" val="2"></div>
    <div class="buttons" id="yellow" val="3"></div>

    <div class="row">
        <div class="col-md-5"></div>
        <div class="col-md-1"><h4>Count: <span id="count">0</span></h4></div>
    </div>
</div>