LoginSignup
0
0

More than 5 years have passed since last update.

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

Posted at

ソースコードをおう

初期化処理

  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以降のソースコードを読み解いていきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0