烁灵 发表于 2024-10-5 20:14:59

【汉化】仿XP/VX模式屏幕渐变

原贴:RPGツクール2000/XPのトランジション【プラグイン】: あわや自己またもや三時 (seesaa.net)


复刻 XP/VX 模式的屏幕渐变图渐变效果。
附带渐变图素材网站:For You | ぽけっとの中のいたち (4you.bz)






另存为 Transition200X.js
// Transition200X.js Ver.2.0.0
// MIT License (C) 2024 あわやまたな
// http://opensource.org/licenses/mit-license.php

/*:
* @target MZ
* @plugindesc 增加类似 RPG Maker XP/VX 的屏幕渐变效果。
* 汉化 by 烁灵 更多脚本请访问 www.hknmtt.com
* @author あわやまたな (Awaya_Matana)
* @url https://awaya3ji.seesaa.net/article/499185153.html
* @help Ver.2.0.0
* 将渐变图像放置于 img/transitions 文件夹中。
* The color of "Transfer Player" is reflected when fade to white.
*
* 文件名开头为 ! 会反转渐变顺序。
* 文件名开头为 $ 会保持图像的宽高比。
*
* 本插件是 Shioinu 的 PD_Transition_MZ.js 的修改版本。
*
* -----------------------------------------------
* Copyright (c) 2020 PixelDOG
* Released under the MIT license
* https://opensource.org/licenses/mit-license.php
* -----------------------------------------------
*
* @command hideScreen
* @text 隐藏屏幕内容
* @desc 隐藏屏幕内容。
* 在 XP 模式下固定屏幕。
*
* @arg duration
* @text 持续时间
* @desc 指定帧数。
* 输入数字或从下拉框中选择。
* @default normal
* @type combo
* @option 立刻
* @value instant
* @option 快速
* @value faster
* @option 正常
* @value normal
* @option 缓慢
* @value slower
*
* @arg wait
* @text 等待
* @desc 等待渐变完成。
* @default true
* @type boolean
*
* @command showScreen
* @text 显示屏幕内容
* @desc 显示屏幕内容。
*
* @arg duration
* @text 持续时间
* @desc 指定帧数。
* 输入数字或从下拉框中选择。
* @default normal
* @type combo
* @option 立刻
* @value instant
* @option 快速
* @value faster
* @option 正常
* @value normal
* @option 缓慢
* @value slower
*
* @arg wait
* @text 等待
* @desc 等待渐变完成。
* @default true
* @type boolean
*
* @command changeImage
* @text 更改图像
* @desc 设置渐变图像。
*
* @arg type
* @text 类型
* @desc 选择渐变的类型。
* 在 XP 模式下使用(显示)设置。
*
* @option 插件指令(隐藏)
* @value Plugin Command (Hide)
* @option 插件指令(显示)
* @value Plugin Command (Show)
* @option 场所移动(隐藏)
* @value Transfer Player (Hide)
* @option 场所移动(显示)
* @value Transfer Player (Show)
* @option战斗开始(隐藏)
* @value Start Battle (Hide)
* @option 战斗开始(显示)
* @value Start Battle (Show)
* @option 战斗结束(隐藏)
* @value End Battle (Hide)
* @option 战斗结束(显示)
* @value End Battle (Show)
* @default Plugin Command (Hide)
*
* @arg name
* @text 图像
* @desc 指定文件名。
* 设置为(无)以使用标准淡入效果。
* @type file
* @default
* @dir img/transitions
*
* @command changeMode
* @text 更改模式
* @desc 在 2000 模式和 XP 模式之间切换。
*
* @arg type
* @text 类型
* @desc 选择渐变的类型。
* @type select
* @option 插件指令
* @value Plugin Command
* @option 场所移动
* @value Transfer Player
* @option 战斗开始
* @value Start Battle
* @option 战斗结束
* @value End Battle
* @default Plugin Command
*
* @arg mode
* @text 模式
* @desc 切换模式。
* @type select
* @option 2000
* @option XP
* @default 2000
*
* @command changeColor
* @text 更改颜色
* @desc 更改颜色。
*
* @arg type
* @text 类型
* @desc 选择渐变的类型。
* @type select
* @option 插件指令
* @value Plugin Command
* @option 场所移动
* @value Transfer Player
* @option 战斗开始
* @value Start Battle
* @option 战斗结束
* @value End Battle
* @default Plugin Command
*
* @arg color
* @text 颜色
* @desc 请使用逗号分隔输入 RGB。
* 如果未输入,则为黑色。
* @type string
* @default
*
* @command changeSmoothness
* @text 更改平滑度
* @desc 切换渐变的平滑度。
*
* @arg type
* @text 类型
* @desc 选择渐变的类型。
* @type select
* @option 插件指令
* @value Plugin Command
* @option 场所移动
* @value Transfer Player
* @option 战斗开始
* @value Start Battle
* @option 战斗结束
* @value End Battle
* @default Plugin Command
*
* @arg smoothness
* @text 平滑度
* @desc 平滑屏幕变化。
* 在 0-7 范围内指定。0 不平滑。
* @default 4.5
*
* @command clearTransition
* @text 清除渐变
* @desc 重置渐变设置为默认。
*
* @command waitForCompletion
* @text 等待完成
* @desc 等待渐变完成。
*
* @param pluginCommand
* @text 插件命令
* @desc 选择渐变的类型。
* 在 XP 模式下使用(显示)设置。
* @type struct<settings>
*
* @param transfer
* @text 场所移动
* @desc 选择渐变的类型。
* 在 XP 模式下使用(显示)设置。
* @type struct<settings>
*
* @param battleStart
* @text 战斗开始
* @desc 选择渐变的类型。
* 在 XP 模式下使用(显示)设置。
* @type struct<settings>
*
* @param battleEnd
* @text 战斗结束
* @desc 选择渐变的类型。
* 在 XP 模式下使用(显示)设置。
* @type struct<settings>
*
* @param instant
* @text 立即
* @desc 指定帧数。
* @type number
* @default 1
*
* @param faster
* @text 快速
* @desc 指定帧数。
* @type number
* @default 24
*
* @param normal
* @text 正常
* @desc 指定帧数。
* @type number
* @default 48
*
* @param slower
* @text 缓慢
* @desc 指定帧数。
* @type number
* @default 96
*
* @param encounterEffect
* @text 遭遇效果
* @desc 选择想要用于遭遇效果的制作工具名。
* @type select
* @option 2000
* @option XP
* @option VX
* @option VXAce
* @option Fes
* @option MZ
* @default MZ
*
* @param hideCharacters
* @text 隐藏角色
* @desc 在遭遇效果期间隐藏角色。
* @type select
* @option default
* @option true
* @option false
* @default default
*
* @param sceneTransition
* @text 场景过渡
* @desc 选择想要用于场景过渡的制作工具名。
* @type select
* @option 2000
* @option XP
* @option VX (VXAce)
* @value VX
* @option MZ
* @default MZ
*
* @param speedUpWindows
* @text 加速窗口
* @desc 加速打开和关闭窗口的速度。
* “默认”将匹配场景过渡规格。
* @type select
* @option default
* @option true
* @option false
* @default default
*
* @param gameoverBgm
* @text 失败游戏背景音乐
* @desc 2000 的再现功能(附加)
* @type struct<bgm>
*
*/

/*~struct~settings:
*
* @param name1
* @text 隐藏时渐变图像
* @desc 指定文件名。
* 设置为(无)以使用标准淡入效果。
* @type file
* @default
* @dir img/transitions
*
* @param name2
* @text 显示时渐变图像 / XP 模式时渐变图像
* @desc 指定文件名。
* 设置为(无)以使用标准淡入效果。
* @type file
* @default
* @dir img/transitions
*
* @param mode
* @text 模式
* @desc 切换模式。
* @type select
* @option 2000
* @option XP
* @default 2000
*
* @param color
* @text 颜色
* @desc 请使用逗号分隔输入 RGB。
* 如果未输入,则为黑色。
* @type string
* @default
*
* @param smoothness
* @text 平滑度
* @desc 平滑屏幕变化。
* 在 0-7 范围内指定。0 不平滑。
* @default 4.5

/*~struct~bgm:
*
* @param name
* @text 名称
* @desc
* @type file
* @default
* @dir audio/bgm
*
* @param volume
* @text 音量
* @desc
* @type number
* @default 90
* @min 0
*
* @param pitch
* @text 音调
* @desc
* @type number
* @default 100
* @min 0
*
* @param pan
* @text 声像(左右声道)
* @desc
* @type number
* @default 0
* @min -100
* @max 100
*/

