Trae,用代码点燃创意,探索 VibeCoding 的无限可能,成为 AI 编程的耀眼新星!
本文将带你Trae完整实现一个炫酷的贪吃蛇🐍🐍🐍游戏,从HTML结构到CSS样式,再到JavaScript游戏逻辑,一步步构建这个经典游戏。
🎮 游戏预览与功能
这个贪吃蛇游戏具有以下特点:
- 炫酷的霓虹灯风格UI流畅的蛇身移动动画粒子特效食物收集效果本地存储最高分记录响应式设计适配各种屏幕
完全放手给Trae
的Builder Mcp
搭建框架!!!
🏗️ HTML结构搭建
💬 「请创建一个基于 HTML 和原生 JavaScript 的项目,名字叫做《贪吃蛇-永远饿》。这个项目的核心玩法去操作游戏精髓是:
Canvas绘图的基本原理游戏循环的实现方式面向对象的游戏设计模式粒子特效的实现本地存储的应用键盘控制的实现
<!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样式设计
@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. 游戏初始化
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. 辅助工具类
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. 键盘控制
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. 贪吃蛇类
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. 食物类
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. 粒子特效
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. 游戏主循环
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布局,确保在不同屏幕尺寸下都能正常显示:
.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 功能,打造你的创意项目,无论你是编程新手还是技术大牛,这里都是你的舞台!