当前位置: 首页 > article >正文

从零开始用HTML、CSS和JavaScript制作贪吃蛇网页小游戏

〇、前言

贪吃蛇是一款经典的休闲游戏,在诺基亚手机时代风靡全球。

在这里插入图片描述

作为编程入门者,实现一个贪吃蛇游戏是学习Web前端技术的绝佳练习

名人说:博观而约取,厚积而薄发。——苏轼《稼说送张琥》
创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)

目录

    • 〇、前言
    • 效果预览
    • 一、HTML结构
    • 二、CSS样式设计
    • 三、JavaScript游戏逻辑
    • 四、代码详解
      • 1. 游戏初始化
      • 2. 生成食物
      • 3. 移动蛇
      • 4. 碰撞检测
      • 5. 游戏控制
    • 五、完整代码

很高兴你打开了这篇博客,更多好用的软件工具,请关注我、订阅专栏《项目探索实验室》,内容持续更新中…

思维速览:
在这里插入图片描述

本文将详细讲解如何使用HTML、CSS和JavaScript从零开始创建一个功能完整的贪吃蛇网页游戏(更多功能可以根据个人开发需求拓展)

我们的贪吃蛇游戏将包含以下功能:

  • 基础的游戏逻辑(移动、吃食物、碰撞检测)
  • 分数记录和最高分保存
  • 游戏控制(开始、暂停、继续)
  • 自适应界面设计(支持PC和移动设备)
  • 逐步提高的游戏难度

效果预览

1️⃣静态展示:

在这里插入图片描述

2️⃣动态展示:

请添加图片描述

完成后的游戏效果如下:

  • 一个20x20格子的游戏场地
  • 绿色的蛇,红色的食物
  • 顶部显示当前分数和历史最高分
  • 底部有游戏控制按钮和移动设备专用的方向控制键

一、HTML结构

首先,创建基本的HTML结构:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇小游戏</title>
    <!-- CSS将在这里添加 -->
</head>
<body>
    <h1>贪吃蛇小游戏</h1>
    
    <div class="game-container">
        <div class="game-header">
            <div>分数: <span id="score">0</span></div>
            <div>最高分: <span id="high-score">0</span></div>
        </div>
        
        <div id="game-board"></div>
        
        <div class="controls">
            <button id="start-button">开始游戏</button>
            
            <div class="mobile-controls">
                <button class="up"></button>
                <button class="left"></button>
                <button class="right"></button>
                <button class="down"></button>
            </div>
        </div>
    </div>

    <!-- JavaScript将在这里添加 -->
</body>
</html>

这个HTML结构包含了:

  • 游戏标题
  • 分数和最高分显示区域
  • 游戏主画布(game-board)
  • 游戏控制按钮
  • 移动设备的方向控制按钮

二、CSS样式设计

接下来,我们需要添加CSS样式,使游戏看起来更加美观:

<style>
    body {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: 100vh;
        margin: 0;
        background-color: #f0f0f0;
        font-family: Arial, sans-serif;
    }
    
    .game-container {
        display: flex;
        flex-direction: column;
        align-items: center;
    }
    
    .game-header {
        display: flex;
        justify-content: space-between;
        width: 400px;
        margin-bottom: 10px;
    }
    
    #game-board {
        width: 400px;
        height: 400px;
        border: 2px solid #333;
        position: relative;
        background-color: #eee;
    }
    
    .snake-part {
        width: 20px;
        height: 20px;
        background-color: #4CAF50;
        position: absolute;
        border-radius: 2px;
    }
    
    .snake-head {
        background-color: #388E3C;
    }
    
    .food {
        width: 20px;
        height: 20px;
        background-color: #F44336;
        position: absolute;
        border-radius: 50%;
    }
    
    .controls {
        margin-top: 20px;
        display: flex;
        flex-direction: column;
        align-items: center;
    }
    
    button {
        padding: 10px 20px;
        margin: 5px;
        font-size: 16px;
        cursor: pointer;
        background-color: #2196F3;
        color: white;
        border: none;
        border-radius: 4px;
    }
    
    button:hover {
        background-color: #0b7dda;
    }
    
    .mobile-controls {
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
        grid-template-rows: 1fr 1fr 1fr;
        gap: 5px;
        margin-top: 15px;
        max-width: 200px;
    }
    
    .mobile-controls button {
        padding: 15px;
        margin: 0;
    }
    
    .up {
        grid-column: 2;
        grid-row: 1;
    }
    
    .left {
        grid-column: 1;
        grid-row: 2;
    }
    
    .right {
        grid-column: 3;
        grid-row: 2;
    }
    
    .down {
        grid-column: 2;
        grid-row: 3;
    }
    
    @media (max-width: 500px) {
        #game-board {
            width: 300px;
            height: 300px;
        }
        
        .game-header {
            width: 300px;
        }
    }
