☰
零基础用HTML写贪吃蛇:从入门到游戏实现
2026/10/17 5:08:00 网站建设 项目流程

简介:这是一份面向网页开发初学者与前端入门者的HTML贪吃蛇游戏实战资源,帮助读者在动手实践中理解HTML、CSS与JavaScript如何协同构建交互式网页应用。资源包共3个文件,包含1个html主页面、1张jpg背景图与1张png素材图,整体约86KB,体积轻巧,下载后可直接在浏览器中运行体验。项目围绕游戏区域搭建、分数显示、键盘事件监听、蛇身位置更新、碰撞检测与食物随机生成等核心逻辑展开,并涉及setInterval定时刷新、DOM操作更新界面以及CSS3动画平滑移动等知识点,是练习网页开发基本技巧与逻辑思维的良好范例。目前已有1453人学习下载,适合希望从零掌握前端交互开发、巩固事件处理与状态更新思路的读者参考借鉴。

1. 零基础也能玩转:用 HTML 写一个贪吃蛇到底有多简单

很多刚接触编程的朋友一听到“写代码”三个字,脑子里浮现的可能是满屏跳动的绿色字符,或者是密密麻麻像天书一样的英文单词。其实,编程入门完全可以像搭积木一样简单。今天我们要聊的,就是用最基础的html语言来做一个贪吃蛇小游戏。你不需要安装复杂的软件,也不需要配置晦涩的环境,只要有一台能上网的电脑和一个浏览器,就能亲手让一条小蛇在屏幕上跑起来。这可能是你离“自己写游戏”最近的一次,也是理解网页如何动起来的最佳切入点。

为什么选贪吃蛇?因为它规则简单到不用解释:蛇吃蛋变长,撞墙或撞自己就结束。但在这简单的规则背后,藏着网页开发最核心的三样东西:结构(HTML)、样式(CSS)和逻辑(JavaScript)。很多新手学编程觉得枯燥,是因为一直在背语法、看文档,却看不到自己能做出什么。而贪吃蛇是一个即时反馈的项目——你改一个数字,蛇的速度就变了;你改一个颜色,蛇身就变色了。这种“所见即所得”的成就感,是支撑你继续学下去的最好燃料。这篇文章就是写给完全零基础的你,我们不深挖浏览器底层原理,只求用最直白的方式,把第一个能跑起来的游戏做出来。

2. 动手前的准备:搞懂网页的三驾马车与贪吃蛇的骨架

在正式敲代码之前,我们得先花几分钟把“地基”打牢。很多新手上来就复制一大段代码,结果运行报错,连错在哪都找不到,这就是因为没搞懂网页文件的基本结构。你可以把做网页想象成盖房子:HTML 是毛坯房的墙和柱子,决定了哪里是客厅、哪里是卧室;CSS 是装修,决定墙刷什么颜色、家具怎么摆;JavaScript 则是水电和智能家居,决定你按开关灯会不会亮、门会不会自动开。贪吃蛇这个项目,三者缺一不可。

2.1 先认识一下 HTML 文件的基本长相

不管你用什么编辑器(电脑自带的记事本都行),新建一个文件,名字叫snake.html。注意后缀必须是.html,不能是.txt。然后在这个文件里输入下面这段最基础的代码。这就像盖房子先搭个框架,所有网页都长这样。

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>我的第一个贪吃蛇</title> <!-- 这里以后放 CSS 装修代码 --> </head> <body> <!-- 这里放游戏画面,现在先写一句话测试 --> <h1>Hello,贪吃蛇!</h1> <!-- 这里以后放 JavaScript 逻辑代码 --> </body> </html>

写完后保存,双击这个文件,它就会用你默认的浏览器打开。如果你看到了“Hello,贪吃蛇!”这行大字,恭喜你,你已经迈出了第一步。这里面的<head>是给浏览器看的配置信息,<body>才是用户能看见的内容。<meta charset="UTF-8">这行很重要,它告诉浏览器用中文编码,不然汉字可能会变成乱码。很多新手第一次写网页,打开全是问号,就是漏了这行。

