Files
pixelheros/.qoder/repowiki/zh/content/地图系统/地图视图/地图视图.md
panw 4235e3b776 refactor(game): 移除已弃用的事件常量
- 删除 UpdateHero 和 UpdateFightHero 事件
- 移除 MISSION_UPDATE 事件常量
- 优化游戏事件枚举定义
2025-10-28 16:15:47 +08:00

269 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 地图视图
<cite>
**本文档引用的文件**
- [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)
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts)
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
- [map.json](file://assets/resources/config/map/map.json)
</cite>
## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概述](#架构概述)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
## 引言
本文档深入解析 `MapViewComp` 作为地图表现层的核心作用,涵盖地图预制体加载、地图图层管理(背景、实体、技能等)以及 UV 动画效果的实现。结合 `MapView.ts``MapViewScene.ts` 阐述地图场景的构建流程与节点组织结构。分析 `MapLayer.ts``EntityLayer.ts` 如何实现分层渲染与实体挂载。阐述 `MoveUV.ts` 实现的动态纹理偏移技术用于模拟地图流动效果。最后提供自定义地图视觉风格、添加新图层及优化渲染性能的实践指南。
## 项目结构
项目结构清晰地将地图相关逻辑分离到 `assets/script/game/map/` 目录下,采用 MVC 模式组织代码。`model` 目录存放地图数据模型,`view` 目录存放视图组件和图层管理,`view/map/layer` 子目录进一步细化了不同图层的实现。
```mermaid
graph TB
subgraph "地图系统"
subgraph "模型层"
MapModelComp[MapModelComp.ts]
end
subgraph "视图层"
MapViewComp[MapViewComp.ts]
MapViewScene[MapViewScene.ts]
MoveUV[MoveUV.ts]
subgraph "图层组件"
MapLayer[MapLayer.ts]
EntityLayer[EntityLayer.ts]
SkillLayer[SkillLayer.ts]
end
end
subgraph "控制层"
GameMap[GameMap.ts]
end
end
MapViewComp --> MapViewScene
MapViewScene --> MapLayer
MapViewScene --> EntityLayer
MapViewScene --> SkillLayer
MapViewComp --> MoveUV
GameMap --> MapModelComp
GameMap --> MapViewComp
```
**Diagram sources**
- [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)
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts)
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
**Section sources**
- [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)
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts)
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
- [GameMap.ts](file://assets/script/game/map/GameMap.ts)
## 核心组件
`MapViewComp` 是地图表现层的核心组件,负责协调地图场景的初始化和生命周期管理。它通过 `MapViewScene` 组件访问各个地图图层,并在 `start` 方法中建立引用关系。`MapModelComp` 定义了地图的基本属性,如初始地图编号和地图显示预制体路径。`GameMap` 类作为 ECS 实体,整合了模型和视图组件,提供地图加载的入口方法。
**Section sources**
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
## 架构概述
地图系统采用基于 ECSEntity-Component-System架构的设计模式将地图数据Model、视图View和控制逻辑Controller分离。`GameMap` 实体持有 `MapModelComp``MapViewComp` 组件,实现了数据与表现的解耦。地图场景由 `MapViewScene` 组件管理,它通过属性装饰器关联了多个图层组件,包括 `MapLayer`(背景层)、`EntityLayer`(实体层)和 `SkillLayer`(技能层),形成了清晰的层次化结构。
```mermaid
classDiagram
class GameMap {
+MapModel : MapModelComp
+MapView : MapViewComp
+load() : void
}
class MapModelComp {
+id : number
+resPrefab : string
+reset() : void
}
class MapViewComp {
+scene : MapViewScene
+start() : void
+update(dt : number) : void
}
class MapViewScene {
+camera : Camera
+mapLayer : MapLayer
+entityLayer : EntityLayer
+SkillLayer : SkillLayer
+isFollowPlayer : boolean
+ratio : Vec2
+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
+clear() : void
}
class SkillLayer {
+light : Prefab
+doSkill() : void
+clear() : void
}
GameMap --> MapModelComp : "包含"
GameMap --> MapViewComp : "包含"
MapViewComp --> MapViewScene : "引用"
MapViewScene --> MapLayer : "引用"
MapViewScene --> EntityLayer : "引用"
MapViewScene --> SkillLayer : "引用"
```
**Diagram sources**
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L47)
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L48)
## 详细组件分析
### MapViewComp 分析
`MapViewComp` 组件作为地图视图的主控制器,负责地图场景的初始化和事件监听。在 `onLoad` 方法中,它可以监听全局事件,如角色添加或技能使用。`start` 方法中,它通过 `getComponent` 获取 `MapViewScene` 的引用,建立与地图场景的连接。该组件还包含一个 `Timer` 实例,可用于周期性任务的调度。
**Section sources**
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
### MapViewScene 分析
`MapViewScene` 组件是地图场景的核心逻辑容器,它通过 Cocos Creator 的属性系统(`@property`)将场景中的各个节点和组件关联起来。这包括摄像机(`camera`)、背景层(`mapLayer`)、实体层(`entityLayer`)和技能层(`SkillLayer`)。`isFollowPlayer` 属性控制摄像机是否跟随玩家移动。`reset` 方法用于清理各个图层的状态,确保地图切换时的干净环境。
```mermaid
sequenceDiagram
participant LoadingView as LoadingViewComp
participant GameMap as GameMap
participant MapView as MapViewComp
participant MapViewScene as MapViewScene
LoadingView->>GameMap : map.load()
GameMap->>Oops : oops.res.load(resPrefab)
Oops-->>GameMap : Prefab
GameMap->>GameMap : instantiate(res)
GameMap->>GameMap : add(map.getChildByName("map").getComponent(MapViewComp))
MapView->>MapView : start()
MapView->>MapView : getComponent(MapViewScene)
MapViewScene->>MapViewScene : 初始化各图层引用
```
**Diagram sources**
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
- [LoadingViewComp.ts](file://assets/script/game/initialize/view/LoadingViewComp.ts#L1-L90)
### MapLayer 分析
`MapLayer` 组件负责管理地图的背景图像。它通过 `@property(Sprite)` 装饰器引用一个 Sprite 组件(`bgImg`),用于显示地图背景。`init` 方法根据背景图的尺寸设置自身的宽高,`clear` 方法则用于清除当前的背景图片。`width``height` 属性通过访问 `bgImg``UITransform` 组件来获取实际尺寸。
**Section sources**
- [MapLayer.ts](file://assets/script/game/map/view/map/layer/MapLayer.ts#L1-L47)
### EntityLayer 分析
`EntityLayer` 组件管理地图上的所有游戏实体,如角色、怪物等。其 `update` 方法中包含一个定时器(`timer`),可用于定期执行深度排序等操作,以确保实体的正确渲染顺序。`clear` 方法遍历并清理所有子节点,为地图切换做准备。注释中提到深度排序可能成为性能瓶颈,建议在必要时优化为非每帧执行。
**Section sources**
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
### MoveUV 分析
`MoveUV` 组件实现了动态纹理偏移效果,用于模拟水流、云层移动等视觉效果。它通过 `moveSpeedX``moveSpeedY` 属性控制纹理在 X 和 Y 方向上的移动速度。在 `update` 方法中,它获取 `Sprite` 组件的 `spriteFrame`,修改其 `rect``x``y` 值,从而实现 UV 坐标的偏移。`wrapMode` 属性确保纹理在边缘处重复,形成无缝滚动效果。
```mermaid
flowchart TD
Start([MoveUV.update]) --> GetSprite["获取Sprite组件"]
GetSprite --> CheckWrapMode{"WrapMode变化?"}
CheckWrapMode --> |是| UpdateWrap["更新纹理WrapMode"]
CheckWrapMode --> |否| UpdateRect["更新Rect坐标"]
UpdateWrap --> UpdateRect
UpdateRect --> ApplyRect["设置spriteFrame.rect"]
ApplyRect --> MarkUpdate["标记渲染数据更新"]
MarkUpdate --> End([结束])
```
**Diagram sources**
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L50)
## 依赖分析
地图系统依赖于 Cocos Creator 引擎的核心模块(如 `cc`),以及项目中的 `oops-plugin-framework` 框架。`MapViewComp``MapViewScene` 依赖于 `oops` 对象进行资源加载和消息通信。`EntityLayer``SkillLayer` 依赖于框架中的 `Timer` 类。各图层组件之间通过 `MapViewScene` 进行协调,没有直接的相互依赖,保证了模块的独立性。
```mermaid
graph LR
MapViewComp --> oops[Oops Framework]
MapViewScene --> oops
EntityLayer --> Timer[Timer Class]
SkillLayer --> Timer
SkillLayer --> oops
MapViewComp --> MapViewScene
MapViewScene --> MapLayer
MapViewScene --> EntityLayer
MapViewScene --> SkillLayer
GameMap --> MapModelComp
GameMap --> MapViewComp
GameMap --> oops
```
**Diagram sources**
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L48)
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
**Section sources**
- [MapViewComp.ts](file://assets/script/game/map/view/MapViewComp.ts#L1-L45)
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
- [SkillLayer.ts](file://assets/script/game/map/view/map/layer/SkillLayer.ts#L1-L48)
- [GameMap.ts](file://assets/script/game/map/GameMap.ts#L1-L36)
## 性能考虑
- **深度排序**: `EntityLayer``SkillLayer` 中的每帧深度排序可能成为性能瓶颈尤其是在实体数量众多时。建议根据实际需求将排序频率降低如每0.2秒一次)或采用空间分区等更高效的排序算法。
- **纹理重复**: `MoveUV` 组件通过修改 `spriteFrame.rect` 来实现动画,这是一种轻量级的方法,避免了创建额外的动画帧,对性能友好。
- **资源加载**: `GameMap.load()` 方法异步加载地图预制体,避免了主线程阻塞,保证了游戏的流畅性。
- **节点清理**: `MapViewScene.reset()` 方法显式清理各图层的子节点,防止内存泄漏。
## 故障排除指南
- **地图未显示**: 检查 `MapModelComp.resPrefab` 路径是否正确,确认预制体资源已正确导入。
- **UV动画无效**: 确保应用 `MoveUV` 组件的精灵Sprite的纹理TextureWrap Mode 设置为 `REPEAT`,否则偏移效果将不可见。
- **实体层排序异常**: 如果发现实体渲染顺序错误,检查 `EntityLayer.update()` 中的排序逻辑是否被正确执行,或尝试调整 `Timer` 的间隔。
- **摄像机不跟随**: 确认 `MapViewScene.isFollowPlayer` 属性已启用,并检查摄像机跟随的逻辑是否在其他地方被实现(当前代码中未找到具体实现)。
**Section sources**
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
- [MoveUV.ts](file://assets/script/game/map/view/MoveUV.ts#L1-L50)
- [EntityLayer.ts](file://assets/script/game/map/view/map/layer/EntityLayer.ts#L1-L39)
- [MapViewScene.ts](file://assets/script/game/map/view/MapViewScene.ts#L1-L77)
## 结论
本项目中的地图视图系统设计清晰,采用 MVC 和 ECS 模式实现了良好的代码组织和可维护性。`MapViewComp``MapViewScene` 协同工作,构建了地图场景的骨架。通过 `MapLayer``EntityLayer``SkillLayer` 等组件实现了分层渲染,便于管理和优化。`MoveUV` 组件提供了一种简单有效的动态纹理动画方案。开发者可以基于此架构轻松扩展新功能,如添加新的图层类型或实现更复杂的地图特效。