カスタムタイマー
タイマーは、多くの場合、ゲームで使用されているので、弾丸などはああ毎秒、2秒ごとにモンスターAI自動操舵ああを解雇しました
たびに私はあまりにも多くの問題のような... addEventListenerを(egret.TimerEvent次に、新しいタイマーを行きます。
カスタムタイマーので、
2つのカスタムタイマーのShachengの戦い
カスタムタイマーのShachengの戦いを見てみましょう
Egret.Ticker原理は、コールバックの実装に、時間の時に終了時間を確認するために、そのリストTimerHandlerプラスまたは時間枠ことを、フレームごとに行われます。
/ ** * 2014年11月23日にyangsongによって作成されます。 *タイマー管理器 * / クラスTimerManagerははSingtonClass {延び プライベート_handlers:配列<TimerHandlerを>。 プライベート_delHandlers:アレイ<TimerHandler>。 プライベート_currTime:数; プライベート_currFrame:数; プライベート_count:数; プライベート_timeScale:数; プライベート_isPause:ブール。 プライベート_pauseTime:数; / ** *构造函数 * / publicコンストラクタ(){ スーパー(); this._handlers =新しいアレイ<TimerHandler>(); this._currFrame = 0; this._delHandlers =新しいアレイ<TimerHandler>(); this._currTime = egret.getTimer()。 this._currTime = egret.getTimer()。 this._count = 0; this._timeScale = 1。 egret.Ticker.getInstance()(this.onEnterFrame、これ)を登録。 } / ** *设置时间参数 * @paramスケール * / パブリックsetTimeScale(タイムスケール:数):ボイド{ this._timeScale =タイムスケール。 } / ** *每帧执行函数 * @param frameTime * / プライベートonEnterFrame():無効{ 場合(this._isPause){ リターン。 } this._currFrame ++。 App.DebugUtils.start( "TimerManagerは:"); 一方、(this._delHandlers.length){ this.removeHandle(this._delHandlers.pop())。 } (VAR I:番号= 0; I <this._count; I ++)用{ VARハンドラ:TimerHandler = this._handlers [I]。 もし(this._delHandlers.indexOf(ハンドラ)= -1!){ 続けます。 } VARのT:番号= handler.userFrame?this._currFrame:this._currTime。 もし(T> = handler.exeTime){ App.DebugUtils.start(handler.method.toString())。 handler.method.call(handler.methodObj、(this._currTime - handler.dealTime)* this._timeScale)。 handler.exeTime + = handler.delay。 App.DebugUtils.stop(handler.method.toString())。 handler.dealTime = this._currTime。 App.DebugUtils.stop( "TimerManagerは:")。 (!handler.repeat)であれば、{ (handler.repeatCount> 1)の場合{ handler.repeatCount--。 }他{ IF(handler.complateMethod){ handler.complateMethod.apply(handler.complateMethodObj)。 } (this._delHandlers.indexOf(ハンドラ)== -1){もし this._delHandlers.push(ハンドラ) } } } } } } プライベートremoveHandle(ハンドラ:TimerHandler):無効{ VAR私はthis._handlers.indexOf(ハンドラ)=。 IF(I == -1){ Log.warn( "何????")。 リターン; } this._handlers.splice(I、1)。 ObjectPool.push(ハンドラ); this._count--; } プライベート(useFrameを:ブール、遅延:数、repeatCountに:数、方法:機能、methodObj:任意の、complateMethod:機能、complateMethodObj:いずれかを):作成し、ボイド{ //参数监测 場合(遅延<0 ||のrepeatCount <0 | |方法== NULL){ リターン。 } //先删除相同函数的计时 this.remove(方法methodObj)。 //创建 VARハンドラ:TimerHandler = ObjectPool.pop( "TimerHandler"); handler.userFrame = useFrame。 handler.repeat = repeatCountに== 0。 handler.repeatCount = repeatCountに。 handler.delay =遅延。 handler.method =方法。 handler.methodObj = methodObj。 handler.complateMethod = complateMethod。 handler.complateMethodObj = complateMethodObj。 handler.exeTime =遅延+(useFrame this._currFrame:?this._currTime)。 handler.dealTime = this._currTime。 this._handlers.push(ハンドラ); this._count ++; } / ** *指定された機能動作後(ミリ秒単位)は、遅延を指定しました。 * @param遅延执行间隔:毫秒 * @param法执行函数 * @param methodObj执行函数所属对象 * / 公共のsetTimeout(遅延:番号、方法:機能、methodObj:任意):ボイド{ this.doTimer(ディレイ,. 1、方法、methodObj); } / ** *指定されたフレームで指定された関数を実行します。 * @Param遅延実行間隔:フレームレート * @param方法を行う機能 * @param methodObjオブジェクトに関連する機能を実行 * / パブリックsetFrameOut(遅延:番号、方法:機能、methodObj:任意):ボイド{ this.doFrame(ディレイ,. 1 、メソッド、methodObj); } / ** * *正規実装 * @param遅延実行間隔:MS * @param repeatCountに実行時間、0無制限の 実行* @paramメソッド関数 * @Param methodObjは、オブジェクトに関連する機能を実行する * / 機能の* @param complateMethod完全実行 *オブジェクトに関連する機能の実行の@Param complateMethodObj完了 * * / パブリックdoTimer(遅延:番号、repeatCountに:番号、方法:機能、methodObj:任意、complateMethod:機能= NULL、complateMethodObj:任意= NULL):ボイド{ this.create( falseに、遅延、repeatCountに、メソッド、methodObj、complateMethod、complateMethodObj); } / ** * *正規実装 * @param遅延実行間隔:フレームレート * @param repeatCountに実行時間、0無制限 * @param方法を行う機能 * @param methodObj関数はオブジェクト属する行う * @param complateMethod完全な実行機能を * @param complateMethodObj完全な実行機能は、オブジェクトの所属 * doFrame公開(遅延:番号、repeatCountに:番号、方法:機能、methodObj:任意、complateMethod:機能= NULL、complateMethodObj:任意= NULL):ボイド{ this.create(trueに、遅延、repeatCountに、メソッド、methodObj、complateMethod、 complateMethodObj); } / ** *番号、実行タイマ * @return * * / パブリックGETのCOUNT():数は{ this._count返す; } / ** *クリーンアップ 機能を除去する* @param法 * @param methodObj削除されたオブジェクトに対応する機能 * / パブリック削除(:関数、methodObj:方法いずれかを):ボイド{ ため(VAR I:番号= 0; I <this._count; I ++){ VARハンドラ:TimerHandler = this._handlers [i]は、 IF(handler.method ==方法&& handler.methodObj == methodObj && this._delHandlers.indexOf(ハンドラ)== -1){ this._delHandlers.push(ハンドラ) ブレーク; } } } / ** *清理 * @param methodObj要移除的函数对应的对象 * / 公共のremoveAll(methodObj:任意):{ボイド ため(VAR I:番号= 0; I <this._count; I ++){ VARハンドラ:TimerHandler = this._handlers [i]は、 IF(handler.methodObj == methodObj && this._delHandlers.indexOf(ハンドラ)== -1){ this._delHandlers.push(ハンドラ) } } } (this._isPause)であれば{ / ** *検出はすでに存在してい * @param法 * @param methodObj * * / パブリックisExists(方法:機能、methodObj:任意):ブール{ ため(VAR I:番号= 0; iは<this._count; I ++){ VARハンドラ:TimerHandler =この。 _handlers [I]。 IF(handler.method ==方法&& handler.methodObj == methodObj && this._delHandlers.indexOf(ハンドラ)== -1){ trueを返します。 } } falseを返します。 } / ** *暂停 * / パブリックポーズ():ボイド{ リターン。 } this._isPause = TRUE。 this._pauseTime = egret.getTimer()。 } / ** *从暂停中恢复 * / 公共の履歴書():無効{ 場合(!this._isPause){ リターン。 } this._isPause = FALSE; this._currTime = egret.getTimer()。 VARギャップ= this._currTime - this._pauseTime。 (VAR I:番号= 0; I <this._count; I ++)用{ VARハンドラ:TimerHandler = this._handlers [I]。 handler.dealTime + =ギャップ。 (!handler.userFrame){もし handler.exeTime + =ギャップ。 } } } } クラスTimerHandler { / **実行間隔* / 公共の遅延:数= 0; / *繰り返し実行した場合* / 公共REPEAT:ブール; / **繰り返し数* / 公共のrepeatCount:数= 0; / * **フレームレートが使用するかどうか/ 公共userFrame:ブール; / **実行時間* / 公共exeTime:数= 0; / **ハンドラ* / パブリックメソッド:機能; / **ハンドラオブジェクト* /に関連する 公共methodObj:任意の; / **完了ハンドラ* / 公共complateMethod:機能; オブジェクト* /に関連する/ **完了ハンドラ 公共complateMethodObj:任意の; / **前回の実行時間* / 公共dealTime:数= 0; / **クリーンアップ* / 公共クリア( ):ボイド{ this.method = NULL; this.methodObj = NULL; this.complateMethod = NULL; this.complateMethodObj = NULL; } }
ラヤの3つのタイマー
ラヤは、開発者が使用するためのタイマーを備えており、ほとんどShacheng戦いました
Date.nowラヤが長すぎるため、バックグラウンドで、その後、ゲームを使用して、フロントデスクに戻っているので、コールバックを実行するために膨大な時間差に、何回もつながります。だから、ラヤは、追加の処理を行います。
しかしegret.tickerの白鷺の使用は、バックグラウンドで、egret.tickerが逮捕されたときに、その時大きな問題の違いに対処していません。
クラスタイマ{ コンストラクタ(autoActiveがtrue =){ this.scale = 1。 this.currTimer = Date.now()。 this.currFrame = 0; this._delta = 0; this._lastTimer = Date.now()。 this._map = []; this._handlers = []; this._temp = []; this._count = 0; autoActive && Timer.gSysTimer && Timer.gSysTimer.frameLoop(1本、this._update)。 } (デルタを得る){ this._deltaを返します。 } _update(){ IF(this.scale <= 0){ this._lastTimer = Date.now()。 this._delta = 0; リターン; } VARフレーム= this.currFrame = this.currFrame + this.scale。 VAR今= Date.now(); VAR目を覚まし=(今- this._lastTimer)> 30000; this._delta =(今- this._lastTimer)* this.scale。 VARタイマー= this.currTimer = this.currTimer + this._delta。 this._lastTimerは今=。 VARハンドラ= this._handlers。 this._count = 0; ため(VAR iが、0 = N = handlers.length; I <N; I ++){ VARハンドラ=ハンドラ[I]。 (handler.method!== null)の場合は{ T = handler.userFrameでしたか?フレーム:時間。 handler.exeTime + = handler.delay。 もし(T> = handler.exeTime){ IF(handler.repeat){ IF(handler.jumpFrame ||覚醒!){ handler.exeTime + = handler.delay。 handler.run(偽); もし(T> handler.exeTime){ handler.exeTime + = Math.ceil((T - handler.exeTime)/ handler.delay)* handler.delay。 } } 他{ ながら(T> = handler.exeTime){ handler.run(偽)。 } } } 他{ handler.run(TRUE)。 } } } 他{ this._count ++。 } } もし(this._count> 30 ||フレーム200%=== 0) this._clearHandlers(); } _clearHandlers(){ VARハンドラ= this._handlers。 以下のために(VAR私は、0を= N = handlers.length; I <N; I ++){ this._temp.push(ハンドラ); 他 VARハンドラ=ハンドラ[I]。 (!handler.method == null)の場合は ヌルを返します。 this._recoverHandler(ハンドラ); } this._handlers = this._temp。 handlers.length = 0; this._temp =ハンドラ。 } _recoverHandler(ハンドラ){ IF(this._map [handler.key] ==ハンドラ) this._map [handler.key] = NULL; handler.clear(); Timer._pool.push(ハンドラ); } _CREATE(useFrame、リピート、遅延、発信者、方法、引数、coverBefore){ {IF(遅延!) method.apply(発信者、引数)。 {(coverBefore)場合 } ハンドラ= Timer._pool.length> 0?Timer._pool.pop():新しいTimerHandler(); VARハンドラ= this._getHandler(発信者、法)。 (ハンドラ){もし handler.repeat =リピート; handler.userFrame = useFrame。 handler.delay =遅延。 handler.caller =呼び出し元; handler.method =方法。 handler.args =引数。 handler.exeTime = +遅延(useFrame this.currFrame:this.currTimer + Date.now() - this._lastTimer)。 ハンドラを返します。 } } handler.repeat =リピート; handler.userFrame = useFrame。 handler.delay =遅延。 handler.caller =呼び出し元; = handler.method方法。 handler.args =引数。 handler.exeTime = +遅延(useFrame this.currFrame:this.currTimer + Date.now() - this._lastTimer)。 this._indexHandler(取引)。 this._handlers.push(取引)。 取引を返します。 } _IndexHandler(ACT){ 発信= handler.callerでした。 方法= handler.methodました。 CID =呼び出し側がでしたか?呼び出し側。$ _ GID || (呼び出し元$ _ GID = ILaya.Utils.getGID()。):0; 半ば=方法であった。$ _ TIME || (メソッド$ _ = TIME(Timer._mid ++)* 100000); handler.key CID =ミッド+。 this._map [handler.key] =取引。 } (遅延、発信者、方法、引数=ヌル、coverBefore = TRUE){回 this._create(偽、偽、遅延、発信者、方法、引数、coverBefore)。 } ループ(遅延、発信者、方法、引数=ヌル、coverBefore =真、jumpFrame = FALSE){ VARハンドラ= this._create(偽、真、遅延、発信者、方法、引数、coverBefore)。 (ハンドラ)の場合 handler.jumpFrame = jumpFrame。 } frameOnce(遅延、発信者、方法、引数=ヌル、coverBefore = TRUE){ this._create(真、偽、遅延、発信者、方法、引数、coverBefore)。 } frameLoop(遅延、発信者、方法、引数=ヌル、coverBefore = TRUE){ this._create(真、真、遅延、発信者、方法、引数、coverBefore)。 } のtoString(){ リターン"ハンドラ:" + this._handlers.length + "プール" + Timer._pool.length。 } クリア(発信者、法){ VARハンドラ= this._getHandler(発信者、法)。 もし(ハンドラ){ this._map [handler.key] = NULL; handler.key = 0; handler.clear(); } } ClearAllを(発呼者){ IF(!呼び出し側) リターン。 ため(VAR iがN =、0 = this._handlers.length、I <N; I ++){ CallLater.I.callLater(発信者、方法、引数)。 VARハンドラ= this._handlers [I]。 IF(handler.caller ===発信者){ this._map [handler.key] = NULL; handler.key = 0; handler.clear(); } } } _getHandler(発信者、法){ VAR CID =発呼者?呼び出し側。$ _ GID || (呼び出し元$ _ GID = ILaya.Utils.getGID()。):0; VaRの半ば=方法。$ _ TID || (メソッド$ _ TID =(Timer._mid ++)* 100000); this._map [+ミッドCID]を返します。 } callLater(発信者、方法、引数= NULL){ CallLater.I.runCallLater(発信者、法)。 } } runCallLater(発信者、法){ runTimer(発信者、法){ VARハンドラ= this._getHandler(発信者、法)。 (!ハンドラ&& handler.method = NULL){もし this._map [handler.key] = NULL; handler.run(真の); } } ポーズ(){ this.scale = 0。 } 再開(){ this.scale = 1。 } } Timer.gSysTimer = NULL; Timer._pool = []; Timer._mid = 1。 クラスTimerHandler { (クリア){ this.caller = NULL; this.method = NULL; this.args = NULL; } ラン(withClear){ VAR発信者= this.caller。 (呼び出し側が&& caller.destroyed)場合 this.clear()を返します。 VAR法= this.method。 VAR引数= this.args。 withClear && this.clear()。 (方法== NULL)場合は リターン。 引数?method.apply(呼び出し側、引数):method.call(呼び出し元); } }