SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html>
<head>
    <title>边界碰撞贪吃蛇</title>
    <style>
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            background-color: #2c3e50;
            font-family: Arial, sans-serif;
            margin: 0;
            min-height: 100vh;
        }

        #game-container {
            position: relative;
            margin-top: 20px;
        }

        #gameCanvas {
            border: 3px solid #ecf0f1;
            border-radius: 5px;
            background-color: #34495e;
        }

        .control-btn {
            position: absolute;
            padding: 15px 30px;
            font-size: 1.2em;
            background-color: #27ae60;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s;
            transform: translate(-50%, -50%);
            z-index: 1;
        }

        #startBtn {
            top: 50%;
            left: 50%;
        }

        #restartBtn {
            display: none;
            top: 60%;
            left: 50%;
        }

        #score {
            color: #ecf0f1;
            font-size: 2em;
            margin: 20px 0;
        }
    </style>
</head>
<body>
    <div id="score">得分: 0</div>
    <div id="game-container">
        <canvas id="gameCanvas" width="400" height="400"></canvas>
        <button id="startBtn" class="control-btn">开始游戏</button>
        <button id="restartBtn" class="control-btn">再来一次</button>
    </div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const scoreElement = document.getElementById('score');
        const startBtn = document.getElementById('startBtn');
        const restartBtn = document.getElementById('restartBtn');

        // 游戏配置
        const GRID_SIZE = 20;
        const TILE_COUNT = canvas.width / GRID_SIZE;
        const GAME_SPEED = 100;

        // 游戏状态
        let snake = [];
        let food = { x: 0, y: 0 };
        let dx = 0;
        let dy = 0;
        let score = 0;
        let lastTime = 0;
        let isPlaying = false;
        let animationFrameId = null;

        // 初始化游戏
        function initGame() {
            snake = [{ x: 10, y: 10 }];
            dx = 1;  // 初始向右移动
            dy = 0;
            score = 0;
            scoreElement.textContent = `得分: ${score}`;
            generateFood();
            isPlaying = true;
        }

        // 生成食物
        function generateFood() {
            do {
                food.x = Math.floor(Math.random() * TILE_COUNT);
                food.y = Math.floor(Math.random() * TILE_COUNT);
            } while (snake.some(segment => 
                segment.x === food.x && 
                segment.y === food.y
            ));
        }

        // 游戏主循环
        function gameLoop(timestamp) {
            if (!isPlaying) return;

            const delta = timestamp - lastTime;
            
            if (delta > GAME_SPEED) {
                lastTime = timestamp;

                // 移动蛇
                const newHead = {
                    x: snake[0].x + dx,
                    y: snake[0].y + dy
                };

                // 边界碰撞检测(新增)
                if (newHead.x < 0 || newHead.x >= TILE_COUNT || 
                    newHead.y < 0 || newHead.y >= TILE_COUNT) {
                    gameOver();
                    return;
                }

                // 自身碰撞检测
                if (snake.some(segment => 
                    segment.x === newHead.x && 
                    segment.y === newHead.y
                )) {
                    gameOver();
                    return;
                }

                snake.unshift(newHead);

                // 吃食物检测
                if (newHead.x === food.x && newHead.y === food.y) {
                    score += 10;
                    scoreElement.textContent = `得分: ${score}`;
                    generateFood();
                } else {
                    snake.pop();
                }

                draw();
            }

            animationFrameId = requestAnimationFrame(gameLoop);
        }

        // 绘制游戏
        function draw() {
            ctx.fillStyle = '#34495e';
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            // 绘制食物
            ctx.fillStyle = '#e74c3c';
            ctx.fillRect(
                food.x * GRID_SIZE,
                food.y * GRID_SIZE,
                GRID_SIZE - 2,
                GRID_SIZE - 2
            );

            // 绘制蛇(红色蛇头)
            snake.forEach((segment, index) => {
                ctx.fillStyle = index === 0 ? '#ff0000' : '#27ae60';
                ctx.fillRect(
                    segment.x * GRID_SIZE,
                    segment.y * GRID_SIZE,
                    GRID_SIZE - 2,
                    GRID_SIZE - 2
                );
            });
        }

        // 游戏结束处理
        function gameOver() {
            isPlaying = false;
            cancelAnimationFrame(animationFrameId);
            restartBtn.style.display = 'block';
        }

        // 方向控制
        function handleKeyDown(e) {
            if (!isPlaying) return;

            const key = e.key;
            const goingUp = dy === -1;
            const goingDown = dy === 1;
            const goingRight = dx === 1;
            const goingLeft = dx === -1;

            switch(key) {
                case 'ArrowLeft':
                    if (!goingRight) { dx = -1; dy = 0; }
                    break;
                case 'ArrowUp':
                    if (!goingDown) { dx = 0; dy = -1; }
                    break;
                case 'ArrowRight':
                    if (!goingLeft) { dx = 1; dy = 0; }
                    break;
                case 'ArrowDown':
                    if (!goingUp) { dx = 0; dy = 1; }
                    break;
            }
        }

        // 按钮事件
        startBtn.addEventListener('click', () => {
            startBtn.style.display = 'none';
            restartBtn.style.display = 'none';
            initGame();
            gameLoop(0);
        });

        restartBtn.addEventListener('click', () => {
            restartBtn.style.display = 'none';
            startBtn.click();
        });

        // 初始化事件监听
        document.addEventListener('keydown', handleKeyDown);
        
        // 首次加载显示开始按钮
        initGame();
        draw();
        startBtn.style.display = 'block';
        restartBtn.style.display = 'none';
    </script>
</body>
</html>