【解決済み】自由な内容を記述できるウィンドウを作成するプラグインについて

Asta15
記事: 4
登録日時: 2021年10月26日(火) 00:16

【解決済み】自由な内容を記述できるウィンドウを作成するプラグインについて

投稿記事by Asta15 » 2021年10月26日(火) 01:33

トピックの初投稿失礼いたします。

ツクールMVにて、右上に現在のゲーム内時間を常に表示するウィンドウを作成したいと思い、kotonoha*様のInfoWindow.jsを参考にさせていただき、さらに他のプラグイン製作者様の作成したプラグインを参考に以下のようなテスト用プラグインを作成いたしました。スイッチや変数は以下のように使用されております。
フィールド上で特定のイベント(採取や戦闘など)を読み込んだ時に、時間が経過する仕様なので、常に時間は表示するようになっています。

スイッチ#0001 : true=表示 false=非表示
変数  #0005 : 日にちを表す変数
変数  #0006 : 時間(分)を表す変数

tomoaky様が作成した「TMMapHpGauge.js」も作成中のゲームで併用しているので、同様の動作を行うようなウィンドウが作成したいです。
(・メニューを起動時、ウィンドウが瞬間消去され、メニューを閉じた後に瞬間表示される。
 ・バトル開始時、ウィンドウが瞬間消去され、終了後に瞬間表示される。)
 ・プラグインコマンドにより、ウィンドウが緩やかに開閉する。)

しかし、私はjsの記述に慣れていないため、思うようなプラグインが作成できませんでした。
上記カッコ内の仕様で動くようなウィンドウの作成方法を教えていただけないでしょうか?
この以下のプラグインはスイッチにより表示のON,OFFを変更していますが、可能であればプラグインコマンドにより開閉させられるようにしたいです。

コード: 全て選択

// TimeWindow.js

(function() {
   
   var Scene_map_start = Scene_Map.prototype.start;
   Scene_Map.prototype.start = function() {
      Scene_map_start.call(this);
      this._TimeWindow = new TimeWindow();
      this.addWindow(this._TimeWindow);
   };
   
   
   var _Scene_Map_update = Scene_Map.prototype.update;
   Scene_Map.prototype.update = function() {
      _Scene_Map_update.call(this);
      this._TimeWindow.loadText();
   };
   
   
   function TimeWindow() {
      this.initialize.apply(this, arguments);
   }

   TimeWindow.prototype = Object.create(Window_Base.prototype);
   TimeWindow.prototype.constructor = TimeWindow;
   
   TimeWindow.prototype.initialize = function() {
      if ($gameSwitches.value(1) == true){
         Window_Base.prototype.initialize.call(this, 626, 10, 180, 108);
         this.openness = 255;
         
         this.contents.clear();
         this.drawText($gameVariables.value(5) + "日目", 1, 1);
         var hour = Math.floor($gameVariables.value(6)/60);
         var min = $gameVariables.value(6)%60;
         this.drawText(hour + " 時 " + min + " 分",0,this.lineHeight());
      } else {
         Window_Base.prototype.initialize.call(this, 626, 10, 180, 108);
         this.openness = 0;
         this.contents.clear();
      }
   };
   
   TimeWindow.prototype.loadText = function() {
      if ($gameSwitches.value(1) == true){
         this.opacity = 255;
         this.contents.clear();
         this.drawText($gameVariables.value(5) + "日目", 1, 1);
         var hour = Math.floor($gameVariables.value(6)/60);
         var min = $gameVariables.value(6)%60;
         this.drawText(hour + " 時 " + min + " 分",0,this.lineHeight());
         this.opacity = 255;
      } else {
         this.opacity = 0;
         this.contents.clear();
         this.opacity = 0;
      }
   };
   
   TimeWindow.prototype.standardFontSize = function() {
      return 24;
   };
})();
最後に編集したユーザー Asta15 on 2021年10月26日(火) 14:24 [ 編集 1 回目 ]

アバター
Plasma Dark
記事: 674
登録日時: 2020年2月08日(土) 02:29
連絡を取る:

Re: 自由な内容を記述できるウィンドウを作成するプラグインについて

