// ==========================================
// MR. ALEX JÁTÉK
// 
// Hasznos tipp: Ha közvetlenül 3D módban szeretnéd elindítani a játékot,
// egyszerűen írd a webcím végére a ?mode=3d paramétert! 
// (Pl.: index.html?mode=3d)
// ==========================================

// Betöltjük a vásznat
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// Alapvető képek betöltése (teszteléshez, bár később a proxy kezeli)
const imgAlexStand = new Image();
imgAlexStand.src = 'sprites/alex_stand.png';

// ==========================================
// A JÁTÉKOS ÁLTAL MÓDOSÍTHATÓ SZÍNEK (3D)
// ==========================================
const PADLO_FENTI_SZIN1 = '#d42020';       // Felső padlók 1. színe (Piros)
const PADLO_FENTI_SZIN2 = '#e8c020';       // Felső padlók 2. színe (Sárga)
const PADLO_FENTI_ELSOLAP_SZIN1 = '#a01818'; // Felső padlók vastagságának 1. színe (Sötétpiros)
const PADLO_FENTI_ELSOLAP_SZIN2 = '#b89818'; // Felső padlók vastagságának 2. színe (Sötétsárga)

const PADLO_ALSO_SZIN1 = '#1a5656';        // Alsó, fix padló 1. színe
const PADLO_ALSO_SZIN2 = '#1a5656';        // Alsó, fix padló 2. színe (ugyanaz, ha egyszínűt akarsz)
const PADLO_ALSO_ELSOLAP_SZIN1 = '#164a4a';  // Alsó padló vastagságának 1. színe
const PADLO_ALSO_ELSOLAP_SZIN2 = '#164a4a';  // Alsó padló vastagságának 2. színe

// Játékállandók
const CANVAS_WIDTH = 512;
const CANVAS_HEIGHT = 480;
const FLOOR_COUNT = 6; // 1 alsó + 4 középső + 1 legfelső plafon
const FLOOR_HEIGHT = 84; // Padlók közötti távolság
const BASE_Y = 420; // Az alsó padló Y koordinátája
const PLAYER_WIDTH = 16;
const PLAYER_HEIGHT = 32;
const GRAVITY = 0.5;
const JUMP_FORCE = -10; // Maximális ugrási magasság 100px (tökéletesen átugorja a 90px magasan lévő padlót)
const HOLE_SPEED = 2;
const MOVE_SPEED = 2; // Pixel / frame a lyukak és az ellenségek számára
const START_STAGE = 1; // Átírhatod teszteléshez (pl. 3 vagy 6)
const START_LIVES = 8; // Kezdő életek száma

// 3D Padló rajzolásának állandói
const FLOOR_STRIPE_W = 16;
const FLOOR_LIP_H = 6;
const FLOOR_OFFSET_X = 14;
const FLOOR_OFFSET_Y = -14;

// 2D Eredeti színek
const BG_TEAL = '#2b8b8b';
const FRAME_TEAL = '#278080';
const HUD_BG = '#278080';

// Alapvető képek
let sprites2d = {};
let sprites3d = {};
const sprites = new Proxy({}, {
    get: function(target, prop) {
        return window.isModern ? sprites3d[prop] : sprites2d[prop];
    }
});

/**
 * Betölt egy sprite-ot 2D és 3D módhoz.
 * @param {string} name A sprite belső neve.
 * @param {string} file A fájlnév (kiterjesztés nélkül).
 */
function loadSprite(name, file) {
    sprites2d[name] = new Image();
    sprites2d[name].src = 'sprites/' + file + '.png';
    sprites3d[name] = new Image();
    sprites3d[name].src = 'sprites3d/' + file + '.png';
}

loadSprite('stand', 'stand1');
loadSprite('standright', 'standright');
loadSprite('run1', 'right1');
loadSprite('run2', 'right2');
loadSprite('run3', 'right3');
loadSprite('jump', 'jump');
loadSprite('jumpbump', 'jumpbump');
loadSprite('stun1', 'lies1');
loadSprite('stun2', 'lies2');
loadSprite('lives', 'lives');
loadSprite('enemy1a', 'enemy1a');
loadSprite('enemy1b', 'enemy1b');
loadSprite('enemy2a', 'enemy2a');
loadSprite('enemy2b', 'enemy2b');
loadSprite('enemy3a', 'enemy3a');
loadSprite('enemy3b', 'enemy3b');
loadSprite('enemy4a', 'enemy4a');
loadSprite('enemy4b', 'enemy4b');
loadSprite('enemy5a', 'enemy5a');
loadSprite('enemy5b', 'enemy5b');
loadSprite('enemy6a', 'enemy6a');
loadSprite('enemy6b', 'enemy6b');
loadSprite('enemy6c', 'enemy6c');
loadSprite('enemy7a', 'enemy7a');
loadSprite('csucs', 'csucs');
loadSprite('pont', 'pont');
loadSprite('mainscreen', 'mainscreen');
loadSprite('introscreen', 'introscreen');
loadSprite('hatup', 'hatup');

// Bemenet kezelése
const keys = {
    left: false,
    right: false,
    up: false
};

let musicStarted = false;
let musicMuted = false;
let sfxMuted = false;
let currentMusicTrack = window.isModern ? 2 : 1;

/**
 * Visszaadja az aktuálisan aktív zene audio elemét.
 */
function getActiveMusic() {
    return document.getElementById(currentMusicTrack === 1 ? 'bg-music' : 'bg-music-alter');
}

/**
 * Vált a zeneszámok között (1. és 2. zene).
 */
function toggleMusicTrack() {
    let oldMusic = getActiveMusic();
    if (oldMusic && !oldMusic.paused) oldMusic.pause();
    if (oldMusic) oldMusic.currentTime = 0;
    
    currentMusicTrack = currentMusicTrack === 1 ? 2 : 1;
    let btnSwitch = document.getElementById('btn-music-switch');
    if (btnSwitch) btnSwitch.innerText = 'Zene: #' + currentMusicTrack;
    
    let newMusic = getActiveMusic();
    if (newMusic && !musicMuted && musicStarted && (typeof game === 'undefined' || !game.isPaused)) {
        newMusic.play().catch(err => console.log('Play failed:', err));
    }
}

/**
 * Lejátszik egy hangeffektust az azonosítója alapján.
 * @param {string} id Az audio elem ID-ja.
 */
function playSound(id) {
    if (sfxMuted) return;
    let sfx = document.getElementById(id);
    if (sfx) {
        sfx.currentTime = 0;
        sfx.play().catch(err => console.log('SFX play failed:', err));
    }
}

