文档及教程更新
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
# 核心概念
|
||||
# 核心 API 参考
|
||||
|
||||
ECS Framework 基于 Entity-Component-System 架构模式,这是一种高度模块化和可扩展的游戏开发架构。本文档将详细介绍框架的核心概念。
|
||||
本文档详细介绍 ECS Framework 的核心 API 和使用方法。
|
||||
|
||||
> 🤔 **不熟悉ECS概念?** 建议先阅读 [技术概念详解](concepts-explained.md) 了解ECS架构基础和性能优化原理
|
||||
|
||||
## ECS 架构概述
|
||||
|
||||
@@ -90,7 +92,7 @@ entities.forEach(entity => {
|
||||
scene.querySystem.clearCache(); // 手动清理缓存
|
||||
|
||||
// 获取性能统计
|
||||
const stats = scene.getPerformanceStats();
|
||||
const stats = scene.getStats();
|
||||
console.log(`实体数量: ${stats.entityCount}`);
|
||||
```
|
||||
|
||||
@@ -101,20 +103,8 @@ console.log(`实体数量: ${stats.entityCount}`);
|
||||
### 实体的基本属性
|
||||
|
||||
```typescript
|
||||
import { Vector2 } from '@esengine/ecs-framework';
|
||||
|
||||
const entity = scene.createEntity("MyEntity");
|
||||
|
||||
// 位置
|
||||
entity.position = new Vector2(100, 200);
|
||||
entity.position = entity.position.add(new Vector2(10, 0));
|
||||
|
||||
// 旋转(弧度)
|
||||
entity.rotation = Math.PI / 4;
|
||||
|
||||
// 缩放
|
||||
entity.scale = new Vector2(2, 2);
|
||||
|
||||
// 标签(用于分类)
|
||||
entity.tag = 1;
|
||||
|
||||
@@ -126,6 +116,22 @@ entity.active = true;
|
||||
|
||||
// 更新顺序
|
||||
entity.updateOrder = 10;
|
||||
|
||||
// 注意:框架专注于ECS架构,不提供Transform相关功能
|
||||
// 位置、旋转、缩放等Transform功能需要通过组件实现
|
||||
class TransformComponent extends Component {
|
||||
public x: number = 0;
|
||||
public y: number = 0;
|
||||
public rotation: number = 0;
|
||||
public scaleX: number = 1;
|
||||
public scaleY: number = 1;
|
||||
}
|
||||
|
||||
// 使用Transform组件
|
||||
const transform = entity.addComponent(new TransformComponent());
|
||||
transform.x = 100;
|
||||
transform.y = 200;
|
||||
transform.rotation = Math.PI / 4;
|
||||
```
|
||||
|
||||
### 实体层级关系
|
||||
@@ -278,20 +284,24 @@ class BulletComponent extends Component {
|
||||
}
|
||||
|
||||
// 注册组件池
|
||||
ComponentPoolManager.getInstance().registerPool(BulletComponent, 1000);
|
||||
ComponentPoolManager.getInstance().registerPool(
|
||||
'BulletComponent',
|
||||
() => new BulletComponent(),
|
||||
(bullet) => bullet.reset(),
|
||||
1000
|
||||
);
|
||||
|
||||
// 使用对象池获取组件
|
||||
const bullet = ComponentPoolManager.getInstance().getComponent(BulletComponent);
|
||||
entity.addComponent(bullet);
|
||||
const bullet = ComponentPoolManager.getInstance().acquireComponent('BulletComponent');
|
||||
if (bullet) {
|
||||
entity.addComponent(bullet);
|
||||
}
|
||||
|
||||
// 释放组件回对象池
|
||||
ComponentPoolManager.getInstance().releaseComponent(bullet);
|
||||
ComponentPoolManager.getInstance().releaseComponent('BulletComponent', bullet);
|
||||
|
||||
// 预热组件池
|
||||
ComponentPoolManager.getInstance().preWarmPools({
|
||||
BulletComponent: 1000,
|
||||
EffectComponent: 500
|
||||
});
|
||||
// 预热所有组件池
|
||||
ComponentPoolManager.getInstance().prewarmAll(100);
|
||||
|
||||
// 获取池统计
|
||||
const stats = ComponentPoolManager.getInstance().getPoolStats();
|
||||
@@ -305,7 +315,9 @@ console.log('组件池统计:', stats);
|
||||
### 场景生命周期
|
||||
|
||||
```typescript
|
||||
class GameScene extends es.Scene {
|
||||
import { Scene } from '@esengine/ecs-framework';
|
||||
|
||||
class GameScene extends Scene {
|
||||
public initialize() {
|
||||
// 场景初始化,创建实体和系统
|
||||
this.setupEntities();
|
||||
@@ -365,8 +377,14 @@ console.log("系统数量:", stats.processorCount);
|
||||
最常用的系统类型,处理实体集合:
|
||||
|
||||
```typescript
|
||||
class MovementSystem extends es.EntitySystem {
|
||||
protected process(entities: es.Entity[]) {
|
||||
import { EntitySystem, Entity, Matcher } from '@esengine/ecs-framework';
|
||||
|
||||
class MovementSystem extends EntitySystem {
|
||||
constructor() {
|
||||
super(Matcher.empty().all(MovementComponent));
|
||||
}
|
||||
|
||||
protected process(entities: Entity[]) {
|
||||
for (const entity of entities) {
|
||||
const movement = entity.getComponent(MovementComponent);
|
||||
if (movement) {
|
||||
@@ -382,12 +400,26 @@ class MovementSystem extends es.EntitySystem {
|
||||
定期处理的系统:
|
||||
|
||||
```typescript
|
||||
class HealthRegenerationSystem extends es.ProcessingSystem {
|
||||
protected process(entities: es.Entity[]) {
|
||||
for (const entity of entities) {
|
||||
const health = entity.getComponent(HealthComponent);
|
||||
import { ProcessingSystem, Time, Matcher } from '@esengine/ecs-framework';
|
||||
|
||||
class HealthRegenerationSystem extends ProcessingSystem {
|
||||
constructor() {
|
||||
super(Matcher.empty().all(HealthComponent));
|
||||
}
|
||||
|
||||
public processSystem() {
|
||||
// ProcessingSystem不处理具体实体,而是执行全局逻辑
|
||||
// 如果需要处理实体,应该使用EntitySystem
|
||||
this.regenerateAllPlayerHealth();
|
||||
}
|
||||
|
||||
private regenerateAllPlayerHealth() {
|
||||
// 通过场景查找所有玩家实体并恢复生命值
|
||||
const players = this.scene.findEntitiesByTag(PlayerTag);
|
||||
for (const player of players) {
|
||||
const health = player.getComponent(HealthComponent);
|
||||
if (health && health.currentHealth < health.maxHealth) {
|
||||
health.currentHealth += 10 * es.Time.deltaTime;
|
||||
health.currentHealth += 10 * Time.deltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,12 +431,15 @@ class HealthRegenerationSystem extends es.ProcessingSystem {
|
||||
按时间间隔执行的系统:
|
||||
|
||||
```typescript
|
||||
class SpawnSystem extends es.IntervalSystem {
|
||||
import { IntervalSystem, Matcher } from '@esengine/ecs-framework';
|
||||
|
||||
class SpawnSystem extends IntervalSystem {
|
||||
constructor() {
|
||||
super(3.0); // 每3秒执行一次
|
||||
// IntervalSystem需要Matcher和间隔时间
|
||||
super(Matcher.empty(), 3.0); // 每3秒执行一次
|
||||
}
|
||||
|
||||
protected processSystem() {
|
||||
protected process(entities: Entity[]) {
|
||||
// 生成敌人
|
||||
const enemy = this.scene.createEntity("Enemy");
|
||||
enemy.addComponent(new EnemyComponent());
|
||||
@@ -417,7 +452,13 @@ class SpawnSystem extends es.IntervalSystem {
|
||||
被动系统,不自动处理实体:
|
||||
|
||||
```typescript
|
||||
class CollisionSystem extends es.PassiveSystem {
|
||||
import { PassiveSystem, Matcher } from '@esengine/ecs-framework';
|
||||
|
||||
class CollisionSystem extends PassiveSystem {
|
||||
constructor() {
|
||||
super(Matcher.empty());
|
||||
}
|
||||
|
||||
public checkCollisions() {
|
||||
// 手动调用的碰撞检测逻辑
|
||||
}
|
||||
@@ -429,54 +470,32 @@ class CollisionSystem extends es.PassiveSystem {
|
||||
时间管理工具类,提供游戏时间相关功能:
|
||||
|
||||
```typescript
|
||||
import { Time } from '@esengine/ecs-framework';
|
||||
|
||||
// 获取时间信息
|
||||
console.log("帧时间:", es.Time.deltaTime);
|
||||
console.log("总时间:", es.Time.totalTime);
|
||||
console.log("帧数:", es.Time.frameCount);
|
||||
console.log("时间缩放:", es.Time.timeScale);
|
||||
console.log("帧时间:", Time.deltaTime);
|
||||
console.log("总时间:", Time.totalTime);
|
||||
console.log("帧数:", Time.frameCount);
|
||||
console.log("时间缩放:", Time.timeScale);
|
||||
|
||||
// 设置时间缩放(慢动作效果)
|
||||
es.Time.timeScale = 0.5;
|
||||
Time.timeScale = 0.5;
|
||||
|
||||
// 检查时间间隔
|
||||
if (es.Time.checkEvery(1.0, lastCheckTime)) {
|
||||
if (Time.checkEvery(1.0, lastCheckTime)) {
|
||||
// 每秒执行一次
|
||||
}
|
||||
```
|
||||
|
||||
## Vector2(二维向量)
|
||||
|
||||
二维向量类,提供数学运算:
|
||||
|
||||
```typescript
|
||||
// 创建向量
|
||||
const vec1 = new es.Vector2(10, 20);
|
||||
const vec2 = es.Vector2.zero;
|
||||
const vec3 = es.Vector2.one;
|
||||
|
||||
// 向量运算
|
||||
const sum = vec1.add(vec2);
|
||||
const diff = vec1.subtract(vec2);
|
||||
const scaled = vec1.multiply(2);
|
||||
const normalized = vec1.normalize();
|
||||
|
||||
// 向量属性
|
||||
console.log("长度:", vec1.length);
|
||||
console.log("长度平方:", vec1.lengthSquared);
|
||||
|
||||
// 静态方法
|
||||
const distance = es.Vector2.distance(vec1, vec2);
|
||||
const lerped = es.Vector2.lerp(vec1, vec2, 0.5);
|
||||
const fromAngle = es.Vector2.fromAngle(Math.PI / 4);
|
||||
```
|
||||
|
||||
## 性能监控
|
||||
|
||||
框架内置性能监控工具:
|
||||
|
||||
```typescript
|
||||
import { PerformanceMonitor } from '@esengine/ecs-framework';
|
||||
|
||||
// 获取性能监控实例
|
||||
const monitor = es.PerformanceMonitor.instance;
|
||||
const monitor = PerformanceMonitor.instance;
|
||||
|
||||
// 查看性能数据
|
||||
console.log("平均FPS:", monitor.averageFPS);
|
||||
@@ -493,22 +512,46 @@ monitor.reset();
|
||||
内存管理优化工具:
|
||||
|
||||
```typescript
|
||||
// 创建对象池
|
||||
class BulletPool extends es.Pool<Bullet> {
|
||||
protected createObject(): Bullet {
|
||||
return new Bullet();
|
||||
import { Pool, IPoolable } from '@esengine/ecs-framework';
|
||||
|
||||
// 定义可池化的对象(需要实现IPoolable接口)
|
||||
class Bullet implements IPoolable {
|
||||
public x: number = 0;
|
||||
public y: number = 0;
|
||||
public speed: number = 0;
|
||||
|
||||
// 重置对象状态,准备重用
|
||||
public reset(): void {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.speed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const bulletPool = new BulletPool();
|
||||
// 创建对象池
|
||||
const bulletPool = new Pool<Bullet>(() => new Bullet(), 100);
|
||||
|
||||
// 预热对象池
|
||||
bulletPool.warmUp(20);
|
||||
|
||||
// 使用对象池
|
||||
const bullet = bulletPool.obtain();
|
||||
// 使用bullet...
|
||||
bullet.x = 100;
|
||||
bullet.y = 200;
|
||||
bullet.speed = 500;
|
||||
|
||||
// 使用完后归还到池中
|
||||
bulletPool.free(bullet);
|
||||
|
||||
// 查看池统计信息
|
||||
console.log(bulletPool.getStats());
|
||||
|
||||
// 清空对象池
|
||||
bulletPool.clear();
|
||||
|
||||
// 使用静态方法(自动管理池)
|
||||
const bullet2 = Pool.obtain(Bullet);
|
||||
Pool.free(Bullet, bullet2);
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
@@ -539,57 +582,18 @@ bulletPool.clear();
|
||||
|
||||
## 高级性能优化功能
|
||||
|
||||
### 位掩码优化器
|
||||
### 查询系统优化
|
||||
|
||||
位掩码优化器可以预计算和缓存常用的组件掩码,提升查询性能。
|
||||
框架内部已集成查询优化,无需手动配置。查询系统会自动使用最优的算法:
|
||||
|
||||
```typescript
|
||||
import { BitMaskOptimizer } from '@esengine/ecs-framework';
|
||||
// 查询系统会自动优化这些操作
|
||||
const movingEntities = scene.querySystem.queryAll(PositionComponent, VelocityComponent);
|
||||
const renderableEntities = scene.querySystem.queryAll(PositionComponent, RenderComponent);
|
||||
|
||||
const optimizer = BitMaskOptimizer.getInstance();
|
||||
|
||||
// 注册组件类型
|
||||
optimizer.registerComponentType(PositionComponent);
|
||||
optimizer.registerComponentType(VelocityComponent);
|
||||
optimizer.registerComponentType(RenderComponent);
|
||||
|
||||
// 预计算常用掩码组合
|
||||
optimizer.precomputeCommonMasks();
|
||||
|
||||
// 获取优化的掩码
|
||||
const positionMask = optimizer.getComponentMask(PositionComponent);
|
||||
const movementMask = optimizer.getCombinedMask([PositionComponent, VelocityComponent]);
|
||||
|
||||
// 掩码操作
|
||||
const hasBothComponents = optimizer.hasAllComponents(entityMask, movementMask);
|
||||
const hasAnyComponent = optimizer.hasAnyComponent(entityMask, movementMask);
|
||||
|
||||
// 获取掩码分析
|
||||
const analysis = optimizer.analyzeMask(entityMask);
|
||||
console.log('掩码包含的组件类型:', analysis.componentTypes);
|
||||
```
|
||||
|
||||
### 延迟索引更新器
|
||||
|
||||
批量更新索引可以显著提升大规模实体操作的性能。
|
||||
|
||||
```typescript
|
||||
import { IndexUpdateBatcher } from '@esengine/ecs-framework';
|
||||
|
||||
const batcher = new IndexUpdateBatcher((updates) => {
|
||||
// 处理批量更新
|
||||
console.log(`批量处理 ${updates.length} 个索引更新`);
|
||||
});
|
||||
|
||||
// 配置批量大小和延迟
|
||||
batcher.configure(100, 16); // 批量大小100,延迟16ms
|
||||
|
||||
// 添加更新任务
|
||||
batcher.addUpdate("add", entity, componentMask);
|
||||
batcher.addUpdate("remove", entity, componentMask);
|
||||
|
||||
// 强制刷新
|
||||
batcher.flush();
|
||||
// 获取查询统计信息
|
||||
const queryStats = scene.querySystem.getStats();
|
||||
console.log('查询统计:', queryStats);
|
||||
```
|
||||
|
||||
### 批量操作API
|
||||
@@ -598,14 +602,8 @@ batcher.flush();
|
||||
// 批量创建实体 - 最高性能
|
||||
const entities = scene.createEntities(10000, "Bullets");
|
||||
|
||||
// 延迟缓存清理
|
||||
entities.forEach(entity => {
|
||||
scene.addEntity(entity, false); // 延迟清理
|
||||
});
|
||||
scene.querySystem.clearCache(); // 手动清理
|
||||
|
||||
// 批量查询优化
|
||||
const movingEntities = scene.getEntitiesWithComponents([PositionComponent, VelocityComponent]);
|
||||
const movingEntities = scene.querySystem.queryAll(PositionComponent, VelocityComponent).entities;
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
Reference in New Issue
Block a user