投稿記事

無料プランの記事 (61)

羽根珈琲 2024/07/12 07:00

羽根珈琲 2024/07/11 02:28

制作ノート:2.5h,(【drawTextEx() で制御文字が使えない】)_202407011

drawTextEx() で制御文字が使えない

結論:javascript 内で制御文字を使うには、バックスラッシュが2個必要。
\V[1]\\V[1]

マップ画面に任意のテキストを表示

これは前々回とかで解決した。
ただ、時間を表示しただけで日付を表示してなかったな、と思って処理を追加。
……したらハマった。

日付なのでフォントサイズ大きくしたい。
なのでdrawText()じゃなくてdrawTextEx()を使う。
Exは制御文字が使えるので、"\{XXX\}" とか打てば大文字になるはず…なのだが制御がきかない。

なんで!?
と思って非公式リファレンス読んでmakeFontBigger()を試したり、あーだこーだガチャガチャ2時間くらいやったんだけれどもうまくいかない(text.replace がどうたらでエラー)。

なんなの~?
自作したWindow_Baseはテキスト制御できないのかな?
そんなことある?

インターネットを歩いて情報がないか探したら、こんな記述があった。(【解決済み】初歩的な質問ですみません[制御文字について])

ただし、jsファイル内に直接記述する場合には、 \\i[40] のように \(バックスラッシュ) を2重で記述する必要があります。

そうなんだ。
"\{XXX\}" じゃなくて"\\{XXX\\}" を試したら期待通り動いた。

しょ~もな!

羽根珈琲 2024/07/10 23:57

羽根珈琲 2024/07/10 05:17

制作ノート:2h,(マップ上に任意のテキストを表示する)_20240709

復習

マップ上にテキストを表示させるのは難しかったので、
代わりに前回は、メニュー画面にテキストを表示させた。

Scene_Menu.prototype.create = function() {
	Scene_MenuBase.prototype.create.call(this);
    
	this.任意の関数();

	this.createCommandWindow();
	this.createStatusWindow();
};

Scene_Menu.prototype.任意の関数 = function() {
	rect = new Rectangle(100,400,200,250);
	this._mystatus = new Window_Base(rect);
	this._mystatus.drawText("aaaaaa", 10,0,100, "right");
	this.addChild(this._mystatus);
}

これだね。
メニュー画面は開くときにScene_Menu.prototype.create()が呼び出される。
これを編集して、任意関数を呼び出した。
その任意関数内でWindow_BaseaddChild()して、テキストを表示するようにした。

じゃあ~マップはどうなってるんだっけ?

マップ画面の起動のために呼び出される関数から、テキストを表示する関数を呼び出す

メニューは Scene_Menu なので、 マップは Scene_Map 周りに正解があるはず。
メニューと同じように、Scene_Map.prototype.create() をいじってみよう。

そういえばメニュー画面はメニュー画面でプラグインをまとめていた。
せっかくなので練習がてら、マップ用のプラグインを新しく作成する。

ほぼコピペで、MenuをMapに置き換えた。
プラグインを読み込んでONにする。
でもテキストは表示されない。

動いてないのかな?と思って、動作確認用のサンプルコードを投入。
サンプルコードの動作が確認できたので、、プラグインは正常に読み込まれて動いている。

う~ん?
やっぱりテキストの表示の部分に問題があるっぽい。
もしくは、正常に動いているけど、表示が重なっていて見えない…とか?

ソースコードを眺めてたら、
Scene_Map.prototype.onMapLoaded() の中に this.createDisplayObjects();を発見。
Scene_Map.prototype.create()をやめて、createDisplayObjects() からテキスト表示できないか試してみたらあっさりできた。

呼び出しのタイミングの問題だったっぽい。

暫定で位置を調整して、テキスト更新用の関数を用意する。

表示したテキストの更新

さて、
この更新用の関数って、よそからどうやって呼び出すのかな?
javascript の知識が不足しているので苦戦。
雑魚だから、グローバル関数に手を出した。

グローバル関数のおかげで、外からテキストを更新できるようになった。
でも、元あったテキストが消えずにその上から新しくテキストが描画されるようになっちゃった。

元のテキストには消えてほしいんだけど!

試行錯誤の末、コンテンツ領域を削除して、再度作成することでなんとかなった。

destroyContents();
createContents();

これ大丈夫なのかなあ…見た目的には消えたけど、内部でちゃんと破棄されてるんだろうか…?
destroy って怖い単語使ってるけど、こういう命名ってあんまり信用できないよな~(じゃあソースコード読みな)。

左下の時刻が、イベントに合わせて変動するようになった。

今回作成したプラグイン。

//=============================================================================
// RPG Maker MZ - Original Map Screen
//=============================================================================

/*:ja
 * @target MZ
 * @plugindesc マップ画面を編集します。ウィンドウサイズ1280x720を想定
 * @author phether coffee
 *
 */

