1 min read
Create a game in only 15 minutes to with all the tools you probably already know. All the code necessary to get this game up and running is in the post but there is a lot of room for improvement. Challenge yourself by creating the game yourself and improving upon it.
We are going to be building a simple memory game where you can improve in many ways if you want to in the future. It's very easy to create and a good practice your Javascript skills. Basically you try to find the matching pics and win the game. Don't worry if you are just a beginner, the code should be easy enough for you to understand. HTML and CSS is very basic. In the javascript part I tried to explain the code in the comments.
I didn't implement any logic for actually winning the game, what happens when you win the game, keeping score or restarting the game. These are only some of the things you can implement in yours. Go check it out.
As I said before the HTML setup is very basic.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script defer src="main.js"></script>
<title>Memory Game</title>
</head>
<body>
<h1>Find the matching pics</h1>
<div class="board-container">
{# Our board will appear here #}
</div>
</body>
</html>
All the necessary CSS that I used:
/* /style.css */
body {
background-color: azure;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.board-container {
background-color: rgb(65, 78, 78);
width: 600px;
height: 600px;
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(6, 1fr);
grid-gap:10px;
padding: 20px;
border-radius: 20px;
}
.board-container > * {
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
}
First of all, get all the images you want to use in your game. If you don't wanna bother looking for a bunch of images here are mine (I mean the ones I found online that were free).
// /main.js
// The logic to randomize the image array
const shuffle = (objects) => {
for (let i = objects.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
let temp = objects[i];
objects[i] = objects[j];
objects[j] = temp;
}
}
window.onload = async () => {
// get the board container
let boardContainer = await document.querySelector('.board-container');
// doubling my array size and randomizing the contents
const doubleAndRender = async (objects, objectsLength) => {
for (let i = 0; i < objectsLength; i++){
objects.push({"id":19+i, "src": `${i+1}.png`})
}
// shuffling my array a bunch of times
// not really necessary to do it 3 times though :)
await shuffle(objects);
await shuffle(objects);
await shuffle(objects);
for(let i = 0; i < objects.length; i++){
let div = document.createElement("div");
div.style.background = "red";
// give the png number as a class to be used later
div.classList.add("grid-item", `${objects[i]["id"]}.png`)
// id will get the number of the png without the ".png" extension
div.setAttribute("id", `${objects[i]["id"]}`)
boardContainer.appendChild(div)
};
};
await shuffle(objects);
await doubleAndRender(objects, 18);
}
And this is where the magic happens. Logic can be found on in the comments below.
// keep track of how many images are open to be matched
let num = 0;
// first image clicked
var target1;
// second image clicked
var target2;
window.addEventListener('click', (e) => {
// I numbered my pngs to be used thm easily here (1.png, 2.png, etc.)
// and with pngNum I'm keeping track of the pngs
let pngNum;
// Checking for 3 different cases:
// is it a grid-item
// is it not active
// does it have multiple classes
if(e.target.classList.contains("grid-item") && e.target.classList[1] && !e.target.classList.contains("active")){
// grabbing the number of the png for matching later
if(e.target.classList[1].split(".")[0] <= 18){
pngNum = e.target.classList[1].split(".")[0];
} else {
pngNum = e.target.classList[1].split(".")[0] - 18;
}
// if there is no active open image
if(num === 0){
target1 = e.target;
// creating the image on on the grid item that's been clicked on
let image = document.createElement("img");
image.src = `pngs/${pngNum}.png`
image.style.maxWidth= '64px';
target1.appendChild(image)
// Increment the number of active images to be matched
num += 1;
// when there's and active image already
} else if(num == 1){
if(target1 !== e.target){
target2 = e.target;
let image = document.createElement("img");
image.src = `pngs/${pngNum}.png`
image.style.maxWidth= '64px';
target2.appendChild(image)
num += 1;
}
// when two images are open/revealed
} else if(num == 2){
// If both ids are higher than the number of pngs there can't be a match
if(parseInt(target1.id) > 18 && (parseInt(target2.id) > 18)) {
num = 0;
target1.removeChild(target1.childNodes[0]);
target2.removeChild(target2.childNodes[0]);
}
// If both ids are lower than the number of pngs there can't be a match
else if (parseInt(target1.id) <= 18 && (parseInt(target2.id) <= 18)){
console.log("both low, not a match");
num = 0;
target1.removeChild(target1.childNodes[0]);
target2.removeChild(target2.childNodes[0]);
}
// Now ids are in range so start checking for a match
else {
if(parseInt(target1.id) > 18) {
// Handle match
if(parseInt(target1.id) - 18 == parseInt(target2.id)){
// Add active so they won't be mixed with the unmatched ones
target1.classList.add("active")
target2.classList.add("active")
//Adding color as well as an indicator
target1.style.background = "white";
target2.style.background = "white";
// the number of open images to be mathced should be 0
num = 0;
}else {
// No match
target1.removeChild(target1.childNodes[0]);
target2.removeChild(target2.childNodes[0]);
num = 0
}
}else if(parseInt(target2.id) > 18) {
// Handle match
if(parseInt(target2.id) - 18 == parseInt(target1.id)){
target1.classList.add("active")
target2.classList.add("active")
target1.style.background = "white";
target2.style.background = "white";
num = 0;
} else {
// No match
target1.removeChild(target1.childNodes[0]);
target2.removeChild(target2.childNodes[0]);
num = 0;
}
}
}
}
}
})
This project is not even close to being finished. Good thing about it is that it means there is room for improvement that you can do yourself to make it better. Maybe add a flip animation, implement a better logic for rendering the images into cards, make it so that people can create their own games with their own images... There are just so many things that can be added to this game.
As you can see this game was not hard to create at all. There are so many things you can create with basic HTML, CSS and javascript. This was just a quick example to what kind of things you can create by just using your basic web development knowledge.
Ilker Akbiyik