2020-07-23 15:39:18 +08:00
|
|
|
|
module es {
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 全局核心类
|
|
|
|
|
|
*/
|
2020-11-23 16:05:06 +08:00
|
|
|
|
export class Core {
|
2020-07-23 15:39:18 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 核心发射器。只发出核心级别的事件
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static emitter: Emitter<CoreEvents>;
|
2020-11-26 10:39:32 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 启用/禁用焦点丢失时的暂停。如果为真,则不调用更新或渲染方法
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static pauseOnFocusLost = true;
|
2020-08-13 17:39:24 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 是否启用调试渲染
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static debugRenderEndabled = false;
|
2020-07-23 15:39:18 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 简化对内部类的全局内容实例的访问
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static _instance: Core;
|
2020-11-26 10:39:32 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 用于确定是否应该使用EntitySystems
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static entitySystemsEnabled: boolean;
|
|
|
|
|
|
|
2020-07-23 15:39:18 +08:00
|
|
|
|
public _nextScene: Scene;
|
2020-11-26 10:39:32 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 用于凝聚GraphicsDeviceReset事件
|
|
|
|
|
|
*/
|
|
|
|
|
|
public _graphicsDeviceChangeTimer: ITimer;
|
2020-07-23 15:39:18 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 全局访问系统
|
|
|
|
|
|
*/
|
2020-12-14 11:34:23 +08:00
|
|
|
|
public _globalManagers: GlobalManager[] = [];
|
2020-08-26 19:56:48 +08:00
|
|
|
|
public _timerManager: TimerManager = new TimerManager();
|
2020-11-23 16:05:06 +08:00
|
|
|
|
public width: number;
|
|
|
|
|
|
public height: number;
|
2020-07-23 15:39:18 +08:00
|
|
|
|
|
2020-11-26 10:39:32 +08:00
|
|
|
|
constructor(width: number, height: number, enableEntitySystems: boolean = true) {
|
2020-11-23 16:05:06 +08:00
|
|
|
|
this.width = width;
|
|
|
|
|
|
this.height = height;
|
2020-07-28 16:25:20 +08:00
|
|
|
|
|
|
|
|
|
|
Core._instance = this;
|
|
|
|
|
|
Core.emitter = new Emitter<CoreEvents>();
|
2020-11-24 12:15:20 +08:00
|
|
|
|
Core.emitter.addObserver(CoreEvents.FrameUpdated, this.update, this);
|
2020-08-26 19:56:48 +08:00
|
|
|
|
|
|
|
|
|
|
Core.registerGlobalManager(this._timerManager);
|
2020-11-26 10:39:32 +08:00
|
|
|
|
Core.entitySystemsEnabled = enableEntitySystems;
|
2020-11-23 16:05:06 +08:00
|
|
|
|
|
|
|
|
|
|
this.initialize();
|
2020-07-28 16:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 提供对单例/游戏实例的访问
|
|
|
|
|
|
* @constructor
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static get Instance() {
|
|
|
|
|
|
return this._instance;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-29 18:26:05 +08:00
|
|
|
|
public _frameCounterElapsedTime: number = 0;
|
|
|
|
|
|
public _frameCounter: number = 0;
|
2020-11-30 12:57:53 +08:00
|
|
|
|
public _totalMemory: number = 0;
|
2020-11-30 13:50:18 +08:00
|
|
|
|
public _titleMemory: (totalMemory: number, frameCounter: number) => void;
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public _scene: Scene;
|
|
|
|
|
|
|
2020-07-23 15:39:18 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 当前活动的场景。注意,如果设置了该设置,在更新结束之前场景实际上不会改变
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static get scene() {
|
2020-07-23 19:28:01 +08:00
|
|
|
|
if (!this._instance)
|
|
|
|
|
|
return null;
|
2020-07-23 15:39:18 +08:00
|
|
|
|
return this._instance._scene;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 当前活动的场景。注意,如果设置了该设置,在更新结束之前场景实际上不会改变
|
|
|
|
|
|
* @param value
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static set scene(value: Scene) {
|
2020-07-28 16:25:20 +08:00
|
|
|
|
if (!value) {
|
2020-07-23 15:39:18 +08:00
|
|
|
|
console.error("场景不能为空");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (this._instance._scene == null) {
|
2020-08-26 19:56:48 +08:00
|
|
|
|
this._instance._scene = value;
|
2020-12-10 16:15:19 +08:00
|
|
|
|
this._instance.onSceneChanged();
|
2020-07-23 15:39:18 +08:00
|
|
|
|
this._instance._scene.begin();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this._instance._nextScene = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-07-28 16:25:20 +08:00
|
|
|
|
* 添加一个全局管理器对象,它的更新方法将调用场景前的每一帧。
|
|
|
|
|
|
* @param manager
|
2020-07-23 15:39:18 +08:00
|
|
|
|
*/
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public static registerGlobalManager(manager: es.GlobalManager) {
|
2020-12-14 11:34:23 +08:00
|
|
|
|
this._instance._globalManagers.push(manager);
|
2020-07-28 16:25:20 +08:00
|
|
|
|
manager.enabled = true;
|
2020-07-23 15:39:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 删除全局管理器对象
|
|
|
|
|
|
* @param manager
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static unregisterGlobalManager(manager: es.GlobalManager) {
|
2020-12-14 11:34:23 +08:00
|
|
|
|
new linq.List(this._instance._globalManagers).remove(manager);
|
2020-07-28 16:25:20 +08:00
|
|
|
|
manager.enabled = false;
|
2020-07-23 15:39:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取类型为T的全局管理器
|
|
|
|
|
|
* @param type
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static getGlobalManager<T extends es.GlobalManager>(type): T {
|
|
|
|
|
|
for (let i = 0; i < this._instance._globalManagers.length; i++) {
|
2020-12-14 11:34:23 +08:00
|
|
|
|
if (this._instance._globalManagers[i] instanceof type)
|
|
|
|
|
|
return this._instance._globalManagers[i] as T;
|
2020-07-23 15:39:18 +08:00
|
|
|
|
}
|
2020-07-28 16:25:20 +08:00
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2020-07-23 15:39:18 +08:00
|
|
|
|
|
2020-08-26 19:56:48 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 调度一个一次性或重复的计时器,该计时器将调用已传递的动作
|
|
|
|
|
|
* @param timeInSeconds
|
|
|
|
|
|
* @param repeats
|
|
|
|
|
|
* @param context
|
|
|
|
|
|
* @param onTime
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static schedule(timeInSeconds: number, repeats: boolean = false, context: any = null, onTime: (timer: ITimer)=>void){
|
|
|
|
|
|
return this._instance._timerManager.schedule(timeInSeconds, repeats, context, onTime);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public onOrientationChanged() {
|
|
|
|
|
|
Core.emitter.emit(CoreEvents.OrientationChanged);
|
2020-07-23 15:39:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-30 12:57:53 +08:00
|
|
|
|
public startDebugDraw() {
|
|
|
|
|
|
this._frameCounter ++;
|
|
|
|
|
|
this._frameCounterElapsedTime += Time.deltaTime;
|
|
|
|
|
|
if (this._frameCounterElapsedTime >= 1) {
|
|
|
|
|
|
let memoryInfo = window.performance["memory"];
|
|
|
|
|
|
if (memoryInfo != null) {
|
|
|
|
|
|
this._totalMemory = Number((memoryInfo.totalJSHeapSize / 1048576).toFixed(2));
|
|
|
|
|
|
}
|
2020-11-30 13:50:18 +08:00
|
|
|
|
if (this._titleMemory) this._titleMemory(this._totalMemory, this._frameCounter);
|
2020-11-30 12:57:53 +08:00
|
|
|
|
this._frameCounter = 0;
|
|
|
|
|
|
this._frameCounterElapsedTime -= 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-23 15:39:18 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 在一个场景结束后,下一个场景开始之前调用
|
|
|
|
|
|
*/
|
2020-07-28 16:25:20 +08:00
|
|
|
|
public onSceneChanged() {
|
2020-07-23 15:39:18 +08:00
|
|
|
|
Core.emitter.emit(CoreEvents.SceneChanged);
|
|
|
|
|
|
Time.sceneChanged();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-07-28 16:25:20 +08:00
|
|
|
|
* 当屏幕大小发生改变时调用
|
2020-07-23 15:39:18 +08:00
|
|
|
|
*/
|
2020-07-28 16:25:20 +08:00
|
|
|
|
protected onGraphicsDeviceReset() {
|
2020-11-26 10:39:32 +08:00
|
|
|
|
// 我们用这些来避免垃圾事件的发生
|
|
|
|
|
|
if (this._graphicsDeviceChangeTimer != null){
|
|
|
|
|
|
this._graphicsDeviceChangeTimer.reset();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this._graphicsDeviceChangeTimer = Core.schedule(0.05, false, this, t => {
|
|
|
|
|
|
(t.context as Core)._graphicsDeviceChangeTimer = null;
|
|
|
|
|
|
Core.emitter.emit(CoreEvents.GraphicsDeviceReset);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2020-07-23 15:39:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-28 16:25:20 +08:00
|
|
|
|
protected initialize() {
|
2020-11-26 10:39:32 +08:00
|
|
|
|
|
2020-07-23 15:39:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-26 17:26:49 +08:00
|
|
|
|
protected async update(currentTime?: number) {
|
|
|
|
|
|
if (currentTime != null) Time.update(currentTime);
|
2020-11-26 10:39:32 +08:00
|
|
|
|
if (this._scene != null) {
|
2020-07-28 16:25:20 +08:00
|
|
|
|
for (let i = this._globalManagers.length - 1; i >= 0; i--) {
|
2020-12-14 11:34:23 +08:00
|
|
|
|
if (this._globalManagers[i].enabled)
|
|
|
|
|
|
this._globalManagers[i].update();
|
2020-07-28 16:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-30 18:23:03 +08:00
|
|
|
|
this._scene.update();
|
2020-07-28 16:25:20 +08:00
|
|
|
|
|
2020-11-26 10:39:32 +08:00
|
|
|
|
if (this._nextScene != null) {
|
2020-07-28 16:25:20 +08:00
|
|
|
|
this._scene.end();
|
|
|
|
|
|
|
|
|
|
|
|
this._scene = this._nextScene;
|
|
|
|
|
|
this._nextScene = null;
|
|
|
|
|
|
this.onSceneChanged();
|
|
|
|
|
|
|
2020-11-26 10:39:32 +08:00
|
|
|
|
this._scene.begin();
|
2020-07-28 16:25:20 +08:00
|
|
|
|
}
|
2020-07-23 15:39:18 +08:00
|
|
|
|
}
|
2020-07-28 16:25:20 +08:00
|
|
|
|
|
2020-11-30 18:23:03 +08:00
|
|
|
|
this.startDebugDraw();
|
2020-07-28 16:25:20 +08:00
|
|
|
|
}
|
2020-07-23 15:39:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|