移除coreevents事件派发机制
This commit is contained in:
41
README.md
41
README.md
@@ -104,18 +104,41 @@ scene.addEntityProcessor(new MovementSystem());
|
||||
|
||||
### 游戏循环
|
||||
|
||||
ECS框架需要在游戏引擎的更新循环中调用:
|
||||
|
||||
```typescript
|
||||
function gameLoop() {
|
||||
// 更新场景
|
||||
scene.update();
|
||||
|
||||
// 发送帧更新事件
|
||||
Core.emitter.emit(CoreEvents.frameUpdated);
|
||||
|
||||
requestAnimationFrame(gameLoop);
|
||||
// 统一的API:传入deltaTime
|
||||
Core.update(deltaTime);
|
||||
```
|
||||
|
||||
**不同引擎的集成示例:**
|
||||
|
||||
```typescript
|
||||
// Laya引擎
|
||||
Laya.timer.frameLoop(1, this, () => {
|
||||
const deltaTime = Laya.timer.delta / 1000; // 转换为秒
|
||||
Core.update(deltaTime);
|
||||
});
|
||||
|
||||
// Cocos Creator
|
||||
update(deltaTime: number) {
|
||||
Core.update(deltaTime);
|
||||
}
|
||||
|
||||
gameLoop();
|
||||
// Unity (C#)
|
||||
void Update() {
|
||||
Core.Update(Time.deltaTime);
|
||||
}
|
||||
|
||||
// 原生浏览器环境
|
||||
let lastTime = 0;
|
||||
function gameLoop(currentTime: number) {
|
||||
const deltaTime = lastTime > 0 ? (currentTime - lastTime) / 1000 : 0.016;
|
||||
lastTime = currentTime;
|
||||
Core.update(deltaTime);
|
||||
requestAnimationFrame(gameLoop);
|
||||
}
|
||||
requestAnimationFrame(gameLoop);
|
||||
```
|
||||
|
||||
## 实体管理器
|
||||
|
||||
@@ -8,6 +8,28 @@
|
||||
npm install @esengine/ecs-framework
|
||||
```
|
||||
|
||||
## 更新机制说明
|
||||
|
||||
ECS框架需要在游戏引擎的更新循环中调用,并传入deltaTime:
|
||||
|
||||
```typescript
|
||||
// 统一的更新方式:让外部引擎传入deltaTime
|
||||
Core.update(deltaTime);
|
||||
```
|
||||
|
||||
**不同引擎的集成方式:**
|
||||
- **Laya引擎**:使用 `Laya.timer.delta / 1000`
|
||||
- **Cocos Creator**:使用组件的 `update(deltaTime)` 参数
|
||||
- **Unity**:使用 `Time.deltaTime`
|
||||
- **原生浏览器**:自己计算deltaTime
|
||||
- **Node.js服务器**:自己计算deltaTime
|
||||
|
||||
**优势:**
|
||||
- 与引擎时间系统完全同步
|
||||
- 支持引擎的时间缩放和暂停功能
|
||||
- 更精确的时间控制
|
||||
- 统一的API,简化集成
|
||||
|
||||
## 平台集成
|
||||
|
||||
### Laya引擎
|
||||
@@ -45,7 +67,9 @@ class LayaECSGame extends LayaScene {
|
||||
}
|
||||
|
||||
private updateECS(): void {
|
||||
this.ecsScene.update();
|
||||
// 使用Laya的deltaTime更新ECS
|
||||
const deltaTime = Laya.timer.delta / 1000; // 转换为秒
|
||||
Core.update(deltaTime);
|
||||
}
|
||||
|
||||
private setupSystems(): void {
|
||||
@@ -105,8 +129,8 @@ export class ECSGameManager extends CocosComponent {
|
||||
}
|
||||
|
||||
update(deltaTime: number) {
|
||||
// 在Cocos的update中更新ECS
|
||||
this.ecsScene.update();
|
||||
// 使用Cocos Creator的deltaTime更新ECS
|
||||
Core.update(deltaTime);
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
@@ -188,8 +212,8 @@ class ServerGameManager {
|
||||
const deltaTime = (now - this.lastUpdate) / 1000;
|
||||
this.lastUpdate = now;
|
||||
|
||||
Time.update(deltaTime);
|
||||
this.scene.update();
|
||||
// 使用计算出的deltaTime更新ECS
|
||||
Core.update(deltaTime);
|
||||
|
||||
const frameTime = 1000 / this.tickRate;
|
||||
const processingTime = Date.now() - now;
|
||||
@@ -268,11 +292,15 @@ class BrowserGame {
|
||||
}
|
||||
|
||||
private gameLoop(): void {
|
||||
const update = () => {
|
||||
this.scene.update();
|
||||
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);
|
||||
};
|
||||
update();
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
private setupSystems(): void {
|
||||
@@ -431,17 +459,33 @@ const enemiesByTag = entityManager.getEntitiesByTag(2);
|
||||
|
||||
## 事件系统
|
||||
|
||||
```typescript
|
||||
import { Core, CoreEvents } from '@esengine/ecs-framework';
|
||||
推荐使用Scene的事件系统或EntityManager的事件系统:
|
||||
|
||||
// 监听框架事件
|
||||
Core.emitter.addObserver(CoreEvents.frameUpdated, this.onFrameUpdate, this);
|
||||
```typescript
|
||||
// 使用EntityManager的事件系统(推荐)
|
||||
const eventBus = entityManager.eventBus;
|
||||
|
||||
// 监听ECS事件
|
||||
eventBus.onEntityCreated((data) => {
|
||||
console.log(`实体创建: ${data.entityName}`);
|
||||
});
|
||||
|
||||
eventBus.onComponentAdded((data) => {
|
||||
console.log(`组件添加: ${data.componentType}`);
|
||||
});
|
||||
|
||||
// 发射自定义事件
|
||||
Core.emitter.emit("playerDied", { player: entity, score: 1000 });
|
||||
eventBus.emit('player:died', { player: entity, score: 1000 });
|
||||
|
||||
// 移除监听
|
||||
Core.emitter.removeObserver(CoreEvents.frameUpdated, this.onFrameUpdate);
|
||||
// 使用装饰器自动注册事件监听器
|
||||
import { EventHandler } from '@esengine/ecs-framework';
|
||||
|
||||
class GameSystem {
|
||||
@EventHandler('player:died')
|
||||
onPlayerDied(data: { player: Entity; score: number }) {
|
||||
console.log(`玩家死亡,得分: ${data.score}`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 性能监控
|
||||
|
||||
66
src/Core.ts
66
src/Core.ts
@@ -1,5 +1,3 @@
|
||||
import { Emitter } from './Utils/Emitter';
|
||||
import { CoreEvents } from './ECS/CoreEvents';
|
||||
import { GlobalManager } from './Utils/GlobalManager';
|
||||
import { TimerManager } from './Utils/Timers/TimerManager';
|
||||
import { ITimer } from './Utils/Timers/ITimer';
|
||||
@@ -13,7 +11,7 @@ import { Scene } from './ECS/Scene';
|
||||
* 游戏引擎核心类
|
||||
*
|
||||
* 负责管理游戏的生命周期、场景切换、全局管理器和定时器系统。
|
||||
* 提供统一的游戏循环和事件分发机制。
|
||||
* 提供统一的游戏循环管理。
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
@@ -23,6 +21,12 @@ import { Scene } from './ECS/Scene';
|
||||
* // 设置场景
|
||||
* Core.scene = new MyScene();
|
||||
*
|
||||
* // 在游戏循环中更新(Laya引擎示例)
|
||||
* Laya.timer.frameLoop(1, this, () => {
|
||||
* const deltaTime = Laya.timer.delta / 1000;
|
||||
* Core.update(deltaTime);
|
||||
* });
|
||||
*
|
||||
* // 调度定时器
|
||||
* Core.schedule(1.0, false, null, (timer) => {
|
||||
* console.log("1秒后执行");
|
||||
@@ -30,13 +34,6 @@ import { Scene } from './ECS/Scene';
|
||||
* ```
|
||||
*/
|
||||
export class Core {
|
||||
/**
|
||||
* 核心事件发射器
|
||||
*
|
||||
* 用于发布和订阅核心级别的事件,如帧更新、场景切换等。
|
||||
*/
|
||||
public static emitter: Emitter<CoreEvents>;
|
||||
|
||||
/**
|
||||
* 游戏暂停状态
|
||||
*
|
||||
@@ -118,8 +115,6 @@ export class Core {
|
||||
*/
|
||||
private constructor(debug: boolean = true, enableEntitySystems: boolean = true) {
|
||||
Core._instance = this;
|
||||
Core.emitter = new Emitter<CoreEvents>();
|
||||
Core.emitter.addObserver(CoreEvents.frameUpdated, this.update, this);
|
||||
|
||||
// 初始化管理器
|
||||
this._timerManager = new TimerManager();
|
||||
@@ -186,7 +181,6 @@ export class Core {
|
||||
* 如果实例已存在,则返回现有实例。
|
||||
*
|
||||
* @param debug - 是否为调试模式,默认为true
|
||||
* @param options - 额外的配置选项
|
||||
* @returns Core实例
|
||||
*/
|
||||
public static create(debug: boolean = true): Core {
|
||||
@@ -196,7 +190,40 @@ export class Core {
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新游戏逻辑
|
||||
*
|
||||
* 此方法应该在游戏引擎的更新循环中调用。
|
||||
*
|
||||
* @param deltaTime - 外部引擎提供的帧时间间隔(秒)
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // Laya引擎
|
||||
* Laya.timer.frameLoop(1, this, () => {
|
||||
* const deltaTime = Laya.timer.delta / 1000;
|
||||
* Core.update(deltaTime);
|
||||
* });
|
||||
*
|
||||
* // Cocos Creator
|
||||
* update(deltaTime: number) {
|
||||
* Core.update(deltaTime);
|
||||
* }
|
||||
*
|
||||
* // Unity (C#)
|
||||
* void Update() {
|
||||
* Core.Update(Time.deltaTime);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
public static update(deltaTime: number): void {
|
||||
if (!this._instance) {
|
||||
console.warn("Core实例未创建,请先调用Core.create()");
|
||||
return;
|
||||
}
|
||||
|
||||
this._instance.updateInternal(deltaTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册全局管理器
|
||||
@@ -285,19 +312,18 @@ export class Core {
|
||||
}
|
||||
|
||||
/**
|
||||
* 游戏主循环更新
|
||||
* 内部更新方法
|
||||
*
|
||||
* 每帧调用,负责更新时间系统、全局管理器和当前场景。
|
||||
*
|
||||
* @param currentTime - 当前时间戳,默认为-1(使用系统时间)
|
||||
* @param deltaTime - 帧时间间隔(秒)
|
||||
*/
|
||||
protected update(currentTime: number = -1): void {
|
||||
private updateInternal(deltaTime: number): void {
|
||||
if (Core.paused) return;
|
||||
|
||||
// 开始性能监控
|
||||
const frameStartTime = this._performanceMonitor.startMonitoring('Core.update');
|
||||
|
||||
Time.update(currentTime);
|
||||
// 更新时间系统
|
||||
Time.update(deltaTime);
|
||||
|
||||
// 更新FPS监控(如果性能监控器支持)
|
||||
if (typeof (this._performanceMonitor as any).updateFPS === 'function') {
|
||||
|
||||
@@ -1,21 +1,4 @@
|
||||
/**
|
||||
* 核心事件枚举
|
||||
* 定义框架中的核心事件类型
|
||||
*/
|
||||
export enum CoreEvents {
|
||||
/**
|
||||
* 当场景发生变化时触发
|
||||
*/
|
||||
sceneChanged,
|
||||
/**
|
||||
* 每帧更新事件
|
||||
*/
|
||||
frameUpdated,
|
||||
/**
|
||||
* 当渲染发生时触发
|
||||
*/
|
||||
renderChanged,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ECS事件类型枚举
|
||||
@@ -112,13 +95,6 @@ export enum EventPriority {
|
||||
* 提供类型安全的事件类型字符串
|
||||
*/
|
||||
export const EVENT_TYPES = {
|
||||
// 核心事件
|
||||
CORE: {
|
||||
SCENE_CHANGED: 'core:scene:changed',
|
||||
FRAME_UPDATED: 'core:frame:updated',
|
||||
RENDER_CHANGED: 'core:render:changed'
|
||||
},
|
||||
|
||||
// 实体事件
|
||||
ENTITY: {
|
||||
CREATED: ECSEventType.ENTITY_CREATED,
|
||||
@@ -164,10 +140,8 @@ export const EVENT_TYPES = {
|
||||
* 验证事件类型是否有效
|
||||
*/
|
||||
export class EventTypeValidator {
|
||||
private static validTypes = new Set([
|
||||
...Object.values(CoreEvents).map(e => e.toString()),
|
||||
private static validTypes = new Set<string>([
|
||||
...Object.values(ECSEventType),
|
||||
...Object.values(EVENT_TYPES.CORE),
|
||||
...Object.values(EVENT_TYPES.ENTITY),
|
||||
...Object.values(EVENT_TYPES.COMPONENT),
|
||||
...Object.values(EVENT_TYPES.SYSTEM),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export { Entity } from './Entity';
|
||||
export { Component } from './Component';
|
||||
export { CoreEvents, ECSEventType, EventPriority, EVENT_TYPES, EventTypeValidator } from './CoreEvents';
|
||||
export { ECSEventType, EventPriority, EVENT_TYPES, EventTypeValidator } from './CoreEvents';
|
||||
export * from './Systems';
|
||||
export * from './Utils';
|
||||
export { Scene } from './Scene';
|
||||
|
||||
@@ -32,35 +32,15 @@ export class Time {
|
||||
* 当前帧数
|
||||
*/
|
||||
public static frameCount: number = 0;
|
||||
|
||||
/**
|
||||
* 上一帧的时间戳
|
||||
*/
|
||||
private static _lastTime: number = 0;
|
||||
|
||||
/**
|
||||
* 是否为第一次更新
|
||||
*/
|
||||
private static _isFirstUpdate: boolean = true;
|
||||
|
||||
/**
|
||||
* 更新时间信息
|
||||
* @param currentTime 当前时间戳(毫秒)
|
||||
* 使用外部引擎提供的deltaTime更新时间信息
|
||||
* @param deltaTime 外部引擎提供的帧时间间隔(秒)
|
||||
*/
|
||||
public static update(currentTime: number = -1): void {
|
||||
if (currentTime === -1) {
|
||||
currentTime = Date.now();
|
||||
}
|
||||
|
||||
if (this._isFirstUpdate) {
|
||||
this._lastTime = currentTime;
|
||||
this._isFirstUpdate = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算帧时间间隔(转换为秒)
|
||||
this.unscaledDeltaTime = (currentTime - this._lastTime) / 1000;
|
||||
this.deltaTime = this.unscaledDeltaTime * this.timeScale;
|
||||
public static update(deltaTime: number): void {
|
||||
// 设置未缩放的帧时间
|
||||
this.unscaledDeltaTime = deltaTime;
|
||||
this.deltaTime = deltaTime * this.timeScale;
|
||||
|
||||
// 更新总时间
|
||||
this.unscaledTotalTime += this.unscaledDeltaTime;
|
||||
@@ -68,16 +48,17 @@ export class Time {
|
||||
|
||||
// 更新帧数
|
||||
this.frameCount++;
|
||||
|
||||
// 记录当前时间
|
||||
this._lastTime = currentTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景改变时重置时间
|
||||
*/
|
||||
public static sceneChanged(): void {
|
||||
this._isFirstUpdate = true;
|
||||
this.frameCount = 0;
|
||||
this.totalTime = 0;
|
||||
this.unscaledTotalTime = 0;
|
||||
this.deltaTime = 0;
|
||||
this.unscaledDeltaTime = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
// 核心模块
|
||||
export { Core } from './Core';
|
||||
|
||||
// 核心事件和管理器
|
||||
export { CoreEvents } from './ECS/CoreEvents';
|
||||
// 核心管理器
|
||||
export { Emitter, FuncPack } from './Utils/Emitter';
|
||||
export { GlobalManager } from './Utils/GlobalManager';
|
||||
export { TimerManager } from './Utils/Timers/TimerManager';
|
||||
|
||||
Reference in New Issue
Block a user