i am working on a game where you get random numbers 1-25 in individual squares, you also get random colors and font sizes. I have all that set up at this point but what i am struggling with is implementing a check that will check if these numbers have been clicked in the sequence one after another. So, when you start the game and have your numbers from 1 through 25......i want the person to be able to click on 1 then on 2 then on 3 and have the following tests happen:
- #1 is always clickable since its the first number in a sequence.
- #2 is not clickable unless # 1 has been clicked. # 3 is not clickable unless #1 and #2 have been clicked and so on....once its successfully clicked, background color changes.
I understand i need to loop through my random numbers and assign .eventListener to them.
So i came close with this line of code: if (squares[i].textContent = numArray[i] === 1) squares[i].addEventListener('click', function() { return squares[i].style.backgroundColor = 'red'})
I can see that it is identify 1 in this case but everything is being displayed as true or false instead of numbers. I am not sure where to go from here or how i can check for clicked boxes in the correct order.
Thank you so much for taking your time to read this and help me understand a solution.
let startBtn = document.querySelector('.start-btn')
let resetBtn = document.querySelector('.reset-btn')
let timer = document.querySelector('.time__countdown')
const squares = [...document.querySelectorAll('.square')];
let gameStarted = false;
let counter = 60
let timeInterval;
startBtn.addEventListener('click', startGame)
function startGame() {
gameStarted = true;
if (gameStarted === true) {
for (let i = 0; i < squares.length; i ) {
squares[i].addEventListener('click', function() {
squares[i].style.backgroundColor = '#2A3166'
})
}
}
randomNumber()
timeInterval = setInterval(function() {
counter--
if (counter >= 0) {
timer.innerHTML = `Time left: ${counter}`
}
}, 1000)
}
function getRandomColor() {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i ) {
color = letters[Math.floor(Math.random() * 16)];
}
return color;
}
function randomNumber() {
const numArray = []
for (let i = 1; i < 26; i ) {
numArray.push(i)
}
numArray.sort(() => 0.5 - Math.random())
for (let i = 0; i < squares.length; i ) {
const random = Math.floor(Math.random() * 25)
squares[i].textContent = numArray[i]
squares[i].style.fontSize = random 15 "px";
squares[i].style.color = getRandomColor()
squares[i].style.backgroundColor = '#000000'
}
}
resetBtn.addEventListener('click', function() {
clearInterval(timeInterval)
counter = 60
timer.innerHTML = `Time left: 60`
gameStarted = false
squares.forEach((n) => {
n.textContent = "";
n.style.backgroundColor = "#000000";
})
})
* {
margin: 0;
padding: 0;
}
body,
html {
min-width: 100%;
min-height: 100vh;
box-sizing: border-box;
font-size: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: black;
}
img {
max-width: 100%;
display: block;
}
main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 24%;
background-color: #6688CC;
border-radius: 10px;
}
.grid {
border: 2px solid black;
width: 100%;
display: flex;
flex-wrap: wrap;
background-color: #ACBFE6;
justify-content: center;
align-items: center;
gap: 2px;
padding-top: 3px;
padding-bottom: 3px;
}
.square {
border: 2px solid black;
width: 70px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
background-color: #000000;
}
.time {
padding-bottom: 2em;
padding-top: 1em;
}
.btn {
margin: 1em;
}
.buttons {
display: flex;
}
<main>
<div >
<p >Time left: 60</p>
</div>
<grid >
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
</grid>
<div >
<button >Start Game</button>
<button >Reset Game</button>
</div>
</main>
CodePudding user response:
Here is a snippet demonstrating what I think you are looking for. Note how I first loop through and give each square an identifying attribute. Then I compare that to the number of the last one clicked. Comments are in the code.
let ct = 1;
let currentNum = 0;
let squares = document.querySelectorAll('.grid .square');
squares.forEach(s => {
//give it something to identify itself with
s.setAttribute('data-num', ct )
s.addEventListener('click', e => {
// get my number, convert to a number
let mynum = e.target.dataset.num
//compare to the currentNum
if (mynum - 1 === currentNum) {
//deselect current square
document.querySelector('.square-selected')?.classList.remove('square-selected');
// update new square
e.target.classList.add('square-selected');
//update currentNum
currentNum = mynum;
}
})
})
* {
margin: 0;
padding: 0;
}
body,
html {
min-width: 100%;
min-height: 100vh;
box-sizing: border-box;
font-size: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: black;
}
img {
max-width: 100%;
display: block;
}
main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 24%;
background-color: #6688CC;
border-radius: 10px;
}
.grid {
border: 2px solid black;
width: 100%;
display: flex;
flex-wrap: wrap;
background-color: #ACBFE6;
justify-content: center;
align-items: center;
gap: 2px;
padding-top: 3px;
padding-bottom: 3px;
}
.square {
border: 2px solid black;
width: 70px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
background-color: #000000;
}
.square-selected {
background-color: yellow;
}
.time {
padding-bottom: 2em;
padding-top: 1em;
}
.btn {
margin: 1em;
}
.buttons {
display: flex;
}
<grid >
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
</grid>
CodePudding user response:
import React from 'react';
export default function Editor() {
const [numbers, setNumbers] = React.useState([]);
const [count, setCount] = React.useState(0);
const generatenumbers = () => {
const numbersT = [];
for (let i = 0; i < count; i ) {
numbersT.push({
id: i,
value: i,
clickable: i === 0,
});
}
setNumbers(numbersT);
};
const onClick = (id) => {
setNumbers((prev) => {
const index = prev.findIndex((number) => number.id === id);
prev[index].clickable = false;
if (index 1 < prev.length) {
prev[index 1].clickable = true;
}
return [...prev];
});
};
return (
<div className='flex'>
<input onChange={(e) => setCount(e.target.value)} className='m-5' />
<button onClick={generatenumbers} className='m-5'>
Generate Numbers
</button>
<div className='flex flex-wrap'>
{numbers.map((number) => {
return (
<div
onClick={() => {
if (number.clickable) {
onClick(number.id);
}
}}
key={number.id}
className='m-5 rounded-full items-center justify-center flex'
style={{
width: '50px',
height: '50px',
backgroundColor: number.clickable ? 'green' : 'red',
}}
>
{number.value}
</div>
);
})}
</div>
</div>
);
}