×

Search anything:

Snake Game Using JavaScript

Internship at OpenGenus

Get this book -> Problems on Array: For Interviews and Competitive Programming

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";
}

snakejava
A screenshot of the game

With this article at OpenGenus, you must have the complete idea of how to build Snake game in Javascript.

Snake Game Using JavaScript
Share this