Trae,用代码点燃创意,探索 VibeCoding 的无限可能,成为 AI 编程的耀眼新星!
本文将带你Trae完整实现一个炫酷的贪吃蛇 🐍🐍🐍游戏,从HTML结构到CSS样式,再到JavaScript游戏逻辑,一步步构建这个经典游戏。
🎮 游戏预览与功能
这个贪吃蛇游戏具有以下特点:
- 炫酷的霓虹 灯风格UI
- 流畅的蛇身移动动画
- 粒子特效食物收集效果
- 本地存储最高分记录
- 响应式设计适配各种屏幕

完全放手给Trae
的Builder Mcp
搭建框架!!!

🏗️ HTML结构搭建
💬 「请创建一个基于 HTML 和原生 JavaScript 的项目,名字叫做《贪吃蛇-永远饿》。 这个项目的核心玩法去操作游戏精髓是:
- Canvas绘图的基本原理
- 游戏循环的实现方式
- 面向对象的游戏设计模式
- 粒子特效的实现
- 本地存储的应用
- 键盘控制的实现
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div class="container">
<div class="wrapper">
<button id="replay">
<i class="fas fa-play"></i>
再来一局
</button>
<div id="ui">
分数:<span id="score">00</span>
</div>
<div id="canvas"></div>
</div>
</div>
<script src="./index.js"></script>
</body>
</html>
HTML结构非常简单清晰:
- 一个游戏容器(
.container
) - 包含重新开始按钮(
#replay
) - 分数显示区域(
#ui
) - 游戏画布容器(
#canvas
)
🎨 CSS样式设计
css
@font-face {
font-family: "game";
src: url("https://fonts.googleapis.com/css2?family=Poppins:wght@500;800&display=swap");
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #222738;
box-shadow: inset 0 0 100px #206DD3;
display: flex;
justify-content: center;
align-items: center;
color: #6e7888;
height: 100%;
font-family: "Poppins", sans-serif;
background-image: url("https://example.com/bg.gif");
background-position: top center;
background-repeat: no-repeat;
}
.container {
display: flex;
width: 100%;
height: 100%;
flex-flow: column wrap;
justify-content: center;
align-items: center;
user-select: none;
}
.wrapper {
display: flex;
flex-flow: column wrap;
justify-content: center;
align-items: center;
text-align: center;
margin-top: 135px;
}
#replay {
font-size: 20px;
padding: 10px 20px;
background: #ffffff;
border: none;
color: #222738;
border-radius: 40px;
font-weight: 800;
cursor: pointer;
transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
#replay:hover {
background: #206DD3;
color: #ffffff;
box-shadow: 0 0 10px #206DD3;
}
#ui {
margin: 15px 0;
font-size: 30px;
font-weight: bold;
color: #ffffff;
text-shadow: 0 0 10px #206DD3;
}
canvas {
background-color: #181825;
}
CSS设计亮点:
- 使用Google Fonts的Poppins字体
- 霓虹灯效果的蓝色阴影
- 动态背景GIF增加视觉效果
- 按钮悬停动画
- 分数显示区域的发光效果
🧠 JavaScript游戏逻辑
JavaScript部分是整个游戏的核心,分为以下几个关键模块:
1. 游戏初始化
javascript
let dom_replay = document.querySelector("#replay");
let dom_score = document.querySelector("#score");
let dom_canvas = document.createElement("canvas");
document.querySelector("#canvas").appendChild(dom_canvas);
let CTX = dom_canvas.getContext("2d");
const W = (dom_canvas.width = 400);
const H = (dom_canvas.height = 400);
let snake, food, currentHue, cells = 20, cellSize, isGameOver = false;
let tails = [], score = 00, particles = [], requestID;
2. 辅助工具类
javascript
let helpers = {
// 二维向量类
Vec: class {
constructor(x, y) { this.x = x; this.y = y; }
add(v) { this.x += v.x; this.y += v.y; return this; }
mult(v) { /*...*/ }
},
// 碰撞检测
isCollision(v1, v2) { return v1.x == v2.x && v1.y == v2.y; },
// 绘制网格
drawGrid() { /*...*/ },
// 颜色转换
hsl2rgb(hue, saturation, lightness) { /*...*/ }
};
3. 键盘控制
javascript
let KEY = {
ArrowUp: false,
ArrowRight: false,
ArrowDown: false,
ArrowLeft: false,
resetState() {
this.ArrowUp = false;
this.ArrowRight = false;
this.ArrowDown = false;
this.ArrowLeft = false;
},
listen() {
addEventListener("keydown", (e) => {
// 防止180度转向
if (e.key === "ArrowUp" && this.ArrowDown) return;
if (e.key === "ArrowDown" && this.ArrowUp) return;
if (e.key === "ArrowLeft" && this.ArrowRight) return;
if (e.key === "ArrowRight" && this.ArrowLeft) return;
this[e.key] = true;
// 确保只有一个方向键被激活
Object.keys(this)
.filter(f => f !== e.key && f !== "listen" && f !== "resetState")
.forEach(k => { this[k] = false; });
}, false);
}
};
4. 贪吃蛇类
javascript
class Snake {
constructor() {
this.pos = new helpers.Vec(W / 2, H / 2); // 初始位置居中
this.dir = new helpers.Vec(0, 0); // 初始方向
this.size = W / cells; // 每节大小
this.color = "white";
this.history = []; // 蛇身历史位置
this.total = 1; // 初始长度
this.delay = 5; // 移动延迟
}
// 绘制蛇
draw() {
let { x, y } = this.pos;
CTX.fillStyle = this.color;
CTX.shadowBlur = 20;
CTX.shadowColor = "rgba(255,255,255,.3)";
CTX.fillRect(x, y, this.size, this.size);
// 绘制蛇身
if (this.total >= 2) {
for (let i = 0; i < this.history.length - 1; i++) {
let { x, y } = this.history[i];
CTX.fillStyle = "rgba(225,225,225,1)";
CTX.fillRect(x, y, this.size, this.size);
}
}
}
// 边界检测(穿墙)
walls() {
let { x, y } = this.pos;
if (x + cellSize > W) this.pos.x = 0;
if (y + cellSize > W) this.pos.y = 0;
if (y < 0) this.pos.y = H - cellSize;
if (x < 0) this.pos.x = W - cellSize;
}
// 控制方向
controlls() {
let dir = this.size;
if (KEY.ArrowUp) this.dir = new helpers.Vec(0, -dir);
if (KEY.ArrowDown) this.dir = new helpers.Vec(0, dir);
if (KEY.ArrowLeft) this.dir = new helpers.Vec(-dir, 0);
if (KEY.ArrowRight) this.dir = new helpers.Vec(dir, 0);
}
// 自碰撞检测
selfCollision() {
for (let p of this.history) {
if (helpers.isCollision(this.pos, p)) {
isGameOver = true;
}
}
}
update() {
this.walls();
this.draw();
this.controlls();
if (!this.delay--) {
// 吃到食物
if (helpers.isCollision(this.pos, food.pos)) {
incrementScore();
particleSplash();
food.spawn();
this.total++;
}
// 更新蛇身历史位置
this.history[this.total - 1] = new helpers.Vec(this.pos.x, this.pos.y);
for (let i = 0; i < this.total - 1; i++) {
this.history[i] = this.history[i + 1];
}
this.pos.add(this.dir);
this.delay = 5;
this.total > 3 ? this.selfCollision() : null;
}
}
}
5. 食物类
javascript
class Food {
constructor() {
this.size = cellSize;
this.spawn();
}
draw() {
let { x, y } = this.pos;
CTX.globalCompositeOperation = "lighter";
CTX.shadowBlur = 20;
CTX.shadowColor = this.color;
CTX.fillStyle = this.color;
CTX.fillRect(x, y, this.size, this.size);
}
spawn() {
let randX = ~~(Math.random() * cells) * this.size;
let randY = ~~(Math.random() * cells) * this.size;
// 确保食物不会生成在蛇身上
for (let path of snake.history) {
if (helpers.isCollision(new helpers.Vec(randX, randY), path)) {
return this.spawn();
}
}
this.color = currentHue = `hsl(${helpers.randHue()}, 100%, 50%)`;
this.pos = new helpers.Vec(randX, randY);
}
}
6. 粒子特效
javascript
class Particle {
constructor(pos, color, size, vel) {
this.pos = pos;
this.color = color;
this.size = Math.abs(size / 2);
this.ttl = 0;
this.gravity = -0.2;
this.vel = vel;
}
draw() {
let { x, y } = this.pos;
let [r, g, b] = helpers.hsl2rgb(...this.color.match(/\d+/g));
CTX.shadowColor = `rgb(${r},${g},${b},${1})`;
CTX.globalCompositeOperation = "lighter";
CTX.fillStyle = `rgb(${r},${g},${b},${1})`;
CTX.fillRect(x, y, this.size, this.size);
}
update() {
this.draw();
this.size -= 0.3;
this.ttl += 1;
this.pos.add(this.vel);
this.vel.y -= this.gravity;
}
}
function particleSplash() {
for (let i = 0; i < 20; i++) {
let vel = new helpers.Vec(Math.random() * 6 - 3, Math.random() * 6 - 3);
particles.push(new Particle(
new helpers.Vec(food.pos.x, food.pos.y),
currentHue,
food.size,
vel
));
}
}
7. 游戏主循环
javascript
function loop() {
clear();
if (!isGameOver) {
requestID = setTimeout(loop, 1000 / 60); // 60fps
helpers.drawGrid();
snake.update();
food.draw();
// 更新所有粒子
for (let p of particles) p.update();
helpers.garbageCollector();
} else {
gameOver();
}
}
function gameOver() {
// 保存最高分到localStorage
let maxScore = window.localStorage.getItem("maxScore") || 0;
score > maxScore && (maxScore = score);
window.localStorage.setItem("maxScore", maxScore);
// 绘制游戏结束界面
CTX.fillStyle = "#4cffd7";
CTX.textAlign = "center";
CTX.font = "bold 30px Poppins, sans-serif";
CTX.fillText("GAME OVER", W / 2, H / 2);
CTX.font = "15px Poppins, sans-serif";
CTX.fillText(`SCORE ${score}`, W / 2, H / 2 + 60);
CTX.fillText(`MAXSCORE ${maxScore}`, W / 2, H / 2 + 80);
}
function reset() {
score = 0;
dom_score.innerText = "00";
snake = new Snake();
food.spawn();
KEY.resetState();
isGameOver = false;
clearTimeout(requestID);
loop();
}
// 初始化游戏
function initialize() {
CTX.imageSmoothingEnabled = false;
KEY.listen();
cellSize = W / cells;
snake = new Snake();
food = new Food();
dom_replay.addEventListener("click", reset, false);
loop();
}
initialize();
🚀 游戏特色实现
-
流畅的蛇身移动 :通过
history
数组记录蛇身每一节的位置历史,实现平滑的移动效果。 -
粒子特效:吃到食物时生成20个随机方向的粒子,增加游戏视觉效果。
-
本地存储最高分 :使用
localStorage
保存玩家的最高分记录。 -
防止180度转向:在键盘监听中加入了方向判断,防止蛇头直接反向移动。
-
自适应网格 :根据
cells
变量自动计算每个格子的大小,方便调整游戏难度。
📱 响应式设计
游戏容器使用flex布局,确保在不同屏幕尺寸下都能正常显示:
css
.container {
display: flex;
width: 100%;
height: 100%;
flex-flow: column wrap;
justify-content: center;
align-items: center;
}
安装 node 环境,(本 mcp 需要 npx 指令运行)。
一键部署:在 Trae Chat 中选择@Builder with MCP,部署至掘金获取公开链接。
利用juejin发布MCP 部署并发布
配置掘金 MCP 插件,输入掘金 Token,并填到token的位置。(获取:aicoding.juejin.cn/tokens)

💬
: 部署该项目并发布到掘金。
随着掘金的这个部署MCP就会自动帮忙发布上去了,等审核通过即可。
注意本地要装node
。
喜欢的动动发财的鼠标🖱帮忙点点赞:aicoding.juejin.cn/aicoding/wo...
🎉 总结
当然,后期可以向Trae
要得更多,比如拓展一下游戏功能,吸引让更多人来玩:
- 添加不同种类的食物(加速、减速等)
- 实现关卡系统
- 添加背景音乐和音效
- 开发手机触摸控制版本
基于 Trae AI 与掘金 MCP 功能,打造你的创意项目,无论你是编程新手还是技术大牛,这里都是你的舞台!