// 🎬 INTRO SEQUENCE - FINAL HYTALE TEXT MODE (69s) // "Text Only + Hytale Visuals + 3.0s/slide" // Created: January 19, 2026 class IntroScene extends Phaser.Scene { constructor() { super({ key: 'IntroScene' }); } preload() { console.log("📖 Loading Intro Visuals (Text Only Mode)..."); // --- VISUALS --- 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 (Volume 0.6 steady) if (!this.sound.get('main_theme')) { this.music = this.sound.add('main_theme', { volume: 0.6, loop: true }); this.music.play(); } else { this.music = this.sound.get('main_theme'); if (!this.music.isPlaying) this.music.play(); this.music.setVolume(0.6); } this.imageLayer = this.add.container(0, 0); this.currentImage = null; // HYTALE UI (Clean) const boxWidth = width * 0.9; const boxHeight = 100; this.subtitleBg = this.add.graphics(); this.subtitleBg.fillStyle(0x000000, 0.75); this.subtitleBg.fillRoundedRect((width - boxWidth) / 2, height - 120, boxWidth, boxHeight, 10); this.subtitle = this.add.text(width / 2, height - 120 + (boxHeight / 2), "", { fontFamily: 'Verdana, Arial, sans-serif', fontSize: '24px', color: '#FFFFFF', align: 'center', wordWrap: { width: boxWidth - 40 }, stroke: '#000000', strokeThickness: 2, shadow: { offsetX: 1, offsetY: 1, color: '#000000', blur: 2, stroke: true, fill: true } }).setOrigin(0.5); this.playTextIntro(); // SKIP this.add.text(width - 20, 20, "SKIP >>", { fontSize: '18px', fontFamily: 'Verdana' }) .setOrigin(1, 0) .setInteractive({ useHandCursor: true }) .on('pointerdown', () => this.finishIntro()); } playTextIntro() { const TIME_PER_IMAGE = 3000; 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(1500, () => this.finishIntro()); return; } const imgKey = `story_${currentIndex + 1}`; // 1. Image this.showImageHytaleStyle(imgKey, TIME_PER_IMAGE); // 2. Text (No audio manipulation) this.typewriterText(story[currentIndex], TIME_PER_IMAGE); currentIndex++; this.time.delayedCall(TIME_PER_IMAGE, nextSlide); }; console.log(`🎬 Playing Text-Only Intro: ${SLIDE_COUNT} slides.`); nextSlide(); } showImageHytaleStyle(key, duration) { const { width, height } = this.cameras.main; if (this.currentImage) { const old = this.currentImage; this.tweens.add({ targets: old, alpha: 0, duration: 800, onComplete: () => old.destroy() }); } 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: 800, ease: 'Linear' }); const scaleBase = img.scaleX; img.setScale(scaleBase * 1.02); this.tweens.add({ targets: img, scaleX: scaleBase * 1.05, scaleY: img.scaleY * (1.05 / 1.02), duration: duration + 1000, ease: 'Linear' }); } typewriterText(text, duration) { this.subtitle.setText(""); const speed = 45; let i = 0; if (this.textTimer) this.textTimer.remove(); this.textTimer = this.time.addEvent({ delay: speed, 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('🎬 Text Intro Complete -> Waking Up'); if (this.music) { this.tweens.add({ targets: this.music, volume: 0.3, duration: 3000 }); } this.cameras.main.fadeOut(1500, 0, 0, 0, (camera, progress) => { if (progress === 1) { this.scene.start('GameScene', { startMode: 'AMNESIA_WAKEUP', backgroundMusic: this.music }); } }); } }