</style>

这些CSS样式:

  • 使用Flexbox和Grid布局
  • 设计蛇和食物的外观
  • 美化按钮和控件
  • 添加响应式设计,适应不同屏幕尺寸

三、JavaScript游戏逻辑

最后,也是最重要的部分,我们需要实现游戏的核心逻辑:

<script>
    document.addEventListener('DOMContentLoaded', () => {
        // 游戏变量
        const boardSize = 20; // 20x20 格子
        const gridSize = 20; // 每个格子的大小(像素)
        const board = document.getElementById('game-board');
        const scoreElement = document.getElementById('score');
        const highScoreElement = document.getElementById('high-score');
        const startButton = document.getElementById('start-button');
        
        let snake = []; // 蛇的身体部分坐标
        let food = null; // 食物坐标
        let direction = 'right'; // 初始方向
        let nextDirection = 'right';
        let gameInterval = null;
        let score = 0;
        let highScore = localStorage.getItem('snakeHighScore') || 0;
        let gameSpeed = 150; // 游戏速度,毫秒
        let gameStarted = false;
        let gamePaused = false;
        
        highScoreElement.textContent = highScore;
        
        // 初始化游戏
        function initGame() {
            clearBoard();
            
            // 初始化蛇
            snake = [
                {x: 5, y: 10}, // 头部
                {x: 4, y: 10},
                {x: 3, y: 10}
            ];
            
            // 重置游戏状态
            direction = 'right';
            nextDirection = 'right';
            score = 0;
            scoreElement.textContent = score;
            
            // 生成第一个食物
            generateFood();
            
            // 渲染初始状态
            renderSnake();
            renderFood();
        }
        
        // 清空游戏板
        function clearBoard() {
            board.innerHTML = '';
        }
        
        // 生成食物
        function generateFood() {
            let foodPosition;
            let onSnake;
            
            do {
                // 随机生成食物位置
                foodPosition = {
                    x: Math.floor(Math.random() * boardSize),
                    y: Math.floor(Math.random() * boardSize)
                };
                
                // 检查食物是否与蛇重叠
                onSnake = snake.some(part => part.x === foodPosition.x && part.y === foodPosition.y);
            } while (onSnake);
            
            food = foodPosition;
        }
        
        // 渲染蛇
        function renderSnake() {
            snake.forEach((part, index) => {
                const snakePart = document.createElement('div');
                snakePart.className = 'snake-part';
                
                if (index === 0) {
                    snakePart.classList.add('snake-head');
                }
                
                snakePart.style.left = `${part.x * gridSize}px`;
                snakePart.style.top = `${part.y * gridSize}px`;
                
                board.appendChild(snakePart);
            });
        }
        
        // 渲染食物
        function renderFood() {
            const foodElement = document.createElement('div');
            foodElement.className = 'food';
            foodElement.style.left = `${food.x * gridSize}px`;
            foodElement.style.top = `${food.y * gridSize}px`;
            
            board.appendChild(foodElement);
        }
        
        // 移动蛇
        function moveSnake() {
            // 更新方向
            direction = nextDirection;
            
            // 获取蛇头的当前位置
            const head = {...snake[0]};
            
            // 根据方向移动蛇头
            switch (direction) {
                case 'up':
                    head.y -= 1;
                    break;
                case 'down':
                    head.y += 1;
                    break;
                case 'left':
                    head.x -= 1;
                    break;
                case 'right':
                    head.x += 1;
                    break;
            }
            
            // 检查碰撞
            if (checkCollision(head)) {
                gameOver();
                return;
            }
            
            // 将新头部添加到蛇的开始
            snake.unshift(head);
            
            // 检查是否吃到食物
            if (head.x === food.x && head.y === food.y) {
                // 吃到食物,增加分数
                score += 10;
                scoreElement.textContent = score;
                
                // 更新最高分
                if (score > highScore) {
                    highScore = score;
                    highScoreElement.textContent = highScore;
                    localStorage.setItem('snakeHighScore', highScore);
                }
                
                // 生成新食物
                generateFood();
                
                // 增加游戏速度
                if (gameSpeed > 50) {
                    gameSpeed -= 2;
                    clearInterval(gameInterval);
                    gameInterval = setInterval(gameLoop, gameSpeed);
                }
            } else {
                // 没吃到食物,移除蛇尾
                snake.pop();
            }
            
            // 重新渲染游戏
            clearBoard();
            renderSnake();
            renderFood();
        }
        
        // 检查碰撞
        function checkCollision(head) {
            // 检查墙壁碰撞
            if (head.x < 0 || head.x >= boardSize || head.y < 0 || head.y >= boardSize) {
                return true;
            }
            
            // 检查自身碰撞
            return snake.some((part, index) => {
                // 跳过第一个元素,因为它就是头部
                if (index === 0) return false;
                return part.x === head.x && part.y === head.y;
            });
        }
        
        // 游戏结束
        function gameOver() {
            clearInterval(gameInterval);
            alert(`游戏结束! 你的得分: ${score}`);
            gameStarted = false;
            startButton.textContent = '开始游戏';
        }
        
        // 游戏循环
        function gameLoop() {
            moveSnake();
        }
        
        // 开始游戏
        function startGame() {
            if (gameStarted) {
                // 如果游戏已经开始,暂停或继续
                if (gamePaused) {
                    // 继续游戏
                    gameInterval = setInterval(gameLoop, gameSpeed);
                    startButton.textContent = '暂停游戏';
                    gamePaused = false;
                } else {
                    // 暂停游戏
                    clearInterval(gameInterval);
                    startButton.textContent = '继续游戏';
                    gamePaused = true;
                }
            } else {
                // 开始新游戏
                initGame();
                gameInterval = setInterval(gameLoop, gameSpeed);
                gameStarted = true;
                gamePaused = false;
                startButton.textContent = '暂停游戏';
            }
        }
        
        // 处理键盘输入
        document.addEventListener('keydown', e => {
            if (!gameStarted || gamePaused) return;
            
            // 防止方向键引起页面滚动
            if(['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '].includes(e.key)) {
                e.preventDefault();
            }
            
            // 更新方向
            switch (e.key) {
                case 'ArrowUp':
                    if (direction !== 'down') nextDirection = 'up';
                    break;
                case 'ArrowDown':
                    if (direction !== 'up') nextDirection = 'down';
                    break;
                case 'ArrowLeft':
                    if (direction !== 'right') nextDirection = 'left';
                    break;
                case 'ArrowRight':
                    if (direction !== 'left') nextDirection = 'right';
                    break;
            }
        });
        
        // 移动设备控制按钮
        document.querySelector('.up').addEventListener('click', () => {
            if (direction !== 'down' && gameStarted && !gamePaused) nextDirection = 'up';
        });
        
        document.querySelector('.down').addEventListener('click', () => {
            if (direction !== 'up' && gameStarted && !gamePaused) nextDirection = 'down';
        });
        
        document.querySelector('.left').addEventListener('click', () => {
            if (direction !== 'right' && gameStarted && !gamePaused) nextDirection = 'left';
        });
        
        document.querySelector('.right').addEventListener('click', () => {
            if (direction !== 'left' && gameStarted && !gamePaused) nextDirection = 'right';
        });
        
        // 开始游戏按钮
        startButton.addEventListener('click', startGame);
        
        // 初始化游戏
        initGame();
    });
