• 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

    {

    }

  • 相关阅读:
    20190817-T1-LOJ6322「雅礼国庆 2017 Day6」Star Way To Heaven
    20190817-涪
    20190816-周期
    考试总结 模拟95
    考试总结 模拟94
    考试总结 模拟93
    考试总结 模拟92
    考试总结 模拟91
    考试总结 模拟90
    考试总结 模拟89
  • 原文地址:https://www.cnblogs.com/as3lib/p/2611461.html
Copyright © 2020-2023  润新知