canvas路径算法仅负责绘制,游戏逻辑由坐标管理、方向控制、碰撞检测和帧循环驱动;蛇身用rect()绘制方块,食物用arc()画圆,核心是清屏后按数组坐标批量重绘,移动靠数组头插尾删,碰撞检测防撞墙与自撞。

Canvas 路径算法本身不直接参与贪吃蛇游戏逻辑,真正驱动游戏的是坐标管理、方向控制、碰撞检测和帧循环机制;Canvas 的 beginPath()、arc()、rect() 等路径方法仅负责绘制当前状态,而非计算逻辑。
用 Canvas 绘制蛇身与食物(路径绘制)
贪吃蛇的“身体”由多个单元格组成,每个单元格可用 rect() 绘制为实心方块;食物通常用 arc() 画成圆形。关键不是路径多复杂,而是每次重绘前清空画布、按最新坐标批量调用绘图命令:
- 使用
ctx.clearRect(0, 0, canvas.width, canvas.height)清屏 - 遍历蛇身数组
snake(如[{x:10,y:10}, {x:9,y:10}, ...]),对每个点调用ctx.fillRect(x * size, y * size, size, size) - 食物用
ctx.beginPath(); ctx.arc(x*size+size/2, y*size+size/2, size/2-1, 0, Math.PI*2); ctx.fill()
核心逻辑靠数据结构和定时器驱动
蛇的移动本质是数组操作:每帧在头部插入新坐标,按方向决定插入位置;若未吃到食物,则删掉尾部坐标。方向变更通过键盘事件更新 direction 变量,但需防止 180° 反向(如上变下):
- 用
requestAnimationFrame替代setInterval实现平滑帧循环 - 方向控制示例:
if (e.key === 'ArrowRight' && dir !== 'left') dir = 'right' - 坐标更新规则(假设格子大小为 20):
const head = {...snake[0]};<br> if (dir === 'right') head.x++;<br> if (dir === 'down') head.y++;<br> snake.unshift(head);<br> if (!ateFood) snake.pop();
碰撞检测决定游戏成败
两类碰撞必须检查:蛇头撞墙(超出画布格子范围)、蛇头撞自身(遍历蛇身除头部外的所有点):
- 边界判断:
head.x = width / size || head.y = height / size - 自撞判断:
snake.slice(1).some(segment => segment.x === head.x && segment.y === head.y) - 吃到食物只需判断
head.x === food.x && head.y === food.y,然后生成新食物(确保不在蛇身上)
性能与交互细节建议
避免卡顿和误操作,需注意几个实际细节:
- 键盘事件用
keydown并加event.preventDefault()防止页面滚动 - 方向变量只在按键时更新,不随帧循环重复赋值
- 食物坐标用随机整数生成后,用
snake.some()检查是否重叠,冲突则重试 - Canvas 设置固定宽高(如
canvas.width = 600; canvas.height = 400;),CSS 仅用于缩放显示,避免像素模糊
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











