更新api文档

This commit is contained in:
YHH
2025-08-15 13:47:11 +08:00
parent 021e892e33
commit e4e38ee4e6
2 changed files with 63 additions and 214 deletions

View File

@@ -37,18 +37,22 @@ class Enemy extends Player { // 敌人需要射击但不需要玩家控制?
**ECS 方式:** **ECS 方式:**
```typescript ```typescript
// 数据和逻辑分离,灵活组合 // 数据和逻辑分离,灵活组合
const player = createEntity() const player = scene.createEntity("Player")
.add(PositionComponent) // 位置数据 .addComponent(new PositionComponent()) // 位置数据
.add(HealthComponent) // 生命值数据 .addComponent(new HealthComponent()) // 生命值数据
.add(PlayerInputComponent) // 玩家输入标记 .addComponent(new PlayerInputComponent()) // 玩家输入标记
const enemy = createEntity() const enemy = scene.createEntity("Enemy")
.add(PositionComponent) // 复用位置数据 .addComponent(new PositionComponent()) // 复用位置数据
.add(HealthComponent) // 复用生命值数据 .addComponent(new HealthComponent()) // 复用生命值数据
.add(AIComponent) // AI标记 .addComponent(new AIComponent()) // AI标记
// 系统处理具有特定组件的实体 // 系统自动处理具有特定组件的实体
MovementSystem.process([PositionComponent, VelocityComponent]); class MovementSystem extends EntitySystem {
onUpdate() {
// 处理具有Position和Velocity组件的实体
}
}
``` ```
### ECS 的优势 ### ECS 的优势
@@ -84,11 +88,12 @@ function findEntitiesWithHealth() {
} }
``` ```
**解决方案:** 建立索引,直接访问 **解决方案:** 查询系统,直接访问
```typescript ```typescript
// 快的方式:索引查找 O(1) // 快的方式:使用查询系统 O(1)
const healthIndex = componentIndex.get(HealthComponent); const entitiesWithHealth = entityManager.query()
const entitiesWithHealth = healthIndex.getEntities(); // 直接获取 .withAll(HealthComponent)
.execute(); // 直接获取SparseSet自动优化
``` ```
**应用场景:** **应用场景:**
@@ -96,152 +101,28 @@ const entitiesWithHealth = healthIndex.getEntities(); // 直接获取
- 大规模实体场景(数千到数万个实体) - 大规模实体场景(数千到数万个实体)
- 实时游戏中的系统更新 - 实时游戏中的系统更新
### 索引类型选择指南 ### SparseSet 组件索引
框架提供两种索引类型,选择合适的类型对性能至关重要: **什么是 SparseSet**
SparseSet是一种高效的数据结构结合了哈希表的快速访问和数组的缓存友好特性。
#### 🔸 哈希索引 (Hash Index) **SparseSet 的优势:**
- **O(1) 添加/删除/查找** - 所有基本操作都是常数时间
**适用场景:** - **缓存友好遍历** - 密集数组存储,提高遍历性能
- 实体数量较多(> 1000个 - **内存高效** - 自动管理稀疏和密集数据
- 组件数据变化不频繁 - **无需配置** - 框架自动选择最优策略
- 需要快速查找特定实体
**优势:**
- 查询速度极快 O(1)
- 内存使用相对较少
- 适合大量实体
**缺点:**
- 添加/删除组件时有额外开销
- 不适合频繁变化的组件
```typescript ```typescript
// 适合哈希索引的组件 // 统一的查询API无需手动配置
componentIndex.setIndexType(PositionComponent, 'hash'); // 位置变化不频繁 const entitiesWithHealth = entityManager.query()
componentIndex.setIndexType(HealthComponent, 'hash'); // 生命值组件稳定 .withAll(HealthComponent)
componentIndex.setIndexType(PlayerComponent, 'hash'); // 玩家标记组件 .execute(); // O(1) 访问SparseSet自动优化
``` ```
#### 🔹 位图索引 (Bitmap Index) **应用场景:**
- 任意规模的实体场景(从几十到数万)
**适用场景:** - 频繁的组件添加/删除操作
- 组件频繁添加/删除 - 高性能的批量查询需求
- 实体数量适中(< 1000个
- 需要批量操作
**优势:**
- 添加/删除组件极快
- 批量查询效率高
- 内存访问模式好
**缺点:**
- 随实体数量增长,内存占用增加
- 稀疏数据时效率降低
```typescript
// 适合位图索引的组件
componentIndex.setIndexType(BuffComponent, 'bitmap'); // Buff经常添加删除
componentIndex.setIndexType(TemporaryComponent, 'bitmap'); // 临时组件
componentIndex.setIndexType(StateComponent, 'bitmap'); // 状态组件变化频繁
```
#### 选择决策表
| 考虑因素 | 哈希索引 (Hash) | 位图索引 (Bitmap) |
|---------|----------------|-------------------|
| **实体数量** | > 1,000 | < 10,000 |
| **组件变化频率** | 低频变化 | 高频变化 |
| **查询频率** | 高频查询 | 中等查询 |
| **内存使用** | 较少 | 随实体数增加 |
| **批量操作** | 一般 | 优秀 |
#### 快速决策流程
**第一步:判断组件变化频率**
- 组件经常添加/删除? → 选择 **位图索引**
- 组件相对稳定? → 继续第二步
**第二步:判断实体数量**
- 实体数量 > 1000 → 选择 **哈希索引**
- 实体数量 < 1000 → 选择 **位图索引**
**第三步:特殊情况**
- 需要频繁批量操作? → 选择 **位图索引**
- 内存使用很重要? → 选择 **哈希索引**
#### 实际游戏中的选择示例
**射击游戏:**
```typescript
// 稳定组件用哈希索引
componentIndex.setIndexType(PositionComponent, 'hash'); // 实体位置稳定存在
componentIndex.setIndexType(HealthComponent, 'hash'); // 生命值组件持续存在
componentIndex.setIndexType(WeaponComponent, 'hash'); // 武器组件不常变化
// 变化组件用位图索引
componentIndex.setIndexType(BuffComponent, 'bitmap'); // Buff频繁添加删除
componentIndex.setIndexType(ReloadingComponent, 'bitmap'); // 装弹状态临时组件
```
**策略游戏:**
```typescript
// 大量单位,核心组件用哈希
componentIndex.setIndexType(UnitComponent, 'hash'); // 单位类型稳定
componentIndex.setIndexType(OwnerComponent, 'hash'); // 所属玩家稳定
// 状态组件用位图
componentIndex.setIndexType(SelectedComponent, 'bitmap'); // 选中状态常变化
componentIndex.setIndexType(MovingComponent, 'bitmap'); // 移动状态变化
componentIndex.setIndexType(AttackingComponent, 'bitmap'); // 攻击状态临时
```
**RPG游戏**
```typescript
// 角色核心属性用哈希
componentIndex.setIndexType(StatsComponent, 'hash'); // 属性组件稳定
componentIndex.setIndexType(InventoryComponent, 'hash'); // 背包组件稳定
componentIndex.setIndexType(LevelComponent, 'hash'); // 等级组件稳定
// 临时状态用位图
componentIndex.setIndexType(StatusEffectComponent, 'bitmap'); // 状态效果变化
componentIndex.setIndexType(QuestComponent, 'bitmap'); // 任务状态变化
componentIndex.setIndexType(CombatComponent, 'bitmap'); // 战斗状态临时
```
#### ❌ 常见选择错误
**错误示例1大量实体使用位图索引**
```typescript
// ❌ 错误10万个单位用位图索引内存爆炸
const entityCount = 100000;
componentIndex.setIndexType(UnitComponent, 'bitmap'); // 内存占用过大!
// 正确:大量实体用哈希索引
componentIndex.setIndexType(UnitComponent, 'hash');
```
**错误示例2频繁变化组件用哈希索引**
```typescript
// ❌ 错误Buff频繁添加删除哈希索引效率低
componentIndex.setIndexType(BuffComponent, 'hash'); // 添加删除慢!
// 正确:变化频繁的组件用位图索引
componentIndex.setIndexType(BuffComponent, 'bitmap');
```
**错误示例3不考虑实际使用场景**
```typescript
// ❌ 错误:所有组件都用同一种索引
componentIndex.setIndexType(PositionComponent, 'hash');
componentIndex.setIndexType(BuffComponent, 'hash'); // 应该用bitmap
componentIndex.setIndexType(TemporaryComponent, 'hash'); // 应该用bitmap
// 正确:根据组件特性选择
componentIndex.setIndexType(PositionComponent, 'hash'); // 稳定组件
componentIndex.setIndexType(BuffComponent, 'bitmap'); // 变化组件
componentIndex.setIndexType(TemporaryComponent, 'bitmap'); // 临时组件
```
### Archetype 系统 ### Archetype 系统
@@ -396,21 +277,20 @@ class GameManager {
### 实体生命周期 ### 实体生命周期
**创建实体的不同方式:** **创建实体的方式:**
```typescript ```typescript
// 单个创建 - 适用于重要实体 // 单个创建 - 适用于重要实体
const player = scene.createEntity("Player"); const player = scene.createEntity("Player");
player.addComponent(new PositionComponent());
player.addComponent(new HealthComponent());
// 批量创建 - 适用于大量相似实体 // 批量创建 - 需要循环处理
const bullets = scene.createEntities(100, "Bullet"); const bullets: Entity[] = [];
// 延迟创建 - 避免性能峰值
// 分批创建大量实体以避免单帧卡顿
for (let i = 0; i < 100; i++) { for (let i = 0; i < 100; i++) {
setTimeout(() => { const bullet = scene.createEntity(`Bullet_${i}`);
const batch = scene.createEntities(10, "Enemy"); bullet.addComponent(new PositionComponent());
// 配置批次实体... bullet.addComponent(new VelocityComponent());
}, i * 16); // 每16ms创建一批 bullets.push(bullet);
} }
``` ```
@@ -440,21 +320,21 @@ const result = entityManager
### 批量操作 ### 批量操作
**为什么需要批量操作?** **批量操作的优化:**
```typescript ```typescript
// 慢的方式:逐个处理 // 优化的批量创建方式
const bullets: Entity[] = [];
for (let i = 0; i < 1000; i++) { for (let i = 0; i < 1000; i++) {
const bullet = createEntity(); const bullet = scene.createEntity(`Bullet_${i}`);
bullet.addComponent(new PositionComponent()); bullet.addComponent(new PositionComponent());
bullet.addComponent(new VelocityComponent()); bullet.addComponent(new VelocityComponent());
bullets.push(bullet);
} }
// 快的方式:批量处理 // 批量查询操作
const bullets = scene.createEntities(1000, "Bullet"); const allMovableEntities = entityManager.query()
bullets.forEach(bullet => { .withAll(PositionComponent, VelocityComponent)
bullet.addComponent(new PositionComponent()); .execute();
bullet.addComponent(new VelocityComponent());
});
``` ```
**应用场景:** **应用场景:**
@@ -462,49 +342,17 @@ bullets.forEach(bullet => {
- 加载关卡时创建大量实体 - 加载关卡时创建大量实体
- 清理场景时删除大量实体 - 清理场景时删除大量实体
## 性能建议
### 什么时候使用这些优化?
| 实体数量 | 推荐配置 | 说明 |
|---------|---------|------|
| < 1,000 | 默认配置 | 简单场景,不需要特殊优化 |
| 1,000 - 10,000 | 启用组件索引 | 中等规模,索引提升查询速度 |
| 10,000 - 50,000 | 启用Archetype | 大规模场景,分组优化 |
| > 50,000 | 全部优化 | 超大规模,需要所有优化技术 |
### 常见使用误区
**错误:过度优化**
```typescript
// 不要在小项目中使用所有优化
const entityManager = new EntityManager();
entityManager.enableAllOptimizations(); // 小项目不需要
```
**正确:按需优化**
```typescript
// 根据实际需求选择优化
if (entityCount > 10000) {
entityManager.enableArchetypeSystem();
}
if (hasFrequentQueries) {
entityManager.enableComponentIndex();
}
```
## 总结 ## 总结
这些技术概念可能看起来复杂,但它们解决的都是实际开发中的具体问题 ECS框架包含以下核心技术概念
1. **ECS架构** - 让代码更灵活、可维护 1. **ECS架构** - 组件化设计模式
2. **组件索引** - 让查询更快速 2. **SparseSet索引** - 高效的组件查询
3. **Archetype系统** - 让批量操作更高效 3. **Archetype系统** - 实体分组优化
4. **脏标记系统** - 让更新更智能 4. **脏标记系统** - 变化检测机制
5. **事件系统** - 组件间通信更安全 5. **事件系统** - 组件间通信
6. **实体管理** - 让大规模场景成为可能 6. **实体管理** - 生命周期管理
从简单的场景开始,随着项目复杂度增加,逐步引入这些优化技术。
## 框架类型系统 ## 框架类型系统

View File

@@ -598,14 +598,15 @@ enemies.forEach(enemy => {
enemy.addComponent(new HealthComponent(50)); enemy.addComponent(new HealthComponent(50));
}); });
// 查询实体 // 查询实体 - 推荐方式
const movingEntities = entityManager const movingEntities = entityManager
.query() .query()
.withAll(PositionComponent, VelocityComponent) .withAll(PositionComponent, VelocityComponent)
.execute(); .execute();
// 简单查询方式
const healthEntities = entityManager.getEntitiesWithComponent(HealthComponent); const healthEntities = entityManager.getEntitiesWithComponent(HealthComponent);
const enemiesByTag = entityManager.getEntitiesByTag(2); const taggedEntities = entityManager.getEntitiesByTag(2);
``` ```
## 事件系统 ## 事件系统