どうもこんにちは
軽く内容を検めましたけど酷いコードですね。該当のコアスクリプトの方です
コード: 全て選択
const lastFontSize = this.contents.fontSize;
const textHeight = this.maxFontSizeInLine(lines[0]) + lineSpacing;
this.contents.fontSize = lastFontSize;
this.maxFontSizeInLine内で破壊的な変更を加えて呼び出し元の方で元に戻すって
修正したいところですけど今回はここは本題ではなさそうです
まず修正作業をする前に一つ、
Window_Base.prototype.maxFontSizeInLineの厄介な仕様について
このメソッドは
与えられた文字列の中でもっとも大きな文字サイズを調べて返す事を目的にしています
ではもしもdrawTextExメソッドに
"\\FS[24]あ\n\\FS[48]い\n\\FS[32]う\n\\FS[18]え\n\\FS[26]お\n"
という文字列を与えた場合、maxFontSizeInLineはそれぞれどのような数値を返却するか?
ユーザーが期待する答えは「24」「48」「32」「18」「26」です。
でも実際には「26」「48」「48」「32」「26」が返ってきます。
一体何故なのか?
これは最大値を決定する上での基準値に最後に設定された文字サイズを適用している為です。
1行目は最初はデータベースで設定した文字サイズ(26)と24を比較して26が最大値、
2行目はこの時点での文字サイズ(24)と新たに設定された48を比較して48が最大値、
3行目はこの時点での文字サイズ(48)と新たに設定された32を比較して48が最大値、
同様に4行目は32、5行目は26です。
つまりこのメソッドには
一文字も描画していない文字サイズの残骸が判定に影響を与えるという欠陥があります。
ではこれはバグなのか、というと一概にそう言い切る事も出来ず
改行を2回押して三行目から描画し始める、等のテクニックに使えるので完全に直す訳にもいかないです。
何にせよこのメソッドを適切な値を返すように直さないと話は始まりません。
基準値を0にして最終最大値が0の場合は最後の文字サイズを返す、くらいが無難な修正だと思いますね。
コード: 全て選択
Window_Base.prototype.maxFontSizeInLine = function(line) {
const lastFontSize = this.contents.fontSize;
let maxFontSize = 0;
const regExp = /\x1b({|}|FS)(\[(\d+)])?/gi;
for (;;) {
const array = regExp.exec(line);
if (!array) {
break;
}
const code = String(array[1]).toUpperCase();
if (code === "{") {
this.makeFontBigger();
} else if (code === "}") {
this.makeFontSmaller();
} else if (code === "FS") {
this.contents.fontSize = parseInt(array[3]);
}
if (this.contents.fontSize > maxFontSize) {
maxFontSize = this.contents.fontSize;
}
}
return maxFontSize || lastFontSize;
};
厳密に言えばこれも
"ああ\\FS[14]いい"と言ったテキストには対応出来ませんけど、
それでも使用に気を付ければ差し支えない範囲です。
想定しうる全てのケースに対応するのは面倒なので今回はこの仕様で妥協します。
閑話休題。本題の方は簡単で
コード: 全て選択
const lineSpacing = this.lineHeight() - $gameSystem.mainFontSize();
これを弄るだけで良いです。
詳細は割愛しますけど文字列の最大フォントサイズの大きさに合わせて
次の余白を変動させるとしたらこんな感じですか。
コード: 全て選択
Window_Base.prototype.calcTextHeight = function(textState) {
const lastFontSize = this.contents.fontSize;
const lines = textState.text.slice(textState.index).split("\n");
const fontHeight = this.maxFontSizeInLine(lines[0]);
this.contents.fontSize = lastFontSize;
let lineSpacing = this.lineHeight() - $gameSystem.mainFontSize();
lineSpacing *= fontHeight / $gameSystem.mainFontSize();
return fontHeight + Math.floor(lineSpacing);
};
追記:意図を読み違えていた部分が有ったので修正しました