window.addEventListener('keydown', e => {
    let music = getActiveMusic();
    
    if (e.key === 'm' || e.key === 'M') {
        if (music) {
            let btnToggle = document.getElementById('btn-music-toggle');
            if (music.paused) {
                music.play().catch(err => console.log('Play failed:', err));
                musicMuted = false;
                musicStarted = true;
                if (btnToggle) btnToggle.innerText = 'Zene: BE';
            } else {
                music.pause();
                musicMuted = true;
                if (btnToggle) btnToggle.innerText = 'Zene: KI';
            }
        }
    } else if (e.key === 's' || e.key === 'S') {
        let btnSfxToggle = document.getElementById('btn-sfx-toggle');
        sfxMuted = !sfxMuted;
        if (btnSfxToggle) {
            btnSfxToggle.innerText = sfxMuted ? 'Hang: KI' : 'Hang: BE';
        }
    } else if (e.key === 'c' || e.key === 'C') {
        toggleMusicTrack();
    } else if (e.key === 'p' || e.key === 'P') {
        if (typeof game !== 'undefined') {
            game.isPaused = !game.isPaused;
            let music = getActiveMusic();
            if (music) {
                if (game.isPaused) {
                    music.pause();
                } else if (!musicMuted) {
                    music.play().catch(err => console.log(err));
                }
            }
        }
    } else if (e.key === 'r' || e.key === 'R') {
        if (typeof game !== 'undefined') {
            game.restartGame();
            game.isMainMenu = true; // Vissza a főmenübe
            game.isIntro = false;
        }
    } else {
        // Automatikus lejátszás az első egyéb interakcióra, ha nincs némítva
        if (music && !musicStarted && !musicMuted) {
            musicStarted = true;
            music.play().catch(err => {
                console.log('Audio play failed:', err);
                musicStarted = false;
            });
        }
    }

    if (e.key === 'ArrowLeft') keys.left = true;
    if (e.key === 'ArrowRight') keys.right = true;
    if (e.key === 'ArrowUp' || e.key === ' ') {
        if (game.isMainMenu) {
            game.isMainMenu = false;
            game.startIntro();
            initMusic();
            return;
        }
        if (game.isGameOver) {
            game.restartGame();
            game.startIntro();
            return;
        }
        keys.up = true;
    }
});

// Globális interakciókezelő a mobil hanghoz
window.addEventListener('touchstart', () => {
    let music = getActiveMusic();
    if (music && !musicStarted && !musicMuted) {
        musicStarted = true;
        music.play().catch(err => {
            musicStarted = false;
        });
    }
});

window.addEventListener('click', () => {
    let music = getActiveMusic();
    if (music && !musicStarted && !musicMuted) {
        musicStarted = true;
        music.play().catch(err => {
            musicStarted = false;
        });
    }
});

window.addEventListener('keyup', (e) => {
    if (e.key === 'ArrowLeft') keys.left = false;
    if (e.key === 'ArrowRight') keys.right = false;
    if (e.key === 'ArrowUp' || e.key === ' ') keys.up = false;
});

// Mobil vezérlők
/**
 * Beállítja az érintőképernyős (mobil) vezérlést.
 */
function setupMobileControls() {
    const btnLeft = document.getElementById('btn-left');
    const btnRight = document.getElementById('btn-right');
    const btnJump = document.getElementById('btn-jump');
    
    if (!btnLeft) return;

    const initMusic = () => {
        let music = getActiveMusic();
        if (music && !musicStarted && !musicMuted) {
            musicStarted = true;
            music.play().catch(err => {
                console.log('Audio play failed:', err);
                musicStarted = false;
            });
        }
    };

    btnLeft.addEventListener('touchstart', (e) => { e.preventDefault(); keys.left = true; initMusic(); });
    btnLeft.addEventListener('touchend', (e) => { e.preventDefault(); keys.left = false; });
    
    btnRight.addEventListener('touchstart', (e) => { e.preventDefault(); keys.right = true; initMusic(); });
    btnRight.addEventListener('touchend', (e) => { e.preventDefault(); keys.right = false; });
    
    btnJump.addEventListener('mousedown', (e) => { 
        if (game.isMainMenu) {
            game.isMainMenu = false;
            game.startIntro();
            initMusic();
            return;
        }
        if (game.isGameOver) {
            game.restartGame();
            game.startIntro();
            return;
        }
        keys.up = true; 
        initMusic(); 
    });
    btnJump.addEventListener('touchstart', (e) => { 
        e.preventDefault(); 
        if (game.isMainMenu) {
            game.isMainMenu = false;
            game.startIntro();
            initMusic();
            return;
        }
        if (game.isGameOver) {
            game.restartGame();
            game.startIntro();
            return;
        }
        keys.up = true; 
        initMusic(); 
    });
    btnJump.addEventListener('touchend', (e) => { e.preventDefault(); keys.up = false; });

    // Egérkattintások támogatása asztali teszteléshez
    btnLeft.addEventListener('mousedown', (e) => { keys.left = true; initMusic(); });
    btnLeft.addEventListener('mouseup', (e) => { keys.left = false; });
    btnLeft.addEventListener('mouseleave', (e) => { keys.left = false; });

    btnRight.addEventListener('mousedown', (e) => { keys.right = true; initMusic(); });
    btnRight.addEventListener('mouseup', (e) => { keys.right = false; });
    btnRight.addEventListener('mouseleave', (e) => { keys.right = false; });

    btnJump.addEventListener('mousedown', (e) => { 
        if (game.isGameOver) {
            game.restartGame();
            return;
        }
        keys.up = true; 
        initMusic(); 
    });
    btnJump.addEventListener('mouseup', (e) => { keys.up = false; });
    btnJump.addEventListener('mouseleave', (e) => { keys.up = false; });
    
    const btnPauseToggle = document.getElementById('btn-pause-toggle');
    if (btnPauseToggle) {
        btnPauseToggle.addEventListener('click', (e) => {
            e.preventDefault();
            if (game) {
                game.isPaused = !game.isPaused;
                let music = getActiveMusic();
                if (game.isPaused) {
                    if (musicStarted && !musicMuted && music) music.pause();
                } else {
                    if (musicStarted && !musicMuted && music) music.play().catch(err => console.log('Audio play failed:', err));
                }
            }
        });
    }

    const btnMusicToggle = document.getElementById('btn-music-toggle');
    if (btnMusicToggle) {
        btnMusicToggle.addEventListener('click', (e) => {
            e.preventDefault();
            let music = getActiveMusic();
            if (music) {
                if (music.paused) {
                    music.play().catch(err => console.log('Play failed:', err));
                    musicMuted = false;
                    musicStarted = true;
                    btnMusicToggle.innerText = 'Zene: BE';
                } else {
                    music.pause();
                    musicMuted = true;
                    btnMusicToggle.innerText = 'Zene: KI';
                }
            }
        });
    }

    const btnMusicSwitch = document.getElementById('btn-music-switch');
    if (btnMusicSwitch) {
        btnMusicSwitch.innerText = 'Zene: #' + currentMusicTrack;
        btnMusicSwitch.addEventListener('click', (e) => {
            e.preventDefault();
            toggleMusicTrack();
        });
    }

    const btnSfxToggle = document.getElementById('btn-sfx-toggle');
    if (btnSfxToggle) {
        btnSfxToggle.addEventListener('click', (e) => {
            e.preventDefault();
            sfxMuted = !sfxMuted;
            btnSfxToggle.innerText = sfxMuted ? 'Hang: KI' : 'Hang: BE';
        });
    }

    const btnResetMobile = document.getElementById('btn-reset-mobile');
    if (btnResetMobile) {
        btnResetMobile.addEventListener('click', (e) => {
            e.preventDefault();
            if (typeof game !== 'undefined') {
                game.restartGame();
                game.isMainMenu = true;
                game.isIntro = false;
            }
        });
    }
}

