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

488 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.
# ECS架构深度解析
<cite>
**本文档引用的文件**
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts)
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts)
- [EcsPositionSystem.ts](file://assets/script/game/common/ecs/position/EcsPositionSystem.ts)
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts)
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts)
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
- [ecs.md](file://doc/ecs/ecs.md)
- [Main.ts](file://assets/script/Main.ts)
</cite>
## 目录
1. [简介](#简介)
2. [ECS架构概述](#ecs架构概述)
3. [组件系统详解](#组件系统详解)
4. [实体生命周期管理](#实体生命周期管理)
5. [系统架构与执行机制](#系统架构与执行机制)
6. [实际案例分析](#实际案例分析)
7. [性能优化与最佳实践](#性能优化与最佳实践)
8. [扩展开发指南](#扩展开发指南)
9. [总结](#总结)
## 简介
ECSEntity-Component-System是一种流行的游戏架构模式它通过将数据与行为分离来实现高度模块化和可扩展的系统设计。本项目采用TypeScript版本的ECS框架实现了游戏逻辑的数据与行为解耦为复杂的游戏系统提供了清晰的架构基础。
## ECS架构概述
### 核心概念
ECS架构由三个核心元素组成
```mermaid
graph TB
subgraph "ECS架构核心"
Entity["实体 (Entity)<br/>唯一标识符"]
Component["组件 (Component)<br/>数据容器"]
System["系统 (System)<br/>逻辑处理器"]
end
subgraph "交互关系"
Entity --> Component
System --> Entity
System -.-> Component
end
subgraph "执行流程"
System --> Filter["筛选机制"]
Filter --> Entities["符合条件的实体"]
Entities --> Update["系统更新"]
end
```
**图表来源**
- [ecs.md](file://doc/ecs/ecs.md#L1-L27)
### 架构优势
1. **数据与行为分离**:组件只存储数据,系统处理逻辑
2. **高度模块化**:通过组合不同组件创建复杂实体
3. **性能优化**:批量处理相同类型的操作
4. **易于扩展**:新增功能只需添加新组件和系统
## 组件系统详解
### 组件注册机制
组件通过装饰器`@ecs.register`进行注册,框架自动管理组件的生命周期和内存回收。
```mermaid
classDiagram
class Component {
<<abstract>>
+reset() void
}
class BattleMoveComp {
+number direction
+number targetX
+boolean moving
+reset() void
}
class HeroViewComp {
+string hero_name
+number fac
+boolean is_dead
+number[] Attrs
+reset() void
}
class MapModelComp {
+number id
+string resPrefab
+reset() void
}
Component <|-- BattleMoveComp
Component <|-- HeroViewComp
Component <|-- MapModelComp
```
**图表来源**
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L1-L16)
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L50)
- [MapModelComp.ts](file://assets/script/game/map/model/MapModelComp.ts#L1-L43)
### 组件添加与移除机制
组件的添加和移除遵循严格的生命周期管理:
```mermaid
sequenceDiagram
participant Entity as 实体
participant ECS as ECS框架
participant Pool as 组件池
participant System as 系统
Entity->>ECS : add(Component)
ECS->>Pool : 获取可用组件
alt 组件池中有可用组件
Pool-->>ECS : 返回组件实例
else 组件池为空
ECS->>ECS : 创建新组件
end
ECS->>Entity : 绑定组件
System->>Entity : 筛选实体
Entity-->>System : 返回实体列表
Entity->>ECS : remove(Component)
ECS->>Component : reset()重置状态
ECS->>Pool : 回收组件到池中
```
**图表来源**
- [ecs.md](file://doc/ecs/ecs.md#L45-L87)
**章节来源**
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L1-L16)
- [ecs.md](file://doc/ecs/ecs.md#L15-L45)
## 实体生命周期管理
### 实体创建与销毁
实体通过继承`ecs.Entity`创建,并支持父子实体关系管理:
```mermaid
stateDiagram-v2
[*] --> Created : createEntity()
Created --> Active : addComponents()
Active --> Updated : systemUpdate()
Updated --> Active : continue
Active --> Removed : removeComponents()
Removed --> Destroyed : destroy()
Destroyed --> [*]
Active --> Paused : systemPause()
Paused --> Active : systemResume()
```
### 实体管理操作
| 操作 | 方法 | 描述 |
|------|------|------|
| 创建实体 | `ecs.getEntity<Entity>()` | 从实体池中获取或创建新实体 |
| 添加组件 | `entity.add(Component)` | 优先从组件池获取,否则创建新实例 |
| 移除组件 | `entity.remove(Component)` | 组件重置后放回组件池 |
| 销毁实体 | `entity.destroy()` | 清理所有组件并回收实体 |
| 子实体管理 | `addChild(Entity)` | 管理实体间的父子关系 |
**章节来源**
- [ecs.md](file://doc/ecs/ecs.md#L29-L87)
## 系统架构与执行机制
### 系统层次结构
```mermaid
classDiagram
class System {
<<abstract>>
+execute(dt) void
}
class ComblockSystem {
+filter() IMatcher
+update(entity) void
+entityEnter(entity) void
+entityRemove(entity) void
}
class BattleMoveSystem {
+filter() IMatcher
+update(entity) void
-checkEnemiesExist(entity) boolean
-findNearestEnemy(entity) HeroViewComp
-validatePosition(x, move) boolean
}
class EcsPositionSystem {
+constructor()
}
System <|-- ComblockSystem
ComblockSystem <|-- BattleMoveSystem
System <|-- EcsPositionSystem
```
**图表来源**
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L50)
- [EcsPositionSystem.ts](file://assets/script/game/common/ecs/position/EcsPositionSystem.ts#L1-L9)
### 筛选机制
系统通过`filter()`方法筛选符合条件的实体:
```mermaid
flowchart TD
Start([系统执行]) --> Filter["filter()筛选"]
Filter --> Matcher{"IMatcher匹配"}
Matcher --> |allOf| AllMatch["所有组件都存在"]
Matcher --> |anyOf| AnyMatch["至少有一个组件存在"]
Matcher --> |excludeOf| ExcludeMatch["不包含指定组件"]
Matcher --> |onlyOf| OnlyMatch["只有指定组件"]
AllMatch --> ProcessEntities["处理实体列表"]
AnyMatch --> ProcessEntities
ExcludeMatch --> ProcessEntities
OnlyMatch --> ProcessEntities
ProcessEntities --> Update["系统更新"]
Update --> End([完成])
```
**图表来源**
- [ecs.md](file://doc/ecs/ecs.md#L88-L128)
### 系统执行流程
```mermaid
sequenceDiagram
participant Root as RootSystem
participant System as ComblockSystem
participant Entity as Entity
participant Component as Component
Root->>System : execute(dt)
System->>System : filter()筛选实体
loop 遍历符合条件的实体
System->>Entity : entityEnter()首次进入
System->>Entity : update()每帧更新
Entity->>Component : get(Component)
Component-->>Entity : 返回组件实例
System->>Entity : 处理业务逻辑
end
System->>Entity : entityRemove()移除处理
```
**图表来源**
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L10-L30)
**章节来源**
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L1-L272)
- [EcsPositionSystem.ts](file://assets/script/game/common/ecs/position/EcsPositionSystem.ts#L1-L9)
## 实际案例分析
### BattleMoveSystem详细分析
BattleMoveSystem展示了ECS架构在游戏AI中的应用
#### 组件依赖关系
```mermaid
graph LR
Entity["游戏实体"] --> BattleMoveComp["BattleMoveComp<br/>移动控制"]
Entity --> HeroViewComp["HeroViewComp<br/>视图控制"]
BattleMoveComp --> Direction["direction<br/>移动方向"]
BattleMoveComp --> TargetX["targetX<br/>目标位置"]
BattleMoveComp --> Moving["moving<br/>移动状态"]
HeroViewComp --> HP["hp/mp<br/>生命值"]
HeroViewComp --> Status["status<br/>状态"]
HeroViewComp --> Position["node.position<br/>位置信息"]
```
**图表来源**
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L10-L20)
- [BattleMoveComp.ts](file://assets/script/game/common/ecs/position/BattleMoveComp.ts#L4-L12)
#### 系统更新逻辑
BattleMoveSystem的核心更新逻辑体现了ECS的优势
1. **数据分离**:移动逻辑完全封装在系统中
2. **条件筛选**只处理同时拥有BattleMoveComp和HeroViewComp的实体
3. **状态管理**:根据游戏状态动态调整行为
4. **性能优化**:只处理活跃实体,避免不必要的计算
#### 关键算法实现
| 算法 | 功能 | 实现位置 |
|------|------|----------|
| 敌人检测 | 检查攻击范围内是否有敌人 | `checkEnemiesInRange()` |
| 最近敌人查找 | 寻找最近的敌对单位 | `findNearestEnemy()` |
| 位置验证 | 验证移动位置的有效性 | `validatePosition()` |
| 渲染层级更新 | 根据位置更新渲染顺序 | `updateRenderOrder()` |
**章节来源**
- [BattleMoveSystem.ts](file://assets/script/game/common/ecs/position/BattleMoveSystem.ts#L15-L272)
### HeroViewComp综合组件分析
HeroViewComp展示了组件如何存储复杂的游戏状态
#### 属性管理系统
```mermaid
classDiagram
class HeroViewComp {
+Record~number,Array~ BUFFS
+Record~number,Array~ BUFFS_TEMP
+number[] Attrs
+number[] NeAttrs
+addBuff(conf) void
+recalculateSingleAttr(attrIndex) void
+updateTemporaryBuffsDebuffs(dt) void
}
class BuffInstance {
+number value
+BType BType
+number remainTime
}
HeroViewComp --> BuffInstance : 管理
```
**图表来源**
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L60-L120)
#### BUFF系统架构
HeroViewComp实现了复杂的BUFF/DEBUFF管理系统
1. **持久BUFF**:存储在`BUFFS`数组中,永久存在直到手动移除
2. **临时BUFF**:存储在`BUFFS_TEMP`数组中,带有剩余时间
3. **属性计算**根据数值型和百分比型BUFF计算最终属性值
4. **自动更新**每帧更新临时BUFF的剩余时间
**章节来源**
- [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts#L1-L780)
## 性能优化与最佳实践
### 内存管理策略
ECS框架通过以下机制优化内存使用
```mermaid
flowchart TD
Create["创建组件"] --> Pool{"组件池检查"}
Pool --> |有可用| Reuse["重用组件实例"]
Pool --> |无可用| New["创建新实例"]
Reuse --> Use["使用组件"]
New --> Use
Use --> Remove["移除组件"]
Remove --> Reset["reset()重置"]
Reset --> Pool
Destroy["销毁实体"] --> Clear["清理所有组件"]
Clear --> Recycle["回收到池中"]
```
### 性能优化技巧
1. **组件池化**:避免频繁的垃圾回收
2. **批量处理**:系统一次性处理所有符合条件的实体
3. **条件筛选**:精确的过滤机制减少不必要的遍历
4. **状态缓存**:避免重复计算相同的状态
### 开发最佳实践
| 实践 | 原则 | 示例 |
|------|------|------|
| 组件职责单一 | 一个组件只负责一种数据类型 | BattleMoveComp只处理移动相关数据 |
| 系统逻辑集中 | 系统处理相关的业务逻辑 | BattleMoveSystem处理所有移动逻辑 |
| 避免循环依赖 | 组件间不应有强耦合关系 | 通过系统协调组件交互 |
| 合理使用筛选器 | 精确的过滤条件提高性能 | `ecs.allOf(BattleMoveComp, HeroViewComp)` |
## 扩展开发指南
### 定义新组件
创建新组件的基本步骤:
```typescript
// 1. 继承ecs.Comp
@ecs.register('NewComponent')
export class NewComponent extends ecs.Comp {
// 2. 定义组件数据
public data: any;
public enabled: boolean = true;
// 3. 实现reset方法
reset() {
this.data = null;
this.enabled = true;
}
}
// 4. 在实体中声明
export class NewEntity extends ecs.Entity {
New: NewComponent;
}
```
### 创建新系统
系统开发的标准流程:
```typescript
@ecs.register('NewSystem')
export class NewSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
// 1. 定义筛选条件
filter(): ecs.IMatcher {
return ecs.allOf(NewComponent, AnotherComponent);
}
// 2. 实现更新逻辑
update(e: ecs.Entity) {
const comp = e.get(NewComponent);
const another = e.get(AnotherComponent);
// 处理业务逻辑
if (comp.enabled) {
// ...具体逻辑
}
}
}
```
### 系统接口选择
| 接口 | 用途 | 使用场景 |
|------|------|----------|
| `ISystemUpdate` | 每帧更新 | 需要持续处理的逻辑 |
| `IEntityEnterSystem` | 实体首次进入 | 初始化实体状态 |
| `IEntityRemoveSystem` | 实体移除处理 | 清理资源和状态 |
| `ISystemFirstUpdate` | 系统首次更新 | 系统初始化逻辑 |
### 扩展示例
基于现有架构扩展新功能:
```mermaid
graph TB
subgraph "扩展架构"
NewComp["NewComponent<br/>新功能组件"]
NewSys["NewSystem<br/>新功能系统"]
ExistingComp["ExistingComponent<br/>现有组件"]
end
subgraph "系统集成"
BattleMove["BattleMoveSystem"]
NewSys --> BattleMove
NewComp --> BattleMove
end
subgraph "实体组合"
Entity["游戏实体"]
Entity --> NewComp
Entity --> ExistingComp
end
```
**章节来源**
- [ecs.md](file://doc/ecs/ecs.md#L129-L272)
## 总结
本项目采用的ECS架构展现了现代游戏开发的最佳实践
### 核心优势
1. **高度模块化**:通过组件组合创建复杂实体
2. **清晰的职责分离**:数据存储在组件,逻辑处理在系统
3. **优秀的性能表现**:批量处理和精确筛选机制
4. **良好的可扩展性**:易于添加新功能和修改现有逻辑
### 架构特点
- **数据驱动**:系统通过筛选机制处理数据
- **事件驱动**:支持实体进入和移除事件
- **类型安全**TypeScript提供完整的类型检查
- **内存友好**:组件池化和自动回收机制
### 应用价值
ECS架构特别适合
- 复杂的游戏AI系统
- 大量相似但行为不同的实体
- 需要高性能处理的游戏逻辑
- 需要频繁扩展和修改的系统
通过深入理解和正确应用ECS架构开发者可以构建出既高效又易于维护的游戏系统为玩家提供流畅的游戏体验。