class Game {
    constructor() {
        this.canvas = document.getElementById('gameCanvas');
        this.ctx = this.canvas.getContext('2d');
        this.ctx.imageSmoothingEnabled = false;
        
        this.spriteSheet = new Image();
        this.backgroundMusic = new Audio();
        
        this.player = null;
        this.backgroundElements = [];
        this.backgroundLayers = {
            far: [],      // Elementos muy lejanos (nubes, montañas)
            mid: [],      // Elementos medios (árboles, edificios)
            near: []      // Elementos cercanos (decoraciones, elementos interactivos)
        };
        
        // Sistema de generación de nubes mejorado
        this.cloudSystem = new CloudSystem(this.canvas);
        
        // Sistema de objetos de fondo
        this.backgroundObjectSystem = new BackgroundObjectSystem(this.canvas, this);
        
        // Sistema de letras sincronizadas
        this.lyricsSystem = new LyricsSystem();
        
        // Estado del juego
        this.gameState = 'playing'; // 'playing', 'gameOver', 'paused'
        
        // Definir tipos de elementos con sus configuraciones
        this.elementTypes = {
            floor: {
                renderMethod: 'sprite',
                defaultSpriteCoords: { x: 2, y: 430, w: 32, h: 32 },
                layer: 'near'
            },
            decoration: {
                renderMethod: 'sprite',
                defaultSpriteCoords: { x: 137, y: 104, w: 35, h: 26 },
                layer: 'near'
            },
            background: {
                renderMethod: 'color',
                color: '#4A90E2',
                layer: 'far'
            },
            text: {
                renderMethod: 'text',
                font: '12px Arial',
                color: 'white',
                align: 'center',
                layer: 'near'
            },
            sprite: {
                renderMethod: 'sprite',
                layer: 'near'
            },
            cloud: {
                renderMethod: 'sprite',
                layer: 'far',
                defaultSpriteCoords: { x: 231, y: 112, w: 287, h: 148 },
                autoMove: true,
                moveSpeed: 0.5
            },
            backgroundObject: {
                renderMethod: 'sprite',
                layer: 'mid',
                autoMove: true,
                moveSpeed: 0.1,
                // Definir las variantes de sprites disponibles
                spriteVariants: [
                    { x: 546, y: 264, w: 30, h: 21 },
                    { x: 546, y: 286, w: 30, h: 21 },
                    { x: 546, y: 308, w: 30, h: 25 },
                    { x: 546, y: 334, w: 30, h: 24 },
                    { x: 546, y: 359, w: 30, h: 21 },
                    { x: 545, y: 382, w: 31, h: 29 },
                    { x: 516, y: 264, w: 29, h: 17 },
                    { x: 516, y: 282, w: 29, h: 21 },
                    { x: 516, y: 304, w: 29, h: 18 },
                    { x: 516, y: 323, w: 29, h: 18 },
                    { x: 516, y: 342, w: 29, h: 19 },
                    { x: 516, y: 362, w: 29, h: 19 },
                    { x: 516, y: 382, w: 28, h: 29 },
                    { x: 491, y: 270, w: 24, h: 26 },
                    { x: 491, y: 297, w: 24, h: 26 },
                    { x: 491, y: 324, w: 24, h: 26 },
                    { x: 491, y: 353, w: 24, h: 26 },
                    { x: 489, y: 382, w: 26, h: 29 },
                    { x: 465, y: 310, w: 25, h: 23 },
                    { x: 465, y: 334, w: 25, h: 23 },
                    { x: 465, y: 358, w: 25, h: 23 },
                    { x: 465, y: 382, w: 11, h: 29 },
                    { x: 477, y: 382, w: 11, h: 29 }
                ]
            }
        };
        
        this.init();
    }
    
