H5手游页游的资源版本管理(带Egret例子)

标签: html5手游网页游戏资源管理版本管理
1741人阅读 评论(1) 收藏 举报
分类:

Html5网络游戏和网页游戏,是属于打开浏览器就可以直接玩的,而且是边玩边下载的游戏。
由于每个版本更新,只是更新一小部分资源,如果每次进行版本更新都导致用户重新加载全部游戏资源,那么会导致用户消耗的流量以及不能快速进入游戏,严重影响体验。所以需要对网络资源加载这一块做深入的分析研究,拿出一个资源管理方案。

一般浏览器都会有缓存url对应的中资源,只有当url改变的时候才会进行重新加载,根据这个特性,我们可以详细制定一套资源管理方案。

本文相关信息

  1. 完整的资源管理方案和分析
  2. JavaScript/TypeScript/Egret语言
  3. EgretWing开发工具
  4. 提供完整的Egret资源管理例子,点击下载

一、几种资源版本控制方式

1.随机方式

每次加载资源的时候,后面加个随机参数,确保每次都是获取到最新的服务器资源,这种简单而粗暴,但是一般是在内网调试以及个别配置文件才使用这种方式。例如加载资源版本配置文件本身的时候:

RES.getResByUrl("resource/version.txt?v=" + Math.random(),this.onVersionTxt,this);

2.总版本号控制

每次都获取最新资源,真是太浪费了,所以根据特性,出个根据版本号,也就是说每次发版本的时候,定制了一个版本,比如采用日期:20170731,统一配置在config.json配置文件。

config.json
{
    "debug": true,
    "showLog": -1,
    "version": "20170731"
}

在游戏中实际使用代码

url = url + "?v=10" + config.version; //输出结果:url = url + "?v=20170710";
RES.getResByUrl(url, this.onSeverList, this);

这种方式可以通过修改配置文件来控制文件版本号.也可以增加多个版本号来控制不同的资源,这样控制版本号的粒度会更细,更加优化网络加载。

"uiVersion": "20170710",
"roleVersion": "20170713"

虽然按照模块分了,但是事实上,每次游戏发布之后,并不会更新所有的美术资源或者某个模块资源其实只更新了几个文件,所以这样也是会造成网络流量的浪费。

3.每个文件定制版本号

为了得到更好的网络性能,只有把粒度做得更细才行,所以会有一种为每个网络文件定制一个版本号的机制了。一般可以采用文件生成日期时间或者采用svn的版本号,这个可以根据自己项目的具体情况,各有优劣。

二、版本号获取生成方式

  1. 采用文件生成日期时间
  2. svn的版本号

三、版本号保存规则

通过制定不同的版本保本规则,可以使得记录版本号的文件尽量小,同时使用也比较方便。

1.直接记录每个文件

这种其实也是简单粗暴,直接为每个文件生成对应的时间或者svn版本号,最终生成一个大文件。这个做法就是文件稍微有点大,因为要记录每个文件,后面会有优化技巧介绍。

// url路径 + 时间日期版本号
resource/default.res.json,2017813;
resource/assets/bg.jpg,2017814;
resource/assets/egret_icon.png,2017815;
resource/config/description.json,20170816

在游戏中,则把url和日期进行对应存起来就可以了,通过url找到对应的版本号,然后组合成新的url。这样可以随时控制每个资源的版本号了。

url = resource/default.res.json?v=2017813;
url = resource/assets/bg.jpg?v=2017814;

2.根据资源类型(或者文件夹名字)保存

游戏中的资源会分成不同的类型,放在不同的文件夹,那么可以根据这个特点来保存.

//模块名字 + 版本号
mornui,2017813;
config,2017814;
scenes,2017815;

这里写图片描述

3.自定义二进制格式

采用自定义二进制,可以做得更加细化了。比如可以把同个模块下的路径只记录一次,然后根据顺序和规则来只记录模块下面的单个文件。大概的结构顺序可以是这样:

