特点如下:

  • 使用 <canvas> 绘制游戏场景
  • 键盘控制蛇的移动
  • 吃食物蛇身增长
  • 撞墙或撞到自己结束游戏
  • 适合 H5 网页、移动端 WebView 或桌面浏览器

&lt;!DOCTYPE html>
&lt;html lang="zh-CN">
&lt;head>
&lt;meta charset="UTF-8">
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0">
&lt;title>Canvas 贪食蛇实践&lt;/title>
&lt;style>
  body {
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background: #000;
  }
  canvas {
    background: #111;
    display: block;
    border: 2px solid #0f0;
  }
&lt;/style>
&lt;/head>
&lt;body>

&lt;canvas id="gameCanvas" width="400" height="400">&lt;/canvas>

&lt;script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

const box = 20; // 单位格子大小
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;

let snake = [];
snake[0] = { x: 8 * box, y: 8 * box }; // 初始蛇头

let food = {
  x: Math.floor(Math.random() * (canvasWidth / box)) * box,
  y: Math.floor(Math.random() * (canvasHeight / box)) * box
};

let direction = 'RIGHT';
let score = 0;

// 监听键盘
document.addEventListener('keydown', changeDirection);

function changeDirection(e) {
  if(e.key === 'ArrowUp' &amp;&amp; direction !== 'DOWN') direction = 'UP';
  if(e.key === 'ArrowDown' &amp;&amp; direction !== 'UP') direction = 'DOWN';
  if(e.key === 'ArrowLeft' &amp;&amp; direction !== 'RIGHT') direction = 'LEFT';
  if(e.key === 'ArrowRight' &amp;&amp; direction !== 'LEFT') direction = 'RIGHT';
}

// 检查碰撞(自己或墙)
function collision(head, array) {
  for(let i = 0; i &lt; array.length; i++) {
    if(head.x === array[i].x &amp;&amp; head.y === array[i].y) return true;
  }
  return false;
}

// 绘制场景
function draw() {
  // 清空画布
  ctx.fillStyle = '#111';
  ctx.fillRect(0, 0, canvasWidth, canvasHeight);

  // 绘制食物
  ctx.fillStyle = '#f00';
  ctx.fillRect(food.x, food.y, box, box);

  // 绘制蛇
  for(let i = 0; i &lt; snake.length; i++){
    ctx.fillStyle = (i === 0) ? '#0f0' : '#0a0';
    ctx.fillRect(snake[i].x, snake[i].y, box, box);
  }

  // 蛇移动
  let snakeX = snake[0].x;
  let snakeY = snake[0].y;

  if(direction === 'LEFT') snakeX -= box;
  if(direction === 'UP') snakeY -= box;
  if(direction === 'RIGHT') snakeX += box;
  if(direction === 'DOWN') snakeY += box;

  // 吃到食物
  if(snakeX === food.x &amp;&amp; snakeY === food.y) {
    score++;
    food = {
      x: Math.floor(Math.random() * (canvasWidth / box)) * box,
      y: Math.floor(Math.random() * (canvasHeight / box)) * box
    };
    // 不移除尾巴,蛇身增长
  } else {
    snake.pop(); // 移除尾巴
  }

  const newHead = { x: snakeX, y: snakeY };

  // 撞墙或自己死亡
  if(snakeX &lt; 0 || snakeX >= canvasWidth || snakeY &lt; 0 || snakeY >= canvasHeight || collision(newHead, snake)){
    clearInterval(game);
    alert('游戏结束!得分: ' + score);
    return;
  }

  snake.unshift(newHead); // 添加新蛇头

  // 绘制分数
  ctx.fillStyle = '#fff';
  ctx.font = '16px Arial';
  ctx.fillText('得分: ' + score, 10, 20);
}

// 游戏循环
const game = setInterval(draw, 150);

&lt;/script>

&lt;/body>
&lt;/html>


✅ 特性说明

  1. 栅格化网格
    • 每格 20px,方便碰撞计算和移动。
  2. 键盘控制
    • 支持上下左右箭头(可拓展为移动端手势控制)。
  3. 动态增长
    • 吃到食物蛇身增加一格,不吃则尾巴消失。
  4. 碰撞判定
    • 撞墙或撞到自己会结束游戏。
  5. 分数显示
    • 左上角显示当前得分。