Notifications 0
Creating a Snake Game Using HTML, CSS, and JavaScript
Ashutosh Singh - March 30, 2025
Are you ready to create your own version of the classic Snake game? In this tutorial, we'll walk you through building a simple Snake game using HTML, CSS, and JavaScript. By the end of this tutorial, you'll have a fully functional game that you can enhance and share with friends.
Setting Up Your Project
First, let's set up our project structure. Create a new folder for your project and inside it, create three files: index.html, style.css, and script.js.
1. Creating index.html
The index.html file will hold the structure of our game.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Snake Game</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="game-container">
<canvas id="gameCanvas"></canvas>
</div>
<script src="script.js"></script>
</body>
</html>
2. Creating style.css
The style.css file will style our game. We'll make the canvas take up the full view and center it.
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.game-container {
position: relative;
}
canvas {
background-color: #000;
border: 1px solid #ddd;
}
3. Creating script.js
The script.js file will contain all the game logic.
Implementing the Game Logic
Setting Up the Canvas
First, let's set up the canvas where our game will be rendered.
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
const scale = 20;
const rows = canvas.height / scale;
const columns = canvas.width / scale;
canvas.width = 400;
canvas.height = 400;
Creating the Snake
Now, let's define the Snake class with properties for the snake's position and methods to draw and move the snake.
class Snake {
constructor() {
this.x = 0;
this.y = 0;
this.xSpeed = scale * 1;
this.ySpeed = 0;
this.total = 0;
this.tail = [];
}
draw() {
ctx.fillStyle = "#FFFFFF";
for (let i = 0; i < this.tail.length; i++) {
ctx.fillRect(this.tail[i].x, this.tail[i].y, scale, scale);
}
ctx.fillRect(this.x, this.y, scale, scale);
}
update() {
for (let i = 0; i < this.tail.length - 1; i++) {
this.tail[i] = this.tail[i + 1];
}
if (this.total >= 1) {
this.tail[this.total - 1] = { x: this.x, y: this.y };
}
this.x += this.xSpeed;
this.y += this.ySpeed;
if (this.x >= canvas.width) {
this.x = 0;
}
if (this.y >= canvas.height) {
this.y = 0;
}
if (this.x < 0) {
this.x = canvas.width - scale;
}
if (this.y < 0) {
this.y = canvas.height - scale;
}
}
changeDirection(direction) {
switch (direction) {
case 'Up':
if (this.ySpeed === 0) {
this.xSpeed = 0;
this.ySpeed = -scale * 1;
}
break;
case 'Down':
if (this.ySpeed === 0) {
this.xSpeed = 0;
this.ySpeed = scale * 1;
}
break;
case 'Left':
if (this.xSpeed === 0) {
this.xSpeed = -scale * 1;
this.ySpeed = 0;
}
break;
case 'Right':
if (this.xSpeed === 0) {
this.xSpeed = scale * 1;
this.ySpeed = 0;
}
break;
}
}
eat(fruit) {
if (this.x === fruit.x && this.y === fruit.y) {
this.total++;
return true;
}
return false;
}
}
let snake = new Snake();
Creating the Fruit
Next, we need a Fruit class to represent the food that the snake eats.
class Fruit {
constructor() {
this.x;
this.y;
}
pickLocation() {
this.x = Math.floor(Math.random() * rows) * scale;
this.y = Math.floor(Math.random() * columns) * scale;
}
draw() {
ctx.fillStyle = "#4cafab";
ctx.fillRect(this.x, this.y, scale, scale);
}
}
let fruit = new Fruit();
fruit.pickLocation();
Game Loop
Now, let's set up the game loop which will update and draw the snake and fruit.
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
snake.update();
snake.draw();
if (snake.eat(fruit)) {
fruit.pickLocation();
}
fruit.draw();
setTimeout(gameLoop, 250);
}
gameLoop();
Handling Keyboard Input
We need to handle keyboard input to change the snake's direction.
window.addEventListener('keydown', (e) => {
const direction = e.key.replace('Arrow', '');
snake.changeDirection(direction);
});
Putting It All Together
Here is the complete script.js with all the parts combined:
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
const scale = 20;
const rows = canvas.height / scale;
const columns = canvas.width / scale;
canvas.width = 400;
canvas.height = 400;
class Snake {
constructor() {
this.x = 0;
this.y = 0;
this.xSpeed = scale * 1;
this.ySpeed = 0;
this.total = 0;
this.tail = [];
}
draw() {
ctx.fillStyle = "#FFFFFF";
for (let i = 0; i < this.tail.length; i++) {
ctx.fillRect(this.tail[i].x, this.tail[i].y, scale, scale);
}
ctx.fillRect(this.x, this.y, scale, scale);
}
update() {
for (let i = 0; i < this.tail.length - 1; i++) {
this.tail[i] = this.tail[i + 1];
}
if (this.total >= 1) {
this.tail[this.total - 1] = { x: this.x, y: this.y };
}
this.x += this.xSpeed;
this.y += this.ySpeed;
if (this.x >= canvas.width) {
this.x = 0;
}
if (this.y >= canvas.height) {
this.y = 0;
}
if (this.x < 0) {
this.x = canvas.width - scale;
}
if (this.y < 0) {
this.y = canvas.height - scale;
}
}
changeDirection(direction) {
switch (direction) {
case 'Up':
if (this.ySpeed === 0) {
this.xSpeed = 0;
this.ySpeed = -scale * 1;
}
break;
case 'Down':
if (this.ySpeed === 0) {
this.xSpeed = 0;
this.ySpeed = scale * 1;
}
break;
case 'Left':
if (this.xSpeed === 0) {
this.xSpeed = -scale * 1;
this.ySpeed = 0;
}
break;
case 'Right':
if (this.xSpeed === 0) {
this.xSpeed = scale * 1;
this.ySpeed = 0;
}
break;
}
}
eat(fruit) {
if (this.x === fruit.x && this.y === fruit.y) {
this.total++;
return true;
}
return false;
}
}
class Fruit {
constructor() {
this.x;
this.y;
}
pickLocation() {
this.x = Math.floor(Math.random() * rows) * scale;
this.y = Math.floor(Math.random() * columns) * scale;
}
draw() {
ctx.fillStyle = "#4cafab";
ctx.fillRect(this.x, this.y, scale, scale);
}
}
let snake = new Snake();
let fruit = new Fruit();
fruit.pickLocation();
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
snake.update();
snake.draw();
if (snake.eat(fruit)) {
fruit.pickLocation();
}
fruit.draw();
setTimeout(gameLoop, 250);
}
gameLoop();
window.addEventListener('keydown', (e) => {
const direction = e.key.replace('Arrow', '');
snake.changeDirection(direction);
});
Conclusion
In this tutorial, we've walked through the process of creating a simple Snake game using HTML, CSS, and JavaScript. This game serves as a great starting point for understanding the basics of game development on the web. You can enhance this game by adding more features like levels, score tracking, and even sounds. Happy coding!
I am attaching a working live url of this project. Please go here and see how it would work after you have built it for yourself. Snake Game on Codeground