Files
novafarma/docs/design/ADVANCED_CAMERA_PLAN.md
2025-12-12 13:48:49 +01:00

10 KiB

🎬 ADVANCED CAMERA FEATURES - IMPLEMENTATION PLAN

Datum: 12. December 2025
Prioriteta: MEDIUM
Estimated Time: 2-3 ure


🎯 CILJI:

Razširitev Camera System z naprednimi funkcionalnostmi za profesionalne trailerje:

  • Smooth camera movement (Bezier curves)
  • Recording Mode (UI hide, slow-mo)
  • Cinematic Sequences (pre-made cutscenes)
  • Demo Recording (60s gameplay loops)

📋 FAZA 1: SMOOTH CAMERA MOVEMENT (45 min)

1.1 Bezier Curve Paths

Dodaj v CameraSystem.js:

// Bezier curve camera path
createBezierPath(points, duration = 5000) {
    // points = [{ x, y, zoom }, { x, y, zoom }, ...]
    
    const path = new Phaser.Curves.Spline(points.map(p => [p.x, p.y]));
    
    let progress = 0;
    const tween = this.scene.tweens.add({
        targets: { t: 0 },
        t: 1,
        duration: duration,
        ease: 'Sine.easeInOut',
        onUpdate: (tween) => {
            const t = tween.getValue();
            const point = path.getPoint(t);
            
            // Interpolate zoom
            const zoomIndex = Math.floor(t * (points.length - 1));
            const zoomT = (t * (points.length - 1)) - zoomIndex;
            const zoom = Phaser.Math.Linear(
                points[zoomIndex].zoom,
                points[Math.min(zoomIndex + 1, points.length - 1)].zoom,
                zoomT
            );
            
            this.camera.scrollX = point.x - this.camera.width / 2;
            this.camera.scrollY = point.y - this.camera.height / 2;
            this.camera.setZoom(zoom);
        }
    });
    
    return tween;
}

// Example usage:
// cameraSystem.createBezierPath([
//     { x: 100, y: 100, zoom: 1.0 },
//     { x: 200, y: 150, zoom: 1.5 },
//     { x: 300, y: 100, zoom: 1.0 }
// ], 5000);

1.2 Cinematic Zoom Controls

cinematicZoom(targetZoom, duration = 2000, ease = 'Sine.easeInOut') {
    return this.scene.tweens.add({
        targets: this.camera,
        zoom: targetZoom,
        duration: duration,
        ease: ease
    });
}

// Zoom presets
zoomPresets = {
    'extreme_closeup': 2.5,
    'closeup': 1.8,
    'medium': 1.2,
    'wide': 0.8,
    'extreme_wide': 0.4
};

applyZoomPreset(preset) {
    const zoom = this.zoomPresets[preset];
    if (zoom) {
        this.cinematicZoom(zoom);
    }
}

1.3 Camera Shake Intensity Controls

cinematicShake(intensity = 'medium', duration = 500) {
    const intensities = {
        'subtle': 0.002,
        'medium': 0.005,
        'strong': 0.01,
        'extreme': 0.02
    };
    
    const value = intensities[intensity] || intensities.medium;
    this.camera.shake(duration, value);
}

📋 FAZA 2: RECORDING MODE (30 min)

2.1 Hide UI Toggle (F4)

Že implementirano kot F7!

2.2 Free Camera Mode (noclip)

Že implementirano kot F6!

2.3 Time Slow-Mo

setTimeScale(scale) {
    // scale: 1.0 = normal, 0.5 = half speed, 0.25 = quarter speed
    this.scene.time.timeScale = scale;
    
    // Also affect physics
    if (this.scene.physics && this.scene.physics.world) {
        this.scene.physics.world.timeScale = scale;
    }
    
    console.log(`⏱️ Time scale: ${scale}x`);
}

// Keyboard shortcuts
// F11 - Slow-mo 0.5x
// F12 - Slow-mo 0.25x
// Shift+F12 - Normal speed

2.4 Screenshot Mode (High-Res)

captureHighResScreenshot(scale = 2) {
    // Temporarily increase resolution
    const originalZoom = this.camera.zoom;
    this.camera.setZoom(originalZoom * scale);
    
    // Capture after next frame
    this.scene.time.delayedCall(100, () => {
        this.scene.game.renderer.snapshot((image) => {
            // Download image
            const link = document.createElement('a');
            link.download = `novafarma_${Date.now()}.png`;
            link.href = image.src;
            link.click();
            
            console.log('📸 High-res screenshot captured!');
        });
        
        // Restore zoom
        this.camera.setZoom(originalZoom);
    });
}

📋 FAZA 3: CINEMATIC SEQUENCES (60 min)

3.1 Intro Cutscene (Farm Arrival)

playIntroCutscene() {
    console.log('🎬 Playing intro cutscene...');
    
    // Hide UI
    this.toggleScreenshotMode();
    
    // Sequence
    const sequence = [
        // 1. Fade in from black
        () => this.fadeIn(2000),
        
        // 2. Wide shot of farm (3 seconds)
        () => {
            this.panTo(400, 400, 2000);
            this.zoomTo(0.5, 2000);
        },
        
        // 3. Zoom to player (2 seconds)
        () => {
            this.panTo(this.scene.player.sprite.x, this.scene.player.sprite.y, 2000);
            this.zoomTo(1.2, 2000);
        },
        
        // 4. Follow player
        () => {
            this.mode = 'follow';
            this.camera.startFollow(this.scene.player.sprite);
            this.toggleScreenshotMode(); // Restore UI
        }
    ];
    
    this.playSequence(sequence, [0, 3000, 5000, 7000]);
}

playSequence(actions, timings) {
    actions.forEach((action, i) => {
        this.scene.time.delayedCall(timings[i], action);
    });
}

