Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

RPGツクールMVで「Hello World」というだけのシーンを作成、プラグイン化

More than 3 years have passed since last update.

はじめに

RPGツクールMVで僕の考えた最強のバトルシステムを実現したいと考えたとき、もっとも有力な選択肢はプラグインを作ることです。
というわけでプラグインを作ろうと思ったのですが、スクリプトを書くまでの準備の段階でけっこう手間取ってしまったので今日は「Hello World」だけで終了としてそこまでで記事を書いてみます。

ファイルを作る

まず js/plugins フォルダの中にファイルを作ります。今回は hello.js とします。
全体を無名関数の中に入れます。

(function() {
  //ここに処理
})();

関数の中に入れるのは外(グローバル)とスコープを分けるためだと思いますが自分もよくわかっていません。

プラグインコマンドを登録、呼び出す

MVではプラグインを実行するのに、イベントコマンドから「プラグインコマンド」を打ち込みます。
プラグイン側では、プラグインコマンドに反応するように処理を書かなければなりません。
(自動で実行されるタイプのプラグインは例外)

(function() {
//ここに処理
var _Game_Interpreter_pluginCommand =
            Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
        _Game_Interpreter_pluginCommand.call(this, command, args);
        if (command === 'Hello') {
            switch (args[0]) {
            case 'World':
                $gameMassage.add("Hello World");
                break;
            }
        }
    };
})();

一気に書きましたが…
本体は

Game_Interpreter.prototype.pluginCommand = function(command, args) {}

この辺です。
イベントコマンド「プラグインコマンド」が打ち込まれたとき、この関数が実行され、

_Game_Interpreter_pluginCommand.call(this, command, args);

ここで「本来するはずだった処理(Game_Interpreter.prototype.pluginCommand が上書きされてなかったらするはずだった処理)」を呼んでいます。
単純に上書きしてしまうと、他のプラグインの動作の妨げになるので、ここで「本来するはずだった処理」を呼び戻すことで他のプラグインの邪魔にならないようにしているのです。
…たぶん!

        if (command === 'Hello') {
            switch (args[0]) {
            case 'World':
                $gameMassage.add("Hello World");
                break;
            }
        }

ここは見た目にわかりやすいですが、プラグインコマンドが'Hello'のときswitch文が実行され、プラグインコマンドの引数が'World'だったときゲームメッセージ、つまりデフォルトの文章表示を呼び出しています。

これで本体エディタの方でプラグインコマンド「Hello World」を入力してテストプレイすると文章「Hello World」が表示されると思います。

ここまででプラグインができました。次はシーンです。

シーンの作成

ゲームの場合キー入力などがありますが、「右」を入れたときもしバトルシーン、マップ移動シーン、アイテム選択シーンが同時に起動していたらすべてに「右」という命令が入ってしまってややこしいです。
そこでツクールMVではSceneManagerがシーンを管理し、バトルやマップ移動を同時に一つだけ実行するようにしています。
今回作る予定の僕の考えた最強のバトルシステムも、Scene_MyBattleなどとしてシーンとして作ることになるはずです(そこまで行ってませんけど)。

    function Scene_Hello() {
        this.initialize.apply(this, arguments);
    }

    Scene_Hello.prototype = Object.create(Scene_Base.prototype);
    Scene_Hello.prototype.constructor = Scene_Hello;

とりあえずシーン「Scene_Hello」を作ろうと思います。
MVではシーンを作る際、Scene_Baseを継承してくるみたいです。
(詳しいことは自分はよくわかってません)

    /**
    * シーンの開始時
    */
    Scene_Hello.prototype.initialize = function() {
        console.log("シーン呼んだよ");
        Scene_Base.prototype.initialize.call(this);
    };

    /**
    * シーンの、画面がアップデートされるたびに呼び出される処理
    * メインループ
    */
    Scene_Hello.prototype.update = function() {
        console.log("hello world");
        Scene_Base.prototype.update.call(this);
    };

そしてScene_Hello.prototypeの関数を例によって上書きします。
今回はupdateの中にconsole.log「Hello World」を入れました。
この他にも上書きして使う関数があるようなので、Scene_Baseを開いて確認ください。

仕上げ & 呼び出し

先程のプラグインコマンドを微妙に書き換えます。

        if (command === 'Hello') {
            switch (args[0]) {
            case 'World':
                //ここ書き換え
                SceneManager.goto(Scene_Hello);
                break;
            }
        }

SceneManagerは前述の通りシーンを管理するオブジェクトです。
それのgotoメソッドに、先程作成したScene_Helloを渡してやります。
テストプレイするとconsole(F8で表示)で、永遠に「Hello World」し続けます!
永遠にし続けるのはシーンから抜けてないからで、
再びgotoするか、popするなど対策があります。

//行って帰ってこない
SceneManager.goto(Scene_Hello);


//行くが帰ってくる準備をしておく
SceneManager.push(Scene_Hello);
//帰ってくる
SceneManager.pop();

まとめ

というわけでコンソールにハローワールドするだけのシーンを作ってプラグイン化しました。
けっこう長かった…
ツクール2000時代はプラグインの代わりにイベントコマンド組み合わせで複雑なシステムを組むものでしたが、それは少なくとも動くという利点があり、プラグイン時代は動くまでが長いという欠点がある気がします。
とはいえ一度動く状態にしてしまえばあとは早い(はず)です。
僕の考えた最強のバトルシステムをツクるぞ!

今日書いたjs

//=============================================================================
// Hello.js
//=============================================================================
(function() {
        function Scene_Hello() {
        this.initialize.apply(this, arguments);
    }

    Scene_Hello.prototype = Object.create(Scene_Base.prototype);
    Scene_Hello.prototype.constructor = Scene_Hello;
    /**
    * シーンの開始時
    */
    Scene_Hello.prototype.initialize = function() {
        Scene_Base.prototype.initialize.call(this);

    };

    /**
    * シーンの、画面がアップデートされるたびに呼び出される処理
    * メインループ
    */
    Scene_Hello.prototype.update = function() {
        console.log("hello world");


        Scene_Base.prototype.update.call(this);


    };


//ここに処理
var _Game_Interpreter_pluginCommand =
            Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
        _Game_Interpreter_pluginCommand.call(this, command, args);
        if (command === 'Hello') {
            switch (args[0]) {
            case 'World':
                SceneManager.goto(Scene_Hello);
                break;
            }
        }
    };
})();
mi_ki_ri
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away