make a snake game and turn it into a webpage
I have built a complete, retro-styled Snake game and published it as an interactive webpage. You can play it directly here: Play Classic Snake Game.
Here is the complete source code containing HTML, CSS, and JavaScript:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Classic Snake Game</title>
<style>
body {
background-color: #1a1a1a;
color: #ffffff;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
overflow: hidden;
}
h1 {
margin-bottom: 5px;
font-size: 2rem;
letter-spacing: 2px;
color: #4CAF50;
text-shadow: 0 0 10px rgba(76, 175, 80, 0.4);
}
.scoreboard {
font-size: 1.2rem;
margin-bottom: 15px;
background: #2a2a2a;
padding: 8px 20px;
border-radius: 20px;
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
}
canvas {
border: 4px solid #333;
background-color: #111;
box-shadow: 0 10px 30px rgba(0,0,0,0.6);
border-radius: 8px;
}
.instructions {
margin-top: 15px;
color: #888;
font-size: 0.9rem;
text-align: center;
}
</style>
</head>
<body>
<h1>SNAKE</h1>
<div class="scoreboard">
Score: <span id="score">0</span> | High Score: <span id="highScore">0</span>
</div>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div class="instructions">
Use <strong>Arrow Keys</strong> or <strong>W, A, S, D</strong> to move. <br>
Press <strong>Spacebar</strong> to restart when game over.
</div>
<script>
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
const gridSize = 20;
const tileCount = canvas.width / gridSize;
let snake = [
{ x: 10, y: 10 },
{ x: 9, y: 10 },
{ x: 8, y: 10 }
];
let food = { x: 5, y: 5 };
let dx = 1;
let dy = 0;
let score = 0;
let highScore = localStorage.getItem('snakeHighScore') || 0;
document.getElementById('highScore').innerText = highScore;
let changingDirection = false;
let gameInterval;
let isGameOver = false;
document.addEventListener("keydown", changeDirection);
main();
createFood();
function main() {
if (hasGameEnded()) {
isGameOver = true;
clearInterval(gameInterval);
drawGameOver();
return;
}
changingDirection = false;
clearCanvas();
drawFood();
moveSnake();
drawSnake();
}
gameInterval = setInterval(main, 100);
function clearCanvas() {
ctx.fillStyle = "#111";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
function drawSnake() {
snake.forEach((part, index) => {
ctx.fillStyle = index === 0 ? "#4CAF50" : "#81C784";
ctx.strokeStyle = "#111";
ctx.fillRect(part.x * gridSize, part.y * gridSize, gridSize, gridSize);
ctx.strokeRect(part.x * gridSize, part.y * gridSize, gridSize, gridSize);
});
}
function moveSnake() {
const head = { x: snake[0].x + dx, y: snake[0].y + dy };
snake.unshift(head);
const hasEatenFood = snake[0].x === food.x && snake[0].y === food.y;
if (hasEatenFood) {
score += 10;
document.getElementById('score').innerText = score;
if (score > highScore) {
highScore = score;
localStorage.setItem('snakeHighScore', highScore);
document.getElementById('highScore').innerText = highScore;
}
createFood();
} else {
snake.pop();
}
}
function randomFood(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
function createFood() {
food.x = randomFood(0, tileCount);
food.y = randomFood(0, tileCount);
snake.forEach(part => {
const hasEaten = part.x === food.x && part.y === food.y;
if (hasEaten) createFood();
});
}
function drawFood() {
ctx.fillStyle = "#FF5252";
ctx.shadowBlur = 10;
ctx.shadowColor = "#FF5252";
ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);
ctx.shadowBlur = 0;
}
function hasGameEnded() {
for (let i = 4; i < snake.length; i++) {
if (snake[i].x === snake[0].x && snake[i].y === snake[0].y) return true;
}
const hitLeftWall = snake[0].x < 0;
const hitRightWall = snake[0].x >= tileCount;
const hitToptWall = snake[0].y < 0;
const hitBottomWall = snake[0].y >= tileCount;
return hitLeftWall || hitRightWall || hitToptWall || hitBottomWall;
}
function changeDirection(event) {
const keyPressed = event.keyCode;
const LEFT_KEY = 37;
const UP_KEY = 38;
const RIGHT_KEY = 39;
const DOWN_KEY = 40;
const W_KEY = 87;
const A_KEY = 65;
const S_KEY = 83;
const D_KEY = 68;
const SPACE_KEY = 32;
if (isGameOver && keyPressed === SPACE_KEY) {
resetGame();
return;
}
if (changingDirection) return;
const goingUp = dy === -1;
const goingDown = dy === 1;
const goingRight = dx === 1;
const goingLeft = dx === -1;
if ((keyPressed === LEFT_KEY || keyPressed === A_KEY) && !goingRight) {
dx = -1;
dy = 0;
changingDirection = true;
}
if ((keyPressed === UP_KEY || keyPressed === W_KEY) && !goingDown) {
dx = 0;
dy = -1;
changingDirection = true;
}
if ((keyPressed === RIGHT_KEY || keyPressed === D_KEY) && !goingLeft) {
dx = 1;
dy = 0;
changingDirection = true;
}
if ((keyPressed === DOWN_KEY || keyPressed === S_KEY) && !goingUp) {
dx = 0;
dy = 1;
changingDirection = true;
}
}
function drawGameOver() {
ctx.fillStyle = "rgba(0, 0, 0, 0.75)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "white";
ctx.font = "bold 28px Segoe UI";
ctx.textAlign = "center";
ctx.fillText("GAME OVER", canvas.width / 2, canvas.height / 2 - 15);
ctx.fillStyle = "#888";
ctx.font = "14px Segoe UI";
ctx.fillText("Press Spacebar to Restart", canvas.width / 2, canvas.height / 2 + 20);
}
function resetGame() {
snake = [
{ x: 10, y: 10 },
{ x: 9, y: 10 },
{ x: 8, y: 10 }
];
score = 0;
document.getElementById('score').innerText = score;
dx = 1;
dy = 0;
isGameOver = false;
createFood();
clearInterval(gameInterval);
gameInterval = setInterval(main, 100);
}
</script>
</body>
</html>