用 HTML + JavaScript 实现经典贪吃蛇小游戏:从零开始,轻松上手!

还记得小时候玩过的贪吃蛇吗?那条不断吃食物、不断变长的像素小蛇,承载了多少人的童年回忆!今天,我们就用 HTML + JavaScript 从零开始实现一个经典的贪吃蛇小游戏,带你重温经典,感受编程的乐趣!

一、游戏简介

贪吃蛇是一款简单易懂的休闲游戏,玩家通过控制蛇的移动方向,使其吃到随机出现的食物。每吃到一个食物,蛇的身体就会变长一节,同时游戏得分也会增加。如果蛇撞到墙壁或自己的身体,游戏就会结束。

二、游戏实现

1. 游戏界面

我们使用 HTML 的 <canvas> 元素来创建游戏画布,并使用 JavaScript 来绘制游戏元素。

<canvas id="gameCanvas" width="400" height="400"></canvas>
2. 游戏逻辑
  • 蛇的移动: 使用数组存储蛇身的每个方块坐标,数组的第一个元素代表蛇头。通过不断更新蛇头的位置,并在蛇尾添加新的方块,实现蛇的移动。

  • 食物的生成: 使用随机数生成食物的坐标,并确保食物不会生成在蛇的身体上。

  • 碰撞检测: 检测蛇头是否与墙壁或自身发生碰撞,如果发生碰撞则游戏结束。

  • 用户输入: 监听键盘事件,根据方向键改变蛇的移动方向。

3. 代码实现
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇</title>
    <style>
        canvas {
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas" width="400" height="400"></canvas>
    <script>
        // ... (代码省略,请参考上文完整代码)
    </script>
</body>
</html>

三、代码解析

  • canvas: 创建了一个 400x400 像素的画布。

  • snake: 使用数组存储蛇身的每个方块坐标,初始位置为 (10, 10)。

  • direction: 存储蛇的移动方向,初始方向为静止。

  • food: 存储食物的坐标,初始位置为 (5, 5)。

  • gameLoop: 游戏循环函数,不断调用 update 和 draw 函数。

  • update: 更新游戏状态,包括移动蛇、检测碰撞、生成食物等。

  • draw: 绘制游戏画面,包括蛇、食物等。

  • keydown: 监听键盘事件,根据方向键改变蛇的移动方向。

四、游戏体验

将代码保存为 HTML 文件,用浏览器打开即可开始游戏!你可以使用方向键控制蛇的移动,体验经典贪吃蛇的乐趣!

五、总结

通过这个简单的贪吃蛇小游戏,我们学习了如何使用 HTML 和 JavaScript 实现基本的游戏逻辑和图形绘制。希望这个教程能够帮助你入门游戏开发,并激发你的编程兴趣!

欢迎在评论区分享你的游戏体验和改进建议!

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇</title>
    <style>
        canvas {
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas" width="400" height="400"></canvas>
    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');

        // 游戏参数
        const gridSize = 20; // 每个方块的大小
        const tileCount = canvas.width / gridSize; // 每行/列的方块数量

        // 蛇
        let snake = [{ x: 10, y: 10 }]; // 初始蛇身
        let direction = { x: 0, y: 0 }; // 初始方向

        // 食物
        let food = { x: 5, y: 5 }; // 初始食物位置

        // 游戏循环
        function gameLoop() {
            update();
            draw();
        }

        // 更新游戏状态
        function update() {
            // 移动蛇
            const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y };
            snake.unshift(head); // 在头部添加新方块

            // 检测是否吃到食物
            if (head.x === food.x && head.y === food.y) {
                // 生成新的食物
                food = {
                    x: Math.floor(Math.random() * tileCount),
                    y: Math.floor(Math.random() * tileCount)
                };
            } else {
                // 没有吃到食物,移除尾部方块
                snake.pop();
            }

            // 检测游戏结束
            if (
                head.x < 0 || head.x >= tileCount ||
                head.y < 0 || head.y >= tileCount ||
                snake.slice(1).some(segment => segment.x === head.x && segment.y === head.y)
            ) {
                clearInterval(intervalId); // 停止游戏循环
                alert('游戏结束!');
            }
        }

        // 绘制游戏画面
        function draw() {
            // 清空画布
            ctx.fillStyle = 'black';
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            // 绘制蛇
            ctx.fillStyle = 'lime';
            snake.forEach(segment => ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize));

            // 绘制食物
            ctx.fillStyle = 'red';
            ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);
        }

        // 监听键盘事件
        document.addEventListener('keydown', event => {
            switch (event.key) {
                case 'ArrowUp':
                    if (direction.y === 0) direction = { x: 0, y: -1 };
                    break;
                case 'ArrowDown':
                    if (direction.y === 0) direction = { x: 0, y: 1 };
                    break;
                case 'ArrowLeft':
                    if (direction.x === 0) direction = { x: -1, y: 0 };
                    break;
                case 'ArrowRight':
                    if (direction.x === 0) direction = { x: 1, y: 0 };
                    break;
            }
        });

        // 启动游戏循环,速度减半(200 毫秒)
        const intervalId = setInterval(gameLoop, 200);
    </script>
</body>
</html>

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