brainwashing-school/js/plugins/TalkSystem.js
2025-05-30 08:36:40 -05:00

1082 lines
38 KiB
JavaScript

//==============================================================================
// TalkSystem.js ver.0.15
//==============================================================================
/*:
* @plugindesc 会話システム
* @author 奏ねこま(おとぶきねこま)
* @url http://makonet.sakura.ne.jp/rpg_tkool
* @target MZ
*
* @param switches
* @text スイッチ
* @desc スイッチ
*
* @param talk mode switch id
* @text 会話モードスイッチ
* @type number
* @default 101
* @desc 会話モードのON/OFFを切り替えるスイッチの番号
* @parent switches
*
* @param center mode switch id
* @text 立ち絵中央モードスイッチ
* @type number
* @default 102
* @desc 立ち絵中央モードのON/OFFを切り替えるスイッチの番号
* @parent switches
*
* @param hide name switch id
* @text 名前非表示モードスイッチ
* @type number
* @default 103
* @desc 名前非表示モードのON/OFFを切り替えるスイッチの番号
* @parent switches
*
* @param monologue mode switch id
* @text 独白モードスイッチ
* @type number
* @default 104
* @desc 独白モードのON/OFFを切り替えるスイッチの番号
* @parent switches
*
* @param variables
* @text 変数
* @desc 変数
*
* @param dress up variable base id
* @text 着せ替え変数起点番号
* @type number
* @default 105
* @desc 着せ替え判定用変数番号の起点番号
* @parent variables
*
* @param points
* @text 座標
* @desc 座標
*
* @param left picture point
* @text 左側立ち絵座標
* @type struct<Point>
* @default {"x":"300","y":"752"}
* @desc 左側に表示する立ち絵の原点座標(下端中央)
* @parent points
*
* @param right picture point
* @text 右側立ち絵座標
* @type struct<Point>
* @default {"x":"900","y":"752"}
* @desc 右側に表示する立ち絵の原点座標(下端中央)
* @parent points
*
* @param name column point
* @text 名前欄座標
* @type struct<Point>
* @default {"x":"420","y":"530"}
* @desc 名前欄の原点座標(中心)
* @parent points
*
* @param name display point
* @text 名前表示座標
* @type struct<Point>
* @default {"x":"320","y":"497"}
* @desc 名前を表示する位置(左上座標)
* @parent points
*
* @param balloon picture point
* @text フキダシ座標
* @type struct<Point>
* @default {"x":"600","y":"626"}
* @desc フキダシの原点座標(中心)
* @parent points
*
* @param message display point
* @text 会話本文表示座標
* @type struct<Point>
* @default {"x":"320","y":"568"}
* @desc 会話本文を表示する位置(左上座標)
* @parent points
*
* @param pause sign point
* @text ポーズサイン表示座標
* @type struct<Point>
* @default {"x":"276","y":"148"}
* @desc ポーズサインを表示する位置
* (下端中央:会話本文表示座標基準)
* @parent points
*
* @command ERASE_TALK_SPRITE
* @text 立ち絵消去
* @desc 立ち絵を消去します。
*
* @arg target
* @text 消去対象
* @type select
* @option 左
* @value 0
* @option 右
* @value 1
* @option 両方
* @value 2
* @default 0
* @desc 消去する立ち絵を指定してください。
*
* @arg opacity
* @text 不透明度
* @type number
* @min 0
* @max 255
* @default 0
* @desc 立ち絵消去時に適用する不透明度を指定してください。
*
* @arg tone
* @text 色調
* @type number
* @min -255
* @max 255
* @default 0
* @desc 立ち絵消去時に適用する色調を指定してください。
*
* @arg duration
* @text フレーム数
* @type number
* @default 0
* @desc 立ち絵消去に掛かるフレーム数を指定してください。
*
* @param picture
* @text ピクチャ番号
* @desc ピクチャ番号
*
* @param left picture display id
* @text 左側立ち絵表示位置
* @type number
* @default 5
* @desc 指定したピクチャ番号の上に左側立ち絵を表示します。
* @parent picture
*
* @param right picture display id
* @text 右側立ち絵表示位置
* @type number
* @default 10
* @desc 指定したピクチャ番号の上に右側立ち絵を表示します。
* @parent picture
*
* @help
* 2023年03月16日
* ダミー画像差し替えロジック改善
*
* 2022年09月15日
* $gameTemp生成前の画像読み込みエラー対策
*
* 2022年08月21日
* メッセージスキップをすると立ち絵が重複する問題を修正
*
* 2022年08月03日
* 文章表示開始時にウインドウが閉じてしまうことがある問題を修正
* 顔画像の指定がない場合はダミーの顔画像名を設定するように対応
*
* 2022年07月07日
* ②-4 立ち絵の表示位置を設定する機能
* ②-5 独白モード仕様変更
*
* 2022年07月07日
* ②-1 立ち絵をピクチャより下に表示する対応
* ②-2 フキダシ画像がない場合の対応
* ②-3 独白モード不具合対応
*
* 2022年04月24日
* コンティニューするとエラーになる問題を修正
*
* 2022年04月23日
* ①-14 メッセージスキップ機能
*
* 2022年04月23日
* ①-13 ウインドウ非表示機能
* ポーズサインの座標指定を追加
* 会話本文表示座標のY座標が効かない問題を修正
* フキダシ展開時に直前のフキダシ画像がチラつくことがある問題を修正
*
* 2022年04月23日
* ①-11 独白モード
* 名前欄とフキダシの開閉演出実装
*
* 2022年04月22日
* ①-8 フキダシ表示機能
* ①-9 名前を表示する機能
* ※上記いずれも開閉演出未対応
*
* 2022年04月21日
* ①-7 立ち絵中央表示機能
* ①-5 立ち絵クロスフェード機能
* 立ち絵消去コマンドの消去対象に「両方」を追加
*
* 2022年04月20日
* ①-4 立ち絵を消す機能
* ①-6 立ち絵の色調変更機能
*
* 2022年04月18日
* ①-2 一行目を話者名とする機能
* ①-10 名前非表示機能
* ①-12 着せ替え機能
*
* 2022年04月16日
* ①-1 立ち絵を表示する機能
* ①-3 立ち絵の位置を指定する機能
*
* ----------------------------------------------------------------------------
* 本プラグインの利用はRPGツクール/RPG Makerの正規ユーザーに限られます。
* 商用、非商用、有償、無償、一般向け、成人向けを問わず利用可能です。
* ご利用の際に連絡や報告は必要ありません。また、製作者名の記載等も不要です。
* プラグインを導入した作品に同梱する形以外での再配布、転載はご遠慮ください。
* 本プラグインにより生じたいかなる問題についても一切の責任を負いかねます。
* ----------------------------------------------------------------------------
* Copylight (c) 2022 Nekoma Otobuki
* http://makonet.sakura.ne.jp/rpg_tkool/
* https://twitter.com/koma_neko
*/
/*~struct~Point:
* @param x
* @text X座標
* @type number
* @default 0
* @desc X座標
*
* @param y
* @text Y座標
* @type number
* @default 0
* @desc Y座標
*/
var $gameTalk = null;
!function() {
'use strict';
function parse(param) {
try {
param = JSON.parse(param);
} catch (e) {
}
if (Array.isArray(param)) {
param = param.map(value => parse(value));
} else if (typeof param == 'object') {
for (let key in param) {
param[key] = parse(param[key]);
}
}
return param;
}
let $p = parse({
...PluginManager.parameters('TalkSystem')
});
//==============================================================================
// Common Function
//==============================================================================
function easing(start, end, duration) {
let amount = end - start;
let list = [];
for (let i = 0; i < duration; i++) {
let v = (i + 1) / duration;
let e = 0.5 - 0.5 * Math.cos(v * Math.PI);
list.push(start + Math.floor(amount * e));
}
return list;
}
//==============================================================================
// Plugin Command
//==============================================================================
PluginManager.registerCommand('TalkSystem', 'ERASE_TALK_SPRITE', args => {
$gameTalk.eraseTalker(parse(args));
});
//==============================================================================
// Input
//==============================================================================
Input.keyMapper[65] = 'A';
(function() {
// NW.js環境でのみ動作させる
if (!Utils.isNwjs()) return;
// 元のタイトルを保持
const baseTitle = document.title;
// タイトルを更新する関数
const updateWindowTitle = function() {
if ($gameTalk && $gameTalk.isHideWindow) {
document.title = baseTitle + "(※会話ウィンドウ非表示中※Aキーで復帰※)";
} else {
document.title = baseTitle;
}
};
// Scene_Base の update 内で毎フレームタイトルを更新する
const _Scene_Base_update = Scene_Base.prototype.update;
Scene_Base.prototype.update = function() {
_Scene_Base_update.call(this);
updateWindowTitle();
};
})();
//==============================================================================
// DataManager
//==============================================================================
(__createGameObjects => {
DataManager.createGameObjects = function() {
__createGameObjects.apply(this, arguments);
$gameTalk = new Game_Talk();
};
})(DataManager.createGameObjects);
(__makeSaveContents => {
DataManager.makeSaveContents = function() {
let contents = __makeSaveContents.apply(this, arguments);
contents.talk = $gameTalk;
return contents;
};
})(DataManager.makeSaveContents);
(__extractSaveContents => {
DataManager.extractSaveContents = function(contents) {
__extractSaveContents.apply(this, arguments);
$gameTalk = contents.talk || new Game_Talk();
};
})(DataManager.extractSaveContents);
//==============================================================================
// Bitmap
//==============================================================================
(___onError => {
Bitmap.prototype._onError = function() {
___onError.apply(this, arguments);
if ($gameTemp) {
for (let image in $gameTemp._defaultImage) {
if (this._url.includes(`/${image}.`)) {
this._url = this._url.replace(`/${image}.`, `/${$gameTemp._defaultImage[image]}.`);
this._startLoading();
}
}
}
};
})(Bitmap.prototype._onError);
//==============================================================================
// Scene_Message
//==============================================================================
(__createAllWindows => {
Scene_Message.prototype.createAllWindows = function() {
__createAllWindows.apply(this, arguments);
$gameTalk.backupPosition(this._messageWindow, this._nameBoxWindow);
};
})(Scene_Message.prototype.createAllWindows);
//==============================================================================
// Scene_Map
//==============================================================================
(__createSpriteset => {
Scene_Map.prototype.createSpriteset = function() {
__createSpriteset.apply(this, arguments);
let spriteset = new Spriteset_Talk();
spriteset.setupPosition(this._spriteset._pictureContainer);
this.addChild(spriteset);
};
})(Scene_Map.prototype.createSpriteset);
(__isFastForward => {
Scene_Map.prototype.isFastForward = function() {
let isFastForward = __isFastForward.apply(this, arguments);
return (
isFastForward ||
$gameMap.isEventRunning() &&
!SceneManager.isSceneChanging() &&
$gameTalk.isSkip
);
};
})(Scene_Map.prototype.isFastForward);
//==============================================================================
// Game_Temp
//==============================================================================
(__initialize => {
Game_Temp.prototype.initialize = function() {
__initialize.apply(this, arguments);
this._defaultImage = {};
};
})(Game_Temp.prototype.initialize);
//==============================================================================
// Game_Map
//==============================================================================
(__update => {
Game_Map.prototype.update = function() {
__update.apply(this, arguments);
$gameTalk.update();
};
})(Game_Map.prototype.update);
//==============================================================================
// Game_Interpreter
//==============================================================================
(__command101 => {
Game_Interpreter.prototype.command101 = function(params) {
let command101 = __command101.apply(this, arguments);
if (command101) {
$gameTalk.refresh();
}
return command101;
};
})(Game_Interpreter.prototype.command101);
//==============================================================================
// Window_Base
//==============================================================================
(__setBackgroundType => {
Window_Base.prototype.setBackgroundType = function(type) {
__setBackgroundType.apply(this, arguments);
if (this instanceof Window_NameBox || this instanceof Window_Message) {
if ($gameTalk.isTalkMode) {
this.opacity = 0;
}
}
};
})(Window_Base.prototype.setBackgroundType);
//==============================================================================
// Window_Message
//==============================================================================
(__startMessage => {
Window_Message.prototype.startMessage = function() {
if (!$gameTalk.isTalkMode) {
$gameTalk.restorePosition(this);
}
__startMessage.apply(this, arguments);
if ($gameTalk.isTalkMode) {
this.x = $p['message display point'].x;
this.y = $p['message display point'].y;
this._pauseSignSprite.x = $p['pause sign point'].x;
this._pauseSignSprite.y = $p['pause sign point'].y;
}
};
})(Window_Message.prototype.startMessage);
(__checkToNotClose => {
Window_Message.prototype.checkToNotClose = function() {
__checkToNotClose.apply(this, arguments);
if (this.isClosing() && !this.doesContinue()) {
$gameTalk.closeBalloon();
}
};
})(Window_Message.prototype.checkToNotClose);
(__isTriggered => {
Window_Message.prototype.isTriggered = function() {
return __isTriggered.apply(this, arguments) && !$gameTalk.isHideWindow || $gameTalk.isSkip;
};
})(Window_Message.prototype.isTriggered);
(__update => {
Window_Message.prototype.update = function() {
__update.apply(this, arguments);
this.visible = !$gameTalk.isHideWindow;
};
})(Window_Message.prototype.update);
(__startWait => {
Window_Message.prototype.startWait = function(count) {
__startWait.apply(this, arguments);
if ($gameTalk.isSkip) {
this._waitCount = 1;
}
};
})(Window_Message.prototype.startWait);
//==============================================================================
// Window_NameBox
//==============================================================================
(__start => {
Window_NameBox.prototype.start = function() {
if (!$gameTalk.isTalkMode) {
$gameTalk.restorePosition(this);
}
__start.apply(this, arguments);
if ($gameTalk.isTalkMode) {
this.x = $p['name display point'].x;
this.y = $p['name display point'].y;
}
};
})(Window_NameBox.prototype.start);
(__update => {
Window_NameBox.prototype.update = function() {
__update.apply(this, arguments);
this.visible = !$gameTalk.isHideWindow;
};
})(Window_NameBox.prototype.update);
//==============================================================================
// Game_Talk
//==============================================================================
class Game_Talk {
constructor() {
this._talker = [new Game_Talker(), new Game_Talker()];
this._balloonName = '';
this._nameBoxName = '';
this._defaultPosition = {
messageWindow: {},
nameBoxWindow: {},
pauseSignSprite: {}
};
this._isHideWindow = false;
}
get isTalkMode() { return $gameSwitches.value($p['talk mode switch id']); }
get isCenterMode() { return $gameSwitches.value($p['center mode switch id']); }
get isHideNameMode() { return $gameSwitches.value($p['hide name switch id']); }
get isMonologueMode() { return $gameSwitches.value($p['monologue mode switch id']); }
get leftPoint() { return {...$p['left picture point']}; }
get rightPoint() { return {...$p['right picture point']}; }
get leftDisplayPosition() { return $p['left picture display id']; }
get rightDisplayPosition() { return $p['right picture display id']; }
get leftTalker() { return this._talker[0]; }
get rightTalker() { return this._talker[1]; }
get balloonName() { return this._balloonName; }
get nameBoxName() { return this._nameBoxName; }
get isHideWindow() { return this._isHideWindow; }
get isSkip() { return !this._isHideWindow && Input.isPressed('control'); }
eraseTalker(param) {
let target = param.target == 0 ? 1 : param.target == 1 ? 2 : 3;
if (target & 0x01) {
this.leftTalker.erase(param);
}
if (target & 0x02) {
this.rightTalker.erase(param);
}
}
backupPosition(messageWindow, nameBoxWindow) {
this._defaultPosition.messageWindow.x = messageWindow.x;
this._defaultPosition.messageWindow.y = messageWindow.y;
this._defaultPosition.nameBoxWindow.x = nameBoxWindow.x;
this._defaultPosition.nameBoxWindow.y = nameBoxWindow.y;
this._defaultPosition.pauseSignSprite.x = messageWindow._pauseSignSprite.x;
this._defaultPosition.pauseSignSprite.y = messageWindow._pauseSignSprite.y;
}
restorePosition(window) {
if (window instanceof Window_Message) {
window.x = this._defaultPosition.messageWindow.x;
window.y = this._defaultPosition.messageWindow.y;
window._pauseSignSprite.x = this._defaultPosition.pauseSignSprite.x;
window._pauseSignSprite.y = this._defaultPosition.pauseSignSprite.y;
}
if (window instanceof Window_NameBox) {
window.x = this._defaultPosition.nameBoxWindow.x;
window.y = this._defaultPosition.nameBoxWindow.y;
}
}
closeBalloon() {
this._balloonName = '';
this._nameBoxName = '';
}
refresh() {
if (!this.isTalkMode) {
return;
}
let faceName = $gameMessage.faceName();
let faceIndex = $gameMessage.faceIndex();
let positionType = $gameMessage.positionType();
// 名前を設定
if ($gameMessage.hasText() && !this.isHideNameMode && !this.isMonologueMode) {
let name = $gameMessage._texts.shift();
$gameMessage.setSpeakerName(name);
}
// ウインドウ位置を下に固定
$gameMessage.setPositionType(2);
// 顔画像を非表示にする
$gameMessage.setFaceImage('');
this.refreshTalker(faceName, faceIndex, positionType);
this.refreshBalloon(faceName, positionType);
}
refreshTalker(faceName, faceIndex, positionType) {
let talker = positionType == 0 ? this._talker[1] : this._talker[0];
let opposite = positionType == 0 ? this._talker[0] : this._talker[1];
// 立ち絵(話者)
if (faceName != '') {
let picture = `${faceName}_${faceIndex + 1}`;
let point = positionType == 0 ? this.rightPoint : this.leftPoint;
if (this.isCenterMode && !opposite.visible) {
// 中央表示
point.x = Math.floor(Graphics.width / 2);
}
let dressUp = '';
let id = Number(faceName.match(/(?<=^\D+_\d+_)\d+/));
if (id > 0) {
// 着せ替え
let value = $gameVariables.value(id + $p['dress up variable base id'] - 1);
if (value > 0) {
dressUp = `${picture}_${value}`;
}
}
talker.setup(
picture,
point.x,
point.y,
dressUp,
0
);
}
// 立ち絵(反対側)
if (opposite.name) {
let point = positionType == 0 ? this.leftPoint : this.rightPoint;
opposite.setPosition(point.x, point.y, 15);
opposite.setTone(-96, 15);
}
}
refreshBalloon(faceName, positionType) {
if (!faceName) {
faceName = 'DummyFace_0_0';
}
if (!this.isMonologueMode) {
let ballonNumber = Number(faceName.replace(/.*_/, ''));
let ballonType = positionType == 0 ? 'R' : 'L';
this._balloonName = `fukidasi_${ballonNumber}_${ballonType}`;
} else {
this._balloonName = 'fukidasi_D';
}
this._nameBoxName = (this.isHideNameMode || this.isMonologueMode) ? '' : faceName.replace(/_.*/, '');
}
update() {
this.leftTalker.update();
this.rightTalker.update();
if (this._isHideWindow) {
// いま非表示中 ── A キー または 決定キー(Z/Enter/Space) で復帰
if (Input.isTriggered('A') || Input.isTriggered('ok')) {
this._isHideWindow = false;
}
} else {
// 表示中 ── A キーで非表示
if (Input.isTriggered('A')) {
this._isHideWindow = true;
}
}
}
}
window.Game_Talk = Game_Talk;
//==============================================================================
// Game_Talker
//==============================================================================
class Game_Talker {
constructor() {
this.init();
}
get name() { return this._name; }
get x() { return this._x; }
get y() { return this._y; }
get dressUp() { return this._dressUp; }
get opacity() { return this._opacity; }
get tone() { return this._tone; }
get visible() { return this._name && this._eraseCount == 0; }
init() {
this._name = '';
this._x = 0;
this._y = 0;
this._dressUp = '';
this._opacity = 255;
this._tone = 0;
this._easing = { x: [], y: [], opacity: [], tone: [] }
this._eraseCount = 0;
}
setup(name, x, y, dressUp = '', tone = 0) {
if (this._name) {
this._easing.x = easing(this._x, x, 15);
this._easing.y = easing(this._y, y, 15);
this._easing.opacity = easing(this._opacity, 255, 15);
this._easing.tone = easing(this._tone, tone, 15);
} else {
this._x = x;
this._y = y;
this._opacity = 255;
this._tone = tone;
}
this._name = name;
this._dressUp = dressUp;
}
setPosition(x, y, duration) {
if (duration > 0) {
this._easing.x = easing(this._x, x, duration);
this._easing.y = easing(this._y, y, duration);
} else {
this._x = x;
this._y = y;
this._easing.x = [];
this._easing.y = [];
}
}
setTone(tone, duration) {
if (duration > 0) {
this._easing.tone = easing(this._tone, tone, duration);
} else {
this._tone = tone;
this._easing.tone = [];
}
}
erase(param) {
this._easing.opacity = easing(this._opacity, param.opacity, param.duration);
this._easing.tone = easing(this._tone, param.tone, param.duration);
this._eraseCount = param.duration;
}
update() {
for (let key in this._easing) {
if (this._easing[key].length > 0) {
this[`_${key}`] = this._easing[key].shift();
}
}
if (this._eraseCount > 0) {
this._eraseCount--;
if (this._eraseCount == 0) {
this._name = '';
this._dressUp = '';
}
}
}
}
window.Game_Talker = Game_Talker;
//==============================================================================
// Spriteset_Talk
//==============================================================================
class Spriteset_Talk extends Sprite {
constructor() {
super();
this.createTalkerSprite();
this.createTalkBalloonSprite();
}
createTalkerSprite() {
this._leftSprite = new Sprite_Talker($gameTalk.leftTalker);
this._rightSprite = new Sprite_Talker($gameTalk.rightTalker);
this.addChild(this._leftSprite);
this.addChild(this._rightSprite);
}
createTalkBalloonSprite() {
this._balloonSprite = new Sprite_TalkBalloon();
this.addChild(this._balloonSprite);
}
setupPosition(pictureContainer) {
let leftPicture = null;
let rightPicture = null;
for (let sprite of pictureContainer.children) {
if (sprite._pictureId == $gameTalk.leftDisplayPosition) {
leftPicture = sprite;
}
if (sprite._pictureId == $gameTalk.rightDisplayPosition) {
rightPicture = sprite;
}
if (leftPicture && rightPicture) {
break;
}
}
if (leftPicture) {
leftPicture.addChild(this._leftSprite);
$gameScreen.showPicture(leftPicture._pictureId, '', 0, 0, 0, 100, 100, 255, 0);
}
if (rightPicture) {
rightPicture.addChild(this._rightSprite);
$gameScreen.showPicture(rightPicture._pictureId, '', 0, 0, 0, 100, 100, 255, 0);
}
}
}
//==============================================================================
// Sprite_Talk
//==============================================================================
class Sprite_Talker extends Sprite {
constructor(talker) {
super();
this._talker = talker;
this.init();
this.setup();
}
init() {
this._name = '';
this._x = 0;
this._y = 0;
this._dressUp = '';
this._opacity = 255;
this._tone = 0;
this._displaySprite = null;
this._disappearSprite = null;
this._displayOpacity = null;
this.filters = [
new PIXI.filters.ColorMatrixFilter(),
new ColorFilter()
];
this.filters[1].setColorTone([0, 0, 0, 0]);
this.removeChildren();
}
setup() {
let sprite = new Sprite();
sprite.anchor.x = 0.5;
sprite.anchor.y = 1.0;
sprite.filters = [new PIXI.filters.ColorMatrixFilter()];
this.addChild(sprite);
this._displaySprite = sprite;
}
update() {
this.updateTalker();
this.updatePosition();
this.updateOpacity();
this.updateTone();
super.update();
}
updateTalker() {
let bodyBitmap = null;
let dressBitmap = null;
let isFade = false;
// 本体
if (this._name != this._talker.name) {
if (this._talker.name) {
bodyBitmap = ImageManager.loadPicture(this._talker.name);
if (this._name.indexOf(this._talker.name.replace(/_.*/, '')) != 0) {
if (this._disappearSprite) {
this.removeChild(this._disappearSprite);
}
this._disappearSprite = this._displaySprite;
this._disappearSprite.filters = [new PIXI.filters.ColorMatrixFilter()];
this.addChild(this._disappearSprite);
this.setup();
isFade = true;
}
} else {
this._displaySprite.bitmap = null;
}
this._name = this._talker.name;
}
// 着せ替え
if (this._dressUp != this._talker.dressUp) {
this._dressUp = this._talker.dressUp;
if (this._dressUp) {
dressBitmap = ImageManager.loadPicture(this._dressUp);
} else {
this._displaySprite.removeChildren();
}
}
// 本体と着せ替えの更新の同期
let listener = function (sprite) {
if (bodyBitmap && !bodyBitmap.width) {
bodyBitmap.addLoadListener(listener);
return;
}
if (dressBitmap && !dressBitmap.width) {
dressBitmap.addLoadListener(listener);
return;
}
if (bodyBitmap) {
sprite.bitmap = bodyBitmap;
if (isFade) {
sprite.filters = [new PIXI.filters.ColorMatrixFilter()];
sprite.filters[0].matrix[18] = 0;
this._displayOpacity = easing(0, 255, 15);
}
}
if (dressBitmap) {
let child = new Sprite();
child.anchor.x = 0.5;
child.anchor.y = 1.0;
child.bitmap = dressBitmap;
sprite.removeChildren();
sprite.addChild(child);
}
}.bind(this, this._displaySprite);
listener();
}
updatePosition() {
this.x = this._talker.x;
this.y = this._talker.y;
}
updateOpacity() {
if (this._talker.opacity != this._opacity) {
this._opacity = this._talker.opacity;
this.filters[0].matrix[18] = this._opacity / 255;
}
if (this._displayOpacity) {
let alpha = this._displayOpacity.shift() / 255;
this._displaySprite.filters[0].matrix[18] = alpha;
if (this._disappearSprite) {
this._disappearSprite.filters[0].matrix[18] = 1 - alpha;
}
if (this._displayOpacity.length == 0) {
this.removeChild(this._disappearSprite);
this._displaySprite.filters = null;
this._disappearSprite = null;
this._displayOpacity = null;
}
}
}
updateTone() {
if (this._talker.tone != this._tone) {
this._tone = this._talker.tone;
this.filters[1].setColorTone([...Array(3).fill(this._tone), 0]);
}
}
}
//==============================================================================
// Sprite_TalkBalloon
//==============================================================================
class Sprite_TalkBalloon extends Sprite {
constructor() {
super();
this.init();
this.setup();
}
init() {
this._balloonName = '';
this._nameBoxName = '';
this._balloonSprite = null;
this._nameBoxSprite = null;
this._easing = { scale: [] };
this.removeChildren();
}
setup() {
// フキダシ画像
this._balloonSprite = new Sprite();
this._balloonSprite.x = $p['balloon picture point'].x;
this._balloonSprite.y = $p['balloon picture point'].y;
this._balloonSprite.anchor.x = 0.5;
this._balloonSprite.anchor.y = 0.5;
this._balloonSprite.scale.y = 0;
this.addChild(this._balloonSprite);
// 名前欄画像
this._nameBoxSprite = new Sprite();
this._nameBoxSprite.x = $p['name column point'].x;
this._nameBoxSprite.y = $p['name column point'].y;
this._nameBoxSprite.anchor.x = 0.5;
this._nameBoxSprite.anchor.y = 0.5;
this.addChild(this._nameBoxSprite);
}
update() {
this.updateBitmap();
this.updateScale();
this.updateVisible();
super.update();
}
updateBitmap() {
let balloonBitmap = null;
let nameBoxBitmap = null;
if ($gameTalk.balloonName != this._balloonName) {
this._balloonName = $gameTalk.balloonName;
if (this._balloonName) {
$gameTemp._defaultImage[this._balloonName] = this._balloonName.replace(/\d+/, '0');
balloonBitmap = ImageManager.loadSystem(this._balloonName);
}
}
if ($gameTalk.nameBoxName != this._nameBoxName) {
this._nameBoxName = $gameTalk.nameBoxName;
if (this._nameBoxName) {
$gameTemp._defaultImage[this._nameBoxName] = 'name';
nameBoxBitmap = ImageManager.loadSystem(this._nameBoxName);
} else {
this._nameBoxSprite.bitmap = null;
}
}
// 名前欄とフキダシの更新の同期
let listener = function() {
if (balloonBitmap && !balloonBitmap.width) {
balloonBitmap.addLoadListener(listener);
return;
}
if (nameBoxBitmap && !nameBoxBitmap.width) {
nameBoxBitmap.addLoadListener(listener);
return;
}
if (balloonBitmap) {
this._balloonSprite.bitmap = balloonBitmap;
}
if (nameBoxBitmap) {
this._nameBoxSprite.bitmap = nameBoxBitmap;
}
}.bind(this);
listener();
}
updateScale() {
if (this._balloonName && this._balloonSprite.scale.y == 0) {
this._easing.scale = easing(0, 100, 8);
}
if (!this._balloonName && this._balloonSprite.scale.y == 1) {
this._easing.scale = easing(100, 0, 8);
}
if (this._easing.scale.length > 0) {
let scale = this._easing.scale.shift() / 100;
this._balloonSprite.scale.y = scale;
if (scale == 0) {
this._balloonSprite.bitmap = null;
}
}
this._nameBoxSprite.visible = (this._balloonSprite.scale.y == 1);
}
updateVisible() {
this._balloonSprite.visible = !$gameTalk.isHideWindow;
this._nameBoxSprite.visible = !$gameTalk.isHideWindow;
}
}
}();