正在加载...
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里的处理可以实现灵活多变的控制流程。

随便看看吧......

: http://ljy.me/archives/webgame-as3-game-mainloop

本文相关评论 - 1条评论都没有呢

还没有评论。