/*:ja
* @target MZ
* @plugindesc 画像によるトランジション演出機能を追加します。
* @author あわやまたな (Awaya_Matana)
* @url https://awaya3ji.seesaa.net/article/499185153.html
* @help トランジション画像はimg/transitionsフォルダに配置してください。
* 「場所移動」の色はフェードを白にすると反映されます。
*
* ファイル名先頭に!があるとトランジションの順序を反転します。
* ファイル名先頭に$があると画像のアスペクト比を保持します。
*
* このプラグインはしおいぬ氏のPD_Transition_MZ.jsを改変したものです。
*
* -----------------------------------------------
* Copyright (c) 2020 PixelDOG
* Released under the MIT license
* https://opensource.org/licenses/mit-license.php
* -----------------------------------------------
*
* [更新履歴]
* 2023/04/30:Ver.1.0.0 公開。
* 2023/07/04:Ver.1.0.1 不具合修正。
* 2024/09/08:Ver.2.0.0 不具合修正。スムージング機能、エンカウントエフェクト、シーン遷移、プラグインコマンドを追加。
*
* @command hideScreen
* @text 画面の消去
* @desc 画面を消去します。
* XPモード時は画面を固定します。
*
* @arg duration
* @text 時間
* @desc フレーム数を指定します。
* 数値を入力するかコンボボックスから選択します。
* @default 普通
* @type combo
* @option 瞬時
* @option 速い
* @option 普通
* @option 遅い
*
* @arg wait
* @text 完了までウェイト
* @desc トランジョンが完了するまで待ちます。
* @default true
* @type boolean
*
* @command showScreen
* @text 画面の表示
* @desc 画面を表示します。
*
* @arg duration
* @text 時間
* @desc フレーム数を指定します。
* 数値を入力するかコンボボックスから選択します。
* @default 普通
* @type combo
* @option 瞬時
* @option 速い
* @option 普通
* @option 遅い
*
* @arg wait
* @text 完了までウェイト
* @desc トランジョンが完了するまで待ちます。
* @default true
* @type boolean
*
* @command changeImage
* @text 画像の変更
* @desc トランジションの画像を設定します。
*
* @arg type
* @text 種類
* @desc 画面切り替えの種類を選択します。
* XPモード時は表示の設定を使用します。
* @type select
*
* @option プラグインコマンド/消去
* @value Plugin Command (Hide)
* @option プラグインコマンド/表示
* @value Plugin Command (Show)
* @option 場所移動/消去
* @value Transfer Player (Hide)
* @option 場所移動/表示
* @value Transfer Player (Show)
* @option 戦闘開始/消去
* @value Start Battle (Hide)
* @option 戦闘開始/表示
* @value Start Battle (Show)
* @option 戦闘終了/消去
* @value End Battle (Hide)
* @option 戦闘終了/表示
* @value End Battle (Show)
* @default Plugin Command (Hide)
*
* @arg name
* @text 画像
* @desc ファイル名を指定します。
* (なし)にすると標準のフェードを行います。
* @type file
* @default
* @dir img/transitions
*
* @command changeMode
* @text モードの変更
* @desc 2000形式、XP形式を切り替えます。
*
* @arg type
* @text 種類
* @desc 画面切り替えの種類を選択します。
* @type select
* @option プラグインコマンド
* @value Plugin Command
* @option 場所移動
* @value Transfer Player
* @option 戦闘開始
* @value Start Battle
* @option 戦闘終了
* @value End Battle
* @default Plugin Command
*
* @arg mode
* @text モード
* @desc モードを切り替えます。
* @type select
* @option 2000
* @option XP
* @default 2000
*
* @command changeColor
* @text 色の変更
* @desc 色を変更します。
*
* @arg type
* @text 種類
* @desc 画面切り替えの種類を選択します。
* @type select
* @option プラグインコマンド
* @value Plugin Command
* @option 場所移動
* @value Transfer Player
* @option 戦闘開始
* @value Start Battle
* @option 戦闘終了
* @value End Battle
* @default Plugin Command
*
* @arg color
* @text 色
* @desc コンマ区切りでRGBを入力して下さい。
* 未入力で黒。
* @type string
* @default
*
* @command changeSmoothness
* @text 滑らかさの変更
* @desc 画面遷移の滑らかさを切り替えます。
*
* @arg type
* @text 種類
* @desc 画面切り替えの種類を選択します。
* @type select
* @option プラグインコマンド
* @value Plugin Command
* @option 場所移動
* @value Transfer Player
* @option 戦闘開始
* @value Start Battle
* @option 戦闘終了
* @value End Battle
* @default Plugin Command
*
* @arg smoothness
* @text 滑らかさ
* @desc 画面の変化を滑らかにします。
* 0-7の範囲で指定。0でスムージングなし。
* @default 4.5
*
* @command clearTransition
* @text トランジションの初期化
* @desc トランジションの設定をデフォルトに戻します。
*
* @command waitForCompletion
* @text 完了までウェイト
* @desc トランジションが完了するまで待ちます。
*
* @param pluginCommand
* @text プラグインコマンド
* @desc トランジションの設定をします。
* XPモード時は表示の設定を使用します。
* @type struct<settings>
*
* @param transfer
* @text 場所移動
* @desc トランジションの設定をします。
* XPモード時は表示の設定を使用します。
* @type struct<settings>
*
* @param battleStart
* @text 戦闘開始
* @desc トランジションの設定をします。
* XPモード時は表示の設定を使用します。
* @type struct<settings>
*
* @param battleEnd
* @text 戦闘終了
* @desc トランジションの設定をします。
* XPモード時は表示の設定を使用します。
* @type struct<settings>
*
* @param instant
* @text 瞬時
* @desc トランジションのフレーム数です。
* @type number
* @default 1
*
* @param faster
* @text 速い
* @desc トランジションのフレーム数です。
* @type number
* @default 24
*
* @param normal
* @text 普通
* @desc トランジションのフレーム数です。
* @type number
* @default 48
*
* @param slower
* @text 遅い
* @desc トランジションのフレーム数です。
* @type number
* @default 96
*
* @param encounterEffect
* @text エンカウントエフェクト
* @desc どのツクールに準拠したエンカウントエフェクトを行うか選択します。
* @type select
* @option 2000
* @option XP
* @option VX
* @option VXAce
* @option Fes
* @option MZ
* @default MZ
*
* @param hideCharacters
* @text キャラクターを隠す
* @desc エンカウントエフェクト中にキャラクターを隠します。
* @type select
* @option デフォルト
* @value default
* @option true
* @option false
* @default default
*
* @param sceneTransition
* @text シーン遷移
* @desc どのツクールに準拠したシーン遷移を行うか選択します。
* @type select
* @option 2000
* @option XP
* @option VX (VXAce)
* @value VX
* @option MZ
* @default MZ
*
* @param speedUpWindows
* @text ウィンドウ高速化
* @desc ウィンドウの開閉を高速化します。
* 「デフォルト」はシーン遷移の仕様に合わせます。
* @type select
* @option デフォルト
* @value default
* @option true
* @option false
* @default default
*
* @param gameoverBgm
* @text ゲームオーバーBGM
* @desc 2000の再現機能(おまけ)
* @type struct<bgm>
*
*/