投稿記事by Plasma Dark » 2021年10月26日(火) 04:03

GraphicalDesignMode.js のユーザー定義領域を利用する方法もあるかとは思いますが、どのみち .js を編集することになるので、ここでは自前で書くアプローチについて記します。

コアスクリプト(rpg_scenes.jsやrpg_windows.js)をよく読んで実装されると良いと思います。

最初はこれだけだと辛かろうと思いますので、見本を置いておきます。
あくまで見本ですので、要件を全て満たすものではないことにご注意ください。

ご提示頂いたコードと見本の違い、コアスクリプトの関連箇所について説明します。

1. ウィンドウの生成は createAllWindows から呼び出す
Scene_Map クラスには、シーン内で使うウィンドウを生成するための createAllWindows メソッドがいます。
start メソッドはシーンの開始を意味するもので、ウィンドウの生成をここで行うには特別な理由が必要であるように思われます。

createAllWindows メソッド内で直接 new を記述しても良いですが、コアスクリプトでは他のウィンドウがそれぞれメソッドを作って生成しているので見本はそれに倣っています。

2. updateメソッドで重たい処理を毎回行ってはいけない
TimeWindow クラスの loadText メソッドは、見る限りだと中身をクリアして再描画しています。
一度描画した内容は、それを変化させたい場合以外に、消して再描画する必要はありません。
Scene_Map クラスの update メソッドは、毎フレーム呼ばれる処理になっていて、ここで毎度ウィンドウの内容を消して再描画するとパフォーマンスに影響が出そうです。

見本では、 $gameTemp.isRefreshTimeWindowRequsted() が真を返した場合のみに絞って、ウィンドウの内容を更新しています。

3. プラグインパラメータによるウィンドウの開閉
見本では、閉じるプラグインコマンドのみ定義しています。
マップシーンで表示されるウィンドウなので、閉じるリクエストが発行されたかどうかを Scene_Map クラスの update メソッドで確認して閉じています。
ウィンドウの開閉状態をセーブデータに保持する必要はたいてい無いので、 Game_Temp クラスに真偽値を持たせていますが、要件によってはスイッチを使っても良いと思います。

Window_Base クラスには close メソッドが定義されていて、時間ウィンドウにも継承されているので、それを用いて閉じています。
開く場合には open メソッドが使えます。

4. メニューを開く前にウィンドウを非表示にする
Scene_Map クラスの callMenu がメニューシーンへ遷移するコードになっているので、ここで時間ウィンドウを非表示にしています。
close 同様に hide メソッドも定義されていますので、それを使えば非表示にする(閉じる動作ではなく、瞬時に消す)ことができます。

見本では、マップシーンを開いた瞬間から時間ウィンドウを表示するようになっているので、メニューを閉じた後に瞬間表示の要件は自動的に満たされます。
(メニューに限らず、戦闘でも、別シーンに遷移して戻ってきた場合は同様の挙動をします)

戦闘開始時も同様に書けます。メニューより少し複雑ですが、マップシーンから戦闘シーンに遷移するコードを rpg_scenes.js から探してみてください。
シーンから別のシーンに遷移する際には、 stop メソッドが呼ばれます。

5. その他細かい違い
- 厳格モードを使用しましょう。
- varではなくconst(必要に応じてlet)を使用しましょう。
- プログラム中の値を文字列に含めたい場合、テンプレートリテラルが便利です。
- ウィンドウクラスの定義に class 構文を用いるかどうかは好みの問題ですので、わかりやすいと思ったほうを使用されると良いと思います。
Asta15
記事: 4
登録日時: 2021年10月26日(火) 00:16

Re: 自由な内容を記述できるウィンドウを作成するプラグインについて

投稿記事by Asta15 » 2021年10月26日(火) 04:35

Plasma Dark 様

丁寧でわかりやすいご回答をしてくださっただけでなくサンプルコードまで用意していただきありがとうございます。
ご指摘の通り、時間に余裕があるときにコアスクリプトのソースコードの閲覧をじっくりとすることにします。
後日、コアスクリプトや作成してくださった見本を参考に勉強として自分でコードを書く練習をしてみます。
しかしながら、現在の私の技量では一からプラグインを作成することは厳しいかと思われます。
お借りした素材の中に記述させていただきますので、今回、Plasma Dark 様に作っていただいた見本のプラグインを(私の技量に余裕があれば改変をして)使用させていただいてもよろしいでしょうか。

