How to Make a Snake Game in JavaScript!

About: I am a 13 year old kid who is Passionate for Technology. I love coding and i know languages like PHP , JS & C++. I also love Arduino and Electronics. Love to learn new things

In this Tutorial we will be creating a Retro Snake game in Javascript!

As it is made in JavaScript it can be run in a browser and works very well, You will need some basic javascript knowledge beforehand !

So without Wasting time , LETS GET STARTED!

Step 1: Gather All the Needs!

We need some supplies to make this game before:

  • A Computer
  • A Web Browser installed and updated
  • A Text Editor ( You can use Notepad but i am using Komodo Edit )
  • Basic Javascript & HTML,CSS Knowledge
  • Some imagination, time & patiencetime

Final Code can be found here: Source Code

Step 2: Check Your System!

You need to enable JavaScript for this project to work, to enable this follow these steps:

  1. Click the Chrome menu in the top right hand corner of your browser
  2. Select Settings

  3. Click Show advanced settings Under the "Privacy" section, click the Content settings button.

  4. Click Show advanced settings Under the "Privacy" section, click the Content settings button. In the "Javascript" section, select "Allow all sites to run JavaScript (recommended)"

Now you are ready to start your project , lets begin!

Step 3: Setup the Files

You need to your text editor (notepad or any other) and make a file named snake.html.

Open this file in the code editor and in the browser and we are ready to code now!

Step 4: Creating the Canvas

We are going to start coding, lets begin:

First we will make a canvas for the game from the below code:

test.html

<html>
<head>
<title>Snake Gametitle>
head>
<body>
<canvasid="gameCanvas"width="300"height="300">canvas>
body>
html>
view rawtest.html hosted with ❤ by GitHub

Step 5: Give the Canvas a Background Color and a Border

To make our canvas visible, we can give it a border by writing some JavaScript code. To do that, we need to insert <script> tags where all our JavaScript code will go.

We can now write some JavaScript code, between the enclosing <script> tags. Update your code as below.

snake.html

<html>
<head>
<title>Snake Gametitle>
head>
<body>
<canvasid="gameCanvas"width="300"height="300">canvas>
<script>
/** CONSTANTS **/
constCANVAS_BORDER_COLOUR='black';
constCANVAS_BACKGROUND_COLOUR="white";
// Get the canvas element
var gameCanvas =document.getElementById("gameCanvas");
// Return a two dimensional drawing context
var ctx =gameCanvas.getContext("2d");
// Select the colour to fill the canvas
ctx.fillStyle=CANVAS_BACKGROUND_COLOUR;
// Select the colour for the border of the canvas
ctx.strokestyle=CANVAS_BORDER_COLOUR;
// Draw a "filled" rectangle to cover the entire canvas
ctx.fillRect(0, 0, gameCanvas.width, gameCanvas.height);
// Draw a "border" around the entire canvas
ctx.strokeRect(0, 0, gameCanvas.width, gameCanvas.height);
script>
body>
html>
view rawsnake.html hosted with ❤ by GitHub

Step 6: Creating and Drawing Our Snake

To display the snake on the canvas, we can write a function to draw a rectangle for each pair of coordinates.

After this if you open your browser: you will see something like a dash between the screen

function drawSnakePart(snakePart) {
ctx.fillStyle = 'lightgreen'; ctx.strokestyle = 'darkgreen'; ctx.fillRect(snakePart.x, snakePart.y, 10, 10); ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);

}

function drawSnake() {
snake.forEach(drawSnakePart); }

Step 7: Enabling Snake to Move

We will now update our code to the below one to enable it to move:

snake.html

