• 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改名后,就会使用不正常了。

    找不到路径下的资源。

     

     

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

     

  • 相关阅读:
    go函数和方法
    Golang的“面向对象”
    高性能 socket 框架
    wpf 自定义圆形按钮
    WPF 实际国际化多语言界面
    使用过滤器对mvc api接口安全加密
    使用mvc3实现ajax跨域
    WPF,给颜色SolidColorBrush添加动画
    C# 通用验证类 支持 WPF,MVC,Winform
    WSL安装ubuntu搭建vue开发环境(三):docker安装
  • 原文地址:https://www.cnblogs.com/gamedaybyday/p/6079694.html
Copyright © 2020-2023  润新知