贪吃蛇游戏edit icon

作者:
lynn-ssk
Fork(复制)
下载
嵌入
BUG反馈
index.html
现在支持上传本地图片了!
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇游戏</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Arial', sans-serif;
            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
        
        .game-container {
            background-color: rgba(0, 0, 0, 0.8);
            border-radius: 20px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            padding: 25px;
            text-align: center;
            max-width: 500px;
            width: 100%;
        }
        
        h1 {
            color: #4CAF50;
            margin-bottom: 15px;
            font-size: 2.5rem;
            text-shadow: 0 0 10px rgba(76, 175, 80, 0.5);
        }
        
        .game-info {
            display: flex;
            justify-content: space-between;
            margin-bottom: 20px;
            background: rgba(30, 30, 30, 0.7);
            padding: 15px;
            border-radius: 10px;
            color: white;
            font-size: 1.2rem;
        }
        
        #score {
            color: #FFD700;
            font-weight: bold;
        }
        
        #high-score {
            color: #FF6347;
            font-weight: bold;
        }
        
        .game-board {
            background-color: #0a1f0a;
            border: 2px solid #2E7D32;
            border-radius: 8px;
            display: block;
            margin: 0 auto;
            box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5);
        }
        
        .controls {
            margin-top: 25px;
            display: flex;
            flex-direction: column;
            gap: 15px;
        }
        
        .btn {
            background: linear-gradient(to bottom, #4CAF50, #2E7D32);
            color: white;
            border: none;
            padding: 12px 20px;
            font-size: 1.1rem;
            border-radius: 50px;
            cursor: pointer;
            transition: all 0.3s;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
        }
        
        .btn:hover {
            transform: translateY(-3px);
            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4);
            background: linear-gradient(to bottom, #66BB6A, #388E3C);
        }
        
        .btn:active {
            transform: translateY(1px);
        }
        
        #restart-btn {
            background: linear-gradient(to bottom, #2196F3, #0D47A1);
        }
        
        #restart-btn:hover {
            background: linear-gradient(to bottom, #42A5F5, #1565C0);
        }
        
        .instructions {
            margin-top: 25px;
            background: rgba(30, 30, 30, 0.7);
            padding: 15px;
            border-radius: 10px;
            color: #ddd;
            font-size: 0.9rem;
            line-height: 1.5;
        }
        
        .instructions h3 {
            color: #4CAF50;
            margin-bottom: 10px;
        }
        
        .game-over {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(0, 0, 0, 0.9);
            padding: 30px;
            border-radius: 15px;
            text-align: center;
            display: none;
            z-index: 10;
            border: 2px solid #f44336;
            box-shadow: 0 0 30px rgba(244, 67, 54, 0.5);
        }
        
        .game-over h2 {
            color: #f44336;
            font-size: 2.5rem;
            margin-bottom: 20px;
        }
        
        .game-over p {
            color: white;
            font-size: 1.5rem;
            margin-bottom: 25px;
        }
        
        .mobile-controls {
            display: none;
            grid-template-columns: repeat(3, 1fr);
            grid-template-rows: repeat(2, 1fr);
            gap: 10px;
            margin-top: 20px;
        }
        
        .mobile-btn {
            background: rgba(76, 175, 80, 0.3);
            color: white;
            border: 2px solid #4CAF50;
            border-radius: 10px;
            padding: 15px;
            font-size: 1.5rem;
            cursor: pointer;
            user-select: none;
        }
        
        .up-btn { grid-column: 2; grid-row: 1; }
        .left-btn { grid-column: 1; grid-row: 2; }
        .right-btn { grid-column: 3; grid-row: 2; }
        .down-btn { grid-column: 2; grid-row: 2; }
        
        @media (max-width: 600px) {
            .mobile-controls {
                display: grid;
            }
            
            .game-container {
                padding: 15px;
            }
            
            h1 {
                font-size: 2rem;
            }
        }
    </style>
</head>
<body>
    <div class="game-container">
        <h1>贪吃蛇游戏</h1>
        
        <div class="game-info">
            <div>得分: <span id="score">0</span></div>
            <div>最高分: <span id="high-score">0</span></div>
        </div>
        
        <canvas id="game-board" class="game-board" width="400" height="400"></canvas>
        
        <div class="mobile-controls">
            <div class="mobile-btn up-btn">↑</div>
            <div class="mobile-btn left-btn">←</div>
            <div class="mobile-btn down-btn">↓</div>
            <div class="mobile-btn right-btn">→</div>
        </div>
        
        <div class="controls">
            <button id="start-btn" class="btn">开始游戏</button>
            <button id="pause-btn" class="btn">暂停游戏</button>
            <button id="restart-btn" class="btn">重新开始</button>
        </div>
        
        <div class="instructions">
            <h3>游戏说明</h3>
            <p>使用方向键控制蛇的移动,吃到食物后蛇会变长,避免撞到墙壁或自己的身体。</p>
        </div>
    </div>
    
    <div id="game-over" class="game-over">
        <h2>游戏结束!</h2>
        <p>最终得分: <span id="final-score">0</span></p>
        <button id="play-again-btn" class="btn">再玩一次</button>
    </div>

    <script>
        // 游戏变量
        const canvas = document.getElementById('game-board');
        const ctx = canvas.getContext('2d');
        const scoreDisplay = document.getElementById('score');
        const highScoreDisplay = document.getElementById('high-score');
        const finalScoreDisplay = document.getElementById('final-score');
        const startBtn = document.getElementById('start-btn');
        const pauseBtn = document.getElementById('pause-btn');
        const restartBtn = document.getElementById('restart-btn');
        const playAgainBtn = document.getElementById('play-again-btn');
        const gameOverScreen = document.getElementById('game-over');
        
        // 移动端控制按钮
        const upBtn = document.querySelector('.up-btn');
        const downBtn = document.querySelector('.down-btn');
        const leftBtn = document.querySelector('.left-btn');
        const rightBtn = document.querySelector('.right-btn');
        
        // 游戏设置
        const gridSize = 20;
        const tileCount = canvas.width / gridSize;
        let speed = 120; // 毫秒
        
        // 游戏状态
        let snake = [];
        let food = {};
        let dx = 0;
        let dy = 0;
        let score = 0;
        let highScore = localStorage.getItem('snakeHighScore') || 0;
        let gameRunning = false;
        let gamePaused = false;
        let gameLoop;
        
        // 初始化游戏
        function initGame() {
            // 初始化蛇的位置
            snake = [
                {x: 10, y: 10},
                {x: 9, y: 10},
                {x: 8, y: 10}
            ];
            
            // 生成食物
            generateFood();
            
            // 重置移动方向
            dx = 1;
            dy = 0;
            
            // 重置分数
            score = 0;
            scoreDisplay.textContent = score;
            highScoreDisplay.textContent = highScore;
            
            // 隐藏游戏结束界面
            gameOverScreen.style.display = 'none';
        }
        
        // 生成食物
        function generateFood() {
            food = {
                x: Math.floor(Math.random() * tileCount),
                y: Math.floor(Math.random() * tileCount)
            };
            
            // 确保食物不会生成在蛇身上
            for (let segment of snake) {
                if (segment.x === food.x && segment.y === food.y) {
                    return generateFood();
                }
            }
        }
        
        // 绘制游戏
        function draw() {
            // 清空画布
            ctx.fillStyle = '#0a1f0a';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // 绘制网格背景
            ctx.strokeStyle = '#0d2b0d';
            for (let i = 0; i < tileCount; i++) {
                for (let j = 0; j < tileCount; j++) {
                    if ((i + j) % 2 === 0) {
                        ctx.fillRect(i * gridSize, j * gridSize, gridSize, gridSize);
                    }
                }
            }
            
            // 绘制蛇
            snake.forEach((segment, index) => {
                if (index === 0) {
                    // 蛇头
                    ctx.fillStyle = '#4CAF50';
                } else {
                    // 蛇身
                    ctx.fillStyle = '#2E7D32';
                }
                
                ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize - 1, gridSize - 1);
                
                // 添加蛇身的细节
                if (index !== 0) {
                    ctx.fillStyle = '#1B5E20';
                    ctx.fillRect(segment.x * gridSize + 4, segment.y * gridSize + 4, gridSize - 8, gridSize - 8);
                }
            });
            
            // 绘制食物
            ctx.fillStyle = '#FF5252';
            ctx.beginPath();
            ctx.arc(
                food.x * gridSize + gridSize/2,
                food.y * gridSize + gridSize/2,
                gridSize/2 - 1,
                0,
                Math.PI * 2
            );
            ctx.fill();
            
            // 添加食物的高光效果
            ctx.fillStyle = '#FF8A80';
            ctx.beginPath();
            ctx.arc(
                food.x * gridSize + gridSize/3,
                food.y * gridSize + gridSize/3,
                gridSize/6,
                0,
                Math.PI * 2
            );
            ctx.fill();
        }
        
        // 更新游戏状态
        function update() {
            // 计算新头部位置
            const head = {x: snake[0].x + dx, y: snake[0].y + dy};
            
            // 检查碰撞边界
            if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
                gameOver();
                return;
            }
            
            // 检查碰撞自身
            for (let i = 0; i < snake.length; i++) {
                if (snake[i].x === head.x && snake[i].y === head.y) {
                    gameOver();
                    return;
                }
            }
            
            // 将新头部添加到蛇的前面
            snake.unshift(head);
            
            // 检查是否吃到食物
            if (head.x === food.x && head.y === food.y) {
                // 增加分数
                score += 10;
                scoreDisplay.textContent = score;
                
                // 生成新的食物
                generateFood();
                
                // 提高速度(但不超过最大速度)
                if (speed > 60) {
                    speed -= 2;
                }
            } else {
                // 如果没有吃到食物,移除尾部
                snake.pop();
            }
        }
        
        // 游戏主循环
        function gameStep() {
            if (!gamePaused) {
                update();
                draw();
            }
        }
        
        // 开始游戏
        function startGame() {
            if (!gameRunning) {
                initGame();
                gameRunning = true;
                gamePaused = false;
                startBtn.textContent = "继续游戏";
                gameLoop = setInterval(gameStep, speed);
            } else if (gamePaused) {
                gamePaused = false;
                startBtn.textContent = "继续游戏";
            }
        }
        
        // 暂停游戏
        function pauseGame() {
            if (gameRunning && !gamePaused) {
                gamePaused = true;
                startBtn.textContent = "继续游戏";
            }
        }
        
        // 重新开始游戏
        function restartGame() {
            clearInterval(gameLoop);
            gameRunning = false;
            gamePaused = false;
            startBtn.textContent = "开始游戏";
            initGame();
            draw();
        }
        
        // 游戏结束
        function gameOver() {
            clearInterval(gameLoop);
            gameRunning = false;
            gamePaused = false;
            startBtn.textContent = "开始游戏";
            
            // 更新最高分
            if (score > highScore) {
                highScore = score;
                localStorage.setItem('snakeHighScore', highScore);
                highScoreDisplay.textContent = highScore;
            }
            
            // 显示游戏结束界面
            finalScoreDisplay.textContent = score;
            gameOverScreen.style.display = 'block';
        }
        
        // 键盘控制
        function handleKeydown(e) {
            // 防止反向移动
            switch(e.key) {
                case 'ArrowUp':
                    if (dy === 0) {
                        dx = 0;
                        dy = -1;
                    }
                    break;
                case 'ArrowDown':
                    if (dy === 0) {
                        dx = 0;
                        dy = 1;
                    }
                    break;
                case 'ArrowLeft':
                    if (dx === 0) {
                        dx = -1;
                        dy = 0;
                    }
                    break;
                case 'ArrowRight':
                    if (dx === 0) {
                        dx = 1;
                        dy = 0;
                    }
                    break;
            }
        }
        
        // 移动端控制
        function setupMobileControls() {
            upBtn.addEventListener('click', () => {
                if (dy === 0) {
                    dx = 0;
                    dy = -1;
                }
            });
            
            downBtn.addEventListener('click', () => {
                if (dy === 0) {
                    dx = 0;
                    dy = 1;
                }
            });
            
            leftBtn.addEventListener('click', () => {
                if (dx === 0) {
                    dx = -1;
                    dy = 0;
                }
            });
            
            rightBtn.addEventListener('click', () => {
                if (dx === 0) {
                    dx = 1;
                    dy = 0;
                }
            });
        }
        
        // 事件监听器
        startBtn.addEventListener('click', startGame);
        pauseBtn.addEventListener('click', pauseGame);
        restartBtn.addEventListener('click', restartGame);
        playAgainBtn.addEventListener('click', restartGame);
        document.addEventListener('keydown', handleKeydown);
        
        // 初始化游戏
        window.onload = function() {
            initGame();
            draw();
            setupMobileControls();
        };
    </script>
</body>
</html>

        
预览
控制台