1.游戏开发生命周期
关于游戏开发中的生命周期相关的知识,参考一下:https://www.jianshu.com/p/ebc9e087676e
2.egret 2d引擎中的生命周期
对于egret 2D中的生命周期我们来了解一下:
(1)心跳
egret的 SystemTicker,是引擎的心跳计时器,egret通过SystemTicker来执行每一帧的eventLoop,渲染等操作。
保持游戏框架的运行。
pause():void 是暂停心跳的操作。
resume():void 是恢复心跳
update函数,egret在运行每帧是回调。
(2)计时器
egret.startTick(callBack: (timeStamp: number) => boolean, thisObject: any):void;
egret开启计时器的注册函数。
egret.stopTick(callBack: (timeStamp: number) => boolean, thisObject: any): void;
egret停止计时器函数。
在游戏中经常会出现有些对象随着时间的变化而变化的。一旦有这种需求,那么就需要用到计时器 来记录时间并且在合适的时间
里对物品的属性变化进行操作。
如果有大量的这类型的需求,那么我们应该集中来管理,那么就需要一个计时器回调函数管理器。
心跳管理器
/**
* Timer管理器
*/
class TimerMgr extends BaseClass {
private _handlers: Array<TimerHandler>;
private _currTime: number;
private _currFrame: number;
private currHandler: TimerHandler = null;
private nexthandles: Array<TimerHandler>;
/**
* 构造函数
*/
public constructor() {
super();
this._handlers = [];
this.nexthandles = null;
this._currTime = egret.getTimer();
this._currFrame = 0;
egret.startTick(this.onEnterFrame, this);
}
public static ins(): TimerMgr {
return super.ins() as TimerMgr;
}
public getFrameId(): number {
return this._currFrame;
}
public getCurrTime(): number {
return this._currTime;
}
// 从大到小排序
public static binFunc(b1: TimerHandler, b2: TimerHandler): number {
if (b1.exeTime > b2.exeTime) return -1;
else if (b1.exeTime < b2.exeTime) return 1;
else return 0;
}
private static DeleteHandle(handler: TimerHandler) {
handler.clear();
ObjPool.push(handler);
}
/**
* 每帧执行函数
* @param frameTime
*/
private onEnterFrame(time: number): boolean {
this._currFrame++;
this._currTime = egret.getTimer();
let currTime: number = 0;
// process the nextlist first
let nexthandles = this.nexthandles;
this.nexthandles = null;
if (nexthandles && nexthandles.length > 0) {
for (let handler of nexthandles) {
handler.method.call(handler.methodObj);
TimerMgr.DeleteHandle(handler);
}
nexthandles = null;
}
if (this._handlers.length <= 0) return false;
let handler = this._handlers[this._handlers.length - 1];
while (handler.exeTime <= this._currTime) {
this.currHandler = handler = this._handlers.pop();
let times = (this._currTime - handler.exeTime) / handler.delay;
if (times > 1) {
handler.method.call(handler.methodObj, times);
} else {
handler.method.call(handler.methodObj);
}
currTime = egret.getTimer();
handler.exeTime = currTime + handler.delay;
let repeat: boolean = handler.forever;
if (!repeat) {
if (handler.repeatCount > 1) {
handler.repeatCount--;
repeat = true;
} else {
if (handler.onFinish) {
handler.onFinish.apply(handler.finishObj);
}
}
}
if (repeat) {
let index = Algorithm.binSearch(this._handlers, handler, TimerMgr.binFunc);
this._handlers.splice(index, 0, handler);
}
else {
TimerMgr.DeleteHandle(handler);
}
if (currTime - this._currTime > 5) break;
if (this._handlers.length <= 0) break;
else handler = this._handlers[this._handlers.length - 1];
}
this.currHandler = null;
return false;
}
private create(startTime: number, delay: number, repeat: number, method: Function, methodObj: any,
onFinish: Function, fobj: any, remove: boolean = false): void {
if (delay < 0 || repeat < 0 || method == null) {
return;
}
let handler: TimerHandler = ObjPool.pop("TimerHandler");
handler.forever = repeat == 0;
handler.repeatCount = repeat;
handler.delay = delay;
handler.method = method;
handler.methodObj = methodObj;
handler.onFinish = onFinish;
handler.finishObj = fobj;
handler.exeTime = startTime + this._currTime;
// this._handlers.push(handler);
let index = Algorithm.binSearch(this._handlers, handler, TimerMgr.binFunc);
this._handlers.splice(index, 0, handler);
}
/**
*
* 定时执行
* @param delay 执行间隔:毫秒
* @param repeat 执行次数, 0为无限次
* @param method 执行函数
* @param methodObj 执行函数所属对象
* @param onFinish 完成执行函数
* @param fobj 完成执行函数所属对象
* @param remove 是否删除已经存在的
*
*/
public doTimer(delay: number, repeat: number, method: Function, methodObj: any
, onFinish: Function = null, fobj: any = null, remove: boolean = false): void {
this.create(delay, delay, repeat, method, methodObj, onFinish, fobj, remove);
}
/**
*
* 定时执行
* @param startTime 延迟多久第一次执行
* @param delay 执行间隔:毫秒
* @param repeat 执行次数, 0为无限次
* @param method 执行函数
* @param methodObj 执行函数所属对象
* @param onFinish 完成执行函数
* @param fobj 完成执行函数所属对象
* @param remove 是否删除已经存在的
*
*/
public doTimerDelay(startTime: number, delay: number, repeat: number, method: Function, methodObj: any
, onFinish: Function = null, fobj: any = null): void {
this.create(startTime, delay, repeat, method, methodObj, onFinish, fobj);
}
/** 下一帧执行,且只执行一次*/
public doNext(method: Function, methodObj: any) {
let handler: TimerHandler = ObjPool.pop("TimerHandler");
handler.method = method;
handler.methodObj = methodObj;
if (!this.nexthandles)
this.nexthandles = [];
this.nexthandles.push(handler);
}
/**
* 清理
* @param method 要移除的函数
* @param methodObj 要移除的函数对应的对象
*/
public remove(method: Function, methodObj: any): void {
let currHandler = this.currHandler;
if (currHandler && currHandler.method == method &&
currHandler.methodObj == methodObj) {
currHandler.forever = false;
currHandler.repeatCount = 0;
}
for (let i = this._handlers.length - 1; i >= 0; i--) {
let handler = this._handlers[i];
if (handler.method == method && handler.methodObj == methodObj) {
this._handlers.splice(i, 1);
TimerMgr.DeleteHandle(handler);
}
}
}
/**
* 清理
* @param methodObj 要移除的函数对应的对象
*/
public removeAll(methodObj: any): void {
let currHandler = this.currHandler;
if (currHandler && currHandler.methodObj == methodObj) {
currHandler.forever = false;
currHandler.repeatCount = 0;
}
for (let i = this._handlers.length - 1; i >= 0; i--) {
let handler = this._handlers[i];
if (handler.methodObj == methodObj) {
this._handlers.splice(i, 1);
TimerMgr.DeleteHandle(handler);
}
}
}
/**
* 检测是否已经存在
* @param method
* @param methodObj
*
*/
public isExists(method: Function, methodObj: any): boolean {
for (let handler of this._handlers) {
if (handler.method == method && handler.methodObj == methodObj) {
return true;
}
}
return false;
}
}
class TimerHandler {
/**执行间隔*/
public delay: number = 0;
/**是否重复执行*/
public forever: boolean = false;
/**重复执行次数*/
public repeatCount: number = 0;
/**执行时间*/
public exeTime: number = 0;
/**处理函数*/
public method: Function;
/**处理函数所属对象*/
public methodObj: any;
/**完成处理函数*/
public onFinish: Function;
/**完成处理函数所属对象*/
public finishObj: any;
/**清理*/
public clear(): void {
this.method = null;
this.methodObj = null;
this.onFinish = null;
this.finishObj = null;
this.forever = false;
}
}
(3)帧事件
帧事件是egret 每一帧都发出的一个基础事件类型。
帧事件的是生命周期的体现,相当于unity的updata函数。
帧事件的监听,继承自DisplayObject
this.addEventListener(egret.Event.ENTER_FRAME,this.onUpdata,this);
移除
this.removeEventListener(egret.Event.ENTER_FRAME,this.onUpdata,this);