var myClock ; //時刻を変動させるタイミングで、本ファイルの Scene_Map.prototype.updateClock()を呼び出す。thisだと参照できない。

(() => {
    Scene_Map.prototype.createDisplayObjects = function() {
        this.createSpriteset();
        this.createWindowLayer();
        this.createAllWindows();
        this.createButtons();

        this.createClock(); //以下自作関数
        this.updateClock();
	};

    Scene_Map.prototype.createClock = function() {
        rect = new Rectangle(65,565,100,56);
        myClock = new Window_Base(rect);
        myClock.opacity = 0;//背景透過
        this.addChild(myClock);
    };

    Scene_Map.prototype.updateClock = function() {
        text = $gameVariables.value(14);
        myClock.destroyContents(); // テキストが重複するので、コンテンツ領域を一度削除する。
        myClock.createContents(); // 領域が消えて描画できなくなったので、再度コンテンツ領域を作成。
        myClock.drawText(text, 0,0,100);
    };
})();

ほかのファイル等から、Scene_Map.prototype.updateClock();を記述することで呼び出せる。(プラグインの場合、読み込み順が影響するかも)
時刻自体はここでは管理してないので、変数を参照してテキストを更新している。

羽根珈琲 2024/07/07 18:14

制作ノート:4h,(メニュー画面テキスト、状態異常ステート反映)_20240707

タスク

何をしないといけないんだっけ?
あとはシナリオガリガリやるだけ! とかメモしたのは覚えてる。
そう思って今ある分だけプレイしたら、結構足りてなかった。

とりあえず、現在時刻がわからないのが不便なのでこれを表示させる。
あと体力0(内部的には1)になったときのイベントが用意されてないので作る。

↑ わき道にそれたから今日は結局やってない。

マップ上の任意の位置に文字を表示する。(できなかった

任意の位置に文字を表示させるには、まずテキストを表示するWindowを用意してあげる必要があるっぽい。
このWindowSceneに依存するらしい(?)。
タイトル画面はシーン、タイトル画面にある「最初から」とかのボタンはウィンドウ(たぶん)。
メニュー画面もシーン、メニュー画面の「アイテム」とか「ステータス」とかのボタンを表示してるのがウィンドウ(たぶん)。

だとすると、キャラクターをマップ上で操作してるときのシーンに、ウィンドウを追加すればいいっぽい。
で、これってなんのシーンなわけ?
シーン一覧みてもよくわからん。

Scene_Message @MZ
	Scene_Battle (継承位置変更)
	Scene_Map (継承位置変更)

Scene_Mapかな…?

これめちゃむずい。意味わからん。

メニュー画面のステータス

こっちはScene_Menuがわかってるので、こっちのほうが簡単そう。
適当なプラグインの中で、Scene_Menu.prototype.create をオーバライドする。

Scene_Menu.prototype.create = function() {
    Scene_MenuBase.prototype.create.call(this);

	this.任意の関数();
    
    this.createCommandWindow();
    this.createStatusWindow();
};

Scene_Menu.prototype.任意の関数 = function() {
    rect = new Rectangle(100,400,200,250);
    this._mystatus = new Window_Base(rect);
    this._mystatus.drawText("aaaaaa", 10,0,100, "right");
    this.addChild(this._mystatus);
}
 

これでとりあえず任意の文字列が表示できる。
ビジュアルをいい感じに調整するだけ。

調整版。

Scene_Menu.prototype.任意の関数 = function() {
    rx = 50;
    ry = 340;
    rw = 260;
    rh = 350;
    margin = 14;
    rop = 0; //背景と枠を透過。
    this._mystatusWwidth = 250;

    rect = new Rectangle(rx,ry,rw,rh);
    this._mystatus_1 = new Window_Base(rect);
    rect = new Rectangle(rx+rw+margin, ry, rw, rh);
    this._mystatus_2 = new Window_Base(rect);
    rect = new Rectangle(rx+rw+rw+margin+margin,ry,rw,rh);
    this._mystatus_3 = new Window_Base(rect);

    this._mystatus_1.opacity = rop;
    this._mystatus_2.opacity = rop;
    this._mystatus_3.opacity = rop;
    
    this.addChild(this._mystatus_1);
    this.addChild(this._mystatus_2);
    this.addChild(this._mystatus_3);
}

これを状態異常に応じて表示させる。

ステータス画面への状態異常反映

$gameActors.actor(1).isStateAffected(10) とかからステートの判定を持ってきて、
this._mystatus_1.drawTextEx(文字列, 0, 0, this._mystatusWwidth); に反映させるだけ。
数があるから適当にarrayにしてjoin("\n")する。

できた。
このぶんだとほかのメニュー画面も簡単かも。

マップ上にテキスト表示させるのはまだよくわからん。

1 2 3 4 5 6 7

限定特典から探す

記事のタグから探す

月別アーカイブ

記事を検索