zoukankan      html  css  js  c++  java
  • Egret资源管理解决方案

    关于egret开发H5页游,资源管理和加载的一点看法。

    一 多json文件管理

    二 资源归类和命名

    三 exml文件编写规范

    四 资源预加载、分步加载、偷载

    五 资源文件group分组

    六 ResUtils,多json文件管理类

    七 ResUtils,资源组加载管理类

    八 开发中遇到的一点问题 

    一 多json文件管理

    当多人协作时,添加资源时常因为资源文件修改而导致svn冲突。

    根据各人不同负责的模块,将资源文件划分。

    原来的

    default.res.json

    可以修改为

    login.res.json
    hall.res.json
    game.res.json
    sound.res.json
    ...

    新建的文件需要配置一下,否则无法使用,配置方法见下面《八 开发中遇到的一点问题》。 

    二 资源归类和命名

    asset文件夹下,分类存放图片。根据项目可自行划分。

     

    为了防止多个文件中资源命名冲突,软件只有检测单文件中命名冲突,没有自动检测多文件命名冲突的功能。

    所以可以加前缀解决。

    login_loginbtn
    login_logo
    
    hall_roombg
    hall_setbtn
    
    game_bg
    game_option
    ....

     

    对于公用的图片,尤其是login、hall、game中通用的按钮和背景,可以单独放在common资源组中,以备复用。

    一来防止图片多次加载,导致发包体积过大。二来修改按钮图片时,只需修改一处即可。

    com_btn0
    com_btn1
    com_box0
    com_box1
    com_panelbg
    ...

     

     

     三 exml文件编写规范

    编写Exml文件时,为了二次修改,便于查找阅读,可以效仿Flash多图层的存放元件。

    优点:

    1. 当查找时,可以根据图层名查找到图片或文本。

    2. 点击图层左侧眼镜,可隐藏该图层的所有组件。

    缺点:

    1. 单击选择时,只能选择最上层Group,而不能穿透Group选择到另一层的组件...比如直接点击界面是无法选择Logo这个文本的。(注:wing3.0已经解决了这个问题)

    2. group折叠时,无法一目了然当前所有组件。

     

     

    四 资源预加载、实时加载、偷载

    1. 黑屏  

    在进入preload预加载界面时,此时会有短暂的黑屏。可将html背景色设置为白色或其他颜色,感觉比黑屏要好一些。

    2. 预加载

    打开场景。 从preload进入login场景时,预先加载login界面的资源,给出加载loading界面,加载完成后再进入login。

     

     

     

    3. 实时加载

    预加载只加载用户一进入场景时所见资源,其他该场景资源,比如弹框资源等,在使用时再实时加载。这样可以大大减少用户进入场景等待时间。

    在打开弹框时,给出loading动画,加载完后再显示弹框。

     

     

     

     

    弹框除了资源,还有http请求显示的数据,这个请求也需要时间等待,未返回数据前,界面数据为空,或者显示之前请求的数据,等加载完成再显示更新。

    如下图,当http请求无返回数据时,界面是空的,或者是之前请求的数据。

     

    当http请求返回数据时,再更新该弹框。

     

     

     

    3. 偷载

    进入某场景后,用户可能不会马上进行某些操作。进入场景后即刻加载该场景所用资源。不用显示loading画面,在用户不知的情况完成加载。

     

    五 资源文件group分组

    资源文件可按照场景、弹框、通用来分组。

    场景必须资源:preload、login、hall、game

    大厅中弹框资源:option、rank、mission、skill、roleInfo

    声音资源:sound

    通用资源:common

    根据项目可自行细分。

    资源组划分的目的,就是将资源分类管理,方便在加载时使用。

    在进入login场景时,只加载login资源组。打开设置弹框时,只加载option资源组。

     

     

     六 ResUtils,多json文件管理类

    六、七代码部分参考了Egret论坛某人的代码,略微修改了一下。首先感谢这位仁兄分享自己的代码,其次我忘了他叫啥了- -! 。。。

    ResUtils.ts

    /**
     * 资源加载工具类,
     * 支持多个resource.json文件加载
     */
    class ResUtils  {
        private static instance:ResUtils;
        private _configs: Array<any>;
        private _onConfigComplete: Function;
        private _onConfigCompleteTarget: any;
    
        public static getInstance():ResUtils{
            if(this.instance == null){
                this.instance = new ResUtils();
            }
            return this.instance;
        }
        
        /**
         * 构造函数
         */
        public constructor() {
            this._configs = new Array<any>();
        }
    
        /**
         * 添加一个配置文件
         * @param jsonPath resource.json路径
         * @param filePath 访问资源路径
         */
        public addConfig(jsonPath: string,filePath: string): void {
            this._configs.push([jsonPath,filePath]);
        }
    
        /**
         * 开始加载配置文件
         * @param $onConfigComplete 加载完成执行函数
         * @param $onConfigCompleteTarget 加载完成执行函数所属对象
         */
        public loadConfig($onConfigComplete: Function,$onConfigCompleteTarget: any): void {
            this._onConfigComplete = $onConfigComplete;
            this._onConfigCompleteTarget = $onConfigCompleteTarget;
            this.loadNextConfig();
        }
    
        /**
         * 加载
         */
        private loadNextConfig(): void {
            //加载完成
            if(this._configs.length == 0) {
                this._onConfigComplete.call(this._onConfigCompleteTarget);
                this._onConfigComplete = null;
                this._onConfigCompleteTarget = null;
                return;
            }
    
            var arr: any = this._configs.shift();
            RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE,this.onConfigCompleteHandle,this);
            RES.loadConfig(arr[0],arr[1]);
        }
    
        /**
         * 加载完成
         * @param event
         */
        private onConfigCompleteHandle(event: RES.ResourceEvent): void {
            RES.removeEventListener(RES.ResourceEvent.CONFIG_COMPLETE,this.onConfigCompleteHandle,this);
            this.loadNextConfig();
        }
    }

     

    //加载多个资源文件
    ResUtils.getInstance().addConfig("resource/test.json","resource/"); ResUtils.getInstance().addConfig("resource/test2.json","resource/"); ResUtils.getInstance().loadConfig(this.onConfigComplete, this);

     

     七 ResUtils,资源组加载管理类

     ResUtils.ts

    /**
     * 资源加载
    * 支持单个或多个资源组加载
    */ class ResUtils extends BaseClass { /**保存资源组名*/ private groups: any; /** * 构造函数 */ public constructor() { super(); this.groups = {}; RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE,this.onResourceLoadComplete,this); RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS,this.onResourceLoadProgress,this); RES.addEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR,this.onResourceLoadError,this); } /** * 加载资源组,静默加载(无回调函数) * @group 资源组(支持字符串和数组) */ public loadGroupQuiet(group){ var groupName:string = this.combGroupName(group); RES.loadGroup(groupName); } /** * 加载资源组,带加载完成回调 * @group 资源组(支持字符串和数组) * @onComplete 加载完成回调 * @thisObject 回调执行对象 * @priority 优先级 */ public loadGroup(group, onComplete:Function, thisObject:any, priority:number = 1){ var groupName:string = this.combGroupName(group); this.groups[groupName] = [onComplete,null,thisObject]; RES.loadGroup(groupName); } /** * 加载资源组,带加载进度 * @group 资源组(支持字符串和数组) * @onComplete 加载完成回调 * @onProgress 加载进度回调 * @thisObject 回调执行对象 */ public loadGroupWithPro(group ,onComplete: Function,onProgress: Function,thisObject: any): void { var groupName:string = this.combGroupName(group); this.groups[groupName] = [onComplete,onProgress,thisObject]; RES.loadGroup(groupName); } /** * 组合资源组名。单个资源组直接返回。多个资源组则重新命名。 * @group 新资源组名 */ private combGroupName(group){ if(typeof(group) == "string"){ return group; }else{ var len = group.length; var groupName:string = ""; for(var i=0;i<len;i++){ groupName += group[i]; } RES.createGroup(groupName,group,false); //是否覆盖已经存在的同名资源组,默认 false return groupName; } } /** * 资源组加载完成 */ private onResourceLoadComplete(event: RES.ResourceEvent): void { var groupName: string = event.groupName; console.log("资源组加载完成:" + groupName); if(this.groups[groupName]) { var loadComplete: Function = this.groups[groupName][0]; var loadCompleteTarget: any = this.groups[groupName][2]; if(loadComplete != null) { loadComplete.call(loadCompleteTarget); } this.groups[groupName] = null; delete this.groups[groupName]; } } /** * 资源组加载进度 */ private onResourceLoadProgress(event: RES.ResourceEvent): void { var groupName: string = event.groupName; if(this.groups[groupName]) { var loadProgress: Function = this.groups[groupName][1]; var loadProgressTarget: any = this.groups[groupName][2]; if(loadProgress != null) { loadProgress.call(loadProgressTarget,event); } } } /** * 资源组加载失败 */ private onResourceLoadError(event: RES.ResourceEvent): void { console.log(event.groupName + "资源组有资源加载失败"); this.onResourceLoadComplete(event); } }

    测试加载

    var res:ResUtils = ResUtils.getInstance();
    //res.loadGroupQuiet("login");
    //res.loadGroup("login", ()=>{ console.log("login load complete")}, this);
    //res.loadGroupWithPro("login", 
    //    ()=>{console.log("login load complete")}, 
    //    (e:RES.ResourceEvent)=>{console.log("login progress",e.itemsLoaded,e.itemsTotal)},this);
          
    res.loadGroupQuiet(["preload","login"]);

     八 开发中遇到的一点问题 

    但是在egret wing2.5中,default.des.json改名后,就会使用不正常了。

    找不到路径下的资源。

     

     

    解决以上问题,需要在 项目-项目属性-资源 中添加配置文件。

     

  • 相关阅读:
    Poj 2017 Speed Limit(水题)
    Poj 1316 Self Numbers(水题)
    Poj 1017 Packets(贪心策略)
    Poj 1017 Packets(贪心策略)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2000 Gold Coins(水题)
    poj 2000 Gold Coins(水题)
  • 原文地址:https://www.cnblogs.com/gamedaybyday/p/6079694.html
Copyright © 2011-2022 走看看