【问题标题】:Javascript/jQuery bug in my Trivia Game我的琐事游戏中的 Javascript/jQuery 错误
【发布时间】:2017-05-11 22:11:13
【问题描述】:

我正在为 Web Dev 课程创建一个基本的琐事游戏。我们将使用 HTML/CSS/JS/jQuery 来创建它。我们将在此作业中使用的新元素是 setTimeout() 和 setInterval() 方法。

点击开始按钮后,游戏会提出一个问题并提供 4 个可能的答案。用户要么点击答案,要么计时器用完。显示结果,然后自动加载下一个问题。一旦问题数组中的所有问题都被问完,游戏就会显示整体结果,然后刷新屏幕。

我发现的错误是,如果我让计时器一直运行到屏幕上刚刚显示“零”,然后快速单击答案,它会导致游戏做出反应,就好像条件一个答案被点击和时间耗尽同时发生。然后下一个问题加载了太多答案,并且计时器以增加的速率递减。我不确定计时器中是否存在某种时间延迟达到零某处允许答案点击传输,这会创建一个不会被清除的新timerID,这会导致下一个问题的时间减少增加率。

我为此创建了一个小提琴:https://jsfiddle.net/brianpatrickhummel/0a2hg782/

var correctAnswers = 0;
var incorrectAnswers = 0;
var unansweredQuestions = 0;
var timeRemaining = 16;
var intervalID;
var indexQandA = 0;    //index to load a different question each round without the game reset or screen refresh
var answered = false;  //variable to stop the timer if user has clicked an answer
var correct;
var triviaGame = [
        {question:"HOW MANY COLORS ARE THERE ON A RUBIK'S CUBE ?", answer:["5", "6", "7", "4"], correct: "1", image:("assets/images/rubik.png")},
        {question:"WHAT IS THE SPEED OF LIGHT ?", answer:["8,600 MILES per SECOND","86,000 MILES per SECOND","186,000 MILES per SECOND","886,000 MILES per SECOND"], correct:"2", image:("assets//images/lightspeed.jpg")},
        {question:"APPROXIMATELY HOW LONG DOES IT TAKE FOR SUNLIGHT TO REACH THE EARTH ?", answer:["45 SECONDS", "10 HOURS", "2 HOURS 15 MINUTES", "8 MINUTES"], correct:"3", image:("assets//images/sunlight.jpg")},
        {question:"WHAT ELEMENT'S CHEMICAL SYMBOL IS Pb ?", answer:["POTASSIUM","STRONTIUM","LEAD","PALLADIUM"], correct:"2", image:("assets//images/periodictable.png")},
        {question:"HOW FAST CAN BEES FLY ?", answer:["35 MPH", "15 MPH", "48 MPH", "8 MPH"], correct:"1", image: ("assets/images/bee.png")},
        {question:"WHAT IS THE MOST ABUNDANT ELEMENT IN THE UNIVERSE ?", answer:["HYDROGEN", "OXYGEN", "HELIUM", "CARBON"], correct:"0", image:("assets//images/universe.png")},
        {question:"THE AIR THAT WE BREATHE IS COMPRISED MOSTLY OF WHAT ELEMENT ?", answer:["CARBON", "ARGON", "OXYGEN", "NITROGEN"], correct:"3", image:("assets//images/breathe.jpg")},
        {question:"WHAT IS THE DIAMETER OF THE EARTH ?", answer:["140,000 MILES", "2,500,000 MILES", "8,000 MILES", "25,000,000 MILES"], correct:"2", image:("assets//images/earth.png")}   
];

// ------------- FUNCTION DECLARATIONS ----------------------------


function startGame() {
    console.log("game has begun");
    $('.start-button').remove();
    correctAnswers = 0;
    incorrectAnswers = 0;
    unansweredQuestions = 0;
    loadQandA ();
}       

function loadQandA() {
    // console.log(correctAnswers);
    // console.log(incorrectAnswers);
    // console.log(unansweredQuestions);
    // console.log(indexQandA);
    answered = false;    // will allow timeRemaining to be pushed back to <h5> after round reset....else statement in function timer()
    timeRemaining = 16;
    intervalID = setInterval(timer, 1000);
    if (answered === false){
        timer();
    }
    correct = triviaGame[indexQandA].correct;
    var question = triviaGame[indexQandA].question;
    $('.question').html(question);
    for (var i = 0; i < 4; i++) {
        var answer = triviaGame[indexQandA].answer[i];
        $('.answers').append('<h4 class= answersAll id=' + i + '>' + answer + '</h4>');
    }

    $( "h4" ).click(function() {
        var id = $(this).attr('id');
        // alert(id);
        if (id === correct) {
            answered = true;    // stops the timer
            // alert("correct answer");
            $('.question').text("THE ANSWER IS: " + triviaGame[indexQandA].answer[correct]);
            correctAnswer ();
        }
        else {
            answered = true;    //stops the timer
            // alert("incorrect answer");
            $('.question').text("YOU CHOSE: " + triviaGame[indexQandA].answer[id] + ".....HOWEVER THE ANSWER IS: " + triviaGame[indexQandA].answer[correct]);
            incorrectAnswer();
        }
    });     
}

