走在网页游戏开发的路上(五)
定时器:
package<!--CRLF-->
{<!--CRLF-->
import flash.events.TimerEvent;<!--CRLF-->
import flash.utils.Timer;<!--CRLF-->
import flash.utils.getTimer;<!--CRLF-->
<!--CRLF-->
public class MyTimer<!--CRLF-->
{<!--CRLF-->
private static var _instance:MyTimer;<!--CRLF-->
private var _timer:Timer;<!--CRLF-->
private var _timerList:Array;<!--CRLF-->
<!--CRLF-->
/*<!--CRLF-->
* 获取单例类MyTimer的实例<!--CRLF-->
* 返回值:<!--CRLF-->
* _instance<!--CRLF-->
*/<!--CRLF-->
public static function getInstance():MyTimer<!--CRLF-->
{<!--CRLF-->
if (_instance == null)<!--CRLF-->
_instance = new MyTimer();<!--CRLF-->
<!--CRLF-->
return _instance;<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
/*<!--CRLF-->
* 构造函数,用于防止单例类生成多个实例<!--CRLF-->
*/<!--CRLF-->
public function MyTimer()<!--CRLF-->
{<!--CRLF-->
if (_instance != null)<!--CRLF-->
trace("单例类,请不要实例化");<!--CRLF-->
return;<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
/*<!--CRLF-->
* 注册计时器,首先检查id是否存在,如果不存在,就将定时器插入数组_timerList中;否则啥都不做<!--CRLF-->
* 参数:<!--CRLF-->
* id - 唯一标识一个定时器<!--CRLF-->
* interval - 刷新间隔,单位为秒(s)<!--CRLF-->
* repeatCount - 重复次数<!--CRLF-->
* callback - 回调函数,每隔interval就执行一次<!--CRLF-->
* ...args - 回调函数参数 ///注意,参数实际并没有用到,有待改进<!--CRLF-->
* 返回值:空<!--CRLF-->
*/<!--CRLF-->
public function registerTimer(id:String, interval:int, repeatCount:int, callback:Function, ...args):void<!--CRLF-->
{<!--CRLF-->
if (_timerList == null)<!--CRLF-->
_timerList = new Array();<!--CRLF-->
<!--CRLF-->
if ( check(id) == -1 )<!--CRLF-->
{<!--CRLF-->
_timerList.push( { id:id, interval:interval, repeatCount:repeatCount, callback:callback, args:args, tempInterval:0 } );<!--CRLF-->
startTimer();<!--CRLF-->
}<!--CRLF-->
else<!--CRLF-->
{<!--CRLF-->
trace(id + "已经存在!!!");<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
/*<!--CRLF-->
* 注销计时器,首先检查id是否存在,如果存在,从数组_timerList中删除定时器<!--CRLF-->
* 参数:<!--CRLF-->
* id - 唯一标识一个定时器<!--CRLF-->
* 返回值:空<!--CRLF-->
*/<!--CRLF-->
public function removeTimer(id:String):void<!--CRLF-->
{<!--CRLF-->
var index:int = check(id);<!--CRLF-->
if (index != -1)<!--CRLF-->
{<!--CRLF-->
_timerList.splice(index, 1);<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
/*<!--CRLF-->
* 检查指定id的Object是否在_timerList数组中,<!--CRLF-->
* 如果存在返回在_timerList数组中的索引;否则返回-1<!--CRLF-->
* 参数:<!--CRLF-->
* id - String,唯一标识一个定时器<!--CRLF-->
* 返回值:<!--CRLF-->
* -1 or 指定Object的索引<!--CRLF-->
*/<!--CRLF-->
private function check(id:String):int<!--CRLF-->
{<!--CRLF-->
var len:int = _timerList.length;<!--CRLF-->
<!--CRLF-->
for (var index:int = 0; index < len; index++)<!--CRLF-->
{<!--CRLF-->
if (_timerList[index]["id"] == id)<!--CRLF-->
{<!--CRLF-->
return index;<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
return -1;<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
/*<!--CRLF-->
* 启动计时器<!--CRLF-->
* 如果_timer为空,生成一个定时器Timer,事件发生间隔1000ms(1s);<!--CRLF-->
* 监听TimerEvent.TIMER,处理函数为timerHandler<!--CRLF-->
*/<!--CRLF-->
private function startTimer():void<!--CRLF-->
{<!--CRLF-->
if (_timer == null)<!--CRLF-->
_timer = new Timer(1000);<!--CRLF-->
if (!_timer.running)<!--CRLF-->
{<!--CRLF-->
_timer.addEventListener(TimerEvent.TIMER, timerHandler);<!--CRLF-->
_timer.start();<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
/*<!--CRLF-->
* 停止计时器<!--CRLF-->
* 当_timerList数组为空时,即没有用户注册定时器,停止_timer<!--CRLF-->
*/<!--CRLF-->
private function stopTimer():void<!--CRLF-->
{<!--CRLF-->
_timer.stop();<!--CRLF-->
_timer.removeEventListener(TimerEvent.TIMER, timerHandler);<!--CRLF-->
}<!--CRLF-->
?<!--CRLF-->
/*<!--CRLF-->
* 运行计时器<!--CRLF-->
* 如果_timerList数组为空,调用stopTimer()停止计时器;<!--CRLF-->
* 否则判断_timerList数组中的定时器间隔是否达到,<!--CRLF-->
* 如果达到,就调用回调函数;<!--CRLF-->
* 否则啥都不做<!--CRLF-->
*/<!--CRLF-->
public function runTimer():void<!--CRLF-->
{<!--CRLF-->
var timerComplete:Array = new Array();<!--CRLF-->
var len:int = _timerList.length;<!--CRLF-->
if (len == 0)<!--CRLF-->
{<!--CRLF-->
stopTimer();<!--CRLF-->
return;<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
for (var i:int = 0; i < len; i++)<!--CRLF-->
{<!--CRLF-->
//运行MyTimer管理的所有计时器<!--CRLF-->
<!--CRLF-->
_timerList[i]["tempInterval"] += 1;<!--CRLF-->
//判断是否已经经过interval间隔<!--CRLF-->
if (_timerList[i]["tempInterval"] == _timerList[i]["interval"])<!--CRLF-->
{<!--CRLF-->
//如果callback不空,执行callback函数<!--CRLF-->
if (_timerList[i]["callback"] != null)<!--CRLF-->
{<!--CRLF-->
_timerList[i]["callback"](_timerList[i]["args"]);<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
_timerList[i]["tempInterval"] = 0;<!--CRLF-->
<!--CRLF-->
//判断初始repeatCount是否=0,如果注册时为0,即无限次数<!--CRLF-->
//否则每执行一次,就-1;然后判断repeatCount是否=0,如果=0就注销计时器<!--CRLF-->
if (_timerList[i]["repeatCount"] != 0)<!--CRLF-->
{<!--CRLF-->
_timerList[i]["repeatCount"] -= 1;<!--CRLF-->
if (_timerList[i]["repeatCount"] == 0)<!--CRLF-->
{<!--CRLF-->
trace("执行完成......");<!--CRLF-->
timerComplete.push(_timerList[i]["id"]);<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
//注销所有已完成的计时器<!--CRLF-->
len = timerComplete.length;<!--CRLF-->
if (len != 0)<!--CRLF-->
{<!--CRLF-->
trace("注销所有已经完成的计时器...");<!--CRLF-->
for ( i = 0; i < len; i++)<!--CRLF-->
{<!--CRLF-->
removeTimer(timerComplete.pop());<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
/*<!--CRLF-->
* timerHandler是_timer的TimerEvent.TIMER事件处理函数<!--CRLF-->
* 其中调用runTimer(),管理所有注册的计时器<!--CRLF-->
*/<!--CRLF-->
private function timerHandler(evt:TimerEvent):void<!--CRLF-->
{<!--CRLF-->
runTimer();<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
}<!--CRLF-->
测试代码:
package<!--CRLF-->
{<!--CRLF-->
import flash.display.Sprite;<!--CRLF-->
import flash.events.Event;<!--CRLF-->
import flash.utils.Timer;<!--CRLF-->
import flash.events.TimerEvent;<!--CRLF-->
<!--CRLF-->
public class Main extends Sprite<!--CRLF-->
{<!--CRLF-->
<!--CRLF-->
public function Main():void<!--CRLF-->
{<!--CRLF-->
if (stage) init();<!--CRLF-->
else addEventListener(Event.ADDED_TO_STAGE, init);<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
private function init(e:Event = null):void<!--CRLF-->
{<!--CRLF-->
removeEventListener(Event.ADDED_TO_STAGE, init);<!--CRLF-->
// entry point<!--CRLF-->
<!--CRLF-->
var timer:MyTimer = MyTimer.getInstance();<!--CRLF-->
timer.registerTimer("1", 1, 15, tick);<!--CRLF-->
<!--CRLF-->
var timer1:MyTimer = MyTimer.getInstance();<!--CRLF-->
timer1.registerTimer("2", 5, 0, tick1);<!--CRLF-->
<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
private function tick(...args):void<!--CRLF-->
{<!--CRLF-->
trace("tick(1s)");<!--CRLF-->
}<!--CRLF-->
?<!--CRLF-->
private function tick1(...args):void<!--CRLF-->
{<!--CRLF-->
trace("tick(5s)");<!--CRLF-->
}<!--CRLF-->
/* private function complete(evt:TimerEvent):void<!--CRLF-->
{<!--CRLF-->
trace("complete...");<!--CRLF-->
}*/<!--CRLF-->
<!--CRLF-->
}<!--CRLF-->
<!--CRLF-->
}<!--CRLF-->
?
参考文献1. Hashed and Hierarchical Timing Wheels: Ef?cient Data Structures for Implementing a Timer Facility
2. ActionScript3帮助文档
3. 一个高效的定时器分析及设计