作为egret刚入门的小白这里汇总一些目前遇到过的一些比较棘手并解决了的坑,供大家参考。
自定义组件无法显示
我们定义的新的组件皮肤,当我们在新的皮肤中想要使用时,发信显示出来的只有一个框框,没有具体的组件内容,虽然也可以将就着用但很不舒服。原因是我们没有在resource/default.thm.json这个皮肤配置文件中进行配置,该文件默认内容:
{
"skins": {
"eui.Button": "resource/eui_skins/ButtonSkin.exml",
"eui.CheckBox": "resource/eui_skins/CheckBoxSkin.exml",
"eui.HScrollBar": "resource/eui_skins/HScrollBarSkin.exml",
"eui.HSlider": "resource/eui_skins/HSliderSkin.exml",
"eui.Panel": "resource/eui_skins/PanelSkin.exml",
"eui.TextInput": "resource/eui_skins/TextInputSkin.exml",
"eui.ProgressBar": "resource/eui_skins/ProgressBarSkin.exml",
"eui.RadioButton": "resource/eui_skins/RadioButtonSkin.exml",
"eui.Scroller": "resource/eui_skins/ScrollerSkin.exml",
"eui.ToggleSwitch": "resource/eui_skins/ToggleSwitchSkin.exml",
"eui.VScrollBar": "resource/eui_skins/VScrollBarSkin.exml",
"eui.VSlider": "resource/eui_skins/VSliderSkin.exml",
"eui.ItemRenderer": "resource/eui_skins/ItemRendererSkin.exml",
},
"autoGenerateExmlsList": true,
"exmls": [
"resource/eui_skins/ButtonSkin.exml",
"resource/eui_skins/CheckBoxSkin.exml",
"resource/eui_skins/ItemRendererSkin.exml",
"resource/eui_skins/PanelSkin.exml",
"resource/eui_skins/ProgressBarSkin.exml",
"resource/eui_skins/RadioButtonSkin.exml",
"resource/eui_skins/ScrollerSkin.exml",
"resource/eui_skins/TextInputSkin.exml",
"resource/eui_skins/ToggleSwitchSkin.exml",
"resource/eui_skins/VScrollBarSkin.exml",
"resource/eui_skins/VSliderSkin.exml"
],
"path": "resource/default.thm.json"
}
里面配置的都是eui项目自带的一些组件和他们的皮肤。当我们有自定义组件时,需要分别在skins和exmls这两个节点中增加内容,比如我们增加一个叉子组件:default_fork,对应皮肤文件路径:resource/eui_skins/module/default_fork.exml,对应的控制脚本类名:DefaultFork,则我们需要在skins节点中增加配置:
{
"skins": {
"DefaultFork": "resource/eui_skins
/module/default_fork.exml"
},
"exmls": [
"resource/eui_skins/module/default_fork.exml"
]
}
注:我们可以看到默认的组件的类都是eui.**,原因是这些组件的控制脚本类是eui这个模块下的,如果我们在定义自己的脚本类时页规定了组件类所属模块,则也要加上模块的前缀。
egret wing 3无法显示皮肤
这个问题可能比较少见,可能也和系统有关,本人是mac,具体就是用egret wing 3打开exml文件,正常情况下我们是可以通过可视化界面进行编辑的,但是我打开exml文件后预览和设计模式是没有反应的,可视化界面就死在那里了,但是点击源码也还是可以编辑的。而且新创建一个项目是没问题的,一旦编译运行后,再重启打开项目就不行了,经过一点点进行文件对比后,发现是scripts/plugins/node_modules文件导致的.这是经过对一个项目编译和没编译的文件夹进行逐一对比后才发现的(这里发现了mac一个自带的文件对比和合并工具FileMerge还挺不错的)。知道原因解决方法就是删掉node_modules这个文件,但是每次重新编译后又会出现这个文件,但是只要egret wing 3不重启就没事,重启之后,所以每次重启都需要先删掉node_modules这个文件。暂时还没有更好的解决方法。
配置文件无法加载远程资源
egret有一个资源加载配置文件resource/default.res.json,但是正常情况下我们配置的资源都必须是本地的,否则会加载失败。但是比如微信小程序这种,对项目整体大小是有强制限制的,如果把所有资源文件都放在本地肯定不现实,所以就需要我们去加载远程文件。官方提供了一种新增资源类型,并自己实现资源加载器,比如这样:
- 自定义一个资源加载器
module ResourceAnalyzer {
export class RemoteImvAnalyzer implements RES.processor.Processor {
public constructor() {
}
onLoadStart(host, resource): Promise<any>{
return new Promise(( reslove ,reject ) =>{
RES.getResByUrl(resource.url,function(data){
let img:egret.Texture = data
return reslove(img)
},this,RES.ResourceItem.TYPE_IMAGE)
})
}
onRemoveStart(host, resource){
let texture = host.get(resource);
texture.dispose();
return Promise.resolve();
}
getData?(host, resource, key: string, subkey: string){
console.log("没有子图")
}
}
}
- 在main.ts中增加注册加载起注册:
//让egret支持跨域请求
egret.ImageLoader.crossOrigin = "anonymous";
RES.map("remote_img",new ResourceAnalyzer.RemoteImvAnalyzer())
这样之后我们就可以在资源配置文件default.res.json中配置该类型资源:
{
"url": "http://xxx.xxx.xxx:90/set_icon.png",
"type": "remote_img",
"name": "set_icon_png"
}
但是这么解决会有一个问题,就是程序运行时能够加载出资源,但是我们在皮肤设计时会报错:没有remtoe_img该资源类型的加载器。所以通过新增资源加载器不适用于这种场景,只能用于一些其他类型的资源加载。我们还是得在原有的资源加载器基础上做文章,我们通过搜索可以找到程序默认的图片和音频的资源加载器,在lib/modules/assetsmanager/assetsmanager.js文件中,我么能找到资源加载的具体代码:
processor_1.ImageProcessor = {
onLoadStart: function (host, resource) {
var loader = new egret.ImageLoader();
//这一行就是资源加载
loader.load(RES.getVirtualUrl(resource.root + resource.url));
return promisify(loader, resource)
.then(function (bitmapData) {
var texture = new egret.Texture();
texture._setBitmapData(bitmapData);
var r = host.resourceConfig.getResource(resource.name);
if (r && r.scale9grid) {
var list = r.scale9grid.split(",");
texture["scale9Grid"] = new egret.Rectangle(parseInt(list[0]), parseInt(list[1]), parseInt(list[2]), parseInt(list[3]));
}
return texture;
});
},
onRemoveStart: function (host, resource) {
var texture = host.get(resource);
texture.dispose();
}
};
我们可以看到资源加载时是加了一个resource.root这样一个前缀,所以会导致我们的http开头的远程链接无法加载。所以我们将这一部分代码改写:
processor_1.ImageProcessor = {
onLoadStart: function (host, resource) {
var loader = new egret.ImageLoader();
//改后动的加载代码
console.log("加载资源url:" + resource.url)
if(resource.url.indexOf("http")==-1){
loader.load(RES.getVirtualUrl(resource.root + resource.url));
}else{
loader.load(RES.getVirtualUrl( resource.url));
}
//以上是改动代码
return promisify(loader, resource)
.then(function (bitmapData) {
var texture = new egret.Texture();
texture._setBitmapData(bitmapData);
var r = host.resourceConfig.getResource(resource.name);
if (r && r.scale9grid) {
var list = r.scale9grid.split(",");
texture["scale9Grid"] = new egret.Rectangle(parseInt(list[0]), parseInt(list[1]), parseInt(list[2]), parseInt(list[3]));
}
return texture;
});
},
onRemoveStart: function (host, resource) {
var texture = host.get(resource);
texture.dispose();
}
};
我们将这个代码运行后果然能加载,所以我们的配置文件中只要这样配置就好了:
{
"url": "http://xxx.xxx.xxx:90/set_icon.png",
"type": "images",
"name": "set_icon_png"
}
这样之后,皮肤设计时同样能加载出来,就完美解决了我们的问题。
本来以为这样就好了,谁知道项目重新编译后,原本改的代码又恢复回去了,所以直接改项目中的代码是不行的,所以一定是程序中有什么地方存储者源文件,而项目中的文件只是每个项目里的副本,一旦重新编译又会被源文件覆盖。通过搜索发现源文件的路径是:~/Library/Application\ Support/Egret/engine/5.4.1/build/assetsmanager/assetsmanager.js。这是mac的路径,可能window还不太一样,需要大家去探索一下。然后我将上面修改的代码在源文件中进行了修改,之后重新编译代码,果然有效,到此完美解决。
2021-07-24日,接上面说的通过修改egret引擎代码实现我们的配置文件可以配置远程资源,但是当我们将egret程序打包成微信小程序后,会发现又不行了。查询代码后发现,打包成微信小程序后,重新实现了资源加载,比如音频加载,我们在sound.js文件中会找到这两行代码:
const processor = new SoundProcessor();
RES.processor.map("sound", processor);
我们只需要将这两行代码注释掉了就可以了,同样我们可以在image.js文件中找到同样类似的代码:
const processor = new ImageProcessor();
RES.processor.map("image", processor);
同样我们将这两行代码注释掉。