3.2 Boss Encounter Intro

playBossIntroCutscene(bossX, bossY) {
    const sequence = [
        // Dramatic zoom out
        () => this.zoomTo(0.3, 1000),
        
        // Pan to boss
        () => this.panTo(bossX, bossY, 2000),
        
        // Zoom to boss face
        () => this.zoomTo(1.5, 1500),
        
        // Shake
        () => this.cinematicShake('strong', 500),
        
        // Flash red
        () => this.flash(0xff0000, 300),
        
        // Return to player
        () => {
            this.panTo(this.scene.player.sprite.x, this.scene.player.sprite.y, 1500);
            this.zoomTo(1.0, 1500);
        }
    ];
    
    this.playSequence(sequence, [0, 1000, 3000, 4500, 5000, 5500]);
}

3.3 Day/Night Transition Showcase

playDayNightShowcase() {
    // Speed up time temporarily
    const originalTimeScale = this.scene.timeSystem.timeScale;
    this.scene.timeSystem.timeScale = 10.0; // 10x speed
    
    // Wide shot
    this.zoomTo(0.6, 2000);
    
    // Wait for full day/night cycle
    this.scene.time.delayedCall(12000, () => {
        // Restore time
        this.scene.timeSystem.timeScale = originalTimeScale;
        this.zoomTo(1.0, 2000);
    });
}

3.4 Season Change Sequence

playSeasonShowcase() {
    // Cycle through seasons
    const seasons = ['spring', 'summer', 'autumn', 'winter'];
    
    seasons.forEach((season, i) => {
        this.scene.time.delayedCall(i * 3000, () => {
            if (this.scene.weatherSystem) {
                this.scene.weatherSystem.setSeason(season);
            }
            
            // Flash transition
            this.flash(0xffffff, 500);
        });
    });
}

📋 FAZA 4: DEMO RECORDING (45 min)

4.1 60-Second Gameplay Loop

recordGameplayLoop() {
    console.log('🎥 Recording 60-second gameplay loop...');
    
    const script = [
        // 0-10s: Farming
        { time: 0, action: () => this.showcaseFarming() },
        
        // 10-20s: Building
        { time: 10000, action: () => this.showcaseBuilding() },
        
        // 20-30s: Combat
        { time: 20000, action: () => this.showcaseCombat() },
        
        // 30-40s: Crafting
        { time: 30000, action: () => this.showcaseCrafting() },
        
        // 40-50s: NPCs
        { time: 40000, action: () => this.showcaseNPCs() },
        
        // 50-60s: Day/Night
        { time: 50000, action: () => this.playDayNightShowcase() }
    ];
    
    script.forEach(({ time, action }) => {
        this.scene.time.delayedCall(time, action);
    });
}

showcaseFarming() {
    // Pan to farm area
    this.panTo(400, 400, 2000);
    this.zoomTo(1.2, 2000);
    
    // Simulate farming actions
    // (Player would do this manually or via AI)
}

showcaseBuilding() {
    // Show building mode
    if (this.scene.buildSystem) {
        this.scene.buildSystem.toggleBuildMode();
    }
}

showcaseCombat() {
    // Spawn enemy for demo
    // Show combat
}

showcaseCrafting() {
    // Open crafting menu
    const uiScene = this.scene.scene.get('UIScene');
    if (uiScene) {
        uiScene.toggleCraftingMenu();
    }
}

showcaseNPCs() {
    // Pan to NPCs
    if (this.scene.npcs && this.scene.npcs.length > 0) {
        const npc = this.scene.npcs[0];
        this.panTo(npc.sprite.x, npc.sprite.y, 2000);
    }
}

📝 KEYBOARD SHORTCUTS:

F6  - Free Camera Mode
F7  - Screenshot Mode (Hide UI)
F8  - Save Camera Position
F10 - Cinematic Mode
F11 - Slow-mo 0.5x
F12 - Slow-mo 0.25x
Shift+F12 - Normal speed
Ctrl+S - High-res screenshot

🔧 INTEGRATION:

GameScene.js:

// In create():
this.cameraSystem = new CameraSystem(this);

// In update():
if (this.cameraSystem) {
    this.cameraSystem.update(delta);
}

// Keyboard shortcuts:
this.input.keyboard.on('keydown-F11', () => {
    this.cameraSystem.setTimeScale(0.5);
});

this.input.keyboard.on('keydown-F12', () => {
    this.cameraSystem.setTimeScale(0.25);
});

this.input.keyboard.on('keydown', (event) => {
    if (event.shiftKey && event.key === 'F12') {
        this.cameraSystem.setTimeScale(1.0);
    }
    if (event.ctrlKey && event.key === 's') {
        event.preventDefault();
        this.cameraSystem.captureHighResScreenshot();
    }
});

📊 IMPLEMENTATION STEPS:

  1. Razširi CameraSystem.js (45 min)

    • Bezier curves
    • Cinematic zoom
    • Shake controls
  2. Dodaj Recording Mode (30 min)

    • Time slow-mo
    • High-res screenshots
  3. Ustvari Cinematic Sequences (60 min)

    • Intro cutscene
    • Boss intro
    • Day/night showcase
    • Season showcase
  4. Implementiraj Demo Recording (45 min)

    • 60s gameplay loop
    • Feature showcases
  5. Integration \u0026 Testing (30 min)

Total: 3h 30min


🎯 PRIORITETA:

MEDIUM - Pomembno za marketing, ampak ne kritično za gameplay.

Priporočam: Implementacija po dokončanju core funkcionalnosti.


Status: PLAN PRIPRAVLJEN

CameraSystem.js že obstaja - samo razširitev potrebna!

Estimated time: 3h 30min

Želite implementacijo zdaj ali kasneje? 🎬