【问题标题】:Simon game javascript, how do I synchronize the lights of the buttons not to step on each other with animation() and delay() JQUERY?西蒙游戏javascript,如何使按钮的灯与animation()和delay()JQUERY同步不相互踩踏?
【发布时间】:2016-09-07 00:25:25
【问题描述】:

我正在做一个西蒙游戏,我将不透明度从 1 提高到 0.3,然后在每次序列出现时回到 1。它几乎可以工作,但出现问题的情况是,当我在序列中连续使用相同的颜色时。 GREEN, GREEN, RED, BLUE 例如只显示一个绿色按键和一个红色和一个蓝色按键。这是时间问题,因为逻辑工作正常。这是我的代码

$(document).ready(function(){


 let simon={
      colors:["green","red","yellow","blue"],
      sequence:[],
      userSequence:[],
      strict:false,
      buttonSounds : {},
      init: function(){
        let objectContext=this;


        $("#start").on("click",function(){

           objectContext.setSounds();


            //executes for the first time
  objectContext.emptyAllSequences();
           //I generate the first of the sequence
      objectContext.generateAndAddRandomColor();
           //I display the sequence on the board
      objectContext.displaySequenceOnBoard();


           }); 

          $("#title").addClass('tada animated');  

          $("#strict").on("click",function(){
            $(this).toggleClass("active");

            if($(this).hasClass("active")){
              objectContext.strict=true;
            }else{
              objectContext.strict=false;
            }

          });

       $(".button").on("click",function(){
            const color=$(this).attr("data-color");
           objectContext.lightButton(color,0);
            objectContext.userSequence.push(color);


            let isSequenceCorrect=objectContext.checkUserSequence();

       /*  console.log("sequenceCorrect "+isSequenceCorrect);
         console.log("sequence "+objectContext.sequence);
         console.log("user sequence "+objectContext.userSequence);
         console.log("user sec length "+objectContext.userSequence.length);
         console.log("sec length "+objectContext.sequence.length);*/
            if(objectContext.userSequence.length===objectContext.sequence.length || !isSequenceCorrect){

                if(isSequenceCorrect){
         setTimeout(function(){objectContext.generateAndAddRandomColor();
                  objectContext.displaySequenceOnBoard();
                  //reset the userSequence to check the whole sequence again 
                  objectContext.emptyUserSequence(); }, 1500);               
                }else{

                  //if strict mode is on
                  if(strict){
                    //user looses
                  $("#count").html("Lost");
                  //wipe sequence array
                   objectContext.emptyAllSequences();
                  $("#start").removeClass("active");
                  }else{

                    setTimeout(function(){
               //change this to generate another sequence instead of displaying the existent       
                  objectContext.displaySequenceOnBoard();
                  //reset the userSequence to check the whole sequence again 
                  objectContext.emptyUserSequence(); }, 1500);        



                  }
                }
            }
     });

  },
      setSounds:function(){

        this.buttonSounds["green"] = new Audio("https://s3.amazonaws.com/freecodecamp/simonSound1.mp3");
        this.buttonSounds["red"] = new Audio("https://s3.amazonaws.com/freecodecamp/simonSound2.mp3");
        this.buttonSounds["yellow"] = new Audio("https://s3.amazonaws.com/freecodecamp/simonSound3.mp3");
        this.buttonSounds["blue"] = new Audio("https://s3.amazonaws.com/freecodecamp/simonSound4.mp3");

      },

      emptyUserSequence: function(){
            this.userSequence.length=0;
      },

      emptyAISequence: function(){
               this.sequence.length=0;
      },

      emptyAllSequences:function(){
        this.emptyUserSequence();
        this.emptyAISequence();
      },
      updateCount: function(){
        $("#count").html(this.sequence.length);

      },

      checkUserSequence:function(){

        for(let i=0,len=this.userSequence.length;i<len;i++){

          if(this.userSequence[i]!== this.sequence[i]){
            return false;
          }

        }


        return true;    
      },

      generateAndAddRandomColor:function(){

        const randColorIndex=Math.floor(Math.random()*4);


        const randColor=this.colors[randColorIndex];
        this.sequence.push(randColor);
        this.updateCount(); 

      },

      displaySequenceOnBoard: function(){

        for(let i=0,len=this.sequence.length;i<len;i++){

          // this.buttonSounds[this.sequence[i]].play();
           this.lightButton(this.sequence[i],i);


        }//end for
      },
      lightButton: function(color,i){

        var objectContext=this;

                     $("#"+color).delay(400*i) 
        .animate({opacity : 0.3}, 300,function(){

                objectContext.buttonSounds[color].play();
                  $("#"+color).animate({opacity : 1}, 150);


                });


      }
    }
 simon.init();
});

这是代码笔。您必须按开始才能开始游戏,随着序列的增长并显示在板上,出现之前评论过的问题,会发生什么?谢谢!

http://codepen.io/juanf03/pen/jrEdWz?editors=1111

【问题讨论】:

    标签: javascript jquery asynchronous settimeout


    【解决方案1】:

    您同时在同一个元素上设置多个延迟,而最新的只是替换现有的。

    不要使用延迟,而是将complete 函数与您的动画一起传递,并为其提供整个剩余序列。为了说明,将您当前的displaySequenceOnBoard() 替换为这两个函数:

      displaySequenceOnBoard: function(){
        $(".button").removeClass("enabled");
        this.lightButtonsInSequence(this.sequence);
    
      },
    
      lightButtonsInSequence: function(sequence) {
        var color = sequence[0]
        var remainingSequence = sequence.slice(1)
        var lightNextButtonFunction = remainingSequence.length > 0 ? jQuery.proxy(function(){
                    this.lightButtonsInSequence(sequence.slice(1));
                  }, this) : null;
        console.log("Lighting color: " + color);
        $("#"+color).animate({opacity : .3}, 300).animate({opacity : 1}, 150, lightNextButtonFunction)
    
      }
    

    它已插入您的 CodePen 和 working

    【讨论】:

    • 很好的答案,但你能解释一下为什么我“一次在同一个元素上设置多个延迟”吗?...我不明白为什么....
    • @Juan 每次调用 lightButton() 时,都会在具有命名颜色的元素上设置一个 $().delay() 。第一次调用 lightButton("green") 时,它会在 #green 上设置延迟。然后第二次调用它(for 循环中的下一次迭代)它会在#green 上设置另一个更长的延迟。但是由于一个元素只能有一个延迟,所以第二个会替换第一个。
    • 如水般清澈...非常感谢...我的最终代码笔是codepen.io/juanf03/pen/jrEdWz?editors=0001,它运行良好,声音不起作用,但我将其添加到您的功能中。现在我有一个问题,当相同的颜色连续出现时,第二个声音不会发出声音......例如红色红色只有第一个红色声音......会发生什么?我在第 160 行添加了声音
    • 我已经通过缩短时间解决了。这些文件来自亚马逊 s3,所以如果您将超时设置得很低,第二次就不会发出声音了……再次感谢您!完美运行!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-26
    • 2021-10-25
    • 2023-03-28
    • 2021-10-31
    相关资源
    最近更新 更多