How to make 2048 Game with HTML,CSS
and JavaScript
HOW TO PLAY?
Use your arrow keys ➡️⬅️⬆️⬇️ or swipe left or right, up or down to move the tiles. When two tiles with the same number touch, they merge into one. Once you get 2048 in any square, you win.
What is the game where you move number tiles?
2048 is a single-player sliding block puzzle game designed by Italian web developer Gabriele Cirulli. The game's objective is to slide numbered tiles on a grid to combine them to create a tile with the number 2048. However, one can continue to play the game after reaching the goal, creating tiles with larger numbers.
Video Tutorial of 2048 puzzle Game
2048 puzzle Game [Source Codes]
To make 2048 puzzle Game follow the given steps line by line:
Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
Create an index.html file. The file name must be index and its extension .html
Create a style.css file. The file name must be style and its extension .css
Create a script.js file. The file name must be style and its extension .js
Once you create these files, paste the given codes into the specified files. If you don’t want to do these then scroll down and download the source code.
First, paste the following codes into your index.html file
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>2048 Game</title>
- <link rel="stylesheet" href="style.css" />
- </head>
- <body>
- <div class="container hide">
- <div class="heading">
- <h1>2048</h1>
- <div class="score-container">
- Score:
- <span id="score">0</span>
- </div>
- </div>
- <div class="grid"></div>
- </div>
- <div class="cover-screen">
- <h2 id="over-text" class="hide">Game Over</h2>
- <p id="result"></p>
- <button id="start-button">Start Game</button>
- </div>
- <script src="script.js"></script>
- </body>
- </html>
-
Now paste the following codes into your style.css file
- * {
- padding: 0;
- margin: 0;
- box-sizing: border-box;
- font-family: Arial, sans-serif;
- }
- body {
- background-color: #282A35;
- }
- .heading {
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
- h1 {
- color: #e5e5e5;
- }
- .container {
- position: absolute;
- transform: translate(-50%, -50%);
- left: 50%;
- top: 50%;
- }
- h1 {
- font-size: 4em;
- }
- .score-container {
- color: #fff;
- }
- #score {
- font-weight: 600;
- }
- .grid {
- width: 25em;
- height: 25em;
- background-color: #cdc1b5;
- border: 5px solid #bbada0;
- margin: 0 auto;
- display: flex;
- flex-wrap: wrap;
- border-radius: 0.5em;
- }
- .box {
- width: 97.5px;
- height: 97.5px;
- border: 5px solid #bbada0;
- font-size: 40px;
- font-weight: bold;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .cover-screen {
- position: absolute;
- top: 0;
- left: 0;
- background-color: #282A35;
- height: 100%;
- width: 100%;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- }
- #start-button {
- background-color: #209DEE;
- padding: 1em 2em;
- border: none;
- border-radius: 0.5em;
- font-size: 1.5em;
- letter-spacing: 0.2px;
- color: #ffffff;
- }
- #start-button:hover{
- background: #0056b3;
- }
- .hide {
- display: none;
- }
- .box-2 {
- background-color: #9200FF;
- color: #F0F0F0;
- }
- .box-4 {
- background-color: #F7135B;
- color: #F0F0F0;
- }
-
- .box-8 {
- background-color: #FFC917;
- color: white;
- }
-
- .box-16 {
- background-color: #00CA18;
- color: white;
- }
-
- .box-32 {
- background-color: #0095D4;
- color: white;
- }
-
- .box-64 {
- background-color: #CE007B;
- color: white;
- }
-
- .box-128 {
- background-color: #FF5417;
- color: white;
- }
-
- .box-256 {
- background-color: #29D6A3;
- color: white;
- }
-
- .box-512 {
- background-color: #edc651;
- color: white;
- }
-
- .box-1024 {
- background-color: #000000;
- color: white;
- }
-
- .box-2048 {
- background-color: #ecc230;
- color: white;
- }
-
Now paste the following codes into your script.js file
- let grid = document.querySelector(".grid");
- const startButton = document.getElementById("start-button");
- const container = document.querySelector(".container");
- const coverScreen = document.querySelector(".cover-screen");
- const result = document.getElementById("result");
- const overText = document.getElementById("over-text");
-
- let matrix,
- score,
- isSwiped,
- touchY,
- initialY = 0,
- touchX,
- initialX = 0,
- rows = 4,
- columns = 4,
- swipeDirection;
-
- let rectLeft = grid.getBoundingClientRect().left;
- let rectTop = grid.getBoundingClientRect().top;
-
- const getXY = (e) => {
- touchX = e.touches[0].pageX - rectLeft;
- touchY = e.touches[0].pageY - rectTop;
- };
-
- const createGrid = () => {
- for (let i = 0; i < rows; i++) {
- for (let j = 0; j < columns; j++) {
- const boxDiv = document.createElement("div");
- boxDiv.classList.add("box");
- boxDiv.setAttribute("data-position", `${i}_${j}`);
- grid.appendChild(boxDiv);
- }
- }
- };
-
- const adjacentCheck = (arr) => {
- for (let i = 0; i < arr.length - 1; i++) {
- if (arr[i] == arr[i + 1]) {
- return true;
- }
- }
- return false;
- };
-
- const possibleMovesCheck = () => {
- for (let i in matrix) {
- if (adjacentCheck(matrix[i])) {
- return true;
- }
- let colarr = [];
- for (let j = 0; j < columns; j++) {
- colarr.push(matrix[i][j]);
- }
- if (adjacentCheck(colarr)) {
- return true;
- }
- }
- return false;
- };
-
- const randomPosition = (arr) => {
- return Math.floor(Math.random() * arr.length);
- };
-
- const hasEmptyBox = () => {
- for (let r in matrix) {
- for (let c in matrix[r]) {
- if (matrix[r][c] == 0) {
- return true;
- }
- }
- }
- return false;
- };
-
- const gameOverCheck = () => {
- if (!possibleMovesCheck()) {
- coverScreen.classList.remove("hide");
- container.classList.add("hide");
- overText.classList.remove("hide");
- result.innerText = `Final score: ${score}`;
- startButton.innerText = "Restart Game";
- }
- };
-
- const generateTwo = () => {
- if (hasEmptyBox()) {
- let randomRow = randomPosition(matrix);
- let randomCol = randomPosition(matrix[randomPosition(matrix)]);
- if (matrix[randomRow][randomCol] == 0) {
- matrix[randomRow][randomCol] = 2;
- let element = document.querySelector(
- `[data-position = '${randomRow}_${randomCol}']`
- );
- element.innerHTML = 2;
- element.classList.add("box-2");
- } else {
- generateTwo();
- }
- } else {
- gameOverCheck();
- }
- };
-
- const generateFour = () => {
- if (hasEmptyBox()) {
- let randomRow = randomPosition(matrix);
- let randomCol = randomPosition(matrix[randomPosition(matrix)]);
- if (matrix[randomRow][randomCol] == 0) {
- matrix[randomRow][randomCol] = 4;
- let element = document.querySelector(
- `[data-position= '${randomRow}_${randomCol}']`
- );
- element.innerHTML = 4;
- element.classList.add("box-4");
- } else {
- generateFour();
- }
- } else {
- gameOverCheck();
- }
- };
-
- const removeZero = (arr) => arr.filter((num) => num);
- const checker = (arr, reverseArr = false) => {
- arr = reverseArr ? removeZero(arr).reverse() : removeZero(arr);
-
- for (let i = 0; i < arr.length - 1; i++) {
- if (arr[i] == arr[i + 1]) {
- arr[i] += arr[i + 1];
- arr[i + 1] = 0;
- score += arr[i];
- }
- }
-
- arr = reverseArr ? removeZero(arr).reverse() : removeZero(arr);
-
- let missingCount = 4 - arr.length;
- while (missingCount > 0) {
- if (reverseArr) {
- arr.unshift(0);
- } else {
- arr.push(0);
- }
- missingCount -= 1;
- }
- return arr;
- };
-
- const slideDown = () => {
- for (let i = 0; i < columns; i++) {
- let num = [];
- for (let j = 0; j < rows; j++) {
- num.push(matrix[j][i]);
- }
- num = checker(num, true);
- for (let j = 0; j < rows; j++) {
- matrix[j][i] = num[j];
- let element = document.querySelector(`[data-position='${j}_${i}']`);
- element.innerHTML = matrix[j][i] ? matrix[j][i] : "";
- element.classList.value = "";
- element.classList.add("box", `box-${matrix[j][i]}`);
- }
- }
-
- let decision = Math.random() > 0.5 ? 1 : 0;
- if (decision) {
- setTimeout(generateFour, 200);
- } else {
- setTimeout(generateTwo, 200);
- }
- };
-
- const slideUp = () => {
- for (let i = 0; i < columns; i++) {
- let num = [];
- for (let j = 0; j < rows; j++) {
- num.push(matrix[j][i]);
- }
- num = checker(num);
- for (let j = 0; j < rows; j++) {
- matrix[j][i] = num[j];
- let element = document.querySelector(`[data-position = '${j}_${i}']`);
- element.innerHTML = matrix[j][i] ? matrix[j][i] : "";
- element.classList.value = "";
- element.classList.add("box", `box-${matrix[j][i]}`);
- }
- }
- let decision = Math.random() > 0.5 ? 1 : 0;
- if (decision) {
- setTimeout(generateFour, 200);
- } else {
- setTimeout(generateTwo, 200);
- }
- };
-
- const slideRight = () => {
- for (let i = 0; i < rows; i++) {
- let num = [];
- for (let j = 0; j < columns; j++) {
- num.push(matrix[i][j]);
- }
- num = checker(num, true);
- for (let j = 0; j < columns; j++) {
- matrix[i][j] = num[j];
- let element = document.querySelector(`[data-position = '${i}_${j}']`);
- element.innerHTML = matrix[i][j] ? matrix[i][j] : "";
- element.classList.value = "";
- element.classList.add("box", `box-${matrix[i][j]}`);
- }
- }
- let decision = Math.random() > 0.5 ? 1 : 0;
- if (decision) {
- setTimeout(generateFour, 200);
- } else {
- setTimeout(generateTwo, 200);
- }
- };
-
- const slideLeft = () => {
- for (let i = 0; i < rows; i++) {
- let num = [];
- for (let j = 0; j < columns; j++) {
- num.push(matrix[i][j]);
- }
-
- num = checker(num);
- for (let j = 0; j < columns; j++) {
- matrix[i][j] = num[j];
- let element = document.querySelector(`[data-position = '${i}_${j}']`);
- element.innerHTML = matrix[i][j] ? matrix[i][j] : "";
- element.classList.value = "";
- element.classList.add("box", `box-${matrix[i][j]}`);
- }
- }
- let decision = Math.random() > 0.5 ? 1 : 0;
- if (decision) {
- setTimeout(generateFour, 200);
- } else {
- setTimeout(generateTwo, 200);
- }
- };
-
- document.addEventListener("keyup", (e) => {
- if (e.code == "ArrowLeft") {
- slideLeft();
- } else if (e.code == "ArrowRight") {
- slideRight();
- } else if (e.code == "ArrowUp") {
- slideUp();
- } else if (e.code == "ArrowDown") {
- slideDown();
- }
- document.getElementById("score").innerText = score;
- });
-
- grid.addEventListener("touchstart", (event) => {
- isSwiped = true;
- getXY(event);
- initialX = touchX;
- initialY = touchY;
- });
-
- grid.addEventListener("touchmove", (event) => {
- if (isSwiped) {
- getXY(event);
- let diffX = touchX - initialX;
- let diffY = touchY - initialY;
- if (Math.abs(diffY) > Math.abs(diffX)) {
- swipeDirection = diffX > 0 ? "down" : "up";
- } else {
- swipeDirection = diffX > 0 ? "right" : "left";
- }
- }
- });
-
- grid.addEventListener("touchend", () => {
- isSwiped = false;
- let swipeCalls = {
- up: slideUp,
- down: slideDown,
- left: slideLeft,
- right: slideRight,
- };
- swipeCalls[swipeDirection]();
- document.getElementById("score").innerText = score;
- });
-
- const startGame = () => {
- score = 0;
- document.getElementById("score").innerText = score;
- grid.innerHTML = "";
- matrix = [
- [0, 0, 0, 0],
- [0, 0, 0, 0],
- [0, 0, 0, 0],
- [0, 0, 0, 0],
- ];
- container.classList.remove("hide");
- coverScreen.classList.add("hide");
- createGrid();
- generateTwo();
- generateTwo();
- };
-
- startButton.addEventListener("click", () => {
- startGame();
- swipeDirection = "";
- });
-
If you face any difficulties while creating your 2048 puzzle Game or your code is not working as expected, you can download the source code files by clicking on the download button.