🎬🔥 60-SECOND EPIC INTRO - COMPLETE IMPLEMENTATION!

 COMPLETE 60-SECOND CINEMATIC:
- ALL 20 intro shots integrated
- 4 emotional phases (Childhood→Virus→Amnesia→Awakening)
- Perfect timing (3s per shot)
- Smooth transitions with glitch effects

 FULL VOICE INTEGRATION:
- 12 Kai voices (complete narrative arc)
- 8 Ana voices (emotional journey)
- 1 Gronk voice (wake-up call)
- playVoice() function for audio triggers
- Synchronized with shot timing

 4 PHASES BREAKDOWN:
**Phase 1 (0-15s): HAPPY CHILDHOOD**
- 5 shots: Family, Father, Dreads, Barbershop, Birthday
- Kai + Ana voices: 'Bili smo... celi.'
- Warm colors, nostalgic

**Phase 2 (15-30s): THE VIRUS**
- 5 shots: Virus, Chaos, Zombies, Parents, Ana Taken
- Dramatic voices: 'KAI! NE POZABI ME!'
- Red/green toxic, glitch, camera shake

**Phase 3 (30-45s): THE AMNESIA**
- 5 shots: Alone, Young, Adult, Elder, Memory
- Aging timeline: 'Leta so minila...'
- Dark, mysterious

**Phase 4 (45-60s): THE AWAKENING**
- 5 shots: Bedroom, Gronk, Memory, Twins, Fade
- Final resolve: '...tudi če mi vzame celo življenje.'
- Fade to GameScene

🎨 VISUAL EFFECTS:
- Polaroid frames (65% size, floating)
- VHS scanlines + noise
- Chromatic aberration (RGB flash)
- Warm/red/toxic color tints
- Camera shake + strobe
- Glitch transitions

🎵 AUDIO SYSTEM:
- Ambient noir music (loop)
- Voice auto-stop on new voice
- Skip stops all audio
- Volume balanced (ambient 0.2, voices 0.8)

⏱️  TOTAL DURATION: 60 seconds exactly
🎯 SKIP: Available after 5s (X or SPACE)
🔄 TRANSITIONS: Fade to GameScene at 60s

READY FOR EPIC TEST! 🎆
This commit is contained in:
2026-01-10 13:59:39 +01:00
parent d383483d96
commit d9f40d016d

View File