<html>
<head>
<title>Snake Gametitle>
head>
<body>
<canvasid="gameCanvas"width="300"height="300">canvas>
<script>
/** CONSTANTS **/
constCANVAS_BORDER_COLOUR='black';
constCANVAS_BACKGROUND_COLOUR="white";
constSNAKE_COLOUR='lightgreen';
constSNAKE_BORDER_COLOUR='darkgreen';
let snake = [
{x:150, y:150},
{x:140, y:150},
{x:130, y:150},
{x:120, y:150},
{x:110, y:150}
]
// Horizontal velocity
let dx =10;
// Vertical velocity
let dy =0;
// Get the canvas element
var gameCanvas =document.getElementById("gameCanvas");
// Return a two dimensional drawing context
var ctx =gameCanvas.getContext("2d");
// Select the colour to fill the canvas
ctx.fillStyle=CANVAS_BACKGROUND_COLOUR;
// Select the colour for the border of the canvas
ctx.strokestyle=CANVAS_BORDER_COLOUR;
// Draw a "filled" rectangle to cover the entire canvas
ctx.fillRect(0, 0, gameCanvas.width, gameCanvas.height);
// Draw a "border" around the entire canvas
ctx.strokeRect(0, 0, gameCanvas.width, gameCanvas.height);
// Move on step to the right
advanceSnake()
// Change vertical velocity to 0
dx =0;
// Change horizontal velocity to 10
dy =-10;
// Move one step up
advanceSnake();
// Draw snake on the canvas
drawSnake();
/**
* Advances the snake by changing the x-coordinates of its parts
* according to the horizontal velocity and the y-coordinates of its parts
* according to the vertical veolocity
*/
functionadvanceSnake() {
consthead= {x: snake[0].x+ dx, y: snake[0].y+ dy};
snake.unshift(head);
snake.pop();
}
/**
* Draws the snake on the canvas
*/
functiondrawSnake() {
// loop through the snake parts drawing each part on the canvas
snake.forEach(drawSnakePart)
}
/**
* Draws a part of the snake on the canvas
* @param { object } snakePart - The coordinates where the part should be drawn
*/
functiondrawSnakePart(snakePart) {
// Set the colour of the snake part
ctx.fillStyle=SNAKE_COLOUR;
// Set the border colour of the snake part
ctx.strokestyle=SNAKE_BORDER_COLOUR;
// Draw a "filled" rectangle to represent the snake part at the coordinates
// the part is located
ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
// Draw a border around the snake part
ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
}
script>
body>
html>
view rawsnake.html hosted with ❤ by GitHub

Step 8: Changing Snake Direction

Our next task is to change the snake’s direction when one of the arrow keys is pressed. Add the following code after the drawSnakePart function.

There is nothing tricky going on here. We check if the key pressed matches one of the arrow keys. If it does, we change the vertical and horizontal velocity as described earlier.
Notice that we also check if the snake is moving in the opposite direction of the new intended direction. This is to prevent our snake from reversing, for example when you press the right arrow key when the snake is moving to the left.

function changeDirection(event) {

const LEFT_KEY = 37;

const RIGHT_KEY = 39;
const UP_KEY = 38; const DOWN_KEY = 40; const keyPressed = event.keyCode; const goingUp = dy === -10; const goingDown = dy === 10; const goingRight = dx === 10; const goingLeft = dx === -10; if (keyPressed === LEFT_KEY && !goingRight) { dx = -10; dy = 0; } if (keyPressed === UP_KEY && !goingDown) { dx = 0; dy = -10; } if (keyPressed === RIGHT_KEY && !goingLeft) { dx = 10; dy = 0; } if (keyPressed === DOWN_KEY && !goingDown) { dx = 0; dy = 10; } }


Step 9: Generating Food for the Snake

For our snake food, we have to generate a random set of coordinates. We can use a helper function randomTen to produce two numbers. One for the x-coordinate and one for the y-coordinate. We also have to make sure that the food is not located where the snake currently is. If it is, we have to generate a new food location.

function randomTen(min, max) {
  return Math.round((Math.random() * (max-min) + min) / 10) * 10;
}function createFood() {
  foodX = randomTen(0, gameCanvas.width - 10);
  foodY = randomTen(0, gameCanvas.height - 10);  snake.forEach(function isFoodOnSnake(part) {
    const foodIsOnSnake = part.x == foodX && part.y == foodY
    if (foodIsOnSnake)
      createFood();
  });
}

We then have to create a function to draw the food on the canvas.

function drawFood() {
 ctx.fillStyle = 'red';
 ctx.strokestyle = 'darkred';
 ctx.fillRect(foodX, foodY, 10, 10);
 ctx.strokeRect(foodX, foodY, 10, 10);
}

Finally we can call createFood before calling main. Don’t forget to also update main to use the drawFood function.

function main() {
  setTimeout(function onTick() {
    clearCanvas();
    drawFood()
    advanceSnake();
    drawSnake();    main();
  }, 100)
}

Step 10: Growing the Snake

Growing our snake is simple. We can update our advanceSnake function to check if the head of the snake is touching the food. If it is we can skip removing the last part of the snake and create a new food location.

function advanceSnake() {
  const head = {x: snake[0].x + dx, y: snake[0].y};  snake.unshift(head);  const didEatFood = snake[0].x === foodX && snake[0].y === foodY;
  if (didEatFood) {
    createFood();
  } else {
    snake.pop();
  }
}

