Posted at

EgretEngineでRPGマップはどう実現するか?(2) 表示処理が呼び出されるまで


ソースコードをおう


初期化処理



  1. Main::constructorthis.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);

  2. コールバックされたMain::onAddToStageからMain::loadResConfigを呼び出す


  3. Main::loadResConfigからApp.ResourceUtils.loadConfig(this.onConfigComplete, this);

  4. コールバックされたMain::onConfigCompleteからtheme.addEventListener(eui.UIEvent.COMPLETE, this.onThemeLoadComplete, this);

  5. コールバックされたMain::onThemeLoadCompleteにて以下の処理


Main.ts

class Main extends egret.DisplayObjectContainer {

:
private onThemeLoadComplete(): void {
this.initModule();
App.SceneManager.runScene(SceneConsts.LOADING);
new RpgTest();
new ProtoBufTest();
}
:
}


RpgTest

RpgTestクラスは、src/example/testにある

image.png

コンストラクタでマップリソースの初期化メソッドinitMapResourceを呼び出す。


RpgTest

    public constructor() {

:
this.mapId = 1193;
this.mapGroupKey = "map_" + this.mapId;
this.initMapResource();
:
}

initMapResourceはマップ情報を読み込んでいるわけではなく、マップ情報を読み込むたむのリソース定義情報を動的に生成しています。

今回のサンプルではマップ(mapId=1193)が1つしかありませんので、この処理は無駄に見えます。

しかし多数ある場合はこのように読み込むほうがいいですね。


RpgTest.ts

    private initMapResource(): void {

var mapResPath: string = "resource/assets/rpgGame/map/" + this.mapId + "/";
var mapResKey: string = this.mapGroupKey + "_";
var mapResKeys: string[] = [];
var mapRes: any[] = [
{
name: "data.json",
type: "json"
},
{
name: "mini.jpg",
type: "image"
}
];
mapRes.forEach(function (res) {
var resKey: string = mapResKey + res.name;
App.ResourceUtils.createResource(resKey, res.type, mapResPath + res.name);
mapResKeys.push(resKey);
})

App.ResourceUtils.createGroup(this.mapGroupKey, mapResKeys);
}


リソース定義に記載があるmini.pngは以下のようなミニマップの一枚絵の画像です

mini.jpg

マップの定義ファイルdata.jsonはこのようになっています

0と1しか値があらわれませんのでこちらは移動可能・不可能情報のみかもしれません


data.json

{

"path":"/map/1193/",
"width": 3200,
"height": 2400,
"blocks":[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],

:
:

[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
]
}


data.jsonmini.pngが含まれるリソースが読み込み開始されます


RpgTest.ts

  constructor() {

:
App.ResourceUtils.loadGroups(groupName, subGroups, this.onResourceLoadComplete, this.onResourceLoadProgress, this);
}

読み込みが終わった後は、各種モジュールがの読み込みや初期化が行われ、SceneConsts.RpgGame シーンが起動します。


RpgTest.ts

    private onResourceLoadComplete(): void {

this.initModule();
App.Init();

App.SoundManager.setBgOn(true);
App.SoundManager.setEffectOn(true);

App.SceneManager.runScene(SceneConsts.RpgGame, this.mapId);
}



RpgGameScene

SceneConsts.RpgGame シーンは、Main.tsクラスの初期化時に、RpgGameSceneクラスにバインドされています。


Main.ts

private initScene(): void {

:
App.SceneManager.register(SceneConsts.RpgGame, new RpgGameScene());
}

またApp.SceneManager.runsSceneを呼び出すと、新しいシーンのonEnterが呼び出されますので、RpgGameScene.onEnterを確認します。

    public runScene(key: number, ...param: any[]): void {

var nowScene: BaseScene = this._scenes[key];
:
var oldScene: BaseScene = this._scenes[this._currScene];
if (oldScene) {
oldScene.onExit();
}

nowScene.onEnter.apply(nowScene, param);
this._currScene = key;
}

シーンから実際に処理をするControllerConst.RpgGameという名前?のコントローラを呼び出しています。


src/example/module/RpgGameScene.ts


class RpgGameScene extends BaseScene{
:
public onEnter(...param:any[]):void{
:
var mapId:number = param[0];
:
App.ControllerManager.applyFunc(ControllerConst.RpgGame, RpgGameConst.GameInit, mapId);
:
}
}

実際には、RpgTest.tsにて、ControllerConst.RpgGameという名前は、RpgGameControllerというクラスにバインドされています。


RpgTest.ts

App.ControllerManager.register(ControllerConst.RpgGame, new RpgGameController());


ControllerManager.applyFuncの定義を見ると、RpgGameControllerというクラスが呼び出されていることがわかります。


ControllerManager.ts

    public applyFunc(controllerD: number, key: number, ...param: any[]): any {

var manager: BaseController = this._modules[controllerD];
if (manager) {
var params = [];
for (var i = 1; i < arguments.length; i++) {
params[i - 1] = arguments[i];
}
return manager.applyFunc.apply(manager, params);
} else {
Log.warn("模块" + controllerD + "不存在");
return null;
}
}

BaseController.applyFuncでは、第一引数をメソッド名と解釈しています。

つまり、App.ControllerManager.applyFunc(ControllerConst.RpgGame, RpgGameConst.GameInit, mapId);は、RpgGameController.GameInit(mapId)という呼び出しになります。

正確にはこのRpgGameControllerRpgGameControllerのインスタンスという意味です。


BaseController

    public applyFunc(key: any, ...param: any[]): any {

var listen: any = this._messages[key];
if (listen) {
return listen[0].apply(listen[1], param);
} else {
Log.warn("消息" + key + "不存在侦听");
return null;
}
}


RpgGameController

コントローラーからはViewConst.RpgGameビューを開きます。


RpgGameController.ts

    private gameInit(mapId: number) {

this.gameModel.mapId = mapId;
:
App.ViewManager.open(ViewConst.RpgGame, this.gameModel);
}

コンストラクターにてViewConst.RpgGameRpgGameViewにバインドされています。


RpgGameController.ts

        this.gameView = new RpgGameView(this, LayerManager.Game_Main);

App.ViewManager.register(ViewConst.RpgGame, this.gameView);


RpgGameView

ViewManagerにて、Viewの初期化処理が行われます。

またopenメソッドではRpgGameViewloadResourceメソッドを呼び出しリソースを読み込みます。

次に、initUIinitDataで初期化を行い、

最後にopenメソッドを呼び出し、

そのあとにsetVisible(true);が呼び出され表示されます。


ViewManager.ts

    public open(key: number, ...param: any[]): IBaseView {

var view: IBaseView = this.getView(key);
:
App.EasyLoading.showLoading();
view.loadResource(function () {
view.setVisible(false);
view.addToParent();
App.EasyLoading.hideLoading();
}.bind(this), function () {
view.initUI();
view.initData();
view.open(...param);
view.setVisible(true);
}.bind(this));
:
}


しめ

いったん長くなりましたので今日はここまで。

次回はRpgGameView以降のソースコードを読み解いていきます。