/** * TwinBondSystem.js * * Sistem, ki občasno pošlje srhljiv telepatski signal (spomin/klic) od Ane. * Ekran naključno utripne vijolično in se izpiše skrit tekst v glavi Kaja. */ export default class TwinBondSystem { constructor(scene) { this.scene = scene; this.isActive = false; // Overlay za vijoličen blisk this.flashOverlay = scene.add.graphics() .setDepth(9999) .setScrollFactor(0); // Tekst na sredini zaslona const cx = scene.cameras.main.width / 2; const cy = scene.cameras.main.height / 2; this.messageText = scene.add.text(cx, cy - 100, '', { fontFamily: 'Courier New', fontSize: '42px', color: '#ff99ff', stroke: '#2b002b', strokeThickness: 8, align: 'center', fontStyle: 'bold' }) .setOrigin(0.5, 0.5) .setDepth(10000) .setScrollFactor(0) .setAlpha(0); // Nabor Aninih sporočil this.messages = [ "K a i . . . n a j d i m e . . .", "T u k a j d o l j e t e m a . . .", "N e o b u p a j . . . T w i n B o n d d e l u j e .", "K a i . . . b o l i m e . . .", "P a z i s e n o č i . . ." ]; // Tipka za testiranje (tipka T) this.keyT = scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.T); } update(time, delta) { // Testni sprožilec if (Phaser.Input.Keyboard.JustDown(this.keyT) && !this.isActive) { this.triggerBond(); } // Naključno sprožanje (zelo majhna možnost ob igranju) // 1 na 10,000 frejmov (~ vsake 3-5 minut) if (Math.random() < 0.0001 && !this.isActive) { // Samo če je zunaj spanja this.triggerBond(); } } triggerBond() { this.isActive = true; // Oddaj event za AccessibilityManager (za Deaf Mode Purple HUD glow) if (this.scene.game) { this.scene.game.events.emit('twinBondPulse'); } // Zaustavi Kaja za kratek čas (šok) if (this.scene.kai) { this.scene.kai.canMove = false; this.scene.kai.setVelocity(0, 0); } // 1. Zvok (Web Audio API srhljiv glitch freq) this._playGlitchSound(); // 2. Narisemo purple flash, ki pokrije zaslon const W = this.scene.cameras.main.width; const H = this.scene.cameras.main.height; this.flashOverlay.clear(); let alpha = this.scene.accessState?.autismMode ? 0.2 : 0.85; // Omehčan za avtizem this.flashOverlay.fillStyle(0x3a0055, alpha); // Temno vijolična this.flashOverlay.fillRect(0, 0, W, H); // Skrijemo čez 0.15s this.scene.time.delayedCall(150, () => { this.flashOverlay.clear(); }); // 3. Izberi random text in naredi typewriter const text = Phaser.Utils.Array.GetRandom(this.messages); this.messageText.setText(''); this.messageText.setAlpha(1); let index = 0; const typeTimer = this.scene.time.addEvent({ delay: 80, repeat: text.length - 1, callback: () => { this.messageText.setText(text.substring(0, index + 1)); index++; } }); // 4. Fade out text in enable movement po 3 sekundah this.scene.time.delayedCall(3000, () => { this.scene.tweens.add({ targets: this.messageText, alpha: 0, duration: 1000, onComplete: () => { this.isActive = false; if (this.scene.kai) { this.scene.kai.canMove = true; } } }); }); } _playGlitchSound() { if (!this.scene.sound.context) return; const ctx = this.scene.sound.context; const osc = ctx.createOscillator(); const gain = ctx.createGain(); // Srhljiv nizek zvok s frekvenčno modulacijo osc.type = 'sawtooth'; osc.frequency.setValueAtTime(120, ctx.currentTime); osc.frequency.linearRampToValueAtTime(40, ctx.currentTime + 1.5); gain.gain.setValueAtTime(0.3, ctx.currentTime); gain.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 1.5); osc.connect(gain); gain.connect(ctx.destination); osc.start(); osc.stop(ctx.currentTime + 1.5); } }