    init() {
        // Load assets
        this.spriteSheet.src = 'assets/sprites.png';
        this.backgroundMusic.src = 'assets/music.mp3';
        
        // Configure audio
        this.backgroundMusic.loop = true;
        this.backgroundMusic.volume = 0.05;
        
        // Create sprite processor for color key-out
        this.spriteProcessor = new SpriteProcessor();
        
        // Wait for assets to load
        Promise.all([
            new Promise(resolve => this.spriteSheet.onload = resolve),
            new Promise(resolve => this.backgroundMusic.oncanplaythrough = resolve)
        ]).then(() => {
            // Process sprite sheet to remove #00ffff background
            this.processedSpriteSheet = this.spriteProcessor.processSpriteSheet(this.spriteSheet, '#00ffff');
            this.processedSpriteSheet.onload = () => {
                this.startGame();
            };
        });
        
        // Handle audio context (for browsers that require user interaction)
        const startMusic = () => {
            if (this.backgroundMusic.paused && this.gameState === 'playing') {
                this.backgroundMusic.play().catch(e => console.log('Audio play failed:', e));
            }
        };
        
        this.canvas.addEventListener('click', startMusic);
        this.canvas.addEventListener('touchstart', startMusic, { passive: true });
        
        // Agregar controles de teclado
        this.setupKeyboardControls();
        
        // Inicializar controles táctiles para dispositivos móviles
        this.touchControls = new TouchControls(this.canvas, input);
    }
    
    // Método para agregar elementos de forma dinámica
    addElement(type, x, y, w, h, options = {}) {
        const elementConfig = this.elementTypes[type];
        const layer = options.layer || elementConfig?.layer || 'near';
        
        const element = {
            type,
            x,
            y,
            w,
            h,
            ...options
        };
        
        // Agregar a la capa correspondiente
        if (this.backgroundLayers[layer]) {
            this.backgroundLayers[layer].push(element);
        } else {
            this.backgroundElements.push(element);
        }
        
        return element;
    }
    
    // Método para agregar elementos de piso
    addFloorTile(x, y) {
        return this.addElement('floor', x, y, 32, 32);
    }
    
    // Método para agregar decoraciones
    addDecoration(x, y, w = 35, h = 26) {
        return this.addElement('decoration', x, y, w, h);
    }
    
    // Método para agregar elementos de color sólido
    addColorElement(x, y, w, h, color, layer = 'far') {
        return this.addElement('background', x, y, w, h, { color, layer });
    }
    
    // Método para agregar texto
    addText(x, y, text, options = {}) {
        return this.addElement('text', x, y, 0, 0, { text, ...options });
    }
    
    // Método para agregar sprites personalizados
    addSprite(x, y, w, h, spriteCoords, options = {}) {
        return this.addElement('sprite', x, y, w, h, { 
            spriteCoords,
            ...options 
        });
    }
    
    // Método para agregar cualquier sprite con coordenadas específicas
    addCustomSprite(type, x, y, w, h, spriteCoords, options = {}) {
        return this.addElement(type, x, y, w, h, { 
            spriteCoords,
            ...options 
        });
    }
    
    startGame() {
        // Create player
        this.player = new Player(72, 88, this.processedSpriteSheet);
        
        // Crear elementos de fondo usando los nuevos métodos
        // Piso
        for (let i = 0; i < 10; i++) {
            this.addFloorTile(i * 32, 208);
        }
        
        // Inicializar sistema de nubes
        this.cloudSystem.init(this.processedSpriteSheet, this.backgroundLayers.far);
        
        // Inicializar sistema de objetos de fondo
        this.backgroundObjectSystem.init(this.processedSpriteSheet, this.backgroundLayers.mid);
        
        // Macarons
        this.addSprite(10, 183, 35, 26, { x: 137, y: 104, w: 35, h: 26 });
        this.addSprite(42, 183, 35, 26, { x: 173, y: 104, w: 35, h: 26 });
        this.addSprite(74, 183, 35, 26, { x: 137, y: 131, w: 35, h: 26 });
        this.addSprite(106, 183, 35, 26, { x: 173, y: 131, w: 35, h: 26 });

        // Candybar
        this.addSprite(200, 130, 48, 79, { x: 179, y: 438, w: 48, h: 79 });

        // Cake
        this.addSprite(260, 134, 100, 75, { x: 461, y: 414, w: 100, h: 75 });

        // Cat
        this.addSprite(185, 187, 20, 23, { x: 235, y: 87, w: 20, h: 23 });
        this.addSprite(200, 187, 20, 23, { x: 389, y: 87, w: 16, h: 23 });
        
        this.gameLoop();
    }
    
