If you grew up in the late '90s or early 2000s, you probably remember the classic Snake game.
It was simple, addictive, and a PUBG of early mobile gaming. I recently decided to recreate it using just 100 lines of Javascript.
Here is the HTML:
<!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="styles.css">
</head>
<body>
<div class="container">
<h1>Snake Game</h1>
<div id="score">Score: 0</div>
<div id="game-board"></div>
<button id="start-restart">Start / Restart</button>
</div>
<script src="script.js"></script>
</body>
</html>
CSS:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f3f3f3;
}
.container {
text-align: center;
}
#game-board {
display: grid;
grid-template-columns: repeat(20, 20px);
grid-template-rows: repeat(20, 20px);
gap: 1px;
background-color: #e0e0e0;
margin: 20px auto;
width: 400px;
height: 400px;
position: relative;
}
.cell {
width: 20px;
height: 20px;
background-color: #f3f3f3;
}
.snake {
background-color: green;
}
.food {
background-color: red;
}
#score {
font-size: 20px;
margin: 10px 0;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
border: none;
background-color: #007BFF;
color: white;
border-radius: 5px;
}
button:hover {
background-color: #0056b3;
}
JS:
const board = document.getElementById('game-board');
const scoreDisplay = document.getElementById('score');
const startRestartButton = document.getElementById('start-restart');
const gridSize = 20;
const boardSize = gridSize * gridSize;
let snake = [42, 41, 40]; // Starting position
let direction = 1; // Moving right
let nextDirection = 1; // Buffer for next direction
let food = null;
let score = 0;
let intervalId = null;
const speed = 100;
function createBoard() {
board.innerHTML = '';
for (let i = 0; i < boardSize; i++) {
const cell = document.createElement('div');
cell.classList.add('cell');
board.appendChild(cell);
}
}
function updateBoard() {
const cells = document.querySelectorAll('.cell');
cells.forEach(cell => cell.classList.remove('snake', 'food'));
snake.forEach(index => cells[index].classList.add('snake'));
if (food !== null) cells[food].classList.add('food');
}
function spawnFood() {
let newFood;
do {
newFood = Math.floor(Math.random() * boardSize);
} while (snake.includes(newFood));
food = newFood;
}
function moveSnake() {
const head = snake[0];
const newHead = getNewHead(head);
// Check for collisions with itself
if (snake.includes(newHead)) {
clearInterval(intervalId);
alert(`Game Over! Your final score is ${score}.`);
return;
}
// Move snake
snake.unshift(newHead);
if (newHead === food) {
score++;
scoreDisplay.textContent = `Score: ${score}`;
spawnFood();
} else {
snake.pop();
}
direction = nextDirection;
updateBoard();
}
function getNewHead(head) {
let newHead = head + nextDirection;
if (nextDirection === 1 && head % gridSize === gridSize - 1) {
newHead = head - (gridSize - 1); // Wrap to the left
} else if (nextDirection === -1 && head % gridSize === 0) {
newHead = head + (gridSize - 1); // Wrap to the right
} else if (nextDirection === gridSize && head + gridSize >= boardSize) {
newHead = head % gridSize; // Wrap to the top
} else if (nextDirection === -gridSize && head - gridSize < 0) {
newHead = head + boardSize - gridSize; // Wrap to the bottom
}
return newHead;
}
function changeDirection(e) {
const key = e.key;
// Prevent reversing direction
if (key === 'ArrowUp' && direction !== gridSize) nextDirection = -gridSize;
if (key === 'ArrowDown' && direction !== -gridSize) nextDirection = gridSize;
if (key === 'ArrowLeft' && direction !== 1) nextDirection = -1;
if (key === 'ArrowRight' && direction !== -1) nextDirection = 1;
}
function startGame() {
snake = [42, 41, 40];
direction = 1;
nextDirection = 1;
score = 0;
scoreDisplay.textContent = `Score: ${score}`;
spawnFood();
updateBoard();
if (intervalId) clearInterval(intervalId);
intervalId = setInterval(moveSnake, speed);
}
createBoard();
startRestartButton.addEventListener('click', startGame);
document.addEventListener('keydown', changeDirection);
You can make changes to above code according to what more creativity you can add.
Try playing here: https://codepen.io/alexya99/pen/EaYbaxo
As a game developer I have worked on many gaming projects. You can review our one of gaming portfolio site such as geometry dash spam full of such web based games.
Top comments (1)
hahaha, geometrydash-meltdown you recommended is interesting. I like it!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.