egret插件使用案例
Posted egret-edcation
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了egret插件使用案例相关的知识,希望对你有一定的参考价值。
插件使用案例
2018年8月13日,白鹭引擎发布5.2.7 版本。本次版本主要新增了两大功能:命令行增加自动合图插件TextureMergerPlugin,微信小游戏支持库增加二进制和声音缓存方案。
同时,本次版本还是对 5.2 版本的一次集中性缺陷修复,更新修复了大家反馈的涉及2D渲染- javascript、AssetsManager、微信小游戏支持库的数个BUG。在此,我们要再次特别感谢开发者们通过Egret社区、白鹭引擎小游戏开发微信群等渠道提交的BUG反馈。
5.2.7版本中新增的自动合图插件可以帮助开发者在开发期使用碎图,在发布后将碎图自动整合为整图发布,提高开发者开发和发布的效率,完善整个开发和发布的工作流。
由于原有的文件缓存方案只缓存了图片和文本资源,所以这次微信小游戏支持库新增的二进制和声音缓存方案,解决游戏第二次进入不重新加载资源问题,节省资源服务器费用,提高用户体验。
引言
本文不详细介绍各插件的细节,只展示使用方法,如果开发者对细节有兴趣可以参考 文档。
为了让开发者以更简单的使用Egret内置的插件,我们将通过一个案例来展示插件的具体使用方法和注意事项。
本文案例从一个刚编写完成的eui卡牌项目开始发布到微信小游戏,为了让代码包的体积更小,更好管理,逐步添加使用不同的插件,以实现不同的需求。
todos
-
使用UglifyPlugin将代码混淆压缩
-
使用ResSplitPlugin把部分资源分离出去
-
使用ZipPlugin把文件压缩成zip格式
-
使用TextureMergerPlugin将纹理合并,且用ConvertResConfigFilePlugin修改res.json配置文件
项目初始化
-
把index.html中的
data-scale-mode
改成fixedWidth
-
打开EgretLauncher,将本项目发布成微信小游戏
-
打开微信开发者工具
使用UglifyPlugin压缩代码
在微信开发者工具可以看到,js文件夹中5个库文件和一个main.js
。
现在需求是是要把库文件压缩到一个文件lib.min.js
中。
回到EgretWing,编辑sctipts下的config.wxgame.ts:
//***其他代码*** // ? if(command==‘build‘) { return{ outputDir, commands: [ // 清理js,resource文件夹 newCleanPlugin({ matchers: ["js", "resource"] }), newCompilePlugin({ libraryType: "debug", defines: { DEBUG: true, RELEASE: false} }), newExmlPlugin(‘commonjs‘), // 非 EUI 项目关闭此设置 newWxgamePlugin(), ? // 压缩插件 newUglifyPlugin([ { // 需要被压缩的文件 sources: [ "libs/modules/egret/egret.js", "libs/modules/eui/eui.js", "libs/modules/assetsmanager/assetsmanager.js", "libs/modules/tween/tween.js", ], // 压缩后的文件 target: "lib.min.js" } ]), ? newManifestPlugin({ output: ‘manifest.js‘}) ] } } ? // // ***其他代码***
保存后在终端执行:
egret build
可以在微信开发者工具看到发布后的代码,js文件夹内的库文件已经被压缩到lib.min.js。
但是报错,找不到eui,这是因为自动生成的manifest.js
里面对js的引用顺序出错,需要优先引用lib.min.js
打开根目录下的manifest.js
, 修改一下引用顺序。
require("js/lib.min.js")
require("js/main.js")
require("js/default.thm.js")
每次编译的时候manifest.js
都会被重新生成,所以我们使用一个自定义脚本来修改他们的顺序
打开 scripts下的myPlugin.ts :
/** * 示例自定义插件,您可以查阅 http://developer.egret.com/cn/2d/projectConfig/cmdExtensionPluginin/ * 了解如何开发一个自定义插件 */ exportclassCustomPluginimplementsplugins.Command{ privatebuffer constructor() { } ? asynconFile(file: plugins.File) { // 保存manifest.js文件的内容 if(file.basename.indexOf(‘manifest.js‘) >-1) { this.buffer=file.contents } returnfile; } ? asynconFinish(commandContext: plugins.CommandContext) { // 把‘lib.min.js‘移到第一位 if(this.buffer) { letcontents: string=this.buffer.toString() letarr=contents.split(‘ ‘) letlib=null arr.forEach((item, index) =>{ if(item.indexOf(‘lib.min.js‘) >-1) { lib=item arr.splice(index, 1) } }) if(lib!=null) { arr.unshift(lib) } ? letnewCont=arr.join(‘ ‘) commandContext.createFile(‘manifest.js‘, newBuffer(newCont)) } } }
这个文件就是用来自定义插件的,在config.wxgame.ts中已经默认引用,所以只需要调用即可,注意调用顺序
newManifestPlugin({ output: ‘manifest.js‘}), // 在manifest.js生成之后调用 newCustomPlugin()
使用ResSplitPlugin分离资源文件
因为微信对代码包的大小是有限制的,总大小不能超过4M(使用分包功能可以提升到8M),所以我们需要通过ResSplitPlugin把某些游戏资源文件分离出去,将游戏资源放置在一个外部CDN服务器上,需要的时候动态加载即可。
编辑config.wxgame.ts:
// ***其他代码*** // ? newResSplitPlugin({ verbose: false, matchers: [ // from 使用glob表达式来匹配文件, projectName就是项目的名字 { from: "resource/art/about/**.**", to: `${projectName}_wxgame_remote`}, { from: "resource/art/heros_goods/**.**", to: `${projectName}_wxgame_remote`} ] }) ? // ***其他代码***
保存后在终端执行:
egret build
微信开发者工具中resource > art 下的about
和heros_goods
已经不在了。
被分离出去的在项目根目录中 egret-eui-demo_wxgame_remote
文件夹内。
使用ZipPlugin把文件压缩成zip格式
为了减少加载次数和传输量,我们可以把文件压缩成zip格式,使用的时候可以使用第三方库JSZip来读取使用zip文件。
使用ZipPlugin插件之前,需要安装cross-zip 和 cross-zip-cli , 在终端中输入:
//全局安装 npminstall cross-zip -g npminstall cross-zip-cli -g
安装完成之后,在config.wxgame.ts添加代码:
newZipPlugin({ mergeSelector: p=>{ // 如果文件是assets/路径下的, 压缩到assets.zip if(p.indexOf("assets/") >=0) { return"assets.zip" } } })
项目中其实assets里面的资源都是没有用到的,这里我们用它来演示压缩插件的使用。
保存后在终端执行:
egret build
执行之后可以在微信开发者工具看到,resource目录下原来的assets文件夹已经被压缩成了assets.zip。
使用TextureMergerPlugin,ConvertResConfigFilePlugin合并纹理集
项目中使用的图片资源都是单独的png文件,在加载的时候每张图片都会单独请求。我们可以通过合并纹理集的方式把这些图片合成一张图,以减少请求数量。使用插件之前,我们需要有纹理集的配置文件tmpropject
, 可以用两种方式生成:
-
执行脚本生成
这里使用第二种方法,使用脚本autoMerger.js:
"use strict"; Object.defineProperty(exports, "__esModule", { value: true}); varfs=require("fs"); varpath=require("path"); varresjsons=["resource/default.res.json"]; //要扫描的res.json文件 vartargetDir="resource/TextureMerger"; //输出目录 varpathNor=path.relative(targetDir, "resource"); //返回一个相对路径 vartempindex=0; //创建输出文件夹 if(resjsons.length>0) { if(!fs.existsSync(targetDir)) { ? // var paths = path.normalize(targetDir).split("\\"); //windows 下使用 varpaths=path.normalize(targetDir).split("/"); //mac linux 下使用 ? vartarget="."; for(var_i=0, paths_1=paths; _i<paths_1.length; _i++) { varp=paths_1[_i]; ? // target += ("\\" + p); // windows 下使用 target+=("/"+p); // mac linux 下使用 ? if(!fs.existsSync(target)) // 根据路径创建文件夹 fs.mkdirSync(target); } } } var_loop_1=function(resJson) { // 判断是否是res.json文件 if(fs.existsSync(resJson) &&resJson.indexOf("res.json") >-1) { vardefaultJson=fs.readFileSync(resJson, "utf-8"); // 解析res.json文件内容 vardefaultObject=JSON.parse(defaultJson); vargroups=defaultObject.groups; //组 varresources=defaultObject.resources; //资源 varresourcesHash_1={}; // 用来存放resources的资源信息 ? // 遍历resources for(var_i=0, resources_1=resources; _i<resources_1.length; _i++) { varresource=resources_1[_i]; resourcesHash_1[resource.name] =resource.url; } ? // 遍历groups for(var_a=0, groups_1=groups; _a<groups_1.length; _a++) { vargroup=groups_1[_a]; vartmproject={}; //用来存放tmproject文件的信息 // tmproject文件配置 tmproject["options"] ={ "layoutMath": "2", "sizeMode": "2n", "useExtension": 1, "layoutGap": 1, "extend": 0 }; // projectName tmproject["projectName"] =group.name+"_"+tempindex; // 版本 tmproject["version"] =5; tempindex++; ? // 获取res.json分组的keys, 并分割成数组 varoldkeys=group.keys.split(","); varoldkeysHash={}; // 遍历oldkeys for(var_b=0, oldkeys_1=oldkeys; _b<oldkeys_1.length; _b++) { varkey=oldkeys_1[_b]; // 保存到oldkeysHash对象中 oldkeysHash[key] =true; } ? varnewKeys=[]; // 遍历oldkeys for(var_c=0, oldkeys_2=oldkeys; _c<oldkeys_2.length; _c++) { varkey=oldkeys_2[_c]; if(key.indexOf("json") ==-1) { if(!oldkeysHash[key.replace("png", "json")]) { //粒子和龙骨对应的图集不合图 if(!oldkeysHash[key.replace("png", "fnt")]) //位图字体 newKeys.push(key); } elseif(key.indexOf("jpg") >-1) { newKeys.push(key); } } } oldkeysHash={}; oldkeys=[]; // files路径 varurls=newKeys.map(function(key) { returnpath.join(pathNor, resourcesHash_1[key]); }); tmproject["files"] =urls; // 根据tmproject写入文件 if(urls.length>0) { fs.writeFileSync(path.join(targetDir, tmproject["projectName"] +".tmproject"), JSON.stringify(tmproject)); } tmproject={}; } } }; //根据数组开始扫描 for(var_a=0, resjsons_1=resjsons; _a<resjsons_1.length; _a++) { varresJson=resjsons_1[_a]; _loop_1(resJson); } ? ?
把这个脚本放在scripts文件夹内,这个脚本是根据项目的default.res.json
文件的内容来生成tmpropject
文件
在终端中执行:
nodescripts/autoMerger.js
执行成功之后可以在resource文件夹中看到多出了一个TextureMerger文件夹,里面就是根据default.res.json
分组生成的tmpropject
文件。
newTextureMergerPlugin({textureMergerRoot:[ ‘resource‘]})
保存后在终端执行:
egret build
执行完成后,在微信开发者工具可以看到,resource > TextureMerger 内新增了三个png文件,就是合并之后的纹理集。游戏运行的时候只需要加载这三个纹理集就可以,无需加载那些单独的png文件但是需要去res.json里面配置,把单独的资源引用都删除,加上纹理集的引用。
这些操作当然不需要手动去完成,现在只需要使用ConvertResConfigFilePlugin插件就可以实现这个功能。
编辑config.wxgame.ts:
newTextureMergerPlugin(), ? newConvertResConfigFilePlugin({ resourceConfigFiles: [{ filename: "resource/default.res.json", root: "resource/"}], nameSelector: (p) =>{ returnpath.basename(p).split(".").join("_") }, TM_Verbose: true })
保存后在终端执行:
egret build
在微信开发者工具中,打开调试器,在network面板可以看到加载的纹理集。
这里有个注意事项,在游戏中点击英雄按钮,切换到英雄场景时,会发现列表里面的图片加载不出来。
在network面板可以看到加载请求是单独的png文件,而不是纹理集。
这是因为列表中的图片地址是直接使用url。
// 原始数组 letdataArr:any[] =[ {image: ‘resource/art/heros_goods/heros01.png‘, name: ‘亚特伍德‘, value: ‘评价: 很特么厉害, 为所欲为‘, isSelected: false}, {image: ‘resource/art/heros_goods/heros02.png‘, name: ‘亚特伍德‘, value: ‘评价: 很特么厉害, 为所欲为‘, isSelected: false}, {image: ‘resource/art/heros_goods/heros03.png‘, name: ‘亚特伍德‘, value: ‘评价: 很特么厉害, 为所欲为‘, isSelected: true}, {image: ‘resource/art/heros_goods/heros04.png‘, name: ‘亚特伍德‘, value: ‘评价: 很特么厉害, 为所欲为‘, isSelected: false}, {image: ‘resource/art/heros_goods/heros05.png‘, name: ‘亚特伍德‘, value: ‘评价: 很特么厉害, 为所欲为‘, isSelected: false}, {image: ‘resource/art/heros_goods/heros06.png‘, name: ‘亚特伍德‘, value: ‘评价: 很特么厉害, 为所欲为‘, isSelected: false}, {image: ‘resource/art/heros_goods/heros07.png‘, name: ‘亚特伍德‘, value: ‘评价: 很特么厉害, 为所欲为‘, isSelected: false} ] // 转成eui数据 leteuiArr:eui.ArrayCollection=neweui.ArrayCollection(dataArr) // 把list_hero数据源设置成euiArr this.list_hero.dataProvider=euiArr // 设置list_hero的项呈视器 (这里直接写类名,而不是写实例) this.list_hero.itemRenderer=heroList_item
这种引用方式的图片,需要开发者手动在代码中修改,将图片地址修改成纹理集中的图片。
结语
本文通过使用UglifyPlugin,ResSplitPlugin,ZipPlugin,TextureMergerPlugin,ConvertResConfigFilePlugin插件,使项目发布到微信小程序之后的代码包体积减小,用户发起的请求数变少,且将代码混淆压缩。
使用Egret自带的插件,已经可以满足开发者的基本需求,如果有针对项目的特殊需求,可以选择自定义插件。
以上是关于egret插件使用案例的主要内容,如果未能解决你的问题,请参考以下文章