</script>

四、代码详解

1. 游戏初始化

function initGame() {
    clearBoard();
    
    // 初始化蛇
    snake = [
        {x: 5, y: 10}, // 头部
        {x: 4, y: 10},
        {x: 3, y: 10}
    ];
    
    // 重置游戏状态
    direction = 'right';
    nextDirection = 'right';
    score = 0;
    scoreElement.textContent = score;
    
    // 生成第一个食物
    generateFood();
    
    // 渲染初始状态
    renderSnake();
    renderFood();
}

这个函数负责:

  • 清空游戏板
  • 创建初始长度为3的蛇
  • 重置方向和分数
  • 生成食物
  • 渲染初始游戏状态

2. 生成食物

function generateFood() {
    let foodPosition;
    let onSnake;
    
    do {
        // 随机生成食物位置
        foodPosition = {
            x: Math.floor(Math.random() * boardSize),
            y: Math.floor(Math.random() * boardSize)
        };
        
        // 检查食物是否与蛇重叠
        onSnake = snake.some(part => part.x === foodPosition.x && part.y === foodPosition.y);
    } while (onSnake);
    
    food = foodPosition;
}

这个函数:

  • 随机生成食物的位置
  • 确保食物不会出现在蛇身上
  • 使用do-while循环直到找到合适的位置