    update() {
        if (this.gameState !== 'playing') return;
        
        if (this.player) {
            this.player.update();
        }
        
        // Actualizar sistema de nubes
        this.cloudSystem.update();
        
        // Actualizar sistema de objetos de fondo
        this.backgroundObjectSystem.update();
        
        // Actualizar sistema de letras
        if (!this.backgroundMusic.paused) {
            this.lyricsSystem.update(this.backgroundMusic.currentTime);
            
            // Verificar si la canción ha terminado y detenerla
            if (this.lyricsSystem.isGameOver && !this.backgroundMusic.paused) {
                this.backgroundMusic.pause();
                this.gameState = 'gameOver';
            }
        }
    }
    
    // Método para renderizar un elemento individual
    renderElement(element) {
        const elementConfig = this.elementTypes[element.type];
        if (!elementConfig) {
            console.warn(`Tipo de elemento desconocido: ${element.type}`);
            return;
        }
        
        switch (elementConfig.renderMethod) {
            case 'sprite':
                this.renderSpriteElement(element, elementConfig);
                break;
            case 'color':
                this.renderColorElement(element, elementConfig);
                break;
            case 'text':
                this.renderTextElement(element, elementConfig);
                break;
            default:
                console.warn(`Método de renderizado desconocido: ${elementConfig.renderMethod}`);
        }
    }
    
    renderSpriteElement(element, config) {
        // Usar coordenadas personalizadas si están especificadas, sino usar las por defecto
        const spriteCoords = element.spriteCoords || config.defaultSpriteCoords;
        
        if (!spriteCoords) {
            console.warn(`No se especificaron coordenadas de sprite para elemento tipo: ${element.type}`);
            return;
        }
        
        // Si el elemento tiene rotación, aplicar transformaciones
        if (element.rotation) {
            this.ctx.save();
            
            // Calcular el centro del sprite para la rotación
            const centerX = element.x + element.w / 2;
            const centerY = element.y + element.h / 2;
            
            // Aplicar transformaciones
            this.ctx.translate(centerX, centerY);
            this.ctx.rotate(element.rotation);
            this.ctx.translate(-centerX, -centerY);
        }
        
        this.ctx.drawImage(
            this.processedSpriteSheet,
            spriteCoords.x, spriteCoords.y, spriteCoords.w, spriteCoords.h,
            element.x, element.y, element.w, element.h
        );
        
        // Restaurar el contexto si se aplicó rotación
        if (element.rotation) {
            this.ctx.restore();
        }
    }
    
    renderColorElement(element, config) {
        const color = element.color || config.color;
        this.ctx.fillStyle = color;
        this.ctx.fillRect(element.x, element.y, element.w, element.h);
    }
    
    renderTextElement(element, config) {
        this.ctx.fillStyle = element.color || config.color;
        this.ctx.font = element.font || config.font;
        this.ctx.textAlign = element.align || config.align;
        this.ctx.fillText(element.text, element.x, element.y);
    }
    
    draw() {
        // Clear canvas con degradado
        const gradient = this.ctx.createLinearGradient(0, 0, 0, this.canvas.height);
        gradient.addColorStop(0, '#d9e6ff');    // Color superior
        gradient.addColorStop(1, '#eee5ff');    // Color inferior
        
        this.ctx.fillStyle = gradient;
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
        
        // Renderizar elementos por capas (de lejos a cerca)
        // Capa lejana (nubes, montañas)
        this.backgroundLayers.far.forEach(element => {
            this.renderElement(element);
        });
        
        // Capa media (árboles, edificios)
        this.backgroundLayers.mid.forEach(element => {
            this.renderElement(element);
        });
        
        // Capa cercana (decoraciones, elementos interactivos)
        this.backgroundLayers.near.forEach(element => {
            this.renderElement(element);
        });
        
        // Elementos legacy (para compatibilidad)
        this.backgroundElements.forEach(element => {
            this.renderElement(element);
        });
        
        // Draw player
        if (this.player) {
            this.player.draw(this.ctx);
        }
        
        // Dibujar letras si están activadas
        this.lyricsSystem.draw(this.ctx, this.canvas);
        
        // Draw instructions if music hasn't started
        if (this.backgroundMusic.paused && this.gameState === 'playing') {
            this.ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
            this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
            
            this.ctx.fillStyle = 'white';
            this.ctx.font = '10px Courier New';
            this.ctx.textAlign = 'center';
            this.ctx.fillText('Click to start music', 160, 100);
            this.ctx.fillText('WASD or ↑↓←→  to move', 160, 115);
            this.ctx.fillText('L - Show/Hide lyrics', 160, 130);
            this.ctx.fillText('R - Restart game', 160, 145);
        }
        
        // Dibujar pantalla de fin de juego
        if (this.lyricsSystem.gameOverScreen) {
            this.drawGameOverScreen();
        }
    }
    