setupMobileControls();

// ============================================================
//  3D padló rajzoló segédfüggvények
// ============================================================

/**
 * Megrajzol egy 3D padlószakaszt a megadott koordinátákon.
 */
function drawFloor3DSegment(ctx, x, y, w, hasLeftCap, hasRightCap, isBottomFloor = false) {
    // A csíkok kezdő X koordinátájának meghatározása, hogy zökkenőmentesen ismétlődjenek
    let stripeStart = Math.floor((x - Math.abs(FLOOR_OFFSET_X)*2) / FLOOR_STRIPE_W) * FLOOR_STRIPE_W;

    let cTopRed = PADLO_FENTI_SZIN1;
    let cTopYellow = PADLO_FENTI_SZIN2;
    let cFrontRed = PADLO_FENTI_ELSOLAP_SZIN1;
    let cFrontYellow = PADLO_FENTI_ELSOLAP_SZIN2;

    if (isBottomFloor) {
        cTopRed = PADLO_ALSO_SZIN1;
        cTopYellow = PADLO_ALSO_SZIN2;
        cFrontRed = PADLO_ALSO_ELSOLAP_SZIN1;
        cFrontYellow = PADLO_ALSO_ELSOLAP_SZIN2;
    }

    // --- 1. A 3D felső felület megrajzolása (Paralelogramma az Y fölött) ---
    ctx.save();
    ctx.beginPath();
    ctx.moveTo(x, y);
    ctx.lineTo(x + w, y);
    ctx.lineTo(x + w + FLOOR_OFFSET_X, y + FLOOR_OFFSET_Y);
    ctx.lineTo(x + FLOOR_OFFSET_X, y + FLOOR_OFFSET_Y);
    ctx.closePath();
    ctx.clip();

    for (let sx = stripeStart; sx < x + w + Math.abs(FLOOR_OFFSET_X); sx += FLOOR_STRIPE_W) {
        let stripeIdx = Math.floor(sx / FLOOR_STRIPE_W);
        ctx.fillStyle = (stripeIdx % 2 === 0) ? cTopRed : cTopYellow;
        
        ctx.beginPath();
        ctx.moveTo(sx, y);
        ctx.lineTo(sx + FLOOR_STRIPE_W, y);
        ctx.lineTo(sx + FLOOR_STRIPE_W + FLOOR_OFFSET_X, y + FLOOR_OFFSET_Y);
        ctx.lineTo(sx + FLOOR_OFFSET_X, y + FLOOR_OFFSET_Y);
        ctx.closePath();
        ctx.fill();
        
        // Padlólapok közötti elválasztó vonalak (fugák) megrajzolása a tömör alsó padlónál
        if (isBottomFloor) {
            ctx.strokeStyle = 'rgba(0, 0, 0, 0.3)';
            ctx.lineWidth = 1;
            ctx.stroke();
        }
    }
    ctx.restore();

    // --- 2. Az elvágott oldalélek megrajzolása (Paralelogramma, ami csak a jobb oldali mélységet mutatja) ---
    if (hasRightCap) {
        let endStripeIdx = Math.floor((x + w - 0.1) / FLOOR_STRIPE_W);
        let capColor = (endStripeIdx % 2 === 0) ? cFrontRed : cFrontYellow;

        ctx.fillStyle = capColor;
        ctx.beginPath();
        ctx.moveTo(x + w, y + FLOOR_LIP_H);                                     // a perem alja
        ctx.lineTo(x + w, y);                                                   // a perem teteje
        ctx.lineTo(x + w + FLOOR_OFFSET_X, y + FLOOR_OFFSET_Y);                 // a felső hátsó sarok
        ctx.lineTo(x + w + FLOOR_OFFSET_X, y + FLOOR_OFFSET_Y + FLOOR_LIP_H);   // az alsó hátsó sarok
        ctx.closePath();
        ctx.fill();
        
        // Egy finom vonal hozzáadása az oldalél alsó széléhez
        ctx.strokeStyle = '#000000';
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.moveTo(x + w, y + FLOOR_LIP_H - 0.5);
        ctx.lineTo(x + w + FLOOR_OFFSET_X, y + FLOOR_OFFSET_Y + FLOOR_LIP_H - 0.5);
        ctx.stroke();
    }

    // --- 3. A vékony elülső perem megrajzolása ---
    for (let sx = stripeStart; sx < x + w; sx += FLOOR_STRIPE_W) {
        let stripeIdx = Math.floor(sx / FLOOR_STRIPE_W);
        let drawLeft = Math.max(sx, x);
        let drawRight = Math.min(sx + FLOOR_STRIPE_W, x + w);
        let drawW = drawRight - drawLeft;
        if (drawW <= 0) continue;

        ctx.fillStyle = (stripeIdx % 2 === 0) ? cFrontRed : cFrontYellow;
        ctx.fillRect(drawLeft, y, drawW, FLOOR_LIP_H);
        
        if (isBottomFloor) {
            ctx.strokeStyle = 'rgba(0, 0, 0, 0.3)';
            ctx.lineWidth = 1;
            ctx.strokeRect(drawLeft, y, drawW, FLOOR_LIP_H);
        }
    }
    // Fekete árnyékvonal a perem legalsó szélén
    ctx.fillStyle = '#000000';
    ctx.fillRect(x, y + FLOOR_LIP_H - 1, w, 1);
}

class Floor {
    /**
     * Inicializál egy új padlót.
     * @param {number} level A padló szintje (0 a legalsó).
     * @param {number} y A padló Y koordinátája.
     * @param {boolean} isBottom Igaz, ha ez a legalsó, tömör padló.
     */
    constructor(level, y, isBottom) {
        this.level = level;
        this.y = y;
        this.isBottom = isBottom;
        this.holes = [];
        
        // Lyukak generálása padlónként, kivéve a legalsót
        if (!this.isBottom) {
            // Kezdeti időzítő az első lyukhoz (eltolva, hogy ne egyszerre jöjjenek)
            this.spawnTimer = 20 + Math.random() * 100;
            // A legfelső szint kicsit később induljon
            if (this.level === FLOOR_COUNT - 1) {
                this.spawnTimer += 50;
            }
        }
    }

