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

84 lines
2.0 KiB
TypeScript
Raw Normal View History

import { ReactiveScene } from "./ReactiveScene";
2026-04-12 16:52:53 +08:00
export interface FadeSceneData {
[key: string]: unknown;
2026-04-12 16:52:53 +08:00
}
/**
*
*/
export class FadeScene extends ReactiveScene<FadeSceneData> {
private overlay!: Phaser.GameObjects.Rectangle;
private isFading = false;
2026-04-12 16:52:53 +08:00
constructor() {
super(FADE_SCENE_KEY);
}
2026-04-12 16:52:53 +08:00
create(): void {
super.create();
2026-04-12 16:52:53 +08:00
// 创建黑色遮罩层,覆盖整个游戏区域
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 });
2026-04-12 16:52:53 +08:00
// 防止遮罩阻挡输入
this.overlay.disableInteractive();
}
2026-04-12 16:52:53 +08:00
/**
*
* @param duration
*/
fadeIn(duration = 300): Promise<void> {
return this.fadeTo(0, duration);
}
2026-04-12 16:52:53 +08:00
/**
*
* @param duration
*/
fadeOut(duration = 300): Promise<void> {
return this.fadeTo(1, duration);
}
2026-04-12 16:52:53 +08:00
/**
*
*/
private fadeTo(targetAlpha: number, duration: number): Promise<void> {
// 如果 overlay 还未初始化,直接返回 resolved promise
if (!this.overlay) {
console.warn("FadeScene: overlay 未初始化,跳过过渡动画");
return Promise.resolve();
}
2026-04-12 18:02:10 +08:00
if (this.isFading) {
console.warn("FadeScene: 正在进行过渡动画");
}
2026-04-12 16:52:53 +08:00
this.isFading = true;
this.overlay.setAlpha(targetAlpha === 1 ? 0 : 1);
2026-04-12 16:52:53 +08:00
return new Promise<void>((resolve) => {
this.tweens.add({
targets: this.overlay,
alpha: targetAlpha,
duration,
ease: "Linear",
onComplete: () => {
this.isFading = false;
resolve();
},
});
});
}
2026-04-12 16:52:53 +08:00
}
// 导出常量供 PhaserGame 使用
export const FADE_SCENE_KEY = "__fade__";