2010-4
5
之前一直感觉AS3是不需要针对整个系统做主循环的,因为flash自身就是一个循环系统,后来发现随着系统的增大,尤其是一些socket即时游戏,系统的整体维护性急剧降低,用起来也不够便捷,所以还是要考虑在AS3的上层封装一个循环系统,供于任何地方的调用。正好今天有个朋友问我实现方式,所以在这里简要的写一下。
先看图后描述:

ILoop接口:所有需要应用循环的类必须实现此接口
ILoopHandler接口:它提供了一些管理ILoop对象的操作
MainLoop类:整个主循环的核心
SysManager类:它是所有子系统管理类的基类,它实现了ILoopHandler接口和ILoop接口,也就是说它具有管理ILoop对象功能,同时它又是一个ILoop对象,可以被MainLoop类来管理。游戏的所有系统的管理类都要继承自此类。
下面是完整代码实现:
ILoopHandler接口
package { public interface ILoopHandler { function addLoop(loopPm:ILoop):void; function removeLoop(loopPm:ILoop):void; function hasLoop(loopPm:ILoop):Boolean; } }
ILoop接口
package { public interface ILoop { function onRun(delayPm:uint):void; } }
MainLoop类
package { import flash.events.TimerEvent; import flash.utils.Timer; public class MainLoop implements ILoopHandler { private static var _instance:MainLoop; private var _time:Timer; private var _delay:uint=30; //设定基础时间为30毫秒 private var _loopArr:Array; public function MainLoop(singletonEnforcer:SingletonEnforcer) { _loopArr = []; _time = new Timer(_delay); _time.addEventListener(TimerEvent.TIMER,onTimeHandler); _time.start(); } //单例构造方法 public static function getInstance():MainLoop { if (MainLoop._instance == null) { MainLoop._instance=new MainLoop(new SingletonEnforcer()); } return MainLoop._instance; } public function addLoop(loopPm:ILoop):void { if(loopPm != null) { var i:int = _loopArr.indexOf(loopPm); if(i == -1) { _loopArr.push(loopPm); } } } public function hasLoop(loopPm:ILoop):Boolean { if(loopPm != null) { return _loopArr.indexOf(loopPm) != -1; } return false; } public function removeLoop(loopPm:ILoop):void { if(loopPm != null) { var i:int = _loopArr.indexOf(loopPm); if(i != -1) { _loopArr.splice(i, 1); } } } private function onTimeHandler(event:TimerEvent):void { var len:int = _loopArr.length; var loop:ILoop = null; for(var i:int = 0; i < len; ++i) { loop = _loopArr[i]; if(loop != null) { loop.onRun(_delay); } } } } } class SingletonEnforcer { }
SysManager类
package { public class SysManager implements ILoop, ILoopHandler { private var _loopArr:Array; public function SysManager() { _loopArr = []; } public function init():Boolean { return true; } public function postInit():Boolean { return true; } public function onRun(delayPm:uint):void { var len:int = _loopArr.length; var loop:ILoop = null; for(var i:int = 0; i < len; ++i) { loop = _loopArr[i]; if(loop != null) { loop.onRun(delayPm); } } } public function addLoop(loopPm:ILoop):void { if(loopPm != null) { var i:int = _loopArr.indexOf(loopPm); if(i == -1) { _loopArr.push(loopPm); } } } public function removeLoop(loopPm:ILoop):void { if(loopPm != null) { var i:int = _loopArr.indexOf(loopPm); if(i != -1) { _loopArr.splice(i, 1); } } } public function hasLoop(loopPm:ILoop):Boolean { if(loopPm != null) { return _loopArr.indexOf(loopPm) != -1; } return false; } } }
下面写一个LoopTest测试类,它由SysManager类管理
package { public class LoopTest implements ILoop { //计时器变量 private var _delay:uint; //间隔时间 private var _currTime:int; private var _name:String; public function LoopTest(name:String,delay:uint=1000) { _name=name; _delay=delay; _currTime=0; } public function onRun(delayPm:uint):void { if (_currTime > 0) { _currTime-=delayPm; } else { //重置时间或者停止处理 //比如移除循环 _currTime=_delay; //执行相关程序 loopHandler(); } } private function loopHandler():void { trace("Instance "+_name+",Run !!!"); } } }
测试系统运行
package { import flash.display.Sprite; public class Main extends Sprite { public function Main() { //初始化系统 sys var sys:SysManager=new SysManager(); MainLoop.getInstance().addLoop(sys); //LoopTest是SysManager系统管理的类 var loopTest1:LoopTest=new LoopTest("loopTest1",5000); sys.addLoop(loopTest1); var loopTest2:LoopTest=new LoopTest("loopTest2",2000); sys.addLoop(loopTest2); } } }
整个循环操作类似一个树状结构,分层遍历。
实际应用时SysManager并不服务于具体系统上的,具体子系统由继承自SysManager的子类来实现,比如skill系统,SkillManager继承自SysManager来实现游戏的技能系统,然后把SkillManager初始化添加到MainLoop,Skill系统的其他需要实现循环的对象添加到SkillManager里来管理。我们通过delay和currTime在onRun里的处理可以实现灵活多变的控制流程。

还没有评论。