webgame之资源管理队列加载,并发加载

游戏里的资源管理其实就是加载资源(swf,png,jpg)用统一的入口管理。

1.IE6并发数2个,IE8并发数8个,其他浏览器并发数10个

2.反复用一个loader 加载到当前域的时候,会覆盖掉上次加载的,会找不到新的资源MC。所以得每次new一个loader。

3.如何计算空闲时间,让loader偷偷load -------------- 所有的loader都由工厂统一创建,工厂里loader有两个队列,一个队列是业务逻辑创建的loader,另一个队列是后台偷偷load的队列。当业务逻辑的队列为空时,后台队列开始load,当业务逻辑队列有时,后台停止。

View Code
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);
            }
            
        }
        
        
    }
}
View Code
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));
        }

    }
}
View Code
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

{

}

原文地址:https://www.cnblogs.com/as3lib/p/2611461.html