This is a Colour Matching game where there is a target colour and a grid of colours. We have to click the correct colour and earn a point. But there is a problem in checking the colour and points iteration processs. At first, it works. But clicking more and more colours makes some error and at some point it completely breaks.
// script.js
const startBtn = document.getElementById('startBtn');
const startScreen = document.getElementById('startScreen');
const gameScreen = document.getElementById('gameScreen');
const endScreen = document.getElementById('endScreen');
const pointsBox = document.getElementById('pointsBox');
let points = 0;
console.log(points)
const targetClrBox = document.getElementById('targetClr');
const gridClrs = document.getElementById('gridClrs');
startBtn.addEventListener('click', setupColorGame);
function setupColorGame() {
startScreen.classList.add('hidden');
gameScreen.classList.remove('hidden');
gameScreen.style.display = 'flex';
initializeGame();
}
function initializeGame() {
const clrs = [
'rgb(238, 82, 83)',
'rgb(253, 57, 115)',
'rgb(87, 101, 116)',
'rgb(95, 39, 205)',
'rgb(6, 152, 22)',
'rgb(29, 209, 161)',
'rgb(243, 104, 224)',
'rgb(255, 159, 243)',
'rgb(230, 126, 34)',
'rgb(254, 202, 87)',
'rgb(46, 134, 222)',
'rgb(84, 160, 255)',
'rgb(1, 163, 164)',
'rgb(0, 210, 211)'
];
const targetClr = selectTargetClr(clrs);
targetClrBox.style.backgroundColor = targetClr;
const shuffledGridClrs = shuffleArray(clrs);
setDivBackgroundColors(shuffledGridClrs);
addBoxEventListeners();
}
function selectTargetClr(clrs) {
const clrsIndex = Math.floor(Math.random() * clrs.length);
return clrs[clrsIndex];
}
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
let boxes;
function setDivBackgroundColors(colors) {
boxes = document.querySelectorAll('.clrBoxes');
boxes.forEach((box, index) => {
box.style.backgroundColor = colors[index];
});
}
function addBoxEventListeners() {
boxes.forEach(box => {
box.addEventListener('click', () => {
if (box.style.backgroundColor === targetClrBox.style.backgroundColor) {
points++
pointsBox.innerHTML = points;
console.log(points);
initializeGame();
} else {
initializeGame();
}
});
});
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.hidden {
display: none;
}
#gameScreen {
flex-direction: column;
justify-content: space-between; /* Changed to space-between */
align-items: center;
height: 100vh;
}
.clrBox {
width: 125px;
height: 125px;
border: 1px dashed black;
border-radius: 7px;
margin: 3px;
transition: all ease 0.1s;
}
.clrBox:hover {
margin-top: -3px;
margin-left: -1px;
}
#targetClr {
margin-top: 20px;
border: 1px solid black;
}
#gridClrs {
display: grid;
grid-template-columns: repeat(7, 1fr);
grid-gap: 7px;
margin-bottom: 20px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Color Match Chaos</title>
<link rel="stylesheet" href="./styles/main.css">
</head>
<body>
<div id="startScreen">
<button id="startBtn">Start Game</button>
</div>
<div id="gameScreen" class="hidden">
<div id="targetBox">
<div id="targetClr" class="clrBox"></div>
</div>
<div>
<span id="pointsBox">0</span> / 10
</div>
<div id="gridClrs">
<div class="clrBox clrBoxes" id="1"></div>
<div class="clrBox clrBoxes" id="2"></div>
<div class="clrBox clrBoxes" id="3"></div>
<div class="clrBox clrBoxes" id="4"></div>
<div class="clrBox clrBoxes" id="5"></div>
<div class="clrBox clrBoxes" id="6"></div>
<div class="clrBox clrBoxes" id="7"></div>
<div class="clrBox clrBoxes" id="8"></div>
<div class="clrBox clrBoxes" id="9"></div>
<div class="clrBox clrBoxes" id="10"></div>
<div class="clrBox clrBoxes" id="11"></div>
<div class="clrBox clrBoxes" id="12"></div>
<div class="clrBox clrBoxes" id="13"></div>
<div class="clrBox clrBoxes" id="14"></div>
</div>
</div>
<div id="endScreen" class="hidden">
</div>
<script type="module" src="./scripts/main.js"></script>
</body>
</html>
2
Answers
I tried adding event listener only to target clr in the grids box and remove it after increment. I also add eventListener to all boxes to create NewGame. now it works
Because you add event listeners every iteration with
And never remove them.
if you debug you will see that each click triggers handlers N times where N is the number of clicked performed before