skip to Main Content

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


  1. Chosen as BEST ANSWER
    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;
    
    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;
    }
    
    function setDivBackgroundColors(colors) {
      const boxes = document.querySelectorAll('.clrBoxes');
      boxes.forEach((box, index) => {
        box.style.backgroundColor = colors[index];
      });
    }
    
    function addBoxEventListeners() {
      const boxes = document.querySelectorAll('.clrBoxes');
      boxes.forEach(box => {
        box.addEventListener('click', checkColorMatch);
        box.addEventListener('click', startNewGame);
      });
    }
    
    function checkColorMatch(event) {
      const clickedColor = event.target.style.backgroundColor;
      const targetColor = targetClrBox.style.backgroundColor;
      
      if (clickedColor === targetColor) {
        points++;
        pointsBox.textContent = `Points: ${points}`;
        event.target.removeEventListener('click', checkColorMatch);
      }
    }
    
    function startNewGame() {
      initializeGame();
    }
    
    

    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


  2. Because you add event listeners every iteration with

    box.addEventListener('click', () => {
    

    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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search