/* FrameUtils 类说明: 使用: 1、避免 Flash 最小化机制带来帧频降低的影响。更准确的控制帧的运行,方便为不同影片剪辑设置不同的帧频,更方便在帧标签中添加动作(注册回调函数)。 优点: 1、与 EnterFrame 相比,不受最小化降帧影响。 2、方便为不同的影片剪辑设置不同的帧频。 3、方便在帧标签中添加动作。 缺点: 创建FrameUtils会带来内存的开销,由于采用 MovieClip的EnterFrame在内部运行,创建对象等于创建MovieClip,建议整个游戏中只创建一个或者几个FrameUtils,经测试,创建一个,已足够使用。 例子: var frameUtils:FrameUtils = new FrameUtils(); frameUtils.registerCallback("1", function():void{ trace(new Date()); }, 1000); frameUtils.play(); */ package utils { import flash.display.MovieClip; import flash.events.Event; import flash.utils.Dictionary; import flash.utils.getTimer; /** * 模拟计时器 */ public class FrameUtils { /** * 暂停状态 */ public static var pause:Boolean = false; /** * 计时器 */ private var _movieClip:MovieClip; /** * 当前时间 getTimer(); */ private var _currentTime:int; /** * 回调函数列表 */ private var _dictionary:Dictionary; /** * 不支持 addEventListener 任何事件,请通过 registerCallback 添加回调函数。 * */ public function FrameUtils() {} /** * 播放,暂停请直接设置 FrameUtils.pause = false; * */ public function play():void { this._currentTime = getTimer(); if(this._movieClip == null) this._movieClip = new MovieClip(); if(!this._movieClip.hasEventListener(Event.ENTER_FRAME)){ this._movieClip.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler); } this._movieClip.play(); } /** * 停止 ,暂停请直接设置 FrameUtils.pause = false; * */ public function stop():void { if(this._movieClip == null) return; if(this._movieClip.hasEventListener(Event.ENTER_FRAME)) { this._movieClip.removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler); } this._movieClip.stop(); } /** * 销毁 * */ public function destory():void { this.stop(); this._movieClip = null; for each(var key:String in this._dictionary) { this._dictionary[key] = null; delete this._dictionary[key]; } this._dictionary = null; } /** * 注册侦函数 * @param type 消息类别 * @param callback 回调函数 * @param delay 延迟时间,单位:毫秒 * */ public function registerCallback(type:String, callback:Function, delay:int = 1000):void { if(this._dictionary == null) this._dictionary = new Dictionary(); var frameCallback:FrameCallback = new FrameCallback(callback, delay); if(this._dictionary[type] != null){ var index:int = this.getCallback(callback, this._dictionary[type]); if(index == -1){ this._dictionary[type].push(frameCallback); } }else{ this._dictionary[type] = [frameCallback]; } } /** * 移除侦函数 * @param type 消息类别 * @param callback 回调函数 * */ public function unRegisterCallback(type:String, callback:Function):void { if(this._dictionary == null) return; if(this._dictionary[type] != null){ var index:int = this.getCallback(callback, this._dictionary[type]); if(index != -1){ this._dictionary[type].splice(index, 1); } } } /** * Event.ENTER_FRAME * @param eventHandler * */ private function onEnterFrameHandler(eventHandler:Event):void { // 如果是非暂停状态 if(!pause) { this.enterFrameCallback(); } } /** * Event.ENTER_FRAME 处理 * */ private function enterFrameCallback():void { var subTime:int = getTimer() - this._currentTime; if(this._dictionary != null) { for(var key:String in this._dictionary){ for each(var frameCallback:FrameCallback in this._dictionary[key] as Array){ var currentTime:int = subTime + frameCallback.currentDelay; if(currentTime >= frameCallback.delay){ var tickNum:int = int(currentTime / frameCallback.delay); var modNum:int = currentTime % frameCallback.delay; while(tickNum > 0){ frameCallback.callback(); tickNum --; } frameCallback.currentDelay = modNum; }else{ frameCallback.currentDelay += subTime; } } } } this._currentTime = getTimer(); } /** * 获取侦函数,采用遍历获取索引 * @param callback * @param list * @return * */ private function getCallback(callback:Function, list:Array):int { var index:int = 0; for each(var frameCallback:FrameCallback in list){ if(frameCallback.callback == callback) return index; index ++; } return -1; } } } /** * 内部类,回调使用 * */ class FrameCallback { public var callback:Function; public var delay:int; public var currentDelay:int; public function FrameCallback(callback:Function, delay:int){ this.callback = callback; this.delay = delay; } }