    /**
     * Frissíti a padlón lévő lyukak helyzetét és újakat generál.
     */
    update() {
        if (!this.isBottom) {
            // Meglévő lyukak frissítése
            for (let i = this.holes.length - 1; i >= 0; i--) {
                let hole = this.holes[i];
                hole.x += hole.speed;
                
                // Lyuk törlése, ha teljesen elhagyja a kiterjesztett 3D-s láthatósági területet
                if (hole.speed > 0 && hole.x > CANVAS_WIDTH + 150) {
                    this.holes.splice(i, 1);
                } else if (hole.speed < 0 && hole.x < -150) {
                    this.holes.splice(i, 1);
                }
            }

            // Új lyukak létrehozása
            this.spawnTimer--;
            if (this.spawnTimer <= 0) {
                let holeSpeed = MOVE_SPEED * (Math.random() > 0.5 ? 1 : -1);
                // Képernyőn kívül hozzuk létre, hogy a 3D-s árnyék ne hirtelen jelenjen meg
                let spawnX = holeSpeed > 0 ? -150 : CANVAS_WIDTH + 150;
                this.holes.push({ x: spawnX, speed: holeSpeed });
                
                // Következő lyuk késleltetésének kiszámítása
                let isTopLevel = (this.level === FLOOR_COUNT - 1);
                let baseDelay = isTopLevel ? 200 : 120;
                let randDelay = isTopLevel ? 150 : 150;
                
                let chance = Math.random();
                if (chance < 0.25 && !isTopLevel) {
                    // 25% esély egy gyors, rögtön következő lyukra (csak az alsóbb szinteken)
                    this.spawnTimer = 40 + Math.random() * 60;
                } else if (chance > 0.8) {
                    // 20% esély egy hatalmas lyukra (egy darabig nincs lyuk)
                    this.spawnTimer = (baseDelay * 1.5) + Math.random() * (randDelay * 1.5);
                } else {
                    // Normál távolság
                    this.spawnTimer = baseDelay + Math.random() * randDelay;
                }
            }
        }
    }

    /**
     * Kirajzolja a padlót és a rajta lévő lyukakat.
     * @param {CanvasRenderingContext2D} ctx A rajzolási kontextus.
     */
    draw(ctx) {
        if (window.isModern) {
            let drawYOffset = 4; // A 3D-s padlókat vizuálisan 4 pixellel lejjebb toljuk
            if (this.isBottom) {
                // Egybefüggő 3D-s padlószakasz rajzolása a teljes képernyőn
                drawFloor3DSegment(ctx, -100, this.y + drawYOffset, CANVAS_WIDTH + 200, false, false, true);
            } else {
                let segments = [];
                let holeRects = this.holes.map(h => ({ x: Math.floor(h.x), w: 48 }));
                holeRects.sort((a, b) => a.x - b.x);
                let prevEnd = -100;
                for (let hole of holeRects) {
                    let hStart = hole.x;
                    let hEnd = hole.x + hole.w;
                    if (hEnd < -100) continue;
                    if (hStart > prevEnd) segments.push({ x: prevEnd, w: hStart - prevEnd });
                    prevEnd = Math.max(prevEnd, hEnd);
                }
                if (prevEnd < CANVAS_WIDTH + 100) segments.push({ x: prevEnd, w: CANVAS_WIDTH + 100 - prevEnd });
                for (let seg of segments) {
                    let hasLeftCap = (seg.x > -100);
                    let hasRightCap = (seg.x + seg.w < CANVAS_WIDTH + 100);
                    drawFloor3DSegment(ctx, seg.x, this.y + drawYOffset, seg.w, hasLeftCap, hasRightCap);
                }
            }
        } else {
            if (this.isBottom) {
                // Alsó padló megrajzolása (fekete szaggatott vonal, felváltva 8px fekete, 8px cián)
                for (let x = 0; x < CANVAS_WIDTH; x += 16) {
                    ctx.fillStyle = '#000000';
                    ctx.fillRect(x, this.y, 8, 8);
                }
            } else {
                // Először megrajzoljuk a normál tömör padlót
                for (let x = 0; x < CANVAS_WIDTH; x += 8) {
                    // 4 pixel magas színsáv
                    ctx.fillStyle = (x / 8) % 2 === 0 ? '#d21313' : '#f7f738';
                    ctx.fillRect(x, this.y, 8, 4);
                    // 2 pixel magas fekete árnyék alatta
                    ctx.fillStyle = '#000000';
                    ctx.fillRect(x, this.y + 4, 8, 2);
                }
                
                // Most pedig szépen letöröljük a lyukakat!
                for (let hole of this.holes) {
                    ctx.clearRect(Math.floor(hole.x), this.y, 48, 6);
                }
            }
        }
    }
}

class Player {
    /**
     * Inicializálja a játékost.
     */
    constructor() {
        this.width = PLAYER_WIDTH;
        this.height = PLAYER_HEIGHT;
        this.reset();
        this.score = 0;
        this.highscore = 0;
        this.isDead = false;
        this.lives = START_LIVES;
        this.stage = START_STAGE;
        this.lastEnemyType = null;
    }

    /**
     * Alaphelyzetbe állítja a játékos pozícióját és állapotát.
     */
    reset() {
        this.x = 320;
        this.y = BASE_Y - this.height;
        this.vx = 0;
        this.vy = 0;
        this.state = 'idle';
        this.facing = 1;
        this.stunTimer = 0;
        this.idleTimer = 0;
        this.willBeStunned = false;
        this.scoredThisJump = false;
        this.topReached = false;
        this.highestFloorReached = 0;
    }

