egret引擎生命周期相关

本文详细解析了游戏开发的生命周期,包括游戏开发的各个阶段,并深入探讨了egret2D引擎中关键的生命周期概念,如心跳、计时器及帧事件的运用,为游戏开发者提供实用指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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_FRAMEthis.onUpdata,this);

移除

this.removeEventListener(egret.Event.ENTER_FRAMEthis.onUpdata,this);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值