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