/*~struct~settings:ja
*
* @param name1
* @text 消去時の画像
* @desc ファイル名を指定します。
* (なし)にすると標準のフェードを行います。
* @type file
* @default
* @dir img/transitions
*
* @param name2
* @text 表示時の画像/XPモードの画像
* @desc ファイル名を指定します。
* (なし)にすると標準のフェードを行います。
* @type file
* @default
* @dir img/transitions
*
* @param mode
* @text モード
* @desc モードを切り替えます。
* @type select
* @option 2000
* @option XP
* @default 2000
*
* @param color
* @text 色
* @desc コンマ区切りでRGBを入力して下さい。
* 未入力で黒。
* @type string
* @default
*
* @param smoothness
* @text 滑らかさ
* @desc 画面の変化を滑らかにします。
* 0-7の範囲で指定。0でスムージングなし。
* @default 4.5
*/

/*~struct~bgm:ja
*
* @param name
* @text 名前
* @desc
* @type file
* @default
* @dir audio/bgm
*
* @param volume
* @text 音量
* @desc
* @type number
* @default 90
* @min 0
*
* @param pitch
* @text ピッチ
* @desc
* @type number
* @default 100
* @min 0
*
* @param pan
* @text 位相
* @desc
* @type number
* @default 0
* @min -100
* @max 100
*/