3. 移动蛇

function moveSnake() {
    // 更新方向
    direction = nextDirection;
    
    // 获取蛇头的当前位置
    const head = {...snake[0]};
    
    // 根据方向移动蛇头
    switch (direction) {
        case 'up':
            head.y -= 1;
            break;
        case 'down':
            head.y += 1;
            break;
        case 'left':
            head.x -= 1;
            break;
        case 'right':
            head.x += 1;
            break;
    }
    
    // 检查碰撞
    if (checkCollision(head)) {
        gameOver();
        return;
    }
    
    // 将新头部添加到蛇的开始
    snake.unshift(head);
    
    // 检查是否吃到食物
    if (head.x === food.x && head.y === food.y) {
        // 吃到食物,增加分数
        score += 10;
        scoreElement.textContent = score;
        
        // 更新最高分
        if (score > highScore) {
            highScore = score;
            highScoreElement.textContent = highScore;
            localStorage.setItem('snakeHighScore', highScore);
        }
        
        // 生成新食物
        generateFood();
        
        // 增加游戏速度
        if (gameSpeed > 50) {
            gameSpeed -= 2;
            clearInterval(gameInterval);
            gameInterval = setInterval(gameLoop, gameSpeed);
        }
    } else {
        // 没吃到食物,移除蛇尾
        snake.pop();
    }
    
    // 重新渲染游戏
    clearBoard();
    renderSnake();
    renderFood();
}

这个函数是游戏的核心,它:

  • 根据当前方向移动蛇头
  • 检查是否发生碰撞
  • 如果吃到食物,增加分数,生成新食物,加快游戏速度
  • 如果没吃到食物,移除蛇尾(保持长度不变)
  • 更新游戏界面

4. 碰撞检测

function checkCollision(head) {
    // 检查墙壁碰撞
    if (head.x < 0 || head.x >= boardSize || head.y < 0 || head.y >= boardSize) {
        return true;
    }
    
    // 检查自身碰撞
    return snake.some((part, index) => {
        // 跳过第一个元素,因为它就是头部
        if (index === 0) return false;
        return part.x === head.x && part.y === head.y;
    });
}

这个函数检查两种碰撞情况:

  • 蛇头撞到墙壁(超出游戏边界)
  • 蛇头撞到自己的身体

5. 游戏控制

