首页
学习
活动
专区
圈层
工具
发布
50 篇文章
1
Vibe Coding这一年:从“代码苦力”到“超级个体”,我如何把3天的工作压缩进2小时?
2
小程序项目架构设计与基础页面搭建(基础)
3
微信小程序送补贴!手把手教你薅免费云开发资源+混元Token(附使用教程)
4
如何创建一个有效的阅读清单?
5
踩坑记:Elasticsearch 索引写不进去了?可能是触碰了这个隐藏限制
6
RoLID-11K:面向小目标检测的行车记录仪路边垃圾数据集
7
mysql报错通用排查方法 排查MY-001312 can't return a result set in the given context
8
安装并使用谷歌AI编程工具Antigravity(亲测有效)
9
解密Prompt系列68. 告别逐词蹦字 - Transformer 的新推理范式
10
技术人的人生战略:在代码与成长中寻找平衡
11
JavaScript 文件分析与漏洞挖掘指南
12
多 Agent 视角下的自动驾驶系统设计:车端 Agent 与 RSU Agent 协同机制解析
13
构建AI智能体:潜藏秩序的发现:隐因子视角下的SVD推荐知识提取与机理阐释
14
告别浏览器!用Rust打造一键JSON处理神器
15
仅需1元,基于 LangChain 和腾讯混元大模型,实现知识图谱
16
轻量高效!用Docker运行Gogs,搭建属于你的私有GitHub
17
构建AI智能体:SVD知识整理与降维:从数据混沌到语义秩序的智能转换
18
2025年CodeBuddy是如何拯救职场危机中的我?
19
轻量化知识库方案:Docker部署Dokuwiki 的最佳实践
20
踩坑实录:别被 extended_bounds 骗了!ES 直方图聚合的边界陷阱
21
步履不停,共鸣常在:我的 2025 技术旅程与回响
22
构建AI智能体:从SVD的理论到LoRA的实践:大模型低秩微调的内在逻辑
23
[MYSQL] 恢复被drop/truncate的表
24
Sugo Protector 代码保护效果分析报告
25
前端平台大仓应用稳定性治理之路|得物技术
26
C++的5种高级初始化技术:从reserve到piecewise_construct等
27
HierLight-YOLO:面向无人机航拍的层次化轻量目标检测网络
28
金融服务领域的智能体革命:AI智能体解决方案、产业分析与技术实施的战略分析
29
大模型提示词-新手篇
30
2025,一个普通开发者的社区成长地图
31
“氛围编程”正让创意本身成为最终技能
32
AD域攻防权威指南:九.利用备份组获取域Hash
33
【跟着AI学】H5射击游戏开发实录:射击游戏
34
这一年,熬过许过夜,也有些许收获 | 2025年终总结
35
2025,一个技术徘徊者的AI工具真实答卷
36
告别手撸架构图!AI+Ooder实现漂亮架构+动态交互+全栈可视化实战指南
37
GitHub 霸榜:让你的 Claude 拥有“设计总监”级的品味,只要一行命令
38
构建AI智能体:AI古典文学:基于LoRA微调本地大模型打造唐诗生成器
39
拥抱人机共生,锻造不可替代的“金头脑”
40
[MYSQL] 5.7能否从ibdata1中提取出表DDL
41
Spring Boot 实战:手把手教你实现腾讯云 COS 对象存储文件上传
42
解密Prompt系列67. 智能体的经济学:从架构选型到工具预算
43
Google OCS光路解耦揭秘:寒武纪大爆发,从供应链双轨到CPO百万卡全光计算织物
44
未来已来 | 写给 .NET 开发者的 2025 年度总结
45
MYSQL实战:深入理解内存临时表优化
46
Ooder框架规范执行计划:企业级AI实施流程与大模型协作指南
47
openGauss 核心体系架构深度解析
48
架构视角:Jackson3新特性
49
LLM架构机制管窥:作为黑板的上下文窗口
50
LiveKit Agents 深度技术架构剖析
清单首页123文章详情

【跟着AI学】H5射击游戏开发实录:射击游戏

