PHP Snake Game with Leaderboard
Build the classic Snake game with smooth animations, increasing difficulty, and a PHP-powered server-side leaderboard.
PHPJavaScriptCanvasGameAnimation
Overview
Build the classic Snake game with buttery smooth rendering on Canvas, progressive speed increases, and a PHP-powered high scores leaderboard.
Game UI (index.php)
php
<?php
$scores = [];
if (file_exists('scores.json')) {
$scores = json_decode(file_get_contents('scores.json'), true);
usort($scores, fn($a,$b) => $b['score'] - $a['score']);
$scores = array_slice($scores, 0, 10);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Snake Game</title>
<style>
body { margin: 0; background: #0a0a23; color: #fff; font-family: sans-serif; display: flex; justify-content: center; gap: 2rem; padding: 2rem; }
canvas { border: 2px solid #6c63ff; border-radius: 8px; }
.sidebar { width: 220px; }
.score-display { font-size: 2.5rem; font-weight: bold; color: #6c63ff; text-align: center; margin-bottom: 1rem; }
.leaderboard { background: #1a1a3e; border-radius: 12px; padding: 1rem; }
.leaderboard h3 { text-align: center; margin-bottom: 1rem; }
.game-over { position: fixed; inset: 0; background: rgba(0,0,0,0.8); display: none; justify-content: center; align-items: center; flex-direction: column; }
.game-over h2 { font-size: 3rem; animation: popIn 0.5s; }
@keyframes popIn { from { transform: scale(0); } to { transform: scale(1); } }
</style>
</head>
<body>
<div class="sidebar">
<div class="score-display" id="score">0</div>
<div class="leaderboard">
<h3>������ Top 10</h3>
<ol style="padding-left:1.2rem">
<?php foreach ($scores as $s): ?><li><?= htmlspecialchars($s['name']) ?> — <?= $s['score'] ?></li><?php endforeach; ?>
<?php if (empty($scores)): ?><li>No scores yet</li><?php endif; ?>
</ol>
</div>
</div>
<canvas id="game" width="400" height="400"></canvas>
<div class="game-over" id="gameover">
<h2>Game Over!</h2>
<p style="font-size:1.4rem;margin:1rem">Score: <span id="final"></span></p>
<input id="name" placeholder="Your name" style="padding:10px;border-radius:8px;border:none;font-size:1rem">
<button onclick="submitScore()" style="margin-top:1rem;padding:10px 30px;background:#6c63ff;color:#fff;border:none;border-radius:8px;cursor:pointer">Save Score</button>
</div>
<script>
const canvas = document.getElementById('game'), ctx = canvas.getContext('2d');
const grid = 20, cols = canvas.width/grid, rows = canvas.height/grid;
let snake = [{x:10,y:10}], dir = {x:1,y:0}, food, score = 0, speed = 100, gameLoop;
function spawn() { food = { x: Math.floor(Math.random()*cols), y: Math.floor(Math.random()*rows) }; }
spawn();
document.addEventListener('keydown', e => {
const map = { ArrowUp:{x:0,y:-1}, ArrowDown:{x:0,y:1}, ArrowLeft:{x:-1,y:0}, ArrowRight:{x:1,y:0} };
if (map[e.key] && (map[e.key].x + dir.x !== 0 || map[e.key].y + dir.y !== 0)) dir = map[e.key];
});
function update() {
const head = { x: snake[0].x + dir.x, y: snake[0].y + dir.y };
if (head.x < 0 || head.x >= cols || head.y < 0 || head.y >= rows || snake.some(s => s.x === head.x && s.y === head.y)) return gameOver();
snake.unshift(head);
if (head.x === food.x && head.y === food.y) { score += 10; document.getElementById('score').textContent = score; spawn(); clearInterval(gameLoop); speed = Math.max(50, speed - 2); gameLoop = setInterval(update, speed); }
else { snake.pop(); }
draw();
}
function draw() {
ctx.fillStyle = '#0a0a23'; ctx.fillRect(0, 0, 400, 400);
ctx.fillStyle = '#ff6b6b'; ctx.fillRect(food.x*grid+2, food.y*grid+2, grid-4, grid-4);
snake.forEach((s, i) => { ctx.fillStyle = i === 0 ? '#6c63ff' : '#48dbfb'; ctx.fillRect(s.x*grid+1, s.y*grid+1, grid-2, grid-2); });
}
function gameOver() { clearInterval(gameLoop); document.getElementById('final').textContent = score; document.getElementById('gameover').style.display = 'flex'; }
async function submitScore() {
const name = document.getElementById('name').value || 'Anonymous';
await fetch('save_score.php', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ name, score }) });
location.reload();
}
gameLoop = setInterval(update, speed); draw();
</script>
</body>
</html>Score Saver (save_score.php)
php
<?php
header('Content-Type: application/json');
$input = json_decode(file_get_contents('php://input'), true);
$scores = file_exists('scores.json') ? json_decode(file_get_contents('scores.json'), true) : [];
$scores[] = ['name' => htmlspecialchars(substr($input['name'] ?? 'Anon', 0, 20)), 'score' => (int)($input['score'] ?? 0), 'date' => date('Y-m-d H:i')];
file_put_contents('scores.json', json_encode($scores));
echo json_encode(['ok' => true]);
?>Technologies
- PHP — leaderboard, score persistence - HTML5 Canvas — game rendering - JavaScript — game loop, collision detection
Related Projects
PHPApr 27, 2026
Analog Clock with PHP & CSS
Build a beautiful real-time analog clock using PHP for time calculation and CSS for the rotating hands and dial.
PHPCSSAnimationClock
Read more → Source
PHPApr 27, 2026
Animated Loading Spinners Gallery in PHP
Create a gallery of 10+ beautiful CSS loading spinner animations served dynamically through PHP.
PHPCSSAnimationSpinners
Read more → Source
PHPApr 27, 2026
PHP Color Palette Generator
Generate beautiful random color palettes with hex codes, RGB values, and one-click copy — all powered by PHP.
PHPCSSColorsDesign Tool
Read more → Source
Comments (0)
No comments yet. Be the first to comment!