Недавно у меня возникла проблема с простой игрой JS, о которой я спрашивал здесь: Проблема с отрицательными оценками в простой игре JS
Это было исправлено после того, как мне посоветовали исправить оператор else if. После этого он работал нормально.
Я скопировал эту игру и заменил часть с угадыванием математики на часть с угадыванием столицы, оставив все остальное без изменений. Структура операторов if/else if остается прежней. Однако у меня снова возникает та же проблема, когда оценка не рассчитывается правильно, она начинает увеличиваться более чем в 1 раз каждый раз, когда на вопрос дается ответ.
JS это:
//Initial values assigned
let score = 0
let countDown = 10
//Start Button Triggers this countdown function:
function startCountdown(seconds) {
document.getElementById("start").setAttribute('disabled', '') //Disables Start button once the game starts
let counter = seconds;
const interval = setInterval(() => {
document.getElementById("timer").innerHTML = Math.floor(counter);
counter--;
if (counter < 0 ) {
clearInterval(interval);
game()
startCountdown(countDown) //this function with "countDown" argument passed in starts a new countdown
}
}, 1000);
}
//This function triggers a new question
function game(){
//Decreases the countdown time as the score gets higher:
if (score > 5 && score < 11){
countDown = 10-score/2
}
//This block is game questions and answers:
const countries = [
{ID:1,Country:"New Zealand",Capital:"Wellington"},
{ID:2,Country:"Belarus",Capital:"Minsk"},
{ID:3,Country:"Japan",Capital:"Tokyo"},
{ID:4,Country:"Philippines",Capital:"Manila"},
{ID:5,Country:"Mongolia",Capital:"Ulaanbaatar"},
{ID:6,Country:"Switzerland",Capital:"Bern"}
];
let random = Math.floor(Math.random() * countries.length);
let random2 = Math.floor(Math.random() * countries.length);
let random3 = Math.floor(Math.random() * countries.length);
let chosen = countries[random];
document.getElementById("challenge").innerHTML = `What is the capital city of<b>${chosen.Country}</b> ?`
//let answer1 = Math.floor(Math.random()*500)
//let answer2 = Math.floor(Math.random()*500)
//document.getElementById("challenge").innerHTML = `What is <b>${answer1}</b> plus <b>${answer2}</b>?`
let number1 = countries[random2].Capital;
let number2 = chosen.Capital;
let number3 = countries[random3].Capital;
let gameNums = [number1, number2,number3]
shuffle(gameNums)
document.getElementById("button1").innerHTML = gameNums[0]
document.getElementById("button2").innerHTML = gameNums[1]
document.getElementById("button3").innerHTML = gameNums[2]
//This function determines which answer is correct and incorrect:
function handleClick(event) {
if (event.target.tagName !== "BUTTON") {
return;
}
let buttonValue = event.target.innerText;
//Correct Answer:
if (buttonValue == number2){
document.querySelector("#result").innerText = "Correct!";
document.getElementById("result").style.color = "green";
score++
document.getElementById("score").innerHTML = `Score = ${score}`
game()
}
//Incorrect Answer:
else if (buttonValue == number1 || buttonValue == number3){
document.querySelector("#result").innerText = "Incorrect!";
document.getElementById("result").style.color = "red";
score--
//This stops the score going below zero:
if (score < 0){
score = 0
}
document.getElementById("score").innerHTML = `Score = ${score}`
game()
}
}
//Listens for button clicks
document.querySelector(".buttons").addEventListener("click", handleClick);
}
//function for shuffling the array
function shuffle(array) {
let currentIndex = array.length, randomIndex;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
}
Кодовое слово: https://codepen.io/tmnsoon/pen/yLpOmeX?editors=1010
Не уверен, почему это?
Спасибо!
если (оценка > 0) { оценка --}
@webCatDev, это не вызывает проблемы, потому что код OP использует Math.floor для оценки, поэтому, когда socre больше 0, он будет 1,2 ...
Проблема в том, что вы продолжаете назначать прослушиватель событий document.querySelector(".buttons")
, что вызывает проблемы.
Каждый раз, когда вы запускаете функцию game
, вы назначаете новый eventListener для .buttons
, что делает каждый раз, когда вы нажимаете .button
, вы запускаете игровую функцию не только один раз, из-за чего счет не работает так, как вы ожидали.
Вы можете использовать инструмент разработчика Chrome, чтобы проверить это (если вы используете Chrome)
getEventListeners(document.querySelector('.buttons'));
и вы обнаружите, что после сильного нажатия кнопок eventListener для buttons
будет больше 1.
Теперь у button
есть 190 прослушивателей событий, что означает, что каждый раз, когда он щелкает, он будет запускать функцию 190 раз.
Решение:
Я удаляю handleClicker за пределы функции и объявляю
number1,number2,number3
вне функции, чтобы сделать ее глобальной.
let score = 0
let countDown = 10
let number1,number2,number3;
//Start Button Triggers this countdown function:
function startCountdown(seconds) {
document.getElementById("start").setAttribute('disabled', '') //Disables Start button once the game starts
let counter = seconds;
const interval = setInterval(() => {
document.getElementById("timer").innerHTML = Math.floor(counter);
counter--;
if (counter < 0 ) {
clearInterval(interval);
game()
startCountdown(countDown) //this function with "countDown" argument passed in starts a new countdown
}
}, 1000);
}
//This function triggers a new question
function game(){
console.info('hi')
//Decreases the countdown time as the score gets higher:
if (score > 5 && score < 11){
countDown = 10-score/2
}
//This block is game questions and answers:
const countries = [
{ID:1,Country:"New Zealand",Capital:"Wellington"},
{ID:2,Country:"Belarus",Capital:"Minsk"},
{ID:3,Country:"Japan",Capital:"Tokyo"},
{ID:4,Country:"Philippines",Capital:"Manila"},
{ID:5,Country:"Mongolia",Capital:"Ulaanbaatar"},
{ID:6,Country:"Switzerland",Capital:"Bern"}
];
let random = Math.floor(Math.random() * countries.length);
let random2 = Math.floor(Math.random() * countries.length);
let random3 = Math.floor(Math.random() * countries.length);
let chosen = countries[random];
document.getElementById("challenge").innerHTML = `What is the capital city of<b>${chosen.Country}</b> ?`
number1 = countries[random2].Capital;
number2 = chosen.Capital;
number3 = countries[random3].Capital;
let gameNums = [number1, number2,number3]
shuffle(gameNums)
document.getElementById("button1").innerHTML = gameNums[0]
document.getElementById("button2").innerHTML = gameNums[1]
document.getElementById("button3").innerHTML = gameNums[2]
//This function determines which answer is correct and incorrect:
//Listens for button clicks
}
function handleClick(event) {
if (event.target.tagName !== "BUTTON") {
return;
}
let buttonValue = event.target.innerText;
//Correct Answer:
if (buttonValue == number2){
document.querySelector("#result").innerText = "Correct!";
document.getElementById("result").style.color = "green";
score++
document.getElementById("score").innerHTML = `Score = ${score}`
game()
}
//Incorrect Answer:
else if (buttonValue == number1 || buttonValue == number3){
document.querySelector("#result").innerText = "Incorrect!";
document.getElementById("result").style.color = "red";
score--
//This stops the score going below zero:
if (score < 0){
score = 0
}
document.getElementById("score").innerHTML = `Score = ${score}`
game()
}
}
document.querySelector(".buttons").addEventListener("click",
handleClick);
//function for shuffling the array
function shuffle(array) {
let currentIndex = array.length, randomIndex;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
}
<div class = "wrapper">
<h1>Maths Adding Game</h1>
<button id = "start" onclick = "startCountdown(0)">Start</button>
<br>
<span id = "timer"></span>
<br>
<div id = "challenge"></div>
<br>
<div class = "buttons">
<button type = "button" id = "button1">???</button>
<button type = "button" id = "button2">???</button>
<button type = "button" id = "button3">???</button>
</div>
<div id = "score">Score = Zero</div>
<div class = "result">Result: <span id = "result">N/A</span></div>
</div>
Пожалуйста, не используйте внешние ссылки для обмена простым кодом, вы можете использовать фрагмент кода SO для базового кода HTML, CSS и JS.