【解決済み】「MV」のウィンドウ内に、JavaScriptで長文を表示するための記述の仕方を教えていただきたく・・・

返信する
アバター
蓮賀まさとき
記事: 26
登録日時: 2020年8月30日(日) 15:00

【解決済み】「MV」のウィンドウ内に、JavaScriptで長文を表示するための記述の仕方を教えていただきたく・・・

投稿記事 by 蓮賀まさとき »

「ツクマテ」の皆様、お世話になっております。
今回も、どうぞよろしくお願いいたします。

以下は「RPGツクールXP」のサンプルゲーム、「Alestian_Story」のスクリプトに倣って
「VX」の作品で使用している長文の表示方法です。

コード: 全て選択

@text = ["テキスト テキスト テキスト",
                  "テキスト テキスト",
                  "テキスト テキスト",
                  " ",
                  "テキスト テキスト テキスト",
                  "テキスト テキスト",
                  "テキスト テキスト テキスト",
                  "テキスト",]

for i in 0...@text.size
  x = 0
  y = 0 + i * 20
  self.contents.draw_text(x, y, 200, 20, @text[i])
end
この様な方法を、「MV」の rpg_windows に則った自作ウィンドウ内で行う場合の
記述の仕方を教えていただきたいです。よろしくお願いいたします。
最後に編集したユーザー 蓮賀まさとき [ 2021年6月08日(火) 22:21 ], 累計 1 回
・ツクールは、「触ってる歴」だけはムダに長いです(^^;
・スクリプトは「XP」で興味を持ち、「VX」「MV」でもレイアウトを変更したり、
 画像やテキスト、新たなウィンドウを追加するなど、デフォルトの簡単な応用で
 カスタマイズを楽しんでいます。
名無し蛙
記事: 352
登録日時: 2015年11月23日(月) 02:46

Re: 「MV」のウィンドウ内に、JavaScriptで長文を表示するための記述の仕方を教えていただきたく・・・

投稿記事 by 名無し蛙 »

Window_Base派生の自作ウィンドウを定義する時に書き込む方法って事ですかね
主な文法の違いは
・Rubyにおけるselfはjavascriptにおけるthisに当たる(rubyと違いthisの省略は不可能)
・メンバ変数を定義する場合は@xではなくthis._xと書く
・ローカル変数を定義する場合はconst、またはletを使用する
-基本的にconstを使用、定義時以降に値の変更が生じる場合はletに切り替える事
・命令の最後には;を付ける事。(省略は可能)
・Rubyでは引数無しの関数は()を省略出来たけどjavascriptでは省略不可能
・Rubyでは命名規則がself.hoge_piyo(単語は全て小文字、単語間は_で繋ぐ)だったが
-javascriptではthis.hogePiyo(最初の単語は全て小文字、以降の単語は頭だけ大文字、_は不使用)
-さらにアクセス範囲がprotected以内の変数・メソッドは頭に_を付ける(例:this._hogePiyo)
・文章の書き込みはthis.drawText(text, x, y, maxWidth, align)でcontents等は不要
-alignは文字列で指定する事('left', 'right', 'center')
-画面解像度が引き上げられた影響で文字サイズが28、lineHeightも36が標準なのでそれに合わせる事
・配列にアクセスする場合は基本的にfor文よりもforEachを使用した方が良い
-(Rubyの時点でその方が推奨されてますけど)

総じて、例文のコードを書き換えるなら

コード: 全て選択

    this._texts = [
        "テキスト テキスト テキスト",
        "テキスト テキスト",
        "テキスト テキスト",
        " ",
        "テキスト テキスト テキスト",
        "テキスト テキスト",
        "テキスト テキスト テキスト",
        "テキスト",
    ];
    this._texts.forEach((text, i) => {
        const x = 0;
        const y = 0 +  i * this.lineHeight();
        this.drawText(text, x, y, this.contents.width, 'left');
    });
箇条書きにしてみるとけっこう差異は多いですね…まぁ、必要以上に最適なコードに整えてるせいですけど。
一応、initializeのタイミングでdrawTextする事を想定していますけど
丸暗記で対応するには少し難しいかもしれません。
本格的に自作ウィンドウを作ろうと思うと
newの違いとかaddChildしないと反映されないとか色々あるので他で詰まるかも。
アバター
蓮賀まさとき
記事: 26
登録日時: 2020年8月30日(日) 15:00

Re: 「MV」のウィンドウ内に、JavaScriptで長文を表示するための記述の仕方を教えていただきたく・・・

投稿記事 by 蓮賀まさとき »

名無し蛙様

はじめまして。JavaScript のコードをご提示くださってありがとうございます!
また、Ruby との差異までご解説いただき、感謝いたします。

お陰様で、this.drawText を行数分連ねるやり方から脱却することができた・・・
と思ったのですが、上手く行く場合とエラー( Type Error Cannot read property
'forEach' of undefined )になってしまう場合が出て来てしまいました。
名無し蛙 さんが書きました:一応、initializeのタイミングでdrawTextする事を想定していますけど
丸暗記で対応するには少し難しいかもしれません。
本格的に自作ウィンドウを作ろうと思うと
newの違いとかaddChildしないと反映されないとか色々あるので他で詰まるかも。
早速詰まってしまったかもしれません(汗)。ただ、確率としては私が何か見落として
凡ミスをしている・・・方が高そうなので、それぞれの window の違いなどを
もっと良く確認してみます。

ひとまずお礼とご報告まで。名無し蛙様、ありがとうございました!
・ツクールは、「触ってる歴」だけはムダに長いです(^^;
・スクリプトは「XP」で興味を持ち、「VX」「MV」でもレイアウトを変更したり、
 画像やテキスト、新たなウィンドウを追加するなど、デフォルトの簡単な応用で
 カスタマイズを楽しんでいます。
名無し蛙
記事: 352
登録日時: 2015年11月23日(月) 02:46

Re: 「MV」のウィンドウ内に、JavaScriptで長文を表示するための記述の仕方を教えていただきたく・・・

投稿記事 by 名無し蛙 »

蓮賀まさとき さんが書きました:上手く行く場合とエラー( Type Error Cannot read property
'forEach' of undefined )になってしまう場合が出て来てしまいました。
forEachが無い…これはアレですかね。
実は微妙に気になったので@textからthis._textsに変更してるんですけど
その辺に気付かず混在しているとthis._text.forEachとか書いて同様のエラーが起こる可能性がありますね。

それと新規ウィンドウの用途が分からないのであまり込み入った事は書けなかったのですが
簡単な例文を書くならこうなりますかね…マップ画面に適当なウィンドウを表示するプラグインです。
class構文を使うか迷ったのですけどこちらの方がRubyに近いので
コアスクリプトの書き方とは異なりますがこういう書き方もありますよ、という事で。
新規のクラスを作る場合はこちらの方が捗ります。
一度コツを掴めば後は反復作業だと思うんですけどそこまでのハードルが少し高いかもしれませんね。

コード: 全て選択

(() => {
    'use strict'
    class Window_Test extends Window_Base {
        constructor() {
            super(...arguments);
        }
        initialize(x, y, width, height) {
            super.initialize(x, y, width, height);
            this.refresh();
        }
        refresh() {
            this.contents.clear();
            this._texts = [
                "テキスト テキスト テキスト",
                "テキスト テキスト",
                "テキスト テキスト",
                " ",
                "テキスト テキスト テキスト",
                "テキスト テキスト",
                "テキスト テキスト テキスト",
                "テキスト",
            ];
            this._texts.forEach((text, i) => {
                const x = 0;
                const y = 0 +  i * this.lineHeight();
                this.drawText(text, x, y, this.contents.width, 'left');
            });
        }
    }

    const _Scene_Map_createAllWindows = Scene_Map.prototype.createAllWindows;
    Scene_Map.prototype.createAllWindows = function() {
        _Scene_Map_createAllWindows.apply(this, arguments);
        this.createTestWindow();
    };

    Scene_Map.prototype.createTestWindow = function() {
        this._testWindow = new Window_Test(0, 0, Graphics.boxWidth / 2, Graphics.boxHeight);
        this.addChild(this._testWindow);
    };    

})();
・class Window_Test extends Window_Base
Rubyのclass Window_Test < Window_Baseと同じ。継承を意味します。

・constructor(){}
Rubyで言う所のdef initialize。オブジェクトの生成と共に呼び出される特殊なメソッド。
後述のinitializeはただのメソッドでWindow_Baseのconstructor内で呼び出しているだけなので混同に注意。
親クラスのコンストラクタを呼び出す場合はsuper()で呼び出す。
...argumentsとは与えられた引数をそのまま引き渡す、という意味です。

・super.initialize(x, y, width, height);
親クラス(Window_Base)のinitializeを使うという意味。
コンストラクタやRubyのsuperとは違って逐一、メソッドまで指定する必要があります。

・ const _Scene_Map_createAllWindows = Scene_Map.prototype.createAllWindows;
Rubyのaliasと同じ。既存の処理を退避しています。

・_Scene_Map_createAllWindows.apply(this, arguments);
退避させたメソッドの使用。callとapplyの二種類がありますが
.apply(this, arguments);と書いておけば引数に関係無く元メソッドに処理を渡す事が出来ます。

・new Window_Test(0, 0, Graphics.boxWidth / 2, Graphics.boxHeight);
オブジェクトの作成。Rubyでいうところの.newから変形しています。
ここでは適当にWindowの幅高さに画面の横幅の半分と画面の縦幅を指定しています。

・this.addChild(this._testWindow);
Scene_Mapオブジェクトに作成したWindow_Testオブジェクトを関連付けます。
ここで初めてWindowは有効化されます。
アバター
蓮賀まさとき
記事: 26
登録日時: 2020年8月30日(日) 15:00

Re: 「MV」のウィンドウ内に、JavaScriptで長文を表示するための記述の仕方を教えていただきたく・・・

投稿記事 by 蓮賀まさとき »

名無し蛙様

今回も細やかな解説から注意点までご教授くださって、ありがとうございます!
(私はまだまだレベルが低く、中々にハードルは高いですが ^^;)

さて、エラーの件ですが、原因が判明いたしました!

 条件分岐の、初期状態の条件に対応する記述が抜けていたため、
 行数である “ i ” の値が取得できなかった。
 (今回のケースでは、変数 n番 が 0 の時の処理)

・・・が、真相です。ん~、やっぱり私の凡ミスでした。
テスト用のプラグインまでご提示いただいたのに、大変申し訳ありません(汗)。
名無し蛙 さんが書きました:・this.addChild(this._testWindow);
Scene_Mapオブジェクトに作成したWindow_Testオブジェクトを関連付けます。
ここで初めてWindowは有効化されます。
そう言えば、この this.addChild は Background に必ず書かれていますね。
これでまず土台を有効化して、その上に各ウィンドウ( this.addWindow )を
配置、有効にしていく・・・みたいな仕組みなのでしょうかね。

記述方法のみならず、色々と解説していただき大変勉強になりました。
名無し蛙様、ありがとうございました!

それでは、これにて一件落着! 本件は【解決済み】といたします。
・ツクールは、「触ってる歴」だけはムダに長いです(^^;
・スクリプトは「XP」で興味を持ち、「VX」「MV」でもレイアウトを変更したり、
 画像やテキスト、新たなウィンドウを追加するなど、デフォルトの簡単な応用で
 カスタマイズを楽しんでいます。
返信する

“MV:質問”に戻る