//模块
mornui
//模块里的一个小包
bag
//小包的详细文件
bag.json
bag.png
=============
bless
bless.json
bless.png

甚至还可以把相同的名字给保存起来等等,可以自由根据自己想要的来进行组合。

4.优化版本号文件体积技巧

可以记录最多文件的版本号,只要是这个版本号的都不记录,游戏中url没有对应版本号,都自动使用这个默认版本号。比如之前介绍的第一种文件记录方式可以这样修改:

// url路径 + 时间日期版本号
2017815;
resource/assets/egret_icon.png,2017815;
resource/config/description.json,20170816

其中

resource/default.res.json和resource/assets/bg.jpg

没有了,那么在游戏中使用的时候,当在版本控制容器找不到对应的版本号的时候,就直接那2017815作为版本号,实际url变成这样

url = resource/default.res.json?v=2017815;
url = resource/assets/bg.jpg?v=2017815;

如果资源数量庞大的话,会打打减小版本配置文件的大小(比如上1w条资源的时候)。

四、Egret的资源版本使用例子解析

我们来通过一个完整可运行的Egret例子来解析从加载版本配置文件到游戏中实际处理的过程。
这里写图片描述

1.用Egret创建game的项目(带有相关的资源)

2.加载版本文件

版本控制文件的名字为version.txt的文本,游戏中加载

RES.getResByUrl("resource/version.txt?v=" + 
Math.random(),this.onVersionTxt,this,RES.ResourceItem.TYPE_TEXT);

onVersionTxt中解析并且存放

private onVersionTxt(version:string):void
{
    //解析版本数据,然后放到egret自带的版本控制类里面
    console.log("version string:" + version);
    var urlObj:Object = {};
    //切割出每一条资源
    var arys:string[] = version.split(";");
    var len:number = arys.length;
    //第一个是默认版本好2,不用处理
    for(var i:number = 1; i < len; i++)
    {
        //分析出url和版本号
        var temp:string[] = arys[i].split(",");
        urlObj[temp[0]] = temp[1];
    }
    RES.registerVersionController(new EgretVersion(arys[0],urlObj));
    //初始化Resource资源加载库
    //initiate Resource loading library
    RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);
    RES.loadConfig("resource/default.res.json", "resource/");
}

EgretVersion.ts是用来控制url的版本控制文件的,egret提供了基类。

class EgretVersion extends RES.VersionController
{
    /** key是url,value是版本号 **/
    private urlObj:Object;
    /** 默认版本号 */
    private defaultVersion:string;

    constructor(defaultVersion:string,urlObj:Object)
    {
        super();
        this.defaultVersion = defaultVersion;
        this.urlObj = urlObj;
    }
    getVirtualUrl(url:string):string
    {
        //把程序里使用到的url增加相应的版本号
        var version:string = this.urlObj[url];
        if(version)
        {
            url = url + "?v=" + version;
        }
        else
        {
            //使用默认版本号
            url = url + "?v=" + this.defaultVersion;
        }
        console.log("带有版本号的url:" + url);
        return url;
    }
}

其他的代码都是Egret自动生成了,例子就是这么简单,主要是解析和组合类。
最终编译运行结果:
这里写图片描述
输出日志

带有版本号的url:resource/default.res.json?v=2017813
带有版本号的url:resource/assets/bg.jpg?v=2017814
带有版本号的url:resource/assets/egret_icon.png?v=2017815
带有版本号的url:resource/config/description.json?v=20170816

五、实际项目使用的配置和大小

实际项目中有1w条左右各资源,所以光记录文本文件(采用了默认版本号了)就有几十k(assets.bin),zip压缩之后有4.3k(assets.cfg)。
这里写图片描述
当然,这个还是会进一步游戏的,最终准备采用自定义二进制文件来保存,争取到达性能最优化。

3
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:286325次
    • 积分:3998
    • 等级:
    • 排名:第8326名
    • 原创:90篇
    • 转载:7篇
    • 译文:6篇
    • 评论:192条
    博客专栏
    最新评论
    Flash