boardgame-phaser/packages/framework/src/scenes/FadeScene.ts

84 lines
2.0 KiB
TypeScript

import { ReactiveScene } from "./ReactiveScene";
export interface FadeSceneData {
[key: string]: unknown;
}
/**
* 处理淡入淡出到黑色的过渡场景
*/
export class FadeScene extends ReactiveScene<FadeSceneData> {
private overlay!: Phaser.GameObjects.Rectangle;
private isFading = false;
constructor() {
super(FADE_SCENE_KEY);
}
create(): void {
super.create();
// 创建黑色遮罩层,覆盖整个游戏区域
const game = this.game;
this.overlay = this.add
.rectangle(0, 0, game.scale.width, game.scale.height, 0x000000, 1)
.setOrigin(0)
.setAlpha(1)
.setDepth(999999)
.setInteractive({ useHandCursor: false });
// 防止遮罩阻挡输入
this.overlay.disableInteractive();
}
/**
* 淡入(从黑色到透明)
* @param duration 动画时长(毫秒)
*/
fadeIn(duration = 300): Promise<void> {
return this.fadeTo(0, duration);
}
/**
* 淡出(从透明到黑色)
* @param duration 动画时长(毫秒)
*/
fadeOut(duration = 300): Promise<void> {
return this.fadeTo(1, duration);
}
/**
* 淡入淡出到指定透明度
*/
private fadeTo(targetAlpha: number, duration: number): Promise<void> {
// 如果 overlay 还未初始化,直接返回 resolved promise
if (!this.overlay) {
console.warn("FadeScene: overlay 未初始化,跳过过渡动画");
return Promise.resolve();
}
if (this.isFading) {
console.warn("FadeScene: 正在进行过渡动画");
}
this.isFading = true;
this.overlay.setAlpha(targetAlpha === 1 ? 0 : 1);
return new Promise<void>((resolve) => {
this.tweens.add({
targets: this.overlay,
alpha: targetAlpha,
duration,
ease: "Linear",
onComplete: () => {
this.isFading = false;
resolve();
},
});
});
}
}
// 导出常量供 PhaserGame 使用
export const FADE_SCENE_KEY = "__fade__";