Files
esengine/docs/entity-manager-example.md

421 lines
11 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.
# EntityManager 使用指南
EntityManager 是 ECS Framework 的核心管理系统,提供统一的实体管理、高性能查询和自动优化功能。
## 快速开始
### 创建实体管理器
```typescript
import { EntityManager, Scene } from '@esengine/ecs-framework';
// 通常在游戏管理器中创建
const scene = new Scene();
const entityManager = new EntityManager(scene);
```
### 基础实体操作
```typescript
// 创建单个实体
const player = entityManager.createEntity("Player");
player.addComponent(new PositionComponent(100, 100));
player.addComponent(new HealthComponent(100));
player.tag = "player";
// 批量创建实体
const enemies = entityManager.createEntities(50, "Enemy");
enemies.forEach((enemy, index) => {
enemy.addComponent(new PositionComponent(
Math.random() * 800,
Math.random() * 600
));
enemy.addComponent(new HealthComponent(30));
enemy.tag = "enemy";
});
// 销毁实体
entityManager.destroyEntity(player);
```
## 高性能查询系统
EntityManager 提供多种查询方式,自动选择最优的查询策略。
### 基础查询
```typescript
// 通过ID查询O(1)
const entity = entityManager.getEntity(123);
// 通过名称查询O(1) 哈希查找)
const player = entityManager.getEntityByName("Player");
// 通过标签查询O(1) 索引查找)
const enemies = entityManager.getEntitiesByTag("enemy");
// 组件查询使用O(1)组件索引)
const healthEntities = entityManager.getEntitiesWithComponent(HealthComponent);
// 多组件查询使用Archetype优化
const movingEntities = entityManager.getEntitiesWithComponents([
PositionComponent,
VelocityComponent
]);
```
### 流式查询API
EntityManager 提供强大的流式查询构建器:
```typescript
// 基础查询构建
const results = entityManager
.query()
.withAll([PositionComponent, HealthComponent]) // 必须包含这些组件
.withoutTag("dead") // 不能有死亡标签
.active(true) // 必须激活
.execute();
// 复杂条件查询
const livingEnemies = entityManager
.query()
.withAll([PositionComponent, HealthComponent])
.withTag("enemy")
.withoutTag("dead")
.where(entity => {
const health = entity.getComponent(HealthComponent);
return health && health.currentHealth > 0;
})
.execute();
// 查询变体
const firstEnemy = entityManager
.query()
.withTag("enemy")
.first(); // 获取第一个匹配
const enemyCount = entityManager
.query()
.withTag("enemy")
.count(); // 获取数量
// 直接处理查询结果
entityManager
.query()
.withAll([HealthComponent])
.forEach(entity => {
const health = entity.getComponent(HealthComponent);
if (health.currentHealth <= 0) {
entity.addTag("dead");
}
});
```
### 高级查询选项
```typescript
// 组合条件查询
const combatUnits = entityManager
.query()
.withAll([PositionComponent, HealthComponent]) // AND条件
.withAny([WeaponComponent, MagicComponent]) // OR条件
.without([DeadComponent]) // NOT条件
.withTag("combatant")
.withoutTag("peaceful")
.active(true)
.enabled(true)
.execute();
// 使用自定义过滤器
const nearbyEnemies = entityManager
.query()
.withAll([PositionComponent])
.withTag("enemy")
.where(entity => {
const pos = entity.getComponent(PositionComponent);
const distance = Math.sqrt(
Math.pow(pos.x - playerPos.x, 2) +
Math.pow(pos.y - playerPos.y, 2)
);
return distance < 100; // 距离玩家100像素内
})
.execute();
```
## 批量操作
EntityManager 提供高效的批量操作方法:
```typescript
// 遍历所有实体
entityManager.forEachEntity(entity => {
// 处理每个实体
if (entity.position.x < 0) {
entity.position.x = 0;
}
});
// 遍历特定组件的实体
entityManager.forEachEntityWithComponent(HealthComponent, (entity, health) => {
if (health.currentHealth <= 0) {
entity.addTag("dead");
entity.enabled = false;
}
});
// 批量创建并配置实体
const bullets = entityManager.createEntities(100, "Bullet", (bullet, index) => {
bullet.addComponent(new PositionComponent(
100 + index * 10,
100
));
bullet.addComponent(new VelocityComponent(0, -200));
bullet.tag = "projectile";
});
```
## 性能优化系统
EntityManager 内置了三个性能优化系统:
### 1. 组件索引系统
自动为组件查询提供O(1)性能:
```typescript
// 获取组件索引统计
const componentIndex = entityManager.getComponentIndex();
const stats = componentIndex.getPerformanceStats();
console.log('组件索引统计:', {
totalQueries: stats.totalQueries,
indexHits: stats.indexHits,
hitRate: (stats.indexHits / stats.totalQueries * 100).toFixed(2) + '%'
});
// 手动优化(通常自动进行)
componentIndex.optimize();
```
### 2. Archetype系统
按组件组合分组实体,优化批量查询:
```typescript
// 获取Archetype统计
const archetypeSystem = entityManager.getArchetypeSystem();
const archetypeStats = archetypeSystem.getStatistics();
console.log('Archetype统计:', {
totalArchetypes: archetypeStats.totalArchetypes,
totalEntities: archetypeStats.totalEntities,
queryCacheSize: archetypeStats.queryCacheSize
});
// 查看所有原型
console.log('当前原型:', archetypeSystem.getAllArchetypes());
```
### 3. 脏标记系统
追踪实体变更,避免不必要的更新:
```typescript
// 获取脏标记统计
const dirtyTracking = entityManager.getDirtyTrackingSystem();
const dirtyStats = dirtyTracking.getPerformanceStats();
console.log('脏标记统计:', {
totalMarks: dirtyStats.totalMarks,
batchesProcessed: dirtyStats.batchesProcessed,
listenersNotified: dirtyStats.listenersNotified
});
// 手动处理脏标记
dirtyTracking.processDirtyMarks();
```
## 实体管理器统计
获取EntityManager的综合性能数据
```typescript
const stats = entityManager.getStatistics();
console.log('EntityManager统计:', {
// 基础统计
entityCount: stats.entityCount,
activeEntityCount: stats.activeEntityCount,
// 查询统计
totalQueries: stats.totalQueries,
indexHits: stats.indexHits,
archetypeHits: stats.archetypeHits,
// 性能指标
averageQueryTime: stats.averageQueryTime,
hitRate: (stats.indexHits / stats.totalQueries * 100).toFixed(2) + '%'
});
```
## 系统优化和清理
```typescript
// 手动触发优化
entityManager.optimize();
// 内存清理
entityManager.cleanup();
// 压缩数据结构
entityManager.compact();
// 获取内存使用情况
const memoryStats = entityManager.getMemoryUsage();
console.log('内存使用:', {
entityIndexSize: memoryStats.entityIndex,
componentIndexSize: memoryStats.componentIndex,
archetypeSize: memoryStats.archetype
});
```
## 实际使用案例
### 游戏系统集成
```typescript
class MovementSystem extends EntitySystem {
private entityManager: EntityManager;
constructor(scene: Scene) {
super();
this.entityManager = new EntityManager(scene);
}
protected process(entities: Entity[]): void {
// 使用高效查询获取移动实体
const movingEntities = this.entityManager
.query()
.withAll([PositionComponent, VelocityComponent])
.active(true)
.execute();
// 批量处理
movingEntities.forEach(entity => {
const position = entity.getComponent(PositionComponent);
const velocity = entity.getComponent(VelocityComponent);
position.x += velocity.dx * Time.deltaTime;
position.y += velocity.dy * Time.deltaTime;
});
}
}
```
### 复杂查询示例
```typescript
// 战斗系统:查找攻击范围内的敌人
class CombatSystem {
private entityManager: EntityManager;
findTargetsInRange(attacker: Entity, range: number): Entity[] {
const attackerPos = attacker.getComponent(PositionComponent);
if (!attackerPos) return [];
return this.entityManager
.query()
.withAll([PositionComponent, HealthComponent])
.withTag("enemy")
.withoutTag("dead")
.where(entity => {
const pos = entity.getComponent(PositionComponent);
const distance = Math.sqrt(
Math.pow(pos.x - attackerPos.x, 2) +
Math.pow(pos.y - attackerPos.y, 2)
);
return distance <= range;
})
.execute();
}
// 优化版本:使用空间分区(如果实现了的话)
findTargetsInRangeOptimized(attacker: Entity, range: number): Entity[] {
// 首先通过空间查询缩小范围
const nearbyEntities = this.spatialIndex.queryRange(
attackerPos.x - range,
attackerPos.y - range,
attackerPos.x + range,
attackerPos.y + range
);
// 然后使用EntityManager进行精确过滤
return this.entityManager
.query()
.withAll([HealthComponent])
.withTag("enemy")
.withoutTag("dead")
.where(entity => nearbyEntities.includes(entity))
.execute();
}
}
```
## 性能建议
### 查询优化
1. **利用索引**: 优先使用组件查询和标签查询它们具有O(1)性能
2. **减少自定义过滤**: `where()`条件虽然灵活,但会降低性能
3. **缓存查询结果**: 对于不经常变化的查询结果,考虑缓存
```typescript
// ✅ 推荐:使用索引查询
const enemies = entityManager.getEntitiesByTag("enemy");
// ⚠️ 谨慎:自定义过滤
const enemies = entityManager
.query()
.where(entity => entity.name.includes("Enemy"))
.execute();
```
### 批量操作优化
```typescript
// ✅ 推荐:批量创建
const bullets = entityManager.createEntities(100, "Bullet");
// ❌ 避免:循环单独创建
for (let i = 0; i < 100; i++) {
entityManager.createEntity("Bullet");
}
```
### 内存管理
```typescript
// 定期清理
setInterval(() => {
entityManager.cleanup();
}, 30000); // 每30秒清理一次
// 监控性能
const stats = entityManager.getStatistics();
if (stats.indexHits / stats.totalQueries < 0.8) {
console.warn('查询命中率较低,考虑优化查询策略');
}
```
## 总结
EntityManager 提供了:
- **统一接口**: 所有实体操作通过一个管理器完成
- **自动优化**: 内置三个性能优化系统
- **灵活查询**: 从简单的ID查找到复杂的条件查询
- **性能监控**: 完整的统计和诊断信息
- **批量操作**: 高效的批量处理能力
通过合理使用EntityManager您可以构建高性能、可维护的ECS游戏系统。