pure-full-lily/js/plugins/RegionDarknessAbove.js
2025-09-16 10:12:44 -05:00

179 lines
No EOL
7.3 KiB
JavaScript

//=============================================================================
// RegionDarknessAbove.js
//=============================================================================
// [Update History]
// 2025/07/11 - ver.1.4.0 - 表示順を調整し、ピクチャの下に表示されるように修正
// 2025/07/11 - ver.1.3.0 - タイルの隙間が見える問題を修正
// 2025/07/11 - ver.1.2.0 - 他プラグインとの競合を避けるため、スプライトの追加方法を修正
// 2025/07/11 - ver.1.1.0 - キャラクターの上への表示、フェード処理を追加
// 2025/07/11 - ver.1.0.0 - 初版作成
/*:
* @target MZ
* @plugindesc 特定のスイッチがON/OFFで指定リージョンのタイルをキャラの上にフェードイン・アウトさせます。
* @author あなたの名前 (Your Name)
* @version 1.4.0
*
* @param targetSwitchId
* @text 対象のスイッチID
* @desc このスイッチがONの時に、リージョンを暗くします。
* @type switch
* @default 1
*
* @param targetRegionId
* @text 対象のリージョンID
* @desc このリージョンIDが設定されたタイルを暗くします。
* @type number
* @min 1
* @max 255
* @default 1
*
* @param fadeDuration
* @text フェード時間 (フレーム数)
* @desc フェードイン・アウトにかかる時間です。60で約1秒。
* @type number
* @min 1
* @default 30
*
* @help
* RegionDarknessAbove.js
*
* このプラグインは、RPGツクールMZ専用です。
*
* ■ 概要
* プラグインパラメータで指定したスイッチを操作すると、
* 同じくパラメータで指定したリージョンIDが設定されているマップタイルが
* キャラクターの上に黒い四角でフェードイン・アウトしながら表示/非表示になります。
*
* ■ 使い方
* 1. プラグイン管理からこのプラグインをONにします。
* 2. プラグインパラメータで以下を設定します。
* ・対象のスイッチID: 動作をON/OFFするスイッチを指定します。
* ・対象のリージョンID: 暗くしたいタイルに設定するリージョンIDを指定します。
* ・フェード時間: フェードイン・アウトのアニメーション時間(フレーム単位)を指定します。
*
* 3. ツクールのマップ編集画面で、対象のタイルに指定したリージョンIDを設定します。
*
* 4. ゲーム内で、イベントコマンドの「スイッチの操作」を使って、
* 指定したスイッチをONにすると、該当リージョンがフェードインして暗くなります。
* OFFにするとフェードアウトして元に戻ります。
*
* ■ 仕様・注意点
* ・この暗闇の表示は、キャラクターやイベントより上、ピクチャより下に表示されます。
*
* ■ 利用規約
* ・改変、再配布はご自由に行ってください。
* ・商用、非商用問わずご利用いただけます。
* ・クレジット表記は任意です。
*/
(() => {
'use strict';
const pluginName = 'RegionDarknessAbove';
const params = PluginManager.parameters(pluginName);
const targetSwitchId = Number(params.targetSwitchId || 1);
const targetRegionId = Number(params.targetRegionId || 1);
const fadeDuration = Number(params.fadeDuration || 30);
const fadeSpeed = fadeDuration > 0 ? 255 / fadeDuration : 255;
//-----------------------------------------------------------------------------
// Sprite_RegionDarkness
//
// 指定リージョンを黒く塗りつぶすためのスプライトを定義します。
function Sprite_RegionDarkness() {
this.initialize(...arguments);
}
Sprite_RegionDarkness.prototype = Object.create(Sprite.prototype);
Sprite_RegionDarkness.prototype.constructor = Sprite_RegionDarkness;
Sprite_RegionDarkness.prototype.initialize = function() {
Sprite.prototype.initialize.call(this);
this.bitmap = new Bitmap(Graphics.width, Graphics.height);
this._lastDisplayX = -1;
this._lastDisplayY = -1;
this._lastSwitchState = undefined;
this.opacity = $gameSwitches.value(targetSwitchId) ? 255 : 0;
this._needsRedraw = true;
};
Sprite_RegionDarkness.prototype.update = function() {
Sprite.prototype.update.call(this);
this.updateFade();
this.updateRedraw();
};
Sprite_RegionDarkness.prototype.updateFade = function() {
const switchState = $gameSwitches.value(targetSwitchId);
if (switchState) {
this.opacity = Math.min(this.opacity + fadeSpeed, 255);
} else {
this.opacity = Math.max(this.opacity - fadeSpeed, 0);
}
};
Sprite_RegionDarkness.prototype.updateRedraw = function() {
const switchState = $gameSwitches.value(targetSwitchId);
const displayX = $gameMap.displayX();
const displayY = $gameMap.displayY();
if (
this.opacity > 0 &&
(this._lastSwitchState !== switchState ||
this._lastDisplayX !== displayX ||
this._lastDisplayY !== displayY)
) {
this._needsRedraw = true;
}
if (this._needsRedraw && this.opacity > 0) {
this.redraw();
this._lastDisplayX = displayX;
this._lastDisplayY = displayY;
this._lastSwitchState = switchState;
this._needsRedraw = false;
}
};
Sprite_RegionDarkness.prototype.redraw = function() {
this.bitmap.clear();
const tw = $gameMap.tileWidth();
const th = $gameMap.tileHeight();
const startX = Math.floor($gameMap.displayX());
const startY = Math.floor($gameMap.displayY());
const endX = startX + Math.ceil(Graphics.width / tw) + 1;
const endY = startY + Math.ceil(Graphics.height / th) + 1;
for (let y = startY; y < endY; y++) {
for (let x = startX; x < endX; x++) {
if ($gameMap.isValid(x, y) && $gameMap.regionId(x, y) === targetRegionId) {
const screenX = (x - $gameMap.displayX()) * tw;
const screenY = (y - $gameMap.displayY()) * th;
this.bitmap.fillRect(screenX, screenY, tw + 1, th + 1, "black");
}
}
}
};
//-----------------------------------------------------------------------------
// Spriteset_Map
//
// マップ表示に暗闇スプライトを追加します。
const _Spriteset_Map_createUpperLayer = Spriteset_Map.prototype.createUpperLayer;
Spriteset_Map.prototype.createUpperLayer = function() {
// ★★★ 修正点: 先に暗闇スプライトを追加する ★★★
this.createRegionDarknessSprite();
// 元のcreateUpperLayerを呼び出して、ピクチャなどを「後から」追加させる
_Spriteset_Map_createUpperLayer.call(this);
};
Spriteset_Map.prototype.createRegionDarknessSprite = function() {
this._regionDarknessSprite = new Sprite_RegionDarkness();
this.addChild(this._regionDarknessSprite);
};
})();