139 lines
4.4 KiB
JavaScript
139 lines
4.4 KiB
JavaScript
/**
|
|
* AMNESIA EFFECT PIPELINE & MANAGER
|
|
* Handles the visual distortion for memory loss sequences.
|
|
*
|
|
* USAGE:
|
|
* 1. Initialize in Scene: this.amnesia = new AmnesiaEffect(this);
|
|
* 2. Start effect: this.amnesia.start();
|
|
* 3. Fade out: this.amnesia.fadeOut(2000);
|
|
*/
|
|
|
|
class AmnesiaEffect {
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
this.pipeline = null;
|
|
this.vignette = null;
|
|
this.blurFX = null;
|
|
this.isActive = false;
|
|
|
|
// Register custom pipeline if not exists
|
|
if (!this.scene.renderer.pipelines.get('AmnesiaPipeline')) {
|
|
this.registerPipeline();
|
|
}
|
|
}
|
|
|
|
registerPipeline() {
|
|
// Simple heavy vignette + desaturation pipeline could go here
|
|
// For now, we will use Phaser's built-in PostFX for stability
|
|
// effectively wrapping them in this manager.
|
|
console.log('🌀 AmnesiaEffect: Manager initialized');
|
|
}
|
|
|
|
start(intensity = 1.0) {
|
|
if (this.isActive) return;
|
|
this.isActive = true;
|
|
|
|
const width = this.scene.cameras.main.width;
|
|
const height = this.scene.cameras.main.height;
|
|
|
|
// 1. BLUR CAMERA
|
|
// Note: PostFX requires Phaser 3.60+
|
|
if (this.scene.cameras.main.postFX) {
|
|
this.blurFX = this.scene.cameras.main.postFX.addBlur(2, 2, 2); // strength=2, quality=2
|
|
}
|
|
|
|
// 2. VIGNETTE OVERLAY (Heavy dark edges)
|
|
// We use a radial gradient texture or graphics because Phaser FX vignette can be subtle
|
|
// We want aggressive darkness for "tunnel vision"
|
|
this.vignette = this.scene.add.graphics();
|
|
this.vignette.setDepth(9999);
|
|
this.vignette.setScrollFactor(0);
|
|
|
|
this.vignette.fillStyle(0x000000, 1);
|
|
this.vignette.fillRect(0, 0, width, height);
|
|
|
|
// Create a mask to see through the center (tunnel vision)
|
|
const maskShape = this.scene.make.graphics();
|
|
maskShape.fillStyle(0xffffff);
|
|
maskShape.fillCircle(width / 2, height / 2, height * 0.4);
|
|
|
|
const mask = maskShape.createGeometryMask();
|
|
mask.setInvertAlpha(true);
|
|
this.vignette.setMask(mask);
|
|
|
|
// Pulse animation for the vignette (heartbeat effect)
|
|
this.scene.tweens.add({
|
|
targets: maskShape,
|
|
scale: 0.9,
|
|
duration: 1000,
|
|
yoyo: true,
|
|
repeat: -1,
|
|
ease: 'Sine.easeInOut'
|
|
});
|
|
|
|
// 3. COLOR TINT (Cold/Confused)
|
|
this.scene.cameras.main.setTint(0xcccccc); // Greyish
|
|
|
|
console.log('🌀 Amnesia Effect ACTIVATED');
|
|
}
|
|
|
|
fadeOut(duration = 2000) {
|
|
if (!this.isActive) return;
|
|
|
|
console.log(`🌀 Fading out Amnesia Effect (${duration}ms)`);
|
|
|
|
// Fade out vignette
|
|
if (this.vignette) {
|
|
this.scene.tweens.add({
|
|
targets: this.vignette,
|
|
alpha: 0,
|
|
duration: duration,
|
|
onComplete: () => {
|
|
this.vignette.destroy();
|
|
this.vignette = null;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Fade out blur
|
|
if (this.blurFX) {
|
|
this.scene.tweens.add({
|
|
targets: this.blurFX,
|
|
strength: 0,
|
|
duration: duration,
|
|
onComplete: () => {
|
|
if (this.scene.cameras.main.postFX) {
|
|
this.scene.cameras.main.postFX.remove(this.blurFX);
|
|
}
|
|
this.blurFX = null;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Restore Color
|
|
this.scene.tweens.add({
|
|
targets: this.scene.cameras.main,
|
|
zoom: 1, // Reset any zoom
|
|
duration: duration,
|
|
onUpdate: (tween) => {
|
|
const val = Math.floor(204 + (51 * tween.progress)); // 0xCC (204) to 0xFF (255)
|
|
const color = Phaser.Display.Color.GetColor(val, val, val);
|
|
this.scene.cameras.main.setTint(color);
|
|
},
|
|
onComplete: () => {
|
|
this.scene.cameras.main.clearTint();
|
|
this.isActive = false;
|
|
}
|
|
});
|
|
}
|
|
|
|
pulse(strength = 1.0) {
|
|
// Sudden headache flash
|
|
this.scene.cameras.main.shake(200, 0.005 * strength);
|
|
this.scene.cameras.main.flash(200, 255, 0, 0); // Red flash of pain
|
|
}
|
|
}
|
|
|
|
// Make globally available or export based on project structure
|
|
window.AmnesiaEffect = AmnesiaEffect;
|