Hey Everyone ! Codemagnet is back with another tutorial. Ever played Snake on your old Nokia phone? Well, imagine that game, but on your computer or phone browser! We’ve built it using basic web technologies like HTML for structure, CSS for styling, and JavaScript for making things move and react. You control a snake, guiding it around the screen to eat food and grow longer. But watch out! If you run into yourself or the walls, it’s game over. It’s a fun way to learn about how websites work and maybe even brush up on your gaming skills!
Steps For Creating Snake Game in JavaScript
To create a snake game using HTML, CSS, and JavaScript, 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(snake.html in my case) file. The file name must be index and its extension .html - Create a
style.css(style3.css in my case) file. The file name must be style and its extension .css - Create a
script.js(snake.js in my case) file. The file name must be script and its extension .js
To start, add the following HTML codes to your index.html file to create the game’s basic layout. The “play-board” container is empty now, but it will be filled with snake bodies and food elements later using JavaScript code.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Snake Game</title>
<link rel="stylesheet" href="style3.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css">
<script src="snake.js" defer></script>
</head>
<body>
<div class="wrapper">
<div class="game-details">
<span class="score">Score: 0</span>
<span class="high-score">High Score: 0</span>
</div>
<div class="play-board"></div>
<div class="controls">
<i data-key="ArrowLeft" class="fa-solid fa-arrow-left-long"></i>
<i data-key="ArrowUp" class="fa-solid fa-arrow-up-long"></i>
<i data-key="ArrowRight" class="fa-solid fa-arrow-right-long"></i>
<i data-key="ArrowDown" class="fa-solid fa-arrow-down-long"></i>
</div>
</div>
</body>
</html>
next step, include the following CSS code in your style.css file to structure the layout of the Snake game. Note that the control arrow keys are initially displayed only on small devices like phones. However, if you wish to show them on all devices, you can adjust the media query code accordingly.
If you wish you can learn by watching the tutorial for the same below:
/* Import Google font */
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Open Sans', sans-serif;
}
body {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: #E3F2FD;
}
.wrapper {
width: 65vmin;
height: 70vmin;
display: flex;
overflow: hidden;
flex-direction: column;
justify-content: center;
border-radius: 5px;
background: #293447;
box-shadow: 0 20px 40px rgba(52, 87, 220, 0.2);
}
.game-details {
color: #B8C6DC;
font-weight: 500;
font-size: 1.2rem;
padding: 20px 27px;
display: flex;
justify-content: space-between;
}
.play-board {
height: 100%;
width: 100%;
display: grid;
background: #212837;
grid-template: repeat(30, 1fr) / repeat(30, 1fr);
}
.play-board .food {
background: #FF003D;
}
.play-board .head {
background: #60CBFF;
}
.controls {
display: none;
justify-content: space-between;
}
.controls i {
padding: 25px 0;
text-align: center;
font-size: 1.3rem;
color: #B8C6DC;
width: calc(100% / 4);
cursor: pointer;
border-right: 1px solid #171B26;
}
@media screen and (max-width: 800px) {
.wrapper {
width: 90vmin;
height: 115vmin;
}
.game-details {
font-size: 1rem;
padding: 15px 27px;
}
.controls {
display: flex;
}
.controls i {
padding: 15px 0;
font-size: 1rem;
}
}
Lastly, integrate the provided JavaScript code into your script.js file to implement the functionality for the snake game. This script manages the logic governing the snake’s movement, food consumption, score updating, and collision detection with walls or its own body.
const playBoard = document.querySelector(".play-board");
const scoreElement = document.querySelector(".score");
const highScoreElement = document.querySelector(".high-score");
const controls = document.querySelectorAll(".controls i");
let gameOver = false;
let foodX, foodY;
let snakeX = 5, snakeY = 5;
let velocityX = 0, velocityY = 0;
let snakeBody = [];
let setIntervalId;
let score = 0;
// Getting high score from the local storage
let highScore = localStorage.getItem("high-score") || 0;
highScoreElement.innerText = `High Score: ${highScore}`;
const updateFoodPosition = () => {
// Passing a random 1 - 30 value as food position
foodX = Math.floor(Math.random() * 30) + 1;
foodY = Math.floor(Math.random() * 30) + 1;
}
const handleGameOver = () => {
// Clearing the timer and reloading the page on game over
clearInterval(setIntervalId);
alert("Game Over! Press OK to replay...");
location.reload();
}
const changeDirection = e => {
// Changing velocity value based on key press
if(e.key === "ArrowUp" && velocityY != 1) {
velocityX = 0;
velocityY = -1;
} else if(e.key === "ArrowDown" && velocityY != -1) {
velocityX = 0;
velocityY = 1;
} else if(e.key === "ArrowLeft" && velocityX != 1) {
velocityX = -1;
velocityY = 0;
} else if(e.key === "ArrowRight" && velocityX != -1) {
velocityX = 1;
velocityY = 0;
}
}
// Calling changeDirection on each key click and passing key dataset value as an object
controls.forEach(button => button.addEventListener("click", () => changeDirection({ key: button.dataset.key })));
const initGame = () => {
if(gameOver) return handleGameOver();
let html = `<div class="food" style="grid-area: ${foodY} / ${foodX}"></div>`;
// Checking if the snake hit the food
if(snakeX === foodX && snakeY === foodY) {
updateFoodPosition();
snakeBody.push([foodY, foodX]); // Pushing food position to snake body array
score++; // increment score by 1
highScore = score >= highScore ? score : highScore;
localStorage.setItem("high-score", highScore);
scoreElement.innerText = `Score: ${score}`;
highScoreElement.innerText = `High Score: ${highScore}`;
}
// Updating the snake's head position based on the current velocity
snakeX += velocityX;
snakeY += velocityY;
// Shifting forward the values of the elements in the snake body by one
for (let i = snakeBody.length - 1; i > 0; i--) {
snakeBody[i] = snakeBody[i - 1];
}
snakeBody[0] = [snakeX, snakeY]; // Setting first element of snake body to current snake position
// Checking if the snake's head is out of wall, if so setting gameOver to true
if(snakeX <= 0 || snakeX > 30 || snakeY <= 0 || snakeY > 30) {
return gameOver = true;
}
for (let i = 0; i < snakeBody.length; i++) {
// Adding a div for each part of the snake's body
html += `<div class="head" style="grid-area: ${snakeBody[i][1]} / ${snakeBody[i][0]}"></div>`;
// Checking if the snake head hit the body, if so set gameOver to true
if (i !== 0 && snakeBody[0][1] === snakeBody[i][1] && snakeBody[0][0] === snakeBody[i][0]) {
gameOver = true;
}
}
playBoard.innerHTML = html;
}
updateFoodPosition();
setIntervalId = setInterval(initGame, 100);
document.addEventListener("keyup", changeDirection);
Let’s break down the code and explain each part:
const playBoard = document.querySelector(".play-board");: This selects the element with the class “play-board”, which is the game board where the snake and food will be displayed.const scoreElement = document.querySelector(".score");: This selects the element with the class “score”, where the current score of the game will be displayed.const highScoreElement = document.querySelector(".high-score");: This selects the element with the class “high-score”, where the highest score achieved in the game will be displayed.const controls = document.querySelectorAll(".controls i");: This selects all the arrow icons (representing the controls) inside elements with the class “controls”.- Variables initialization:
let gameOver = false;: Indicates whether the game is over or not.let foodX, foodY;: Coordinates for the food position.let snakeX = 5, snakeY = 5;: Initial position of the snake.let velocityX = 0, velocityY = 0;: Velocity (direction) of the snake.let snakeBody = [];: Array to store the positions of the snake’s body parts.let setIntervalId;: ID returned bysetInterval()function, used to control the game loop.let score = 0;: Current score of the player.
- Retrieving high score from local storage and updating the UI.
updateFoodPosition()function: Generates random coordinates for the food position.handleGameOver()function: Handles the game over condition by clearing the timer and reloading the page.changeDirection()function: Updates the snake’s velocity based on the pressed arrow keys or the arrow icons clicked.- Event listener for arrow icon clicks to change the snake’s direction.
initGame()function: Initializes the game loop. It updates the game state, checks for collisions, updates the score, and renders the game board.setIntervalIdis used to callinitGame()repeatedly every 100 milliseconds, creating the game loop.- Event listener for keyup events to change the snake’s direction when arrow keys are pressed.
This code efficiently manages the game mechanics, including movement, collision detection, score tracking, and UI updates.
you’ve now built a traditional Snake Game using HTML, CSS, and JavaScript. This game is accessible through any device browser, offering an enjoyable gaming experience. I trust that this Snake Game project has provided valuable insights into DOM manipulation, honed problem-solving abilities, and enhanced various web development skills.





Leave a Reply