function startGame() {
    if (gameStarted) {
        // 如果游戏已经开始,暂停或继续
        if (gamePaused) {
            // 继续游戏
            gameInterval = setInterval(gameLoop, gameSpeed);
            startButton.textContent = '暂停游戏';
            gamePaused = false;
        } else {
            // 暂停游戏
            clearInterval(gameInterval);
            startButton.textContent = '继续游戏';
            gamePaused = true;
        }
    } else {
        // 开始新游戏
        initGame();
        gameInterval = setInterval(gameLoop, gameSpeed);
        gameStarted = true;
        gamePaused = false;
        startButton.textContent = '暂停游戏';
    }
}

这个函数处理游戏的控制逻辑:

  • 开始新游戏
  • 暂停正在进行的游戏
  • 继续已暂停的游戏

五、完整代码

最后,我们将上面的HTML、CSS和JavaScript代码合并,得到完整的贪吃蛇游戏

<!--创作者:Code_流苏(CSDN)-->
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇小游戏</title>
    <style>
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
            font-family: Arial, sans-serif;
        }
        
        .game-container {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        
        .game-header {
            display: flex;
            justify-content: space-between;
            width: 400px;
            margin-bottom: 10px;
        }
        
        #game-board {
            width: 400px;
            height: 400px;
            border: 2px solid #333;
            position: relative;
            background-color: #eee;
        }
        
        .snake-part {
            width: 20px;
            height: 20px;
            background-color: #4CAF50;
            position: absolute;
            border-radius: 2px;
        }
        
        .snake-head {
            background-color: #388E3C;
        }
        
        .food {
            width: 20px;
            height: 20px;
            background-color: #F44336;
            position: absolute;
            border-radius: 50%;
        }
        
        .controls {
            margin-top: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        
        button {
            padding: 10px 20px;
            margin: 5px;
            font-size: 16px;
            cursor: pointer;
            background-color: #2196F3;
            color: white;
            border: none;
            border-radius: 4px;
        }
        
        button:hover {
            background-color: #0b7dda;
        }
        
        .mobile-controls {
            display: grid;
            grid-template-columns: 1fr 1fr 1fr;
            grid-template-rows: 1fr 1fr 1fr;
            gap: 5px;
            margin-top: 15px;
            max-width: 200px;
        }
        
        .mobile-controls button {
            padding: 15px;
            margin: 0;
        }
        
        .up {
            grid-column: 2;
            grid-row: 1;
        }
        
        .left {
            grid-column: 1;
            grid-row: 2;
        }
        
        .right {
            grid-column: 3;
            grid-row: 2;
        }
        
        .down {
            grid-column: 2;
            grid-row: 3;
        }
        
        @media (max-width: 500px) {
            #game-board {
                width: 300px;
                height: 300px;
            }
            
            .game-header {
                width: 300px;
            }
        }
    </style>
