关于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 == ) {
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[],arr[]);
} /**
* 加载完成
* @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 = ){
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=;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][];
var loadCompleteTarget: any = this.groups[groupName][];
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][];
var loadProgressTarget: any = this.groups[groupName][];
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改名后,就会使用不正常了。

找不到路径下的资源。

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

Egret资源管理解决方案的更多相关文章

  1. 评点SAP HR功能及人力资源管理软件

    评点SAP HR功能及人力资源管理软件   本文导航 第1页:my SAP 人力资源软件 第2页:my SAP HR协同功能 第3页:组织结构管理 第4页:mySAPTM HR的战略功能 第5页:集成 ...

  2. 2016年 最火的 15 款 HTML5 游戏引擎

    HTML5游戏从2014年Egret引擎开发的神经猫引爆朋友圈之后,就开始一发不可收拾,今年<传奇世界>更是突破流水2000万!从两年多的发展来看,游戏开发变得越来越复杂,需要制作各种炫丽 ...

  3. 微信小游戏 4M升8M分包加载

    一.微信分包加载 微信分包加载教程 嘛,因为原来的4M太小了,满足不了小游戏内容的需求,现在提升到了8M.这8M可以分包加载,而不需要一次性加载8M. 如果是老版本,则分包加载不起作用,会一次加载8M ...

  4. [No00009C]Visual Studio在 解决方案资源管理器 里同步定位打开的文件

    标题的意思就是在使用VS的时候,需要我们打开编辑的文件跟解决方案的资源管理器同步显示,这样方便定位到我们在修改哪个文件. 设置如下: 工具——选项——项目和解决方案——在解决方案资源管理器中跟踪活动项 ...

  5. Egret是一套完整的HTML5游戏开发解决方案

    Egret是一套完整的HTML5游戏开发解决方案.Egret中包含多个工具以及项目.Egret Engine是一个基于TypeScript语言开发的HTML5游戏引擎,该项目在BSD许可证下发布.使用 ...

  6. 在VS解决方案资源管理器中自动定位当前编辑中的文件

    依次点击 [工具]- [选项] - [项目和解决方案]-[常规]- 勾选[在解决方案资源管理器中跟踪活动项]

  7. mvc 分部视图(Partial)显示登陆前后变化以及Shared文件夹在解决方案资源管理器中没有显示的问题

    刚开始我的解决方案资源管理器中没有显示Shared文件夹,但Shared文件夹在项目中是实际存在的,我搜了下好像没有类似的解答(可能是我搜索的关键词不够准确).后来自己看了下vs2012. 其实解决方 ...

  8. VS2015解决方案资源管理器空白,不显示内容

    解决方法: 1.先关闭vs: 2.把C:/Users/<users name>/AppData/Local/Microsoft/VisualStudio/14.0/ComponentMod ...

  9. vs2010 怎样设置文本编辑窗口和解决方案资源管理器同步?

    即切换左边的文本编辑窗口,解决方案资源管理器如何定位到相应的文件项上?答案: 工具--选项--项目和解决方案--常规--在解决方案资源管理器中跟踪活动项(前打勾)确定 应该就可以了.

随机推荐

  1. ORA-12504 warning in PHP

    <?php $conn = oci_connect('proekt', 'proekt1', 'localhost:1521'); $stid = oci_parse($conn, " ...

  2. Rails NameError uninitialized constant class solution

    rails nameerror uninitialized constant class will occur if your rails console is not loaded with con ...

  3. 统一建模语言 UML (2)

    UML的图 1.用例图(use case diagram) 用例图(Use Case Diagram)是被称为参与者(Actor)的外部用户所能观察到的系统功能的模型图 列出系统中的用例和参与者 显示 ...

  4. B树、Trie树详解

    查找(二) 散列表 散列表是普通数组概念的推广.由于对普通数组可以直接寻址,使得能在O(1)时间内访问数组中的任意位置.在散列表中,不是直接把关键字作为数组的下标,而是根据关键字计算出相应的下标. 使 ...

  5. TypeError: datetime.datetime(2016, 9, 25, 21, 12, 19, 135649) is not JSON serializable解决办法(json无法序列化对象的解决办法)

    1.一个简单的方法来修补json模块,这样序列将支持日期时间. import json import datetime json.JSONEncoder.default = lambda self, ...

  6. Lost connection to MySQL server at 'waiting for initial communication packet', system error: 0

    场景: 192.168.7.27 需要访问 192.168.7.175 上的MySQL数据库,连接时报错. 原因: MySQL的配置文件默认没有为远程连接配置好,需要更改下MySQL的配置文件. 解决 ...

  7. enumerate遍历列表

    enumerate 函数用于遍历序列中的元素以及它们的下标: >>> for i,j in enumerate(('a','b','c')):  print i,j 0 a 1 b ...

  8. Openstack镜像和密码

    #!/bin/sh passwd ubuntu<<EOF ubuntu ubuntu EOF sed -i 's/PasswordAuthentication no/PasswordAut ...

  9. [转]线上GC故障解决过程记录

    排查了三四个小时,终于解决了这个GC问题,记录解决过程于此,希望对大家有所帮助.本文假定读者已具备基本的GC常识和JVM调优知识,关于JVM调优工具使用可以查看我在同一分类下的另一篇文章: http: ...

  10. Hyperic-Sigar简介

    Hyperic-Sigar是一个收集系统各项底层信息的工具集.他有如下特点:1. 收集信息全面收集CPU,MEM,NETWORK,PROCESS,IOSTAT等使用Sigar,你完全可以模仿出cpui ...