    /**
     * Frissíti a játékos fizikáját, mozgását és az ütközéseket.
     * @param {Array<Floor>} floors A padlók tömbje az ütközésvizsgálathoz.
     */
    update(floors) {
        // Minden fizika és animáció leállítása, ha a játékos nyert
        if (this.state === 'win') return;

        if (this.state === 'stun') {
            this.stunTimer--;
            if (this.stunTimer <= 0) {
                this.state = 'idle';
            }
        }

        // Vízszintes mozgás kezelése, ha nincs elkábulva és a földön van
        if (this.state !== 'stun' && this.state !== 'win' && this.vy === 0) {
            if (keys.left) {
                this.x -= MOVE_SPEED;
                this.state = 'run';
                this.facing = -1;
                this.idleTimer = 0;
            } else if (keys.right) {
                this.x += MOVE_SPEED;
                this.state = 'run';
                this.facing = 1;
                this.idleTimer = 0;
            } else {
                this.state = 'idle';
                this.idleTimer++;
            }
        } else {
            this.idleTimer = 0;
            // Ha a levegőben van és nem kábult/nyert, az ugrás animációt használjuk
            if (this.vy !== 0 && this.state !== 'stun' && this.state !== 'win') {
                this.state = 'jump';
            }
        }

        // Képernyőn átfordulás (ha kimegy balra, bejön jobbra)
        if (this.x > CANVAS_WIDTH) this.x = -this.width;
        if (this.x < -this.width) this.x = CANVAS_WIDTH;

        let oldBottom = this.y + this.height;
        let oldTop = this.y;

        // Gravitáció alkalmazása
        let currentGravity = (this.state === 'stun') ? GRAVITY / 1.5 : GRAVITY;
        this.vy += currentGravity;
        this.y += this.vy;
        
        let newBottom = this.y + this.height;
        let newTop = this.y;

        // Függőleges ütközés
        if (this.vy > 0) {
            // Lefelé esés
            for (let floor of floors) {
                if (oldBottom <= floor.y && newBottom >= floor.y) {
                    let overHole = false;
                    if (!floor.isBottom) {
                        for (let hole of floor.holes) {
                            if (this.x + this.width / 2 > hole.x && this.x + this.width / 2 < hole.x + 48) {
                                overHole = true;
                                break;
                            }
                        }
                    }

                    if (!overHole) {
                        let justLanded = oldBottom < floor.y - 0.1;
                        this.y = floor.y - this.height;
                        this.vy = 0;
                        if (this.state === 'jump') this.state = 'idle';
                        if (this.state === 'stun' && justLanded) this.stunTimer = 128;
                        
                        if (floor.isBottom) {
                            if (this.highestFloorReached > 0) {
                                this.lives--;
                                this.highestFloorReached = 0;
                                if (this.lives <= 0) {
                                    this.isDead = true;
                                }
                            }
                        }

                        if (this.willBeStunned) {
                            this.state = 'stun';
                            this.stunTimer = 128;
                            this.willBeStunned = false;
                        }
                        break;
                    } else {
                        // Beesett egy lyukba
                        if (!this.willBeStunned) {
                            playSound('sfx-fall');
                            this.willBeStunned = true; // El fog kábuludni, amikor végül földet ér
                            this.vy += 4; // Gyorsabb esés, hogy illeszkedjen a hangeffektus hosszához
                        }
                    }
                }
            }
            
            // Ellenőrizzük, hogy teljesen leesett-e az alsó padlóról
            if (this.y > CANVAS_HEIGHT) {
                playSound('sfx-fall');
                this.lives--;
                if (this.lives <= 0) {
                    this.isDead = true;
                } else {
                    this.reset();
                }
                return;
            }
        } else if (this.vy < 0) {
            // Felfelé mozgás
            for (let floor of floors) {
                // Vizuális magasság korrekció (a fej kb. 20 pixelre van a hitboxtól)
                if (oldTop >= floor.y + 26 && newTop <= floor.y + 26) {
                    let underHole = false;
                    if (!floor.isBottom) {
                        for (let hole of floor.holes) {
                            if (this.x + this.width / 2 > hole.x && this.x + this.width / 2 < hole.x + 48) {
                                underHole = true;
                                break;
                            }
                        }
                    }

                    if (!underHole) {
                        playSound('sfx-bump');
                        this.y = floor.y + 26;
                        this.vy = 0.001; // Kicsi pozitív érték 0 helyett, hogy ne a fekvő sprite-ot rajzolja a levegőben
                        this.state = 'stun';
                        this.stunTimer = 128; // Beütötte a fejét, elkábult
                        break;
                    } else {
                        if (!this.scoredThisJump) {
                            this.score += 7;
                            this.scoredThisJump = true;
                            this.highestFloorReached = Math.max(this.highestFloorReached, floor.level);
                            if (this.score > this.highscore) this.highscore = this.score;
                        }
                        
                        if (floor.level === FLOOR_COUNT - 1 && !this.topReached) {
                            this.topReached = true;
                            this.vy = 0; // Ne emelkedjen a plafon fölé
                            this.y = floor.y; // Maradjon a plafon lyukában
                            this.state = 'win'; // Játékos lefagyasztása
                            this.levelCompleted = true; // Jelzés a Game osztálynak a padlók visszaállítására
                        }
                    }
                }
            }
        }

        // Ugrás
        if (keys.up && this.vy === 0 && this.state !== 'stun' && this.state !== 'win') {
            this.vy = JUMP_FORCE;
            this.state = 'jump';
            this.scoredThisJump = false; // Ugrás pontozásának alaphelyzetbe állítása
            keys.up = false; // A gombot fel kell engedni az újbóli ugráshoz
        }
    }

    /**
     * Kirajzolja a játékos aktuális animációs fázisát.
     * @param {CanvasRenderingContext2D} ctx A rajzolási kontextus.
     */
    draw(ctx) {
        let img = sprites.stand;
        let flipLeft = (this.facing === -1 && this.state !== 'stun');
        
        if (this.state === 'stun') {
            if (this.vy !== 0) {
                // If falling through a hole, use regular jump sprite instead of jumpbump
                if (this.willBeStunned) {
                    img = sprites.jump;
                } else {
                    img = sprites.jumpbump;
                }
            } else {
                // 128 ticks total on ground. 1 cycle = 16 ticks. Toggles every 8 ticks.
                let framePhase = Math.floor(this.stunTimer / 8) % 2;
                img = framePhase === 0 ? sprites.stun1 : sprites.stun2;
                let drawX = this.x + (this.width / 2) - (img.width / 2);
                let drawYOffset = window.isModern ? 2 : 0;
                let drawY = this.y + this.height - img.height - drawYOffset;
                if (img && img.complete && img.naturalWidth > 0) {
                    ctx.drawImage(img, drawX, drawY);
                } else {
                    ctx.fillStyle = '#ffaaaa';
                    ctx.fillRect(this.x, this.y, this.width, this.height);
                }
                return;
            }
        } else if (this.state === 'jump') {
            img = sprites.jump;
        } else if (this.state === 'win') {
            img = sprites.jump; // Keep the jumping pose while frozen in the hole
        } else if (this.state === 'run') {
            let animSpeed = window.isModern ? 100 : 200;
            let frame = Math.floor(Date.now() / animSpeed) % 4;
            if (frame === 0) img = sprites.run1;
            else if (frame === 1) img = sprites.run2;
            else if (frame === 2) img = sprites.run3;
            else img = sprites.run2;
        } else if (this.state === 'idle') {
            if (this.idleTimer > 5) { // after ~2 seconds
                let cycle = Math.floor((this.idleTimer - 5)/15) % 6; // change every 40 frames (~0.6s)
                if (cycle === 0) {
                    img = sprites.stand;
                } else if (cycle === 2) {
                    img = sprites.standright;
                    flipLeft = false; // look right
                } else if (cycle === 3) {
                    img = sprites.stand;
                } else if (cycle === 5) {
                    img = sprites.standright;
                    flipLeft = true; // look left (mirror image)
                }
            }
        }

        if (img && img.complete && img.naturalWidth > 0) {
            ctx.save();
            // Draw centered horizontally, aligned to bottom vertically
            let drawX = this.x + (this.width / 2) - (img.width / 2);
            let drawYOffset = window.isModern ? 2 : 0;
            let drawY = this.y + this.height - img.height - drawYOffset;
            
            if (flipLeft) {
                // Flip horizontally for left movement
                ctx.translate(drawX + img.width / 2, drawY + img.height / 2);
                ctx.scale(-1, 1);
                ctx.drawImage(img, -img.width / 2, -img.height / 2);
            } else {
                ctx.drawImage(img, drawX, drawY);
            }
            ctx.restore();
        } else {
            // Fallback stick figure if image isn't loaded yet
            ctx.fillStyle = '#000000';
            ctx.fillRect(this.x, this.y, this.width, this.height);
        }
    }
}