</head>
<body>
    <h1>贪吃蛇小游戏</h1>
    
    <div class="game-container">
        <div class="game-header">
            <div>分数: <span id="score">0</span></div>
            <div>最高分: <span id="high-score">0</span></div>
        </div>
        
        <div id="game-board"></div>
        
        <div class="controls">
            <button id="start-button">开始游戏</button>
            
            <div class="mobile-controls">
                <button class="up"></button>
                <button class="left"></button>
                <button class="right"></button>
                <button class="down"></button>
            </div>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // 游戏变量
            const boardSize = 20; // 20x20 格子
            const gridSize = 20; // 每个格子的大小(像素)
            const board = document.getElementById('game-board');
            const scoreElement = document.getElementById('score');
            const highScoreElement = document.getElementById('high-score');
            const startButton = document.getElementById('start-button');
            
            let snake = []; // 蛇的身体部分坐标
            let food = null; // 食物坐标
            let direction = 'right'; // 初始方向
            let nextDirection = 'right';
            let gameInterval = null;
            let score = 0;
            let highScore = localStorage.getItem('snakeHighScore') || 0;
            let gameSpeed = 150; // 游戏速度,毫秒
            let gameStarted = false;
            let gamePaused = false;
            
            highScoreElement.textContent = highScore;
            
            // 初始化游戏
            function initGame() {
                clearBoard();
                
                // 初始化蛇
                snake = [
                    {x: 5, y: 10}, // 头部
                    {x: 4, y: 10},
                    {x: 3, y: 10}
                ];
                
                // 重置游戏状态
                direction = 'right';
                nextDirection = 'right';
                score = 0;
                scoreElement.textContent = score;
                
                // 生成第一个食物
                generateFood();
                
                // 渲染初始状态
                renderSnake();
                renderFood();
            }
            
            // 清空游戏板
            function clearBoard() {
                board.innerHTML = '';
            }
            
            // 生成食物
            function generateFood() {
                let foodPosition;
                let onSnake;
                
                do {
                    // 随机生成食物位置
                    foodPosition = {
                        x: Math.floor(Math.random() * boardSize),
                        y: Math.floor(Math.random() * boardSize)
                    };
                    
                    // 检查食物是否与蛇重叠
                    onSnake = snake.some(part => part.x === foodPosition.x && part.y === foodPosition.y);
                } while (onSnake);
                
                food = foodPosition;
            }
            
            // 渲染蛇
            function renderSnake() {
                snake.forEach((part, index) => {
                    const snakePart = document.createElement('div');
                    snakePart.className = 'snake-part';
                    
                    if (index === 0) {
                        snakePart.classList.add('snake-head');
                    }
                    
                    snakePart.style.left = `${part.x * gridSize}px`;
                    snakePart.style.top = `${part.y * gridSize}px`;
                    
                    board.appendChild(snakePart);
                });
            }
            
            // 渲染食物
            function renderFood() {
                const foodElement = document.createElement('div');
                foodElement.className = 'food';
                foodElement.style.left = `${food.x * gridSize}px`;
                foodElement.style.top = `${food.y * gridSize}px`;
                
                board.appendChild(foodElement);
            }
            
            // 移动蛇
            function moveSnake() {
                // 更新方向
                direction = nextDirection;
                
                // 获取蛇头的当前位置
                const head = {...snake[0]};
                
                // 根据方向移动蛇头
                switch (direction) {
                    case 'up':
                        head.y -= 1;
                        break;
                    case 'down':
                        head.y += 1;
                        break;
                    case 'left':
                        head.x -= 1;
                        break;
                    case 'right':
                        head.x += 1;
                        break;
                }
                
                // 检查碰撞
                if (checkCollision(head)) {
                    gameOver();
                    return;
                }
                
                // 将新头部添加到蛇的开始
                snake.unshift(head);
                
                // 检查是否吃到食物
                if (head.x === food.x && head.y === food.y) {
                    // 吃到食物,增加分数
                    score += 10;
                    scoreElement.textContent = score;
                    
                    // 更新最高分
                    if (score > highScore) {
                        highScore = score;
                        highScoreElement.textContent = highScore;
                        localStorage.setItem('snakeHighScore', highScore);
                    }
                    
                    // 生成新食物
                    generateFood();
                    
                    // 增加游戏速度
                    if (gameSpeed > 50) {
                        gameSpeed -= 2;
                        clearInterval(gameInterval);
                        gameInterval = setInterval(gameLoop, gameSpeed);
                    }
                } else {
                    // 没吃到食物,移除蛇尾
                    snake.pop();
                }
                
                // 重新渲染游戏
                clearBoard();
                renderSnake();
                renderFood();
            }
            
            // 检查碰撞
            function checkCollision(head) {
                // 检查墙壁碰撞
                if (head.x < 0 || head.x >= boardSize || head.y < 0 || head.y >= boardSize) {
                    return true;
                }
                
                // 检查自身碰撞
                return snake.some((part, index) => {
                    // 跳过第一个元素,因为它就是头部
                    if (index === 0) return false;
                    return part.x === head.x && part.y === head.y;
                });
            }
            
            // 游戏结束
            function gameOver() {
                clearInterval(gameInterval);
                alert(`游戏结束! 你的得分: ${score}`);
                gameStarted = false;
                startButton.textContent = '开始游戏';
            }
            
            // 游戏循环
            function gameLoop() {
                moveSnake();
            }
            
            // 开始游戏
            function startGame() {
                if (gameStarted) {
                    // 如果游戏已经开始,暂停或继续
                    if (gamePaused) {
                        // 继续游戏
                        gameInterval = setInterval(gameLoop, gameSpeed);
                        startButton.textContent = '暂停游戏';
                        gamePaused = false;
                    } else {
                        // 暂停游戏
                        clearInterval(gameInterval);
                        startButton.textContent = '继续游戏';
                        gamePaused = true;
                    }
                } else {
                    // 开始新游戏
                    initGame();
                    gameInterval = setInterval(gameLoop, gameSpeed);
                    gameStarted = true;
                    gamePaused = false;
                    startButton.textContent = '暂停游戏';
                }
            }
            
            // 处理键盘输入
            document.addEventListener('keydown', e => {
                if (!gameStarted || gamePaused) return;
                
                // 防止方向键引起页面滚动
                if(['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '].includes(e.key)) {
                    e.preventDefault();
                }
                
                // 更新方向
                switch (e.key) {
                    case 'ArrowUp':
                        if (direction !== 'down') nextDirection = 'up';
                        break;
                    case 'ArrowDown':
                        if (direction !== 'up') nextDirection = 'down';
                        break;
                    case 'ArrowLeft':
                        if (direction !== 'right') nextDirection = 'left';
                        break;
                    case 'ArrowRight':
                        if (direction !== 'left') nextDirection = 'right';
                        break;
                }
            });
            
            // 移动设备控制按钮
            document.querySelector('.up').addEventListener('click', () => {
                if (direction !== 'down' && gameStarted && !gamePaused) nextDirection = 'up';
            });
            
            document.querySelector('.down').addEventListener('click', () => {
                if (direction !== 'up' && gameStarted && !gamePaused) nextDirection = 'down';
            });
            
            document.querySelector('.left').addEventListener('click', () => {
                if (direction !== 'right' && gameStarted && !gamePaused) nextDirection = 'left';
            });
            
            document.querySelector('.right').addEventListener('click', () => {
                if (direction !== 'left' && gameStarted && !gamePaused) nextDirection = 'right';
            });
            
            // 开始游戏按钮
            startButton.addEventListener('click', startGame);
            
            // 初始化游戏
            initGame();
        });
    </script>
