HTML实现超简单的贪吃蛇

半兽人 发表于: 2025-04-14   最后更新时间: 2025-04-14 11:32:01  
{{totalSubscript}} 订阅, 167 游览

代码是一个用 HTML5 Canvas 和 JavaScript 实现的简单贪吃蛇游戏。

在线运行

HTML 部分

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple Snake Game</title>
    <style>
        canvas {
            display: block;
            margin: 0 auto;
            background-color: #000;
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas" width="400" height="400"></canvas>
  • <canvas>:游戏在一个 400x400 像素的画布上运行,ID 为 gameCanvas
  • CSS
    • display: blockmargin: 0 auto 让画布居中显示。
    • background-color: #000 设置画布背景为黑色。

JavaScript 部分

JavaScript 代码控制游戏的逻辑,包括蛇的移动、食物生成、碰撞检测等。

1. 初始化

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

const gridSize = 20;
const tileCount = canvas.width / gridSize;
  • canvas:获取画布元素。
  • ctx:获取 2D 绘图上下文,用于绘制图形。
  • gridSize = 20:游戏网格的大小,每个蛇身或食物占 20x20 像素。
  • tileCount = 20:画布宽 400 像素 ÷ 网格大小 20 = 20 个格子,游戏在一个 20x20 的网格中运行。

2. 游戏状态

let snake = [{ x: 10, y: 10 }];
let food = { x: Math.floor(Math.random() * tileCount), y: Math.floor(Math.random() * tileCount) };
let direction = { x: 0, y: 0 };
let score = 0;
  • snake:蛇是一个数组,初始时只有一节,位于网格坐标 (10, 10)。
  • food:食物的初始位置在网格中随机生成(0 到 19 的整数)。
  • direction:蛇的移动方向,初始为静止 { x: 0, y: 0 }
  • score:玩家的得分,初始为 0。

3. 游戏循环

function gameLoop() {
    update();
    draw();
    setTimeout(gameLoop, 100);
}
gameLoop();
  • gameLoop:主循环,调用 update(更新游戏状态)和 draw(绘制画面)。
  • setTimeout(gameLoop, 100):每 100 毫秒运行一次循环,控制游戏速度(每秒约 10 次更新)。
  • 最后调用 gameLoop() 启动游戏。

4. 更新逻辑

function update() {
    const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y };

    if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount || snake.some(segment => segment.x === head.x && segment.y === head.y)) {
        resetGame();
        return;
    }

    snake.unshift(head);

    if (head.x === food.x && head.y === food.y) {
        score++;
        food = { x: Math.floor(Math.random() * tileCount), y: Math.floor(Math.random() * tileCount) };
    } else {
        snake.pop();
    }
}
  • 计算新蛇头
    • head:根据当前方向计算蛇头的新位置(当前蛇头坐标 + 方向)。
  • 碰撞检测
    • 检查蛇头是否撞墙(超出网格边界:x < 0x >= tileCount 等)。
    • 检查蛇头是否撞到自己(snake.some(...) 检查蛇头是否与蛇身任一段重合)。
    • 如果碰撞,调用 resetGame() 重置游戏。
  • 移动蛇
    • snake.unshift(head):将新蛇头加入蛇数组头部。
  • 吃食物
    • 如果蛇头坐标等于食物坐标,说明吃到食物:
      • score++:得分加 1。
      • 随机生成新食物位置。
    • 如果没吃到食物,snake.pop() 移除蛇尾,保持蛇长度不变(模拟移动)。
  • 如果吃到食物,不移除蛇尾,蛇会变长。

5. 绘制画面

function draw() {
    ctx.fillStyle = '#000';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    ctx.fillStyle = '#0f0';
    snake.forEach(segment => ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize));

    ctx.fillStyle = '#f00';
    ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);

    ctx.fillStyle = '#fff';
    ctx.font = '20px Arial';
    ctx.fillText('Score: ' + score, 10, 30);
}
  • 清空画布
    • 用黑色 (#000) 填充整个画布,清除上一帧。
  • 绘制蛇
    • 用绿色 (#0f0) 绘制蛇的每一段,segment.x * gridSize 将网格坐标转为像素坐标。
  • 绘制食物
    • 用红色 (#f00) 绘制食物方块。
  • 绘制得分
    • 用白色 (#fff) 在画布左上角显示得分(Score: X)。

6. 重置游戏

function resetGame() {
    snake = [{ x: 10, y: 10 }];
    direction = { x: 0, y: 0 };
    score = 0;
}
  • 当游戏结束(撞墙或撞自己)时:
    • 重置蛇为初始状态(一节,位于 (10, 10))。
    • 方向设为静止。
    • 得分清零。

7. 键盘控制

window.addEventListener('keydown', e => {
    switch (e.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;
    }
});
  • 监听键盘
    • 使用 keydown 事件捕获方向键输入。
  • 方向控制
    • 上键:y: -1(向上移动)。
    • 下键:y: 1(向下移动)。
    • 左键:x: -1(向左移动)。
    • 右键:x: 1(向右移动)。
  • 防止反向移动
    • 例如,如果蛇正在向右(direction.x !== 0),不能直接向左,if (direction.x === 0) 确保只在水平静止时允许左右移动,防止蛇直接掉头咬自己。

游戏流程总结

  1. 游戏开始,蛇位于网格中央,食物随机出现。
  2. 玩家用方向键控制蛇移动(每 100 毫秒更新一次)。
  3. 蛇吃到食物时,长度增加,得分加 1,食物重新生成。
  4. 如果蛇撞墙或撞自己,游戏重置(蛇回到初始位置,得分清零)。
  5. 画面实时绘制蛇、食物和得分。

代码特点

  • 简单高效:代码逻辑清晰,适合初学者学习。
  • 网格系统:用网格坐标简化了位置计算。
  • 防作弊:防止蛇直接反向移动,增加了游戏合理性。
更新于 2025-04-14

查看HTML更多相关的文章或提一个关于HTML的问题,也可以与我们一起分享文章