    gameLoop() {
        this.update();
        this.draw();
        requestAnimationFrame(() => this.gameLoop());
    }
    
    setupKeyboardControls() {
        document.addEventListener('keydown', (e) => {
            switch(e.key.toLowerCase()) {
                case 'l':
                    this.lyricsSystem.toggleLyrics();
                    break;
                case 'r':
                    this.restartGame();
                    break;
                case 'g':
                    // Shortcut para desarrollo: simular fin de canción
                    if (e.ctrlKey) {
                        this.lyricsSystem.simulateGameOver();
                    }
                    break;
            }
        });
    }
    
    drawGameOverScreen() {
        // Fondo negro translúcido
        this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
        
        // Texto de fin de juego
        this.ctx.fillStyle = 'white';
        this.ctx.font = '20px Courier New';
        this.ctx.textAlign = 'center';
        
        this.ctx.fillText('Song finished!', 160, 100);
        this.ctx.fillText('Want to play again?', 160, 125);
        
        // Botones
        this.ctx.font = '12px Courier New';
        this.ctx.fillText('Press R to restart', 160, 175);
        this.ctx.fillText('or reload the page', 160, 190);
    }
    
    restartGame() {
        // Detener música
        this.backgroundMusic.pause();
        this.backgroundMusic.currentTime = 0;
        
        // Reiniciar sistemas
        this.lyricsSystem.reset();
        
        // Reiniciar estado del juego
        this.gameState = 'playing';
        
        // Limpiar elementos de fondo
        this.backgroundLayers.far = [];
        this.backgroundLayers.mid = [];
        this.backgroundLayers.near = [];
        this.backgroundElements = [];
        
        // Reiniciar sistemas
        this.cloudSystem.init(this.processedSpriteSheet, this.backgroundLayers.far);
        this.backgroundObjectSystem.init(this.processedSpriteSheet, this.backgroundLayers.mid);
        
        // Reiniciar jugador
        this.player = new Player(144, 176, this.processedSpriteSheet);
        
        // Recrear elementos de fondo
        this.recreateBackgroundElements();
    }
    
    recreateBackgroundElements() {
        // Piso - adjusted for 320x240 canvas
        for (let i = 0; i < 10; i++) {
            this.addFloorTile(i * 32, 208); // 240-32=208
        }
        
        // Macarons - original positions
        this.addSprite(10, 183, 35, 26, { x: 137, y: 104, w: 35, h: 26 });
        this.addSprite(42, 183, 35, 26, { x: 173, y: 104, w: 35, h: 26 });
        this.addSprite(74, 183, 35, 26, { x: 137, y: 131, w: 35, h: 26 });
        this.addSprite(106, 183, 35, 26, { x: 173, y: 131, w: 35, h: 26 });

        // Candybar - original size and position
        this.addSprite(200, 130, 48, 79, { x: 179, y: 438, w: 48, h: 79 });

        // Cake - original size and position
        this.addSprite(260, 134, 100, 75, { x: 461, y: 414, w: 100, h: 75 });

        // Cat - original positions
        this.addSprite(185, 187, 20, 23, { x: 235, y: 87, w: 20, h: 23 });
        this.addSprite(200, 187, 20, 23, { x: 389, y: 87, w: 16, h: 23 });
    }
}