</body>
</html>

很感谢你能看到这里,如果你有哪些想学习的项目,欢迎在评论区分享!
创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)


http://www.kler.cn/a/581567.html

相关文章:

  • XXE靶机详细通关攻略(flag)
  • 云计算VS网络安全,应该怎么选?
  • Chebykan wx 文章阅读
  • 新一代开源数字供应链安全审查与治理平台:悬镜源鉴SCA
  • OWL(Optimized Workforce Learning): 优化劳动力学习的通用智能体,用于处理现实世界的自动化任务(58.18 平均分)
  • 《C#上位机开发从门外到门内》1-1:上位机简介
  • Unity 带阻尼感的转盘
  • Helm 安装zookeeper集群
  • Linux网络编程——UDP网络通信的简单实现
  • 【洛谷P1080国王游戏】2025-3-7
  • 【leetcode hot 100 25】K个一组翻转链表
  • 每天五分钟深度学习框架PyTorch:ResNet算法模型完成CAFIR十分类
  • 小红书代运营公司-品融电商:助力品牌在小红书平台实现全域增长
  • Stable Diffusion游戏底模推荐
  • 基于ThinkPHP6用户登录逻辑,结合FastAPI框架实现用户登录系统的全流程解析
  • 碰一碰发视频系统---原生态网页端技术开发逻辑
  • 理解字符流和字节流,节点流和处理流、缓冲流、InputStreamReader、BufferInputStream、BufferReader...
  • Java直通车系列28【Spring Boot】(数据访问Spring Data JPA)
  • Qt5.10版本以下 qml ui语言动态切换
  • ​【C++设计模式】第十九篇:状态模式(State)