prison-brave/js/plugins/Scene_StaffRoll.js
2025-08-28 10:38:20 -05:00

242 lines
8.1 KiB
JavaScript

//=============================================================================
// RPG Maker MZ - Scene_StaffRoll
//
// Copyright 2024 Panzer-IV. All rights reserved.
// This source code or any portion thereof must not be
// reproduced or used without licensed in any manner whatsoever.
//=============================================================================
/*:
* @target MZ
* @plugindesc スタッフロール画面プラグイン
* @author 四号戦車
* @base PluginCommonBase
* @base DebugSwitch
* @base PluginUtils
* @orderAfter PluginCommonBase
* @orderAfter DebugSwitch
* @orderAfter PluginUtils
*
* @param images
* @text スタッフロール画像
* @desc スタッフロールの画像
* @type file[]
* @dir img/system
* @default []
*
* @param bgm
* @text BGM指定
* @desc BGMの指定です。
* @type file
* @dir audio/bgm
* @default
*
* @param event
* @text 次のイベント
* @desc スタッフロール終了後移動するイベントの指定です。
* @type common_event
* @default 0
*
* @param scrollWithMusic
* @text BGM追従スクロール設定
* @desc BGMの終了とスクロールの終了を併せます。
* @type boolean
* @default false
*
* @help Scene_StaffRoll.js
*
* Version: 0.0.1
*
* スタッフロール画面
*
* @command startStaffRoll
* @text スタッフロール開始
* @desc スタッフロールを開始します。
*/
(() => {
"use strict";
//========================================================================
// プラグイン定義
//========================================================================
const pluginName = "Scene_StaffRoll";
const script = document.currentScript;
const param = PluginManagerEx.createParameter(script);
//========================================================================
// コアスクリプト変更部 (Scene_Boot)
//========================================================================
const _Scene_Boot_prototype_onDatabaseLoaded = Scene_Boot.prototype.onDatabaseLoaded;
Scene_Boot.prototype.onDatabaseLoaded = function() {
_Scene_Boot_prototype_onDatabaseLoaded.apply(this, arguments);
// preload
param.images.forEach(image => {
ImageManager.loadSystem(image);
});
}
//========================================================================
// 定数定義 (StaffRollState)
//========================================================================
const StaffRollState = {
NONE: 'none',
READY: 'ready',
RUNNING: 'running',
ENDING: 'ending',
END: 'end',
};
const ENDING_WAIT = 60;
const MOVE_IN_SKIP = 200;
const MOVE_NORMAL = 4;
//========================================================================
// クラス定義 (Scene_StaffRoll)
//========================================================================
class Scene_StaffRoll extends Scene_Base {
constructor() {
super();
this.sprite = null;
this.duration = 60 * 2; // 2 minutes
this.currentY = 0;
this.movePerFrame = 1;
this._state = StaffRollState.NONE;
this.endingCount = 0;
this.imageHeight = Graphics.height;
}
create() {
super.create();
this.sprite = new Sprite_Scrollable(Graphics.width, Graphics.height);
let height = 0;
param.images.forEach(image => {
const sprite = new Sprite(ImageManager.loadSystem(image));
sprite.move((Graphics.width - sprite.width) / 2, height);
this.sprite.addChild(sprite);
height += sprite.height;
});
this.imageHeight = height;
this.sprite.enableInput(false);
this.sprite.enableScrollX(false);
this.sprite.move(0, 0);
this.addChild(this.sprite);
this.movePerFrame = this._calcMoveHeight()
}
start() {
super.start();
if (!!param.bgm && param.bgm !== '') {
const bgm = {
name: param.bgm,
volume: 100,
pitch: 100,
pan: 0,
pos: 0,
};
if (param.scrollWithMusic) {
AudioManager.stopBgm();
AudioManager._bgmBuffer = AudioManager.createBuffer("bgm/", bgm.name);
AudioManager.updateBgmParameters(bgm);
const webAudio = AudioManager._bgmBuffer;
const scene = this;
const onBgmLoaded = () => {
scene.duration = webAudio._totalTime;
scene.movePerFrame = scene._calcMoveHeight()
if (!AudioManager._meBuffer) {
AudioManager._bgmBuffer.play(false, 0);
}
AudioManager.updateCurrentBgm(bgm, 0);
scene.setState(StaffRollState.RUNNING);
};
if (webAudio.isReady()) {
onBgmLoaded.bind(this)();
} else {
webAudio.addLoadListener(onBgmLoaded.bind(this));
}
} else {
AudioManager.playBgm(bgm, 0);
this.setState(StaffRollState.RUNNING);
}
} else {
this.setState(StaffRollState.RUNNING);
}
}
update() {
super.update();
if (!!this.sprite) {
this.sprite.update();
}
switch (this._state) {
case StaffRollState.RUNNING: {
if (Input.isPressed(InputClass.INPUT_CLASS_CTRL)) {
this.currentY += MOVE_IN_SKIP;
} else {
this.currentY += this.movePerFrame;
}
const yEnd = Math.max(this.imageHeight - Graphics.height, 0);
if (this.currentY > yEnd) {
this.currentY = yEnd;
}
this.sprite.smoothScrollTo(0, this.currentY, 10);
if (this.currentY >= yEnd) {
AudioManager.fadeOutBgm(ENDING_WAIT);
this.setState(StaffRollState.ENDING);
}
break;
}
case StaffRollState.ENDING: {
this.endingCount++;
if (this.endingCount > ENDING_WAIT) {
this.setState(StaffRollState.END);
AudioManager.stopBgm();
this.fadeOutAll();
this.popScene();
PluginUtils.fireCommonEvent(param.event);
}
break;
}
default:
/* nothing to do */
break;
} // switch
}
stop() {
super.stop();
}
setState(newState) {
Logger.d(`Scene_StaffRole: setState old = ${this._state}, new = ${newState}`);
this._state = newState;
}
_calcMoveHeight() {
if (param.scrollWithMusic) {
const bgmFrame = this.duration * 60;
return this.imageHeight / bgmFrame;
} else {
return MOVE_NORMAL;
}
}
};
//========================================================================
// プラグインコマンド
//========================================================================
PluginManagerEx.registerCommand(script, 'startStaffRoll', args => {
SceneManager._scene.fadeOutAll();
SceneManager.push(Scene_StaffRoll);
});
})();