Most of us would have played a snake game in our childhood. Today we will see how we can create a snake game by our self using JavaScript, HTML, CSS.
Before we start creating the game you will to have some basic knowledge on JavaScript canvas and HTML.
We will have one single file “snakeGame.html” which will contain all the HTML, CSS, JS code in it.
CSS to style the game and JS code to handle the HTML canvas and control the creation and handling the event of snake.
Step 1 : Let create basic HTML code.
<!DOCTYPE html>
<head>
<title>Snake games by simple coder</title>
</head>
<body>
<div id="snake">
<h3></h3>
<canvas id="canvas" height="600" width="600"></canvas>
</div>
</body>
</html>
We have basic HTML code and with that we have added a canvas element with id “canvas” and height 600 and width 600. The h3 tag will be used to show score dynamically during game.
Step2: Add JS function to game
We have added code to create snake head and food. The snake is an array which will initial contain head(snake[0]) and will grow dynamically when it eats food. The position of the snake is X 300 and Y 300.
The position of food is randomly pickup by using Math.Random() and Math.round() methods in JS.
The setInterval() method will call begin() method every 150 milliseconds
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var box = 30;//size of snake
var game = setInterval(begin, 150);
var dir;
var score = 0;
//creating snake;
snake = [];
snake[0] = {
x: box * 10,//300
y: box * 10//300
};
//food obj
food = {
x: Math.round(Math.random() * 20) * 30,
y: Math.round(Math.random() * 20) * 30
};
Step 3 : Controlling snake movement
Now let create a method to control the snake movement for that we will add EventListener to keydown(when a key is pressed) and event.keyCode give the keycode of each button(up, down, left, right).
When a button is clicked we will check the condition whether its opposite direction or not because the snake cannot go in reverse direction.
window.addEventListener("keydown", direction);
function direction(event) {
var keycode = event.keyCode;
if (keycode == 40 && dir != "up")
dir = "down";
if (keycode == 37 && dir != "right")
dir = "left";
if (keycode == 38 && dir != "down")
dir = "up";
if (keycode == 39 && dir != "left")
dir = "right";
}
Step 4: Rendering the Game screen
Below code is used to render the screen and show the updated the snake and food position in screen.
clearRect(X, Y, Width, Height); will clear the thing on canvas, and we will render the new position of player on screen.
ctx.clearRect(0, 0, 600, 600);
var snakelength= snake.length;
for(var i=0;i<snakelength;i++)
if (i == 0)
ctx.fillStyle = "#0B0C10";
else
ctx.fillStyle = "red";
ctx.fillRect(snake[i].x, snake[i].y, box, box);
ctx.strokeStyle = "black";
ctx.strokeRect(snake[i].x, snake[i].y, box, box);
}
ctx.fillStyle = 'red';
ctx.fillRect(food.x, food.y, box, box);
ctx.strokeStyle = "black";
ctx.strokeRect(food.x, food.y, box, box);
Step 5: Updated the Score
Now we will update the score if snake eat a food and show the score inside H3 tag and again create a new food with random X and Y values.
if (oldx == food.x && oldy == food.y) {
var h = document.getElementsByTagName("h3");
score = score + 1;
h[0].innerHTML = "score " + score;
food = {
x: Math.floor(Math.random() * 20) * 30,
y: Math.floor(Math.random() * 20) * 30
};
} else {
snake.pop();
}
Step 6: Game over
Finally, if the snake touch the boundary then it's game over now let us the condition for that. To restart the game we have to refresh the page.
if (oldx < 0 || oldx > 570 || oldy < 0 || oldy > 570 || toucing(newhead, snake)) {
gamelost();
clearInterval(game);
}
function gamelost() {
ctx.font = "30px Arial";
ctx.fillStyle = "red";
ctx.fillText("Game over", canvas.width / 2 - 100, canvas.height / 2 - 100);
}
Let style the game using some CSS
canvas{
background-color:#C5C6C7;
position: relative;
left:8%;
}
#snake{
width: 700px;
height: 700px;
left:11%;
position:absolute;
/*background-image: url(back1.jpg);
background-size: 50% 80%;
background-repeat: no-repeat;*/
background-color:#D79922;
}
h3{
height:1%;
width:15%;
position:relative;
color:#66FCF1;
left:8%;
font-size:30px;
font-weight:bold;
}
Final complete source code is below.
<html>
<head>
<title>snake games by simple coder</title>
<style>
canvas {
background-color: #C5C6C7;
position: relative;
left: 8%;
}
#snake {
width: 700px;
height: 700px;
left: 11%;
position: absolute;
}
h3 {
height: 1%;
width: 15%;
position: relative;
color: #66FCF1;
left: 8%;
font-size: 30px;
font-weight: bold;
}
</style>
</head>
<body>
<div id="snake">
<h3>Score</h3>
<canvas id="canvas" height="600" width="600"></canvas>
</div>
</body>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var box = 30;
var game = setInterval(begin, 150);
var dir;
var score = 0;
//creating snake;
snake = [];
snake[0] = {
x: box * 10,
y: box * 10
};
//food obj
food = {
x: Math.round(Math.random() * 20) * 30,
y: Math.round(Math.random() * 20) * 30
};
window.addEventListener("keydown", direction);
function direction(event) {
var keycode = event.keyCode;
if(keycode == 40 && dir != "up") dir = "down";
if(keycode == 37 && dir != "right") dir = "left";
if(keycode == 38 && dir != "down") dir = "up";
if(keycode == 39 && dir != "left") dir = "right";
}
function gamelost() {
ctx.font = "30px Arial";
ctx.fillStyle = "red";
ctx.fillText("Game over", canvas.width / 2 - 100, canvas.height / 2 - 100);
}
function begin() {
ctx.clearRect(0, 0, 600, 600);
var snakelength= snake.length;
for(var i=0;i<snakelength;i++)
if(i == 0) ctx.fillStyle = "#0B0C10";
else ctx.fillStyle = "red";
ctx.fillRect(snake[i].x, snake[i].y, box, box);
ctx.strokeStyle = "black";
ctx.strokeRect(snake[i].x, snake[i].y, box, box);
}
ctx.fillStyle = 'red';
ctx.fillRect(food.x, food.y, box, box);
ctx.strokeStyle = "black";
ctx.strokeRect(food.x, food.y, box, box);
oldx = snake[0].x;
oldy = snake[0].y;
if(dir == "up") oldy = oldy - box;
else if(dir == "left") oldx = oldx - box;
else if(dir == "right") oldx = oldx + box;
else if(dir == "down") oldy = oldy + box;
var newhead = {
x: oldx,
y: oldy
};
if(oldx == food.x && oldy == food.y) {
var h = document.getElementsByTagName("h3");
score = score + 1;
h[0].innerHTML = "score " + score;
food = {
x: Math.floor(Math.random() * 20) * 30,
y: Math.floor(Math.random() * 20) * 30
};
} else {
snake.pop();
}
if(oldx < 0 || oldx > 570 || oldy < 0 || oldy > 570 || touching(newhead, snake)) {
gamelost();
clearInterval(game);
}
snake.unshift(newhead);
}
function touching(newhead, snake) {
for(var i = 0; i < snake.length; i++) {
if(newhead.x == snake[i].x && newhead.y == snake[i].y) return true;
}
return false;
}
</script>
</html>