2.2 给贪吃蛇画一块地:用 Canvas 做游戏舞台

贪吃蛇不能直接在<body>里乱跑,我们需要给它圈一块地。在 HTML 里,最常用的画图工具叫<canvas>(画布)。你可以把它想象成一块黑板,JavaScript 就是粉笔,可以在上面画蛇、画食物。把<body>里的<h1>删掉,换成下面这行:

<canvas id="gameCanvas" width="400" height="400" style="border:1px solid #333;"></canvas>

这行代码的意思是:创建一个宽 400 像素、高 400 像素的画布,并且给它加一个深灰色的边框,方便我们看清边界。id="gameCanvas"是这个画布的名字,后面 JavaScript 要凭这个名字找到它。width和height决定了游戏区域的大小,你可以改成 600 或 800,但建议新手先用 400,因为格子小一点,蛇跑起来视觉上更舒服。现在刷新浏览器,你应该能看到一个空白的方框,这就是你的游戏世界了。

2.3 让蛇动起来的关键:理解坐标与格子

贪吃蛇看起来是在连续移动,但在计算机眼里,它其实是在一个个格子上跳。我们假设把 400x400 的画布切成 20x20 的小格子,每个格子就是 20 像素。蛇头的位置可以用(x, y)坐标表示,比如(0,0)是左上角第一个格子,(1,0)是它右边那个格子。每次蛇移动,其实就是把蛇头的坐标加上一个方向值。比如向右走就是x加 1,向下走就是y加 1。食物也是随机出现在某个格子里。理解了这一点,后面的代码就很好懂了。你不用死记硬背,只要知道:蛇是一串坐标点,移动就是改坐标,吃到了就是坐标重合了。

3. 从零敲出第一条蛇:核心逻辑与代码逐行拆解

准备工作做完,现在进入最核心的部分。这一章我们会把贪吃蛇的 JavaScript 逻辑一点点搭起来。别怕代码长,我会把每一段都拆开讲清楚。你只需要跟着步骤,把代码复制到<script>标签里就行。记住,写代码最忌讳只看不练,哪怕照着抄一遍,你的大脑也会开始建立连接。

3.1 初始化游戏:定义蛇、食物和方向

在<body>标签结束前,加上<script>标签,我们的逻辑都写在这里面。首先定义几个最基础的变量。这段代码的作用是告诉浏览器:蛇一开始有多长、食物在哪、蛇往哪走。

// 获取画布和上下文 const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); // 定义格子大小,20像素一格 const box = 20; // 初始化蛇:一个数组,每个元素是一个坐标点 let snake = [{ x: 10 * box, y: 10 * box }]; // 初始化食物:随机出现在画布内 let food = { x: Math.floor(Math.random() * 20) * box, y: Math.floor(Math.random() * 20) * box }; // 初始方向:向右 let direction = 'RIGHT'; // 游戏分数 let score = 0;

这里snake数组里只有一个点,代表蛇头。food的坐标用Math.random()随机生成 0 到 19 之间的整数,再乘以 20,这样食物就正好落在某个格子里。direction是当前移动方向,我们默认向右。score用来记录吃到了多少食物。这些变量名你可以改成中文拼音,但建议习惯英文,因为以后查资料方便。

3.2 画蛇和食物:让画面显示出来

定义好数据后,我们需要一个函数把蛇和食物画到画布上。这个函数会反复执行,每次执行都清空画布,再重新画一遍,这样看起来就像在动。

