1.构建Eui项目结构
让自己的游戏项目构建好Eui的结构,这样就能使用eui的界面和功能了。
新建一个空白游戏项目,和一个Eui项目
打开游戏项目,对比Eui项目和游戏项目以下文件的区别,进行增加:
1.两个Ts文件
/src/AssetAdapter.ts
/src/ThemeAdapter.ts
2.一个default.thm.json
/resource/default.thm.json
{
"skins": {
},
"autoGenerateExmlsList": true,
"exmls": [
"resource/eui_skins/TestPanelViewSkin.exml"
],
"path": "resource/default.thm.json"
}
其中"skins" :{}中的是自定义组件
3.Main.ts中的两处不同
//inject the custom material parser
//注入自定义的素材解析器
let assetAdapter = new AssetAdapter();
egret.registerImplementation("eui.IAssetAdapter", assetAdapter);
egret.registerImplementation("eui.IThemeAdapter", new ThemeAdapter());
private async loadResource() {
try {
const loadingView = new LoadingUI();
this.stage.addChild(loadingView);
await RES.loadConfig(0,0,"resource/default.res.json", "resource/");
await this.loadTheme();
await RES.loadGroup("preload", 0, loadingView);
this.stage.removeChild(loadingView);
}
catch (e) {
console.error(e);
}
}
private loadTheme() {
return new Promise((resolve, reject) => {
// load skin theme configuration file, you can manually modify the file. And replace the default skin.
//加载皮肤主题配置文件,可以手动修改这个文件。替换默认皮肤。
let theme = new eui.Theme("resource/default.thm.json", this.stage);
theme.addEventListener(eui.UIEvent.COMPLETE, () => {
resolve();
}, this);
})
}
4.界面的Ts以及exml文件
\src\TestPanelView.ts
class TestPanelView extends eui.Component{
public constructor() {
super();
this.skinName = "resource/eui_skins/TestPanelViewSkin.exml";
}
}
\resource\eui_skins\TestPanelViewSkin.exml
<?xml version="1.0" encoding="utf-8"?>
<e:Skin class="TestPanelViewSkin" width="400" height="300" xmlns:e="http://ns.egret.com/eui">
<e:Image width="144" height="142" x="135" y="94" anchorOffsetX="0" anchorOffsetY="0" source="bg_jpg"/>
</e:Skin>
5.Main.ts中测试运行(注意添加的界面不要被其他界面挡住,不然看不到效果了)
let panelView:TestPanelView = new TestPanelView();
this.addChild(panelView);
2.把resource资源放在服务器上加载
resource中的网络加载的资源要放在CDN服务器上,提供给玩家加载。这里用Linux服务器上的Tomcat模拟资源服务器.
2.1 从Tomcat上加载资源的跨域问题
添加tomcat的JAVA环境设置
/opt/tomcat8/bin/catalina.sh:
添加两行:
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_151
export JRE_HOME=/usr/lib/jvm/jdk1.8.0_151/jre
修改跨域设置
先用控制台关闭tomcat服务
cd /opt/tomcat8/bin
--关闭:
./shutdown.sh
--开启:
./startup.sh
/opt/tomcat8/lib添加两个文件:
cors-filter-2.4.jar
java-property-utils-1.9.1.jar
这个博客有下载地点:
https://www.cnblogs.com/zhaoyanhaoBlog/p/9370830.html
在tomcat的/opt/tomcat8/conf/Web.xml中加上如下配置:
<!-- 提供跨域支持 -->
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, POST, HEAD, PUT, DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>Set-Cookie</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
重启Tomcat,接着放在Tomcat内的资源就可以被客户端Egret正常访问了。
2.2 Tomcat + Egret配置网络加载资源
服务端Tomcat中:
在websapp/文件夹中建立一个Egret文件夹,把白鹭项目的resource目录移入Egret文件夹
此时用浏览器能够访问到服务器上的资源
客户端中
Main.ts中的关键两个函数的代码:
private async loadResource() {
try {
const loadingView = new LoadingUI();
this.stage.addChild(loadingView);
await RES.loadConfig(0,0,"default.res.json", "http://xxx.xxx.xxx.xxx/Egret/resource/");//这里要填入服务器的ip地址
await this.loadTheme();
await RES.loadGroup("preload", 0, loadingView);
this.stage.removeChild(loadingView);
}
catch (e) {
console.error(e);
}
}
private loadTheme() {
return new Promise((resolve, reject) => {
egret.ImageLoader.crossOrigin = "anonymous";//设置允许跨域加载
EXML.prefixURL = "http://xxx.xxx.xxx.xxx/Egret/";//更改目录位置,这里要填入服务器的ip地址
// load skin theme configuration file, you can manually modify the file. And replace the default skin.
//加载皮肤主题配置文件,可以手动修改这个文件。替换默认皮肤。
let theme = new eui.Theme("http://xxx.xxx.xxx.xxx/Egret/resource/default.thm.json", this.stage);//这里要填入服务器的ip地址
theme.addEventListener(eui.UIEvent.COMPLETE, () => {
resolve();
}, this);
})
}
删掉本地的resource进行测试:
此时本地目录已经没有resource文件夹了
3.美术资源管理方案
当一个项目比较大,模块众多的时候。
对于资源的需求,程序和美术有一个需求冲突。
美术从设计的角度上,希望美术资源按照部件类型分类,方便复用。例如我想设计一个功能,先到面板资源中找到可以复用的面板资源,再到装饰物资源中找到可以复用的美术资源,从而省时省力的设计出一个新的功能面板。
程序员从性能的角度上,希望美术资源按照资源所属模块分类,方便内存加载释放以及其他管理,方便性能优化。例如我想让mainUI或者几个经常停留在界面的模块,他们的资源常驻内存中,而其余使用频率不高的模块的资源,关闭界面就释放掉,提升性能。如果美术资源是按照模块分类的,那我只要把属于这个模块的美术资源释放掉就行了。特别是运用到合图来减少drawcall的时候,要求资源必须以模块的形式来分类,不然当你只需要一个其他地方的小小的按钮素材的时候,会把那个地方整张合图加载过来。
我的公司,用的第二种方式,美术资源按模块来进行分类管理.这其实就对美术工作造成了一个困扰,如果我想新设计一个功能,需要复用到以前用过的资源,比如面板背景资源,美术需要在众多模块文件夹中寻找能够复用的资源。
我构思的方案是:
建立两个资源库,美术设计和实际使用分开
设置两个库。一个是美术设计库,一个是实际使用库
美术设计库
以设计组件的角度,对资源分类的一个文件夹
而为了方便美术查找使用率最多的资源,对每一个类型文件夹中增加“通用资源”以及其他组件资源文件夹
这样,假如美术希望在查找一个比较通用的面板美术资源,美术先进入面板资源文件夹,再进入通用资源,找到相关资源。
或者希望找到一个特定模块使用的面板美术资源,先进入面板资源文件夹,再进入特定的模块文件夹。
实际使用库
以模块的方式分类,每个分类中需要分为两个文件夹,一个是常驻内存区,一个是不常驻内存区。
不常驻内存区的资源可以很方便地关闭界面时就地销毁。
另外,如果有很多组件都要用到的资源,统一放到public文件夹中,根据是否长时间存留在界面中放入不常驻内存区或者常驻内存区。
工作流
1.美术利用美术设计库中的资源设计一个功能面板,如果有新资源增加,就添加到相应的美术设计库中。
2.程序员把相应的资源,按照所属模块,分发到实际使用库文件夹的各个模块文件夹之中(一般只要分发新增资源就行)。
某个资源,使用它的模块比较多,就放入 “实际使用库/public” 中。