class Enemy {
    /**
     * Inicializál egy új ellenséget.
     * @param {number} type Az ellenség típusa (1-7).
     */
    constructor(type) {
        this.type = type; // 1 or 2
        this.animationTick = 0;
        this.reset();
    }
    
    /**
     * Alaphelyzetbe állítja az ellenség pozícióját a legfelső padlón.
     */
    reset() {
        this.level = FLOOR_COUNT - 2; // Legfelső BEJÁRHATÓ padló
        this.width = 30; // Fallback
        this.height = 36; // Fallback
        this.x = CANVAS_WIDTH;
        this.speed = -MOVE_SPEED; // Move left at same speed as holes/player
    }

    /**
     * Frissíti az ellenség helyzetét és kezeli a szintek közötti lépést.
     */
    update() {
        this.animationTick++;
        this.x += this.speed;
        // All enemies must travel the exact same distance to prevent them from catching up to each other due to different image widths.
        if (this.x <= -60) {
            this.level--;
            if (this.level <= 0) {
                // Skip bottom floor (0), respawn at top walkable floor
                this.level = FLOOR_COUNT - 2;
            }
            // Spawn just slightly offscreen so it immediately starts appearing
            this.x = CANVAS_WIDTH;
        }
    }

    /**
     * Kirajzolja az ellenséget a megfelelő animációval.
     * @param {CanvasRenderingContext2D} ctx A rajzolási kontextus.
     */
    draw(ctx) {
        let img;
        if (this.type === 7) {
            // Single phase animation
            img = sprites['enemy7a'];
        } else if (this.type === 6) {
            // Even faster animation (2 ticks per frame) with 3 phases
            let frame = Math.floor(this.animationTick / 2) % 3;
            if (frame === 0) img = sprites['enemy6a'];
            else if (frame === 1) img = sprites['enemy6b'];
            else img = sprites['enemy6c'];
        } else {
            // Standard animation (6 ticks per frame) with 2 phases
            let frame = Math.floor(this.animationTick / 6) % 2;
            img = frame === 0 ? sprites['enemy' + this.type + 'a'] : sprites['enemy' + this.type + 'b'];
        }
        
        let yOffset = this.type === 1 ? 1 : 0;
        if (window.isModern) {
            yOffset += 2; // Walk 2 pixels higher in 3D
        }
        
        if (img && img.complete && img.naturalWidth > 0) {
            this.width = img.width;
            this.height = img.height;
            let drawX = this.x;
            let drawY = BASE_Y - this.level * FLOOR_HEIGHT - this.height - yOffset;
            ctx.drawImage(img, drawX, drawY);
        } else {
            // Fallback
            let drawY = BASE_Y - this.level * FLOOR_HEIGHT - this.height - yOffset;
            ctx.fillStyle = '#ff0000';
            ctx.fillRect(this.x, drawY, this.width, this.height);
        }
    }
}

class Game {
    /**
     * Inicializálja a fő játékosztályt és beállítja a kezdőállapotot.
     */
    constructor() {
        this.player = new Player();
        this.floors = [];
        this.enemies = [];
        this.enemySpawnTimer = 0;
        this.lastStageFirstEnemyType = null;
        this.isPaused = false;
        this.transitionTimer = 0;
        this.ticks = 0;
        this.isGameOver = false;
        this.isMainMenu = true; // Itt kezdődik
        this.isIntro = false;
        this.introPhase = 0;
        this.introAlexX = 0;
        this.introTimer = 0;
        this.initFloors();
    }

    /**
     * Elindítja a játék bevezető animációját.
     */
    startIntro() {
        this.isIntro = true;
        this.introPhase = 0;
        this.introAlexX = 172 - 26; // 1 Alex szélesség + 10px a fehér dobozon kívül (a bal szél 172)
        this.introTimer = 0;
    }

    /**
     * Újraindítja a játékot, nullázva a pontszámokat (kivéve a rekordot) és a pályát.
     */
    restartGame() {
        let oldHighscore = this.player.highscore;
        this.player = new Player();
        this.player.highscore = oldHighscore;
        this.enemies = [];
        this.enemySpawnTimer = 0;
        this.lastStageFirstEnemyType = null;
        this.isGameOver = false;
        this.isPaused = false;
        this.transitionTimer = 0;
        this.ticks = 0;
        this.initFloors();
    }

    /**
     * Létrehozza és inicializálja a pálya padlóit.
     */
    initFloors() {
        this.floors = [];
        for (let i = 0; i < FLOOR_COUNT; i++) {
            let isBottom = (i === 0);
            this.floors.push(new Floor(i, BASE_Y - i * FLOOR_HEIGHT, isBottom));
        }
    }