(function(){
        'use strict';

        const pluginName = document.currentScript.src.match(/^.*\/(.*).js$/);
        const parameters = PluginManager.parameters(pluginName);

        const instant = Number(parameters["instant"]);
        const faster = Number(parameters["faster"]);
        const normal = Number(parameters["normal"]);
        const slower = Number(parameters["slower"]);
        const encounterEffect = parameters["encounterEffect"] || "MZ";
        const sceneTransition = parameters["sceneTransition"] || "MZ";
        let hideCharacters = parameters["hideCharacters"] || "default";
        let speedUpWindows = parameters["speedUpWindows"] || "default";
        if (hideCharacters === "default") {
                hideCharacters = encounterEffect === "MZ";
        } else {
                hideCharacters = hideCharacters === "true";
        }
        if (speedUpWindows === "default") {
                speedUpWindows = sceneTransition === "VX" || sceneTransition === "2000";
        } else {
                speedUpWindows = speedUpWindows === "true";
        }
        const gameoverBgm = JSON.parse(parameters.gameoverBgm || "{}");
        gameoverBgm.volume = parseInt(gameoverBgm.volume || 90);
        gameoverBgm.pitch = parseInt(gameoverBgm.pitch || 100);
        gameoverBgm.pan = parseInt(gameoverBgm.pan || 0);
        const defaultSettings = [];
        defaultSettings.push(JSON.parse(parameters["pluginCommand"] || "{}"));
        defaultSettings.push(JSON.parse(parameters["transfer"] || "{}"));
        defaultSettings.push(JSON.parse(parameters["battleStart"] || "{}"));
        defaultSettings.push(JSON.parse(parameters["battleEnd"] || "{}"));
        const transitionNames = [];
        const transitionXps = [];
        const transitionColors = [];
        const transitionSmooths = [];
        defaultSettings.forEach(params => {
                transitionNames.push(params.name1 || "");
                transitionNames.push(params.name2 || "");
                transitionXps.push(params.mode === "XP");
                const color = !!params.color && params.color.split(",").map(Number);
                transitionColors.push(color);
                transitionSmooths.push(Number(params.smoothness || 4.5));
        });

        const typeList = [
        "Plugin Command (Hide)",
        "Plugin Command (Show)",
        "Transfer Player (Hide)",
        "Transfer Player (Show)",
        "Start Battle (Hide)",
        "Start Battle (Show)",
        "End Battle (Hide)",
        "End Battle (Show)"
        ];

        const commandList = [
        {"code":112,"indent":0,"parameters":[]},
        {"code":357,"indent":1,"parameters":},
        {"code":0,"indent":1,"parameters":[]},
        {"code":413,"indent":0,"parameters":[]},
        {"code":0,"indent":0,"parameters":[]}
        ];

        function typeToIndex(type, dev = 1) {
                let index = 0;
                if (typeof type === "string") {
                        index = typeList.findIndex(str => str.startsWith(type));
                } else {
                        index = Number(type || 0);
                }
                if (index < 0) {
                        index = 0;
                }
                return Math.floor(index / dev);
        }

        function getDuration(duration) {
                switch (duration) {
                case "instant":
                case "瞬時":
                        return instant;
                case "faster":
                case "速い":
                        return faster;
                case "normal":
                case "普通":
                        return normal;
                case "slower":
                case "遅い":
                        return slower;
                }
                return Number(duration || 0);
        }

        //-----------------------------------------------------------------------------
        // SceneManager
        //スクショ
        SceneManager.snapForTransition = function() {
                if (this._transitionBitmap) {
                        this._transitionBitmap.destroy();
                }
                this._transitionBitmap = this.snap();
        };

        SceneManager.transitionBitmap = function() {
                return this._transitionBitmap;
        };

        if (sceneTransition === "VX") {
                const _SceneManager_goto = SceneManager.goto;
                SceneManager.goto = function(sceneClass) {
                        _SceneManager_goto.call(this, sceneClass);
                        if (this.isNextScene(Scene_Gameover)) {
                                this._nextScene.playGameoverMusic();
                        }
                };
        }

        //-----------------------------------------------------------------------------
        // PluginManager

        const _PluginManager = window.PluginManagerEx ?? PluginManager
        const script = window.PluginManagerEx ? document.currentScript : pluginName;
        _PluginManager.registerCommand(script, "hideScreen", function(args) {
                const type = "Plugin Command (Hide)";
                const xpMode = $gameSystem.transitionXp(type);
                const duration = getDuration(args.duration);
                SceneManager._scene.hideScreenWithPreset(duration, type);
                if (String(args.wait) === "true" && !xpMode) {
                        this.setupChild(commandList);
                }
        });

        _PluginManager.registerCommand(script, "showScreen", function(args) {
                const type = "Plugin Command (Show)";
                const duration = getDuration(args.duration);
                SceneManager._scene.showScreenWithPreset(duration, type);
                if (String(args.wait) === "true") {
                        this.setupChild(commandList);
                }
        });

        _PluginManager.registerCommand(script, "changeImage", function(args) {
                $gameSystem.setTransitionName(args.type, args.name);
        });

        _PluginManager.registerCommand(script, "changeMode", function(args) {
                $gameSystem.setTransitionXp(args.type, args.mode === "XP");
        });

        _PluginManager.registerCommand(script, "changeColor", function(args) {
                $gameSystem.setTransitionColor(args.type, args.color !== "" && String(args.color).split(",").map(Number));
        });

        _PluginManager.registerCommand(script, "changeSmoothness", function(args) {
                $gameSystem.setTransitionSmoothness(args.type, +args.smoothness);
        });

        PluginManager.registerCommand(pluginName, "clearTransition", function() {
                $gameSystem.clearTransitionData();
        });

        PluginManager.registerCommand(pluginName, "waitForCompletion", function() {
                this.setupChild(commandList);
        });

        PluginManager.registerCommand(pluginName, "updateWaitMode", function() {
                if (SceneManager._scene.isTransitioning()) {
                        this.wait(1);
                } else {
                        this.command113();
                }
        });

        //-----------------------------------------------------------------------------
        // Tilemap
        //エンカウントエフェクト時に画面を固めるためだけの関数
        if (!hideCharacters) {
                Tilemap.prototype.setFreeze = function(freeze) {
                        this._frozenMap = freeze;
                };

                const _Tilemap_update = Tilemap.prototype.update;
                Tilemap.prototype.update = function(freeze) {
                        if (!this._frozenMap) {
                                _Tilemap_update.call(this);
                        }
                };
        }

        //-----------------------------------------------------------------------------
        // Game_System
        //演出に使うトランジションデータ
        Game_System.prototype.clearTransitionData = function() {
                delete this._transitionNames;
                delete this._transitionXps;
                delete this._transitionColors;
                delete this._transitionSmooths;
        };

        Game_System.prototype.transitionData = function(type) {
                const data = {
                        name: this.transitionName(type),
                        xpMode: this.transitionXp(type),
                        color: this.transitionColor(type),
                        smoothness: this.transitionSmoothness(type)
                }
                return data;
        };

        Game_System.prototype.setTransitionName = function(type, fileName) {
                if (!this._transitionNames) {
                        this._transitionNames = [];
                }
                const index = typeToIndex(type);
                if (fileName != null) {
                        this._transitionNames = String(fileName);
                } else {
                        delete this._transitionNames;
                }
        };

        Game_System.prototype.transitionName = function(type) {
                const index = typeToIndex(type)
                const sysData = this._transitionNames && this._transitionNames;
                if (sysData != null) {
                        return sysData;
                }
                return transitionNames;
        };

        Game_System.prototype.setTransitionXp = function(type, bool) {
                if (!this._transitionXps) {
                        this._transitionXps = [];
                }
                const index = typeToIndex(type, 2);
                if (bool != null) {
                        this._transitionXps = bool;
                } else {
                        delete this._transitionXps;
                }
        };

        Game_System.prototype.transitionXp = function(type) {
                const index = typeToIndex(type, 2);
                const sysData = this._transitionXps && this._transitionXps;
                if (sysData != null) {
                        return sysData;
                }
                return transitionXps;
        };

        Game_System.prototype.setTransitionColor = function(type, color) {
                if (!this._transitionColors) {
                        this._transitionColors = [];
                }
                const index = typeToIndex(type, 2);
                if (color != null) {
                        this._transitionColors = typeof color === "boolean" ? color : color.clone();
                } else {
                        delete this._transitionColors;
                }
        };

        Game_System.prototype.transitionColor = function(type) {
                const index = typeToIndex(type, 2);
                let color = this._transitionColors && this._transitionColors;
                if (color == null) {
                        color = transitionColors;
                }
                return typeof color === "boolean" ? color : color.clone()
        };

        Game_System.prototype.setTransitionSmoothness = function(type, value) {
                if (!this._transitionSmooths) {
                        this._transitionSmooths = [];
                }
                const index = typeToIndex(type, 2);
                if (value != null) {
                        this._transitionSmooths = value;
                } else {
                        delete this._transitionSmooths;
                }
        };

        Game_System.prototype.transitionSmoothness = function(type) {
                const index = typeToIndex(type, 2);
                const sysData = this._transitionSmooths && this._transitionSmooths;
                if (sysData != null) {
                        return sysData;
                }
                return transitionSmooths;
        };

        //-----------------------------------------------------------------------------
        // Game_Temp
        //マップ移動時に色や状態を保存するための一時データ。
        //旧作と異なる方式で行う為必須。
        Game_Temp.prototype.clearMapTransition = function() {
                this._inMapTransition = false;
                this._mapTransitionColor = false;
                this._mapTransitionXp = false;
        };

        Game_Temp.prototype.setMapTransition = function(xpMode, color) {
                this._inMapTransition = true;
                this._mapTransitionColor = color;
                this._mapTransitionXp = xpMode;
        };

        Game_Temp.prototype.inMapTransition = function() {
                return !!this._inMapTransition;
        };

        Game_Temp.prototype.mapTransitionData = function() {
                const data = {
                        color: this._mapTransitionColor,
                        xpMode: !!this._mapTransitionXp
                }
                return data;
        };

        //-----------------------------------------------------------------------------
        // Scene_Base

        const _Scene_Base_initialize = Scene_Base.prototype.initialize;
        Scene_Base.prototype.initialize = function() {
                _Scene_Base_initialize.call(this);
                this._transitionSprite = null;
                this._transitionSign = 0;
                this._transitionDuration = 0;
                this._transitionUpdated = false;
        };
        //必要なら行う
        const _Scene_Base_start = Scene_Base.prototype.start;
        Scene_Base.prototype.start = function() {
                _Scene_Base_start.call(this);
                if (this.needsTransition(1)) {
                        this.performTransition();
                }
        };

        Scene_Base.prototype.performTransition = function() {
                this.executeTransition(this.transitionSpeed());//シーン変更直前のスクショを利用してフェード
        };

        if (sceneTransition === "2000") {
                const _Scene_Base_stop = Scene_Base.prototype.stop;
                Scene_Base.prototype.stop = function() {
                        _Scene_Base_stop.call(this);
                        if (this.needsTransition(-1) && !this.isFading()) {
                                this.startFadeOut(this.transitionSpeed());
                        }
                };
        }

        const _Scene_Base_terminate = Scene_Base.prototype.terminate;
        Scene_Base.prototype.terminate = function() {
                _Scene_Base_terminate.call(this);
                this.snapForTransition();
        };
        //シーン遷移が旧ツクール仕様なら利用
        Scene_Base.prototype.needsTransition = function() {
                return sceneTransition !== "MZ";
        };
        //トランジションを開始した直後なら時間を上書き(既存機能と互換性を保つため)
        const _Scene_Base_startFadeIn = Scene_Base.prototype.startFadeIn;
        Scene_Base.prototype.startFadeIn = function(duration, white) {
                if (this.isTransitioning() && this._transitionSign > 0 && !this._transitionUpdated) {
                        this._transitionDuration = duration || this._transitionDuration;
                        return;
                }
                _Scene_Base_startFadeIn.apply(this, arguments);
        };

        const _Scene_Base_startFadeOut = Scene_Base.prototype.startFadeOut;
        Scene_Base.prototype.startFadeOut = function(duration, white) {
                if (this.isTransitioning() && this._transitionSign < 0 && !this._transitionUpdated) {
                        this._transitionDuration = duration || this._transitionDuration;
                        return;
                }
                _Scene_Base_startFadeOut.apply(this, arguments);
        };
       
        Scene_Base.prototype.transitionSpeed = function() {
                return 12;
        };

        if (sceneTransition === "2000") {
                Scene_Base.prototype.transitionSpeed = function() {
                        return 5;
                };
        } else if (sceneTransition === "VX") {
                Scene_Base.prototype.transitionSpeed = function() {
                        return 10;
                };
        }

        const _Scene_Base_isFading = Scene_Base.prototype.isFading;
        Scene_Base.prototype.isFading = function() {
                return _Scene_Base_isFading.call(this) || this.isTransitioning();
        };

        Scene_Base.prototype.isTransitioning = function() {
                return this._transitionDuration > 0;
        };

        Scene_Base.prototype.rejectFade = function() {
                this._fadeSign = 0;
                this._fadeDuration = 0;
                this._fadeWhite = 0;
                this._fadeOpacity = 0;
                this.updateColorFilter();
        };

        Scene_Base.prototype.showScreenWithPreset = function(duration, type, color) {
                const data = $gameSystem.transitionData(type);
                data.color = color ?? data.color;
                this._transitionDuration = duration || (data.xpMode && !name ? 15 : 30);
                this.setupTransition(data, 1);
        };
        //2000:画面の表示
        Scene_Base.prototype.showScreen = function(duration, name, smoothness, pos, color) {
                const data = {
                        name: name,
                        xpMode: false,
                        pos: pos,
                        color: color,
                        smoothness: smoothness
                };
                this._transitionDuration = duration || 30;
                this.setupTransition(data, 1);
        };
        //XP:トランジション実行
        Scene_Base.prototype.executeTransition = function(duration, name, smoothness, pos) {
                const data = {
                        name: name,
                        xpMode: true,
                        pos: pos,
                        smoothness: smoothness
                };
                this._transitionDuration = duration || (name ? 30 : 15);
                this.setupTransition(data, 1);
        };

        Scene_Base.prototype.hideScreenWithPreset = function(duration, type, color) {
                const data = $gameSystem.transitionData(type);
                data.color = color ?? data.color;
                this._transitionDuration = duration || 30;
                this.setupTransition(data, -1);
        };
        //2000:画面の消去
        Scene_Base.prototype.hideScreen = function(duration, name, smoothness, pos, color) {
                const data = {
                        name: name,
                        xpMode: false,
                        pos: pos,
                        color: color,
                        smoothness: smoothness
                };
                this._transitionDuration = duration || 30;
                this.setupTransition(data, -1);
        };
        //XP:トランジション準備
        Scene_Base.prototype.prepareForTransition = function() {
                const data = {
                        xpMode: true
                };
                this.setupTransition(data, -1);
        };

        Scene_Base.prototype.snapForTransition = function() {
                SceneManager.snapForTransition();
        };

        Scene_Base.prototype.createTransitionSprite = function(data) {
                if (this._transitionSprite) {
                        this.removeTransitionSprite();
                }
                this._transitionSprite = new Sprite_Transition(data);
                this.addChild(this._transitionSprite);
        };

        Scene_Base.prototype.removeTransitionSprite = function() {
                if (this._transitionSprite) {
                        this._transitionSprite.destroy();
                        this._transitionSprite = null;
                }
        };

        const _Scene_Base_update = Scene_Base.prototype.update;
        Scene_Base.prototype.update = function() {
                this.updateTransition();
                _Scene_Base_update.call(this);
        };

        Scene_Base.prototype.setupTransition = function(data, sign) {
                this._transitionUpdated = false;
                if (sign < 0) {
                        if (data.xpMode) {
                                this.snapForTransition();
                                this._transitionDuration = 1;
                        }
                } else if (this._transitionSprite) {
                        data.color = data.color ?? this._transitionSprite.getBlendColor().slice(0, 3);
                }
                this._transitionSign = sign;
                this.createTransitionSprite(data);
                this._transitionSprite.setBitmap(sign);
                this._transitionSprite.opacity = sign < 0 ? 0 : 255;
        };

        Scene_Base.prototype.updateTransition = function() {
                if (this._transitionDuration > 0) {
                        this._transitionUpdated = true;
                        if (this._transitionSprite.durationMax() === 0){
                                const ready = this._transitionSprite.setDefault(this._transitionSign);
                                if(!ready){
                                        return;
                                }
                                this._transitionSprite.setDurationMax(this._transitionDuration);
                        }
                        this._transitionDuration--;
                        const d = this._transitionDuration;
                        const sign = this._transitionSign;
                        this._transitionSprite.updateBitmap(d, sign);
                        if (this._transitionDuration === 0 && sign > 0) {
                                this.removeTransitionSprite();
                        }
                }
        };
       
        Scene_Base.prototype.needsPresetTransition = function(type) {
                const data = $gameSystem.transitionData(type);
                return data.name || data.xpMode || data.color;
        };

        Scene_Base.prototype.presetTransitionSpeed = function(type, slow, normal) {
                const data = $gameSystem.transitionData(type);
                return (data.xpMode && data.name) ? slow ?? this.slowFadeSpeed() : normal ?? this.fadeSpeed();
        };

        //-----------------------------------------------------------------------------
        // Scene_MenuBase

        const _Scene_MenuBase_createBackground = Scene_MenuBase.prototype.createBackground;
        Scene_MenuBase.prototype.createBackground = function() {
                _Scene_MenuBase_createBackground.call(this);
                const bitmap = SceneManager.backgroundBitmap();
                if (bitmap && sceneTransition === "2000") {
                        bitmap.fillAll("#002063");
                        this.setBackgroundOpacity(255);
                }
        };

        //-----------------------------------------------------------------------------
        // Scene_Title

        if (sceneTransition === "2000") {
                const _Scene_Title_start = Scene_Title.prototype.start;
                Scene_Title.prototype.start = function() {
                        _Scene_Title_start.call(this);
                        this._shouldAlwaysOpenCommandWindow = false;
                        if (.some(scene => SceneManager.isPreviousScene(scene))) {
                                this.startFadeIn(this.transitionSpeed());
                                this._shouldAlwaysOpenCommandWindow = true;
                        } else if (SceneManager.isPreviousScene(Scene_Map)) {
                                this.startFadeIn(this.slowFadeSpeed());
                        }
                };

                let slowFadeSpeed = 0;
                const _Scene_Title_commandNewGame = Scene_Title.prototype.commandNewGame;
                Scene_Title.prototype.commandNewGame = function() {
                        slowFadeSpeed = this.transitionSpeed();
                        _Scene_Title_commandNewGame.call(this);
                        slowFadeSpeed = 0;
                };

                if (Scene_Title.prototype.slowFadeSpeed === Scene_Base.prototype.slowFadeSpeed) {
                        Scene_Title.prototype.slowFadeSpeed = function() {
                                return Scene_Base.prototype.slowFadeSpeed.apply(this, arguments);
                        };
                }

                const _Scene_Title_slowFadeSpeed = Scene_Title.prototype.slowFadeSpeed
                Scene_Title.prototype.slowFadeSpeed = function() {
                        return slowFadeSpeed || _Scene_Title_slowFadeSpeed.call(this);
                };

                const _Scene_Title_update = Scene_Title.prototype.update;
                Scene_Title.prototype.update = function() {
                        _Scene_Title_update.call(this);
                        if (this._shouldAlwaysOpenCommandWindow || this._commandWindow.isClosing()) {
                                this._commandWindow.openness = 255;
                                this._commandWindow.open();
                        }
                };
        } else if (sceneTransition === "XP") {
                const _Scene_Title_start = Scene_Title.prototype.start;
                Scene_Title.prototype.start = function() {
                        _Scene_Title_start.call(this);
                        this.startFadeIn(this.transitionSpeed());
                };

                const _Scene_Title_commandNewGame = Scene_Title.prototype.commandNewGame;
                Scene_Title.prototype.commandNewGame = function() {
                        _Scene_Title_commandNewGame.call(this);
                        this.rejectFade();
                };

                const _Scene_Title_update = Scene_Title.prototype.update;
                Scene_Title.prototype.update = function() {
                        _Scene_Title_update.call(this);
                        this._commandWindow.openness = 255;
                        this._commandWindow.open();
                };
        }

        //-----------------------------------------------------------------------------
        // Scene_Load

        const _Scene_Load_onLoadSuccess = Scene_Load.prototype.onLoadSuccess;
        Scene_Load.prototype.onLoadSuccess = function() {
                _Scene_Load_onLoadSuccess.call(this);
                if (sceneTransition === "XP") {
                        this.rejectFade();
                } else if (sceneTransition === "2000") {
                        this.startFadeOut(this.transitionSpeed());
                }
        };

        //-----------------------------------------------------------------------------
        // Scene_GameEnd

        const _Scene_GameEnd_createBackground = Scene_GameEnd.prototype.createBackground;
        Scene_GameEnd.prototype.createBackground = function() {
                _Scene_GameEnd_createBackground.call(this);
                if (sceneTransition === "2000") {
                        this.setBackgroundOpacity(255);
                }
        };

        if (["2000", "XP"].includes(sceneTransition)) {
                const _Scene_GameEnd_create = Scene_GameEnd.prototype.create;
                Scene_GameEnd.prototype.create = function() {
                        _Scene_GameEnd_create.call(this);
                        this._commandWindow.openness = 255;
                        this._commandWindow.open();
                };

                const _Scene_GameEnd_stop = Scene_GameEnd.prototype.stop;
                Scene_GameEnd.prototype.stop = function() {
                        _Scene_GameEnd_stop.call(this);
                        this._commandWindow.open();
                };

                const _Scene_GameEnd_commandToTitle = Scene_GameEnd.prototype.commandToTitle;
                Scene_GameEnd.prototype.commandToTitle = function() {
                        _Scene_GameEnd_commandToTitle.call(this);
                        this.startFadeOut(sceneTransition === "XP" ? this.transitionSpeed() : this.fadeSpeed());
                };
        } else if (sceneTransition === "VX") {
                if (Scene_MenuBase.prototype.isBusy === Scene_GameEnd.prototype.isBusy) {
                        Scene_GameEnd.prototype.isBusy = function() {
                                return Scene_MenuBase.prototype.isBusy.call(this);
                        };
                }
                const _Scene_GameEnd_isBusy = Scene_GameEnd.prototype.isBusy;
                Scene_GameEnd.prototype.isBusy = function() {
                        return this._commandWindow.isClosing() || _Scene_GameEnd_isBusy.call(this);
                };
        }

        //-----------------------------------------------------------------------------
        // Scene_Gameover

        const _Scene_Gameover_playGameoverMusic = Scene_Gameover.prototype.playGameoverMusic;
        Scene_Gameover.prototype.playGameoverMusic = function() {
                _Scene_Gameover_playGameoverMusic.call(this);
                if (gameoverBgm.name) {
                        AudioManager.playBgm(gameoverBgm);
                }
        };

        if (sceneTransition === "VX") {
                let createGameover = false;
                const _Scene_Gameover_create = Scene_Gameover.prototype.create;
                Scene_Gameover.prototype.create = function() {
                        createGameover = true;
                        _Scene_Gameover_create.call(this);
                        createGameover = false;
                };

                const _Scene_Gameover_playGameoverMusic = Scene_Gameover.prototype.playGameoverMusic;
                Scene_Gameover.prototype.playGameoverMusic = function() {
                        if (createGameover) return;
                        _Scene_Gameover_playGameoverMusic.call(this);
                };
        }

        if (sceneTransition === "XP"){
                const _Scene_Gameover_start = Scene_Gameover.prototype.start;
                Scene_Gameover.prototype.start = function() {
                        _Scene_Gameover_start.call(this);
                        this.startFadeIn(180);
                };
        }

        //-----------------------------------------------------------------------------
        // Scene_Message

        Scene_Message.prototype.needsTransition = function() {
                return false;
        };

        if (sceneTransition === "VX") {
                Scene_Message.prototype.transitionSpeed = function() {
                        return 12;
                };
        }

        //-----------------------------------------------------------------------------
        // Scene_Map

        Scene_Map.prototype.inTransition = function() {
                return $gameTemp.inMapTransition() && SceneManager.isPreviousScene(Scene_Map);
        };

        if (sceneTransition !== "MZ") {
                Scene_Map.prototype.needsTransition = function(sign) {
                        if (sign < 0) {
                                return !.some(scene => SceneManager.isNextScene(scene));
                        } else {
                                return !.some(scene => SceneManager.isPreviousScene(scene));
                        }
                };
        }

        Scene_Map.prototype.restoreTransition = function() {
                if (!this.inTransition()) {
                        $gameTemp.clearMapTransition();
                        return;
                }
                this.rejectFade();
                const data = $gameTemp.mapTransitionData();
                this._transitionDuration = 1;
                this.setupTransition(data, -1);
                this.updateTransition();
        };

        const _Scene_Base_setupTransition = Scene_Base.prototype.setupTransition;
        Scene_Map.prototype.setupTransition = function(data, sign) {
                _Scene_Base_setupTransition.apply(this, arguments);
                if (sign < 0) {
                        $gameTemp.setMapTransition(data.xpMode, data.color);
                } else {
                        $gameTemp.clearMapTransition();
                }
        };

        Scene_Map.prototype.snapForTransition = function() {
                this._windowLayer.visible = false;
                Scene_Message.prototype.snapForTransition.call(this);
                this._windowLayer.visible = true;
        };

        const _Scene_Map_fadeInForTransfer = Scene_Map.prototype.fadeInForTransfer;
        Scene_Map.prototype.fadeInForTransfer = function() {
                const type = "Transfer Player (Show)";
                if (!this.needsPresetTransition(type)) {
                        _Scene_Map_fadeInForTransfer.call(this);
                        return;
                }
                this.showScreenForTransfer(type);
        };

        Scene_Map.prototype.showScreenForTransfer = function(type) {
                const fadeType = $gamePlayer.fadeType();
                switch (fadeType) {
                        case 0:
                        case 1:
                                const color = $gameSystem.transitionColor(type) || true;
                                this.showScreenWithPreset(this.presetTransitionSpeed(type), type, fadeType === 1 && color);
                                break;
                }
        };

        const _Scene_Map_fadeOutForTransfer = Scene_Map.prototype.fadeOutForTransfer;
        Scene_Map.prototype.fadeOutForTransfer = function() {
                const type = "Transfer Player (Hide)";
                if (!this.needsPresetTransition(type)) {
                        _Scene_Map_fadeOutForTransfer.call(this);
                        return;
                }
                this.hideScreenForTransfer(type);
        };

        Scene_Map.prototype.hideScreenForTransfer = function(type) {
                const fadeType = $gamePlayer.fadeType();
                switch (fadeType) {
                        case 0:
                        case 1:
                                const color = $gameSystem.transitionColor(type) || true;
                                this.hideScreenWithPreset(this.presetTransitionSpeed(type), type, fadeType === 1 && color);
                                break;
                }
        };

        if (Scene_Base.prototype.startFadeOut === Scene_Map.prototype.startFadeOut) {
                Scene_Map.prototype.startFadeOut = function(duration, white) {
                        Scene_Base.prototype.startFadeOut.apply(this, arguments);
                };
        }
        //エンカウントエフェクト乗っ取り
        const _Scene_Map_startFadeOut = Scene_Map.prototype.startFadeOut;
        Scene_Map.prototype.startFadeOut = function(duration, white) {
                if (updateEncounterEffect) {
                        const type = "Start Battle (Hide)";
                        this.hideScreenWithPreset(duration, type);
                        return;
                }
                _Scene_Map_startFadeOut.apply(this, arguments);
        };

        const _Scene_Map_start = Scene_Map.prototype.start;
        Scene_Map.prototype.start = function() {
                _Scene_Map_start.call(this);
                const type = "End Battle (Show)";
                if (SceneManager.isPreviousScene(Scene_Battle) && this.needsPresetTransition(type)) {
                        this.rejectFade();
                        if (sceneTransition === "XP") {
                                //XPなら更に速くする。
                                this.showScreenWithPreset(this.presetTransitionSpeed(type, this.fadeSpeed(), this.transitionSpeed()), type);
                        } else {
                                this.showScreenWithPreset(this.presetTransitionSpeed(type), type);
                        }
                }
                this.restoreTransition();
        };
        //ニューゲーム、ロードを特殊演出に
        if (sceneTransition === "2000") {
                const _Scene_Map_start = Scene_Map.prototype.start;
                Scene_Map.prototype.start = function() {
                        _Scene_Map_start.call(this);
                        if (SceneManager.isPreviousScene(Scene_Load) || SceneManager.isPreviousScene(Scene_Title)) {
                                this.startFadeIn(this.slowFadeSpeed());
                        }
                };
        } else if (sceneTransition === "XP") {
                const _Scene_Map_start = Scene_Map.prototype.start;
                Scene_Map.prototype.start = function() {
                        _Scene_Map_start.call(this);
                        if (SceneManager.isPreviousScene(Scene_Load) || SceneManager.isPreviousScene(Scene_Title)) {
                                this.startFadeIn(this.transitionSpeed());
                        }
                };
        }

        if (!hideCharacters) {
                Scene_Map.prototype.startEncounterEffect = function() {
                        this._encounterEffectDuration = this.encounterEffectSpeed();
                        this._spriteset._tilemap.setFreeze(true);
                };
        }

        if (encounterEffect === "2000") {
                Scene_Map.prototype.encounterEffectSpeed = function() {
                        return 17;
                };
                //フラッシュからのフェード
                Scene_Map.prototype.updateEncounterEffect = function() {
                        if (this._encounterEffectDuration > 0) {
                                this._encounterEffectDuration--;
                                const speed = this.encounterEffectSpeed();
                                const n = speed - this._encounterEffectDuration;
                                if (n === 1) {
                                        this.snapForBattleBackground();
                                        this.startFlashForEncounter(10);
                                        BattleManager.playBattleBgm();
                                }
                                if (n === 11) {
                                        this.startFlashForEncounter(10);
                                }
                                if (n === 17) {
                                        this.startFadeOut(40);
                                }
                        }
                };

        } else if (["XP", "VX", "VXAce", "Fes"].includes(encounterEffect)) {
                Scene_Map.prototype.encounterEffectSpeed = function() {
                        return 1;
                };

                Scene_Map.prototype.updateEncounterEffect = function() {
                        if (this._encounterEffectDuration > 0) {
                                this._encounterEffectDuration--;
                                const speed = this.encounterEffectSpeed();
                                const n = speed - this._encounterEffectDuration;
                                if (n === 1) {
                                        this.snapForBattleBackground();
                                        if (encounterEffect !== "Fes") {
                                                BattleManager.playBattleBgm();
                                        }
                                        switch (encounterEffect) {
                                        case "XP":
                                                this.startFadeOut(30);
                                                break;
                                        case "VX":
                                                this.startFadeOut(80);
                                                this._transitionSprite._pos = 80; //途中から開始する
                                                break;
                                        case "VXAce":
                                                this.startFadeOut(60);
                                                this._transitionSprite._pos = 120; //同上
                                                break;
                                        case "Fes":
                                                this.startFadeOut(16);
                                                break;
                                               
                                        }
                                }
                        }
                };
        }

        let updateEncounterEffect = false;
        const _Scene_Map_updateEncounterEffect = Scene_Map.prototype.updateEncounterEffect;
        Scene_Map.prototype.updateEncounterEffect = function() {
                updateEncounterEffect = this.needsPresetTransition("Start Battle (Hide)");
                _Scene_Map_updateEncounterEffect.call(this);
                updateEncounterEffect = false;
        };

        if (sceneTransition === "2000") {
                const _Scene_Map_stop = Scene_Map.prototype.stop;
                Scene_Map.prototype.stop = function() {
                        _Scene_Map_stop.call(this);
                        if (SceneManager.isNextScene(Scene_Title)) {
                                this.startFadeOut(this.transitionSpeed());
                        }
                };
        } else if (sceneTransition === "XP") {
                const _Scene_Map_needsSlowFadeOut = Scene_Map.prototype.needsSlowFadeOut;
                Scene_Map.prototype.needsSlowFadeOut = function() {
                        return _Scene_Map_needsSlowFadeOut.call(this) && !SceneManager.isNextScene(Scene_Gameover);
                };
                const _Scene_Map_stop = Scene_Map.prototype.stop;
                Scene_Map.prototype.stop = function() {
                        _Scene_Map_stop.call(this);
                        if (SceneManager.isNextScene(Scene_Title)) {
                                this.startFadeOut(this.transitionSpeed());
                        }
                };
        }

        //-----------------------------------------------------------------------------
        // Scene_Battle

        const _Scene_Battle_start = Scene_Battle.prototype.start;
        Scene_Battle.prototype.start = function() {
                const type = "Start Battle (Show)";
                _Scene_Battle_start.call(this);
                if (this.needsPresetTransition(type) || encounterEffect !== "MZ") {
                        const xpMode = $gameSystem.transitionXp(type);
                        let duration = this.presetTransitionSpeed(type);
                        let pos = 0;
                        switch (encounterEffect) {
                        case "2000":
                                duration = xpMode ? 40 : 20;
                                break;
                        case "VX":
                                duration = xpMode ? 80 : 12;
                                if (xpMode) pos = 80;
                                break;
                        case "VXAce":
                                duration = xpMode ? 60 : 12;
                                if (xpMode) pos = 120;
                                break;
                        case "Fes":
                                duration = 16;
                                break;
                        }
                        this.rejectFade();
                        this.showScreenWithPreset(duration, type);
                        this._transitionSprite._pos = pos;
                }
        };

        const _Scene_Battle_stop = Scene_Battle.prototype.stop;
        Scene_Battle.prototype.stop = function() {
                _Scene_Battle_stop.call(this);
                const type = "End Battle (Hide)";
                if (SceneManager.isNextScene(Scene_Map) && this.needsPresetTransition(type)) {
                        this.rejectFade();
                        this.hideScreenWithPreset(this.fadeSpeed(), type);
                }
        };

        if (sceneTransition === "2000") {
                const _Scene_Battle_stop = Scene_Battle.prototype.stop;
                Scene_Battle.prototype.stop = function() {
                        _Scene_Battle_stop.call(this);
                        if (SceneManager.isNextScene(Scene_Title)) {
                                this.startFadeOut(this.transitionSpeed());
                        }
                };
        } else if (sceneTransition === "XP") {
                const _Scene_Battle_stop = Scene_Battle.prototype.stop;
                Scene_Battle.prototype.stop = function() {
                        _Scene_Battle_stop.call(this);
                        if (SceneManager.isNextScene(Scene_Title)) {
                                this.startFadeOut(this.transitionSpeed());
                        } else if (!SceneManager.isNextScene(Scene_Map)) {
                                this.rejectFade();
                        }
                };
        } else if (sceneTransition === "VX") {
                const _Scene_Battle_terminate = Scene_Battle.prototype.terminate;
                Scene_Battle.prototype.terminate = function() {
                        const playMe = AudioManager.playMe;
                        const stopMe = AudioManager.stopMe;
                        if (SceneManager.isNextScene(Scene_Gameover)) {
                                AudioManager.playMe = function() {};
                                AudioManager.stopMe = function() {};
                        }
                        _Scene_Battle_terminate.call(this);
                        AudioManager.playMe = playMe;
                        AudioManager.stopMe = stopMe;
                };
        }

        //-----------------------------------------------------------------------------
        // Sprite_Transition
        // トランジション用スプライトの定義です。

        function Sprite_Transition() {
                this.initialize(...arguments);
        }

        Sprite_Transition.prototype = Object.create(Sprite.prototype);
        Sprite_Transition.prototype.constructor = Sprite_Transition;

        //イニシャライザ
        //smoothnessとposでVXのvagueを再現できる
        Sprite_Transition.prototype.initialize = function(data) {
                Sprite.prototype.initialize.call(this);
                this.bitmap = new Bitmap(Graphics.width, Graphics.height);
                this._xpMode = !!data.xpMode; //スクショ付きトランジション
                this._fileName = data.name || "";
                this._smoothness = data.smoothness ?? 4.5; //滑らかさ(0-7)
                this._pos = data.pos ?? 0; //開始位置(0-255)
                this.createTransitionData(this._fileName);
                this._durationMax = 0;
                this.setColor(data.color ?? false);
        };

        Sprite_Transition.prototype.setColor = function(c) {
                if (this._xpMode) {
                        c = false;
                } else if (c === true) {
                        c = ;
                }
                if (c && c.some(n => n > 0)) {
                        this.setBlendColor(, c, c, 255]);
                } else {
                        this.setBlendColor();
                }
        };

        Sprite_Transition.prototype.durationMax = function() {
                return this._durationMax;
        };

        Sprite_Transition.prototype.setDurationMax = function(d) {
                this._durationMax = d;
        };

        Sprite_Transition.prototype.destroy = function(options) {
                if (this.bitmap) {
                        this.bitmap.destroy();
                }
                Sprite.prototype.destroy.call(this, options);
        };

        //トランジションの元画像を読み込んでトランジション情報を作成する
        Sprite_Transition.prototype.createTransitionData = function(fileName) {
                const bitmap = new Bitmap(Graphics.width, Graphics.height);
                this._transitionBitmap = null;
                if(fileName){
                        //ファイル名が設定されていたら読み込む
                        const bitmap2 = ImageManager.loadTransition(fileName);
                        if(bitmap2.isReady()){
                                //キャッシュから読み込んだ場合は描画
                                this.synthesizeBitmap(bitmap, bitmap2, ImageManager.isBigCharacter(fileName));
                        } else {
                                //すぐに読み込めなかったらバックアップ
                                this._transitionBitmap = bitmap2;
                        }
                }
                //XPならデータ反転
                const negative = ImageManager.isObjectCharacter(fileName);
                this._transitionData = bitmap.getTransitionData(this._xpMode ? !negative : negative);
                bitmap.destroy();
        };

        Sprite_Transition.prototype.updateBitmap = function(duration, sign) {
                //ファイル名がない場合は普通のフェードを模倣
                this.opacity = 255;
                if (!this._fileName) {
                        this.updateFade(duration, sign);
                } else if (this._smoothness > 0) {
                        this.updateSmoothTransition(duration, sign);
                } else {
                        this.updateTransition(duration, sign);
                }
        };

        Sprite_Transition.prototype.updateFade = function(duration, sign) {
                this.opacity = sign > 0 ? 255 * (duration / this._durationMax) : 255 - 255 * (duration / this._durationMax);
        };

        Sprite_Transition.prototype.updateSmoothTransition = function(duration, sign) {
                const speedRate = 2**(8 - this._smoothness);
                const rate = speedRate / (speedRate-1);
                const max = 255 * rate;
                const speed = 255 * speedRate / this._durationMax;
                const pos = this._pos;
                if (sign > 0) {
                        const offset = 255 - max;
                        let threshold = (max * duration / this._durationMax) + offset;
                        let lastThreshold = (max * (duration + 1) / this._durationMax) + offset;
                        if (pos > 0) {
                                threshold *= (255 - pos) / 255;
                                lastThreshold *= (255 - pos) / 255;
                        }
                        this.bitmap.createSmoothTransitionFadeIn(this._transitionData, threshold, lastThreshold, speed);
                } else {
                        let threshold = max - (max * duration / this._durationMax);
                        let lastThreshold = max - (max * (duration + 1) / this._durationMax);
                        if (pos > 0) {
                                threshold = threshold * (255 - pos) / 255 + pos;
                                lastThreshold = lastThreshold * (255 - pos) / 255 + pos;
                        }
                        this.bitmap.createSmoothTransitionFadeOut(this._transitionData, threshold, lastThreshold, speed);
                }
        };

        Sprite_Transition.prototype.updateTransition = function(duration, sign) {
                const pos = this._pos;
                if (sign > 0) {
                        let threshold = (255 * duration / this._durationMax);
                        if (pos > 0) {
                                threshold *= (255 - pos) / 255;
                        }
                        this.bitmap.createTransitionFadeIn(this._transitionData, threshold);
                } else {
                        let threshold = 255 - (255 * duration / this._durationMax);
                        if (pos > 0) {
                                threshold = threshold * (255 - pos) / 255 + pos;
                        }
                        this.bitmap.createTransitionFadeOut(this._transitionData, threshold);
                }
        };

        Sprite_Transition.prototype.setDefault = function(sign) {
                if(this._transitionBitmap){
                        if(!this._transitionBitmap.isReady()){
                                return false;
                        }
                        this.createTransitionData(this._fileName);
                }
                return true;
        };

        Sprite_Transition.prototype.synthesizeBitmap = function(bitmap1, bitmap2, zoom) {
                if (!zoom) {
                        bitmap1.blt(bitmap2, 0, 0, bitmap2.width, bitmap2.height,
                                0, 0, bitmap1.width, bitmap1.height);
                        return;
                }
                const aspect1 = bitmap1.width / bitmap1.height;
                const aspect2 = bitmap2.width / bitmap2.height;
                let left, top, width, height;
                if(aspect2 < aspect1) {// 画像が横長
                        left = 0;
                        width = bitmap1.width;
                        height = bitmap1.width / aspect2;
                        top = (bitmap1.height - height) / 2;
                } else {// 画像が縦長
                        top = 0;
                        height = bitmap1.height;
                        width = bitmap1.height * aspect2;
                        left = (bitmap1.width - width) / 2;
                }
                bitmap1.blt(bitmap2, 0, 0, bitmap2.width, bitmap2.height,
                        left, top, width, height);
        };

        Sprite_Transition.prototype.setBitmap = function(sign) {
                if (this._xpMode) {
                        const snap = SceneManager.transitionBitmap();
                        this.bitmap.fillAll("black"); //ここで染めておくことでスクショが透明でも動作可能にする。
                        if (snap) {
                                this.synthesizeBitmap(this.bitmap, snap);
                        }
                } else if (sign > 0 || !this._fileName) {
                        //フェードイン
                        this.bitmap.fillAll("black");
                } else {
                        //フェードアウト
                        this.bitmap.clear();
                }
        };

        //-----------------------------------------------------------------------------
        // Window_Base

        if (speedUpWindows) {
                Window_Base.prototype.updateOpen = function() {
                        if (this._opening) {
                                this.openness += 48;
                                if (this.isOpen()) {
                                        this._opening = false;
                                }
                        }
                };

                Window_Base.prototype.updateClose = function() {
                        if (this._closing) {
                                this.openness -= 48;
                                if (this.isClosed()) {
                                        this._closing = false;
                                }
                        }
                };
        }

        //-----------------------------------------------------------------------------
        // ImageManager

        ImageManager.loadTransition = function(filename) {
                return this.loadBitmap('img/transitions/', filename);
        };

        //-----------------------------------------------------------------------------
        // Bitmap

        //トランジションデータを作る
        Bitmap.prototype.createTransitionFadeIn = function(data, threshold) {
                if(this.width > 0 && this.height > 0){
                        const context = this._context;
                        const imageData = context.getImageData(0, 0, this.width, this.height);
                        const pixels = imageData.data;
                        for(let i = 0; i < pixels.length; i+=4){
                                if(pixels === 255){
                                   const alpha = (data >= threshold) ? 0 : 255;
                                   pixels = alpha;
                                }
                        }
                        context.putImageData(imageData, 0, 0);
                        this._baseTexture.update();
                }
        };

        Bitmap.prototype.createTransitionFadeOut = function(data, threshold) {
                if(this.width > 0 && this.height > 0){
                        const context = this._context;
                        const imageData = context.getImageData(0, 0, this.width, this.height);
                        const pixels = imageData.data;
                        for(let i = 0; i < pixels.length; i+=4){
                                if(pixels === 0){
                                   const alpha = (data > threshold) ? 0 : 255;
                                   pixels = alpha;
                                }
                        }
                        context.putImageData(imageData, 0, 0);
                        this._baseTexture.update();
                }
        };
        //閾値の差からグラデーションを復元
        function getSmoothSpeed(opacity, threshold, lastThreshold, speed) {
                return speed * (threshold - opacity) / (threshold - lastThreshold);
        }

        Bitmap.prototype.createSmoothTransitionFadeIn = function(data, threshold, lastThreshold, speed) {
                if(this.width > 0 && this.height > 0){
                        const context = this._context;
                        const imageData = context.getImageData(0, 0, this.width, this.height);
                        const pixels = imageData.data;
                        for(let i = 0; i < pixels.length; i+=4){
                                if(pixels === 255){
                                        const alpha = (data >= threshold) ? 255 - getSmoothSpeed(data, threshold, lastThreshold, speed) : 255;
                                        pixels = alpha;
                                } else if(pixels !== 0) {
                                        pixels -= speed;
                                }
                        }
                        context.putImageData(imageData, 0, 0);
                        this._baseTexture.update();
                }
        };

        Bitmap.prototype.createSmoothTransitionFadeOut = function(data, threshold, lastThreshold, speed) {
                if(this.width > 0 && this.height > 0){
                        const context = this._context;
                        const imageData = context.getImageData(0, 0, this.width, this.height);
                        const pixels = imageData.data;
                        for(let i = 0; i < pixels.length; i+=4){
                                if(pixels === 0){
                                        const alpha = (data > threshold) ? 0 : getSmoothSpeed(data, threshold, lastThreshold, speed);
                                        pixels = alpha;
                                } else if(pixels !== 255) {
                                        pixels += speed;
                                }
                        }
                        context.putImageData(imageData, 0, 0);
                        this._baseTexture.update();
                }
        };

        //画像データの配列情報を取得する
        Bitmap.prototype.getTransitionData = function(negative) {
                if(this.width > 0 && this.height > 0){
                        const context = this._context;
                        const imageData = context.getImageData(0, 0, this.width, this.height);
                        const pixels = imageData.data;
                        if (negative) {
                                for(let i = 0; i < pixels.length; i+=4){
                                        pixels = 255 - pixels;
                                        pixels = 255 - pixels;
                                        pixels = 255 - pixels;
                                }
                        }
                        return pixels;
                }
        };

})();




页: [1]
查看完整版本: 【汉化】仿XP/VX模式屏幕渐变