# 游戏状态管理系统设置指南 本指南将帮助你在Cocos Creator中正确设置游戏状态管理系统,实现血量监控和胜利失败UI显示功能。 ## 📋 前置条件 确保你的场景中已经有以下节点结构: ``` Canvas/ ├── GameLevelUI/ │ ├── HeartNode/ │ │ └── HeartLabeld (Label组件,显示血量) │ ├── EnemyController (挂载EnemyController脚本) │ └── GameManager (挂载增强版GameManager脚本) ├── GameSuccess (游戏成功UI,初始设为不激活) └── GameDefeat (游戏失败UI,初始设为不激活) ``` ## 🔧 设置步骤 ### 1. 配置增强版GameManager组件 在 `Canvas/GameLevelUI/GameManager` 节点的Inspector面板中设置以下属性: **原GameManager属性:** - **Ball Controller**: 拖入BallController节点 - **Block Selection UI**: 拖入BlockSelectionUI节点 - **Game Area**: 拖入GameArea节点 - **Enemy Manager**: 拖入EnemyController节点 **游戏状态管理属性:** - **Heart Label Node**: 拖入 `Canvas/GameLevelUI/HeartNode/HeartLabeld` 节点 - **Game Success UI**: 拖入 `Canvas/GameSuccess` 节点 - **Game Defeat UI**: 拖入 `Canvas/GameDefeat` 节点 **游戏配置属性:** - **Wall Health**: 设置墙体初始血量(如1200) - **Initial Health**: 设置初始血量(如100) - **Check Interval**: 设置检查间隔(建议1.0秒) ### 2. 设置成功失败UI按钮 #### GameSuccess UI 按钮结构 ``` Canvas/GameSuccess/ ├── NextLevelBtn (Button组件) ├── RestartBtn (Button组件) ├── MainMenuBtn (Button组件) └── ShopBtn (Button组件) ``` #### GameDefeat UI 按钮结构 ``` Canvas/GameDefeat/ ├── RestartBtn (Button组件) ├── MainMenuBtn (Button组件) ├── ShopBtn (Button组件) └── ReviveBtn (Button组件) ``` **注意**: 按钮节点名称必须严格按照上述命名,脚本会根据名称自动查找和绑定事件。 ### 3. 初始化其他管理器 确保场景中有以下管理器节点: 1. **LevelManager**: 在某个持久节点上挂载 `LevelManager` 脚本 2. **ShopManager**: 在某个持久节点上挂载 `ShopManager` 脚本 3. **ConfigManager**: 在某个持久节点上挂载 `ConfigManager` 脚本 ## 🎮 工作流程 ### 血量监控流程 1. `GameManager` 每秒检查 `HeartLabeld` 的文本内容 2. 从文本中提取数字作为当前血量 3. 当血量降为0时,自动触发游戏失败 ### 敌人检测流程 1. `GameManager` 通过 `EnemyController` 获取当前敌人数量 2. 当敌人数量为0时,自动触发游戏成功 ### UI交互流程 1. 游戏结束时显示对应的成功/失败UI 2. `GameManager` 处理所有按钮点击事件 3. 按钮功能包括:下一关、重新开始、返回主菜单、商店、复活等 ## 🔍 调试功能 ### GameManager调试方法 ```typescript // 在控制台或其他脚本中调用 const gameManager = find('Canvas/GameLevelUI/GameManager').getComponent('GameManager'); // 强制触发游戏成功 gameManager.forceGameSuccess(); // 强制触发游戏失败 gameManager.forceGameDefeat(); // 手动设置血量 gameManager.setHealth(50); // 造成伤害 gameManager.takeDamage(20); ``` ## ⚠️ 注意事项 1. **节点路径**: 确保所有节点路径与代码中的路径完全一致 2. **组件依赖**: GameManager依赖EnemyController,确保EnemyController正常工作 3. **UI初始状态**: GameSuccess和GameDefeat节点初始应设为不激活状态 4. **按钮命名**: UI按钮的节点名称必须与代码中的查找名称一致 5. **管理器实例**: LevelManager和ShopManager需要正确初始化为单例 6. **脚本位置**: 增强版GameManager脚本位于 `LevelSystem/GameManager.ts` ## 🎯 扩展功能 你可以根据需要扩展以下功能: 1. **音效支持**: 在胜利失败时播放音效 2. **动画效果**: 添加UI显示动画 3. **得分计算**: 实现更复杂的得分系统 4. **星级评定**: 根据表现给出星级评价 5. **成就系统**: 集成成就解锁功能 ## 🐛 常见问题 **Q: 血量检测不工作?** A: 检查HeartLabeld节点路径和Label组件是否正确设置 **Q: 按钮点击无响应?** A: 检查按钮节点命名是否正确,Button组件是否添加 **Q: 敌人检测不准确?** A: 确保EnemyController的getCurrentEnemyCount方法正常工作 **Q: 管理器获取失败?** A: 检查LevelManager和ShopManager是否正确初始化为单例 **Q: 找不到GameManager脚本?** A: 确保使用的是 `LevelSystem/GameManager.ts` 中的增强版GameManager # 武器方块系统集成指南 ## 概述 BlockManager 现在已经集成了武器系统,可以根据武器配置生成带有不同武器属性的方块。每个方块都关联一个武器配置,包含武器的视觉效果、属性和战斗参数。 ## 主要特性 ### 1. 基于武器配置的方块生成 - 不再随机选择预制体,而是基于武器配置生成方块 - 每个方块都关联一个随机的武器配置 - 支持不同稀有度的武器(common, uncommon, rare, epic, legendary) ### 2. 动态价格系统 - 方块价格根据武器稀有度自动设置 - 稀有度越高,价格越贵 - 价格映射: - common: 50 金币 - uncommon: 100 金币 - rare: 200 金币 - epic: 350 金币 - legendary: 500 金币 ### 3. 视觉效果 - 方块根据武器稀有度显示不同颜色 - 自动加载武器图标到方块的 Weapon 子节点 - 支持多种尺寸的武器图标 (1x1, 1x2, 2x1, 2x2) ### 4. 武器配置访问 - 每个方块保存完整的武器配置信息 - 提供公共接口获取方块的武器配置 - 支持通过武器ID获取配置信息 ## 使用方法 ### 1. 场景设置 确保场景中包含以下节点: - ConfigManager 实例(自动获取单例) - BlockManager 的所有必要引用(GridContainer, kuangContainer, coinLabelNode) - 方块预制体数组已正确设置 ### 2. 获取方块武器配置 ```typescript // 获取方块的武器配置 const weaponConfig = blockManager.getBlockWeaponConfig(blockNode); if (weaponConfig) { console.log(`武器名称: ${weaponConfig.name}`); console.log(`武器类型: ${weaponConfig.type}`); console.log(`武器稀有度: ${weaponConfig.rarity}`); console.log(`武器伤害: ${weaponConfig.stats.damage}`); } // 获取方块的武器ID const weaponId = blockManager.getBlockWeaponId(blockNode); ``` ### 3. 刷新方块 ```typescript // 重新生成三个新的武器方块 blockManager.refreshBlocks(); ``` ## 方块结构要求 方块预制体应该包含以下结构: ``` WeaponBlock (根节点) ├── B1 (主要方块节点) │ └── Weapon (武器图标节点,需要 Sprite 组件) └── Price (价格标签节点,可选) ``` ## 武器配置要求 武器配置文件需要包含以下信息: - 基本信息:id, name, type, rarity, weight - 属性信息:stats (damage, fireRate, range 等) - 视觉配置:visualConfig.weaponSprites (包含不同尺寸的图片路径) ## 注意事项 1. **配置加载时机**:方块生成会等待 ConfigManager 加载完成 2. **预制体兼容性**:确保方块预制体结构符合要求 3. **资源路径**:武器图标路径应该指向正确的 SpriteFrame 资源 4. **内存管理**:方块销毁时会自动清理武器配置映射 ## 扩展功能 ### 1. 自定义预制体选择 可以修改 `selectPrefabForWeapon` 方法来根据武器类型选择不同的预制体: ```typescript private selectPrefabForWeapon(weaponConfig: WeaponConfig): Prefab | null { // 根据武器类型选择预制体 switch (weaponConfig.type) { case 'rifle': return this.riflePrefab; case 'pistol': return this.pistolPrefab; default: return this.blockPrefabs[0]; } } ``` ### 2. 战斗效果集成 方块放置后,可以通过武器配置来设置战斗效果: ```typescript // 在方块放置成功后 const weaponConfig = this.getBlockWeaponConfig(block); if (weaponConfig) { // 设置攻击属性 block['attackDamage'] = weaponConfig.stats.damage; block['attackRange'] = weaponConfig.stats.range; block['fireRate'] = weaponConfig.stats.fireRate; } ``` ## 调试信息 系统会输出详细的调试信息: - 武器方块生成日志 - 武器图标加载状态 - 配置加载状态 - 价格设置信息 --- # 节点路径更改和拖拽属性设置指南 ## 📝 重要更新 ### PlacedBlocks 节点位置更改 - **旧路径**: `Canvas/PlacedBlocks` - **新路径**: `Canvas/GameLevelUI/PlacedBlocks` ### 新增拖拽属性配置 为了提高系统的灵活性和避免硬编码路径问题,现在所有关键节点都支持通过编辑器拖拽设置: #### 1. BlockManager 组件设置 在 `Canvas/GameLevelUI/BlockController` 节点上的 BlockManager 脚本中设置: **属性设置:** - **Grid Container**: 拖拽 `Canvas/GameLevelUI/GameArea/GridContainer` 节点 - **Kuang Container**: 拖拽 `Canvas/GameLevelUI/BlockSelectionUI/diban/kuang` 节点 - **Coin Label Node**: 拖拽 `Canvas/GameLevelUI/CoinNode/CoinLabel` 节点 - **Placed Blocks Container**: 拖拽 `Canvas/GameLevelUI/PlacedBlocks` 节点 ✨**新增** #### 2. EnemyController 组件设置 在 `Canvas/GameLevelUI/EnemyController` 节点上的 EnemyController 脚本中设置: **属性设置:** - **Enemy Prefab**: 拖拽敌人预制体 - **Enemy Container**: 拖拽 `Canvas/GameLevelUI/enemyContainer` 节点 ✨**新增** - **Wall Health Node**: 拖拽墙体血量显示节点 #### 3. BallController 组件设置 在球控制器脚本中设置: **属性设置:** - **Ball Prefab**: 拖拽小球预制体 - **Bullet Prefab**: 拖拽子弹预制体 - **Placed Blocks Container**: 拖拽 `Canvas/GameLevelUI/PlacedBlocks` 节点 ✨**新增** ## 🔧 自动兜底机制 如果未通过拖拽设置节点,系统会自动尝试查找: ### BlockManager 自动查找路径: - `placedBlocksContainer`: `Canvas/GameLevelUI/PlacedBlocks` ### EnemyController 自动查找路径: - `enemyContainer`: `Canvas/GameLevelUI/enemyContainer` ### BallController 自动查找路径: - `placedBlocksContainer`: `Canvas/GameLevelUI/PlacedBlocks` ## ✅ 优势 1. **灵活性**: 可以随时更改节点位置而不需要修改代码 2. **可维护性**: 避免硬编码路径,降低维护成本 3. **错误处理**: 提供自动查找机制作为备用方案 4. **可视化**: 编辑器中可以直观看到组件间的引用关系 ## ⚠️ 注意事项 1. **优先级**: 拖拽设置的节点优先于自动查找 2. **有效性检查**: 系统会检查节点是否有效,失效时会显示警告 3. **场景设置**: 确保在场景中正确创建了相应的节点结构 4. **兼容性**: 旧的硬编码路径仍可作为备用方案 ## 🛠️ 升级步骤 1. 确保场景中 PlacedBlocks 节点位于 `Canvas/GameLevelUI/` 下 2. 在各个管理器组件上设置对应的拖拽属性 3. 测试确保所有功能正常工作 4. 可选:移除不再需要的节点路径硬编码 --- # 小球启动流程配置指南 ## 🎮 新增功能:延迟小球启动 ### 功能说明 现在小球不会在游戏开始时自动出现和运动,而是等待玩家点击确定按钮后才开始: 1. **游戏加载时**: BallController 只进行初始设置,不创建小球 2. **放置方块阶段**: 玩家可以自由拖拽和放置方块 3. **点击确定按钮**: 小球才开始创建并开始运动,且避免与已放置方块重叠 ### 🔄 工作流程 #### 1. 游戏启动阶段 ``` GameLevel 场景加载 ↓ BallController.start() 执行 ↓ 只进行基础设置(calculateGameBounds, logCollisionMatrix) ↓ 等待确定按钮点击... ``` #### 2. 确定按钮点击后 ``` 用户点击 confirm 按钮 ↓ GameManager.onConfirmButtonClicked() 执行 ↓ GameManager.startGame() 执行 ↓ GameManager.spawnBall() 执行 ↓ BallController.startBall() 执行 ↓ 小球创建、定位(避开方块)、开始运动 ``` ### 🎯 关键组件方法 #### BallController 新增方法: - **`startBall()`**: 启动小球系统的主要方法 - 检查初始化状态 - 创建小球(如果需要) - 重新定位避开方块 - 设置物理组件 - 开始运动 - 设置运动状态标志 #### GameManager 修改的方法: - **`spawnBall()`**: 现在调用 `startBall()` 而不是 `initialize()` ### 🔧 技术实现 #### 状态管理: - `initialized`: 是否已初始化(创建小球但未运动) - `ballStarted`: 是否已开始运动 #### 避免重叠机制: - 小球创建时会调用 `positionBallRandomly()` - 自动检测已放置的方块位置 - 智能选择不重叠的生成位置 - 如果找不到合适位置,使用安全的默认位置 ### ⚙️ 配置要求 确保以下组件正确设置: #### GameManager 组件 - **Ball Controller**: 拖拽包含 BallController 脚本的节点 #### 确定按钮设置 - 按钮路径: `Canvas/GameLevelUI/BlockSelectionUI/diban/confirm` - 点击事件已绑定到 `GameManager.onConfirmButtonClicked()` ### 🎮 用户体验 1. **直观的游戏流程**: 玩家先放置方块,确定后小球才出现 2. **避免干扰**: 小球不会在方块放置阶段造成视觉干扰 3. **智能定位**: 小球自动避开已放置的方块 4. **即时反馈**: 点击确定按钮后立即看到小球开始运动 ### 🐛 故障排除 **Q: 点击确定按钮后小球没有出现?** A: 检查 GameManager 的 Ball Controller 属性是否正确设置 **Q: 小球出现但不运动?** A: 检查 BallController 的物理组件设置和碰撞矩阵配置 **Q: 小球与方块重叠?** A: 检查 PlacedBlocks 容器路径是否正确,确保方块已正确放置到容器中 **Q: 确定按钮点击无响应?** A: 检查按钮的点击事件绑定和 GameManager 组件设置