function draw() { // 清空画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 画蛇:遍历蛇的每一节 for (let i = 0; i < snake.length; i++) { // 蛇头用绿色,蛇身用浅绿色 ctx.fillStyle = (i === 0) ? '#2ecc71' : '#a9dfbf'; ctx.fillRect(snake[i].x, snake[i].y, box, box); // 给蛇身加个边框,看起来更清楚 ctx.strokeStyle = '#1e8449'; ctx.strokeRect(snake[i].x, snake[i].y, box, box); } // 画食物:红色方块 ctx.fillStyle = '#e74c3c'; ctx.fillRect(food.x, food.y, box, box); }

ctx.fillRect(x, y, width, height)就是画一个实心方块。蛇头用深绿,蛇身用浅绿,这样一眼就能看出头在哪。食物用红色,醒目。ctx.strokeRect是给方块加个边框,不然蛇身连在一起会糊成一团。这个draw函数现在还没被调用,我们稍后会用一个定时器反复调用它。

3.3 让蛇跑起来:方向控制与移动逻辑

接下来是游戏的心脏部分:更新蛇的位置。每次更新,我们根据direction计算新蛇头的坐标,然后判断有没有吃到食物、有没有撞墙。

function update() { // 复制蛇头坐标 let headX = snake[0].x; let headY = snake[0].y; // 根据方向移动蛇头 if (direction === 'RIGHT') headX += box; else if (direction === 'LEFT') headX -= box; else if (direction === 'UP') headY -= box; else if (direction === 'DOWN') headY += box; // 判断是否吃到食物 if (headX === food.x && headY === food.y) { // 吃到食物:分数加1,重新生成食物,蛇不删尾巴(变长) score++; food = { x: Math.floor(Math.random() * 20) * box, y: Math.floor(Math.random() * 20) * box }; } else { // 没吃到:删除蛇尾,保持长度不变 snake.pop(); } // 把新蛇头加到数组最前面 let newHead = { x: headX, y: headY }; snake.unshift(newHead); // 判断撞墙或撞自己 if (headX < 0 || headX >= canvas.width || headY < 0 || headY >= canvas.height || collision(newHead, snake.slice(1))) { clearInterval(game); alert('游戏结束!得分:' + score); } } // 碰撞检测函数 function collision(head, body) { for (let i = 0; i < body.length; i++) { if (head.x === body[i].x && head.y === body[i].y) { return true; } } return false; }

这段逻辑是:先算出新蛇头的位置,如果吃到食物就不删尾巴(蛇变长),没吃到就删尾巴(蛇保持长度)。然后把新蛇头插到数组最前面。最后检查新蛇头有没有超出画布边界,或者撞到了自己的身体。如果撞了,就停止游戏并弹出分数。collision函数就是遍历蛇身,看看有没有坐标和头重合。

3.4 键盘控制与游戏循环

蛇能动之后,我们需要用键盘控制方向。监听键盘事件,并且防止蛇直接反向走(比如正在向右,不能马上按左)。

// 键盘按下事件 document.addEventListener('keydown', function(event) { if (event.key === 'ArrowRight' && direction !== 'LEFT') direction = 'RIGHT'; else if (event.key === 'ArrowLeft' && direction !== 'RIGHT') direction = 'LEFT'; else if (event.key === 'ArrowUp' && direction !== 'DOWN') direction = 'UP'; else if (event.key === 'ArrowDown' && direction !== 'UP') direction = 'DOWN'; }); // 游戏循环:每 150 毫秒更新一次 let game = setInterval(function() { update(); draw(); }, 150);

setInterval是定时器,每 150 毫秒执行一次update和draw。150 毫秒大概是一秒动 6 到 7 次,速度适中。如果你觉得慢,可以改成 100;觉得快就改成 200。注意game变量要在update函数之前定义,不然clearInterval(game)会报错。把上面所有代码按顺序放进<script>标签里,保存刷新,你就能用方向键控制小蛇吃红点变长了。

4. 新手避坑指南:为什么你的蛇不动、乱跑或直接撞死

第一次写代码,几乎没有人能一次成功。下面这几个坑,是我见过新手最容易踩的,每一个都对应着具体的现象和原因。如果你卡住了,先对照这里排查,大概率能自己解决。

4.1 现象:按键盘没反应,蛇一动不动

原因:最常见的是document.addEventListener写在了canvas元素还没加载之前。浏览器是从上往下读代码的,如果<script>放在<head>里,执行时<body>里的画布还没创建,getElementById就会拿到null,后面全错。解决:把<script>标签放到</body>前面,或者用window.onload = function() { ... }把代码包起来,等页面加载完再执行。

4.2 现象:蛇走几步就撞墙,明明按了方向键

原因:方向判断逻辑写反了,或者direction变量被重复赋值。比如你按了右键,但代码里写的是direction = 'LEFT'。还有一种可能是键盘事件里用了event.keyCode,但不同浏览器键码不一样。解决:统一用event.key,它返回的是'ArrowRight'这种字符串,直观且兼容性好。检查每个方向的赋值,确保和移动逻辑里的字符串完全一致(大小写敏感)。

4.3 现象:蛇吃到食物后身体错位,或者食物刷在蛇身上

原因:食物随机生成时没有排除蛇身已经占据的格子。虽然概率低,但一旦食物出现在蛇身上,蛇头永远吃不到,游戏就卡住了。解决:写一个generateFood函数,用do...while循环反复随机,直到食物的坐标不在snake数组里为止。代码示例如下:

function generateFood() { let newFood; do { newFood = { x: Math.floor(Math.random() * 20) * box, y: Math.floor(Math.random() * 20) * box }; } while (snake.some(segment => segment.x === newFood.x && segment.y === newFood.y)); return newFood; }

4.4 现象:游戏结束后刷新页面,分数还在,蛇还在动

原因:setInterval没有真正清除,或者alert弹窗后定时器还在后台跑。解决:在clearInterval(game)之后,把game变量设为null,并且在update函数开头加一个判断if (!game) return;。另外,alert会阻塞浏览器,弹窗期间定时器其实还在排队,点掉后会瞬间执行多次。建议用clearInterval后直接return,不要依赖alert做唯一中断。

4.5 现象:蛇移动时闪烁严重,或者拖影

原因:draw函数里没有清空画布,或者清空区域不对。clearRect的宽高写成了canvas.width和canvas.height,但画布被 CSS 缩放了。解决:确保ctx.clearRect(0, 0, canvas.width, canvas.height)里的宽高和<canvas>标签上的width、height属性一致,不要用 CSS 去改画布尺寸。CSS 改的是显示大小,画布内部坐标系不变,会导致错位。

5. 下一步学什么:从贪吃蛇到更完整的网页作品

当你把上面这个版本跑通,并且能自己改速度、改颜色、改格子大小之后,你已经摸到了网页开发的门槛。接下来不要急着去学复杂的框架,先把这几个小改进做一遍,每一个都能让你对 JavaScript 的理解更深一层。第一,加一个“暂停/继续”功能,按空格键切换game定时器的状态。第二,把分数显示在画布上,用ctx.fillText在左上角写Score: 0,每次吃到食物更新。第三,给蛇加一个“穿墙”模式,撞到右边界时从左边出来,这需要你把坐标判断从>= canvas.width改成取模运算。第四,把蛇身换成圆角矩形,用ctx.arc画圆,或者用ctx.roundRect(新浏览器支持)。第五,加一个重新开始按钮,用 HTML 的<button>配合location.reload()或者重置所有变量。

这些改动都不难,但每一个都需要你查一点资料、试错几次。我第一次学的时候,光是把分数显示在画面上就折腾了一下午,因为忘了在draw函数里每帧重绘文字,导致分数叠在一起看不清。从那以后我每次做画布项目,都强制自己先写一个clearRect,再写所有绘制逻辑,这个习惯帮我省了很多后悔药。如果你能独立完成上面任意两个改进,就可以去尝试更复杂的项目了,比如用 Canvas 画一个时钟、做一个打砖块游戏,或者学一点 DOM 操作,把网页上的按钮和输入框联动起来。贪吃蛇只是一个起点,它证明了你完全有能力让代码听你的话。希望帮到你,我们下一个项目见。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询