更新文档

This commit is contained in:
YHH
2025-08-11 08:18:18 +08:00
parent 3b9ae4f384
commit d539bb3dd9
2 changed files with 78 additions and 89 deletions

View File

@@ -49,7 +49,7 @@ npm install @esengine/ecs-framework
### 1. 基础使用 ### 1. 基础使用
```typescript ```typescript
import { Core, Scene, Entity, Component, EntitySystem } from '@esengine/ecs-framework'; import { Core, Scene, Entity, Component, EntitySystem, Matcher, Time } from '@esengine/ecs-framework';
// 创建核心实例 // 创建核心实例
const core = Core.create({ debug: true }); const core = Core.create({ debug: true });
@@ -58,14 +58,26 @@ Core.scene = scene;
// 定义组件 // 定义组件
class PositionComponent extends Component { class PositionComponent extends Component {
constructor(public x: number = 0, public y: number = 0) { public x: number = 0;
public y: number = 0;
constructor(...args: unknown[]) {
super(); super();
const [x = 0, y = 0] = args as [number?, number?];
this.x = x;
this.y = y;
} }
} }
class VelocityComponent extends Component { class VelocityComponent extends Component {
constructor(public dx: number = 0, public dy: number = 0) { public x: number = 0;
public y: number = 0;
constructor(...args: unknown[]) {
super(); super();
const [x = 0, y = 0] = args as [number?, number?];
this.x = x;
this.y = y;
} }
} }
@@ -76,15 +88,17 @@ entity.addComponent(new VelocityComponent(5, 0));
// 创建系统 // 创建系统
class MovementSystem extends EntitySystem { class MovementSystem extends EntitySystem {
public process(entities: Entity[]) { constructor() {
for (const entity of entities) { super(Matcher.all(PositionComponent, VelocityComponent));
const position = entity.getComponent(PositionComponent);
const velocity = entity.getComponent(VelocityComponent);
if (position && velocity) {
position.x += velocity.dx;
position.y += velocity.dy;
} }
protected override process(entities: Entity[]) {
for (const entity of entities) {
const position = entity.getComponent(PositionComponent)!;
const velocity = entity.getComponent(VelocityComponent)!;
position.x += velocity.x * Time.deltaTime;
position.y += velocity.y * Time.deltaTime;
} }
} }
} }
@@ -100,16 +114,26 @@ Core.update(deltaTime);
### 查询系统 ### 查询系统
```typescript ```typescript
import { EntityManager } from '@esengine/ecs-framework'; import { Matcher } from '@esengine/ecs-framework';
const entityManager = new EntityManager(); // 方式1使用Matcher和EntitySystem
class QuerySystem extends EntitySystem {
constructor() {
super(Matcher.all(PositionComponent, VelocityComponent).none(HealthComponent));
}
// 流式查询 API protected override process(entities: Entity[]) {
const results = entityManager // 处理匹配的实体
.query() console.log(`Found ${entities.length} entities`);
.withAll(PositionComponent, VelocityComponent) }
.withNone(HealthComponent) }
.execute();
// 方式2手动过滤场景中的实体
const results = scene.entities.buffer.filter(entity =>
entity.hasComponent(PositionComponent) &&
entity.hasComponent(VelocityComponent) &&
!entity.hasComponent(HealthComponent)
);
``` ```
### 事件系统 ### 事件系统
@@ -119,7 +143,7 @@ import { EventHandler, ECSEventType } from '@esengine/ecs-framework';
class GameSystem { class GameSystem {
@EventHandler(ECSEventType.ENTITY_DESTROYED) @EventHandler(ECSEventType.ENTITY_DESTROYED)
onEntityDestroyed(data: EntityDestroyedEventData) { onEntityDestroyed(data: any) {
console.log('实体销毁:', data.entityName); console.log('实体销毁:', data.entityName);
} }
} }
@@ -198,12 +222,16 @@ function gameLoop(currentTime: number) {
### 查询 API ### 查询 API
```typescript ```typescript
entityManager.query() // Matcher API - 用于EntitySystem
.withAll(...components) // 包含所有组件 Matcher.all(...components) // 包含所有组件
.withAny(...components) // 包含任意组件 Matcher.any(...components) // 包含任意组件
.withNone(...components) // 不包含组件 Matcher.none(...components) // 不包含组件
.withTag(tag) // 包含标签
.execute() // 执行查询 // 手动查询 - 用于场景实体过滤
scene.entities.buffer.filter(entity =>
entity.hasComponent(ComponentA) &&
entity.tag === someTag
);
``` ```
## 文档 ## 文档

View File

@@ -221,31 +221,18 @@ class LayaECSGame extends LayaScene {
// Laya渲染系统 // Laya渲染系统
class LayaRenderSystem extends EntitySystem { class LayaRenderSystem extends EntitySystem {
private layaScene: LayaScene; private layaScene: LayaScene;
private renderMatcher: Matcher;
constructor(layaScene: LayaScene) { constructor(layaScene: LayaScene) {
super(); super(Matcher.all(PositionComponent, SpriteComponent));
this.layaScene = layaScene; this.layaScene = layaScene;
} }
public initialize(): void { protected override process(entities: Entity[]): void {
super.initialize(); entities.forEach(entity => {
// 创建Matcher来查询需要渲染的实体
if (this.scene) {
this.renderMatcher = Matcher.create(this.scene.querySystem)
.all(PositionComponent, SpriteComponent);
}
}
protected process(entities: Entity[]): void {
// 获取需要渲染的实体
const renderableEntities = this.renderMatcher.query();
renderableEntities.forEach(entity => {
const pos = entity.getComponent(PositionComponent)!; const pos = entity.getComponent(PositionComponent)!;
const sprite = entity.getComponent(SpriteComponent)!; const sprite = entity.getComponent(SpriteComponent)!;
if (pos && sprite && sprite.layaSprite) { if (sprite.layaSprite) {
sprite.layaSprite.x = pos.x; sprite.layaSprite.x = pos.x;
sprite.layaSprite.y = pos.y; sprite.layaSprite.y = pos.y;
} }
@@ -260,7 +247,7 @@ Laya.Scene.open("GameScene.scene", false, null, null, LayaECSGame);
### Cocos Creator ### Cocos Creator
```typescript ```typescript
import { Component as CocosComponent, _decorator } from 'cc'; import { Component as CocosComponent, _decorator, Node } from 'cc';
import { Core, Scene as ECSScene, EntityManager, EntitySystem } from '@esengine/ecs-framework'; import { Core, Scene as ECSScene, EntityManager, EntitySystem } from '@esengine/ecs-framework';
const { ccclass, property } = _decorator; const { ccclass, property } = _decorator;
@@ -307,25 +294,14 @@ export class ECSGameManager extends CocosComponent {
// Cocos渲染系统 // Cocos渲染系统
class CocosRenderSystem extends EntitySystem { class CocosRenderSystem extends EntitySystem {
private rootNode: Node; private rootNode: Node;
private renderMatcher: Matcher;
constructor(rootNode: Node) { constructor(rootNode: Node) {
super(); super(Matcher.all(PositionComponent, SpriteComponent));
this.rootNode = rootNode; this.rootNode = rootNode;
} }
public initialize(): void { protected override process(entities: Entity[]): void {
super.initialize(); entities.forEach(entity => {
if (this.scene) {
this.renderMatcher = Matcher.create(this.scene.querySystem)
.all(PositionComponent, SpriteComponent);
}
}
protected process(entities: Entity[]): void {
const renderableEntities = this.renderMatcher.query();
renderableEntities.forEach(entity => {
const pos = entity.getComponent(PositionComponent)!; const pos = entity.getComponent(PositionComponent)!;
const sprite = entity.getComponent(SpriteComponent)!; const sprite = entity.getComponent(SpriteComponent)!;
@@ -507,8 +483,9 @@ class PositionComponent extends Component {
public x: number = 0; public x: number = 0;
public y: number = 0; public y: number = 0;
constructor(x: number = 0, y: number = 0) { constructor(...args: unknown[]) {
super(); super();
const [x = 0, y = 0] = args as [number?, number?];
this.x = x; this.x = x;
this.y = y; this.y = y;
} }
@@ -524,8 +501,9 @@ class VelocityComponent extends Component {
public x: number = 0; public x: number = 0;
public y: number = 0; public y: number = 0;
constructor(x: number = 0, y: number = 0) { constructor(...args: unknown[]) {
super(); super();
const [x = 0, y = 0] = args as [number?, number?];
this.x = x; this.x = x;
this.y = y; this.y = y;
} }
@@ -541,8 +519,9 @@ class HealthComponent extends Component {
public maxHealth: number = 100; public maxHealth: number = 100;
public currentHealth: number = 100; public currentHealth: number = 100;
constructor(maxHealth: number = 100) { constructor(...args: unknown[]) {
super(); super();
const [maxHealth = 100] = args as [number?];
this.maxHealth = maxHealth; this.maxHealth = maxHealth;
this.currentHealth = maxHealth; this.currentHealth = maxHealth;
} }
@@ -576,44 +555,26 @@ class MovementSystem extends EntitySystem {
super(Matcher.all(PositionComponent, VelocityComponent)); super(Matcher.all(PositionComponent, VelocityComponent));
} }
protected process(entities: Entity[]): void { protected override process(entities: Entity[]): void {
const movingEntities = entities; entities.forEach(entity => {
const position = entity.getComponent(PositionComponent)!;
const velocity = entity.getComponent(VelocityComponent)!;
movingEntities.forEach(entity => {
const position = entity.getComponent(PositionComponent);
const velocity = entity.getComponent(VelocityComponent);
if (position && velocity) {
position.x += velocity.x * Time.deltaTime; position.x += velocity.x * Time.deltaTime;
position.y += velocity.y * Time.deltaTime; position.y += velocity.y * Time.deltaTime;
}
}); });
} }
} }
class HealthSystem extends EntitySystem { class HealthSystem extends EntitySystem {
private healthMatcher: Matcher;
constructor() { constructor() {
super(); super(Matcher.all(HealthComponent));
} }
public initialize(): void { protected override process(entities: Entity[]): void {
super.initialize(); entities.forEach(entity => {
if (this.scene) { const health = entity.getComponent(HealthComponent)!;
this.healthMatcher = Matcher.create(this.scene.querySystem) if (health.currentHealth <= 0) {
.all(HealthComponent);
}
}
protected process(entities: Entity[]): void {
if (!this.healthMatcher) return;
const healthEntities = this.healthMatcher.query();
healthEntities.forEach(entity => {
const health = entity.getComponent(HealthComponent);
if (health && health.currentHealth <= 0) {
entity.destroy(); entity.destroy();
} }
}); });