Files
esengine/docs/getting-started.md
YHH 6ea366cfed 优化matcher内部实现改为querysystem
完善type类型
更新文档
2025-07-31 11:56:04 +08:00

699 lines
19 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.
# 快速入门
本指南将帮助您快速上手 ECS Framework这是一个专业级的实体组件系统框架采用现代化架构设计专为高性能游戏开发打造。
## 安装
```bash
npm install @esengine/ecs-framework
```
## 更新机制说明
ECS框架需要在游戏引擎的更新循环中调用并传入deltaTime
```typescript
// 统一的更新方式让外部引擎传入deltaTime
Core.update(deltaTime);
```
**不同平台的集成方式:**
- **Laya引擎**:使用 `Laya.timer.delta / 1000`
- **Cocos Creator**:使用组件的 `update(deltaTime)` 参数
- **原生浏览器**自己计算deltaTime
- **Node.js服务器**自己计算deltaTime
**优势:**
- 与引擎时间系统完全同步
- 支持引擎的时间缩放和暂停功能
- 更精确的时间控制
- 统一的API简化集成
## Core配置
### 基础配置
ECS框架提供了灵活的配置选项来满足不同项目需求
```typescript
import { Core, ICoreConfig } from '@esengine/ecs-framework';
// 方式1简化配置向后兼容
Core.create(true); // 启用调试模式
Core.create(false); // 发布模式
Core.create(); // 默认调试模式
// 方式2详细配置推荐
const config: ICoreConfig = {
debug: true, // 启用调试模式
enableEntitySystems: true, // 启用实体系统默认true
debugConfig: { // 可选:远程调试配置
enabled: true,
websocketUrl: 'ws://localhost:8080',
autoReconnect: true,
updateInterval: 1000, // 调试数据更新间隔(毫秒)
channels: { // 调试数据通道
entities: true, // 实体信息
systems: true, // 系统信息
performance: true, // 性能数据
components: true, // 组件信息
scenes: true // 场景信息
}
}
};
const core = Core.create(config);
```
### 调试功能
ECS框架内置了强大的调试功能支持运行时监控和远程调试
#### Cocos Creator专用调试插件
** 对于Cocos Creator用户我们提供了专门的可视化调试插件**
- **插件地址**[cocos-ecs-framework 调试插件](https://store.cocos.com/app/detail/7823)
- **插件版本**v1.0.0
- **支持版本**Cocos Creator v3.0.0+
- **支持平台**Android | iOS | HTML5
这个插件提供了完整的ECS可视化调试界面包括实体查看器、组件编辑器、系统监控、性能分析等功能。
#### 通用调试配置
```typescript
// 运行时启用调试
Core.enableDebug({
enabled: true,
websocketUrl: 'ws://localhost:8080',
autoReconnect: true,
updateInterval: 500,
channels: {
entities: true,
systems: true,
performance: true,
components: false, // 可以选择性禁用某些通道
scenes: true
}
});
// 获取调试数据
const debugData = Core.getDebugData();
console.log('当前实体数量:', debugData?.entities?.totalEntities);
// 禁用调试
Core.disableDebug();
// 检查调试状态
if (Core.isDebugEnabled) {
console.log('调试模式已启用');
}
```
### 生产环境配置建议
```typescript
// 开发环境 - Cocos Creator
const devConfigForCocos: ICoreConfig = {
debug: true,
enableEntitySystems: true,
debugConfig: {
enabled: true,
websocketUrl: 'ws://localhost:8080', // 连接Cocos插件
autoReconnect: true,
updateInterval: 1000,
channels: {
entities: true,
systems: true,
performance: true,
components: true,
scenes: true
}
}
};
// 开发环境 - 其他平台
const devConfig: ICoreConfig = {
debug: true,
enableEntitySystems: true,
debugConfig: {
enabled: true,
websocketUrl: 'ws://localhost:8080',
autoReconnect: true,
updateInterval: 1000,
channels: {
entities: true,
systems: true,
performance: true,
components: true,
scenes: true
}
}
};
// 生产环境
const prodConfig: ICoreConfig = {
debug: false, // 关闭调试以提升性能
enableEntitySystems: true,
// debugConfig 可以省略或设为 undefined
};
const isDevelopment = process.env.NODE_ENV === 'development';
Core.create(isDevelopment ? devConfig : prodConfig);
```
** 调试功能说明:**
- **Cocos Creator**:推荐使用[官方调试插件](https://store.cocos.com/app/detail/7823)获得最佳调试体验
- **其他平台**可以通过WebSocket连接自定义调试工具
- **生产环境**:建议关闭调试功能以获得最佳性能
## 平台集成
### Laya引擎
```typescript
import { Scene as LayaScene } from "laya/display/Scene";
import { Core, Scene as ECSScene, EntityManager, EntitySystem } from '@esengine/ecs-framework';
class LayaECSGame extends LayaScene {
private ecsScene: ECSScene;
private entityManager: EntityManager;
constructor() {
super();
// 初始化ECS框架简化方式
Core.create(true); // 启用调试模式
// 完整配置示例: Core.create({ debug: true, enableEntitySystems: true, debugConfig: {...} })
this.ecsScene = new ECSScene();
this.ecsScene.name = "LayaGameScene";
Core.scene = this.ecsScene;
this.entityManager = new EntityManager();
this.setupSystems();
}
onAwake(): void {
super.onAwake();
// 使用Laya的帧循环更新ECS
Laya.timer.frameLoop(1, this, this.updateECS);
}
onDestroy(): void {
Laya.timer.clear(this, this.updateECS);
super.onDestroy();
}
private updateECS(): void {
// 使用Laya的deltaTime更新ECS
const deltaTime = Laya.timer.delta / 1000; // 转换为秒
Core.update(deltaTime);
}
private setupSystems(): void {
this.ecsScene.addEntityProcessor(new LayaRenderSystem(this));
this.ecsScene.addEntityProcessor(new MovementSystem());
}
}
// Laya渲染系统
class LayaRenderSystem extends EntitySystem {
private layaScene: LayaScene;
private renderMatcher: Matcher;
constructor(layaScene: LayaScene) {
super();
this.layaScene = layaScene;
}
public initialize(): void {
super.initialize();
// 创建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 sprite = entity.getComponent(SpriteComponent)!;
if (pos && sprite && sprite.layaSprite) {
sprite.layaSprite.x = pos.x;
sprite.layaSprite.y = pos.y;
}
});
}
}
// 使用方法
Laya.Scene.open("GameScene.scene", false, null, null, LayaECSGame);
```
### Cocos Creator
```typescript
import { Component as CocosComponent, _decorator } from 'cc';
import { Core, Scene as ECSScene, EntityManager, EntitySystem } from '@esengine/ecs-framework';
const { ccclass, property } = _decorator;
@ccclass('ECSGameManager')
export class ECSGameManager extends CocosComponent {
private ecsScene: ECSScene;
private entityManager: EntityManager;
start() {
// 初始化ECS框架简化方式
Core.create(true); // 启用调试模式
// 完整配置示例: Core.create({ debug: true, enableEntitySystems: true, debugConfig: {...} })
this.ecsScene = new ECSScene();
this.ecsScene.name = "CocosGameScene";
Core.scene = this.ecsScene;
this.entityManager = new EntityManager();
this.setupSystems();
}
update(deltaTime: number) {
// 使用Cocos Creator的deltaTime更新ECS
Core.update(deltaTime);
}
onDestroy() {
if (this.ecsScene) {
this.ecsScene.onDestroy();
}
}
private setupSystems(): void {
this.ecsScene.addEntityProcessor(new CocosRenderSystem(this.node));
this.ecsScene.addEntityProcessor(new MovementSystem());
}
public getEntityManager(): EntityManager {
return this.entityManager;
}
}
// Cocos渲染系统
class CocosRenderSystem extends EntitySystem {
private rootNode: Node;
private renderMatcher: Matcher;
constructor(rootNode: Node) {
super();
this.rootNode = rootNode;
}
public initialize(): void {
super.initialize();
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 sprite = entity.getComponent(SpriteComponent)!;
if (sprite.cocosNode) {
sprite.cocosNode.setPosition(pos.x, pos.y);
}
});
}
}
// 将ECSGameManager脚本挂载到场景根节点
```
** Cocos Creator调试提示**
为了获得最佳的ECS调试体验建议安装我们的专用调试插件
- 插件地址:[https://store.cocos.com/app/detail/7823](https://store.cocos.com/app/detail/7823)
- 支持Cocos Creator v3.0.0+
- 提供实体查看器、组件编辑器、系统监控等功能
### Node.js后端
```typescript
import { Core, Scene, EntityManager, EntitySystem, Time } from '@esengine/ecs-framework';
class ServerGameManager {
private scene: Scene;
private entityManager: EntityManager;
private isRunning: boolean = false;
private tickRate: number = 60; // 60 TPS
private lastUpdate: number = Date.now();
constructor() {
// 初始化ECS框架简化方式
Core.create(true); // 启用调试模式
// 完整配置示例: Core.create({ debug: true, enableEntitySystems: true, debugConfig: {...} })
this.scene = new Scene();
this.scene.name = "ServerScene";
Core.scene = this.scene;
this.entityManager = new EntityManager();
this.setupSystems();
}
public start(): void {
this.isRunning = true;
console.log(`游戏服务器启动TPS: ${this.tickRate}`);
this.gameLoop();
}
public stop(): void {
this.isRunning = false;
}
private gameLoop(): void {
if (!this.isRunning) return;
const now = Date.now();
const deltaTime = (now - this.lastUpdate) / 1000;
this.lastUpdate = now;
// 使用计算出的deltaTime更新ECS
Core.update(deltaTime);
const frameTime = 1000 / this.tickRate;
const processingTime = Date.now() - now;
const delay = Math.max(0, frameTime - processingTime);
setTimeout(() => this.gameLoop(), delay);
}
private setupSystems(): void {
this.scene.addEntityProcessor(new ServerMovementSystem());
this.scene.addEntityProcessor(new NetworkSyncSystem());
this.scene.addEntityProcessor(new AISystem());
}
public handlePlayerInput(playerId: string, input: any): void {
const playerEntity = this.findPlayerEntity(playerId);
if (playerEntity) {
const inputComp = playerEntity.getComponent(InputComponent);
if (inputComp) {
inputComp.updateInput(input);
}
}
}
public getWorldState(): any {
const entities = this.entityManager
.query()
.withAll(PositionComponent, NetworkComponent)
.execute();
return entities.map(entity => ({
id: entity.id,
position: entity.getComponent(PositionComponent),
}));
}
private findPlayerEntity(playerId: string): Entity | null {
const players = this.entityManager
.query()
.withAll(PlayerComponent)
.execute();
return players.find(player =>
player.getComponent(PlayerComponent).playerId === playerId
) || null;
}
}
// 启动服务器
const server = new ServerGameManager();
server.start();
```
### 原生浏览器
```typescript
import { Core, Scene, EntityManager, EntitySystem } from '@esengine/ecs-framework';
class BrowserGame {
private scene: Scene;
private entityManager: EntityManager;
constructor() {
// 初始化ECS框架简化方式
Core.create(true); // 启用调试模式
// 完整配置示例: Core.create({ debug: true, enableEntitySystems: true, debugConfig: {...} })
this.scene = new Scene();
this.scene.name = "BrowserScene";
Core.scene = this.scene;
this.entityManager = new EntityManager();
this.setupSystems();
}
public start(): void {
this.createEntities();
this.gameLoop();
}
private gameLoop(): void {
let lastTime = 0;
const update = (currentTime: number) => {
// 计算deltaTime并更新ECS原生浏览器环境
const deltaTime = lastTime > 0 ? (currentTime - lastTime) / 1000 : 0.016;
lastTime = currentTime;
Core.update(deltaTime);
requestAnimationFrame(update);
};
requestAnimationFrame(update);
}
private setupSystems(): void {
this.scene.addEntityProcessor(new MovementSystem());
this.scene.addEntityProcessor(new RenderSystem());
}
private createEntities(): void {
const player = this.entityManager.createEntity("Player");
player.addComponent(new PositionComponent(400, 300));
player.addComponent(new VelocityComponent(0, 0));
}
}
const game = new BrowserGame();
game.start();
```
## 基础组件定义
```typescript
import { Component } from '@esengine/ecs-framework';
// 位置组件
class PositionComponent extends Component {
public x: number = 0;
public y: number = 0;
constructor(x: number = 0, y: number = 0) {
super();
this.x = x;
this.y = y;
}
public reset() {
this.x = 0;
this.y = 0;
}
}
// 速度组件
class VelocityComponent extends Component {
public x: number = 0;
public y: number = 0;
constructor(x: number = 0, y: number = 0) {
super();
this.x = x;
this.y = y;
}
public reset() {
this.x = 0;
this.y = 0;
}
}
// 生命值组件
class HealthComponent extends Component {
public maxHealth: number = 100;
public currentHealth: number = 100;
constructor(maxHealth: number = 100) {
super();
this.maxHealth = maxHealth;
this.currentHealth = maxHealth;
}
public reset() {
this.maxHealth = 100;
this.currentHealth = 100;
}
public takeDamage(damage: number): void {
this.currentHealth = Math.max(0, this.currentHealth - damage);
}
public heal(amount: number): void {
this.currentHealth = Math.min(this.maxHealth, this.currentHealth + amount);
}
public isDead(): boolean {
return this.currentHealth <= 0;
}
}
```
## 基础系统创建
```typescript
import { EntitySystem, Entity, Matcher, Time } from '@esengine/ecs-framework';
class MovementSystem extends EntitySystem {
constructor() {
super(Matcher.all(PositionComponent, VelocityComponent));
}
protected process(entities: Entity[]): void {
const movingEntities = entities;
movingEntities.forEach(entity => {
const position = entity.getComponent(PositionComponent);
const velocity = entity.getComponent(VelocityComponent);
if (position && velocity) {
position.x += velocity.x * Time.deltaTime;
position.y += velocity.y * Time.deltaTime;
}
});
}
}
class HealthSystem extends EntitySystem {
private healthMatcher: Matcher;
constructor() {
super();
}
public initialize(): void {
super.initialize();
if (this.scene) {
this.healthMatcher = Matcher.create(this.scene.querySystem)
.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();
}
});
}
}
```
## 实体管理
```typescript
// 创建实体
const player = entityManager.createEntity("Player");
player.addComponent(new PositionComponent(100, 100));
player.addComponent(new VelocityComponent(5, 0));
player.addComponent(new HealthComponent(100));
// 批量创建实体
const enemies = scene.createEntities(50, "Enemy");
enemies.forEach(enemy => {
enemy.addComponent(new PositionComponent(Math.random() * 800, Math.random() * 600));
enemy.addComponent(new HealthComponent(50));
});
// 查询实体
const movingEntities = entityManager
.query()
.withAll(PositionComponent, VelocityComponent)
.execute();
const healthEntities = entityManager.getEntitiesWithComponent(HealthComponent);
const enemiesByTag = entityManager.getEntitiesByTag(2);
```
## 事件系统
推荐使用Scene的事件系统或EntityManager的事件系统
```typescript
// 使用EntityManager的事件系统推荐
const eventBus = entityManager.eventBus;
// 监听ECS事件
eventBus.onEntityCreated((data) => {
console.log(`实体创建: ${data.entityName}`);
});
eventBus.onComponentAdded((data) => {
console.log(`组件添加: ${data.componentType}`);
});
// 发射自定义事件
eventBus.emit('player:died', { player: entity, score: 1000 });
// 使用装饰器自动注册事件监听器
import { EventHandler } from '@esengine/ecs-framework';
class GameSystem {
@EventHandler('player:died')
onPlayerDied(data: { player: Entity; score: number }) {
console.log(`玩家死亡,得分: ${data.score}`);
}
}
```
## 性能监控
```typescript
// 获取场景统计
const sceneStats = scene.getStats();
console.log('实体数量:', sceneStats.entityCount);
console.log('系统数量:', sceneStats.processorCount);
// 获取查询统计
const queryStats = scene.querySystem.getStats();
console.log('查询统计:', queryStats);
```
## 下一步
- [EntityManager 使用指南](entity-manager-example.md) - 详细了解实体管理器的高级功能
- [性能优化指南](performance-optimization.md) - 深入了解三大性能优化系统
- [核心概念](core-concepts.md) - 深入了解 ECS 架构和设计原理
- [查询系统使用指南](query-system-usage.md) - 学习高性能查询系统的详细用法