掘金 人工智能 前天 17:16
🐍 人人都是AI码农——游戏开发,全解析 | HTML+CSS+JS三件套
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文详细介绍了使用Trae编程实现炫酷贪吃蛇游戏的过程,从HTML结构、CSS样式到JavaScript游戏逻辑,逐步构建经典游戏。游戏具有霓虹灯风格UI、流畅的蛇身移动动画、粒子特效食物收集、本地存储最高分以及响应式设计等特点。文章还提供了游戏的HTML、CSS和JavaScript代码片段,并详细解释了游戏的核心模块,例如游戏初始化、辅助工具类、键盘控制、贪吃蛇类、食物类、粒子特效以及游戏主循环等。最后,文章还介绍了如何一键部署该项目到掘金平台,并提供了发布和分享的流程。

🐍 HTML 结构搭建:游戏基于HTML和原生JavaScript构建,包含游戏容器、重新开始按钮、分数显示区域和游戏画布容器。

🎨 CSS 样式设计:采用霓虹灯效果、动态背景GIF、Poppins字体以及按钮悬停动画,增强视觉效果。

🕹️ JavaScript 游戏逻辑:核心模块包括游戏初始化、辅助工具类(二维向量、碰撞检测、绘制网格、颜色转换)、键盘控制、贪吃蛇类、食物类、粒子特效和游戏主循环,实现游戏的核心功能。

🚀 游戏特色实现:通过history数组实现蛇身平滑移动、粒子特效增加视觉效果、使用localStorage保存最高分记录、防止180度转向以及自适应网格等功能。

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

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

🎮 游戏预览与功能

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

完全放手给TraeBuilder 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结构非常简单清晰:

🎨 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设计亮点:

🧠 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 功能,打造你的创意项目,无论你是编程新手还是技术大牛,这里都是你的舞台!

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

贪吃蛇游戏 JavaScript HTML CSS 游戏开发
相关文章