This is a complete implementation of a Snake Game using HTML, CSS, and JavaScript. Below is a step-by-step breakdown of the code to help you understand how it works:
HTML Code for Snake 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 - Classic Retro Gaming</title>
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
<style>
/* Reset and base styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Press Start 2P', cursive;
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: #ffffff;
}
/* Header styles */
.site-header {
background-color: #4CAF50;
padding: 20px 0;
text-align: center;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.site-header h1 {
color: white;
font-size: 2em;
letter-spacing: 2px;
text-shadow: 2px 2px 0px rgba(0,0,0,0.2);
}
.site-nav {
background-color: #45a049;
padding: 10px 0;
}
.nav-list {
list-style: none;
display: flex;
justify-content: center;
gap: 20px;
}
.nav-list a {
color: white;
text-decoration: none;
font-size: 0.8em;
transition: opacity 0.3s;
}
.nav-list a:hover {
opacity: 0.8;
}
/* Main content styles */
.main-content {
flex: 1;
padding: 20px;
max-width: 1200px;
margin: 0 auto;
width: 100%;
}
.game-section {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.score-container {
display: flex;
justify-content: center;
gap: 40px;
font-size: 0.8em;
}
.game-board-container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
#gameBoard {
border: 2px solid #4CAF50;
}
.controls-container {
display: flex;
gap: 10px;
flex-wrap: wrap;
justify-content: center;
}
.control-button {
font-family: 'Press Start 2P', cursive;
padding: 10px 20px;
font-size: 0.8em;
border: none;
border-radius: 4px;
cursor: pointer;
transition: opacity 0.3s;
}
.control-button.primary {
background-color: #4CAF50;
color: white;
}
.control-button.secondary {
background-color: #cccccc;
color: #333;
}
.control-button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
/* Footer styles */
.site-footer {
background-color: #4CAF50;
color: white;
padding: 20px 0;
margin-top: auto;
}
.footer-content {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
}
.footer-links {
display: flex;
gap: 20px;
}
.footer-links a {
color: white;
text-decoration: none;
font-size: 0.7em;
}
.copyright {
font-size: 0.7em;
}
/* Game over modal */
.game-over {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
display: none;
align-items: center;
justify-content: center;
}
.game-over-content {
background-color: white;
padding: 30px;
border-radius: 8px;
text-align: center;
}
.game-over-content h2 {
color: #4CAF50;
margin-bottom: 20px;
}
/* Responsive design */
@media (max-width: 768px) {
.site-header h1 {
font-size: 1.5em;
}
.nav-list {
flex-direction: column;
align-items: center;
gap: 10px;
}
.score-container {
flex-direction: column;
align-items: center;
gap: 10px;
}
.game-board-container {
padding: 10px;
}
#gameBoard {
width: 300px;
height: 300px;
}
.controls-container {
flex-direction: column;
align-items: center;
}
.control-button {
width: 200px;
}
.footer-content {
flex-direction: column;
gap: 20px;
text-align: center;
}
.footer-links {
flex-direction: column;
gap: 10px;
}
}
</style>
</head>
<body>
<!-- Header Section -->
<header class="site-header">
<h1>Snake Game</h1>
</header>
<nav class="site-nav">
<ul class="nav-list">
<li><a href="#game">Play Game</a></li>
<li><a href="#instructions">Instructions</a></li>
<li><a href="#highscores">High Scores</a></li>
</ul>
</nav>
<!-- Main Content Section -->
<main class="main-content">
<section id="game" class="game-section">
<div class="score-container">
<span id="score">Score: 0</span>
<span id="high-score">High Score: 0</span>
</div>
<div class="game-board-container">
<canvas id="gameBoard" width="400" height="400"></canvas>
</div>
<div class="controls-container">
<button id="startButton" class="control-button primary">Start Game</button>
<button id="pauseButton" class="control-button secondary" disabled>Pause</button>
<button id="endButton" class="control-button secondary" disabled>End Game</button>
</div>
</section>
<div id="gameOver" class="game-over">
<div class="game-over-content">
<h2>Game Over</h2>
<p id="finalScore">Your score: 0</p>
<button id="restartButton" class="control-button primary">Play Again</button>
</div>
</div>
</main>
<!-- Footer Section -->
<footer class="site-footer">
<div class="footer-content">
<div class="footer-links">
<a href="#about">About</a>
<a href="#privacy">Privacy Policy</a>
<a href="#contact">Contact</a>
</div>
<div class="copyright">
© 2025 Snake Game. All rights reserved.
</div>
</div>
</footer>
<script>
// Game constants
const BOARD_SIZE = 20;
const CELL_SIZE = 20;
const SNAKE_START = [{ x: 10, y: 10 }, { x: 10, y: 11 }];
const APPLE_START = { x: 5, y: 5 };
const SPEED = 100;
const DIRECTIONS = {
38: { x: 0, y: -1 }, // up
40: { x: 0, y: 1 }, // down
37: { x: -1, y: 0 }, // left
39: { x: 1, y: 0 } // right
};
// Game variables
let snake = [...SNAKE_START];
let apple = { ...APPLE_START };
let direction = DIRECTIONS[39];
let gameInterval;
let score = 0;
let highScore = 0;
let isPaused = false;
// DOM Elements
const gameBoard = document.getElementById('gameBoard');
const ctx = gameBoard.getContext('2d');
const startButton = document.getElementById('startButton');
const pauseButton = document.getElementById('pauseButton');
const endButton = document.getElementById('endButton');
const gameOverDiv = document.getElementById('gameOver');
const finalScoreSpan = document.getElementById('finalScore');
const restartButton = document.getElementById('restartButton');
const scoreSpan = document.getElementById('score');
const highScoreSpan = document.getElementById('high-score');
// Game functions
function drawGame() {
ctx.clearRect(0, 0, gameBoard.width, gameBoard.height);
drawSnake();
drawApple();
if (isPaused) {
drawPauseScreen();
}
}
function drawSnake() {
snake.forEach((segment, index) => {
ctx.fillStyle = '#4CAF50';
ctx.fillRect(segment.x * CELL_SIZE, segment.y * CELL_SIZE, CELL_SIZE - 1, CELL_SIZE - 1);
});
}
function drawApple() {
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc((apple.x * CELL_SIZE) + CELL_SIZE / 2, (apple.y * CELL_SIZE) + CELL_SIZE / 2, CELL_SIZE / 2, 0, 2 * Math.PI);
ctx.fill();
}
function drawPauseScreen() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
ctx.fillRect(0, 0, gameBoard.width, gameBoard.height);
ctx.fillStyle = 'white';
ctx.font = '20px "Press Start 2P"';
ctx.textAlign = 'center';
ctx.fillText('PAUSED', gameBoard.width / 2, gameBoard.height / 2);
}
function moveSnake() {
if (isPaused) return;
const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y };
snake.unshift(head);
if (head.x === apple.x && head.y === apple.y) {
score++;
updateScore();
generateApple();
} else {
snake.pop();
}
if (checkCollision()) {
gameOver();
}
}
function checkCollision() {
const head = snake[0];
return (
head.x < 0 || head.x >= BOARD_SIZE ||
head.y < 0 || head.y >= BOARD_SIZE ||
snake.slice(1).some(segment => segment.x === head.x && segment.y === head.y)
);
}
function generateApple() {
do {
apple = {
x: Math.floor(Math.random() * BOARD_SIZE),
y: Math.floor(Math.random() * BOARD_SIZE)
};
} while (snake.some(segment => segment.x === apple.x && segment.y === apple.y));
}
function updateScore() {
scoreSpan.textContent = `Score: ${score}`;
if (score > highScore) {
highScore = score;
highScoreSpan.textContent = `High Score: ${highScore}`;
}
}
function gameOver() {
clearInterval(gameInterval);
finalScoreSpan.textContent = `Your score: ${score}`;
gameOverDiv.style.display = 'flex';
pauseButton.disabled = true;
endButton.disabled = true;
startButton.disabled = false;
}
function startGame() {
snake = [...SNAKE_START];
apple = { ...APPLE_START };
direction = DIRECTIONS[39];
score = 0;
isPaused = false;
updateScore();
gameOverDiv.style.display = 'none';
clearInterval(gameInterval);
gameInterval = setInterval(() => {
moveSnake();
drawGame();
}, SPEED);
pauseButton.disabled = false;
endButton.disabled = false;
startButton.disabled = true;
pauseButton.textContent = 'Pause';
}
function pauseGame() {
isPaused = !isPaused;
pauseButton.textContent = isPaused ? 'Resume' : 'Pause';
drawGame();
}
function endGame() {
clearInterval(gameInterval);
gameOver();
}
// Event Listeners
document.addEventListener('keydown', (e) => {
if (e.keyCode === 32) { // Spacebar
e.preventDefault();
if (gameInterval) {
pauseGame();
}
} else {
const key = e.keyCode;
if (key >= 37 && key <= 40) {
const newDirection = DIRECTIONS[key];
if (direction.x + newDirection.x !== 0 || direction.y + newDirection.y !== 0) {
direction = newDirection;
}
}
}
});
startButton.addEventListener('click', startGame);
pauseButton.addEventListener('click', pauseGame);
endButton.addEventListener('click', endGame);
restartButton.addEventListener('click', startGame);
// Initial game draw
drawGame();
</script>
</body>
</html>
Step 1: HTML Structure
The HTML defines the structure of the game, including the header, game board, controls, and footer.
Key Components:
- Header (
<header>):- Displays the title of the game: “Snake Game.”
- Uses a retro-style font (
Press Start 2P) for a classic gaming feel.
- Navigation (
<nav>):- Contains links to different sections of the page (e.g., Play Game, Instructions, High Scores).
- Main Content (
<main>):- Contains the game board (
<canvas>), score display, and control buttons (Start, Pause, End). - Includes a modal for the “Game Over” screen.
- Contains the game board (
- Footer (
<footer>):- Displays links (About, Privacy Policy, Contact) and a copyright notice.
Step 2: CSS Styling
The CSS styles the game to give it a retro look and ensures responsiveness.
Key Styles:
- Retro Font:
- TheÂ
Press Start 2PÂ font is used throughout the game for a pixelated, old-school feel.
- TheÂ
- Game Board:
- The
<canvas>element is styled with a green border and a white background.
- The
- Buttons:
- Buttons are styled with two variants:
primary(green) andsecondary(gray). - Hover effects and disabled states are added for better user interaction.
- Buttons are styled with two variants:
- Responsive Design:
- Media queries adjust the layout for smaller screens (e.g., stacking buttons and reducing font sizes).
- Game Over Modal:
- A centered modal appears when the game ends, displaying the final score and a “Play Again” button.
Step 3: JavaScript Logic
The JavaScript handles the game logic, including snake movement, collision detection, and score tracking.
Key Functions:
- Game Initialization:
- Constants like
BOARD_SIZE,CELL_SIZE, andSPEEDdefine the game’s dimensions and speed. - Variables like
snake,apple, anddirectionstore the game state.
- Constants like
- Drawing Functions:
drawGame(): Clears the canvas and redraws the snake and apple.drawSnake(): Draws the snake as a series of green rectangles.drawApple(): Draws the apple as a red circle.drawPauseScreen(): Displays a “PAUSED” overlay when the game is paused.
- Game Logic:
moveSnake(): Moves the snake in the current direction and checks for collisions or apple consumption.checkCollision(): Determines if the snake has collided with the wall or itself.generateApple(): Randomly places the apple on the board, ensuring it doesn’t overlap with the snake.
- Score Management:
updateScore(): Updates the score display and tracks the high score.
- Game State Management:
startGame(): Resets the game state and starts the game loop.pauseGame(): Toggles the game’s paused state.endGame(): Stops the game and displays the “Game Over” modal.
- Event Listeners:
- Keyboard input (arrow keys) controls the snake’s direction.
- Buttons (Start, Pause, End, Restart) trigger corresponding game functions.
Step 4: How It Works
- Starting the Game:
- Click the “Start Game” button to initialize the game.
- The snake starts moving in the default direction (right).
- Playing the Game:
- Use the arrow keys to change the snake’s direction.
- Eat the apple to grow the snake and increase the score.
- Pausing the Game:
- Press the spacebar or click the “Pause” button to pause/resume the game.
- Ending the Game:
- The game ends if the snake collides with the wall or itself.
- The “Game Over” modal displays the final score and allows the player to restart.
- Restarting the Game:
- Click the “Play Again” button in the “Game Over” modal to reset the game.
Step 5: Customization
You can customize the game by:
- Changing the
BOARD_SIZEorCELL_SIZEto adjust the grid dimensions. - Modifying the
SPEEDconstant to make the game faster or slower. - Updating the colors or fonts in the CSS for a different visual style.
- Adding new features, such as obstacles or power-ups.
Step 6: Running the Code
To run the game:
- Copy the code into an
index.htmlfile. - Open the file in a web browser.
- Play the game using the arrow keys and buttons.
This step-by-step breakdown should help you understand how the Snake Game works and how you can modify or extend it. Thank you


