🐍 人人都是AI码农——游戏开发,全解析 | HTML+CSS+JS三件套

Trae,用代码点燃创意,探索 VibeCoding 的无限可能,成为 AI 编程的耀眼新星!

本文将带你Trae完整实现一个炫酷的贪吃蛇 🐍🐍🐍游戏,从HTML结构到CSS样式,再到JavaScript游戏逻辑,一步步构建这个经典游戏

🎮 游戏预览与功能

这个贪吃蛇游戏具有以下特点:

  • 炫酷的霓虹 灯风格UI
  • 流畅的蛇身移动动画
  • 粒子特效食物收集效果
  • 本地存储最高分记录
  • 响应式设计适配各种屏幕

完全放手给TraeBuilder Mcp搭建框架!!!

🏗️ HTML结构搭建

💬 「请创建一个基于 HTML 和原生 JavaScript 的项目,名字叫做《贪吃蛇-永远饿》。 这个项目的核心玩法去操作游戏精髓是:

  1. Canvas绘图的基本原理
  2. 游戏循环的实现方式
  3. 面向对象的游戏设计模式
  4. 粒子特效的实现
  5. 本地存储的应用
  6. 键盘控制的实现
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();

🚀 游戏特色实现

  1. 流畅的蛇身移动 :通过history数组记录蛇身每一节的位置历史,实现平滑的移动效果。

  2. 粒子特效:吃到食物时生成20个随机方向的粒子,增加游戏视觉效果。

  3. 本地存储最高分 :使用localStorage保存玩家的最高分记录。

  4. 防止180度转向:在键盘监听中加入了方向判断,防止蛇头直接反向移动。

  5. 自适应网格 :根据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 功能,打造你的创意项目,无论你是编程新手还是技术大牛,这里都是你的舞台!

相关推荐
sean10 小时前
开发一个自己的 claude code
前端·后端·ai编程
云起SAAS11 小时前
ai公司起名取名抖音快手微信小程序看广告流量主开源
微信小程序·小程序·ai编程·看广告变现轻·ai公司起名取名
后端小肥肠13 小时前
效率狂飙!n8n 无人值守工作流,每天自动把领域最新热点做成小红书卡片存本地
人工智能·agent·mcp
trsoliu15 小时前
2025前端AI Coding产品与实战案例大盘点
前端·ai编程
猪猪拆迁队15 小时前
前端图形架构设计:AI生成设计稿落地实践
前端·后端·ai编程
豆包MarsCode18 小时前
快速上手|从版本选择到项目实战
trae
蛋先生DX21 小时前
AI 友好的云开发 MySQL SDK 它来了!微信小程序能直连关系型数据库了
mysql·ai编程·小程序·云开发
薛晓刚1 天前
AI好像除了不能解决业务问题,其他问题都能解决
ai编程
前端双越老师1 天前
建议应届毕业生不要再做前端开发了
人工智能·面试·ai编程
华洛1 天前
聊一下如何稳定的控制大模型的输出格式
前端·产品经理·ai编程