// Clase para manejar el sistema de nubes de forma modular
class CloudSystem {
    constructor(canvas) {
        this.canvas = canvas;
        this.spriteSheet = null;
        this.cloudLayer = null;
        this.frameCount = 0;
        
        // Configuración para canvas 320x240
        this.config = {
            spawnRate: 0.1,           // Probabilidad de spawn por frame
            maxClouds: 2,               // Máximo número de nubes en pantalla
            speedRange: { min: 0.125, max: 0.1875 },  // Velocidad de movimiento (original)
            yRange: { min: 1, max: 150 },        // Rango de altura (original)
            spriteCoords: { x: 231, y: 112, w: 287, h: 148 },
            size: { w: 287, h: 148 },  // Tamaño original de nube
            minSpacing: 125,            // Espaciado mínimo entre nubes (original)
            minTimeBetweenSpawns: 60    // Frames mínimos entre apariciones
        };
        
        this.lastSpawnTime = 0;
    }
    
    init(spriteSheet, cloudLayer) {
        this.spriteSheet = spriteSheet;
        this.cloudLayer = cloudLayer;
        
        // Generar nubes iniciales para que el fondo no se vea vacío
        this.spawnInitialClouds();
    }
    
    spawnInitialClouds() {
        // Generar 2-3 nubes iniciales en posiciones aleatorias
        const initialCount = Math.floor(Math.random() * 2) + 2;
        
        for (let i = 0; i < initialCount; i++) {
            const x = Math.random() * this.canvas.width;
            const y = this.getRandomY();
            const speed = this.getRandomSpeed();
            
            this.createCloud(x, y, speed);
        }
    }
    
    update() {
        this.frameCount++;
        
        // Limpiar nubes que salieron de la pantalla
        this.cleanupOffscreenClouds();
        
        // Intentar generar nueva nube
        if (this.shouldSpawnCloud()) {
            this.spawnCloud();
        }
        
        // Mover nubes existentes
        this.moveClouds();
    }
    
    shouldSpawnCloud() {
        // Verificar tiempo mínimo entre apariciones
        if (this.frameCount - this.lastSpawnTime < this.config.minTimeBetweenSpawns) {
            return false;
        }
        
        // Verificar número máximo de nubes
        const cloudCount = this.cloudLayer.filter(e => e.type === 'cloud').length;
        if (cloudCount >= this.config.maxClouds) {
            return false;
        }
        
        // Verificar probabilidad de spawn
        if (Math.random() > this.config.spawnRate) {
            return false;
        }
        
        // Verificar espaciado mínimo
        const hasSpacing = this.hasEnoughSpacing();
        
        // Debug: mostrar información cada 60 frames (1 segundo)
        if (this.frameCount % 60 === 0) {
            console.log(`Clouds: ${cloudCount}/${this.config.maxClouds}, Spacing: ${hasSpacing}, Time: ${this.frameCount - this.lastSpawnTime}`);
        }
        
        return hasSpacing;
    }
    
    hasEnoughSpacing() {
        const existingClouds = this.cloudLayer.filter(e => e.type === 'cloud');
        
        // Si no hay nubes, siempre se puede generar
        if (existingClouds.length === 0) {
            return true;
        }
        
        // Verificar que no haya nubes muy cerca del borde derecho
        for (const cloud of existingClouds) {
            const distanceFromRight = this.canvas.width - cloud.x;
            if (distanceFromRight < this.config.minSpacing) {
                return false;
            }
        }
        
        return true;
    }
    
    spawnCloud() {
        const y = this.getRandomY();
        const speed = this.getRandomSpeed();
        
        // Generar desde la derecha de la pantalla
        const x = this.canvas.width;
        
        this.createCloud(x, y, speed);
        this.lastSpawnTime = this.frameCount;
        
        console.log(`Nueva nube generada en (${x}, ${y}) con velocidad ${speed}`);
    }
    
