refactor(game): 移除已弃用的事件常量
- 删除 UpdateHero 和 UpdateFightHero 事件 - 移除 MISSION_UPDATE 事件常量 - 优化游戏事件枚举定义
This commit is contained in:
488
.qoder/repowiki/zh/content/技术架构/ECS架构.md
Normal file
488
.qoder/repowiki/zh/content/技术架构/ECS架构.md
Normal file
@@ -0,0 +1,488 @@
|
||||
# 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. [总结](#总结)
|
||||
|
||||
## 简介
|
||||
|
||||
ECS(Entity-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架构,开发者可以构建出既高效又易于维护的游戏系统,为玩家提供流畅的游戏体验。
|
||||
Reference in New Issue
Block a user