Egret游戲大廳制作思路
Egret中,寫好的代碼最終都被打包到main.js里面,只有庫文件會單獨生成出來,按需加載。
游戲中有需求,要將一些游戲(或者模塊)進行外包,然后從主游戲大廳中進入,那么可以通過第三方庫的形式進行開發。
第一步:創建目錄
創建三個目錄,Plaza,Child,lib分別對應 主游戲大廳、子游戲、庫。最終要將子游戲放入到庫中。
第二步:開發
這里只做簡單的開發,即:從主游戲直接打開子游戲。效果如下:
主游戲:
代碼:(通過egret默認的代碼制作的界面)
protected createGameScene(): void {
let button = new eui.Button();
button.label = "Click!";
button.horizontalCenter = 0;
button.verticalCenter = 0;
this.addChild(button);
button.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onButtonClick, this);
}
/**
* 點擊按鈕
* Click the button
*/
private onButtonClick(e: egret.TouchEvent) { }
子游戲:
代碼:(只有一個圖標)
protected createGameScene(): void {
let icon: egret.Bitmap = this.createBitmapByName("egret_icon_png");
this.addChild(icon);
icon.x = 26;
icon.y = 33;
}
第三步:整理子游戲庫
這個時候,我們兩個游戲其實都好了。需要將子游戲嫁接到主游戲大廳中。
有幾個問題需要解決:
首先,資源沖突
resource/default.res.json
resource/default.thm.json
這兩個文件基本上是所有游戲開發中都要用的。並且不能更改(更改后會各種報錯,所以保留)。既然我們要嫁接過去,這兩個文件在主游戲里面是要重新命名的。否則游戲會把這兩個文件解析成主游戲對應的文件,產生沖突,報錯。
所以,子游戲中將兩個文件名字提取,以及 resource目錄也要提取。
我們創建Ress.ts,這個將來也要在主游戲中用。所以我們目錄新建文件夾 same,將Ress.ts放入,並且將LoadingUI.ts放入其中(因為主游戲中也有)。目錄結構如下:
Ress.ts代碼:
class Ress
public constructor() {
}
public static child = ["resource/default.res.json","resource/default.thm.json","resource"]
}
替換Main.ts中路徑:
await RES.loadConfig(Ress.child[0],Ress.child[2]);
let theme = new eui.Theme(Ress.child[1], this.stage);
對了,將不用的資源請刪除掉,兩個項目中不能有同名的資源。
其次:命名空間沖突。
因為兩個項目中都有main.ts,有需要給子游戲添加命名空間(所有的都要,防止沖突);
namespace child {
export class Main extends eui.UILayer {
namespace child {
export class AssetAdapter implements eui.IAssetAdapter {
namespace child {
export class ThemeAdapter implements eui.IThemeAdapter {
第四步:將子游戲發布成第三方庫:
創建child庫
將子游戲src下的文件拷貝到src目錄,不要拷貝same目錄下文件,會跟主游戲引起沖突。
Typings目錄下放入child.d.ts
declare namespace child{
class Main{}
}
讓主游戲調用。
生成庫 egret build
,查看bin
目錄,生成child.js
文件,如果沒有child.d.ts
手動拷貝(我的是沒有生成).
第五步:主游戲引用第三方庫child
{
"name": "child",
"path":"../GameLib/child"
}
清理構建,然后libs目錄多出來我們剛剛創建的。
主游戲Main.ts
private onButtonClick(e: egret.TouchEvent) {
let game = new child.Main();
this.addChild(game as eui.UILayer);
}
運行看一下。
第六步:完了么?裝載子游戲資源
白鷺圖片是child游戲里面的么?我們什么都有做呢。現在顯示的只是我們把子游戲裝載了進來。我們還沒有把子游戲資源拿過來。
將父容器中除了與按鈕相關的資源刪除:
子游戲中將白鷺以外的圖片刪除:
注意:
子游戲中的資源組與資源都不能與主游戲中的沖突。我們把資源組改名。
發布子游戲,正常的游戲發布流程。我們需要壓縮過的資源。
將子游戲拷貝到主游戲中,在主游戲創建新的路徑resource-child
子游戲中加載的preload改成child_preload
將子游戲中的文件拷貝到庫中。編譯(忽略錯誤);
我們在主游戲中開始運行子游戲。
報錯!!!!
將子游戲中的same目錄拷貝到主游戲中,公共部分
放一起。
查看Ress,里面路徑是對應主游戲的,改成子游戲的路徑。
class Ress {
public constructor() {
}
public static child = ["resource-child/child.res.json","resource-child/child.thm.json","resource-child"]
}
可以了,實現目的。
后記:
步驟有些繁瑣,尤其是拷貝文件時候。所以可以自己寫一個腳本來處理這些繁瑣的操作,避免出錯。
里面要避免命名空間沖突以及資源沖突。
公用類放到統一的文件夾里面,方便操作。
路徑可以用配置的形式動態加載,不用每次編譯。
說白了,還是想法操作js(游戲程序員跟web程序員還是不一樣,好多概念會模糊吧)