## 前言 在之前的文章中,我们介绍了如何借助AI编程助手来开发一个[H5扫雷游戏](https://cloud.tencent.com/developer/article/2609379) 。这次我们增加难度,尝试开发一个功能更完整的H5射击游戏。本文将完整记录从需求确认、技术方案设计、开发实现、测试调试到最终完成的完整过程,分享在AI协作开发中的经验、遇到的问题及解决方案。 > 注:本文所有代码和截图均为实际开发过程中的真实记录 --- ## 一、需求确认阶段:让AI理解我们的想法 ### 1.1 初始需求提出 不同于传统的直接编码,我们首先让AI帮助我们梳理需求。这种方式有两个好处: 1. AI会提供更全面的功能建议,避免遗漏 2. 通过交互确认,确保双方理解一致 **开发者**: > 我想开发一个H5的射击游戏,你帮我罗列下需求,我来确认和补充。 **AI生成的初始需求包含**: - **游戏类型**: 竖屏/横屏选择、太空射击/现代战争等风格 - **核心玩法**: 玩家控制、射击机制、关卡设计 - **游戏系统**: 武器升级、道具系统、生命值、分数系统 - **视觉特效**: 粒子效果、爆炸动画、UI界面 - **技术方案**: Canvas vs WebGL、响应式设计、性能优化 ![图1: 需求文档第一部分](https://developer.qcloudimg.com/http-save/yehe-6649301/e9f9bad00cd8156e5b1884ebe6072ca5.png) 初始需求文档非常详细,涵盖了游戏开发的方方面面。 ![图2: 需求文档第二部分](https://developer.qcloudimg.com/http-save/yehe-6649301/61d202958babfee39c660b83dfcb9ff8.png) ![图3: 需求文档第三部分](https://developer.qcloudimg.com/http-save/yehe-6649301/a8f2a0c1324ed9055ac0432746282f14.png) ### 1.2 需求细化与确认 虽然AI提供的需求很完善,但我们仍需根据实际需求进行确认和补充: **开发者**: > 我希望是一个竖屏的太空射击游戏,先制作20个关卡,难度逐级递增,此外上面所有的功能都要有,然后将完善后的技术方案存放到一个单独的文档中。 **AI响应**: - 确认为竖屏设计(375x667分辨率) - 20关卡自动生成配置 - 4级武器升级系统 - 4种敌人类型(小型、中型、Boss) - 4种道具系统(生命H、武器W、炸弹B、护盾S) - 连击系统、成就系统、本地存档 ![图4: 技术方案](https://developer.qcloudimg.com/http-save/yehe-6649301/fff742e87c2fc49ec43550f0c32b6424.png) AI创建了完整的技术方案文档,包含12个章节、20关卡详细配置、敌人类型表、道具掉落概率等。这份文档成为后续开发的指导蓝图。 ### 1.3 技术方案亮点 **自动生成的20关卡配置**: ```javascript // 自动生成关卡难度曲线 LEVEL_CONFIG: { WAVE_COUNT: [3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8], // 波次数量 SMALL_ENEMIES: [4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9], // 小型敌机 MEDIUM_ENEMIES: [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8], // 中型敌机 BOSS_LEVELS: [5, 10, 15, 20] // Boss关卡 } ``` **关键技术选型**: - Canvas 2D API(而非WebGL,降低复杂度) - ES6 Class面向对象设计 - 对象池模式(性能优化) - 本地存储(localStorage) --- ## 二、开发阶段:模块化设计与实现 ### 2.1 项目初始化 在我们确认需求后,AI开始初始化项目结构: **开发者**: > 现在开始项目初始化吧 **AI创建的目录结构**: ``` project/ ├── index.html # 入口文件,完整UI界面 ├── css/ │ └── style.css # 响应式样式 ├── js/ │ ├── config.js # 游戏配置(自动生成20关卡) │ ├── utils.js # 工具函数 │ ├── Game.js # 游戏主逻辑(500+行) │ ├── main.js # 入口脚本 │ └── classes/ # 游戏类模块 │ ├── GameObject.js # 基类 │ ├── Player.js # 玩家类 │ ├── Bullet.js # 子弹类 │ ├── Enemy.js # 敌人类 │ ├── Prop.js # 道具类 │ ├── Particle.js # 粒子类 │ └── Effect.js # 特效类 ├── assets/ # 资源文件(待补充) └── technical-spec.md # 技术方案 ``` ![图6: 项目初始化第一部分](https://developer.qcloudimg.com/http-save/yehe-6649301/98358e0558720d172b7a64434e9d49dd.png) 整个项目采用模块化设计,每个类职责清晰,便于维护和调试。 ![图7: 项目初始化第二部分](https://developer.qcloudimg.com/http-save/yehe-6649301/d1d0974146d63258d863f245ab4a7dac.png) ### 2.2 核心类实现 让我们看看AI实现的核心游戏机制: #### 对象池模式(性能优化) ```javascript class ObjectPool { constructor(factory, size) { this.pool = []; // 空闲对象 this.active = []; // 活跃对象 // 预创建对象 for (let i = 0; i < size; i++) { this.pool.push(factory()); } } acquire() { // 从池子中获取对象(避免new操作) if (this.pool.length > 0) { const obj = this.pool.pop(); this.active.push(obj); return obj; } console.warn('对象池耗尽!'); return null; } release(obj) { // 回收对象到池子 obj.active = false; const index = this.active.indexOf(obj); if (index !== -1) { this.active.splice(index, 1); this.pool.push(obj); } } } ``` 这个设计显著减少了垃圾回收(GC)压力,特别是对于子弹和粒子这类频繁创建销毁的对象。 #### 玩家系统(4级武器) ```javascript WEAPON.LEVELS = [ { bulletCount: 1, angles: [0] }, // Lv0: 单发 { bulletCount: 2, angles: [-15, 15] }, // Lv1: 双发 { bulletCount: 3, angles: [-15, 0, 15] }, // Lv2: 三发散射 { bulletCount: 5, angles: [-30, -15, 0, 15, 30] } // Lv3: 五发扇形 ]; ``` #### 敌人AI系统 ```javascript updateMovement(player) { switch (this.movementPattern) { case 'LINEAR': // 直线向下 this.vx = 0; this.vy = this.moveSpeed; break; case 'CURVE': // 正弦曲线 this.aiTimer++; this.vx = Math.cos(this.aiTimer * 0.1) * 5; this.vy = this.moveSpeed; break; case 'ZIGZAG': // Z字形 this.vx = (this.aiState ? -1 : 1) * this.moveSpeed * 0.5; if (this.x < 24 || this.x > 351) this.aiState ^= 1; this.vy = this.moveSpeed; break; case 'CHASE': // 追踪玩家 const angle = getAngle(this.x, this.y, player.x, player.y); this.vx = Math.cos(angle) * this.moveSpeed * 0.5; this.vy = this.moveSpeed * 0.8; break; } } ``` ### 2.3 任务管理 在整个开发过程中,AI会自动维护任务列表,确保每个模块都被实现: ![图8: 任务列表示例1](https://developer.qcloudimg.com/http-save/yehe-6649301/71fefbd663cb69138f18e2f69d5928d7.png) ![图9: 任务列表示例2](https://developer.qcloudimg.com/http-save/yehe-6649301/fd2b423c70f953e5cd105216d5f77442.png) **开发者的反馈方式**: 我们采用"等所有功能完成后再验证"的策略,避免反复测试影响开发效率。 **开发者**: > 继续创建Bullet类和Enemy类,等所有功能都完成后再体验 这种方式让AI能够专注于构建完整的游戏框架,而不是过早地陷入细节调试。 ![图10: 继续开发](https://developer.qcloudimg.com/http-save/yehe-6649301/433b6bec033bd9b1225aca1b92d7f4fe.png) ![图11: 功能完成](https://developer.qcloudimg.com/http-save/yehe-6649301/7755e26ad0226ea0c1394a600487c38f.png) --- ## 三、测试与调试:问题排查实录 ### 3.1 第一阶段:功能冒烟测试 游戏开发完成后,我们打开index.html进行测试: **现象**: 点击"开始游戏"按钮无反应 **问题**: 控制台报错 `ReferenceError: BulletManager is not defined` **开发者反馈**: > 按照你推荐的方式打开后,点击页面上的所有按钮都没有反应 **AI排查过程**: 1. 检查代码发现 `main.js` 中 `DOMContentLoaded` 事件被注释掉 2. 取消注释后重新测试 **现象**: 仍然报错 **问题**: 浏览器缓存了旧的JS文件 **开发者反馈**: > 控制台显示:main.js:36 ReferenceError: BulletManager is not defined **AI解决方案**: 添加版本号参数,强制刷新浏览器 ```html <!-- 修改前 --> <script src="js/config.js"></script> <!-- 修改后 --> <script src="js/config.js?v=1"></script> ``` 开发者进一步要求AI自行测试: **开发者**: > 这次修改好像还是没成功,你自己去测试吧,没问题后再告诉我,我再进行验证 ![图12: 游戏开发完成](https://developer.qcloudimg.com/http-save/yehe-6649301/027be33dd6b0daab74076012a0b29591.png) ### 3.2 经典Bug集锦 #### Bug #1: 黑屏问题 **现象**: 游戏开始后只看到UI,Canvas是黑色的 ![图13: 游戏运行截图](https://developer.qcloudimg.com/http-save/yehe-6649301/3e34e0c14fecb6c1f6c85141085cb749.png) **原因**: UI层 `.screen` 设置为不透明,遮挡了Canvas ```javascript // 修复方案 .screen { background: rgba(0, 0, 0, 0.5) !important; // 半透明 } #game-screen { background: transparent !important; // 完全透明 } ``` **思考**: 在Canvas游戏中,层级管理很重要。UI层应该只在需要时显示,且不能遮挡游戏画面。 #### Bug #2: 敌机不生成 **现象**: 日志显示"生成第1波敌人",但屏幕上看不到敌机 ``` [07:42:06.042] [INFO] 生成第1波敌人 - 类型: SMALL, 数量: 4 [07:42:06.042] [INFO] 生成敌人 - 类型: SMALL, 位置: (83, -50) ``` **排查过程**: 1. ✓ 日志显示调用成功 2. ✓ 绘制日志显示每帧都在绘制 3. ✗ 坐标y=-50(在屏幕上方,需要4秒才进入) 4. ✗ 游戏状态未正确重置(第二次开始后就不生成了) **根本原因**: `reset()` 方法未重置关卡控制变量 ```javascript // Bug代码 reset() { this.score = 0; this.level = 1; // 遗漏了: // this.waveCount = 0; // this.waveTimer = 0; // this.enemySpawnTimer = 0; } // 修复后 reset() { this.score = 0; this.level = 1; this.waveCount = 0; this.waveTimer = 0; this.enemySpawnTimer = 0; } ``` **思考**: 状态重置是游戏开发中的常见陷阱,特别是随着游戏复杂度增加,容易遗漏某些变量。 #### Bug #3: 对象残留问题 **现象**: 第一次游戏正常,第二次开始后敌机立即被摧毁 **原因**: 对象池中的子弹在(0,0)位置,新敌机生成时立即与残留的子弹碰撞 **解决方案**: 重置对象池,确保位置初始化 ```javascript // EnemyManager.createSmallEnemy() createSmallEnemy(x, y) { const enemy = this.smallEnemyPool.acquire(); // 显式设置所有属性 enemy.x = x; enemy.y = y; enemy.active = true; enemy.hp = ENEMY_CONFIG.TYPES.SMALL.hp; enemy.maxHp = ENEMY_CONFIG.TYPES.SMALL.hp; enemy.age = 0; return enemy; } ``` **思考**: 对象池模式虽然性能好,但需要手动管理对象生命周期,确保"脏数据"不会跨场景污染。 #### Bug #4: 玩家无法移动 **现象**: 玩家战机卡在屏幕底部中间,无法左右移动 **原因**: 边界限制参数错误 ```javascript // Bug代码 clampToBounds({ x: PLAYER_CONFIG.SIZE.WIDTH / 2, // 24 y: PLAYER_CONFIG.SIZE.HEIGHT / 2, // 24 width: CONFIG.CANVAS_WIDTH - PLAYER_CONFIG.SIZE.WIDTH, // 327 height: CONFIG.CANVAS_HEIGHT - PLAYER_CONFIG.SIZE.HEIGHT // 619 }) // 正确代码 clampToBounds({ x: 0, y: 0, width: CONFIG.CANVAS_WIDTH, // 375 height: CONFIG.CANVAS_HEIGHT // 667 }) ``` **思考**: 参数错误是编码中最难发现的Bug之一。良好的命名和清晰的API设计可以避免这类问题。 #### Bug #5: 敌机颜色不明显 **现象**: 敌机与深蓝色背景融合,难以看清 **修复方案**: 添加发光效果增强可见性 ```javascript // 小型敌机(红色) ctx.shadowBlur = 20; ctx.shadowColor = '#ff0000'; ctx.fillStyle = '#ff4444'; // 中型敌机(青色) ctx.shadowBlur = 25; ctx.shadowColor = '#00ffff'; ctx.fillStyle = '#44ffff'; ``` **思考**: 视觉效果是游戏体验的重要部分。即使功能正确,也需要良好的视觉反馈。 ### 3.3 测试工具链 AI在整个开发过程中创建了多个测试工具,帮助我们快速定位问题: **test.html**: 脚本加载测试 - 验证所有JS类是否正确加载 - 显示加载状态(✅/❌) **test-visual.html**: 视觉测试 - 验证敌机颜色(红色/青色发光) - 验证背景颜色(深蓝色) - 验证玩家移动 **test-control.html**: 触摸控制测试 - 简化版触摸控制验证 - 实时调试面板 **快速测试指南** 为了便于验证,AI创建了详细的快速测试文档: ```markdown ### 测试步骤 1. **强制刷新(关键!)** - Windows/Linux: Ctrl + Shift + R - Mac: Cmd + Shift + R 2. **打开开发者工具** 按 F12 → 切换到 Console → 勾选 Preserve log 3. **预期效果** - 2-3秒后顶部出现敌机(红色/青色发光三角形) - 触摸屏幕玩家战机跟随移动 - 蓝色子弹从战机向上发射 ``` 这些工具大大提高了调试效率。 --- ## 四、技术实现深度解析 ### 4.1 游戏架构设计 ``` ┌─────────────────────────────────────┐ │ main.js (入口文件) │ │ - 事件绑定 │ │ - UI交互 │ └──────────────┬──────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ Game.js (游戏主逻辑) │ │ ├─ 状态管理 (menu/playing/paused) │ │ ├─ 游戏循环 (60FPS) │ │ ├─ 关卡系统 │ │ └─ 碰撞检测 │ └──────────────┬──────────────────────┘ │ ┌──────┴──────┐ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ 对象管理器 │ │ 视觉层 │ │ - Player │ │ - Canvas │ │ - Bullet │ │ - CSS │ │ - Enemy │ │ - DOM │ │ - Prop │ │ │ │ - Particle │ │ │ └─────────────┘ └─────────────┘ ``` ### 4.2 关键技术点 #### 4.2.1 游戏循环设计 ```javascript gameLoop(currentTime) { // 计算时间差 const deltaTime = currentTime - this.lastTime; // 1. 更新游戏对象 this.player.update(); this.bulletManager.update(deltaTime); this.enemyManager.update(deltaTime, this.player); this.propManager.update(deltaTime); this.particleManager.update(deltaTime); // 2. 生成新敌人 this.updateEnemySpawning(); // 3. 碰撞检测 this.checkCollisions(); // 4. 渲染画面 this.render(); // 5. 更新UI this.updateUI(); // 6. 请求下一帧 requestAnimationFrame(this.gameLoop); } ``` **性能优化**: 使用 `requestAnimationFrame` 确保60FPS流畅体验,通过deltaTime实现帧率无关的逻辑更新。 #### 4.2.2 碰撞检测算法 ```javascript collidesWith(other) { const dx = this.x - other.x; const dy = this.y - other.y; const distance = Math.sqrt(dx * dx + dy * dy); return distance < (this.radius + other.radius); } ``` 使用圆形碰撞检测,计算两个对象中心点的距离是否小于半径之和。这种方法简单高效,适合射击游戏。 **优化思考**: 对于大量对象(100+子弹 vs 50+敌人),暴力检测的时间复杂度是O(n×m)。后续可以考虑空间分割优化(如四叉树)。 #### 4.2.3 对象池管理 **传统方案的问题**: ```javascript // 每次射击都创建新对象(触发GC) shoot() { const bullet = new Bullet(x, y); // 触发垃圾回收 this.bullets.push(bullet); } ``` **优化后的对象池**: ```javascript // 预创建100个子弹对象 bulletPool = new ObjectPool(() => new Bullet(), 100); shoot() { const bullet = bulletPool.acquire(); // 复用对象 bullet.reset(x, y); // 重置状态 } ``` **性能对比**: - 传统方案: 频繁创建/销毁对象 → 垃圾回收卡顿 - 对象池: 复用对象 → 稳定的帧率 在我们的游戏中,同时活跃的对象数量: - 子弹: 50-100个 - 敌机: 10-30个 - 粒子: 50-200个 - 道具: 0-5个 如果没有对象池,每帧都会触发多次垃圾回收,导致明显的卡顿。 #### 4.2.4 响应式设计 ```javascript resizeCanvas() { const aspectRatio = CONFIG.CANVAS_WIDTH / CONFIG.CANVAS_HEIGHT; if (window.innerWidth < window.innerHeight) { // 竖屏:高度占满 canvas.style.height = '100vh'; canvas.style.width = (window.innerHeight * aspectRatio) + 'px'; } else { // 横屏:显示提示 this.showRotatePrompt(); } } ``` **思考**: 移动端游戏必须考虑不同屏幕尺寸。我们固定游戏逻辑分辨率(375×667),通过CSS缩放适配不同设备。 ### 4.3 游戏平衡性设计 #### 难度曲线 ```javascript // 自动生成20关卡 for (let level = 1; level <= 20; level++) { const difficulty = Math.min((level - 1) / 19, 1); // 0到1 CONFIG.LEVELS[level] = { smallEnemies: Math.floor(4 + difficulty * 6), // 4-10个 mediumEnemies: Math.floor(difficulty * 8), // 0-8个 enemySpeed: 2 + difficulty * 3, // 2-5速度 enemyHp: 1 + Math.floor(difficulty * 3), // 1-4血量 propDropRate: 0.05 + difficulty * 0.1 // 5%-15%掉落率 }; } ``` **设计原则**: - 前期(1-5关):让玩家熟悉操作,难度平缓上升 - 中期(6-15关):增加敌人类型和数量,考验技巧 - 后期(16-20关):高强度弹幕,需要合理使用道具 #### 武器平衡 ```javascript WEAPON.LEVELS = [ { count: 1, interval: 10, damage: 1 }, // Lv0: 稳定输出 { count: 2, interval: 10, damage: 1 }, // Lv1: 双倍输出 { count: 3, interval: 8, damage: 1 }, // Lv2: 散射清场 { count: 5, interval: 6, damage: 1 } // Lv3: 扇形弹幕 ]; ``` **设计要点**: - 每级提升都有明显差异 - 高级武器射速更快,但单发伤害不变 - 散射适合清场,单发适合Boss战 --- ## 五、完整的调试与优化策略 ### 5.1 日志系统 ```javascript // 统一的日志函数 function gameLog(message, level = 'INFO') { const time = new Date().toLocaleTimeString('zh-CN', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' }); console.log(`[${time}][${level}] ${message}`); } // 使用示例 gameLog('游戏已开始'); gameLog('生成第1波敌人 - 类型: SMALL, 数量: 4'); gameLog('绘制敌人 - ID: a1b2c3d4e, 位置: (83, 150)'); ``` **日志输出示例**: ``` [07:42:05.071] [INFO] 游戏已开始 [07:42:06.042] [INFO] 生成第1波敌人 - 类型: SMALL, 数量: 4 [07:42:06.042] [INFO] 生成敌人 - 类型: SMALL, 位置: (83, -50) [07:42:06.042] [INFO] SmallEnemy创建 - ID: a1b2c3d4e, 位置: (83, -50) [Touch] 触摸事件 - 位置: (187, 450) [07:42:08.000] [INFO] Player位置更新 - 位置: (187, 567), 目标: (187, 450) [07:42:08.000] [INFO] 创建玩家子弹 - 位置: (187, 517), 速度: (0, -15) ``` **调试技巧**: 每60帧输出游戏状态统计 ```javascript if (this.gameFrame % 60 === 0) { const bullets = this.bulletManager.getAllBullets().filter(b => b.active).length; const enemies = this.enemyManager.getAllEnemies().filter(e => e.active).length; const particles = this.particleManager.active.length; const props = this.propManager.active.length; gameLog(`📊 游戏状态 - 帧: ${this.gameFrame}, 子弹: ${bullets}, 敌人: ${enemies}, 道具: ${props}, 粒子: ${particles}`); } ``` ### 5.2 可视化调试 #### 坐标网格(前5秒显示) 为了帮助定位敌机位置,添加了临时坐标网格: ```javascript drawDebugGrid(ctx) { if (this.gameFrame > 300) return; // 只显示5秒 ctx.strokeStyle = '#00ff00'; ctx.lineWidth = 1; ctx.globalAlpha = 0.2; // 绘制网格线 for (let x = 0; x <= CONFIG.CANVAS_WIDTH; x += 50) { ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, CONFIG.CANVAS_HEIGHT); ctx.stroke(); } for (let y = 0; y <= CONFIG.CANVAS_HEIGHT; y += 50) { ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(CONFIG.CANVAS_WIDTH, y); ctx.stroke(); } ctx.globalAlpha = 1; } ``` **作用**: 快速验证坐标系统是否正确,帮助定位绘制问题。 #### 碰撞体可视化 ```javascript drawCollisionBox(ctx) { ctx.strokeStyle = '#ff0000'; ctx.lineWidth = 2; // 绘制所有活跃对象的碰撞半径 [...this.bullets, ...this.enemies].forEach(obj => { ctx.beginPath(); ctx.arc(obj.x, obj.y, obj.radius, 0, Math.PI * 2); ctx.stroke(); }); } ``` ### 5.3 性能监控 ```javascript // Frame Time监控 let frameCount = 0; let lastFPSUpdate = 0; function monitorPerformance(currentTime) { frameCount++; if (currentTime - lastFPSUpdate >= 1000) { const fps = frameCount; frameCount = 0; lastFPSUpdate = currentTime; if (fps < 55) { console.warn(`⚠️ 帧率偏低: ${fps} FPS`); } console.log(`FPS: ${fps}`); } } ``` **性能指标**: - 目标: 60 FPS - 当前: 稳定在60 FPS(iPhone 8及以上设备) - 瓶颈: 粒子效果过多时会略有下降 **优化方向**: 1. 限制最多粒子数量(已实施,上限100个) 2. 减少发光效果(shadowBlur性能开销大) 3. 使用离屏Canvas缓存静态元素(星空背景) --- ## 六、完整的测试流程 ### 6.1 测试准备 在最终交付前,AI创建了一套完整的测试指南: **快速测试清单**: ```markdown #### ✅ 强制刷新(关键!) #### ✅ 打开开发者工具(F12) #### ✅ 开始游戏 #### ✅ 前5秒看到绿色坐标网格 #### ✅ 2-3秒后顶部出现敌机(红色/青色发光) #### ✅ 触摸屏幕战机跟随移动 #### ✅ 蓝色子弹向上发射 #### ✅ Console中有正常的日志输出 ``` **预期日志**: ``` [07:42:05.071] [INFO] 游戏已开始 [07:42:06.042] [INFO] 生成第1波敌人 - 类型: SMALL, 数量: 4 [07:42:06.042] [INFO] 生成敌人 - 类型: SMALL, 位置: (83, -50) [07:42:10.000] [INFO] 📊 游戏状态 - 帧: 300, 子弹: 8, 敌人: 4, 道具: 0, 粒子: 15 ``` ### 6.2 问题诊断流程 **如果看不到敌机**: 1. 检查"生成敌人"日志是否存在 2. 检查敌机位置(y坐标是否从-50开始,逐渐增大) 3. 等待5-10秒(移动速度2-4像素/帧) 4. 打开test-visual.html验证颜色和绘制 **如果玩家无法移动**: 1. 检查触摸事件日志("[Touch] 触摸事件") 2. 检查"Player位置更新"日志(位置是否变化) 3. 尝试键盘控制(方向键/WASD) 4. 检查边界限制参数 **如果子弹看不到**: 1. 检查"创建玩家子弹"日志(数量、位置) 2. 验证子弹速度(应为向上,y为负) 3. 检查test-visual.html验证颜色和发光效果 ### 6.3 测试工具 **视觉测试页面** (`test-visual.html`): 这个页面可以独立完成视觉验证,不需要游戏逻辑: ```javascript // 测试模式1:敌机测试 function runEnemyTest() { testMode = 'enemy'; enemyY = -50; console.log('🔴 敌机测试开始 - 应该看到红色发光三角向下移动'); } // 测试模式2:玩家测试 function runPlayerTest() { testMode = 'player'; console.log('🔵 玩家测试开始 - 触摸/点击Canvas移动蓝色战机'); } ``` **验证内容**: - ✓ 敌机颜色(红色vs青色) - ✓ 发光效果(shadowBlur) - ✓ 背景颜色(深蓝色) - ✓ 触摸响应 --- ## 七、项目成果与功能清单 ### 7.1 已实现功能 #### ✅ 核心玩法 - [x] 竖屏Canvas游戏(375×667分辨率) - [x] 触摸/鼠标/键盘三重控制 - [x] 自动射击系统 - [x] 60FPS游戏循环 - [x] 状态管理(菜单/游戏中/暂停/结束) #### ✅ 玩家系统 - [x] 战机移动和边界限制 - [x] 4级武器升级(单发→双发→三发散射→五发扇形) - [x] 生命值系统(3-5条命) - [x] 炸弹系统(清屏) - [x] 护盾系统(5秒无敌) - [x] 受伤无敌时间(闪烁效果) #### ✅ 敌人系统 - [x] 3种敌人类型(小型红色三角形/中型青色菱形/Boss紫色飞船) - [x] 4种AI移动模式(直线/曲线/Z字形/追踪) - [x] 5种射击模式(单发/三向散射/五向扇形/环形弹幕/追踪弹) - [x] 20关卡自动配置 - [x] 动态难度递增(敌机数量↑、速度↑、血量↑) - [x] 每5关自动生成Boss #### ✅ 道具系统 - [x] 4种道具(H-生命/W-武器/B-炸弹/S-护盾) - [x] 掉落概率控制(小型5%/中型15%/Boss100%) - [x] 拾取效果(发光动画) - [x] 上限限制(生命5/武器Lv3/炸弹5/护盾刷新) #### ✅ 视觉特效 - [x] 爆炸粒子效果(20个,重力模拟) - [x] 击中粒子效果(8个,火花效果) - [x] 拖尾粒子(子弹轨迹) - [x] 屏幕震动(强度可调) - [x] 受伤闪烁(红白交替) - [x] 星空背景(50颗星星滚动) - [x] 发光效果(shadowBlur) #### ✅ 游戏系统 - [x] 分数计算(基础+连击) - [x] 连击系统(3秒内连续击杀×2分数) - [x] 关卡完成检测 - [x] 游戏结束判定(生命为0) - [x] 本地存档(最高分、最高关卡) - [x] 成就系统(首胜、连击×10、通关20关等8个成就) #### ✅ UI界面 - [x] 开始菜单(开始游戏/排行榜/设置/说明) - [x] 游戏中HUD(分数/关卡/生命/武器/炸弹) - [x] 暂停菜单(继续/重开/返回) - [x] 结算界面(胜利/失败、分数统计) - [x] 排行榜(本地存储) - [x] 设置面板(音量控制) - [x] 游戏说明(操作指南) - [x] 横屏提示(提示用户旋转设备) ### 7.2 项目文件清单 **核心文件**: ``` ├── index.html # 主入口(完整UI) ├── js/ │ ├── config.js # 配置系统(自动生成20关卡) │ ├── utils.js # 工具函数库 │ ├── Game.js # 游戏主逻辑(500+行) │ ├── main.js # 入口脚本(事件绑定) │ └── classes/ │ ├── GameObject.js # 对象基类(对象池) │ ├── Player.js # 玩家类(武器系统) │ ├── Bullet.js # 子弹类(3种类型) │ ├── Enemy.js # 敌人类(3种+4AI) │ ├── Prop.js # 道具类(4种) │ ├── Particle.js # 粒子类(4种特效) │ └── Effect.js # 特效类(震动/闪烁) ├── css/ │ └── style.css # 响应式样式 └── assets/ # 资源文件(待补充) ``` **测试与文档**: ``` ├── test.html # 脚本加载测试 ├── test-visual.html # 视觉测试 ├── test-control.html # 控制测试 ├── technical-spec.md # 技术方案(12章) ├── 测试指南.md # 完整测试文档 ├── 快速测试.md # 快速验证清单 └── 开发过程记录.md # 完整开发记录 ``` ### 7.3 项目数据 | 指标 | 数量 | |------|------| | 开发时长 | 5-6小时 | | 代码行数 | 约3000行 | | JavaScript文件 | 12个 | | CSS文件 | 1个 | | HTML文件 | 1个 | | 测试文件 | 3个 | | 文档文件 | 4个 | | 已修复Bug | 9个 | | 游戏关卡 | 20个 | | 敌人类型 | 3种 | | 道具类型 | 4种 | | 武器等级 | 4级 | | AI移动模式 | 4种 | | Boss关卡 | 4个 | --- ## 八、开发经验与心得 ### 8.1 协作开发流程 #### 有效的工作模式 1. **需求先行**: 先让AI生成完整需求,再确认补充 - 避免反复修改 - 确保功能完整性 2. **任务驱动**: 使用TODO列表跟踪进度 - 每个模块独立任务 - 完成后标记确认 3. **反馈明确**: 遇到问题时提供具体信息 - 错误截图 - Console日志 - 复现步骤 4. **测试后置**: 功能完成后再统一测试 - 避免过早陷入细节 - 提高开发效率 - 但关键模块仍需早期验证 #### 避免的坑 1. **过早优化**: 先完成功能,再考虑优化 - 实际开发中,性能不是首要问题 - 对象池等优化可以提前设计 2. **过度设计**: 保持简单易用 - 不需要一开始就设计复杂的系统 - 随着需求迭代逐步完善 3. **忽视测试**: 测试工作同样重要 - AI可以生成代码,但需要人工验证 - 创建测试工具提高验证效率 ### 8.2 技术架构思考 #### 优点 1. **模块化设计**: 每个类职责清晰 - Player: 只关心玩家逻辑 - Enemy: 只关心敌人AI - Game: 协调所有模块 2. **配置驱动**: 参数集中在config.js - 便于调整平衡性 - 无需修改代码逻辑 3. **对象池模式**: 性能优化显著 - 60FPS稳定运行 - 无明显卡顿 4. **状态机管理**: 游戏状态清晰 - menu → playing → paused → gameover - 状态切换逻辑明确 #### 不足与改进 1. **缺少单元测试** - 所有功能都依赖手动测试 - 建议: 使用Jest等框架添加自动化测试 2. **代码重复** - 对象池管理代码在各Manager中重复 - 改进: 提取公共基类 3. **缺少类型检查** - JavaScript动态类型容易出错 - 建议: 使用TypeScript改进 4. **资源管理不完善** - 图片、音效资源未统一管理 - 改进: 创建ResourceManager ### 8.3 调试技巧总结 #### 问题排查方法论 1. **先日志,后断点**: 日志比断点高效 ```javascript console.log(`位置: (${x}, ${y}), 状态: ${state}`); ``` 2. **二分法定位**: 快速缩小问题范围 - 在代码中点加日志 - 判断问题在前半段还是后半段 - 重复直到找到问题 3. **隔离测试**: 创建最小复现环境 - test-visual.html独立于游戏逻辑 - 快速验证颜色、绘制、事件 4. **可视化调试**: 将抽象数据转为图形 - 坐标网格 - 碰撞半径 - 速度向量 #### AI协作调试 1. **提供完整上下文** - 错误截图 - 完整日志 - 相关代码 2. **让AI自行测试** - 当问题复杂时,让AI先自测 - 避免反复沟通 3. **创建测试工具** - 请求AI生成专门的测试页面 - 提高后续验证效率 ### 8.4 项目管理建议 #### 文档维护 1. **及时更新**: 代码与文档同步更新 2. **版本控制**: 使用Git管理代码 3. **变更记录**: 记录所有重要修改 #### 代码质量 1. **命名规范**: 使用有意义的变量名 2. **添加注释**: 复杂逻辑必须注释 3. **保持简洁**: 函数不超过50行 4. **避免魔法数字**: 使用配置常量 #### 版本迭代 **v1.0 (当前版本)**: - ✅ 完整游戏功能 - ✅ 20个关卡 - ✅ 所有系统正常 **v1.1 (短期优化)**: - [ ] 添加图片资源(精灵图) - [ ] 添加音效资源 - [ ] 优化移动端触摸 - [ ] 微调难度曲线 **v2.0 (功能扩展)**: - [ ] 无尽模式 - [ ] 皮肤系统 - [ ] 每日挑战 - [ ] 社交分享 --- ## 九、部署与运行 ### 9.1 本地运行 ```bash # 进入项目目录 cd /Users/mac/vscode/gpunexus/推广/射击 # 启动HTTP服务器(必须) python3 -m http.server 8000 # 浏览器访问 http://localhost:8000 ``` **为什么需要HTTP服务器?** - Chrome浏览器不允许file://协议加载多个JS文件 - 避免CORS问题 - 模拟真实部署环境 ### 9.2 生产部署 **方案1: GitHub Pages** ```bash git push origin main git subtree push --prefix dist origin gh-pages ``` **方案2: Netlify/Vercel** - 拖拽上传项目 - 自动部署 - CI/CD集成 **方案3: Nginx** ```nginx server { listen 80; root /path/to/project; index index.html; location / { try_files $uri $uri/ /index.html; } } ``` ### 9.3 资源优化 **图片优化**: - 使用TinyPNG压缩 - 合并精灵图(Spritesheet) - WebP格式(Chrome支持) **代码优化**: - Webpack打包(合并JS文件) - Terser压缩(去除注释、压缩变量名) - Babel转译(兼容旧浏览器) **性能优化**: - Gzip压缩(减少传输体积) - 浏览器缓存(静态资源缓存1年) - CDN加速(CDN分发) --- ## 结语 ### 项目总结 通过这次完整的H5射击游戏开发,我们成功实现了: ✅ **完整的需求分析** → AI生成详细技术方案 ✅ **模块化架构** → 12个JS文件,职责清晰 ✅ **完整的游戏系统** → 20关卡、道具、成就、存档 ✅ **丰富的视觉特效** → 粒子、发光、震动、闪烁 ✅ **多平台支持** → 触摸/鼠标/键盘控制 ✅ **性能优化** → 对象池、60FPS、响应式设计 ✅ **完整的测试体系** → 测试工具、日志系统、调试网格 ✅ **详尽的项目文档** → 技术方案、测试指南、开发记录 整个项目用时约5-6小时,解决了9个关键技术问题,创建了完整的工具链和文档体系。最终交付的是一个**可正常运行、体验流畅、功能完整的H5射击游戏**。 ### 开发者心得 #### 与AI协作的经验 1. **明确需求很重要**: 前期充分沟通,避免后期频繁修改 2. **任务拆分**: 复杂功能拆分成小任务,逐个击破 3. **及时反馈**: 发现问题立即反馈,提供完整上下文 4. **测试后置**: 功能完成后再测试,提高开发效率 5. **文档驱动**: 让AI生成文档,确保理解一致 #### AI的优势 - **快速原型**: 几小时完成基础框架 - **代码质量**: 规范的命名、清晰的结构 - **完整功能**: 不遗漏细节(如边界情况) - **自动优化**: 主动提出性能优化方案 - **持续迭代**: 根据反馈快速修复问题 #### AI的局限 - **缺乏直觉**: 不知道哪里容易出错 - **依赖反馈**: 不会主动测试和验证 - **需要引导**: 不明确表达需求时容易偏离 - **代码重复**: 有时会生成重复代码 #### 最佳实践 1. **先规划,后编码**: 让AI先写文档 2. **小步快跑**: 每个功能模块独立验证 3. **日志驱动**: 详细的日志输出 4. **工具辅助**: 创建专门的测试工具 5. **版本控制**: Git管理代码变更 > 🎮 **尾声**: 游戏开发是一场马拉松,而不是短跑。AI助手是我们的加速器,但创意、设计和细节打磨仍然需要开发者的智慧和耐心。

下一篇
举报
领券