    /**
     * A játék fő logikai ciklusa: frissíti az entitásokat és kezeli a játékmenetet.
     */
    update() {
        if (this.isMainMenu || this.isGameOver || this.isPaused) return;

        if (this.isIntro) {
            if (this.introPhase === 0) {
                // Slower movement to center
                this.introAlexX += 1;
                if (this.introAlexX >= 253 - 8) { // 253 is center, Alex is 16px wide -> center aligns
                    this.introAlexX = 253 - 8;
                    this.introPhase = 1;
                    this.introTimer = 30; // 1s várakozás kalapemelés előtt
                }
            } else if (this.introPhase === 1) {
                this.introTimer--;
                if (this.introTimer <= 0) {
                    this.introPhase = 2;
                    this.introTimer = 60; // Kalapemelés időtartama (hosszabb)
                }
            } else if (this.introPhase === 2) {
                this.introTimer--;
                if (this.introTimer <= 0) {
                    this.introPhase = 3;
                    this.introTimer = 60; // Hosszabb várakozás kalapvétel után
                }
            } else if (this.introPhase === 3) {
                this.introTimer--;
                if (this.introTimer <= 0) {
                    this.isIntro = false;
                    this.restartGame();
                }
            }
            return;
        }

        if (this.player.isDead) {
            this.isGameOver = true;
            this.player.isDead = false;
            return;
        }

        if (this.transitionTimer > 0) {
            this.transitionTimer--;
            if (this.transitionTimer <= 0) {
                this.player.score += 1125;
                if (this.player.score > this.player.highscore) this.player.highscore = this.player.score;
                this.player.stage++;
                this.player.reset();
                this.initFloors();
                
                // Ellenségek törlése a következő pályához
                this.enemies = [];
                this.enemySpawnTimer = 0;
            }
            return;
        }

        this.floors.forEach(f => f.update());
        this.player.update(this.floors);

        // Ellenség logika a 2. pályától kezdve
        if (this.player.stage >= 2) {
            let desiredEnemies = this.player.stage >= 7 ? 4 : (this.player.stage >= 6 ? 3 : (this.player.stage >= 4 ? 2 : 1));
            
            if (this.enemies.length < desiredEnemies) {
                let topFloorClear = !this.enemies.some(e => e.level === FLOOR_COUNT - 2);
                
                if (topFloorClear) {
                    if (this.enemies.length === 0) {
                        // Az első ellenség azonnal megjelenik, biztosítjuk, hogy más legyen, mint az előző pálya első ellensége
                        let randomType;
                        do {
                            randomType = Math.floor(Math.random() * 7) + 1;
                        } while (randomType === this.lastStageFirstEnemyType);
                        
                        this.lastStageFirstEnemyType = randomType;
                        this.enemies.push(new Enemy(randomType));
                        this.enemySpawnTimer = 0;
                    } else {
                        if (this.enemySpawnTimer <= 0) {
                            // Időzítő 0 és aközött, amikor az előző ellenség majdnem eléri a szintjének a végét
                            // A szint hossza 512, sebesség 2 -> ~256 tick. "Majdnem" = 220 tick.
                            this.enemySpawnTimer = Math.floor(Math.random() * 220);
                            if (this.enemySpawnTimer === 0) this.enemySpawnTimer = 1; // biztosítjuk, hogy legalább 1-et visszaszámoljon
                        } else {
                            this.enemySpawnTimer--;
                            if (this.enemySpawnTimer <= 0) {
                                let randomType = Math.floor(Math.random() * 7) + 1;
                                this.enemies.push(new Enemy(randomType));
                            }
                        }
                    }
                } else {
                    // Időzítő nullázása, amíg a legfelső padló ki nem ürül
                    this.enemySpawnTimer = 0;
                }
            }
            
            // Ellenségek frissítése, csak ha a játék nincs 'win' fagyasztott állapotban
            if (this.player.state !== 'win') {
                this.enemies.forEach(e => e.update());
            }

            // Ütközésvizsgálat
            if (this.player.state !== 'stun' && this.player.state !== 'win') {
                let px = this.player.x + 4; // kicsit vékonyabb hitbox
                let py = this.player.y + 8; // fizikai test eltolás
                let pw = this.player.width - 8;
                let ph = this.player.height - 12;
                
                for (let enemy of this.enemies) {
                    let yOffset = enemy.type === 1 ? 1 : 0;
                    let ex = enemy.x + 4; // kis térköz
                    let ey = BASE_Y - enemy.level * FLOOR_HEIGHT - enemy.height - yOffset + 4;
                    let ew = enemy.width - 8;
                    let eh = enemy.height - 8;
                    
                    if (px < ex + ew && px + pw > ex && py < ey + eh && py + ph > ey) {
                        playSound('sfx-bump');
                        this.player.vy = -3; // Felfelé pattanás
                        this.player.state = 'stun';
                        this.player.stunTimer = 128;
                        break;
                    }
                }
            }
        }

        if (this.player.levelCompleted) {
            this.transitionTimer = 75; // 2.5s késleltetés (30fps frissítési rátánál)
            this.player.levelCompleted = false;
        }
    }

    /**
     * Kirajzolja a felső/alsó információs sávot (életek, pontszám, csúcs).
     * @param {CanvasRenderingContext2D} ctx A rajzolási kontextus.
     */
    drawHUD(ctx) {
        ctx.fillStyle = '#ffff00';
        ctx.font = '20px "Courier New", Courier, monospace';
        ctx.textAlign = 'left';
        ctx.textBaseline = 'middle';
        
        let highscoreText = this.player.highscore.toString().padStart(6, '0');
        let scoreText = this.player.score.toString().padStart(6, '0');
        let textWidthH = ctx.measureText(highscoreText).width;
        let textWidthS = ctx.measureText(scoreText).width;
        
        let csucsW = (sprites.csucs && sprites.csucs.complete && sprites.csucs.naturalWidth > 0) ? sprites.csucs.width : ctx.measureText("CSÚCS:").width;
        let pontW = (sprites.pont && sprites.pont.complete && sprites.pont.naturalWidth > 0) ? sprites.pont.width : ctx.measureText("PONTOK:").width;
        
        let gap = 8;
        let middleGap = 40;        
        let centerY = CANVAS_HEIGHT - 24;

        // Segédfüggvények a 3D hatáshoz
        let draw3DText = (text, x, y) => {
            if (window.isModern) {
                ctx.fillStyle = '#804000'; // Sötét narancs/barna a 3D oldalhoz
                for (let j = 2; j >= 1; j--) {
                    ctx.fillText(text, x + j, y + j);
                }
                ctx.fillStyle = '#ffff00';
            }
            ctx.fillText(text, x, y);
        };

        let draw3DSprite = (sprite, x, y) => {
            if (window.isModern) {
                ctx.shadowColor = 'rgba(0, 0, 0, 0.7)'; // Fekete 3D oldal a képeknek
                ctx.shadowBlur = 0;
                for (let j = 2; j >= 1; j--) { 
                    ctx.shadowOffsetX = j;
                    ctx.shadowOffsetY = j;
                    ctx.drawImage(sprite, x, y);
                }
                ctx.shadowColor = 'transparent';
                ctx.shadowOffsetX = 0;
                ctx.shadowOffsetY = 0;
            }
            ctx.drawImage(sprite, x, y);
        };
        
        // --- 1. Életek rajzolása a bal szélre ---
        for (let i = 0; i < this.player.lives; i++) {
            let lx = 20 + i * 20;
            if (sprites.lives && sprites.lives.complete && sprites.lives.naturalWidth > 0) {
                draw3DSprite(sprites.lives, lx, centerY - sprites.lives.height / 2);
            } else {
                ctx.fillStyle = '#ffff00';
                ctx.beginPath();
                ctx.moveTo(lx, centerY + 4);
                ctx.lineTo(lx + 5, centerY - 4);
                ctx.lineTo(lx + 10, centerY + 4);
                ctx.fill();
            }
        }
        
        // --- 2. A 'csúcs' és a rekord rajzolása középre ---
        let csucsTotalW = csucsW + gap + textWidthH;
        let csucsStartX = (CANVAS_WIDTH - csucsTotalW) / 2; // tökéletesen középre igazítva
        let currentX = csucsStartX;
        
        if (sprites.csucs && sprites.csucs.complete && sprites.csucs.naturalWidth > 0) {
            draw3DSprite(sprites.csucs, currentX, centerY - sprites.csucs.height / 2);
        } else {
            draw3DText("CSÚCS:", currentX, centerY);
        }
        currentX += csucsW + gap;
        draw3DText(highscoreText, currentX, centerY + 2);
        
        // --- 3. A 'pont' és a pontszám rajzolása a jobb szélre ---
        let pontTotalW = pontW + gap + textWidthS;
        let pontStartX = CANVAS_WIDTH - 20 - pontTotalW;
        currentX = pontStartX;
        
        if (sprites.pont && sprites.pont.complete && sprites.pont.naturalWidth > 0) {
            draw3DSprite(sprites.pont, currentX, centerY - sprites.pont.height / 2);
        } else {
            draw3DText("PONTOK:", currentX, centerY);
        }
        currentX += pontW + gap;
        draw3DText(scoreText, currentX, centerY + 2); 
        
        ctx.textBaseline = 'alphabetic';

        if (this.isPaused) {
            ctx.fillStyle = '#ffffff';
            ctx.fillText("PAUSE", CANVAS_WIDTH / 2 - 20, CANVAS_HEIGHT / 2);
        }
    }

