尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用矩形相交算法构建碰撞检测迷你游戏:Web-Dev-For-Beginners 太空游戏第 4 课实战作业

用矩形相交算法构建碰撞检测迷你游戏:Web-Dev-For-Beginners 太空游戏第 4 课实战作业 用矩形相交算法构建碰撞检测迷你游戏Web-Dev-For-Beginners 太空游戏第 4 课实战作业【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners碰撞检测是游戏开发的核心机制之一它决定两个游戏对象何时相交、相交后触发什么事件以及对象如何被销毁或重生。在本仓库的 6-space-game 系列第 4 课中你已学习了基于矩形Axis-Aligned Bounding Box的分离测试算法而这份作业则要求你把理论转化为实践——从零打造一个自定义迷你游戏演示多种类型的对象交互。本文以该作业为骨架完整继承其全部要求、创意建议与评分标准并结合仓库中课程文档6-space-game/4-collision-detection/README.md和官方参考答案6-space-game/4-collision-detection/solution/app.js的源码实现深入讲解矩形相交检测、对象生命周期管理、事件驱动编程与武器冷却系统。读完本文你将能独立完成这份作业并理解一套可复用的、可用于物理模拟与交互式 Web 界面的碰撞检测模式。作业目标与项目要求作业的核心是应用你在课程中学到的碰撞检测知识创建一个定制迷你游戏演示不同类型的对象交互并通过创造性实现与实验来理解碰撞机制。具体项目要求如下多个可移动对象可通过键盘或鼠标控制基于矩形相交的碰撞检测系统使用课程中学习的矩形相交rectangle intersection原理碰撞发生时的视觉反馈对象销毁、颜色变化、特效等让碰撞有意义且引人入胜的游戏规则。提示课程的正式英文原版作业见 6-space-game/4-collision-detection/assignment.md丹麦语译本即 translations/da/6-space-game/4-collision-detection/assignment.md。两者内容一致可对照阅读。创意场景建议任选其一作业提供了五个可选场景它们都围绕碰撞这一核心玩法展开小行星带Asteroid field操控飞船穿越危险的太空碎片碰碰车Bumper cars创建一个基于物理的碰撞竞技场陨石防御Meteor defense保护地球免受来袭太空岩石的撞击收集游戏Collection game收集物品的同时躲避障碍物领土控制Territory control相互竞争的对象试图占领空间。这些场景对应了碰撞检测在真实游戏中的几类典型用途碰撞规避躲避、碰撞触发收集/得分、碰撞对抗防御/摧毁。无论选择哪个场景底层机制都是相同的——矩形边界与相交判定。技术实现要求四大核心能力作业要求你的解决方案必须演示以下四项能力它们与课程目标一一对应正确使用基于矩形的碰撞检测——这是整个作业的技术核心对应课程中的intersectRect算法用于用户输入的事件驱动编程——对应课程中的 EventEmitter 发布-订阅模式与键盘事件处理对象生命周期管理创建与销毁——对应课程中的 mark for deletion标记删除模式具有合适类结构的干净代码组织——对应课程中的GameObject/Hero/Enemy/Laser类继承体系。核心技术原理矩形表示与分离测试作业要求使用课程中学习的矩形相交原理其核心分为两步。1. 用矩形描述对象边界每个游戏对象都用一个轴对齐矩形包围盒表示。仓库答案代码中GameObject基类提供了标准的边界描述方法见 solution/app.jsrectFromGameObject() { return { top: this.y, left: this.x, bottom: this.y this.height, right: this.x this.width, }; }top上边界 对象纵坐标yleft左边界 对象横坐标xbottom下边界y heightright右边界x width。任何对象只要拥有位置(x, y)与尺寸(width, height)就能统一换算成这四个边界值从而参与碰撞判定。2. 分离测试算法Separation Test检测矩形相交时我们不做复杂的相交面积计算而是反向验证是否分离——这比直接计算相交更高效。课程文档给出的算法与仓库答案实现完全一致见 solution/app.jsfunction intersectRect(r1, r2) { return !( r2.left r1.right || r2.right r1.left || r2.top r1.bottom || r2.bottom r1.top ); }该算法依次检查四种分离条件矩形 2 完全在矩形 1 的右侧r2.left r1.right矩形 2 完全在矩形 1 的左侧r2.right r1.left矩形 2 完全在矩形 1 的下方r2.top r1.bottom矩形 2 完全在矩形 1 的上方r2.bottom r1.top。只要任一条件成立两矩形必然分离返回false未碰撞若四个条件全部不成立则两矩形必然重叠返回true碰撞。这一模式与雷达判定两架飞机是否处于安全距离、或航天器规避碎片时使用的几何判定逻辑同源可平移到任意 2D 交互场景。对象生命周期管理安全销毁模式作业要求实现对象生命周期管理创建和销毁。直接在被遍历的数组中删除对象会导致循环迭代错乱甚至崩溃因此课程与答案代码统一采用标记删除模式// 标记对象为死亡不立即删除 enemy.dead true;标记之后在下一次渲染前通过过滤清除gameObjects gameObjects.filter((go) !go.dead);这一模式的价值在于当前帧可以安全地继续执行完毕不会出现引用了已被移除对象的崩溃同时被销毁的对象会被及时回收避免内存膨胀。在答案代码的updateGameObjects()中碰撞处理与清理是分离的见 solution/app.js先逐一测试碰撞并发射事件最后统一filter清理正是这一原则的工程化体现。事件驱动架构用 EventEmitter 解耦碰撞响应作业要求的事件驱动编程对应仓库中的Pub-Sub发布-订阅模式。课程与答案代码维护一个消息常量表和极简的事件发射器const Messages { KEY_EVENT_UP: KEY_EVENT_UP, KEY_EVENT_DOWN: KEY_EVENT_DOWN, KEY_EVENT_LEFT: KEY_EVENT_LEFT, KEY_EVENT_RIGHT: KEY_EVENT_RIGHT, KEY_EVENT_SPACE: KEY_EVENT_SPACE, COLLISION_ENEMY_LASER: COLLISION_ENEMY_LASER, COLLISION_ENEMY_HERO: COLLISION_ENEMY_HERO, };class EventEmitter { constructor() { this.listeners {}; } on(message, listener) { /* 注册监听器 */ } emit(message, payload null) { /* 触发监听器 */ } }事件流的完整链条为键盘输入 → 发射事件 → 创建激光 → 碰撞检测 → 发射碰撞事件 → 处理碰撞结果。以太空游戏为例碰撞响应被注册为事件监听器见 solution/app.jseventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) { first.dead true; second.dead true; hero.incrementPoints(); });这种解耦设计的直接好处是碰撞检测逻辑只负责发现相交并报告至于相交后是销毁对象、加分、播放音效还是触发胜利判定都由独立的监听器处理——不同碰撞类型激光 vs 敌人、敌人 vs 英雄可以各自注册行为互不干扰。这正好呼应作业多个碰撞类型、不同行为的进阶要求。从课程示例到迷你游戏参考实现中的完整机制虽然作业要求你自创游戏但仓库的官方答案实现6-space-game/4-collision-detection/solution/app.js演示了一套可直接借鉴的完整机制可作为你开发迷你游戏的对照样板Laser 类自动移动 自管理生命周期class Laser extends GameObject { constructor(x, y) { super(x, y); this.width 9; this.height 33; this.type Laser; this.img laserImg; let id setInterval(() { if (this.y 0) { this.y - 15; } else { this.dead true; clearInterval(id); } }, 100); } }激光每 100ms 上移 15px触顶即自我标记为dead——对应作业中对象生命周期管理和离屏销毁的实现思路。Hero 类发射冷却系统fire() { gameObjects.push(new Laser(this.x 45, this.y - 10)); this.cooldown 500; let id setInterval(() { if (this.cooldown 0) { this.cooldown - 100; ... } }, 200); } canFire() { return this.cooldown 0; }冷却系统cooldown防止玩家无限连射开火后进入 500ms 冷却窗口canFire()为false时按键无效冷却归零后才允许再次发射。如果你选择陨石防御或小行星带这类射击题材这一机制可直接复用。updateGameObjects()集中式碰撞检测入口function updateGameObjects() { const enemies gameObjects.filter((go) go.type Enemy); const lasers gameObjects.filter((go) go.type Laser); // 测试英雄与敌人的碰撞发射 COLLISION_ENEMY_HERO // 测试激光与敌人的碰撞发射 COLLISION_ENEMY_LASER gameObjects gameObjects.filter((go) !go.dead); }该函数在游戏主循环window.onload中每 100ms 调用一次见 solution/app.js是整个碰撞系统的调度中枢。你的迷你游戏同样需要一个每帧执行一次碰撞检测 清理的入口函数。运行参考实现仓库提供了可直接运行的完整工程。进入your-work或solution目录执行npm start即可在http://localhost:5000启动本地服务器体验方向键移动英雄、空格键发射激光注意冷却限制、激光击中敌人后两者同时消失敌人撞到英雄会扣减生命值并最终触发胜负判定见 solution/package.json。额外挑战加分项作业鼓励在基础之上增强游戏粒子效果碰撞发生时产生粒子如爆炸碎片可参考课程 6-space-game/4-collision-detection/README.md 的 Challenge 提示利用游戏资源目录中的爆炸素材见 solution/spaceArt/readme.txt音效为不同类型的碰撞配置不同声音计分系统根据碰撞结果加分答案代码中hero.incrementPoints()每次击杀加 100 分并通过drawPoints()实时渲染多种碰撞类型不同对象对的碰撞产生不同行为渐进难度随时间推移加快对象速度或增加敌人生成频率。评分标准Rubric作业附带完整的评分表是自评与互评的权威依据务必逐项对照标准优秀Exemplary合格Adequate待改进Needs Improvement碰撞检测实现精确的矩形碰撞检测支持多种对象类型与精细的交互规则基础碰撞检测能正确处理简单对象交互碰撞检测存在问题或运行不稳定代码质量代码干净、组织良好具备合适的类结构、有意义的变量命名与恰当注释代码可运行但组织或文档化可更好代码难以理解或结构混乱用户交互响应灵敏的控制、流畅的游戏体验、清晰的视觉反馈与吸引人的机制基础控制可用反馈充分控制无响应或令人困惑创造力原创概念具备独特功能、视觉打磨与创新的碰撞行为标准实现含少量创意元素仅基础功能无创意增强对照此表确保你的碰撞检测能覆盖多种对象组合而非只有一种、代码具备清晰的类结构、控制反馈即时明确、玩法概念有原创性——这正是优秀档的四条基准线。学习路线延伸完成作业后可继续深入同一系列课程的后续内容6-space-game/5-keeping-score/README.md、6-space-game/6-end-condition/README.md实现完整的计分与胜负循环也可尝试课程文档中提出的进阶方向为英雄添加随机生成的能量道具PowerUp实现缩短冷却时间与临时护盾两类效果进一步检验你对事件驱动架构与对象生命周期管理的掌握程度。【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表