WEBLEB
Home
Editor
Login
Pro
English
English
Français
Español
Português
Deutsch
Italiano
हिंदी
Memory Mini Game
4455
codex
Open In Editor
Publish Your Code
Recommended
17 May 2024
Menja game
27 February 2025
STACK GAME by TONY
14 September 2024
Minion Eye Toggle
HTML
Copy
Memory Game
Berhenti
Mulai Game
CSS
Copy
* { padding: 0; margin: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; } body { background-color: #5900ff; } .wrapper { box-sizing: content-box; width: 26.87em; padding: 2.5em 3em; background-color: #ffffff; position: absolute; transform: translate(-50%, -50%); left: 50%; top: 50%; border-radius: 0.6em; box-shadow: 0 0.9em 2.8em rgba(86, 66, 0, 0.2); } .game-container { position: relative; width: 100%; display: grid; gap: 0.6em; } .stats-container { text-align: right; margin-bottom: 1.2em; } .stats-container span { font-weight: 600; } .card-container { position: relative; width: 6.25em; height: 6.25em; cursor: pointer; } .card-before, .card-after { position: absolute; border-radius: 5px; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; border: 4px solid #000000; transition: transform 0.7s ease-out; backface-visibility: hidden; } .card-before { background-color: #00fff2; font-size: 2.8em; font-weight: 600; } .card-after { background-color: #ffffff; transform: rotateY(180deg); } .card-container.flipped .card-before { transform: rotateY(180deg); } .card-container.flipped .card-after { transform: rotateY(0deg); } .controls-container { position: absolute; display: flex; align-items: center; justify-content: center; flex-direction: column; width: 100%; height: 100%; background-color: #a200ff; top: 0; } button { border: none; border-radius: 0.3em; padding: 1em 1.5em; cursor: pointer; } #stop { font-size: 1.1em; display: block; margin: 1.1em auto 0 auto; background-color: #000000; color: #ffffff; } .controls-container button { font-size: 1.3em; box-shadow: 0 0.6em 2em rgba(86, 66, 0, 0.2); } .hide { display: none; } #result { text-align: center; } #result h2 { font-size: 2.5em; } #result h4 { font-size: 1.8em; margin: 0.6em 0 1em 0; }
JS
Copy
const moves = document.getElementById("moves-count"); const timeValue = document.getElementById("time"); const startButton = document.getElementById("start"); const stopButton = document.getElementById("stop"); const gameContainer = document.querySelector(".game-container"); const result = document.getElementById("result"); const controls = document.querySelector(".controls-container"); let cards; let interval; let firstCard = false; let secondCard = false; //Items array const items = [ { name: "bee", image: "bee.png" }, { name: "crocodile", image: "crocodile.png" }, { name: "macaw", image: "macaw.png" }, { name: "gorilla", image: "gorilla.png" }, { name: "tiger", image: "tiger.png" }, { name: "monkey", image: "monkey.png" }, { name: "chameleon", image: "chameleon.png" }, { name: "piranha", image: "piranha.png" }, { name: "anaconda", image: "anaconda.png" }, { name: "sloth", image: "sloth.png" }, { name: "cockatoo", image: "cockatoo.png" }, { name: "toucan", image: "toucan.png" }, ]; //Initial Time let seconds = 0, minutes = 0; //Initial moves and win count let movesCount = 0, winCount = 0; //For timer const timeGenerator = () => { seconds += 1; //minutes logic if (seconds >= 60) { minutes += 1; seconds = 0; } //format time before displaying let secondsValue = seconds < 10 ? `0${seconds}` : seconds; let minutesValue = minutes < 10 ? `0${minutes}` : minutes; timeValue.innerHTML = `<span>Time:</span>${minutesValue}:${secondsValue}`; }; //For calculating moves const movesCounter = () => { movesCount += 1; moves.innerHTML = `<span>Moves:</span>${movesCount}`; }; //Pick random objects from the items array const generateRandom = (size = 4) => { //temporary array let tempArray = [...items]; //initializes cardValues array let cardValues = []; //size should be double (4*4 matrix)/2 since pairs of objects would exist size = (size * size) / 2; //Random object selection for (let i = 0; i < size; i++) { const randomIndex = Math.floor(Math.random() * tempArray.length); cardValues.push(tempArray[randomIndex]); //once selected remove the object from temp array tempArray.splice(randomIndex, 1); } return cardValues; }; const matrixGenerator = (cardValues, size = 4) => { gameContainer.innerHTML = ""; cardValues = [...cardValues, ...cardValues]; //simple shuffle cardValues.sort(() => Math.random() - 0.5); for (let i = 0; i < size * size; i++) { /* Create Cards before => front side (contains question mark) after => back side (contains actual image); data-card-values is a custom attribute which stores the names of the cards to match later */ gameContainer.innerHTML += ` <div class="card-container" data-card-value="${cardValues[i].name}"> <div class="card-before">?</div> <div class="card-after"> <img src="${cardValues[i].image}" class="image"/></div> </div> `; } //Grid gameContainer.style.gridTemplateColumns = `repeat(${size},auto)`; //Cards cards = document.querySelectorAll(".card-container"); cards.forEach((card) => { card.addEventListener("click", () => { //If selected card is not matched yet then only run (i.e already matched card when clicked would be ignored) if (!card.classList.contains("matched")) { //flip the cliked card card.classList.add("flipped"); //if it is the firstcard (!firstCard since firstCard is initially false) if (!firstCard) { //so current card will become firstCard firstCard = card; //current cards value becomes firstCardValue firstCardValue = card.getAttribute("data-card-value"); } else { //increment moves since user selected second card movesCounter(); //secondCard and value secondCard = card; let secondCardValue = card.getAttribute("data-card-value"); if (firstCardValue == secondCardValue) { //if both cards match add matched class so these cards would beignored next time firstCard.classList.add("matched"); secondCard.classList.add("matched"); //set firstCard to false since next card would be first now firstCard = false; //winCount increment as user found a correct match winCount += 1; //check if winCount ==half of cardValues if (winCount == Math.floor(cardValues.length / 2)) { result.innerHTML = `<h2>You Won</h2> <h4>Moves: ${movesCount}</h4>`; stopGame(); } } else { //if the cards dont match //flip the cards back to normal let [tempFirst, tempSecond] = [firstCard, secondCard]; firstCard = false; secondCard = false; let delay = setTimeout(() => { tempFirst.classList.remove("flipped"); tempSecond.classList.remove("flipped"); }, 900); } } } }); }); }; //Start game startButton.addEventListener("click", () => { movesCount = 0; seconds = 0; minutes = 0; //controls amd buttons visibility controls.classList.add("hide"); stopButton.classList.remove("hide"); startButton.classList.add("hide"); //Start timer interval = setInterval(timeGenerator, 1000); //initial moves moves.innerHTML = `<span>Moves:</span> ${movesCount}`; initializer(); }); //Stop game stopButton.addEventListener( "click", (stopGame = () => { controls.classList.remove("hide"); stopButton.classList.add("hide"); startButton.classList.remove("hide"); clearInterval(interval); }) ); //Initialize values and func calls const initializer = () => { result.innerText = ""; winCount = 0; let cardValues = generateRandom(); console.log(cardValues); matrixGenerator(cardValues); };