首页 > 解决方案 > 在下一次循环迭代之前暂停直到事件完成(Simon Game)

问题描述

全部。致力于创建一个 Simon 游戏,类似于此处找到的版本:https:Simon Game(我建议去玩这个游戏,这样你就可以了解游戏应该如何工作以及我想要做什么。)

现在我有一个名为“gamePattern”的数组设置,以便它包含一个从 1-4 随机生成的值的列表。这些值决定了用户需要猜测什么颜色的按钮,并与特定的按钮和按钮声音相关联。因此,例如,当游戏开始时,会在 gamePattern 数组中生成一个数字,这将在我与该值关联的按钮和与该值关联的声音上触发动画。然后用户需要猜测要按下哪个按钮。如果用户猜对了按钮,则在 gamePattern 数组的下一项中生成一个新值,然后用户单击与数组第 1 项中的值相关联的按钮和与第 2 项中的值相关联的按钮数组。检查他们的猜测,然后将生成一个新数字,

然而,我试图通过 gamePattern 数组循环播放与数组每个项目中的值相关联的声音和按钮动画;我希望它在执行下一次循环迭代并播放下一个声音和动画(按钮的淡入/淡出)之前暂停直到动画和声音播放完毕。

这是我的游戏代码(请在你的批评中表现得很好。我是一个新程序员,所以代码看起来很丑,写得也很糟糕。希望不要太糟糕以至于你无法理解它):


var buttonColors = ["red", "blue", "green", "yellow"];
var gamePattern = [];
var userClickedPattern = [];
var level = 0;

//Sets audio file name of audio file and plays audio file
function playChosenColorSound(chosenColor){
    var audioFilePath = 'sounds/' + chosenColor + '.mp3';
    var sound = new Audio(audioFilePath);
    sound.play();
}


function usersChoice(e){
    var userChosenColor = e.target.id; //Determines what button color the user pressed
    userClickedPattern.push(userChosenColor);
    playChosenColorSound(userChosenColor); //Plays sound of users chosen button color
    $("#" + userChosenColor).fadeOut(200).fadeIn(200); //Animates button user pressed with mouse.
    

    //Turns off users ability to click a button until new sequence is generated
    $(".btn").off("click"); 
    checkAnswer();
}

//Generates random number used to choose next button color from buttonColors array.
function nextSequence(){

    level++; //Increases level count

    $("#level-title").html(`Level: ${level}`); //Changes H1 title to show level

    //Choses random color from buttonColors array from random generated number.
    var randomChosenColor = buttonColors[Math.round(Math.random()*3)];

    gamePattern.push(randomChosenColor);

    //Fades in/out the buttons associated with the colors listed in the gamePattern array in sequence
    for (var i = 0; i < gamePattern.length; i++){
        $("#" + gamePattern[i]).fadeOut(200).fadeIn(200,playChosenColorSound(gamePattern[i]));
    }
    

    $(".btn").click(usersChoice); //Gives user ability to click button after gamePattern animations has played

}

function checkAnswer(){

    console.log(gamePattern);
    console.log(userClickedPattern);

    if(userClickedPattern[userClickedPattern.length - 1] === gamePattern[gamePattern.length - 1]){
        nextSequence();
    }
    else{
        wrongAnswer();
    }
    
}

function start(){
    nextSequence();
    $(document).off("keypress");
}

//Let's user know that their choice was wrong. 
function wrongAnswer(){
    var audioFilePath = 'sounds/wrong.mp3';
    var sound = new Audio(audioFilePath);
    sound.play();
    $("body").css("background-color", "red");
    $("#level-title").html("That was the wrong answer. \n Press a Key to Play Again");
    $(document).keypress(resetGame);
}

//Resets level value, gamePattern and userClickedPattern array so user can play again.
function resetGame(){
    $("body").css("background-color", "#011F3F");
    gamePattern = [];
    userClickedPattern = [];
    level = 0;
    start();
}

$(document).keypress(start);

有问题的循环在 nextSequence() 函数中。

非常感谢大家。感谢您提供的任何反馈、提示或建议。

标签: javascriptarrays

解决方案


Audio api 有一个结束的事件。你可以用它来解决一个 Promise。你可以对动画(animationend)做同样的事情。我不确定您的声音和动画持续时间是否相同,或者您是否需要在进入下一个循环之前完成两者,但是您可以调用这些 Promises,Promise.all然后继续下一个序列。

也许是这样的:

generateSoundPromise(color) {
  return new Promise(resolve) {
    const audioFilePath = `sounds/${chosenColor}.mp3`;
    const sound = new Audio(audioFilePath);

    sound.addEventListener('ended', resolve);
    sound.play();
  }
}

generateAnimationPromise(color) {
  return new Promise(resolve) {
    yourElement.addEventListener('animationend', resolve);
  }
}

await Promise.all([
  generateSoundPromise('blue'),
  generateAnimationPromise('blue'),
]);

// Perform next sequence

推荐阅读