# 地图系统 **本文档引用的文件** - [GameMap.ts](file://assets/script/game/map/GameMap.ts) - [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts) - [Mon.ts](file://assets/script/game/hero/Mon.ts) - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts) - [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts) - [map.json](file://assets/resources/config/map/map.json) - [map_delivery.json](file://assets/resources/config/map/map_delivery.json) - [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts) - [heroSet.ts](file://assets/script/game/common/config/heroSet.ts) - [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts) - [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts) - [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts) - [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts) ## 目录 1. [引言](#引言) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构概述](#架构概述) 5. [详细组件分析](#详细组件分析) 6. [依赖分析](#依赖分析) 7. [性能考虑](#性能考虑) 8. [故障排除指南](#故障排除指南) 9. [结论](#结论) ## 引言 本文档详尽描述了基于Cocos引擎的《英雄》游戏项目中地图系统的整体架构与运行机制。系统涵盖关卡设计、怪物生成、战斗区域管理及视图渲染等核心功能。通过分析`GameMap.ts`中的地图主控制器职责,结合`RogueConfig.ts`解释随机关卡生成逻辑,深入剖析`Mon.ts`中怪物实体的设计模式及其与英雄的交互方式。同时,阐述`MapModelComp.ts`与`MapViewComp.ts`如何实现数据与表现层的分离,并结合`map.json`和`map_delivery.json`配置文件说明地图数据结构与关卡参数定义。最后,提供实例说明如何添加新关卡、配置怪物波次及实现战斗区域判定。 ## 项目结构 ```mermaid graph TD subgraph "Assets" subgraph "resources" subgraph "config" subgraph "map" map_json["map.json"] map_delivery_json["map_delivery.json"] end end end subgraph "script" subgraph "game" subgraph "map" GameMap_ts["GameMap.ts"] RogueConfig_ts["RogueConfig.ts"] MissionMonComp_ts["MissionMonComp.ts"] subgraph "model" MapModelComp_ts["MapModelComp.ts"] end subgraph "view" MapViewComp_ts["MapViewComp.ts"] MapViewScene_ts["MapViewScene.ts"] subgraph "layer" MapLayer_ts["MapLayer.ts"] EntityLayer_ts["EntityLayer.ts"] SkillLayer_ts["SkillLayer.ts"] end end end subgraph "hero" Mon_ts["Mon.ts"] MonModelComp_ts["MonModelComp.ts"] end subgraph "common" subgraph "config" heroSet_ts["heroSet.ts"] end end end end end ``` **图示来源** - [map.json](file://assets/resources/config/map/map.json) - [map_delivery.json](file://assets/resources/config/map/map_delivery.json) - [GameMap.ts](file://assets/script/game/map/GameMap.ts) - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts) - [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts) - [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts) - [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts) - [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts) - [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts) **本节来源** - [GameMap.ts](file://assets/script/game/map/GameMap.ts) - [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts) - [Mon.ts](file://assets/script/game/hero/Mon.ts) - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts) - [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts) - [map.json](file://assets/resources/config/map/map.json) - [map_delivery.json](file://assets/resources/config/map/map_delivery.json) ## 核心组件 地图系统的核心由多个组件构成,实现了数据与逻辑的分离。`GameMap`作为地图主控制器,负责协调地图模型与视图。`MapModelComp`封装了地图的静态数据,如初始地图ID和资源路径。`MapViewComp`则负责地图的显示逻辑,通过`MapViewScene`管理地图层、实体层和技能层。`RogueConfig.ts`定义了随机关卡的生成规则,包括怪物类型、数量和强度的动态调整。`Mon.ts`实现了怪物实体的加载与初始化,支持根据关卡进度调整属性强度。 **本节来源** - [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35) - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42) - [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44) - [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L310) - [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108) ## 架构概述 ```mermaid classDiagram class GameMap { +MapModel : MapModelComp +MapView : MapViewComp +init() : void +load() : void } class MapModelComp { +id : number +resPrefab : string +reset() : void } class MapViewComp { +scene : MapViewScene +game_timer : Timer +onLoad() : void +start() : void +reset() : void +update(dt : number) : void } class MapViewScene { +camera : Camera +layer : Node +mapLayer : MapLayer +floorLayer : Node +entityLayer : EntityLayer +SkillLayer : SkillLayer +isFollowPlayer : boolean +ratio : Vec2 +onLoad() : void +start() : void +reset() : void +init() : void +update(dt : number) : void } class MapLayer { +bgImg : Sprite +init() : void +clear() : void +bgImage : Sprite +width : number +height : number } class EntityLayer { +timer : Timer +update(dt : number) : void +start() : void +clear() : void } class SkillLayer { +timer : Timer +light : Prefab +onLoad() : void +doSkill() : void +update(dt : number) : void +start() : void +clear() : void } GameMap --> MapModelComp : "包含" GameMap --> MapViewComp : "包含" MapViewComp --> MapViewScene : "引用" MapViewScene --> MapLayer : "引用" MapViewScene --> EntityLayer : "引用" MapViewScene --> SkillLayer : "引用" ``` **图示来源** - [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35) - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42) - [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44) - [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76) - [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L46) - [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38) - [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L47) ## 详细组件分析 ### 地图主控制器分析 `GameMap`类是地图系统的主控制器,使用ECS(实体-组件-系统)架构模式。它继承自`ecs.Entity`,并注册为`GameMap`实体。该类包含两个核心组件:`MapModel`(数据模型)和`MapView`(视图组件)。`init`方法在实体初始化时被调用,用于添加`MapModelComp`组件。`load`方法负责加载地图的显示资源,通过资源管理器异步加载地图预制件,并将其挂载到游戏根节点下,最后将地图视图组件添加到当前实体。 #### 对象导向组件 ```mermaid classDiagram class GameMap { +MapModel : MapModelComp +MapView : MapViewComp +init() : void +load() : void } class MapModelComp { +id : number +resPrefab : string +reset() : void } GameMap --> MapModelComp : "包含" ``` **图示来源** - [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35) - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42) **本节来源** - [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35) - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42) ### 随机关卡生成逻辑分析 `RogueConfig.ts`文件定义了随机关卡的生成规则。系统通过`getStageType`函数根据关卡号和等级决定关卡类型(普通、精英、Boss、事件)。`generateStageConfig`函数根据关卡类型生成怪物类型数组,`calculateMonsterCount`函数根据关卡进度动态调整怪物数量,`calculateMonsterStrengthMultiplier`函数计算怪物强度倍率。`getStageMonsterConfigs`函数综合以上逻辑,生成包含怪物UUID、类型和强度倍率的完整配置。 #### API/服务组件 ```mermaid sequenceDiagram participant Game as "游戏逻辑" participant RogueConfig as "RogueConfig" participant MissionMonComp as "MissionMonComp" Game->>RogueConfig : getStageType(stageNumber, level) RogueConfig-->>Game : 返回关卡类型 Game->>RogueConfig : generateStageConfig(stageNumber, level) RogueConfig-->>Game : 返回怪物类型数组 Game->>RogueConfig : calculateMonsterCount(...) RogueConfig-->>Game : 返回实际数量 Game->>RogueConfig : calculateMonsterStrengthMultiplier(...) RogueConfig-->>Game : 返回强度倍率 Game->>RogueConfig : getStageMonsterConfigs(...) RogueConfig-->>Game : 返回完整怪物配置 Game->>MissionMonComp : do_mon_wave() MissionMonComp->>MissionMonComp : generateMonstersFromStageConfig() MissionMonComp->>MissionMonComp : addToStageSpawnQueue() loop 每个怪物 MissionMonComp->>MissionMonComp : spawnNextMonster() MissionMonComp->>Monster : load() end ``` **图示来源** - [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L310) - [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L239) **本节来源** - [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L310) - [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L239) ### 怪物实体设计模式分析 `Mon.ts`文件定义了`Monster`类,代表游戏中的怪物实体。该类同样基于ECS架构,包含`HeroModel`(模型组件)、`HeroView`(视图组件)和`BattleMove`(战斗移动组件)。`load`方法负责加载怪物的预制件并初始化其位置和属性。`hero_init`方法根据怪物UUID从`HeroInfo`配置中获取基础属性,并根据强度倍率进行调整。怪物的技能、属性和状态均在此方法中初始化。 #### 复杂逻辑组件 ```mermaid flowchart TD Start([怪物加载]) --> Load["load(pos, scale, uuid, is_boss)"] Load --> GetPrefab["获取预制件路径"] GetPrefab --> Instantiate["实例化预制件"] Instantiate --> SetParent["设置父节点为entityLayer"] SetParent --> Init["调用hero_init初始化"] Init --> GetHeroInfo["从HeroInfo获取基础属性"] GetHeroInfo --> AdjustAttrs["根据strengthMultiplier调整属性"] AdjustAttrs --> InitSkills["初始化技能数组"] InitSkills --> AddComponent["将HeroViewComp添加到实体"] AddComponent --> SetMove["设置BattleMove参数"] SetMove --> Dispatch["派发monster_load事件"] Dispatch --> End([怪物加载完成]) ``` **图示来源** - [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108) - [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L151) **本节来源** - [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108) - [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L151) ### 数据与表现层分离分析 地图系统严格遵循MVC(模型-视图-控制器)设计模式,实现了数据与表现的分离。`MapModelComp`作为模型层,仅负责存储地图的静态数据,如地图ID和资源路径。`MapViewComp`作为视图层,负责地图的显示和用户交互。`MapViewScene`作为视图的具体实现,管理地图的各个显示层(背景层、实体层、技能层)。这种分离使得数据逻辑与显示逻辑解耦,提高了代码的可维护性和可测试性。 ```mermaid classDiagram class MapModelComp { +id : number +resPrefab : string } class MapViewComp { +scene : MapViewScene } class MapViewScene { +mapLayer : MapLayer +entityLayer : EntityLayer +SkillLayer : SkillLayer } MapModelComp --> MapViewComp : "数据驱动" MapViewComp --> MapViewScene : "控制" MapViewScene --> MapLayer : "显示" MapViewScene --> EntityLayer : "显示" MapViewScene --> SkillLayer : "显示" ``` **图示来源** - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42) - [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44) - [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76) **本节来源** - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42) - [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44) - [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76) ### 地图数据结构与关卡参数分析 地图数据由两个JSON文件定义:`map.json`和`map_delivery.json`。`map.json`定义了地图的基本信息,包括地图ID、名称和转场点。`map_delivery.json`定义了地图转场的具体参数,包括转场点ID、所在地图ID、触发位置、目标地图ID和目标地图的起始位置。这种设计支持非线性关卡流程,玩家可以通过不同的转场点进入不同的地图。 ```mermaid erDiagram MAP { string id PK string name string delivery } MAP_DELIVERY { string id PK string mapId FK string pos string toMapId string start } MAP ||--o{ MAP_DELIVERY : "包含" ``` **图示来源** - [map.json](file://assets/resources/config/map/map.json#L1-L11) - [map_delivery.json](file://assets/resources/config/map/map_delivery.json#L1-L29) **本节来源** - [map.json](file://assets/resources/config/map/map.json#L1-L11) - [map_delivery.json](file://assets/resources/config/map/map_delivery.json#L1-L29) ## 依赖分析 ```mermaid graph TD GameMap_ts --> MapModelComp_ts GameMap_ts --> MapViewComp_ts MapViewComp_ts --> MapViewScene_ts MapViewScene_ts --> MapLayer_ts MapViewScene_ts --> EntityLayer_ts MapViewScene_ts --> SkillLayer_ts MissionMonComp_ts --> RogueConfig_ts MissionMonComp_ts --> Mon_ts Mon_ts --> heroSet_ts RogueConfig_ts --> heroSet_ts ``` **图示来源** - [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35) - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42) - [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44) - [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76) - [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L46) - [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38) - [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L47) - [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L239) - [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L310) - [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108) - [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L151) **本节来源** - [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35) - [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L42) - [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L44) - [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L76) - [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L46) - [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L38) - [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L47) - [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L239) - [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L1-L310) - [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108) - [heroSet.ts](file://assets/script/game/common/config/heroSet.ts#L1-L151) ## 性能考虑 地图系统在性能方面进行了合理的设计。视图层的更新通过`update`方法每帧执行,但关键的实体排序逻辑被注释,表明开发者意识到性能问题并考虑优化。怪物生成采用队列机制,通过`spawnInterval`控制生成频率,避免一次性生成过多怪物导致性能骤降。地图资源采用异步加载,防止主线程阻塞。建议进一步优化实体层的深度排序,考虑使用空间分区或仅在必要时排序。 ## 故障排除指南 - **地图无法加载**:检查`MapModelComp`中的`resPrefab`路径是否正确,确保预制件存在于资源目录中。 - **怪物未生成**:确认`MissionMonComp`是否监听了`FightReady`事件,检查`monsterQueue`是否正确填充。 - **属性未按倍率调整**:确保`Mon.ts`中的`hero_init`方法正确接收并应用`strengthMultiplier`参数。 - **转场无效**:验证`map_delivery.json`中的`pos`和`start`坐标格式是否正确,确保触发位置与玩家位置匹配。 **本节来源** - [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L35) - [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L1-L239) - [Mon.ts](file://assets/script/game/hero/Mon.ts#L1-L108) - [map_delivery.json](file://assets/resources/config/map/map_delivery.json#L1-L29) ## 结论 本文档全面分析了Cocos游戏项目中的地图系统架构。系统采用ECS和MVC设计模式,实现了良好的代码分离和可扩展性。随机关卡生成逻辑灵活,支持动态调整怪物数量和强度。数据与表现层分离清晰,便于维护和迭代。通过合理使用配置文件,实现了关卡数据的外部化管理。整体架构设计合理,为游戏的长期发展奠定了坚实基础。