function timer() { 
    if (timeRemaining === 0) {
        answered = true;
        clearInterval(intervalID);  
        $('.question').text("THE CORRECT ANSWER IS: " + triviaGame[indexQandA].answer[correct]);
        unAnswered();
    }
    else if (answered === true) {
        clearInterval(intervalID); 
    }
    else {
        timeRemaining--;
        $('.timeRemaining').text('YOU HAVE ' + timeRemaining + ' SECONDS TO CHOOSE').removeClass('animated pulse infinite');
    }
}   

function correctAnswer() {
    correctAnswers++;
    $('.timeRemaining').text("YOU HAVE ANSWERED CORRECTLY!").css({'color':'#3D414F'}).addClass('animated pulse infinite');
    resetRound();
}

function incorrectAnswer() {
    incorrectAnswers++;
    $('.timeRemaining').text("YOU HAVE ANSWERED INCORRECTLY!").css({'color':'#3D414F'}).addClass('animated pulse infinite');
    resetRound();

}

function unAnswered() {
    unansweredQuestions++;
    $('.timeRemaining').text("YOU FAILED TO CHOOSE AN ANSWER").css({'color':'#3D414F'}).addClass('animated pulse infinite');
    resetRound();
}

function resetRound() {
    $('.answersAll').remove();
    $('.answers').append('<img class=answerImage src="' + triviaGame[indexQandA].image + ' ">');   // adds answer image
    indexQandA++;                                   // increments index which will load next question when loadQandA() is called again
    if (indexQandA < triviaGame.length) {
        setTimeout(function(){ loadQandA(); $('.answerImage').remove();}, 5000);         // removes answer image from previous round
    }
    else {
        setTimeout(function(){ 
            $('.question').remove();
            $('.timeRemaining').remove();
            $('.answerImage').remove(); 
            $('.answers').append('<h4 class= answersAll end>CORRECT ANSWERS: ' + correctAnswers + '</h4>');
            $('.answers').append('<h4 class= answersAll end>INCORRECT ANSWERS: ' + incorrectAnswers + '</h4>');
            $('.answers').append('<h4 class= answersAll end>UNANSWERED QUESTIONS: ' + unansweredQuestions + '</h4>');
            setTimeout(function(){ location.reload(); }, 7000);    
        }, 5000);  
    }
}





// ----------------------- MAIN PROCESS ---------------------


$('.startButton').on("click", function() {
    $('.startButton').removeClass('infinite').addClass('animated fadeOutDown');   //manages the Animate.css applied to Start Button
        startGame();

});

【问题讨论】:

  • 第二场比赛我答对了。我赢了什么?
  • 您调用clearInterval() 的唯一位置是在您的timer 函数内,它首先检查0,无论是否选择了答案。选择答案后应立即清除间隔。
  • 只需在timer 函数中交换前两个if 条件即可使其工作,尽管它不会使代码不那么混乱。 ;) jsfiddle.net/0a2hg782/2
  • 我什至无法想象我的代码看起来有多混乱、臃肿和难看,因为我还没有真正的参考框架来判断这些事情。我已经参加了其中一个臭名昭著的训练营两个月了,我很感激你们中的一些人足够友善地接受我的初步调查。 DarthJDG- 谢谢你的 cmets。
  • @BrianPatrickHummel 任何时候,继续努力。我们都曾经是初学者。

标签: javascript jquery html css timer


【解决方案1】:

每次使用setTimeoutsetInterval 建立计时器时,都需要为返回的计时器ID 设置一个变量。该变量需要具有足够高的范围,以便您可以从必须与计时器交互的任何地方访问它。

然后,在任何需要中断计时器的地方,都可以将其清除。在您的情况下,当点击答案时,您需要停止倒计时。

这是一个按比例缩小的示例:

window.addEventListener("DOMContentLoaded", function(){

  var clock = document.getElementById("clock");
  var btnStart = document.getElementById("btnStart");
  var btnStop = document.getElementById("btnStop");
  
  // Declare this where you can get at it
  var timer1 = null;
  
  function start(){
    clock.textContent = new Date().toLocaleTimeString();
    timer1 = setTimeout(start, 900);
  }
  
  function stop(){
    // Cancel the timer
    clearTimeout(timer1);
  }
  
  btnStart.addEventListener("click", start);
  btnStop.addEventListener("click", stop);
  
  start();

});
<div id="clock"></div>
<button id="btnStop">Stop the Clock</button>
<button id="btnStart">Start the Clock</button>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多