Step 11: Keeping Track of the Score

To make the game more enjoyable for the player, we can also add a score that increases when the snake eats food.

Create a new variable score and set it to 0 after the snake declaration. let score = 0;Next add a new div with an id “score” before the canvas. We can use this to display the score.
Finally update advanceSnake to increase and display the score when the snake eats the food.
function advanceSnake() {
  ...  if (didEatFood) {
    score += 10;
    document.getElementById('score').innerHTML = score;    createFood();
  } else {
    ...
  }
}

Step 12: Near the End!

There is one final piece left, and that is to end the game. To do that we can create a function didGameEnd that returns true when the game has ended or false otherwise.

function didGameEnd() {
  for (let i = 4; i < snake.length; i++) {
    const didCollide = snake[i].x === snake[0].x &&
      snake[i].y === snake[0].y    if (didCollide) return true
  }  const hitLeftWall = snake[0].x < 0;
  const hitRightWall = snake[0].x > gameCanvas.width - 10;
  const hitToptWall = snake[0].y < 0;
  const hitBottomWall = snake[0].y > gameCanvas.height - 10;  return hitLeftWall || 
         hitRightWall || 
         hitToptWall ||
         hitBottomWall
}

First we check if the snake’s head touches another part of the snake and return true if it does.

Step 13: Bind It All Up Together!

Now you are ready to play, your code should look like this:

snake.html

<html>
<head>
<title>Snake Gametitle>
head>
<body>
<canvasid="gameCanvas"width="300"height="300">canvas>
<script>
/** CONSTANTS **/
constCANVAS_BORDER_COLOUR='black';
constCANVAS_BACKGROUND_COLOUR="white";
constSNAKE_COLOUR='lightgreen';
constSNAKE_BORDER_COLOUR='darkgreen';
let snake = [
{x:150, y:150},
{x:140, y:150},
{x:130, y:150},
{x:120, y:150},
{x:110, y:150}
]
// Horizontal velocity
let dx =10;
// Vertical velocity
let dy =0;
// Get the canvas element
var gameCanvas =document.getElementById("gameCanvas");
// Return a two dimensional drawing context
var ctx =gameCanvas.getContext("2d");
// Select the colour to fill the canvas
ctx.fillStyle=CANVAS_BACKGROUND_COLOUR;
// Select the colour for the border of the canvas
ctx.strokestyle=CANVAS_BORDER_COLOUR;
// Draw a "filled" rectangle to cover the entire canvas
ctx.fillRect(0, 0, gameCanvas.width, gameCanvas.height);
// Draw a "border" around the entire canvas
ctx.strokeRect(0, 0, gameCanvas.width, gameCanvas.height);
// Move on step to the right
advanceSnake()
// Change vertical velocity to 0
dx =0;
// Change horizontal velocity to 10
dy =-10;
// Move one step up
advanceSnake();
// Draw snake on the canvas
drawSnake();
/**
* Advances the snake by changing the x-coordinates of its parts
* according to the horizontal velocity and the y-coordinates of its parts
* according to the vertical veolocity
*/
functionadvanceSnake() {
consthead= {x: snake[0].x+ dx, y: snake[0].y+ dy};
snake.unshift(head);
snake.pop();
}
/**
* Draws the snake on the canvas
*/
functiondrawSnake() {
// loop through the snake parts drawing each part on the canvas
snake.forEach(drawSnakePart)
}
/**
* Draws a part of the snake on the canvas
* @param { object } snakePart - The coordinates where the part should be drawn
*/
functiondrawSnakePart(snakePart) {
// Set the colour of the snake part
ctx.fillStyle=SNAKE_COLOUR;
// Set the border colour of the snake part
ctx.strokestyle=SNAKE_BORDER_COLOUR;
// Draw a "filled" rectangle to represent the snake part at the coordinates
// the part is located
ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
// Draw a border around the snake part
ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
}
script>
body>
html>
view rawsnake.html hosted with ❤ by GitHub

Step 14: And You Are Done.......

now you have created your own snake game! Just save it and play yourself and with your friends!

here is the final result! NOTE: You need to refresh if you want o play again!

Cheers!

:)

Share

    Recommendations

    • Cardboard Challenge

      Cardboard Challenge
    • Toys Contest

      Toys Contest
    • PCB Contest

      PCB Contest

    2 Discussions

    Hi, I have updated the instructable and now you can see the end result in the last step!
    I have also added the result to the comment!
    :)

    ezgif.com-video-to-gif.gif