// 🎬 INTRO SEQUENCE - CHILL STORY MODE (80s) // "Zelo umirjen tempo + Mehak prehod 1.5s + Glasba Fade 4s" // Created: January 19, 2026 class IntroScene extends Phaser.Scene { constructor() { super({ key: 'IntroScene' }); } preload() { console.log("📖 Loading Chill Story Assets (23 Slides)..."); // MAPPING: Story Sentence Index -> Image File this.load.image('story_1', 'assets/slike/intro/montage/01_Sreca:/assets_BACKUP_20260112_064319_references_intro_shots_kai_ana_twins_childhood.png'); this.load.image('story_2', 'assets/slike/intro/montage/01_Sreca:/assets_BACKUP_20260112_064319_references_intro_shots_ana_barbershop_dreads.png'); this.load.image('story_3', 'assets/slike/intro/montage/01_Sreca:/assets_BACKUP_20260112_064319_references_intro_shots_kai_first_dreads_family.png'); this.load.image('story_4', 'assets/slike/intro/montage/01_Sreca:/assets_BACKUP_20260112_064319_references_intro_shots_otac_longboard_pier.png'); this.load.image('story_5', 'assets/slike/intro/montage/01_Sreca:/assets_BACKUP_20260112_064319_references_intro_shots_birthday_cake_rd.png'); this.load.image('story_6', 'assets/slike/intro/montage/01_Sreca:/assets_BACKUP_20260112_064319_references_intro_shots_family_portrait_punk_complete.png'); this.load.image('story_7', 'assets/slike/intro/montage/02_Kaos:/assets_BACKUP_20260112_064319_references_intro_shots_virus_xnoir_microscope.png'); this.load.image('story_8', 'assets/slike/intro/montage/02_Kaos:/05_Chernobyl_assets_BACKUP_20260112_064319_references_intro_shots_virus_city_aerial.png'); this.load.image('story_9', 'assets/slike/intro/montage/02_Kaos:/assets_BACKUP_20260112_064319_references_intro_shots_zombie_silhouettes_panic.png'); this.load.image('story_10', 'assets/slike/intro/montage/02_Kaos:/05_Chernobyl_assets_BACKUP_20260112_064319_references_intro_shots_chaos_streets_apocalypse.png'); this.load.image('story_11', 'assets/slike/intro/montage/02_Kaos:/assets_images_intro_sequence_zombie_silhouettes_panic_dreamy.png'); this.load.image('story_12', 'assets/slike/intro/montage/03_Locitev:/assets_BACKUP_20260112_064319_references_intro_shots_ana_taken_military.png'); this.load.image('story_13', 'assets/slike/intro/montage/03_Locitev:/assets_BACKUP_20260112_064319_references_intro_shots_parents_transparent_ghosts.png'); this.load.image('story_14', 'assets/slike/intro/montage/03_Locitev:/assets_BACKUP_20260112_064319_references_intro_shots_ana_taken_military.png'); this.load.image('story_15', 'assets/slike/intro/montage/01_Sreca:/assets_images_intro_sequence_otac_longboard_pier_dreamy.png'); this.load.image('story_16', 'assets/slike/intro/montage/04_Amnesia:/assets_BACKUP_20260112_064319_references_intro_shots_kai_alone_basement.png'); this.load.image('story_17', 'assets/slike/intro/montage/03_Locitev:/assets_BACKUP_20260112_064319_references_intro_shots_gronk_doorway_silhouette.png'); this.load.image('story_18', 'assets/slike/intro/montage/04_Amnesia:/10_Volcanic_Zone_assets_BACKUP_20260112_064319_references_intro_shots_ana_memory_flash_purple.png'); this.load.image('story_19', 'assets/slike/intro/montage/03_Locitev:/MOJE_SLIKE_KONCNA_ostalo_parents_transparent_ghosts_dreamy.png'); this.load.image('story_20', 'assets/slike/intro/montage/01_Sreca:/assets_images_intro_sequence_birthday_cake_rd_dreamy.png'); this.load.image('story_21', 'assets/slike/intro/montage/04_Amnesia:/10_Volcanic_Zone_assets_BACKUP_20260112_064319_references_intro_shots_ana_memory_flash_purple.png'); this.load.image('story_22', 'assets/slike/intro/montage/01_Sreca:/ana_barbershop_dreads_dreamy.png'); this.load.image('story_23', 'assets/slike/intro/montage/04_Amnesia:/assets_BACKUP_20260112_064319_references_intro_shots_kai_bedroom_wakeup.png'); // AUDIO this.load.audio('main_theme', 'assets/audio/music/main_theme.mp3'); } create() { const { width, height } = this.cameras.main; this.cameras.main.setBackgroundColor('#000000'); // MUSIC if (!this.sound.get('main_theme')) { this.music = this.sound.add('main_theme', { volume: 0.8, loop: true }); this.music.play(); } else { this.music = this.sound.get('main_theme'); if (!this.music.isPlaying) this.music.play(); } // VISUALS this.imageLayer = this.add.container(0, 0); this.currentImage = null; // TEXT BOX const boxWidth = width * 0.9; this.subtitleBg = this.add.rectangle(width / 2, height - 100, boxWidth, 120, 0x000000, 0.8).setOrigin(0.5); this.subtitle = this.add.text(width / 2, height - 100, "", { fontFamily: 'Courier New', fontSize: '22px', color: '#e0e0e0', align: 'center', wordWrap: { width: boxWidth - 40 } }).setOrigin(0.5); // PLAY this.playChillIntro(); // SKIP this.add.text(width - 20, 20, "SKIP >>", { fontSize: '20px', color: '#666' }) .setOrigin(1, 0) .setInteractive({ useHandCursor: true }) .on('pointerdown', () => this.finishIntro()); } playChillIntro() { // TIMING: 3.5s per image (Chill Pacing) // Total: ~80s const TIME_PER_IMAGE = 3500; const SLIDE_COUNT = 23; const story = [ "Vse se je začelo tukaj. Naš dom, preden so barve zbledele.", "Ana si je prvič pobarvala lase na tisto njeno noro pink barvo.", "Jaz sem si končno dal naredit drede. Stari naju je samo debelo gledal.", "Ati naju je naučil furat longboard po teh ulicah.", "Tisti rojstni dan... torta je bila zanič, ampak mi smo se režali.", "Bili smo ekipa. Nič nas ni moglo ustaviti. Tako smo mislili.", "Potem so prišla prva opozorila. 'Virus Protocol', so rekli.", "Nihče ni verjel, dokler se ni nad mesto spustila zelena megla.", "Vse je postalo strupeno. Zrak, voda... ljudje.", "Mesto je padlo v enem dnevu. Kaos, kakršnega ne vidiš niti v filmih.", "Bežali smo, ampak poti ven ni bilo več.", "Vojaki so zaprli vse prehode. Postali smo podgane v kletki.", "Potem so začeli ločevati družine. Kričanje, ki ga še zdaj slišim.", "Zgrabili so Ano. Moja mala sestra... nisem je mogel držati.", "Oče je stopil pred njih. Bil je junak, dokler ni postal senca.", "Mama me je potisnila v klet. 'Preživi, Kai!', so bile zadnje besede.", "Videl sem tisto postavo v vratih. Gronk? Ali samo privid?", "Vijoličen dim je zapolnil sobo. Vse je postalo težko.", "Spomini so začeli polzeti stran. Kot pesek med prsti.", "Pozabil sem obraze. Pozabil sem imena. Razen enega.", "Ana. Njen krik še vedno odmeva v tej temi.", "Obljubim ti, sestra. Našel te bom, ne glede na vse.", "Zdaj je čas, da se zbudim. Igra se začne..." ]; let currentIndex = 0; const nextSlide = () => { if (currentIndex >= SLIDE_COUNT) { this.time.delayedCall(2000, () => this.finishIntro()); return; } // 1. Image const imgKey = `story_${currentIndex + 1}`; this.showImageSharp(imgKey, TIME_PER_IMAGE); // 2. Text this.typewriterText(story[currentIndex], TIME_PER_IMAGE); currentIndex++; // Wait for next slide this.time.delayedCall(TIME_PER_IMAGE, nextSlide); }; console.log(`🎬 Playing Chill Story: ${SLIDE_COUNT} slides, ${TIME_PER_IMAGE}ms each.`); nextSlide(); } showImageSharp(key, duration) { const { width, height } = this.cameras.main; // Old fade OUT (Soft 1.5s) if (this.currentImage) { const old = this.currentImage; this.tweens.add({ targets: old, alpha: 0, duration: 1500, onComplete: () => old.destroy() }); } // New fade IN (Soft 1.5s) const img = this.add.image(width / 2, height / 2, key).setAlpha(0); this.fitImage(img); this.imageLayer.add(img); this.currentImage = img; this.tweens.add({ targets: img, alpha: 1, duration: 1500, ease: 'Sine.easeInOut' }); // Slow cinematic pan const scaleBase = img.scaleX; img.setScale(scaleBase * 1.02); this.tweens.add({ targets: img, scaleX: scaleBase * 1.06, scaleY: img.scaleY * (1.06 / 1.02), duration: duration + 2000, ease: 'Linear' }); } typewriterText(text, duration) { this.subtitle.setText(""); // Very slow typewriter // Calculate speed to finish text in ~70% of 3.5s (approx 2450ms) const targetTimeConfig = duration * 0.7; const speed = Math.max(50, targetTimeConfig / text.length); // Limit speed to minimum 80ms per char for CHILL VIBE (user request 0.08f) const chillSpeed = Math.max(speed, 80); let i = 0; if (this.textTimer) this.textTimer.remove(); this.textTimer = this.time.addEvent({ delay: chillSpeed, repeat: text.length - 1, callback: () => { this.subtitle.text += text[i]; i++; } }); } fitImage(sprite) { const screenW = this.cameras.main.width; const screenH = this.cameras.main.height; const scaleX = screenW / sprite.width; const scaleY = screenH / sprite.height; const scale = Math.max(scaleX, scaleY); sprite.setScale(scale); } finishIntro() { console.log('🎬 Chill Story Complete -> Waking Up'); // 4s Music Fade (User Request) if (this.music) { this.tweens.add({ targets: this.music, volume: 0.3, duration: 4000 }); } this.cameras.main.fadeOut(2000, 0, 0, 0, (camera, progress) => { if (progress === 1) { this.scene.start('GameScene', { startMode: 'AMNESIA_WAKEUP', backgroundMusic: this.music }); } }); } }