    createCloud(x, y, speed) {
        const cloud = {
            type: 'cloud',
            x: x,
            y: y,
            w: this.config.size.w,
            h: this.config.size.h,
            spriteCoords: this.config.spriteCoords,
            moveSpeed: speed,
            layer: 'far'
        };
        
        this.cloudLayer.push(cloud);
    }
    
    moveClouds() {
        this.cloudLayer.forEach(cloud => {
            if (cloud.type === 'cloud' && cloud.moveSpeed) {
                cloud.x -= cloud.moveSpeed;
            }
        });
    }
    
    cleanupOffscreenClouds() {
        for (let i = this.cloudLayer.length - 1; i >= 0; i--) {
            const element = this.cloudLayer[i];
            if (element.type === 'cloud' && element.x + element.w < 0) {
                this.cloudLayer.splice(i, 1);
            }
        }
    }
    
    getRandomY() {
        return Math.random() * 
            (this.config.yRange.max - this.config.yRange.min) + 
            this.config.yRange.min;
    }
    
    getRandomSpeed() {
        return Math.random() * 
            (this.config.speedRange.max - this.config.speedRange.min) + 
            this.config.speedRange.min;
    }
}

// Clase para manejar el sistema de objetos de fondo
class BackgroundObjectSystem {
    constructor(canvas, game) {
        this.canvas = canvas;
        this.game = game;
        this.spriteSheet = null;
        this.objectLayer = null;
        this.frameCount = 0;
        
        // Configuración para objetos de fondo (320x240 canvas)
        this.config = {
            spawnRate: 0.15,           // Probabilidad de spawn por frame
            maxObjects: 150,              // Máximo número de objetos en pantalla (reducido)
            speedRange: { min: 0.0625, max: 0.125 },  // Velocidad de movimiento (original)
            yRange: { min: 12, max: 225 },        // Rango de altura (original)
            minSpacing: 150,            // Espaciado mínimo entre grupos (original)
            minTimeBetweenSpawns: 120,  // Frames mínimos entre apariciones
            groupSize: { min: 4, max: 8 }, // Tamaño del grupo de objetos (original)
            groupSpacing: { min: 8, max: 40 } // Espaciado entre objetos en el grupo (original)
        };
        
        this.lastSpawnTime = 0;
    }
    
    init(spriteSheet, objectLayer) {
        this.spriteSheet = spriteSheet;
        this.objectLayer = objectLayer;
        
        // Generar objetos iniciales
        this.spawnInitialObjects();
    }
    
    spawnInitialObjects() {
        // Generar objetos en múltiples filas para mejor distribución
        const layers = 3; // Número de capas de profundidad
        const groupsPerLayer = 4; // Grupos por capa
        
        for (let layer = 0; layer < layers; layer++) {
            for (let i = 0; i < groupsPerLayer; i++) {
                // Distribuir horizontalmente
                const x = (i * this.canvas.width / groupsPerLayer) + (Math.random() * 150);
                
                // Crear diferentes niveles de altura
                const baseY = 100 + (layer * 120); // Capas a diferentes alturas
                const y = baseY + (Math.random() * 80 - 40); // Variación aleatoria
                
                // Velocidad ligeramente diferente por capa para efecto parallax
                const baseSpeed = this.getRandomSpeed();
                const speed = baseSpeed * (1 + layer * 0.1);
                
                this.createObjectGroup(x, y, speed);
            }
        }
    }
    
    update() {
        this.frameCount++;
        
        // Limpiar objetos que salieron de la pantalla
        this.cleanupOffscreenObjects();
        
        // Intentar generar nuevo grupo
        if (this.shouldSpawnObjectGroup()) {
            this.spawnObjectGroup();
        }
        
        // Mover objetos existentes
        this.moveObjects();
    }
    
    shouldSpawnObjectGroup() {
        // Verificar tiempo mínimo entre apariciones
        if (this.frameCount - this.lastSpawnTime < this.config.minTimeBetweenSpawns) {
            return false;
        }
        
        // Verificar número máximo de objetos
        const objectCount = this.objectLayer.filter(e => e.type === 'backgroundObject').length;
        if (objectCount >= this.config.maxObjects) {
            return false;
        }
        
        // Verificar probabilidad de spawn
        if (Math.random() > this.config.spawnRate) {
            return false;
        }
        
        // Verificar espaciado mínimo
        const hasSpacing = this.hasEnoughSpacing();
        
        return hasSpacing;
    }
    