    /**
     * A játék fő rajzoló függvénye: mindent kirajzol a képernyőre.
     * @param {CanvasRenderingContext2D} ctx A rajzolási kontextus.
     */
    draw(ctx) {
        // Háttér törlése pontos TVC cián színnel
        ctx.fillStyle = window.isModern ? BG_TEAL : '#198686';
        ctx.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

        // Padlók rajzolása
        this.floors.forEach(f => f.draw(ctx));

        // Ellenségek rajzolása
        this.enemies.forEach(e => e.draw(ctx));

        // Játékos rajzolása
        this.player.draw(ctx);

        // HUD terület hátterének rajzolása
        ctx.fillStyle = window.isModern ? HUD_BG : '#198686';
        let hudY = window.isModern ? BASE_Y + 12 : BASE_Y + 8;
        ctx.fillRect(0, hudY, CANVAS_WIDTH, CANVAS_HEIGHT - hudY);

        this.drawHUD(ctx);

        if (this.isMainMenu) {
            // Főképernyő rajzolása középre
            if (sprites.mainscreen && sprites.mainscreen.complete && sprites.mainscreen.naturalWidth > 0) {
                let dx = (CANVAS_WIDTH - sprites.mainscreen.width) / 2;
                let dy = (CANVAS_HEIGHT - sprites.mainscreen.height) / 2;
                ctx.drawImage(sprites.mainscreen, dx, dy);
            } else {
                ctx.fillStyle = '#000000';
                ctx.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
                ctx.fillStyle = '#ffffff';
                ctx.font = 'bold 30px "Courier New"';
                ctx.textAlign = 'center';
                ctx.fillText("MR. ALEX", CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2);
            }
        } else if (this.isIntro) {
            ctx.fillStyle = '#000000';
            ctx.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
            
            // Intróképernyő rajzolása
            if (sprites.introscreen && sprites.introscreen.complete && sprites.introscreen.naturalWidth > 0) {
                let dx = (CANVAS_WIDTH - sprites.introscreen.width) / 2;
                let dy = (CANVAS_HEIGHT - sprites.introscreen.height) / 2;
                ctx.drawImage(sprites.introscreen, dx, dy);
            }
            
            // Alex rajzolása
            let alexImg;
            if (this.introPhase === 0) {
                let frame = Math.floor(Date.now() / 200) % 4;
                if (frame === 0) alexImg = sprites.run1;
                else if (frame === 1) alexImg = sprites.run2;
                else if (frame === 2) alexImg = sprites.run3;
                else alexImg = sprites.run2;
            } else if (this.introPhase === 1 || this.introPhase === 3) {
                alexImg = sprites.standright; // Valójában a stand1 előre néz, a felhasználó a stand1-et kérte.
                // Várj, a "stand1 .png" a "stand". Megnézem a loadSprite-ot.
                alexImg = sprites.stand;
            } else if (this.introPhase === 2) {
                alexImg = sprites.hatup;
            }
            
            if (alexImg && alexImg.complete && alexImg.naturalWidth > 0) {
                if (window.isModern) {
                    ctx.save();
                    // Vágómaszk létrehozása, hogy Alex csak a FEHÉR dobozban legyen látható
                    // A fehér doboz bal széle x=172-nél van. A közepe 256. A szélessége 168.
                    ctx.beginPath();
                    ctx.rect(172, 100, 168, 250);
                    ctx.clip();
                }
                
                // A kép vízszintes középre igazítása az introAlexX + 8 körül (16-os logikai szélességet feltételezve)
                let drawX = this.introAlexX + 8 - (alexImg.width / 2);
                // A fehér négyzet alja 320 + 1 pixellel lejjebb van
                let drawY = 321 - alexImg.height;
                ctx.drawImage(alexImg, drawX, drawY);

                if (window.isModern) {
                    ctx.restore();
                }
            }
        } else if (this.isGameOver) {
            ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
            ctx.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
            
            ctx.fillStyle = '#ffffff';
            ctx.font = 'bold 40px "Courier New"';
            ctx.textAlign = 'center';
            ctx.fillText("JÁTÉK VÉGE", CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2 - 20);
            
            ctx.font = '20px "Courier New"';
            ctx.fillText("Nyomj UGRÁST az újrakezdéshez", CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2 + 20);
            ctx.textAlign = 'left';
        }
    }

    /**
     * A játék fő iterációs ciklusa, ami meghívja a frissítést és a rajzolást.
     */
    loop() {
        this.ticks++;
        if (this.ticks % 2 === 0) {
            this.update();
        }
        this.draw(ctx);
        requestAnimationFrame(() => this.loop());
    }
}

// Játék indítása
const game = new Game();
game.loop();