@@ -1,7 +1,8 @@
// 🎬 INTRO SEQUENCE - VERSION B (30-45 seconds Fast-Cut)
// "From Colors to Darkness" - Kai's Amnesia Awakening
// 🎬 INTRO SEQUENCE - 60-SECOND EPIC CINEMATIC
// "From Colors to Darkness" - Complete Story
// Created: January 10, 2026
// Style: Style 32 Dark-Chibi Noir with ADHD energy
// Style: Style 32 Dark-Chibi Noir + Polaroid + VHS
// Voices: Kai (Rok) + Ana (Petra) + Gronk (Rok deep)
class IntroScene extends Phaser.Scene {
constructor() {
@@ -9,64 +10,86 @@ class IntroScene extends Phaser.Scene {
this.skipEnabled = false;
this.currentPhase = 0;
this.skipPrompt = null;
this.currentShot = null;
this.currentPolaroid = null;
this.currentText = null;
this.vhsNoise = null;
this.scanlines = null;
this.ambientAudio = null;
this.projectorAudio = null;
this.currentVoice = null;
}
preload() {
console.log('🎬 IntroScene: Loading assets...');
console.log('🎬 IntroScene: Loading EPIC 60s assets...');
// Base path for intro shots
const introPath = 'assets/references/intro_shots/';
// PHASE 1: HAPPY FAMILY (5 shots)
this.load.image('intro_otac_longboard', introPath + 'otac_longboard_pier.png');
this.load.image('intro_ana_barbershop', introPath + 'ana_barbershop_dreads.png');
this.load.image('intro_twins_childhood', introPath + 'kai_ana_twins_childhood.png');
this.load.image('intro_birthday_cake', introPath + 'birthday_cake_rd.png');
// ALL 20 INTRO SHOTS
this.load.image('intro_family_portrait', introPath + 'family_portrait_punk_complete.png');
// PHASE 2: THE COLLAPSE (4 shots)
this.load.image('intro_otac_longboard', introPath + 'otac_longboard_pier.png');
this.load.image('intro_kai_dreads', introPath + 'kai_first_dreads_family.png');
this.load.image('intro_ana_barbershop', introPath + 'ana_barbershop_dreads.png');
this.load.image('intro_birthday_cake', introPath + 'birthday_cake_rd.png');
this.load.image('intro_virus', introPath + 'virus_xnoir_microscope.png');
this.load.image('intro_zombies', introPath + 'zombie_silhouettes_panic.png');
this.load.image('intro_chaos', introPath + 'chaos_streets_apocalypse.png');
this.load.image('intro_zombies', introPath + 'zombie_silhouettes_panic.png');
this.load.image('intro_parents_ghosts', introPath + 'parents_transparent_ghosts.png');
this.load.image('intro_ana_taken', introPath + 'ana_taken_military.png');
// PHASE 3: AMNESIA WAKE-UP (4 shots)
this.load.image('intro_bedroom', introPath + 'kai_bedroom_wakeup.png');
this.load.image('intro_kai_alone', introPath + 'kai_alone_basement.png');
this.load.image('intro_kai_young', introPath + 'kai_young_timelapse.png');
this.load.image('intro_kai_adult', introPath + 'kai_adult_35_timelapse.png');
this.load.image('intro_kai_elder', introPath + 'kai_elder_50_timelapse.png');
this.load.image('intro_ana_memory', introPath + 'ana_memory_flash_purple.png');
this.load.image('intro_bedroom', introPath + 'kai_bedroom_wakeup.png');
this.load.image('intro_gronk', introPath + 'gronk_doorway_silhouette.png');
this.load.image('intro_twins_childhood', introPath + 'kai_ana_twins_childhood.png');
// 🎵 AUDIO (Optional - with safe loading)
// 🎵 AMBIENT MUSIC
this.loadAudioSafe('noir_ambience', 'assets/audio/ambient/noir_ambience.mp3');
this.loadAudioSafe('projector_loop', 'assets/audio/ambient/projector_loop.mp3');
// Voice triggers (placeholders)
this.loadAudioSafe('audio_kai_memory_01', 'assets/audio/voiceover/kai_memory_01.mp3');
this.loadAudioSafe('audio_kai_memory_02', 'assets/audio/voiceover/kai_memory_02.mp3');
this.loadAudioSafe('audio_kai_memory_03', 'assets/audio/voiceover/kai_memory_03.mp3');
// 🎤 KAI VOICES (12 total)
this.loadAudioSafe('kai_01', 'assets/audio/voiceover/kai_01_beginning.mp3');
this.loadAudioSafe('kai_02', 'assets/audio/voiceover/kai_02_father.mp3');
this.loadAudioSafe('kai_03', 'assets/audio/voiceover/kai_03_whole.mp3');
this.loadAudioSafe('kai_04', 'assets/audio/voiceover/kai_04_virus.mp3');
this.loadAudioSafe('kai_05', 'assets/audio/voiceover/kai_05_zombies.mp3');
this.loadAudioSafe('kai_06', 'assets/audio/voiceover/kai_06_alone.mp3');
this.loadAudioSafe('kai_07', 'assets/audio/voiceover/kai_07_years.mp3');
this.loadAudioSafe('kai_08', 'assets/audio/voiceover/kai_08_memory.mp3');
this.loadAudioSafe('kai_09', 'assets/audio/voiceover/kai_09_fog.mp3');
this.loadAudioSafe('kai_10', 'assets/audio/voiceover/kai_10_wake.mp3');
this.loadAudioSafe('kai_11', 'assets/audio/voiceover/kai_11_find.mp3');
this.loadAudioSafe('kai_12', 'assets/audio/voiceover/kai_12_lifetime.mp3');
// 🎤 ANA VOICES (8 total)
this.loadAudioSafe('ana_01', 'assets/audio/voiceover/ana_01_ride.mp3');
this.loadAudioSafe('ana_02', 'assets/audio/voiceover/ana_02_immortal.mp3');
this.loadAudioSafe('ana_03', 'assets/audio/voiceover/ana_03_whole.mp3');
this.loadAudioSafe('ana_04', 'assets/audio/voiceover/ana_04_changed.mp3');
this.loadAudioSafe('ana_05', 'assets/audio/voiceover/ana_05_parents.mp3');
this.loadAudioSafe('ana_06', 'assets/audio/voiceover/ana_06_scream.mp3');
this.loadAudioSafe('ana_07', 'assets/audio/voiceover/ana_07_truth.mp3');
this.loadAudioSafe('ana_08', 'assets/audio/voiceover/ana_08_two.mp3');
// 🎤 GRONK VOICE
this.loadAudioSafe('gronk_01', 'assets/audio/voiceover/gronk_01_wake.mp3');
}
loadAudioSafe(key, path) {
try {
this.load.audio(key, path);
} catch (error) {
console.warn(`⚠️ Audio skipped: ${key} (file not found)`);
console.warn(`⚠️ Audio skipped: ${key}`);
}
}
create() {
console.log('🎬 IntroScene: Starting intro sequence...');
console.log('🎬 IntroScene: Starting 60-SECOND EPIC...');
// Black background
this.cameras.main.setBackgroundColor('#000000');
// 🎵 Start ambient audio (if available)
// 🎵 Start ambient audio
this.startAmbientAudio();
// 📺 Create VHS overlay effects
@@ -82,49 +105,28 @@ class IntroScene extends Phaser.Scene {
});
// Start Phase 1
this.playPhase1HappyFamily();
}
setupSkipControls() {
// Keyboard skip (X key or SPACE)
this.input.keyboard.on('keydown-X', () => this.skipIntro());
this.input.keyboard.on('keydown-SPACE', () => this.skipIntro());
// Mouse/touch skip (click anywhere)
this.input.on('pointerdown', () => {
if (this.skipEnabled) {
this.skipIntro();
}
});
this.playPhase1HappyChildhood();
}
startAmbientAudio() {
// Noir ambience (constant low drone)
try {
if (this.cache.audio.exists('noir_ambience')) {
this.ambientAudio = this.sound.add('noir_ambience', { volume: 0.15, loop: true });
this.ambientAudio = this.sound.add('noir_ambience', {
volume: 0.2,
loop: true
});
this.ambientAudio.play();
}
} catch (e) {
console.warn('⚠️ Ambient audio not available');
}
// Projector sound (old film aesthetic)
try {
if (this.cache.audio.exists('projector_loop')) {
this.projectorAudio = this.sound.add('projector_loop', { volume: 0.2, loop: true });
this.projectorAudio.play();
}
} catch (e) {
console.warn('⚠️ Projector audio not available');
}
}
createVHSEffects() {
const width = this.cameras.main.width;
const height = this.cameras.main.height;
// VHS Scanlines (horizontal lines)
// VHS Scanlines
this.scanlines = this.add.graphics();
this.scanlines.setDepth(900);
@@ -133,7 +135,7 @@ class IntroScene extends Phaser.Scene {
this.scanlines.fillRect(0, y, width, 2);
}
// VHS Noise overlay (subtle static)
// VHS Noise overlay
this.vhsNoise = this.add.rectangle(
width / 2,
height / 2,
@@ -144,7 +146,7 @@ class IntroScene extends Phaser.Scene {
);
this.vhsNoise.setDepth(901);
// Animate noise (flicker)
// Animate noise
this.tweens.add({
targets: this.vhsNoise,
alpha: { from: 0.01, to: 0.05 },
@@ -154,8 +156,19 @@ class IntroScene extends Phaser.Scene {
});
}
setupSkipControls() {
this.input.keyboard.on('keydown-X', () => this.skipIntro());
this.input.keyboard.on('keydown-SPACE', () => this.skipIntro());
this.input.on('pointerdown', () => {
if (this.skipEnabled) {
this.skipIntro();
}
});
}
showSkipPrompt() {
if (this.skipPrompt) return; // Already showing
if (this.skipPrompt) return;
const width = this.cameras.main.width;
const height = this.cameras.main.height;
@@ -176,7 +189,6 @@ class IntroScene extends Phaser.Scene {
this.skipPrompt.setAlpha(0.7);
this.skipPrompt.setDepth(1000);
// Pulse animation
this.tweens.add({
targets: this.skipPrompt,
alpha: { from: 0.7, to: 1.0 },
@@ -191,7 +203,9 @@ class IntroScene extends Phaser.Scene {
console.log('⏭️ IntroScene: Skipped by user');
// Stop all tweens and timers
// Stop all
if (this.ambientAudio) this.ambientAudio.stop();
if (this.currentVoice) this.currentVoice.stop();
this.tweens.killAll();
this.time.removeAllEvents();
@@ -202,277 +216,162 @@ class IntroScene extends Phaser.Scene {
});
}
playPhase1HappyFamily() {
// PHASE 1: HAPPY FAMILY MEMORIES (0-15s)
console.log('🎬 Phase 1: Happy Family');
playVoice(key) {
try {
if (this.cache.audio.exists(key)) {
if (this.currentVoice) this.currentVoice.stop();
this.currentVoice = this.sound.add(key, { volume: 0.8 });
this.currentVoice.play();
}
} catch (e) {
console.warn(`⚠️ Voice ${key} not available`);
}
}
// ═══════════════════════════════════════════════════════════
// PHASE 1: HAPPY CHILDHOOD (0-15s)
// ═══════════════════════════════════════════════════════════
playPhase1HappyChildhood() {
console.log('🎬 Phase 1: Happy Childhood (0-15s)');
this.currentPhase = 1;
const width = this.cameras.main.width;
const height = this.cameras.main.height;
// Shot 1 (0-3s): Family Portrait + Kai voice
this.showShot('intro_family_portrait', 0, 3000, { warm: true });
this.time.delayedCall(200, () => this.playVoice('kai_01')); // "Vse se je začelo..."
// Text overlay
const text1 = this.add.text(
width / 2,
height - 80,
'Nekoč smo imeli barve...',
{
fontFamily: 'Courier New',
fontSize: '24px',
fill: '#ffffff',
stroke: '#00ffff',
strokeThickness: 1,
shadow: {
offsetX: 2,
offsetY: 2,
color: '#ff00ff',
blur: 5,
stroke: false,
fill: true
}
}
);
text1.setOrigin(0.5);
text1.setAlpha(0);
text1.setDepth(100);
// Shot 2 (3-6s): Otac Longboard + Kai voice
this.showShot('intro_otac_longboard', 3000, 6000, { warm: true });
this.time.delayedCall(3200, () => this.playVoice('kai_02')); // "Oče me je učil..."
this.tweens.add({
targets: text1,
alpha: 1,
duration: 1000,
delay: 500
});
// Shot 3 (6-9s): Kai Dreads + Ana voice
this.showShot('intro_kai_dreads', 6000, 9000, { warm: true });
this.time.delayedCall(6200, () => this.playVoice('ana_01')); // "...ampak divja vožnja..."
// Shots sequence - fast cuts (~3s each)
this.showShot('intro_otac_longboard', 0, 3000, { warm: true });
this.showShot('intro_ana_barbershop', 3000, 6000, { warm: true });
this.showShot('intro_twins_childhood', 6000, 9000, { warm: true, clear: true }); // CLEAREST
this.showShot('intro_birthday_cake', 9000, 12000, { warm: true });
this.showShot('intro_family_portrait', 12000, 15000, { warm: true, freeze: true });
// Shot 4 (9-12s): Ana Barbershop + Ana voice
this.showShot('intro_ana_barbershop', 9000, 12000, { warm: true });
this.time.delayedCall(9200, () => this.playVoice('ana_02')); // "Bili smo neustavljivi..."
// Shot 5 (12-15s): Birthday Cake + Both voices
this.showShot('intro_birthday_cake', 12000, 15000, { warm: true });
this.time.delayedCall(12200, () => this.playVoice('kai_03')); // "Bili smo... celi."
// Transition to Phase 2
this.time.delayedCall(14500, () => {
this.tweens.add({
targets: text1,
alpha: 0,
duration: 500
});
});
this.time.delayedCall(15000, () => {
text1.destroy();
this.playPhase2TheCollapse();
});
this.time.delayedCall(15000, () => this.playPhase2TheVirus());
}
playPhase2TheCollapse() {
// PHASE 2: THE COLLAPSE (15-30s)
console.log('🎬 Phase 2: The Collapse');
// ═══════════════════════════════════════════════════════════
// PHASE 2: THE VIRUS (15-30s)
// ═══════════════════════════════════════════════════════════
playPhase2TheVirus() {
console.log('🎬 Phase 2: The Virus (15-30s)');
this.currentPhase = 2;
const width = this.cameras.main.width;
const height = this.cameras.main.height;
// Shot 6 (15-18s): Virus + Kai voice
this.showShot('intro_virus', 15000, 18000, { toxic: true, glitch: true });
this.time.delayedCall(15200, () => this.playVoice('kai_04')); // "Potem je prišel X-Noir..."
// Text overlay
const text2 = this.add.text(
width / 2,
height - 80,
'Potem je prišla tema...',
{
fontFamily: 'Courier New',
fontSize: '24px',
fill: '#ff0000',
stroke: '#00ff00',
strokeThickness: 2,
shadow: {
offsetX: 3,
offsetY: 3,
color: '#000000',
blur: 10,
stroke: true,
fill: true
}
}
);
text2.setOrigin(0.5);
text2.setAlpha(0);
text2.setDepth(100);
// Shot 7 (18-21s): Chaos + Ana voice
this.showShot('intro_chaos', 18000, 21000, { red: true, glitch: true });
this.time.delayedCall(18200, () => this.playVoice('ana_04')); // "Vsi so se spremenili..."
this.cameras.main.shake(3000, 0.005);
this.tweens.add({
targets: text2,
alpha: 1,
duration: 800,
delay: 300
});
// Shot 8 (21-24s): Zombies + Kai voice
this.showShot('intro_zombies', 21000, 24000, { red: true, strobe: true });
this.time.delayedCall(21200, () => this.playVoice('kai_05')); // "Sosedi, prijatelji..."
// Shots sequence - faster, chaotic (~4s each)
this.showShot('intro_virus', 15000, 19000, { toxic: true, glitch: true });
this.showShot('intro_zombies', 19000, 23000, { red: true, glitch: true, strobe: true });
this.showShot('intro_chaos', 23000, 27000, { chaos: true });
this.showShot('intro_ana_taken', 27000, 30000, { blur: true, red: true });
// Shot 9 (24-27s): Parents Ghosts + Ana voice
this.showShot('intro_parents_ghosts', 24000, 27000, { fadeIn: true });
this.time.delayedCall(24200, () => this.playVoice('ana_05')); // "Starša sta se borila..."
// Add camera shake for chaos
this.time.delayedCall(19000, () => {
this.cameras.main.shake(4000, 0.005);
});
// Shot 10 (27-30s): Ana Taken + Ana SCREAM
this.showShot('intro_ana_taken', 27000, 30000, { red: true, blur: true });
this.time.delayedCall(27200, () => this.playVoice('ana_06')); // "KAI! NE POZABI ME!"
// Transition to Phase 3
this.time.delayedCall(29500, () => {
this.tweens.add({
targets: text2,
alpha: 0,
duration: 500
});
});
this.time.delayedCall(30000, () => {
text2.destroy();
this.playPhase3AmnesiaWakeUp();
});
this.time.delayedCall(30000, () => this.playPhase3TheAmnesia());
}
playPhase3AmnesiaWakeUp() {
// PHASE 3: AMNESIA WAKE-UP (30-45s)
console.log('🎬 Phase 3: Amnesia Wake-Up');
// ═══════════════════════════════════════════════════════════
// PHASE 3: THE AMNESIA (30-45s)
// ═══════════════════════════════════════════════════════════
playPhase3TheAmnesia() {
console.log('🎬 Phase 3: The Amnesia (30-45s)');
this.currentPhase = 3;
const width = this.cameras.main.width;
const height = this.cameras.main.height;
// Shot 11 (30-33s): Kai Alone + Kai voice
this.showShot('intro_kai_alone', 30000, 33000, { fadeIn: true });
this.time.delayedCall(30200, () => this.playVoice('kai_06')); // "Ostal sem sam..."
// Screen goes black first (amnesia darkness)
const blackScreen = this.add.rectangle(
width / 2,
height / 2,
width,
height,
0x000000
);
blackScreen.setDepth(50);
blackScreen.setAlpha(0);
// Shot 12 (33-36s): Kai Young + Kai voice
this.showShot('intro_kai_young', 33000, 36000, { fadeIn: true });
this.time.delayedCall(33200, () => this.playVoice('kai_07')); // "Leta so minila..."
this.tweens.add({
targets: blackScreen,
alpha: 1,
duration: 1000,
delay: 0
});
// Shot 13 (36-39s): Kai Adult + Kai voice
this.showShot('intro_kai_adult', 36000, 39000, { fadeIn: true });
this.time.delayedCall(36200, () => this.playVoice('kai_08')); // "...brada je zrasla..."
// Text overlays
const text3a = this.add.text(
width / 2,
height / 2 - 40,
'In ostal sem sam...',
{
fontFamily: 'Courier New',
fontSize: '20px',
fill: '#666666',
stroke: '#000000',
strokeThickness: 2
}
);
text3a.setOrigin(0.5);
text3a.setAlpha(0);
text3a.setDepth(100);
// Shot 14 (39-42s): Kai Elder + Kai voice
this.showShot('intro_kai_elder', 39000, 42000, { fadeIn: true });
this.time.delayedCall(39200, () => this.playVoice('kai_09')); // "Spomin je ostal megla..."
const text3b = this.add.text(
width / 2,
height / 2,
'z luknjo v glavi.',
{
fontFamily: 'Courier New',
fontSize: '20px',
fill: '#999999',
stroke: '#000000',
strokeThickness: 2
}
);
text3b.setOrigin(0.5);
text3b.setAlpha(0);
text3b.setDepth(100);
// Shot 15 (42-45s): Ana Memory + Ana voice (echo)
this.showShot('intro_ana_memory', 42000, 45000, { fadeIn: true });
this.time.delayedCall(42200, () => this.playVoice('ana_07')); // "Ana... Sestra..."
this.tweens.add({
targets: text3a,
alpha: 1,
duration: 1500,
delay: 1500
});
// Transition to Phase 4
this.time.delayedCall(45000, () => this.playPhase4TheAwakening());
}
this.tweens.add({
targets: text3b,
alpha: 1,
duration: 1500,
delay: 2500
});
// ═══════════════════════════════════════════════════════════
// PHASE 4: THE AWAKENING (45-60s)
// ═══════════════════════════════════════════════════════════
playPhase4TheAwakening() {
console.log('🎬 Phase 4: The Awakening (45-60s)');
this.currentPhase = 4;
// Fade out black screen and text, show bedroom
this.time.delayedCall(5000, () => {
this.tweens.add({
targets: [blackScreen, text3a, text3b],
alpha: 0,
duration: 2000
});
});
// Shot 16 (45-48s): Bedroom + Kai voice
this.showShot('intro_bedroom', 45000, 48000, { fadeIn: true });
this.time.delayedCall(45200, () => this.playVoice('kai_10')); // "In zdaj... se zbudim..."
// Bedroom appears
this.time.delayedCall(7000, () => {
blackScreen.destroy();
text3a.destroy();
text3b.destroy();
this.showShot('intro_bedroom', 37000, 40000, { fadeIn: true });
});
// Shot 17 (48-51s): Gronk + Gronk voice
this.showShot('intro_gronk', 48000, 51000, { fadeIn: true });
this.time.delayedCall(48200, () => this.playVoice('gronk_01')); // "Končno si buden..."
// Ana memory flash
this.time.delayedCall(10000, () => {
const flash = this.add.image(width / 2, height / 2, 'intro_ana_memory');
flash.setAlpha(0);
flash.setDepth(80);
flash.setScale(0.8);
// Shot 18 (51-54s): Ana Memory Reprise + Kai voice
this.showShot('intro_ana_memory', 51000, 54000, { fadeIn: true });
this.time.delayedCall(51200, () => this.playVoice('kai_11')); // "Moram jo najti."
// Shot 19 (54-57s): Twins Childhood + Ana voice
this.showShot('intro_twins_childhood', 54000, 57000, { warm: true, fadeIn: true });
this.time.delayedCall(54200, () => this.playVoice('ana_08')); // "Vedno sva bila dva..."
// Shot 20 (57-60s): Fade to Black + Kai FINAL
this.time.delayedCall(57000, () => {
this.playVoice('kai_12'); // "...tudi če mi vzame celo življenje."
// Fade to black
const blackScreen = this.add.rectangle(
this.cameras.main.width / 2,
this.cameras.main.height / 2,
this.cameras.main.width,
this.cameras.main.height,
0x000000
);
blackScreen.setAlpha(0);
blackScreen.setDepth(1000);
this.tweens.add({
targets: flash,
targets: blackScreen,
alpha: 1,
duration: 300,
yoyo: true,
repeat: 2,
onComplete: () => flash.destroy()
});
});
// Gronk entrance
this.time.delayedCall(12000, () => {
this.showShot('intro_gronk', 42000, 45000, { fadeIn: true });
});
// Final text
const textFinal = this.add.text(
width / 2,
height - 100,
'Moram jo najti.\nTudi če mi vzame celo življenje.',
{
fontFamily: 'Courier New',
fontSize: '18px',
fill: '#ffffff',
stroke: '#ff00ff',
strokeThickness: 1,
align: 'center',
lineSpacing: 10
}
);
textFinal.setOrigin(0.5);
textFinal.setAlpha(0);
textFinal.setDepth(100);
this.time.delayedCall(13000, () => {
this.tweens.add({
targets: textFinal,
alpha: 1,
duration: 2000
duration: 3000
});
});
// Transition to GameScene
this.time.delayedCall(17000, () => {
console.log('🎬 IntroScene: Complete! Starting game...');
this.cameras.main.fadeOut(2000, 0, 0, 0);
this.time.delayedCall(60000, () => {
console.log('🎬 IntroScene: EPIC COMPLETE! Starting game...');
if (this.ambientAudio) this.ambientAudio.stop();
this.cameras.main.fadeOut(1000, 0, 0, 0);
this.cameras.main.once('camerafadeoutcomplete', () => {
this.scene.start('GameScene');
});
@@ -503,7 +402,7 @@ class IntroScene extends Phaser.Scene {
// Create photo image (65% of screen)
const photo = this.add.image(width / 2, height / 2 - 30, imageKey);
photo.setAlpha(options.fadeIn ? 0 : 1);
photo.setAlpha(0);
photo.setDepth(20);
// Scale to 65% of screen size
@@ -512,14 +411,15 @@ class IntroScene extends Phaser.Scene {
photo.setScale(photoScale);
// Create Polaroid white frame
const frameWidth = photo.displayWidth + 40; // 20px padding each side
const frameHeight = photo.displayHeight + 80; // 20px top, 60px bottom (Polaroid style!)
const frameWidth = photo.displayWidth + 40;
const frameHeight = photo.displayHeight + 80;
const frame = this.add.graphics();
frame.setDepth(19);
frame.setAlpha(0);
// Dirty white Polaroid background
frame.fillStyle(0xf5f5dc, 1); // Beige white
frame.fillStyle(0xf5f5dc, 1);
frame.fillRect(
(width - frameWidth) / 2,
(height - frameHeight) / 2 - 30,
@@ -527,7 +427,7 @@ class IntroScene extends Phaser.Scene {
frameHeight
);
// Add subtle dirt/grain texture
// Add dirt/grain texture
for (let i = 0; i < 50; i++) {
const x = (width - frameWidth) / 2 + Math.random() * frameWidth;
const y = (height - frameHeight) / 2 - 30 + Math.random() * frameHeight;
@@ -537,7 +437,7 @@ class IntroScene extends Phaser.Scene {
this.currentPolaroid = { photo, frame };
// 🌊 FLOATING ANIMATION (5px up/down)
// 🌊 FLOATING ANIMATION
this.tweens.add({
targets: [photo, frame],
y: '-=5',
@@ -547,40 +447,38 @@ class IntroScene extends Phaser.Scene {
ease: 'Sine.easeInOut'
});
// Apply visual effects to photo
// Apply visual effects
if (options.warm) {
photo.setTint(0xffddaa); // Warm nostalgic tint
photo.setTint(0xffddaa);
}
if (options.red) {
photo.setTint(0xff6666); // Red danger tint
photo.setTint(0xff6666);
}
if (options.toxic) {
photo.setTint(0x66ff66); // Green toxic tint
photo.setTint(0x66ff66);
}
// 2 SECOND FADE-IN
if (options.fadeIn !== false) {
this.tweens.add({
targets: [photo, frame],
alpha: { from: 0, to: 1 },
duration: 2000,
ease: 'Power2.easeOut'
});
}
this.tweens.add({
targets: [photo, frame],
alpha: { from: 0, to: 1 },
duration: 2000,
ease: 'Power2.easeOut'
});
// GLITCH-OUT transition for next shot
// GLITCH-OUT transition
this.time.delayedCall(duration - 500, () => {
if (this.currentPolaroid) {
// First, quickly fade out the frame (so it doesn't show during glitch!)
// Frame fades first
this.tweens.add({
targets: frame,
alpha: 0,
duration: 100
});
// Then glitch effect on photo only
// Photo glitches
this.tweens.add({
targets: photo,
x: { from: photo.x - 10, to: photo.x + 10 },
@@ -588,12 +486,11 @@ class IntroScene extends Phaser.Scene {
repeat: 5,
yoyo: true,
onComplete: () => {
// Chromatic aberration effect (RGB flash)
// RGB flash
photo.setTint(0xff0000);
this.time.delayedCall(50, () => photo.setTint(0x00ff00));
this.time.delayedCall(100, () => photo.setTint(0x0000ff));
this.time.delayedCall(150, () => {
// Final fade out
this.tweens.add({
targets: photo,
alpha: 0,
@@ -606,7 +503,6 @@ class IntroScene extends Phaser.Scene {
});
if (options.glitch) {
// Extra glitch during display
this.tweens.add({
targets: [photo, frame],
x: { from: width / 2 - 5, to: width / 2 + 5 },
@@ -617,7 +513,6 @@ class IntroScene extends Phaser.Scene {
}
if (options.strobe) {
// Strobe effect
this.tweens.add({
targets: photo,
alpha: { from: 0.7, to: 1.0 },
@@ -630,12 +525,12 @@ class IntroScene extends Phaser.Scene {
}
shutdown() {
// Cleanup
if (this.skipPrompt) {
this.skipPrompt.destroy();
}
if (this.currentShot) {
this.currentShot.destroy();
if (this.ambientAudio) this.ambientAudio.stop();
if (this.currentVoice) this.currentVoice.stop();
if (this.skipPrompt) this.skipPrompt.destroy();
if (this.currentPolaroid) {
this.currentPolaroid.frame.destroy();
this.currentPolaroid.photo.destroy();
}
this.tweens.killAll();
this.time.removeAllEvents();