    hasEnoughSpacing() {
        const existingObjects = this.objectLayer.filter(e => e.type === 'backgroundObject');
        
        // Si no hay objetos, siempre se puede generar
        if (existingObjects.length === 0) {
            return true;
        }
        
        // Verificar que no haya objetos muy cerca del borde derecho
        for (const obj of existingObjects) {
            const distanceFromRight = this.canvas.width - obj.x;
            if (distanceFromRight < this.config.minSpacing) {
                return false;
            }
        }
        
        return true;
    }
    
    spawnObjectGroup() {
        // Generar múltiples grupos a diferentes alturas simultáneamente
        const numLayers = Math.floor(Math.random() * 2) + 2; // 2-3 capas
        
        for (let i = 0; i < numLayers; i++) {
            // Diferentes alturas para cada capa
            const baseY = 100 + (i * 150);
            const y = baseY + (Math.random() * 100 - 50);
            
            // Velocidad ligeramente diferente por capa
            const baseSpeed = this.getRandomSpeed();
            const speed = baseSpeed * (1 + i * 0.15);
            
            // Generar desde la derecha de la pantalla con ligera variación
            const x = this.canvas.width + (Math.random() * 100);
            
            this.createObjectGroup(x, y, speed);
        }
        
        this.lastSpawnTime = this.frameCount;
        console.log(`Nuevos grupos de objetos generados en múltiples capas`);
    }
    
    createObjectGroup(x, y, speed) {
        const groupSize = Math.floor(Math.random() * 
            (this.config.groupSize.max - this.config.groupSize.min + 1)) + 
            this.config.groupSize.min;
        
        // Obtener las variantes de sprites desde elementTypes
        const spriteVariants = this.game.elementTypes.backgroundObject.spriteVariants;
        
        let currentX = x;
        
        for (let i = 0; i < groupSize; i++) {
            // Seleccionar sprite aleatorio
            const spriteVariant = spriteVariants[Math.floor(Math.random() * spriteVariants.length)];
            
            // Aplicar rotación aleatoria
            const rotation = (Math.random() - 0.5) * 0.8; // ±0.4 radianes
            
            // Aplicar dispersión vertical aleatoria
            const yOffset = (Math.random() - 0.5) * 40; // ±20 píxeles
            
            // Use original size for background objects
            const object = {
                type: 'backgroundObject',
                x: currentX,
                y: y + yOffset,
                w: spriteVariant.w,
                h: spriteVariant.h,
                spriteCoords: spriteVariant,
                moveSpeed: speed,
                rotation: rotation,
                layer: 'mid'
            };
            
            this.objectLayer.push(object);
            
            // Calcular siguiente posición con espaciado aleatorio
            const spacing = Math.random() * 
                (this.config.groupSpacing.max - this.config.groupSpacing.min) + 
                this.config.groupSpacing.min;
            currentX += spriteVariant.w + spacing;
        }
    }
    
    moveObjects() {
        this.objectLayer.forEach(obj => {
            if (obj.type === 'backgroundObject' && obj.moveSpeed) {
                obj.x -= obj.moveSpeed;
            }
        });
    }
    
    cleanupOffscreenObjects() {
        for (let i = this.objectLayer.length - 1; i >= 0; i--) {
            const element = this.objectLayer[i];
            if (element.type === 'backgroundObject' && element.x + element.w < 0) {
                this.objectLayer.splice(i, 1);
            }
        }
    }
    
    getRandomY() {
        return Math.random() * 
            (this.config.yRange.max - this.config.yRange.min) + 
            this.config.yRange.min;
    }
    
    getRandomSpeed() {
        return Math.random() * 
            (this.config.speedRange.max - this.config.speedRange.min) + 
            this.config.speedRange.min;
    }
}

// Initialize game when DOM is loaded
window.addEventListener('DOMContentLoaded', () => {
    new Game();
});