Open-Source Internship opportunity by OpenGenus for programmers. Apply now.
In this article, we have explained how to build Snake game using HTML, CSS and JavaScript. This is a strong web development project to work on and is a good addition to Web Developer Portfolio.
TABLE OF CONTENTS
- HTML
- CSS
- JavaScript
- The createBoard function
- The startGame function
- The moveOutcome function
- The moveSnake function
- The checkForHits function
- The eatFruit function
- The randomFruit function
- Set up controls
- The replay function
A breif introduction of the game, the snake game is a simple game created using HTML
, CSS
and Javascript
. The snake navigates the box trying to eat a fruit. Once the snake eats the fruit, the length of the snake increases and the pace becomes faster.
Then the game ends if the snake slide into any part of its body or part of the box.
HTML
For the HTML set up we have a <div>
of class scoreDisplay thats serves the purpose of displaying the scores. Also a <div>
with class box will be serve as the playground. Thee <div>
class button will be used as the game control. The <div>
with class popup will serve as the replay button.
<h1>Javascript Snake Game</h1>
<div class="scoreDisplay"></div>
<div class="grid"></div>
<div class="button">
<button class="top">top</button>
<button class="bottom">bottom</button>
<button class="left">left</button>
<button class="right">right</button>
</div>
<div class="popup">
<button class="playAgain">Play Again</button>
</div>
CSS
The box which is the playground has display: flex
and other set of dimensions. This will allow the container items to ne altered and set dimentsions to order the position. The flex-wrap
property allows enabling the contol direction in which the lines are stacked. The purpose of the CSS
is to style and layout the game
body {
background: #e3d5eb;
}
.grid {
width: 200px;
height: 200px;
border: 2px solid black;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.grid div {
width: 20px;
height: 20px;
}
.snake {
background: #a12e0c;
}
.apple {
background: #54f2ef;
border-radius: 20px;
}
.popup {
background: #1e52e0;
width: 100px;
height: 100px;
border-radius: 20px;
position: fixed;
top: 100px;
left: 100px;
display: flex;
justify-content: center;
align-items: center;
}
Javascript
The first thing we need to do is determine the variables
let grid = document.querySelector(".grid")
let popup = document.querySelector(".popup");
let playAgain = document.querySelector(".playAgain");
let scoreDisplay = document.querySelector(".scoreDisplay")
let left = document.querySelector(".left")
let bottom = document.querySelector(".bottom")
let right = document.querySelector(".right")
let up = document.querySelector(".top")
let width=10;
let currentIndex = 0
let appleIndex=0
let currentSnake=[2,1,0]
let direction =1
let score = 0
let speed = 0.8
let intervalTime =0
let interval =0
The variable width is the same as the width of the box. We make the snake and array
call currentSnake
Will we use an eventListener on the object called DomContentLoaded and this is initiated as soon as the HTML content is loaded on our screen
document.addEventListener("DOMContentLoaded", function () {
document.addEventListener("keyup", control);
createBoard();
startGame();
playAgain.addEventListener("click", replay);
});
The createBoard function
To initiate the createBoard
function we need 100 divs for this project. Stop the div popup and we loop to 100 each time as we create a new div and append it to the grid which is the game board. This will also add some styling to the .grid div
.
function createBoard() {
popup.style.display = "none";
for (let i = 0; i < 100; i++) {
let div = document.createElement("div");
grid.appendChild(div);
}
}
The startGame function
The startGame
function targets all the divs. Select a place on the grid for the apple
using the randApple
function, while the direction means where the snake is sliding towards
The intervalTime
sets the time it takes for the snake to move around the grid, the currentSnake
indicates exactly on the grid where the snake will be. It important to note that the snake is a divs highlighted by colors. To make the snake visibile we will lopp over the currentSnake
with forEach
. Next We are going to append a setInterval
call with funtion Outcome
and a time of intervalTime
to the variable interval
. The ``moveOutcome runs at 100ms(1s).
function startGame() {
let squares = document.querySelectorAll(".grid div");
randomApple(squares);
direction = 1;
scoreDisplay.innerHTML = score;
intervalTime = 1000;
currentSnake = [2, 1, 0];
currentIndex = 0;
currentSnake.forEach((index) => squares[index].classList.add("snake"));
interval = setInterval(moveOutcome, intervalTime);
}
The moveOutcome function
The moveOutcome
tagert all the grid divs too, and confirm if the checkForHits
function returns true.
If it does, this means we have hit something and then it displays the replay button and it clears the interval. If it returns false, this means we did not hit anything and we move the snake with the moveSnake
function. The game can come to an end every 1sec if the checkForHits
is true or extended if the checkForHits
returns false
function moveOutcome() {
let squares = document.querySelectorAll(".grid div");
if (checkForHits(squares)) {
alert("Try Again!!!");
popup.style.display = "flex";
return clearInterval(interval);
} else {
moveSnake(squares);
}
}
The moveSnake function
The moveSnake
function receives an argument called squares..
The first thing we need to do is remove the last element of the currentSnake
array via pop (this is the tail and the first element is always the head). Basically the snake moves a step forward leaving the previous position it was in. After this we simply add a new value to the beginning of the array with unShift
.
function moveSnake(squares) {
let tail = currentSnake.pop();
squares[tail].classList.remove("snake");
currentSnake.unshift(currentSnake[0] + direction);
eatApple(squares, tail);
squares[currentSnake[0]].classList.add("snake");
}
The checkForHits function
If the currentSnake
which is the head of the snake (0) in addition to the width (10) is equal to the total area of the width. This is calculated as Width x Width = 100.
The last layer of the grid is 97. Assumming the snake head is at the last layer of the grid (97) and the movement of the snake is downard, it will hit the bottom hence the game will be over. But if in another sceneario the if the snake was at the aformentioned layer and the player was able to change the direction of the snake using the left key, the snake will not hit anything. At any time duing the game if the snake head touch any of the borderwall(gameboard) the game is over and if the player avoids the border wall by using the controls, the game will continue while the player points increase each time the snake eat the apple.
function checkForHits(squares) {
if (
(currentSnake[0] + width >= width * width && direction === width) ||
(currentSnake[0] % width === width - 1 && direction === 1) ||
(currentSnake[0] % width === 0 && direction === -1) ||
(currentSnake[0] - width <= 0 && direction === -width) ||
squares[currentSnake[0] + direction].classList.contains("snake")
) {
return true;
} else {
return false;
}
}
The eatApple function
The eatApple
function checks if the next grid contains an apple, if its true the snakes eats the apple and its tail increase by a value. This function receives the following arguments; squares, .grid div and tail. It then checks if the next position the snake moves to contains an apple.
Subsequently a new position will be selected for the apple using the functionrandomApple
. Immeadiately after a value will be added to the score.
function eatApple(squares, tail) {
if (squares[currentSnake[0]].classList.contains("apple")) {
squares[currentSnake[0]].classList.remove("apple");
squares[tail].classList.add("snake");
currentSnake.push(tail);
randomApple(squares);
score++;
scoreDisplay.textContent = score;
clearInterval(interval);
intervalTime = intervalTime * speed;
interval = setInterval(moveOutcome, intervalTime);
}
}
The randomApple function
The randomApple
we pick a spot to place our apple by using a do while loop. It picks a random position with Math.random()
in the do loop and checks if the spot it picked already contains a snake class.
This means that the condition in the do statement will keep on running until it finds a spot that does not contain a snake we will keep doing this while this returns true. Once it finds a spot it simply gives that spot a class of apple.
function randomApple(squares) {
do {
appleIndex = Math.floor(Math.random() * squares.length);
} while (squares[appleIndex].classList.contains("snake"));
squares[appleIndex].classList.add("apple");
}
Set up controls
We already set an eventListener
for keyup
. This function starts working once you press a key on the keyboard. With it we can make changes to the direction of the snake.
The next thing is to create thereplay
div which will popup when the snake hits anything. This will reset the game.
function control(e) {
if (e.keycode === 39) {
direction = 1;
} else if (e.keycode === 38) {
direction = -width;
} else if (e.keycode === 37) {
direction = -1;
} else if (e.keycode === 40) {
direction = +width;
}
}
For mobile and tablets:
up.addEventListener("click", () => (direction = -width));
bottom.addEventListener("click", () => (direction = +width));
left.addEventListener("click", () => (direction = -1));
right.addEventListener("click", () => (direction = 1));
The replay function
This function will clear the grid and run the previous functions
function replay() {
grid.innerHTML = "";
createBoard();
startGame();
popup.style.display = "none";
}
A screenshot of the game
With this article at OpenGenus, you must have the complete idea of how to build Snake game in Javascript.