游戏里的资源管理其实就是加载资源(swf,png,jpg)用统一的入口管理。
1.IE6并发数2个,IE8并发数8个,其他浏览器并发数10个
2.反复用一个loader 加载到当前域的时候,会覆盖掉上次加载的,会找不到新的资源MC。所以得每次new一个loader。
3.如何计算空闲时间,让loader偷偷load -------------- 所有的loader都由工厂统一创建,工厂里loader有两个队列,一个队列是业务逻辑创建的loader,另一个队列是后台偷偷load的队列。当业务逻辑的队列为空时,后台队列开始load,当业务逻辑队列有时,后台停止。
package net.libra.loader { import flash.events.Event; import flash.events.EventDispatcher; import net.libra.loader.event.FileEvent; import net.libra.log.Log; import net.libra.utils.HashMap; /** * load工厂类 * 加载完一组swf,然后执行某个函数 * 提供后台偷偷加载的功能 * @author elvisjiang */ public class LoadFactory { /** * 业务loader队列 */ private static var _buissessQueue:HashMap = new HashMap; /** * 背后loader队列 */ private static var _bgQueue:HashMap = new HashMap; /** * @param libs 加载的swf URL数组 * @param callBack 回调函数 * @param context 函数所属对象 * @param parms 函数参数列表 */ public static function addMission(libs:Array, callBack:Function=null, context:Object=null, parms:Array=null):void { var obj:Object = {}; obj.callBack = callBack; obj.context = context; obj.parms = parms; if(SwfLoader.isLoaded(libs)) { var moni:FileEvent = new FileEvent(FileEvent.ON_COMPLETE,obj); __onComplete(moni); } else { var swfloader:SwfLoader = new SwfLoader(); obj.loader = swfloader; _buissessQueue.put(swfloader,obj); swfloader.addURLArray(libs); swfloader.addEventListener(FileEvent.ON_PROGRESS, __onProgress); swfloader.addEventListener(FileEvent.ON_COMPLETE, __onComplete); swfloader.start(); //加载条 show.apply(); } //取消后台加载 var bgkeys:Array = _bgQueue.keys(); var i:int; for(i = 0;i < bgkeys.length; i++) { var loader:SwfLoader = _bgQueue.get(bgkeys[i]).swfloader; loader.stop(); } } private static var show:Function; private static var progress:Function; private static var remove:Function; /** * 注入loadingbox的两个函数 * @param showFunction * @param progressFunction */ public static function setCallBack(show_fun:Function,progress_fun:Function,remove_fun:Function):void { show = show_fun; progress = progress_fun; remove = remove_fun; } public static function setSkin(view:*):void { show = view.show; progress = view.progress; remove = view.remove; } /** * 响应加载进度事件 * */ private static function __onProgress(event:FileEvent):void { //加载条更新 progress.apply(null, [event.data]); } /** * 响应加载完成事件 * */ private static function __onComplete(event:FileEvent):void { var swfLoader:SwfLoader = event.currentTarget as SwfLoader; if(swfLoader) { //加载条销毁 remove.apply(); swfLoader.removeEventListener(FileEvent.ON_PROGRESS, __onProgress); swfLoader.removeEventListener(FileEvent.ON_COMPLETE, __onComplete); var obj:Object = _buissessQueue.get(swfLoader) as Object; if(obj.callBack != null) { obj.callBack.apply(null, obj.parms); } //从业务加载队列中删除 _buissessQueue.remove(swfLoader); }else{ var objs:Object = event.data; if(objs.callBack != null) { objs.callBack.apply(null, objs.parms); } } //开启后台加载 tryStartHideMission(); } private static function tryStartHideMission():void { if(_buissessQueue.size() <= 0) { var bgkeys:Array = _bgQueue.keys(); var i:int; for(i = 0;i < bgkeys.length; i++) { var loader:SwfLoader = (_bgQueue.get(bgkeys[i]) as Object).swfloader; loader.addEventListener(FileEvent.ON_COMPLETE, __bgloaded); loader.start(); } } } private static function __bgloaded(event:FileEvent):void { var swfLoader:SwfLoader = event.currentTarget as SwfLoader; if(swfLoader) { swfLoader.removeEventListener(FileEvent.ON_COMPLETE, __bgloaded); var obj:Object = _bgQueue.get(swfLoader) as Object; if(obj.callBack != null) { obj.callBack.apply(null, obj.parms); } Log.info("[隐藏加载任务完成...]"); //从后台加载队列中删除 _bgQueue.remove(swfLoader); }else{ var objs:Object = event.data; if(objs.callBack != null) { objs.callBack.apply(null, objs.parms); } } tryStartHideMission(); } /** * 闲暇时加载 * 有业务逻辑loader加入,后台要停下来 * 业务逻辑load完毕,业务逻辑队列size为0开启后台加载 * 后台加载不能影响业务逻辑的加载 * @param libs 加载的swf URL数组 * @param eventName 事件名字 */ public static function addHideMission(libs:Array, callBack:Function=null, context:Object=null, parms:Array=null):void { var obj:Object = {}; obj.callBack = callBack; obj.context = context; obj.parms = parms; if(SwfLoader.isLoaded(libs)) { var moni:FileEvent = new FileEvent(FileEvent.ON_COMPLETE,obj); __bgloaded(moni); }else{ var swfloader:SwfLoader = new SwfLoader(); swfloader.addURLArray(libs); obj.swfloader = swfloader; _bgQueue.put(swfloader,obj); } } } }
package net.libra.loader.event { import flash.events.*; public class FileEvent extends Event { public static const ON_PROGRESS:String = "on_progress"; public static const ON_COMPLETE:String = "onComplete"; public static const ON_FAILURE : String = "onFailure"; public var bytesLoaded:int; public var bytesTotal:int; public var data:Object; public function FileEvent(type:String,obj:Object=null,bytesLoaded:int=0, bytesTotal:int=0){ super(type); this.data = obj; this.bytesTotal = bytesTotal; this.bytesLoaded = bytesLoaded; } override public function clone():Event{ return (new LoaderEvent(type,data, bytesLoaded, bytesTotal)); } } }
package net.libra.loader { import flash.display.Loader; import flash.display.LoaderInfo; import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.net.URLRequest; import flash.system.ApplicationDomain; import flash.system.LoaderContext; import flash.utils.Dictionary; import net.libra.loader.event.FileEvent; import net.libra.log.Log; /** * 队列加载swf放进当前域 * @author elvisjiang */ public class SwfLoader extends EventDispatcher { /** * key:URL,value:true/false * 这个URL是否加载过为true,否则为false */ public static var gameSwfLoadedDict:Dictionary = new Dictionary(); /** * swf的版本信息 */ public static var VERSION:String; /** * 真正的加载队列,加载完毕,置为空 */ private var swfList:Array; private var loader:Loader; /** * 计算加载速度用 */ private var _lastLoadedBytes:Number = 0; private var data:Object = {}; private var _loadState:String; private var _totalSwfNum:uint; private var _currentIndex:int; private var _currentSwfLoadedBytes:String; private var _currentSwfTotalbytes:String; /** * 是否繁忙,正在加载 */ private var _busy:Boolean; public function SwfLoader() { this.swfList = []; this._currentIndex = -1; } public function addURL(url:String):void { if(swfList.indexOf(url) != -1) return; if(gameSwfLoadedDict[url] == true) return; this.swfList.push(url); } /** * 如果游戏全局gameSwfLoadedDict没有档案就add进加载队列 * @param arry */ public function addURLArray(arry:Array):void { for(var i:int = 0;i<arry.length;i++) { if(!gameSwfLoadedDict[arry[i]] || gameSwfLoadedDict[arry[i]] == false) { this.swfList.push(arry[i]); } } } /** * 是否loaded * 只要数组里有一个没有加载 就认为没有加载 * @param arry ["a.swf","b.swf"] * @return * */ public static function isLoaded(arry:Array):Boolean { var result:Boolean = true; for(var i:int = 0;i<arry.length;i++) { if(!gameSwfLoadedDict[arry[i]] || gameSwfLoadedDict[arry[i]] == false) { result = false; break; } } return result; } /** * 执行任务 * 如果正在繁忙则跳过 */ public function start():void { if(!_busy){ _busy = true; _totalSwfNum = swfList.length; this.run(); } } /** *停止加载 */ public function stop():void { _busy = false; try{ this.loader.close(); }catch(error:Error) { } gameSwfLoadedDict[this.swfList[this._currentIndex]] = false; this._currentIndex --; } private function run():void { this._currentIndex ++; var url:String = this.swfList[this._currentIndex]; if(url && url != "") { loader = new Loader(); var context:LoaderContext = new LoaderContext(false,ApplicationDomain.currentDomain); loader.contentLoaderInfo.addEventListener(Event.COMPLETE,__onResult); loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,__onResult); loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,__onProgess); loader.load(new URLRequest(url + "?v="+VERSION),context); }else{ _currentIndex = -1; _busy = false; // swfList.length = 0; Log.info("[SwfLoader] AllItemsLoaded"); this.dispatchEvent(new FileEvent(FileEvent.ON_COMPLETE)); finalizeLoader(); } } private function __onResult(event:Event):void { var contentLoaderInfo:LoaderInfo = event.target as LoaderInfo; if(event.type == IOErrorEvent.IO_ERROR) { this.dispatchEvent(new FileEvent(FileEvent.ON_FAILURE)); // this._currentIndex = -1; gameSwfLoadedDict[this.swfList[this._currentIndex]] = false; finalizeLoader(); throw new Error("路径有错,检查下URL:"+this.swfList[this._currentIndex]); this._currentIndex = -1; Log.error("[SwfLoader] 路径有错,检查下URL"); }else if(event.type == Event.COMPLETE ) { Log.info("[SwfLoader] Loaded " + this.swfList[this._currentIndex]); gameSwfLoadedDict[this.swfList[this._currentIndex]] = true; _lastLoadedBytes = 0; finalizeLoader(); this.run(); } } protected function __onProgess(event:ProgressEvent):void { _currentSwfLoadedBytes = (event.bytesLoaded/1000).toFixed(1); _currentSwfTotalbytes = (event.bytesTotal/1000).toFixed(1); //trace(event.bytesLoaded,event.bytesTotal); data.currentIndex = _currentIndex+1; data.totalSwfNum = _totalSwfNum; data.currentSwfLoadedBytes = _currentSwfLoadedBytes; data.currentSwfTotalBytes = _currentSwfTotalbytes; dispatchEvent(new FileEvent(FileEvent.ON_PROGRESS,{state:data})); } private function finalizeLoader():void { if(loader){ loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,__onResult); loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,__onResult); loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,__onResult); loader = null; } } } }
/**
*首屏加载元素
*assets/swf/1.swf
*/
public static var libs:Array = [
URLConst.LOADING_BAR,
URLConst.LIB,
URLConst.MAIN_VIEW,
URLConst.MAIN_CHAT,
URLConst.MAP_PLAYER,
URLConst.SMALLROLE
];
/**
*闲加载战斗特效,新手指引动画
*闲暇时加载战斗场景资源
*/
public static var someBigResource:Array = [
URLConst.GAME_FIRST_ANI,
URLConst.GUIDE_UI,
URLConst.FIGHT_EFFECT_SWF,
URLConst.FIGHT_BEFORE_ANI,
URLConst.MAP_NATION_ENGLEND,
URLConst.MAP_NATION_FRANCE,
URLConst.MAP_NATION_GERMANY
];
LoadFactory.addMission(libs,onCompleteHandler,this,[]);
LoadFactory.addHideMission(someBigResource,null,this,[]);
function onCompleteHandler():void
{
}