JavaScriptに触れた経験がRPGツクールMV以前になかったので、説明していただけるまでrpg_scenes.jsでどのメソッドがどのタイミングで呼び出されているかの理解が全くできませんでした。
それどころか、質問した当時constと宣言することで定数が宣言できることすら存じ上げておらずJavaScriptに対する理解が全く足りていませんでした。
このような基礎的な技術もままならないまま高度な質問をしてしまい申し訳ございません。

次回、またツクマテ様に質問を投稿する時には、ある程度自分の中での理解を深めてから投稿しようかと思います。
本日はご親切に回答していただき、誠にありがとうございました。
アバター
Plasma Dark
記事: 674
登録日時: 2020年2月08日(土) 02:29
連絡を取る:

Re: 自由な内容を記述できるウィンドウを作成するプラグインについて

投稿記事by Plasma Dark » 2021年10月26日(火) 12:05

今回、Plasma Dark 様に作っていただいた見本のプラグインを(私の技量に余裕があれば改変をして)使用させていただいてもよろしいでしょうか。


はい。最初から読むだけでは何が何やらわからないと思いますので、動くサンプルを書き換えて動かしてを繰り返しながら、理解を深めていってください。
私がgistに公開しているコードは、積極的にサポートしない代わりにCC0として、特に制限なくご利用いただけます。

JavaScriptに触れた経験がRPGツクールMV以前になかった


ご提示頂いたプラグインがある程度整った形をしていたので、多少の読み書きはできるものだと想定した書き込みになってしまいました。

コアスクリプトを読み解く近道は、先人の足跡をたどることです。
とんびさんが作成された Map関連クラスを調べてみた 辺りは調べ方も詳しく、わかりやすいと思います。
JavaScript自体の読み方、書き方で迷ったときには MDNJavaScript Primer が役立ちます。

プラグインを一から書く練習の方法としては、自分の最終目的と全く関係のないものを書いても辛いので、自分の目的を小さく分割して、少しずつ書いて動きを理解していくのが良いと思います。
今回の例で言えば、
- 指定したスイッチをON/OFFにするだけのプラグインコマンド
- マップにウィンドウを表示するだけのプラグイン
- スイッチの状態によってウィンドウの表示/非表示を切り替えるプラグイン(見本を参考にしても構いませんし、 DestinationWindow.js 辺りを参考にしてみても良いと思います)
といった風に。

この過程でも、先人のプラグインを参考にすることである程度の近道はできます。
目的に近い機能を持ったプラグインを探して参考にされているようですが、その方針自体はとても良いと思います。
結果として出来上がったコードの品質に不安がある場合は、技術のある人に見てもらうと良いでしょう。

このような基礎的な技術もままならないまま高度な質問をしてしまい申し訳ございません。


質問内容が高度なものであるかどうか、最初はわからないものです。
知らなかったことを一つずつ知って身につけていくことで、目的に近づくことができます。
行き詰まったと感じたら、(もちろん、内容を整理した上で)また質問を投げてみてください。
Asta15
記事: 4
登録日時: 2021年10月26日(火) 00:16

Re: 自由な内容を記述できるウィンドウを作成するプラグインについて

投稿記事by Asta15 » 2021年10月26日(火) 14:31

タイトルを【解決済み】にいたしました。

はい。最初から読むだけでは何が何やらわからないと思いますので、動くサンプルを書き換えて動かしてを繰り返しながら、理解を深めていってください。
私がgistに公開しているコードは、積極的にサポートしない代わりにCC0として、特に制限なくご利用いただけます。


サンプルコードの利用の許可を感謝いたします。
これからはツクールMVだけでなくJavaScriptの習得も頑張りたいと思います。
次回、また私がプラグインを作るような機会があれば、先人様方が作ったプラグインを参考にし、まずは小さく簡単なプラグインの作成からしてみようかと思います。
この度は丁寧にご親切にしていただきありがとうございました。

“MV:質問” へ戻る