LoginSignup
2
4

More than 3 years have passed since last update.

SetWaitModeはその実、何をwaitしているのか?

Posted at

そもそも私がこの記事を書こうと思ったのは、公式フォーラムで見たとある質問が切っ掛けになっております。

◆スクリプト:$gameMessage.add('aaaa');
:     :this.setWaitMode('message');
◆スクリプト:AudioManager.playSe({name:'Attack1', volume:90, pitch:100, pan:0})

何故スクリプトを分けるとsetWaitModeが機能するのかさっぱり分かりませんが、とにかくありがとうございました。

(https://forum.tkool.jp/index.php?threads/%E3%80%90%E8%A7%A3%E6%B1%BA%E6%B8%88%E3%81%BF%E3%80%91-gamemessage-add-%E3%81%A7%E5%81%9C%E6%AD%A2%E3%81%95%E3%81%9B%E3%82%8B%E6%96%B9%E6%B3%95.3422/#post-18405)

ここら辺の仕組み、あまり解説している所ないよな…
しかも、これってツクールの根幹を理解するのに良い機会だよな…
と考え、この記事を建てました。

そもツクールMVはどうやって「動いて」いるのか?

大元を辿れば、メインとなるループはSceneManager.updateです。
この中で更にSceneManager.updateMain → SceneManager.requestUpdateを経て、pixiのrequestAnimationFrameにより次のフレームで再度SceneManager.updateが呼び出されます。

このSceneManager.updateMainの中にはSceneManager.updateSceneがあり、各Scene(Scene_Map/Scene_Battle等)のprototype.updateに繋がります。

setWaitModeがしている事

前述の通り、Scene_Mapの場合、Scene_Map.prototype.updateが呼び出され、その中にはイベントコマンドをコントロールするGame_Interpreterのupdateも、Scene_Map.prototype.updateMainMultiply → Scene_Map.prototype.updateMain → Game_Map.prototype.update → Game_Map.prototype.updateInterpreter を経由して呼び出されてます。

rpg_object.js
Game_Interpreter.prototype.update = function() {
    while (this.isRunning()) {
        if (this.updateChild() || this.updateWait()) {
            break;
        }
        if (SceneManager.isSceneChanging()) {
            break;
        }
        if (!this.executeCommand()) {
            break;
        }
        if (this.checkFreeze()) {
            break;
        }
}

これを見ると分かる通り、Game_Interpreter.prototype.updateWaitがtrueを返した場合、breakが発生し次のコマンドを実行するだろうGame_Interpreter.prototype.executeCommandは実行されません。
そして――

rpg_object.js
Game_Interpreter.prototype.updateWaitMode = function() {
    var waiting = false;
    switch (this._waitMode) {
    case 'message':
        waiting = $gameMessage.isBusy();
        break;
    case 'transfer':
        waiting = $gamePlayer.isTransferring();
        break;
    case 'scroll':
        waiting = $gameMap.isScrolling();
        break;
    case 'route':
        waiting = this._character.isMoveRouteForcing();
        break;
    case 'animation':
        waiting = this._character.isAnimationPlaying();
        break;
    case 'balloon':
        waiting = this._character.isBalloonPlaying();
        break;
    case 'gather':
        waiting = $gamePlayer.areFollowersGathering();
        break;
    case 'action':
        waiting = BattleManager.isActionForced();
        break;
    case 'video':
        waiting = Graphics.isVideoPlaying();
        break;
    case 'image':
        waiting = !ImageManager.isReady();
        break;
    }
    if (!waiting) {
        this._waitMode = '';
    }
    return waiting;
};

こちらで分かる通り、_waitmodeに値がセットされていると、相応のパラメータをチェックし、まだ終わっていない場合は次のイベントコマンドに進まない仕組みになっております。

結局何故スクリプトの中でsetWaitModeをセットしても次の行(スクリプト)が実行されてしまうのか

上記から分かる通り、waitmodeはあくまでも「一つのイベントコマンドから次のイベントコマンドに進むのを止める」効果を発揮してます。
同じスクリプトコマンドの中で改行しても、それは結局同じイベントコマンドの中身であり、それ故にwaitmodeは効果を発揮しません。
逆にスクリプトを別々のイベントコマンドに分けた場合、上記の通り、次のスクリプトイベントコマンドに進む事がupdateWaitmodeによって阻まれ、3行目相当のAudioManager.playSe({name:'Attack1', volume:90, pitch:100, pan:0})は実行されない…と言う事ですね。

2
4
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
2
4