Ibikubiye k'urubuga
Snake Game
Snake Game
⭐ Exclusive Game Application

Snake Game

Snake Game

Software · · Feb 01, 2026
📁
Game Application
Category
📚
Software
Subject
🕒
Feb 2026
Updated

Source Code Examples

HTML
HTML Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Serpentine - Premium Snake Game</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
<div class="game-container">
<div class="header">
<h1 class="logo">SERPENTINE</h1>
<p class="tagline">Premium Snake Experience with Immersive UX</p>
</div>
<div class="main-content">
<div class="game-section">
<div class="game-wrapper">
<div class="game-board">
<canvas id="gameCanvas"></canvas>
<div id="gameOver" class="game-over">
<h2>GAME OVER</h2>
<p>Your score: <span id="finalScore">0</span></p>
<p>High score: <span id="highScoreDisplay">0</span></p>
<button id="restartBtn" class="control-btn pulse">
<i class="fas fa-redo"></i> PLAY AGAIN
</button>
</div>
</div>
<div class="controls-panel">
<button id="startBtn" class="control-btn">
<i class="fas fa-play"></i> START GAME
</button>
<button id="pauseBtn" class="control-btn secondary">
<i class="fas fa-pause"></i> PAUSE
</button>
<button id="resetBtn" class="control-btn secondary">
<i class="fas fa-undo"></i> RESET
</button>
</div>
<div class="mobile-controls">
<div class="mobile-btn up" data-direction="up"><i class="fas fa-arrow-up"></i></div>
<div class="mobile-btn left" data-direction="left"><i class="fas fa-arrow-left"></i></div>
<div class="mobile-btn right" data-direction="right"><i class="fas fa-arrow-right"></i></div>
<div class="mobile-btn down" data-direction="down"><i class="fas fa-arrow-down"></i></div>
</div>
</div>
</div>
<div class="sidebar">
<div class="stats-card">
<h3 class="card-title"><i class="fas fa-chart-line"></i> GAME STATS</h3>
<div class="stats-grid">
<div class="stat-item">
<div class="stat-value" id="currentScore">0</div>
<div class="stat-label">SCORE</div>
</div>
<div class="stat-item">
<div class="stat-value" id="highScore">0</div>
<div class="stat-label">HIGH SCORE</div>
</div>
<div class="stat-item">
<div class="stat-value" id="snakeLength">3</div>
<div class="stat-label">LENGTH</div>
</div>
<div class="stat-item">
<div class="stat-value" id="gameSpeed">5</div>
<div class="stat-label">SPEED</div>
</div>
</div>
</div>
<div class="settings-card">
<h3 class="card-title"><i class="fas fa-cog"></i> SETTINGS</h3>
<div class="settings-group">
<label class="setting-label">Game Speed</label>
<div class="slider-container">
<input type="range" min="1" max="20" value="5" class="slider" id="speedSlider">
<span class="slider-value" id="speedValue">5</span>
</div>
</div>
<div class="settings-group">
<label class="setting-label">Grid Size</label>
<div class="slider-container">
<input type="range" min="15" max="30" value="20" class="slider" id="gridSlider">
<span class="slider-value" id="gridValue">20</span>
</div>
</div>
<div class="settings-group">
<label class="setting-label" style="display: flex; justify-content: space-between;">
<span>Zen Mode</span>
<div class="toggle-switch">
<input type="checkbox" id="zenToggle">
<span class="toggle-slider"></span>
</div>
</label>
<p style="font-size: 0.85rem; color: #94a3b8; margin-top: 5px;">Calm colors, no time pressure</p>
</div>
</div>
<div class="themes-card">
<h3 class="card-title"><i class="fas fa-palette"></i> VISUAL THEMES</h3>
<div class="theme-grid">
<div class="theme-option theme-nebula active" data-theme="nebula">
<div class="theme-color"></div>
<div class="theme-name">Nebula</div>
</div>
<div class="theme-option theme-biolume" data-theme="biolume">
<div class="theme-color"></div>
<div class="theme-name">Biolume</div>
</div>
<div class="theme-option theme-neoclassic" data-theme="neoclassic">
<div class="theme-color"></div>
<div class="theme-name">Neo-Classic</div>
</div>
<div class="theme-option theme-sunset" data-theme="sunset">
<div class="theme-color"></div>
<div class="theme-name">Sunset</div>
</div>
<div class="theme-option theme-ocean" data-theme="ocean">
<div class="theme-color"></div>
<div class="theme-name">Ocean</div>
</div>
<div class="theme-option theme-matrix" data-theme="matrix">
<div class="theme-color"></div>
<div class="theme-name">Matrix</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="game.js"></script>
</body>
</html>
CSS
CSS Styles
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    user-select: none;
}
body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
    background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
    color: #f8fafc;
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
    overflow-x: hidden;
}
.game-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 25px;
    max-width: 1200px;
    width: 100%;
}
.header {
    text-align: center;
    padding: 20px;
    width: 100%;
}
.logo {
    font-size: 3.5rem;
    font-weight: 800;
    background: linear-gradient(45deg, #6366f1, #8b5cf6);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    margin-bottom: 10px;
    letter-spacing: -1px;
}
.tagline {
    color: #94a3b8;
    font-size: 1.1rem;
    font-weight: 300;
}
.main-content {
    display: flex;
    flex-wrap: wrap;
    gap: 30px;
    justify-content: center;
    width: 100%;
}
.game-section {
    flex: 1;
    min-width: 320px;
    max-width: 600px;
}
.game-wrapper {
    background: rgba(30, 41, 59, 0.7);
    backdrop-filter: blur(10px);
    border-radius: 24px;
    padding: 20px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(255, 255, 255, 0.1);
    position: relative;
    overflow: hidden;
}
.game-board {
    width: 100%;
    aspect-ratio: 1;
    background: rgba(15, 23, 42, 0.6);
    border-radius: 16px;
    position: relative;
    overflow: hidden;
}
#gameCanvas {
    width: 100%;
    height: 100%;
    display: block;
}
.controls-panel {
    display: flex;
    flex-wrap: wrap;
    gap: 15px;
    margin-top: 20px;
    justify-content: center;
}
.control-btn {
    padding: 14px 28px;
    border: none;
    border-radius: 50px;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    display: flex;
    align-items: center;
    gap: 8px;
    background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
    color: white;
    box-shadow: 0 4px 20px rgba(59, 130, 246, 0.3);
}
.control-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 30px rgba(59, 130, 246, 0.4);
}
.control-btn:active {
    transform: translateY(0);
}
.control-btn.secondary {
    background: linear-gradient(135deg, #475569 0%, #334155 100%);
    box-shadow: 0 4px 20px rgba(71, 85, 105, 0.3);
}
.control-btn.secondary:hover {
    box-shadow: 0 8px 30px rgba(71, 85, 105, 0.4);
}
.sidebar {
    flex: 1;
    min-width: 300px;
    max-width: 400px;
    display: flex;
    flex-direction: column;
    gap: 25px;
}
.stats-card, .settings-card, .themes-card {
    background: rgba(30, 41, 59, 0.7);
    backdrop-filter: blur(10px);
    border-radius: 20px;
    padding: 25px;
    box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.1);
}
.card-title {
    font-size: 1.3rem;
    font-weight: 700;
    margin-bottom: 20px;
    color: #e2e8f0;
    display: flex;
    align-items: center;
    gap: 10px;
}
.card-title i {
    color: #6366f1;
}
.stats-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
}
.stat-item {
    text-align: center;
    padding: 15px;
    background: rgba(15, 23, 42, 0.5);
    border-radius: 12px;
    transition: transform 0.2s;
}
.stat-item:hover {
    transform: translateY(-2px);
}
.stat-value {
    font-size: 2.2rem;
    font-weight: 800;
    color: #60a5fa;
    line-height: 1;
}
.stat-label {
    font-size: 0.9rem;
    color: #94a3b8;
    margin-top: 5px;
    text-transform: uppercase;
    letter-spacing: 1px;
}
.settings-group {
    margin-bottom: 20px;
}
.setting-label {
    display: block;
    margin-bottom: 8px;
    color: #cbd5e1;
    font-weight: 500;
}
.slider-container {
    display: flex;
    align-items: center;
    gap: 15px;
}
.slider {
    flex: 1;
    -webkit-appearance: none;
    height: 6px;
    background: linear-gradient(to right, #6366f1, #8b5cf6);
    border-radius: 3px;
    outline: none;
}
.slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 22px;
    height: 22px;
    background: white;
    border-radius: 50%;
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}
.slider-value {
    min-width: 30px;
    text-align: center;
    font-weight: 600;
    color: #60a5fa;
}
.toggle-switch {
    position: relative;
    display: inline-block;
    width: 60px;
    height: 30px;
}
.toggle-switch input {
    opacity: 0;
    width: 0;
    height: 0;
}
.toggle-slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #475569;
    transition: .4s;
    border-radius: 34px;
}
.toggle-slider:before {
    position: absolute;
    content: "";
    height: 22px;
    width: 22px;
    left: 4px;
    bottom: 4px;
    background-color: white;
    transition: .4s;
    border-radius: 50%;
}
input:checked + .toggle-slider {
    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
}
input:checked + .toggle-slider:before {
    transform: translateX(30px);
}
.theme-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 15px;
}
.theme-option {
    aspect-ratio: 1;
    border-radius: 12px;
    cursor: pointer;
    transition: all 0.3s;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 8px;
    padding: 10px;
    border: 2px solid transparent;
}
.theme-option:hover {
    transform: scale(1.05);
}
.theme-option.active {
    border-color: #60a5fa;
    box-shadow: 0 0 0 3px rgba(96, 165, 250, 0.2);
}
.theme-color {
    width: 100%;
    height: 70%;
    border-radius: 8px;
}
.theme-name {
    font-size: 0.8rem;
    color: #94a3b8;
    text-align: center;
}
/* Themes */
.theme-nebula .theme-color { background: linear-gradient(135deg, #0f172a, #1e1b4b); }
.theme-biolume .theme-color { background: linear-gradient(135deg, #064e3b, #0d9488); }
.theme-neoclassic .theme-color { background: linear-gradient(135deg, #1c1917, #44403c); }
.theme-sunset .theme-color { background: linear-gradient(135deg, #7c2d12, #c2410c); }
.theme-ocean .theme-color { background: linear-gradient(135deg, #1e3a8a, #0ea5e9); }
.theme-matrix .theme-color { background: linear-gradient(135deg, #14532d, #22c55e); }
/* Game states */
.game-over {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: rgba(15, 23, 42, 0.95);
    padding: 40px;
    border-radius: 20px;
    text-align: center;
    z-index: 10;
    display: none;
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5);
    min-width: 300px;
}
.game-over h2 {
    font-size: 2.5rem;
    color: #f87171;
    margin-bottom: 15px;
}
.game-over p {
    font-size: 1.2rem;
    margin-bottom: 25px;
    color: #cbd5e1;
}
.pulse {
    animation: pulse 2s infinite;
}
@keyframes pulse {
    0% { transform: scale(1); }
    50% { transform: scale(1.05); }
    100% { transform: scale(1); }
}
.snake-segment {
    position: absolute;
    border-radius: 4px;
    transition: all 0.1s ease-out;
}
.food {
    position: absolute;
    border-radius: 50%;
    animation: float 3s ease-in-out infinite;
}
@keyframes float {
    0%, 100% { transform: translateY(0px); }
    50% { transform: translateY(-5px); }
}
/* Mobile controls */
.mobile-controls {
    display: none;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    gap: 10px;
    margin-top: 20px;
    max-width: 300px;
    aspect-ratio: 1;
}
.mobile-btn {
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 12px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 1.5rem;
    color: white;
    cursor: pointer;
    transition: all 0.2s;
}
.mobile-btn:active {
    background: rgba(255, 255, 255, 0.2);
    transform: scale(0.95);
}
.mobile-btn.up { grid-column: 2; grid-row: 1; }
.mobile-btn.left { grid-column: 1; grid-row: 2; }
.mobile-btn.right { grid-column: 3; grid-row: 2; }
.mobile-btn.down { grid-column: 2; grid-row: 3; }
/* Responsive */
@media (max-width: 768px) {
    .main-content {
        flex-direction: column;
    }
    .mobile-controls {
        display: grid;
    }
    .game-wrapper {
        padding: 15px;
    }
    .logo {
        font-size: 2.5rem;
    }
}
/* Particle effects */
.particle {
    position: absolute;
    pointer-events: none;
    border-radius: 50%;
    opacity: 0;
}
/* Score animation */
@keyframes scorePop {
    0% { transform: scale(0); opacity: 0; }
    50% { transform: scale(1.2); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
}
.score-pop {
    animation: scorePop 0.5s ease-out;
}
JavaScript
JavaScript Code
// Game Configuration
const config = {
    gridSize: 20,
    initialSpeed: 5,
    themes: {
        nebula: { snake: '#6366f1', food: '#f59e0b', bg: '#0f172a', grid: '#1e293b' },
        biolume: { snake: '#10b981', food: '#8b5cf6', bg: '#064e3b', grid: '#0d9488' },
        neoclassic: { snake: '#fbbf24', food: '#ef4444', bg: '#1c1917', grid: '#44403c' },
        sunset: { snake: '#f97316', food: '#eab308', bg: '#7c2d12', grid: '#c2410c' },
        ocean: { snake: '#0ea5e9', food: '#f0abfc', bg: '#1e3a8a', grid: '#0ea5e9' },
        matrix: { snake: '#22c55e', food: '#84cc16', bg: '#14532d', grid: '#22c55e' }
    },
    currentTheme: 'nebula'
};
// Game State
let game = {
    canvas: null,
    ctx: null,
    gridSize: config.gridSize,
    cellSize: 0,
    snake: [],
    food: { x: 0, y: 0 },
    direction: 'right',
    nextDirection: 'right',
    score: 0,
    highScore: localStorage.getItem('snakeHighScore') || 0,
    speed: config.initialSpeed,
    gameLoop: null,
    isRunning: false,
    isPaused: false,
    zenMode: false,
    particles: []
};
// Initialize Game
function initGame() {
    game.canvas = document.getElementById('gameCanvas');
    game.ctx = game.canvas.getContext('2d');
    // Set canvas size
    resizeCanvas();
    window.addEventListener('resize', resizeCanvas);
    // Initialize UI elements
    updateUI();
    // Set up event listeners
    setupEventListeners();
    // Initialize snake
    resetGame();
    // Apply saved theme
    const savedTheme = localStorage.getItem('snakeTheme') || 'nebula';
    applyTheme(savedTheme);
    document.querySelector(`[data-theme="${savedTheme}"]`).classList.add('active');
    // Draw initial state
    draw();
}
// Resize canvas to fit container
function resizeCanvas() {
    const container = document.querySelector('.game-board');
    const size = Math.min(container.clientWidth, container.clientHeight);
    game.canvas.width = size;
    game.canvas.height = size;
    game.cellSize = size / game.gridSize;
    draw();
}
// Set up event listeners
function setupEventListeners() {
    // Keyboard controls
    document.addEventListener('keydown', handleKeyPress);
    // Button controls
    document.getElementById('startBtn').addEventListener('click', startGame);
    document.getElementById('pauseBtn').addEventListener('click', togglePause);
    document.getElementById('resetBtn').addEventListener('click', resetGame);
    document.getElementById('restartBtn').addEventListener('click', () => {
        document.getElementById('gameOver').style.display = 'none';
        resetGame();
        startGame();
    });
    // Mobile controls
    document.querySelectorAll('.mobile-btn').forEach(btn => {
        btn.addEventListener('click', () => {
            const direction = btn.dataset.direction;
            changeDirection(direction);
            // Visual feedback
            btn.style.transform = 'scale(0.9)';
            setTimeout(() => btn.style.transform = '', 100);
        });
    });
    // Settings controls
    const speedSlider = document.getElementById('speedSlider');
    const gridSlider = document.getElementById('gridSlider');
    const zenToggle = document.getElementById('zenToggle');
    speedSlider.addEventListener('input', (e) => {
        game.speed = parseInt(e.target.value);
        document.getElementById('speedValue').textContent = game.speed;
        document.getElementById('gameSpeed').textContent = game.speed;
        if (game.isRunning && !game.isPaused) {
            clearInterval(game.gameLoop);
            game.gameLoop = setInterval(gameUpdate, 1000 / game.speed);
        }
    });
    gridSlider.addEventListener('input', (e) => {
        game.gridSize = parseInt(e.target.value);
        document.getElementById('gridValue').textContent = game.gridSize;
        resizeCanvas();
        resetGame();
    });
    zenToggle.addEventListener('change', (e) => {
        game.zenMode = e.target.checked;
        applyTheme(config.currentTheme);
    });
    // Theme selection
    document.querySelectorAll('.theme-option').forEach(option => {
        option.addEventListener('click', () => {
            const theme = option.dataset.theme;
            applyTheme(theme);
            // Update active theme
            document.querySelectorAll('.theme-option').forEach(opt => {
                opt.classList.remove('active');
            });
            option.classList.add('active');
            // Save to localStorage
            localStorage.setItem('snakeTheme', theme);
        });
    });
}
// Handle keyboard input
function handleKeyPress(e) {
    if (game.isPaused || !game.isRunning) return;
    switch(e.key) {
        case 'ArrowUp':
        case 'w':
        case 'W':
        if (game.direction !== 'down') game.nextDirection = 'up';
        break;
        case 'ArrowDown':
        case 's':
        case 'S':
        if (game.direction !== 'up') game.nextDirection = 'down';
        break;
        case 'ArrowLeft':
        case 'a':
        case 'A':
        if (game.direction !== 'right') game.nextDirection = 'left';
        break;
        case 'ArrowRight':
        case 'd':
        case 'D':
        if (game.direction !== 'left') game.nextDirection = 'right';
        break;
        case ' ':
        togglePause();
        break;
    }
    e.preventDefault();
}
// Change direction with validation
function changeDirection(newDirection) {
    if (!game.isRunning || game.isPaused) return;
    const oppositeDirections = {
        'up': 'down',
        'down': 'up',
        'left': 'right',
        'right': 'left'
    };
    if (newDirection !== oppositeDirections[game.direction]) {
        game.nextDirection = newDirection;
    }
}
// Start the game
function startGame() {
    if (game.isRunning) return;
    game.isRunning = true;
    game.isPaused = false;
    document.getElementById('startBtn').innerHTML = '<i class="fas fa-play"></i> RESTART';
    game.gameLoop = setInterval(gameUpdate, 1000 / game.speed);
}
// Toggle pause state
function togglePause() {
    if (!game.isRunning) return;
    game.isPaused = !game.isPaused;
    const pauseBtn = document.getElementById('pauseBtn');
    if (game.isPaused) {
        clearInterval(game.gameLoop);
        pauseBtn.innerHTML = '<i class="fas fa-play"></i> RESUME';
    } else {
        game.gameLoop = setInterval(gameUpdate, 1000 / game.speed);
        pauseBtn.innerHTML = '<i class="fas fa-pause"></i> PAUSE';
    }
}
// Reset game to initial state
function resetGame() {
    // Clear existing game loop
    if (game.gameLoop) {
        clearInterval(game.gameLoop);
        game.gameLoop = null;
    }
    // Reset game state
    game.snake = [
        { x: Math.floor(game.gridSize / 2), y: Math.floor(game.gridSize / 2) },
        { x: Math.floor(game.gridSize / 2) - 1, y: Math.floor(game.gridSize / 2) },
        { x: Math.floor(game.gridSize / 2) - 2, y: Math.floor(game.gridSize / 2) }
    ];
    game.direction = 'right';
    game.nextDirection = 'right';
    game.score = 0;
    game.isRunning = false;
    game.isPaused = false;
    game.particles = [];
    // Generate initial food
    generateFood();
    // Reset UI
    document.getElementById('startBtn').innerHTML = '<i class="fas fa-play"></i> START GAME';
    document.getElementById('pauseBtn').innerHTML = '<i class="fas fa-pause"></i> PAUSE';
    document.getElementById('gameOver').style.display = 'none';
    updateUI();
    draw();
}
// Main game update loop
function gameUpdate() {
    // Update direction
    game.direction = game.nextDirection;
    // Calculate new head position
    const head = { ...game.snake[0] };
    switch(game.direction) {
        case 'up': head.y--; break;
        case 'down': head.y++; break;
        case 'left': head.x--; break;
        case 'right': head.x++; break;
    }
    // Check wall collision
    if (head.x < 0 || head.x >= game.gridSize || head.y < 0 || head.y >= game.gridSize) {
        gameOver();
        return;
    }
    // Check self collision
    for (let segment of game.snake) {
        if (head.x === segment.x && head.y === segment.y) {
            gameOver();
            return;
        }
    }
    // Add new head to snake
    game.snake.unshift(head);
    // Check food collision
    if (head.x === game.food.x && head.y === game.food.y) {
        // Increase score
        game.score += 10;
        // Create particles
        createFoodParticles(game.food.x, game.food.y);
        // Generate new food
        generateFood();
        // Update UI with animation
        document.getElementById('currentScore').classList.remove('score-pop');
        void document.getElementById('currentScore').offsetWidth;
        document.getElementById('currentScore').classList.add('score-pop');
        // Increase speed slightly
        if (game.score % 50 === 0 && game.speed < 20) {
            game.speed++;
            document.getElementById('speedSlider').value = game.speed;
            document.getElementById('speedValue').textContent = game.speed;
            document.getElementById('gameSpeed').textContent = game.speed;
            clearInterval(game.gameLoop);
            game.gameLoop = setInterval(gameUpdate, 1000 / game.speed);
        }
    } else {
        // Remove tail if no food eaten
        game.snake.pop();
    }
    // Update particles
    updateParticles();
    // Update UI
    updateUI();
    // Draw everything
    draw();
}
// Generate food at random position
function generateFood() {
    let foodPosition;
    let attempts = 0;
    const maxAttempts = 100;
    do {
        foodPosition = {
            x: Math.floor(Math.random() * game.gridSize),
            y: Math.floor(Math.random() * game.gridSize)
        };
        attempts++;
    } while (isPositionOnSnake(foodPosition) && attempts < maxAttempts);
    game.food = foodPosition;
}
// Check if position is on snake
function isPositionOnSnake(pos) {
    return game.snake.some(segment => segment.x === pos.x && segment.y === pos.y);
}
// Game over logic
function gameOver() {
    game.isRunning = false;
    clearInterval(game.gameLoop);
    // Update high score
    if (game.score > game.highScore) {
        game.highScore = game.score;
        localStorage.setItem('snakeHighScore', game.highScore);
        // Celebration effect
        createConfetti();
    }
    // Show game over screen
    document.getElementById('finalScore').textContent = game.score;
    document.getElementById('highScoreDisplay').textContent = game.highScore;
    document.getElementById('gameOver').style.display = 'block';
}
// Update UI elements
function updateUI() {
    document.getElementById('currentScore').textContent = game.score;
    document.getElementById('highScore').textContent = game.highScore;
    document.getElementById('snakeLength').textContent = game.snake.length;
    document.getElementById('gameSpeed').textContent = game.speed;
}
// Draw everything on canvas
function draw() {
    const ctx = game.ctx;
    const theme = config.themes[config.currentTheme];
    // Clear canvas
    ctx.fillStyle = theme.bg;
    ctx.fillRect(0, 0, game.canvas.width, game.canvas.height);
    // Draw grid (subtle in zen mode)
    if (!game.zenMode) {
        ctx.strokeStyle = `${theme.grid}20`;
        ctx.lineWidth = 0.5;
        for (let x = 0; x < game.gridSize; x++) {
            for (let y = 0; y < game.gridSize; y++) {
                ctx.strokeRect(
                x * game.cellSize,
                y * game.cellSize,
                game.cellSize,
                game.cellSize
                );
            }
        }
    }
    // Draw snake with gradient effect
    for (let i = 0; i < game.snake.length; i++) {
        const segment = game.snake[i];
        // Calculate gradient from head to tail
        const alpha = 1 - (i / game.snake.length) * 0.7;
        let color = theme.snake;
        // Convert hex to rgba for alpha
        if (color.startsWith('#')) {
            const r = parseInt(color.slice(1, 3), 16);
            const g = parseInt(color.slice(3, 5), 16);
            const b = parseInt(color.slice(5, 7), 16);
            color = `rgba(${r}, ${g}, ${b}, ${alpha})`;
        }
        // Draw segment with rounded corners
        ctx.fillStyle = color;
        drawRoundedRect(
        ctx,
        segment.x * game.cellSize + 1,
        segment.y * game.cellSize + 1,
        game.cellSize - 2,
        game.cellSize - 2,
        game.cellSize * 0.2
        );
        // Draw eyes on head
        if (i === 0) {
            ctx.fillStyle = '#ffffff';
            const eyeSize = game.cellSize * 0.2;
            const offset = game.cellSize * 0.25;
            // Position eyes based on direction
            let leftEye = { x: offset, y: offset };
            let rightEye = { x: game.cellSize - offset - eyeSize, y: offset };
            if (game.direction === 'up' || game.direction === 'down') {
                leftEye = { x: offset, y: offset };
                rightEye = { x: game.cellSize - offset - eyeSize, y: offset };
            } else if (game.direction === 'left') {
                leftEye = { x: offset, y: offset };
                rightEye = { x: offset, y: game.cellSize - offset - eyeSize };
            } else if (game.direction === 'right') {
                leftEye = { x: game.cellSize - offset - eyeSize, y: offset };
                rightEye = { x: game.cellSize - offset - eyeSize, y: game.cellSize - offset - eyeSize };
            }
            ctx.beginPath();
            ctx.arc(
            segment.x * game.cellSize + leftEye.x + eyeSize/2,
            segment.y * game.cellSize + leftEye.y + eyeSize/2,
            eyeSize/2,
            0,
            Math.PI * 2
            );
            ctx.fill();
            ctx.beginPath();
            ctx.arc(
            segment.x * game.cellSize + rightEye.x + eyeSize/2,
            segment.y * game.cellSize + rightEye.y + eyeSize/2,
            eyeSize/2,
            0,
            Math.PI * 2
            );
            ctx.fill();
        }
    }
    // Draw food with shine effect
    const foodX = game.food.x * game.cellSize;
    const foodY = game.food.y * game.cellSize;
    // Food gradient
    const foodGradient = ctx.createRadialGradient(
    foodX + game.cellSize/2,
    foodY + game.cellSize/2,
    0,
    foodX + game.cellSize/2,
    foodY + game.cellSize/2,
    game.cellSize/2
    );
    foodGradient.addColorStop(0, '#ffffff');
    foodGradient.addColorStop(0.5, theme.food);
    foodGradient.addColorStop(1, `${theme.food}80`);
    ctx.fillStyle = foodGradient;
    ctx.beginPath();
    ctx.arc(
    foodX + game.cellSize/2,
    foodY + game.cellSize/2,
    game.cellSize/2 - 1,
    0,
    Math.PI * 2
    );
    ctx.fill();
    // Food shine
    ctx.fillStyle = '#ffffff60';
    ctx.beginPath();
    ctx.arc(
    foodX + game.cellSize/3,
    foodY + game.cellSize/3,
    game.cellSize/6,
    0,
    Math.PI * 2
    );
    ctx.fill();
    // Draw particles
    drawParticles();
}
// Draw rounded rectangle
function drawRoundedRect(ctx, x, y, width, height, radius) {
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.closePath();
    ctx.fill();
}
// Create particles when food is eaten
function createFoodParticles(x, y) {
    const theme = config.themes[config.currentTheme];
    const centerX = (x + 0.5) * game.cellSize;
    const centerY = (y + 0.5) * game.cellSize;
    for (let i = 0; i < 15; i++) {
        game.particles.push({
            x: centerX,
            y: centerY,
            vx: (Math.random() - 0.5) * 8,
            vy: (Math.random() - 0.5) * 8,
            size: Math.random() * 3 + 1,
            color: theme.food,
            life: 1.0,
            decay: 0.02 + Math.random() * 0.03
        });
    }
}
// Create confetti for high score
function createConfetti() {
    const colors = ['#6366f1', '#8b5cf6', '#f59e0b', '#10b981', '#0ea5e9'];
    for (let i = 0; i < 50; i++) {
        game.particles.push({
            x: Math.random() * game.canvas.width,
            y: -10,
            vx: (Math.random() - 0.5) * 6,
            vy: Math.random() * 3 + 2,
            size: Math.random() * 8 + 4,
            color: colors[Math.floor(Math.random() * colors.length)],
            life: 1.0,
            decay: 0.005
        });
    }
}
// Update particles
function updateParticles() {
    for (let i = game.particles.length - 1; i >= 0; i--) {
        const p = game.particles[i];
        p.x += p.vx;
        p.y += p.vy;
        p.vy += 0.1; // Gravity
        p.life -= p.decay;
        if (p.life <= 0 || p.y > game.canvas.height) {
            game.particles.splice(i, 1);
        }
    }
}
// Draw particles
function drawParticles() {
    const ctx = game.ctx;
    for (const p of game.particles) {
        ctx.globalAlpha = p.life;
        ctx.fillStyle = p.color;
        ctx.beginPath();
        ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
        ctx.fill();
    }
    ctx.globalAlpha = 1.0;
}
// Apply visual theme
function applyTheme(themeName) {
    config.currentTheme = themeName;
    // Update CSS variables for theme
    const theme = config.themes[themeName];
    const root = document.documentElement;
    root.style.setProperty('--snake-color', theme.snake);
    root.style.setProperty('--food-color', theme.food);
    root.style.setProperty('--bg-color', theme.bg);
    // Apply zen mode adjustments
    if (game.zenMode) {
        document.body.style.background = `linear-gradient(135deg, ${theme.bg} 0%, ${theme.grid} 100%)`;
    } else {
        document.body.style.background = `linear-gradient(135deg, #0f172a 0%, #1e293b 100%)`;
    }
    // Redraw with new theme
    if (game.ctx) draw();
}
// Initialize game when page loads
window.addEventListener('DOMContentLoaded', initGame);
// Export for debugging
window.game = game;
window.config = config;

Project Description

Iyi ni game yinzoka, aho inzoka igenda irya igi , ikagenda ikura muburebure, uko inzoka iriye igi ninako ikura, nawe ugenda ubona amanota menshi, ikozwe muri HTML, CSS na JavaScript. Wowe icyo ukora nukureba aho igi riri ugapimiranya neza, ukayobora inzoka yawe igana kwigi, iyo iriye iryo gi ihita ikura muburebure, namanota yawe agahita yiyongera.

Iyo inzoka ikomeje kugenda ikagonga urukuta rwaho igomaba kugendera, uba utsinzwe, urongera ugatangira bundi bushya. Ifite amabuto atatu ariyo: START GAME ho ukanda kugira ngo utangire gukina game, ibuto ya PAUSE ukandaho, mugihe ushaka kuba uhagaritse gukina kugira ngo uze gukomerezaho nyuma, nindi buto yitwa RESET ukandaho, mugihe ushaka gutangira game bundi bushya.

Ushobora kongera cyangwa kugabanya umuvuduko inzoka igendaho, guhindura ingano yinzoka cyangwa igi. Ifite color themes mubabara atandatu ariyo: Nebula, Biolume, Neo-Classic, Sunset, Ocean na Matrix. Ifite aho urebera umuvuduko, inzoka iri kugenderaho, aho urebera amanota ugejeje, namagi inzoka imaze kurya, arinayo agaragaza uburebure bw'inzoka.

Ikwereka amanota ugenda ugira uko inzoka igenda irya, ibika amanota menshi washoboye kugira. Ugifungura game, inzoka igendera kumuvuduko wa 5 ariko ushobora kuwugabanya, ugashyira kumuvuduko wo munsi ya 5 cyangwa hejuru yaho.

Icyo amakode akoze iyi game, yagufasha kumenya nimba uri umuporogarama

  • Kwiga kumuvinga cyangwa se kugendesha elements za html ukoresheje JavaScript
  • Kwiga events listener muri JavaScript.
  • Guhindura color themes muri JavaScript.

Project Resources

Download source code, images, and documentation

📦 8.55 KB 🗜 ZIP Format

Project Information

Feb 01, 2026 Created
Feb 01, 2026 Updated

Share This Project

If you found this helpful, share it with others who might benefit.

Link yakopiwe!

Cookie Settings

Theme Customization