Description
A developer's journey through code. I build, I break, and I write about it. Explore articles on modern software development, programming tips, and more.
Hello, fellow developers! I am Jonathan Izuchukwu, popularly known to many as SunshineIHCTS, and today I am excited to share with you a simple yet entertaining project I just worked on (a classic snake game implemented in JavaScript). Back in 2007 when I was a child I enjoyed playing this game on my mum's Nokia phone and am glad I have been able to recreate such awesome childhood experience, I will teach you step by step processes involved in creating a snake game in JavaScript and I will include the source code in this article which you are free to download and use in your project if you want.
To begin, let us take a look at the structure of the game. The HTML file (index.html) sets up the basic layout, including a game container, a snake element, a food element, and a score display. The styling is handled in the style.css file, creating an attractive game interface on a background featuring a captivating snake image.
HTML:
<!-- Developed by SunshineIHCTS | Visit sunshineihcts.com for more -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Snake Game</title>
</head>
<body>
<div class="game-container">
<div id="score" class="score"></div>
<div id="snake" class="snake"></div>
<div id="food" class="food"></div>
</div>
<script src="script.js"></script>
</body>
</html>
CSS:
/* Developed by SunshineIHCTS | Visit sunshineihcts.com for more */
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background-image: url("snakes.jpg");
}
.game-container {
position: relative;
width: 400px;
height: 400px;
border: 2px solid green;
}
.food {
position: absolute;
width: 15px;
height: 15px;
background-color: red;
border-radius: 50%;
}
.snake {
position: absolute;
width: 20px;
height: 20px;
background-color: green;
border-radius: 30%;
}
.score {
position: absolute;
background-color: green;
color: white;
width: 150px;
height: 20px;
}
JavaScript:
Finally, let us dive into the actual stuff which is the JavaScript code (script.js). The game logic is implemented using event listeners, functions, and a game loop. The snake moves in response to arrow key presses, and the goal is to eat the randomly generated food, growing longer with each successful consumption. The game keeps track of your score, and if you collide with the boundaries or yourself, it is game over which will alert "game over!". I am sure some of my audience will remember their childhood experince with this game on their Nokia button phone (fun to remember right?).
// Developed by SunshineIHCTS | Visit sunshineihcts.com for more
document.addEventListener('DOMContentLoaded', () => {
const gameContainer = document.querySelector('.game-container');
const snakeElement = document.getElementById('snake');
const foodElement = document.getElementById('food');
const scoreElement = document.getElementById('score');
let snake = [{ x: 10, y: 10 }];
let food = { x: 0, y: 0 };
let direction = 'right';
let eatenFood = 0;
let speed = 1; // Adjust this value to control the speed
function updateGame() {
const head = { ...snake[0] };
switch (direction) {
case 'up':
head.y -= 1;
break;
case 'down':
head.y += 1;
break;
case 'left':
head.x -= 1;
break;
case 'right':
head.x += 1;
break;
}
// Check if the head is outside the game container
if (
head.x < 0 ||
head.x >= 20 ||
head.y < 0 ||
head.y >= 20 ||
checkCollision()
) {
alert('Game Over!');
resetGame();
return;
}
snake.unshift(head);
// Check for collisions
if (head.x === food.x && head.y === food.y) {
generateFood();
eatenFood++;
updateScore();
} else {
snake.pop();
}
updateSnake();
}
function updateSnake() {
// Clear previous snake elements
while (snakeElement.firstChild) {
snakeElement.removeChild(snakeElement.firstChild);
}
// Display the snake
snake.forEach(segment => {
const segmentElement = document.createElement('div');
segmentElement.className = 'snake';
segmentElement.style.top = `${segment.y * 20}px`;
segmentElement.style.left = `${segment.x * 20}px`;
snakeElement.appendChild(segmentElement);
});
}
function generateFood() {
food = {
x: Math.floor(Math.random() * 15),
y: Math.floor(Math.random() * 15)
};
foodElement.style.top = `${food.y * 20}px`;
foodElement.style.left = `${food.x * 20}px`;
}
function checkCollision() {
return snake.slice(1).some(segment => segment.x === snake[0].x && segment.y === snake[0].y);
}
function updateScore() {
scoreElement.textContent = `_____SCORE: ${eatenFood}`;
}
function resetGame() {
snake = [{ x: 10, y: 10 }];
direction = 'right';
eatenFood = 0;
generateFood();
updateSnake();
updateScore();
}
document.addEventListener('keydown', event => {
switch (event.key) {
case 'ArrowUp':
if (direction !== 'down') {
direction = 'up';
}
break;
case 'ArrowDown':
if (direction !== 'up') {
direction = 'down';
}
break;
case 'ArrowLeft':
if (direction !== 'right') {
direction = 'left';
}
break;
case 'ArrowRight':
if (direction !== 'left') {
direction = 'right';
}
break;
}
});
// Initial setup
generateFood();
updateScore();
function gameLoop() {
updateGame();
setTimeout(gameLoop, 500 / speed);
}
// Start the game loop
gameLoop();
});
Let me further break down the JavaScript code for a better understanding:
1. Initialization:
- Select HTML elements representing the game area, snake, food, and score.
- Initialize variables for the snake, food, direction, score, and speed.
2. Update Game Function:
- Create a function to update the game state.
- Get the head of the snake based on the current direction.
- Check for collisions with the game boundaries or the snake itself.
- If a collision occurs, display a game over alert, reset the game, and return.
- Add the new head to the front of the snake.
- Check if the snake has eaten the food:
- If yes, generate a new food item, increment the score, and update the score display.
- If no, remove the last segment of the snake.
3. Update Snake Function:
- Clear the previous snake elements from the DOM.
- Display each segment of the snake using div elements.
4. Generate Food Function:
- Generate random coordinates for the food within the game area.
- Update the food element's position on the screen.
5. Check Collision Function:
- Check if the snake's head collides with any other segment of the snake.
6. Update Score Function:
- Update the score display with the current score.
7. Reset Game Function:
- Reset the snake, direction, and score.
- Generate a new food item, update the snake and score displays.
8. Event Listener for Keydown:
- Listen for arrow key presses to change the snake's direction.
9. Initial Setup:
- Generate initial food, update the score, and start the game loop.
10. Game Loop:
- Create a game loop function that repeatedly calls the update game function.
- Adjust the speed of the game by changing the timeout duration.
11. Start the Game Loop:
- Invoke the game loop function to start the game.
In this breakdown I have provided a clear understanding of the structure and flow of the snake game JavaScript code. You can download the source code below (it is in a zip file so unzip after downloading), watch me play the game in the video below. You can share your contribution to this project in the comments section below, do subscribe to my channel on YouTube (@sunshineihcts) for more interesting projects or keep coming back to my website for my daily articles.
Cookies improve user experience on SunshineIHCTS. By continuing to use this website, you consent to the use of cookies in accordance with the Privacy policy.
A developer's journey through code. I build, I break, and I write about it. Explore articles on modern software development, programming tips, and more.
Comments section
You need to be logged in to comment, Login or Register.Approved comments:
David Scott in 2023-12-03 08:18:28
This is good but you should show us how to add a feature that will enable a player pause the game at will.
Reply You need to be logged in to reply to this comment, Login or Register.
_SunshineIHCTS in 2023-12-03 08:26:15
_You can implement that feature using an "if statement" inside the "function updateGame()". If you're having issues adding the pause feature contact me through the contact page for personal assistance.
_David Scott in 2023-12-03 08:35:01
_Okay.
Heis Em in 2023-12-03 08:29:22
Wow😲 interesting.
Reply You need to be logged in to reply to this comment, Login or Register.
VincenZöArt in 2023-12-03 09:04:32
I want to implement this on my site to keep my users busy when their network connection is off, do you think it's a good idea?
Reply You need to be logged in to reply to this comment, Login or Register.
_SunshineIHCTS in 2023-12-03 09:17:12
_Yes it is, but do not use a background image because it has to be light.
_VincenZöArt in 2023-12-03 09:22:16
_Okay, thank you.