Code edit (1 edits merged)
Please save this source code
User prompt
puedes hacer que ese texto se centre, es decir que sea centrado porfa
Code edit (2 edits merged)
Please save this source code
User prompt
Quiero que tenga un tipografia pixelar con negrita gruesa de color blanco y si se puede con online ademaas que se posicione mejor en el centro de la apntalla ya que no salio exacto en la mitad var combinationMessageText = new Text2('', { size: 80, fill: 0xFFFF00 }); combinationMessageText.anchor.set(0.5, 0.5); combinationMessageText.x = 524; // Center of screen width combinationMessageText.y = 800; // Above other debug texts combinationMessageText.alpha = 0; game.addChild(combinationMessageText);
Code edit (2 edits merged)
Please save this source code
User prompt
showCombinationMessage haz que este texto este en la capa gui porfa
Code edit (1 edits merged)
Please save this source code
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: numberComic is not defined' in or related to this line: 'numberComic.setText('Comic: ' + (currentComicIndex + 1) + '/' + maxComics);' Line Number: 6569
Code edit (2 edits merged)
Please save this source code
User prompt
usa el/* */ para encerrrar el codigo de textos informaticos primero con el texto comic informativo
User prompt
Please fix the bug: 'timingIntervalsText is not defined' in or related to this line: 'timingIntervalsText.anchor.set(0.5, 0.5);' Line Number: 4797
User prompt
Please fix the bug: 'numberComic is not defined' in or related to this line: 'numberComic.anchor.set(0.5, 0.5);' Line Number: 4788
User prompt
Please fix the bug: 'numberComic is not defined' in or related to this line: 'numberComic.anchor.set(0.5, 0.5);' Line Number: 4788
User prompt
Please fix the bug: 'collisionDebugText is not defined' in or related to this line: 'collisionDebugText.anchor.set(0.5, 0.5);' Line Number: 4733
Code edit (1 edits merged)
Please save this source code
User prompt
agrega nos bootnes mas de niveles porfa
Code edit (1 edits merged)
Please save this source code
User prompt
agrega dos niveles, y si el juagdor llega al nivel 32 gana
User prompt
agrega dosniveles mas
User prompt
Si nivel es mayor que nivel llegado, nivel llegado es igua a nivel porfa
Code edit (1 edits merged)
Please save this source code
User prompt
haz uqe aqui el mana sea igual al amna maximo function destroy_mapa() {
User prompt
elimina esos txtos
User prompt
Cuando termino de ver el comic, tengo level 1 pero no se desblpoque la nota de fuego, pero si lo seleccio desde niveles si
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
// true = English (default), false = Spanish
var ElementalNote = Container.expand(function (element, x, y) {
	var self = Container.call(this);
	var noteGraphics = self.attachAsset(element + 'Note', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.element = element;
	self.x = x;
	self.y = y;
	// Text labels removed for cleaner appearance
	self.isDisabled = false;
	self.down = function (x, y, obj) {
		// Check if game is paused
		if (pausa) {
			return;
		}
		// Check if button is disabled
		if (self.isDisabled) {
			return;
		}
		// Check if element is unlocked before playing sound
		if (unlockedElements.indexOf(self.element) === -1) {
			return; // Don't play sound or process note if element is blocked
		}
		// Disable button
		self.isDisabled = true;
		notePressed(self.element);
		// Play sound effect with controlled volume when pressed directly
		// Access current global soundValue instead of captured value
		var currentSoundValue = typeof soundValue !== 'undefined' ? soundValue : 0.8;
		if (self.element === 'fire') {
			var fireSound = LK.getSound('Nota_Fire');
			fireSound.volume = currentSoundValue;
			fireSound.play();
		} else if (self.element === 'water') {
			var waterSound = LK.getSound('Nota_Water');
			waterSound.volume = currentSoundValue;
			waterSound.play();
		} else if (self.element === 'earth') {
			var earthSound = LK.getSound('Nota_Earth');
			earthSound.volume = currentSoundValue;
			earthSound.play();
		} else if (self.element === 'wind') {
			var windSound = LK.getSound('Nota_Wind');
			windSound.volume = currentSoundValue;
			windSound.play();
		} else if (self.element === 'light') {
			var lightSound = LK.getSound('Nota_Light');
			lightSound.volume = currentSoundValue;
			lightSound.play();
		} else {
			var summonSound = LK.getSound('summon');
			summonSound.volume = currentSoundValue;
			summonSound.play();
		}
		// Visual feedback - make smaller on press and reduce opacity
		tween(self.children[0], {
			scaleX: 0.8,
			scaleY: 0.8,
			alpha: 0.6
		}, {
			duration: 100,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Return to normal size and restore opacity quickly
				tween(self.children[0], {
					scaleX: 1.0,
					scaleY: 1.0,
					alpha: 1.0
				}, {
					duration: 100,
					easing: tween.easeInOut,
					onFinish: function onFinish() {
						// Only re-enable button if we have enough mana and haven't reached limit
						LK.setTimeout(function () {
							// Check if we still have enough mana and haven't reached the counter limit
							if (temporaryNoteCounter < currentMana) {
								self.isDisabled = false;
							}
						}, 0); // Re-enable conditionally after color animation
					}
				});
			}
		});
	};
	return self;
});
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphics = self.attachAsset('enemyUnit', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 280,
		height: 280
	});
	self.health = 5;
	self.maxHealth = 5;
	self.damage = 1;
	self.speed = 1.5;
	self.aumento_velocidad = 0;
	self.attackCooldown = 0;
	self.movimiento_enemigo = true; // Boolean to control enemy movement
	self.enemigo_oro = false; // Boolean to control golden statue state
	self.ataque_jugador = true; // Boolean to control if enemy can attack
	self.dormido = false; // Individual sleep state for this enemy
	// Physics properties
	self.velocityY = 0;
	self.onGround = false;
	self.gravity = 0.5;
	// Beat effect properties
	self.baseY = 0;
	self.beatEffectTimer = 0;
	// Health bar
	var healthBar = LK.getAsset('healthBar', {
		width: 100,
		height: 12
	});
	healthBar.anchor.set(0.5, 0.5);
	healthBar.y = -80;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	// Stats text below enemy
	var statsText = new Text2('', {
		size: 48,
		fill: 0xFFFFFF,
		font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
	});
	statsText.anchor.set(0.5, 0.5);
	statsText.y = 120; // Position below the enemy
	self.addChild(statsText);
	self.statsText = statsText;
	// Initialize miniola_colision property
	self.miniola_colision = false;
	self.vortice = false;
	// Function to update stats display
	self.updateStatsDisplay = function () {
		var goldState = self.enemigo_oro ? 'true' : 'false';
		var sleepState = self.dormido ? 'true' : 'false';
		var vorticeState = self.vortice ? 'true' : 'false';
		var statsString = self.health + '-' + self.damage + '-' + goldState + '-' + sleepState + '-' + vorticeState;
		self.statsText.setText(statsString);
	};
	// Initialize stats display
	self.updateStatsDisplay();
	self.update = function () {
		if (pausa == false) {
			// Set base Y position for beat effect
			if (self.baseY === 0) {
				self.baseY = 2186; // Ground level
			}
			// Apply beat effect if active and not golden statue
			if (self.beatEffectTimer > 0 && !self.enemigo_oro) {
				self.beatEffectTimer--;
				// Get current audio level and calculate rotation strength based on sensitivity difference
				var audioLevel = getGameMusicLevel();
				var sensitivityDifference = Math.max(0, audioLevel - musicBeatThreshold);
				if (sensitivityDifference > 0) {
					var rotationAmount = Math.sin((120 - self.beatEffectTimer) * 0.3) * sensitivityDifference * 0.785;
					enemyGraphics.rotation = rotationAmount;
				} else {
					enemyGraphics.rotation = 0; // No rotation when no difference
				}
			} else {
				enemyGraphics.rotation = 0; // Reset rotation when effect ends or when golden statue
				// Apply gravity
				if (!self.onGround) {
					self.velocityY += self.gravity;
					self.y += self.velocityY;
				}
				// Ground collision
				var groundY = 2186;
				if (self.y >= groundY) {
					self.y = groundY;
					self.baseY = groundY; // Update base position
					self.velocityY = 0;
					self.onGround = true;
				} else {
					self.onGround = false;
				}
			}
			if (self.attackCooldown > 0) {
				self.attackCooldown--;
			}
			// Apply tinting based on emerald and sleep states - prioritize emerald over sleep
			if (self.enemigo_oro) {
				// Emerald state active - disable movement and attack
				self.movimiento_enemigo = false;
				self.ataque_jugador = false;
				if (self.dormido) {
					// Both emerald and sleep active - use black tint for sleeping
					enemyGraphics.tint = 0x333333; // 80% black tint for sleeping
					// Start 5-second timer to clear both states
					if (!self.clearStatesTimer) {
						// Add debug text when timer activates
						showCombinationMessage('activado despertar');
						self.clearStatesTimer = true;
						LK.setTimeout(function () {
							self.dormido = false;
							self.enemigo_oro = false;
							self.clearStatesTimer = false;
						}, 5000);
					}
				} else if (self.vortice) {
					// Vortice state active - apply blue tint and mirror effect
					enemyGraphics.tint = 0x4040ff; // 75% blue tint
					// Initialize vortice timer if not set
					if (self.vorticeTimer === undefined) {
						self.vorticeTimer = 0;
					}
					// Increment timer
					self.vorticeTimer++;
					// Apply mirror effect every 0.25 seconds (15 frames at 60fps)
					if (self.vorticeTimer >= 15) {
						volterar(self);
						self.vorticeTimer = 0; // Reset timer
					}
				} else {
					// Only emerald state - use green tint
					enemyGraphics.tint = 0x00FF00; // Pure green color (emerald statue effect)
				}
			} else {
				// No special state - enable movement and attack
				self.movimiento_enemigo = true;
				self.ataque_jugador = true;
				// Reset tint if needed
				if (enemyGraphics.tint === 0x000000 || enemyGraphics.tint === 0xFFD700 || enemyGraphics.tint === 0xFFFF00 || enemyGraphics.tint === 0xFF0000 || enemyGraphics.tint === 0x00FF00 || enemyGraphics.tint === 0x333333 || enemyGraphics.tint === 0x8080FF) {
					enemyGraphics.tint = 0xffffff;
				}
			}
			// Add dormido image when sleeping and particle system
			if (self.dormido && !self.dormidoImageActive) {
				// Create dormido image overlay
				self.dormidoImage = LK.getAsset('dormido', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: 0,
					y: -150,
					width: 100,
					height: 100
				});
				self.addChild(self.dormidoImage);
				self.dormidoImageActive = true;
				// Create sleep particles continuously while sleeping
				self.sleepParticleTimer = 0;
			} else if (!self.dormido && self.dormidoImageActive) {
				// Remove dormido image when no longer sleeping
				if (self.dormidoImage) {
					self.dormidoImage.destroy();
					self.dormidoImage = null;
				}
				self.dormidoImageActive = false;
			}
			// Generate sleep particles while dormido is active
			if (self.dormido && self.dormidoImageActive) {
				self.sleepParticleTimer = (self.sleepParticleTimer || 0) + 1;
				if (self.sleepParticleTimer >= 30) {
					// Every 0.5 seconds
					// Create sleep particles
					for (var sleepP = 0; sleepP < 3; sleepP++) {
						var sleepParticle = game.addChild(LK.getAsset('dormido', {
							anchorX: 0.5,
							anchorY: 0.5,
							x: self.x + (Math.random() - 0.5) * 80,
							y: self.y - 50 - Math.random() * 30,
							width: 30,
							height: 30
						}));
						sleepParticle.alpha = 0.8;
						sleepParticle.tint = 0x9999FF;
						tween(sleepParticle, {
							y: sleepParticle.y - 120,
							alpha: 0,
							scaleX: 2,
							scaleY: 2
						}, {
							duration: 2500,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								sleepParticle.destroy();
							}
						});
					}
					self.sleepParticleTimer = 0;
				}
			}
			// Movement is now controlled by movimiento_enemigo variable above
			// Check for warriors to attack and combat engagement
			var inCombat = false;
			for (var i = 0; i < warriors.length; i++) {
				var warrior = warriors[i];
				// Use half width for enemy and warrior colliders but keep full height
				var enemyColliderWidth = 280 * 0.5; // Half of enemy width
				var warriorColliderWidth = 288 * 0.5; // Half of warrior width
				var distance = Math.sqrt(Math.pow(self.x - warrior.x, 2) + Math.pow(self.y - warrior.y, 2));
				if (distance < 250) {
					// Mark as in combat to stop movement
					inCombat = true;
					// Attack if cooldown is ready and can attack
					if (self.attackCooldown <= 0 && self.ataque_jugador) {
						self.attack(warrior);
						// Play combat sound when fighting with warrior
						playRandomCombatSound();
						// Attack animation - flash red and scale up
						tween(enemyGraphics, {
							tint: 0xff0000,
							scaleX: 1.3,
							scaleY: 1.3
						}, {
							duration: 200,
							onFinish: function onFinish() {
								tween(enemyGraphics, {
									tint: 0xffffff,
									scaleX: 1.0,
									scaleY: 1.0
								}, {
									duration: 200
								});
							}
						});
					}
					break;
				}
			}
			// Set movimiento_enemigo based on combat state, statue status, and dormido state
			if (inCombat) {
				self.movimiento_enemigo = false; // Stop movement when attacking
			} else if (!self.enemigo_oro) {
				self.movimiento_enemigo = true; // Allow movement when not in combat, not a statue, and not sleeping
			}
			// Move towards player tower only if movement is enabled
			if (self.movimiento_enemigo) {
				// Move towards player tower (speed is controlled by combat state)
				var totalSpeed = self.speed + self.aumento_velocidad;
				self.x -= totalSpeed;
			}
			// Check if enemy is at the tower x position - stop movement to focus on tower attack
			var atTowerPosition = Math.abs(self.x - enemyTower.x) <= 50;
			// Control speed based on combat and tower position
			if (inCombat || atTowerPosition) {
				self.speed = 0;
				self.movimiento_enemigo = false; // Stop movement when at tower position or in combat
			} else {
				self.speed = 1.5;
				self.movimiento_enemigo = true; // Allow movement when not in combat or at tower
			}
			// Check collision with player tower and destroy enemy - use half width for enemy collider
			var towerColliderRadius = 700; // Fixed collider size, not scaled with tower
			var enemyColliderWidth = 280 * 0.5; // Half of enemy width
			var enemyColliderHeight = 280; // Full enemy height
			var towerDistance = Math.sqrt(Math.pow(self.x - playerTower.x, 2) + Math.pow(self.y - playerTower.y, 2));
			if (towerDistance < towerColliderRadius) {
				if (self.attackCooldown <= 0 && self.ataque_jugador) {
					self.attackPlayerTower();
				}
				// Destroy enemy when it touches the tower
				self.destroy();
				var index = enemies.indexOf(self);
				if (index > -1) {
					enemies.splice(index, 1);
				}
			}
			// Check if enemy is off-screen and destroy
			if (self.x < -500 || self.x > 4500 || self.y > 3500) {
				self.destroy();
				var index = enemies.indexOf(self);
				if (index > -1) {
					enemies.splice(index, 1);
				}
				return; // Exit update to prevent further execution
			}
			// Update health bar
			var healthPercent = self.health / self.maxHealth;
			self.healthBar.scaleX = healthPercent;
		}
	};
	self.attack = function (target) {
		self.attackCooldown = 80;
		if (target === playerTower) {
			self.attackPlayerTower();
		} else {
			target.takeDamage(self.damage);
		}
	};
	self.attackPlayerTower = function () {
		self.attackCooldown = 80;
		playerTowerHealth -= self.damage;
		// Play random tower damage sound
		var towerSounds = ['sonido_torre_1', 'sonido_torre_2', 'sonido_torre_3', 'sonido_torre_4'];
		var randomIndex = Math.floor(Math.random() * towerSounds.length);
		var sound = LK.getSound(towerSounds[randomIndex]);
		sound.volume = soundValue;
		sound.play();
		// Create escombros particles when tower takes damage - quantity based on damage
		var particleCount = self.damage * 12; // Multiply particle count by damage
		for (var escombrosIndex = 0; escombrosIndex < particleCount; escombrosIndex++) {
			// 360-degree explosion pattern
			var angle = escombrosIndex / particleCount * Math.PI * 2; // Distribute evenly in 360 degrees
			var force = (200 + Math.random() * 300) * 4; // Quadruple the force
			var velocityX = Math.cos(angle) * force;
			var velocityY = Math.sin(angle) * force;
			var escombrosParticle = game.addChild(LK.getAsset('escombro_torre_jugador', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: playerTower.x,
				y: playerTower.y - 800,
				width: (60 + Math.random() * 40) * 5,
				height: (60 + Math.random() * 40) * 5,
				rotation: Math.random() * Math.PI * 2
			}));
			escombrosParticle.alpha = 0.9;
			escombrosParticle.tint = 0x8B4513; // Brown color for debris
			// Add gravity and physics properties
			escombrosParticle.velocityX = velocityX * 0.02; // Scale down for smooth movement
			escombrosParticle.velocityY = velocityY * 0.02;
			escombrosParticle.gravity = 0.8; // Gravity effect
			// Animate escombros particles with physics
			tween(escombrosParticle, {
				y: playerTower.y + 200 + escombrosParticle.velocityY * 100,
				x: playerTower.x + escombrosParticle.velocityX * 100,
				alpha: 0,
				rotation: escombrosParticle.rotation + Math.PI * 4,
				scaleX: 0.1,
				scaleY: 0.1
			}, {
				duration: 2000 + Math.random() * 1000,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					escombrosParticle.destroy();
				}
			});
		}
		if (playerTowerHealth <= 0) {
			LK.showGameOver();
		}
		updateTowerHealthBars();
	};
	self.takeBurnDamage = function (initialDamage, duration, burnDamage) {
		// Apply initial damage
		self.takeDamage(initialDamage);
		// Don't apply burn if enemy is already dead
		if (self.health <= 0) {
			return;
		}
		// Start burn sound loop - store sound instance for stopping later
		var burnSound = LK.getSound('burn_sound');
		burnSound.volume = soundValue * 0.8;
		self.burnSoundInstance = burnSound;
		burnSound.play();
		// Set up sound looping
		var soundLoopTimer = LK.setInterval(function () {
			if (self.health > 0 && self.burnSoundInstance) {
				self.burnSoundInstance.play();
			}
		}, 1000); // Loop every second
		// Add red tint at 80% opacity when burned
		tween(enemyGraphics, {
			tint: 0xff0000
		}, {
			duration: 200,
			onFinish: function onFinish() {
				// Keep 80% red tint during burn
				var redTint = 0xff3333; // 80% red color
				tween(enemyGraphics, {
					tint: redTint
				}, {
					duration: 100
				});
			}
		});
		// Apply burn effect over time
		var burnTicks = duration / 1000 * 60; // Convert duration to ticks (60fps)
		var burnInterval = 60; // Damage every second
		var ticksPerBurn = 0;
		var _burnEffect = function burnEffect() {
			ticksPerBurn++;
			if (ticksPerBurn >= burnInterval) {
				if (self.health > 0) {
					self.takeDamage(burnDamage);
					// Visual burn effect
					if (self.children[0]) {
						tween(self.children[0], {
							tint: 0xff4400
						}, {
							duration: 200,
							onFinish: function onFinish() {
								if (self.children[0]) {
									tween(self.children[0], {
										tint: 0xff3333
									}, {
										duration: 200
									});
								}
							}
						});
					}
				}
				ticksPerBurn = 0;
				burnTicks -= burnInterval;
			}
			if (burnTicks > 0 && self.health > 0) {
				LK.setTimeout(_burnEffect, 16); // ~60fps
			} else {
				// Burn effect ended, stop sound loop and restore normal color
				LK.clearInterval(soundLoopTimer);
				self.burnSoundInstance = null;
				tween(enemyGraphics, {
					tint: 0xffffff
				}, {
					duration: 500
				});
			}
		};
		_burnEffect();
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		// Update stats display to show current health
		self.updateStatsDisplay();
		if (self.health <= 0) {
			// Destroy tornado if it exists
			if (self.tornado) {
				self.tornado.destroy();
				self.tornado = null;
			}
			// Play enemy death sound
			var sound = LK.getSound('enemy_death');
			sound.volume = soundValue;
			sound.play();
			// Death animation - fade out and scale down
			tween(enemyGraphics, {
				alpha: 0,
				scaleX: 0.1,
				scaleY: 0.1,
				rotation: Math.PI * 2
			}, {
				duration: 500,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
			var index = enemies.indexOf(self);
			if (index > -1) {
				enemies.splice(index, 1);
			}
			LK.setScore(LK.getScore() + 10);
			scoreText.setText('Score: ' + LK.getScore());
			// 50% chance to drop mana if not at max capacity
			if (Math.random() < 0.5 && currentMana < maxMana) {
				// Create mana drop at enemy position
				var manaDrop = game.addChild(LK.getAsset('manaOrb', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: self.x,
					y: self.y
				}));
				// Visual effect - pulsing and floating up
				tween(manaDrop, {
					scaleX: 3.0,
					scaleY: 3.0,
					y: self.y - 100
				}, {
					duration: 800,
					easing: tween.easeOut
				});
				// Add mana after short delay and destroy drop
				LK.setTimeout(function () {
					currentMana = Math.min(currentMana + 1, maxMana);
					updateManaDisplay();
					// Flash effect on collection
					tween(manaDrop, {
						alpha: 0,
						scaleX: 4,
						scaleY: 4
					}, {
						duration: 300,
						onFinish: function onFinish() {
							manaDrop.destroy();
						}
					});
				}, 600);
			}
		}
	};
	return self;
});
var Espora = Container.expand(function (targetWarrior) {
	var self = Container.call(this);
	var esporaGraphics = self.attachAsset('esporas', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 100,
		height: 100
	});
	self.targetWarrior = targetWarrior;
	self.velocityX = (Math.random() - 0.5) * 1; // Minimal random horizontal velocity
	self.velocityY = -2 - Math.random() * 3; // Initial upward velocity
	self.gravity = 0.1; // Reduced gravity force
	self.lifespan = 300; // 5 seconds at 60fps
	self.age = 0;
	// Set initial position near target warrior
	self.x = targetWarrior.x + (Math.random() - 0.5) * 100;
	self.y = targetWarrior.y + (Math.random() - 0.5) * 50;
	self.update = function () {
		self.age++;
		// Apply gravity
		self.velocityY += self.gravity;
		// Update position
		self.x += self.velocityX;
		self.y += self.velocityY;
		// Follow target warrior with gentle attraction
		if (self.targetWarrior && !self.targetWarrior.isBeingDestroyed) {
			var distanceToTarget = Math.sqrt(Math.pow(self.targetWarrior.x - self.x, 2) + Math.pow(self.targetWarrior.y - self.y, 2));
			if (distanceToTarget > 100) {
				// Gently drift towards warrior
				var directionX = (self.targetWarrior.x - self.x) / distanceToTarget;
				var directionY = (self.targetWarrior.y - self.y) / distanceToTarget;
				self.velocityX += directionX * 0.05; // Reduced attraction force
				self.velocityY += directionY * 0.05; // Reduced attraction force
			}
		}
		// Apply air resistance to reduce horizontal drift
		self.velocityX *= 0.95; // Air resistance dampens horizontal movement
		// Ground collision
		var groundY = 2186;
		if (self.y >= groundY) {
			self.y = groundY;
			self.velocityY = -self.velocityY * 0.3; // Bounce with energy loss
			self.velocityX *= 0.7; // Increased friction on ground contact
		}
		// Fade out over lifetime
		var fadeAlpha = 1.0 - self.age / self.lifespan;
		esporaGraphics.alpha = Math.max(0, fadeAlpha);
		// Check collision with enemies
		for (var e = 0; e < enemies.length; e++) {
			var enemy = enemies[e];
			var distance = Math.sqrt(Math.pow(self.x - enemy.x, 2) + Math.pow(self.y - enemy.y, 2));
			if (distance < 80) {
				// Only affect enemies that don't already have emerald state active
				if (!enemy.enemigo_oro) {
					// Collision detected
					// Deal damage to enemy
					enemy.takeDamage(3);
					// Apply dormido state first
					enemy.dormido = true;
					// Then apply emerald statue effect
					enemy.enemigo_oro = true;
				}
				// Create visual effect at collision point
				var explosion = game.addChild(LK.getAsset('efecto_electricidad', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: self.x,
					y: self.y,
					width: 120,
					height: 120
				}));
				explosion.tint = 0x44ff44; // Green color for spore explosion
				explosion.alpha = 0.8;
				// Animate explosion
				tween(explosion, {
					scaleX: 2.5,
					scaleY: 2.5,
					alpha: 0
				}, {
					duration: 600,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						explosion.destroy();
					}
				});
				// Create spore particles around impact
				for (var p = 0; p < 8; p++) {
					var angle = p / 8 * Math.PI * 2;
					var particleDistance = 60 + Math.random() * 40;
					var particleX = self.x + Math.cos(angle) * particleDistance;
					var particleY = self.y + Math.sin(angle) * particleDistance;
					var particle = game.addChild(LK.getAsset('esporas', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: self.x,
						y: self.y,
						width: 40 + Math.random() * 20,
						height: 40 + Math.random() * 20
					}));
					particle.tint = 0x88ff88;
					particle.alpha = 0.9;
					tween(particle, {
						x: particleX,
						y: particleY,
						alpha: 0,
						scaleX: 0.3,
						scaleY: 0.3
					}, {
						duration: 500 + Math.random() * 300,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							particle.destroy();
						}
					});
				}
				// Destroy spore after collision
				self.destroy();
				var index = esporas.indexOf(self);
				if (index > -1) {
					esporas.splice(index, 1);
				}
				return; // Exit update after collision
			}
		}
		// Destroy after lifespan
		if (self.age >= self.lifespan) {
			self.destroy();
			var index = esporas.indexOf(self);
			if (index > -1) {
				esporas.splice(index, 1);
			}
		}
	};
	return self;
});
var Meteorito = Container.expand(function () {
	var self = Container.call(this);
	var meteoritoGraphics = self.attachAsset('meteorito_elemental', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 6.0,
		scaleY: 6.0
	});
	self.speed = 20;
	self.rotationSpeed = 0.1;
	// Store the base scale to prevent shrinking
	self.baseScale = 6.0;
	// Rainbow cycling effect for mixed element meteorite
	meteoritoGraphics.tint = 0xffffff;
	// Add rainbow cycling animation
	var rainbowColors = [0xff4400, 0x1e90ff, 0x8b4513, 0x44ff44, 0xffff00];
	var colorIndex = 0;
	var colorTimer = 0;
	self.updateRainbow = function () {
		colorTimer++;
		if (colorTimer >= 10) {
			// Change color every 10 frames
			colorTimer = 0;
			colorIndex = (colorIndex + 1) % rainbowColors.length;
			meteoritoGraphics.tint = rainbowColors[colorIndex];
		}
	};
	// Meteorite maintains full opacity (no alpha animation)
	meteoritoGraphics.alpha = 1.0;
	self.update = function () {
		// Calculate target position (center of map at ground level)
		var targetX = 1920; // Center of the game map (3840/2)
		var targetY = 2186; // Ground level
		// Calculate direction vector toward target
		var deltaX = targetX - self.x;
		var deltaY = targetY - self.y;
		var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
		// Move diagonally toward target - double speed
		if (distance > self.speed) {
			// Normalize direction and apply double speed
			var directionX = deltaX / distance;
			var directionY = deltaY / distance;
			self.x += directionX * self.speed;
			self.y += directionY * self.speed;
		} else {
			// Reached target position - explode
			self.explode();
			return;
		}
		// Update rainbow effect
		self.updateRainbow();
		// Remove if off-screen
		if (self.y > 3000) {
			self.destroy();
			var index = meteoritos.indexOf(self);
			if (index > -1) {
				meteoritos.splice(index, 1);
			}
		}
	};
	self.explode = function () {
		// Generate random color for explosion
		var randomColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff, 0xff8000, 0x8000ff, 0x80ff00, 0xff0080];
		var explosionColor = randomColors[Math.floor(Math.random() * randomColors.length)];
		// Create explosion effect
		var explosion = game.addChild(LK.getAsset('efecto_electricidad', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: self.x,
			y: self.y,
			width: 400,
			height: 400
		}));
		explosion.tint = explosionColor;
		explosion.alpha = 0.9;
		// Animate massive explosion with enormous scale
		tween(explosion, {
			scaleX: 40.0,
			scaleY: 40.0,
			alpha: 0
		}, {
			duration: 2500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				explosion.destroy();
			}
		});
		// Create massive particle explosion
		for (var i = 0; i < 64; i++) {
			var angle = i / 64 * Math.PI * 2;
			var distance = 1600 + Math.random() * 2400;
			var particleEndX = self.x + Math.cos(angle) * distance;
			var particleEndY = self.y + Math.sin(angle) * distance;
			// Generate random color for each particle
			var particleColor = randomColors[Math.floor(Math.random() * randomColors.length)];
			var particle = game.addChild(LK.getAsset('explosion_fuego', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: self.x,
				y: self.y,
				width: 240 + Math.random() * 360,
				height: 240 + Math.random() * 360
			}));
			particle.tint = particleColor;
			particle.alpha = 0.9;
			tween(particle, {
				x: particleEndX,
				y: particleEndY,
				alpha: 0,
				scaleX: 0.05,
				scaleY: 0.05
			}, {
				duration: 2000 + Math.random() * 1000,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					particle.destroy();
				}
			});
		}
		// Hide apocalyptic notes and reset counter when meteorite explodes (before explosion starts)
		ocultar_notas_apocalitica();
		// Deal massive damage to all enemies on the map
		for (var e = enemies.length - 1; e >= 0; e--) {
			var enemy = enemies[e];
			enemy.takeDamage(1000000000000000000); // Deal 1 quintillion damage to guarantee destruction
		}
		// Show message
		showCombinationMessage('¡METEORITO ELEMENTAL - DEVASTACIÓN TOTAL!');
		// Flash screen effect with longer duration for massive impact
		LK.effects.flashScreen(explosionColor, 2000);
		// Clear element list first, then call function to create new random meteorite combination
		elementList = [];
		// Play the meteorite melody instantly when exploding
		playMelodySequenceWithIntervals(['fire', 'water', 'earth', 'wind', 'light'], [0, 200, 200, 200, 200]);
		crea_combinacion_meteorito();
		// Remove meteorite
		self.destroy();
		var index = meteoritos.indexOf(self);
		if (index > -1) {
			meteoritos.splice(index, 1);
		}
	};
	return self;
});
var Nube = Container.expand(function () {
	var self = Container.call(this);
	// Create cloud with random uniform scale to maintain proportions
	var uniformScale = 0.5 + Math.random() * 1.5; // Random scale between 50% and 200%
	var cloudGraphics = self.attachAsset('shape', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: uniformScale,
		scaleY: uniformScale,
		alpha: 0.4 + Math.random() * 0.5 // Random opacity between 40% and 90%
	});
	// Random cloud speed (slower clouds for depth) - will be adjusted by height layer
	self.speed = 0.5 + Math.random() * 1.0; // Speed between 0.5 and 1.5
	// Adjust speed based on scale to simulate depth (smaller clouds move slower)
	self.baseSpeed = self.speed;
	// Store initial Y for floating animation
	self.initialY = 0; // Will be set when cloud is positioned
	// Method to start floating animation after positioning
	self.startFloating = function () {
		if (self.initialY === 0) {
			self.initialY = self.y; // Store the manually set position
		}
		var floatAmount = 20 + Math.random() * 30;
		var floatDuration = 3000 + Math.random() * 2000;
		tween(self, {
			y: self.initialY + floatAmount
		}, {
			duration: floatDuration,
			yoyo: true,
			repeat: -1,
			easing: tween.easeInOut
		});
	};
	self.update = function () {
		// Adjust speed based on scale for depth effect (smaller = slower, further away)
		self.speed = self.baseSpeed * (self.scaleX * 0.7 + 0.3); // Scale speed between 30% and 100%
		// Move cloud to the right
		self.x += self.speed;
		// Remove clouds that have moved off-screen to the right
		if (self.x > 4000 + cloudGraphics.width) {
			self.destroy();
			var index = clouds.indexOf(self);
			if (index > -1) {
				clouds.splice(index, 1);
			}
		}
	};
	return self;
});
var Warrior = Container.expand(function (element, tier) {
	var self = Container.call(this);
	var assetName = element + 'Warrior_nivel_' + tier;
	var warriorGraphics = self.attachAsset(assetName, {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 288,
		height: 288
	});
	self.element = element;
	self.tier = tier;
	// Add wind warrior tier 5 attack tracking
	if (element === 'wind' && tier === 5) {
		self.attackedEnemies = []; // Track which enemies have been attacked
	}
	// Base stats - same as enemies
	var baseDamage = 1;
	var baseHealth = 5;
	// Set elemental-specific stats based on tier
	if (element === 'fire') {
		if (tier === 1) {
			self.maxHealth = 5;
			self.damage = 6;
			self.speed = 2.2;
			self.attackCooldown = 100;
		} else if (tier === 2) {
			self.maxHealth = 10;
			self.damage = 6;
			self.speed = 2.4;
			self.attackCooldown = 50;
		} else if (tier === 3) {
			self.maxHealth = 15;
			self.damage = 18;
			self.speed = 2.6;
			self.attackCooldown = 100;
			self.burnDuration = 3000; // 3 seconds
			self.burnDamage = 6;
			self.canBurn = true;
		} else if (tier === 4) {
			self.maxHealth = 20;
			self.damage = 24;
			self.speed = 2.8;
			self.attackCooldown = 60;
			self.canAreaDamage = true;
			self.areaRange = 400;
			self.burnDuration = 5000; // 5 seconds
			self.burnDamage = 8;
			self.canBurn = true;
		} else if (tier === 5) {
			self.maxHealth = 25;
			self.damage = 50;
			self.speed = 3.0;
			self.attackCooldown = 60;
			self.canActivateFireMode = true;
			self.fireModeActive = false;
		}
	} else if (element === 'water') {
		if (tier === 1) {
			self.maxHealth = 5;
			self.damage = 1;
			self.speed = 1.8;
			self.attackCooldown = 120;
		} else if (tier === 2) {
			self.maxHealth = 10;
			self.damage = 2;
			self.speed = 2.0;
			self.attackCooldown = 120;
			self.selfHealRate = 2; // Heals 2 HP per second
			self.selfHealTimer = 0;
		} else if (tier === 3) {
			self.maxHealth = 15;
			self.damage = 4;
			self.speed = 2.2;
			self.attackCooldown = 120;
			self.selfHealRate = 3.5; // Heals 3.5 HP per second
			self.selfHealTimer = 0;
			self.auraRange = 500;
			self.auraDamageBonus = 4;
			self.explosionTimer = 0;
			self.explosionInterval = 120; // Every 2 seconds
		} else if (tier === 4) {
			self.maxHealth = 20;
			self.damage = 6;
			self.speed = 2.4;
			self.attackCooldown = 120;
			self.selfHealRate = 4; // Heals 4 HP per second
			self.selfHealTimer = 0;
			self.selfHealRate = 5; // Heals 5 HP per second
			self.selfHealTimer = 0;
			self.auraRange = 800;
			self.auraDamageBonus = 10;
			self.explosionTimer = 0;
			self.explosionInterval = 120; // Every 2 seconds
		} else if (tier === 5) {
			self.maxHealth = 25;
			self.damage = 8;
			self.speed = 2.5;
			self.attackCooldown = 120;
			self.selfHealRate = 5; // Heals 5 HP per second
			self.selfHealTimer = 0;
			self.waveTimer = 0;
			self.waveInterval = 300; // Every 5 seconds
		}
		self.canHeal = true;
		self.healCooldown = 0;
		self.isRanged = true;
		self.projectiles = [];
	} else if (element === 'earth') {
		if (tier === 1) {
			self.maxHealth = 20;
			self.damage = 1;
			self.speed = 1.8;
			self.attackCooldown = 120;
		} else if (tier === 2) {
			self.maxHealth = 40;
			self.damage = 4;
			self.speed = 1.8;
			self.attackCooldown = 120;
		} else if (tier === 3) {
			self.maxHealth = 50;
			self.damage = 6;
			self.speed = 1.8;
			self.attackCooldown = 120;
			self.canCreateWalls = true;
			self.wallHealth = 100;
			self.distancia_recorrida = Math.random() * 1000; // Random start between 0-1000
		} else if (tier === 4) {
			self.maxHealth = 80;
			self.damage = 8;
			self.speed = 1.8;
			self.attackCooldown = 120;
			self.canCreateWalls = true;
			self.wallHealth = 200;
			self.damageImmunity = 10; // Immune to damage <= 10
			self.distancia_recorrida = Math.random() * 1000; // Random start between 0-1000
		} else if (tier === 5) {
			self.maxHealth = 100;
			self.damage = 10;
			self.speed = 1.8;
			self.attackCooldown = 120;
			self.canDragEnemies = true;
			self.canSelfDestruct = true;
			self.damageImmunity = 20; // Immune to damage <= 20
			self.distancia_recorrida = Math.random() * 1000; // Random start between 0-1000
		}
	} else if (element === 'light') {
		if (tier === 1) {
			self.maxHealth = 5;
			self.damage = 1;
			self.speed = 2;
			self.attackCooldown = 100;
		} else if (tier === 2) {
			self.maxHealth = 10;
			self.damage = 2;
			self.speed = 2.2;
			self.attackCooldown = 100;
			self.canSecondExplosion = true;
		} else if (tier === 3) {
			self.maxHealth = 15;
			self.damage = 3;
			self.speed = 2.4;
			self.attackCooldown = 100;
			self.canCreateClouds = true;
		} else if (tier === 4) {
			self.maxHealth = 20;
			self.damage = 8;
			self.speed = 2.6;
			self.attackCooldown = 100;
			self.canLaserBeam = true;
		} else if (tier === 5) {
			self.maxHealth = 25;
			self.damage = 5;
			self.speed = 2.8;
			self.attackCooldown = 100;
			self.canTrackingClouds = true;
		} else {
			self.maxHealth = 5;
			self.damage = 1;
			self.speed = 2;
			self.attackCooldown = 100;
		}
		self.isRanged = true;
		self.canAreaDamage = true;
		self.projectiles = [];
	} else if (element === 'wind') {
		if (tier === 1) {
			self.maxHealth = 5;
			self.damage = 1;
			self.speed = 3;
			self.attackCooldown = 60;
		} else if (tier === 2) {
			self.maxHealth = 10;
			self.damage = 2;
			self.speed = 3.4;
			self.attackCooldown = 60;
			self.goldenStatueChance = 0.2; // 20% chance
		} else if (tier === 3) {
			self.maxHealth = 15;
			self.damage = 4;
			self.speed = 3.8;
			self.attackCooldown = 60;
			self.sleepParticleSystem = true;
			self.sleepDuration = 5000; // 5 seconds
		} else if (tier === 4) {
			self.maxHealth = 20;
			self.damage = 8;
			self.speed = 5;
			self.attackCooldown = 60;
			self.emeraldSlaveChance = 0.2; // 20% chance
			self.sleepDuration = 10000; // 10 seconds
		} else if (tier === 5) {
			self.maxHealth = 25;
			self.damage = 15;
			self.speed = 1.05;
			self.attackCooldown = 60;
		} else {
			self.maxHealth = baseHealth;
			self.damage = baseDamage;
			self.speed = 2.8;
		}
		self.isFlying = true;
		self.isRanged = true;
		self.projectiles = [];
	} else {
		// Default stats for any other element
		self.maxHealth = baseHealth;
		self.damage = baseDamage;
		self.speed = 2;
	}
	self.health = self.maxHealth;
	self.aumento_velocidad = 0;
	// Attack cooldown will be set by elemental stats above
	if (!self.attackCooldown) {
		self.attackCooldown = 0; // Default fallback
	}
	self.baseCooldown = self.attackCooldown || 60; // Store base cooldown for resets
	self.target = null;
	self.isBeingDestroyed = false; // Flag to prevent multiple destruction attempts
	self.activar_movimiento = true; // Boolean to control if warrior can move
	// Physics properties
	self.velocityY = 0;
	self.onGround = false;
	self.gravity = 0.5;
	// Beat effect properties
	self.baseY = 0;
	self.beatEffectTimer = 0;
	// Set warrior size based on tier level - using scale multipliers for visible differences
	var tierScale = 1.0; // Base scale for tier 1
	if (tier === 1) {
		tierScale = 1.0; // Tier 1: normal size (288px)
	} else if (tier === 2) {
		tierScale = 1.17; // Tier 2: 17% bigger (338px)
	} else if (tier === 3) {
		tierScale = 1.35; // Tier 3: 35% bigger (388px)
	} else if (tier === 4) {
		tierScale = 1.52; // Tier 4: 52% bigger (438px)
	} else if (tier === 5) {
		tierScale = 1.69; // Tier 5: 69% bigger (488px)
	}
	// Store the tier scale for later reference
	self.tierScale = tierScale;
	// Apply tier-based scaling immediately and permanently
	warriorGraphics.scaleX = tierScale;
	warriorGraphics.scaleY = tierScale;
	// Apply a simple bounce effect that preserves the tier scale
	var bounceScale = tierScale * 1.1;
	tween(warriorGraphics, {
		scaleX: bounceScale,
		scaleY: bounceScale
	}, {
		duration: 200,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			// Ensure we return to the exact tier scale, not a reference that might change
			tween(warriorGraphics, {
				scaleX: self.tierScale,
				scaleY: self.tierScale
			}, {
				duration: 200,
				easing: tween.easeInOut
			});
		}
	});
	// Health bar
	var healthBar = LK.getAsset('warriorHealthBar', {
		width: 120,
		height: 16
	});
	healthBar.anchor.set(0.5, 0.5);
	healthBar.y = -100;
	self.addChild(healthBar);
	self.healthBar = healthBar;
	// Stats text below warrior
	var statsText = new Text2('', {
		size: 48,
		fill: 0xFFFFFF,
		font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
	});
	statsText.anchor.set(0.5, 0.5);
	statsText.y = 120; // Position below the warrior
	self.addChild(statsText);
	self.statsText = statsText;
	// Function to update stats display
	self.updateStatsDisplay = function () {
		var attackSpeed = self.baseCooldown || 60;
		var range = 600;
		if (self.isRanged) {
			if (self.element === 'wind') {
				if (self.tier === 2) {
					range = 700;
				} else if (self.tier === 3) {
					range = 800;
				} else if (self.tier === 4) {
					range = 900;
				} else if (self.tier === 5) {
					range = 600;
				}
			}
		} else {
			range = 250;
		}
		var totalSpeed = self.speed + (self.aumento_velocidad || 0);
		var auraInfo = '';
		if (self.waterAuraCount && self.waterAuraCount > 0) {
			var speedReduction = self.waterAuraCount * 10;
			auraInfo = ' [Aura:' + speedReduction + '%]';
		}
		// Add distance counter for earth warriors tier 3+
		var distanceInfo = '';
		if (self.element === 'earth' && self.tier >= 3 && self.distancia_recorrida !== undefined) {
			distanceInfo = ' [Dist:' + Math.round(self.distancia_recorrida) + ']';
		}
		// Add conversion probability for wind warriors
		var conversionInfo = '';
		if (self.element === 'wind') {
			var conversionChance = 0;
			if (self.tier === 2 && self.goldenStatueChance) {
				conversionChance = Math.round(self.goldenStatueChance * 100);
				conversionInfo = ' [Conv:' + conversionChance + '%]';
			}
		}
		var statsString = self.health + '-' + self.damage + '-' + totalSpeed + '-' + range + '-' + attackSpeed + auraInfo + distanceInfo + conversionInfo;
		self.statsText.setText(statsString);
	};
	// Initialize stats display
	self.updateStatsDisplay();
	self.update = function () {
		if (pausa == false) {
			// Set base Y position for beat effect
			if (self.baseY === 0) {
				if (self.isFlying) {
					self.baseY = 1800; // Flying height
				} else {
					self.baseY = 2186; // Ground level
				}
			}
			// Apply beat effect if active
			if (self.beatEffectTimer > 0) {
				self.beatEffectTimer--;
				// Get current audio level and calculate rotation strength based on sensitivity difference
				var audioLevel = getGameMusicLevel();
				var sensitivityDifference = Math.max(0, audioLevel - musicBeatThreshold);
				if (sensitivityDifference > 0) {
					var rotationAmount = Math.sin((120 - self.beatEffectTimer) * 0.3) * sensitivityDifference * 0.785;
					warriorGraphics.rotation = rotationAmount;
				} else {
					warriorGraphics.rotation = 0; // No rotation when no difference
				}
			} else {
				warriorGraphics.rotation = 0; // Reset rotation when effect ends
				// Apply gravity only to non-flying units
				if (!self.isFlying && !self.onGround) {
					self.velocityY += self.gravity;
					self.y += self.velocityY;
				}
				// Ground collision for non-flying units
				var groundY = 2186;
				if (!self.isFlying && self.y >= groundY) {
					self.y = groundY;
					self.baseY = groundY; // Update base position
					self.velocityY = 0;
					self.onGround = true;
				} else if (!self.isFlying) {
					self.onGround = false;
				}
				// Flying units hover at a specific height
				if (self.isFlying) {
					self.y = 1800; // Fly above ground level
					self.baseY = 1800; // Update base position
				}
			}
			// Move towards enemy tower only if movement is enabled
			if (!self.target && self.activar_movimiento) {
				var totalSpeed = self.speed + (self.aumento_velocidad || 0);
				var previousX = self.x; // Store previous position for distance calculation
				self.x += totalSpeed;
				// Track distance for earth warriors tier 3+
				if (self.element === 'earth' && self.tier >= 3 && self.distancia_recorrida !== undefined) {
					// Add 1 per movement unit (remove random offset from movement tracking)
					self.distancia_recorrida += 1;
					// Update stats display in real time to show distance changes
					self.updateStatsDisplay();
				}
			}
			// Attack logic
			if (self.attackCooldown > 0) {
				self.attackCooldown--;
			}
			// Light warrior tier 4 automatic laser beam attack
			if (self.element === 'light' && self.tier === 4 && self.canLaserBeam) {
				// Fire laser beam every 3 seconds (180 frames) instead of projectiles
				if (self.attackCooldown <= 0) {
					// Find enemies in front of warrior
					var enemiesInRange = [];
					for (var e = 0; e < enemies.length; e++) {
						var enemy = enemies[e];
						var distance = Math.sqrt(Math.pow(self.x - enemy.x, 2) + Math.pow(self.y - enemy.y, 2));
						if (distance < 2000 && enemy.x > self.x) {
							// Enemies in front and within 2000 units
							enemiesInRange.push(enemy);
						}
					}
					if (enemiesInRange.length > 0) {
						// Create laser beam from warrior position to far right of map using rayo_amarillo image asset
						var laserBeam = game.addChild(LK.getAsset('rayo_amarillo', {
							anchorX: 0.0,
							anchorY: 0.5,
							x: self.x,
							y: self.y,
							width: 4000,
							height: 50
						}));
						laserBeam.alpha = 0.9;
						// Animate laser beam appearance and fade
						tween(laserBeam, {
							scaleY: 3.0,
							alpha: 1.0
						}, {
							duration: 200,
							onFinish: function onFinish() {
								tween(laserBeam, {
									alpha: 0,
									scaleY: 0.1
								}, {
									duration: 800,
									onFinish: function onFinish() {
										laserBeam.destroy();
									}
								});
							}
						});
						// Deal damage to all enemies in laser path
						for (var e = 0; e < enemies.length; e++) {
							var enemy = enemies[e];
							// Check if enemy is in laser path (Y coordinate within beam height)
							var yDistance = Math.abs(enemy.y - self.y);
							var xDistance = enemy.x - self.x;
							if (yDistance < 100 && xDistance > 0 && xDistance < 4000) {
								var finalDamage = self.damage + (self.auraDamageBonus || 0);
								enemy.takeDamage(finalDamage);
							}
						}
						showCombinationMessage('¡RAYO LASER GOKU ACTIVADO!');
						self.attackCooldown = 180; // 3 second cooldown
					}
				}
			}
			// Update heal cooldown for water warriors
			if (self.canHeal && self.healCooldown > 0) {
				self.healCooldown--;
			}
			// Water warrior self-healing (tier 2+)
			if (self.element === 'water' && self.tier >= 2 && self.selfHealTimer !== undefined) {
				self.selfHealTimer++;
				if (self.selfHealTimer >= 60) {
					// Every second (60 frames at 60fps)
					if (self.health < self.maxHealth) {
						self.health = Math.min(self.health + self.selfHealRate, self.maxHealth);
						// Self-healing visual effect
						tween(warriorGraphics, {
							tint: 0x00ff00
						}, {
							duration: 300,
							onFinish: function onFinish() {
								tween(warriorGraphics, {
									tint: 0xffffff
								}, {
									duration: 300
								});
							}
						});
						// Add healing particles for tier 2 water warrior self-healing
						if (self.tier === 2) {
							for (var p = 0; p < 6; p++) {
								var particle = game.addChild(LK.getAsset('particulas_curacion', {
									anchorX: 0.5,
									anchorY: 0.5,
									x: self.x + (Math.random() - 0.5) * 80,
									y: self.y + (Math.random() - 0.5) * 80,
									width: 120 + Math.random() * 80,
									height: 120 + Math.random() * 80
								}));
								particle.alpha = 0.8;
								tween(particle, {
									y: self.y - 100 - Math.random() * 50,
									alpha: 0,
									scaleX: 0.2,
									scaleY: 0.2
								}, {
									duration: 800,
									easing: tween.easeOut,
									onFinish: function onFinish() {
										particle.destroy();
									}
								});
							}
						}
					}
					self.selfHealTimer = 0;
				}
			}
			// Water warrior aura effects (tier 3+)
			if (self.element === 'water' && self.tier >= 3 && self.auraRange !== undefined) {
				// Apply aura damage bonus and attack speed reduction to nearby allies
				for (var j = 0; j < warriors.length; j++) {
					var ally = warriors[j];
					if (ally !== self && ally.element !== 'water') {
						var allyDistance = Math.sqrt(Math.pow(self.x - ally.x, 2) + Math.pow(self.y - ally.y, 2));
						if (allyDistance < self.auraRange) {
							// Count number of water tier 3+ warriors affecting this ally
							var waterAuraCount = 0;
							for (var k = 0; k < warriors.length; k++) {
								var waterWarrior = warriors[k];
								if (waterWarrior.element === 'water' && waterWarrior.tier >= 3) {
									var waterDistance = Math.sqrt(Math.pow(waterWarrior.x - ally.x, 2) + Math.pow(waterWarrior.y - ally.y, 2));
									if (waterDistance < waterWarrior.auraRange) {
										waterAuraCount++;
									}
								}
							}
							// Only apply speed changes if aura count has changed
							var previousAuraCount = ally.waterAuraCount || 0;
							if (waterAuraCount !== previousAuraCount) {
								// Initialize originalBaseCooldown if not set
								if (!ally.originalBaseCooldown) {
									ally.originalBaseCooldown = ally.baseCooldown || 60;
								}
								// Calculate cumulative speed reduction: each aura reduces by 10%
								var speedReduction = waterAuraCount * 10; // 10% per aura
								var finalSpeedMultiplier = Math.max(0.1, (100 - speedReduction) / 100); // Minimum 0.1 (10% attack speed)
								// Apply the speed reduction to original base cooldown (multiply to reduce cooldown = attack faster)
								ally.baseCooldown = Math.floor(ally.originalBaseCooldown * finalSpeedMultiplier);
								ally.waterAuraCount = waterAuraCount;
								ally.auraAffected = waterAuraCount > 0;
								ally.auraDamageBonus = waterAuraCount > 0 ? self.auraDamageBonus : 0;
							} else {
								// Keep existing values without recalculation
								ally.waterAuraCount = waterAuraCount;
								ally.auraAffected = waterAuraCount > 0;
								ally.auraDamageBonus = waterAuraCount > 0 ? self.auraDamageBonus : 0;
							}
							// Create continuous particles for allies under aura effect (without tinting)
							if (waterAuraCount > 0) {
								// Create continuous particles (7.5x larger)
								if (LK.ticks % 30 === 0) {
									// Every 0.5 seconds
									for (var p = 0; p < 3; p++) {
										var particle = game.addChild(LK.getAsset('particulas_delfin', {
											anchorX: 0.5,
											anchorY: 0.5,
											x: ally.x + (Math.random() - 0.5) * 80,
											y: ally.y + (Math.random() - 0.5) * 80,
											width: (30 + Math.random() * 15) * 7.5,
											height: (30 + Math.random() * 15) * 7.5
										}));
										particle.alpha = 0.8;
										particle.tint = 0xff22aa; // More intense pink color for dolphin particles
										tween(particle, {
											y: ally.y - 100 - Math.random() * 40,
											alpha: 0,
											scaleX: 0.2,
											scaleY: 0.2
										}, {
											duration: 800,
											easing: tween.easeOut,
											onFinish: function onFinish() {
												particle.destroy();
											}
										});
									}
								}
							}
							// Visual feedback when aura count changes
							if (previousAuraCount !== waterAuraCount && waterAuraCount > 0) {
								// Blue glow effect when gaining aura
								tween(ally.children[0], {
									tint: 0x00aaff
								}, {
									duration: 300,
									onFinish: function onFinish() {
										tween(ally.children[0], {
											tint: 0xffffff // Back to white instead of pink
										}, {
											duration: 300
										});
									}
								});
								// Create visual particles around affected ally
								for (var p = 0; p < 4; p++) {
									var particle = game.addChild(LK.getAsset('particulas_curacion', {
										anchorX: 0.5,
										anchorY: 0.5,
										x: ally.x + (Math.random() - 0.5) * 60,
										y: ally.y + (Math.random() - 0.5) * 60,
										width: 40 + Math.random() * 20,
										height: 40 + Math.random() * 20
									}));
									particle.alpha = 0.6;
									particle.tint = 0x00aaff; // Blue for speed aura
									tween(particle, {
										y: ally.y - 80 - Math.random() * 30,
										alpha: 0,
										scaleX: 0.3,
										scaleY: 0.3
									}, {
										duration: 600,
										easing: tween.easeOut,
										onFinish: function onFinish() {
											particle.destroy();
										}
									});
								}
							}
						}
					}
				}
			}
			// Water warrior explosion healing (tier 3+)
			if (self.element === 'water' && self.tier >= 3 && self.explosionTimer !== undefined) {
				self.explosionTimer++;
				if (self.explosionTimer >= self.explosionInterval) {
					// Every 2 seconds
					// Create healing explosion at warrior position
					var explosion = game.addChild(LK.getAsset('particulas_curacion', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: self.x,
						y: self.y,
						width: 400,
						height: 400
					}));
					explosion.alpha = 0.7;
					explosion.tint = 0x00aaff;
					// Animate explosion
					tween(explosion, {
						scaleX: 3.0,
						scaleY: 3.0,
						alpha: 0
					}, {
						duration: 600,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							explosion.destroy();
						}
					});
					// Heal all allies within 400 units
					for (var j = 0; j < warriors.length; j++) {
						var ally = warriors[j];
						var healDistance = Math.sqrt(Math.pow(self.x - ally.x, 2) + Math.pow(self.y - ally.y, 2));
						if (healDistance < 400) {
							// Apply aura damage bonus to explosion healing amount
							var finalHealAmount = self.damage + (self.auraDamageBonus || 0);
							ally.health = Math.min(ally.health + finalHealAmount, ally.maxHealth);
							// Healing particles for affected allies
							for (var p = 0; p < 6; p++) {
								var particle = game.addChild(LK.getAsset('particulas_curacion', {
									anchorX: 0.5,
									anchorY: 0.5,
									x: ally.x + (Math.random() - 0.5) * 80,
									y: ally.y + (Math.random() - 0.5) * 80,
									width: 60 + Math.random() * 40,
									height: 60 + Math.random() * 40
								}));
								particle.alpha = 0.8;
								tween(particle, {
									y: ally.y - 100 - Math.random() * 50,
									alpha: 0,
									scaleX: 0.2,
									scaleY: 0.2
								}, {
									duration: 800,
									easing: tween.easeOut,
									onFinish: function onFinish() {
										particle.destroy();
									}
								});
							}
						}
					}
					self.explosionTimer = 0;
				}
			}
			// Water warrior healing wave (tier 5)
			if (self.element === 'water' && self.tier === 5 && self.waveTimer !== undefined) {
				self.waveTimer++;
				if (self.waveTimer >= self.waveInterval) {
					// Every 5 seconds
					// Create healing wave from player tower to end of map
					var wave = game.addChild(LK.getAsset('ola', {
						anchorX: 0.0,
						anchorY: 0.5,
						x: playerTower.x,
						y: playerTower.y - 200,
						width: 800,
						height: 1000
					}));
					wave.tint = 0x00ffff;
					// Store wave damage for collision detection
					wave.finalWaveDamage = self.damage + (self.auraDamageBonus || 0);
					// Track which enemies have been hit by this wave
					wave.hitEnemies = [];
					// Add wave update method for collision detection
					wave.update = function () {
						// Check collision with enemies for damage
						for (var e = 0; e < enemies.length; e++) {
							var enemy = enemies[e];
							// Check if enemy hasn't been hit by this wave yet
							if (wave.hitEnemies.indexOf(enemy) === -1) {
								// Check collision between wave and enemy - use wave center for better detection
								var waveCenterX = wave.x + wave.width * 0.5; // Center of wave
								var waveCenterY = wave.y; // Center Y position
								var waveDistance = Math.sqrt(Math.pow(waveCenterX - enemy.x, 2) + Math.pow(waveCenterY - enemy.y, 2));
								if (waveDistance < 300) {
									// Enemy is hit by wave - mark immediately to prevent multiple hits
									wave.hitEnemies.push(enemy);
									// Deal damage to enemy
									enemy.takeDamage(wave.finalWaveDamage);
									// Create splash effect at impact using salpicadura asset
									var splash = game.addChild(LK.getAsset('salpicadura', {
										anchorX: 0.5,
										anchorY: 0.5,
										x: enemy.x,
										y: enemy.y,
										width: 350,
										height: 350
									}));
									splash.alpha = 0.9;
									splash.tint = 0x00ffff;
									// Animate splash with scale and rotation
									tween(splash, {
										scaleX: 3.0,
										scaleY: 3.0,
										alpha: 0,
										rotation: Math.PI * 0.75
									}, {
										duration: 700,
										easing: tween.easeOut,
										onFinish: function onFinish() {
											splash.destroy();
										}
									});
									// Create additional water splash particles in a circular pattern
									for (var splashIndex = 0; splashIndex < 12; splashIndex++) {
										var angle = splashIndex / 12 * Math.PI * 2;
										var distance = 100 + Math.random() * 80;
										var splashEndX = enemy.x + Math.cos(angle) * distance;
										var splashEndY = enemy.y + Math.sin(angle) * distance;
										var splashParticle = game.addChild(LK.getAsset('salpicadura', {
											anchorX: 0.5,
											anchorY: 0.5,
											x: enemy.x,
											y: enemy.y,
											width: 60 + Math.random() * 40,
											height: 60 + Math.random() * 40
										}));
										splashParticle.alpha = 0.8;
										splashParticle.tint = 0x00ddff;
										// Animate splash particles spreading outward
										tween(splashParticle, {
											x: splashEndX,
											y: splashEndY,
											alpha: 0,
											scaleX: 0.2,
											scaleY: 0.2,
											rotation: Math.random() * Math.PI * 2
										}, {
											duration: 500 + Math.random() * 300,
											easing: tween.easeOut,
											onFinish: function onFinish() {
												splashParticle.destroy();
											}
										});
									}
								}
							}
						}
						// Check collision with warriors for speed boost
						for (var w = 0; w < warriors.length; w++) {
							var warrior = warriors[w];
							// Check if warrior hasn't been hit by this wave yet  
							if (wave.hitEnemies.indexOf(warrior) === -1) {
								// Check collision between wave and warrior - use wave center for better detection
								var waveCenterX = wave.x + wave.width * 0.5; // Center of wave
								var waveDistance = Math.sqrt(Math.pow(waveCenterX - warrior.x, 2) + Math.pow(wave.y - warrior.y, 2));
								if (waveDistance < 300) {
									// Warrior is hit by wave
									wave.hitEnemies.push(warrior);
									// Increase speed only if not already boosted by tier 5 water warrior wave
									if (!warrior.tier5WaveSpeedBoosted) {
										warrior.aumento_velocidad = (warrior.aumento_velocidad || 0) + 2;
										warrior.tier5WaveSpeedBoosted = true;
										// Visual effect for speed boost
										tween(warrior.children[0], {
											tint: 0x00ffff
										}, {
											duration: 500,
											onFinish: function onFinish() {
												tween(warrior.children[0], {
													tint: 0xffffff
												}, {
													duration: 500
												});
											}
										});
										warrior.updateStatsDisplay();
									}
								}
							}
						}
					};
					// Animate wave across the map
					tween(wave, {
						x: 4500,
						// Move to end of map
						scaleX: 2.0
					}, {
						duration: 3000,
						easing: tween.linear,
						onFinish: function onFinish() {
							wave.destroy();
						}
					});
					// Heal all allies to full health immediately
					for (var j = 0; j < warriors.length; j++) {
						warriors[j].health = warriors[j].maxHealth;
					}
					showCombinationMessage('¡TSUNAMI CURATIVO ACTIVADO!');
					self.waveTimer = 0;
				}
			}
			// Water warriors heal nearby allies
			if (self.canHeal && self.healCooldown <= 0) {
				self.healCooldown = 120; // 2 seconds
				// Heal nearby warriors
				for (var j = 0; j < warriors.length; j++) {
					var ally = warriors[j];
					if (ally !== self) {
						var allyDistance = Math.sqrt(Math.pow(self.x - ally.x, 2) + Math.pow(self.y - ally.y, 2));
						if (allyDistance < 600 && ally.health < ally.maxHealth) {
							// Apply aura damage bonus to healing amount
							var finalHealAmount = self.damage + (self.auraDamageBonus || 0);
							ally.health = Math.min(ally.health + finalHealAmount, ally.maxHealth);
							// Healing effect
							tween(ally.children[0], {
								tint: 0x00ff88
							}, {
								duration: 200,
								onFinish: function onFinish() {
									tween(ally.children[0], {
										tint: 0xffffff
									}, {
										duration: 200
									});
								}
							});
							// Create healing particles
							for (var particleIndex = 0; particleIndex < 8; particleIndex++) {
								var particle = game.addChild(LK.getAsset('particulas_curacion', {
									anchorX: 0.5,
									anchorY: 0.5,
									x: ally.x + (Math.random() - 0.5) * 100,
									y: ally.y + (Math.random() - 0.5) * 100,
									width: 140 + Math.random() * 100,
									height: 140 + Math.random() * 100
								}));
								particle.alpha = 0.8;
								// Animate particles upward and fade out
								tween(particle, {
									y: ally.y - 150 - Math.random() * 50,
									x: ally.x + (Math.random() - 0.5) * 200,
									alpha: 0,
									scaleX: 0.3,
									scaleY: 0.3
								}, {
									duration: 800 + Math.random() * 400,
									easing: tween.easeOut,
									onFinish: function onFinish() {
										particle.destroy();
									}
								});
							}
						}
					}
				}
			}
			// Check for enemies to attack and combat engagement
			var inCombat = false;
			var attackRange = 250; // Default melee range
			if (self.isRanged) {
				attackRange = 600; // Default ranged
				if (self.element === 'wind') {
					if (self.tier === 1) {
						attackRange = 600;
					} else if (self.tier === 2) {
						attackRange = 700;
					} else if (self.tier === 3) {
						attackRange = 800;
					} else if (self.tier === 4) {
						attackRange = 900;
					} else if (self.tier === 5) {
						attackRange = 600;
					}
				}
			}
			// For wind warriors (aerial units), find the closest enemy
			if (self.element === 'wind' && self.isFlying) {
				var closestEnemy = null;
				var closestDistance = Infinity; // Start with infinite distance
				// For tier 5, find closest enemy regardless of range
				if (self.tier === 5) {
					// Find the closest enemy on the entire map
					for (var i = 0; i < enemies.length; i++) {
						var enemy = enemies[i];
						var distance = Math.sqrt(Math.pow(self.x - enemy.x, 2) + Math.pow(self.y - enemy.y, 2));
						if (distance < closestDistance) {
							closestEnemy = enemy;
							closestDistance = distance;
						}
					}
				} else {
					// For other tiers, find closest enemy within range
					for (var i = 0; i < enemies.length; i++) {
						var enemy = enemies[i];
						var distance = Math.sqrt(Math.pow(self.x - enemy.x, 2) + Math.pow(self.y - enemy.y, 2));
						if (distance < attackRange && distance < closestDistance) {
							closestEnemy = enemy;
							closestDistance = distance;
						}
					}
				}
				// Attack the closest enemy if found
				if (closestEnemy && self.attackCooldown <= 0) {
					inCombat = true;
					self.attack(closestEnemy);
					// Attack animation - flash blue and scale up while preserving tier scale
					var attackScale = self.tierScale * 1.4;
					tween(warriorGraphics, {
						tint: 0x00ffff,
						scaleX: attackScale,
						scaleY: attackScale
					}, {
						duration: 300,
						onFinish: function onFinish() {
							tween(warriorGraphics, {
								tint: 0xffffff,
								scaleX: self.tierScale,
								scaleY: self.tierScale
							}, {
								duration: 300
							});
						}
					});
				}
			} else {
				// Original logic for all other units
				for (var i = 0; i < enemies.length; i++) {
					var enemy = enemies[i];
					// Use half width for warrior and enemy colliders but keep full height
					var warriorColliderWidth = 288 * 0.5; // Half of warrior width
					var enemyColliderWidth = 280 * 0.5; // Half of enemy width
					var distance = Math.sqrt(Math.pow(self.x - enemy.x, 2) + Math.pow(self.y - enemy.y, 2));
					if (distance < attackRange) {
						// Mark as in combat to stop movement for all ranged units including water warriors
						inCombat = true;
						// Attack logic based on warrior type
						if (self.attackCooldown <= 0) {
							if (self.element === 'water') {
								// Water warriors only do ranged attacks
								if (self.isRanged) {
									self.attack(enemy);
									// Attack animation - flash blue and scale up while preserving tier scale
									var attackScale = self.tierScale * 1.4;
									tween(warriorGraphics, {
										tint: 0x00ffff,
										scaleX: attackScale,
										scaleY: attackScale
									}, {
										duration: 300,
										onFinish: function onFinish() {
											tween(warriorGraphics, {
												tint: 0xffffff,
												scaleX: self.tierScale,
												scaleY: self.tierScale
											}, {
												duration: 300
											});
										}
									});
								}
							} else if (self.isRanged && !(self.element === 'light' && self.tier === 4)) {
								// Other ranged warriors (light except tier 4, wind)
								self.attack(enemy);
								// Attack animation - flash blue and scale up while preserving tier scale
								var attackScale = self.tierScale * 1.4;
								tween(warriorGraphics, {
									tint: 0x00ffff,
									scaleX: attackScale,
									scaleY: attackScale
								}, {
									duration: 300,
									onFinish: function onFinish() {
										tween(warriorGraphics, {
											tint: 0xffffff,
											scaleX: self.tierScale,
											scaleY: self.tierScale
										}, {
											duration: 300
										});
									}
								});
							} else {
								// Melee warriors (fire, earth) - attack directly
								self.attack(enemy);
								// Attack animation - flash red for fire warriors and scale up while preserving tier scale
								var attackTint = self.element === 'fire' ? 0xff4400 : 0x8b4513; // Fire red or earth brown
								var attackScale = self.tierScale * 1.4;
								tween(warriorGraphics, {
									tint: attackTint,
									scaleX: attackScale,
									scaleY: attackScale
								}, {
									duration: 300,
									onFinish: function onFinish() {
										tween(warriorGraphics, {
											tint: 0xffffff,
											scaleX: self.tierScale,
											scaleY: self.tierScale
										}, {
											duration: 300
										});
									}
								});
							}
						}
						// Break out of loop for all ranged units except wind warriors to stop movement
						if (self.isRanged && self.element !== 'wind') {
							break;
						} else if (!self.isRanged) {
							break;
						}
					}
				}
			}
			// Check if warrior is at the tower x position - stop movement to focus on tower attack
			var atTowerPosition = Math.abs(self.x - playerTower.x) <= 50;
			// Update projectiles for ranged units
			if (self.isRanged) {
				for (var p = self.projectiles.length - 1; p >= 0; p--) {
					var proj = self.projectiles[p];
					proj.x += proj.speedX;
					proj.y += proj.speedY;
					var projectileDestroyed = false;
					// Water warrior projectiles can heal allies
					if (self.element === 'water') {
						// Check collision with allies first
						for (var w = 0; w < warriors.length; w++) {
							var ally = warriors[w];
							if (ally !== self) {
								// Use half width for ally collider but keep full height
								var allyColliderWidth = 288 * 0.5; // Half of ally width
								var allyDistance = Math.sqrt(Math.pow(proj.x - ally.x, 2) + Math.pow(proj.y - ally.y, 2));
								if (allyDistance < 50) {
									// Hit ally
									if (ally.health < ally.maxHealth) {
										// Heal ally if not at full health (heal amount equals water warrior's damage plus aura bonus)
										var finalHealAmount = self.damage + (self.auraDamageBonus || 0);
										ally.health = Math.min(ally.health + finalHealAmount, ally.maxHealth);
										// Healing effect
										tween(ally.children[0], {
											tint: 0x00ff88
										}, {
											duration: 200,
											onFinish: function onFinish() {
												tween(ally.children[0], {
													tint: 0xffffff
												}, {
													duration: 200
												});
											}
										});
										// Create healing particles
										for (var particleIndex = 0; particleIndex < 8; particleIndex++) {
											var particle = game.addChild(LK.getAsset('particulas_curacion', {
												anchorX: 0.5,
												anchorY: 0.5,
												x: ally.x + (Math.random() - 0.5) * 100,
												y: ally.y + (Math.random() - 0.5) * 100,
												width: 140 + Math.random() * 100,
												height: 140 + Math.random() * 100
											}));
											particle.alpha = 0.8;
											// Animate particles upward and fade out
											tween(particle, {
												y: ally.y - 150 - Math.random() * 50,
												x: ally.x + (Math.random() - 0.5) * 200,
												alpha: 0,
												scaleX: 0.3,
												scaleY: 0.3
											}, {
												duration: 800 + Math.random() * 400,
												easing: tween.easeOut,
												onFinish: function onFinish() {
													particle.destroy();
												}
											});
										}
										proj.destroy();
										self.projectiles.splice(p, 1);
										projectileDestroyed = true;
										break;
									}
									// If ally is at full health, projectile passes through
								}
							}
						}
					}
					// Check collision with enemies only if projectile wasn't destroyed by healing
					if (!projectileDestroyed) {
						for (var e = 0; e < enemies.length; e++) {
							var enemy = enemies[e];
							// Use half width for enemy collider but keep full height
							var enemyColliderWidth = 280 * 0.5; // Half of enemy width
							var projDistance = Math.sqrt(Math.pow(proj.x - enemy.x, 2) + Math.pow(proj.y - enemy.y, 2));
							if (projDistance < 80) {
								// Increased collision radius for better detection
								// Hit enemy
								if (self.canAreaDamage) {
									// Create lightning explosion visual effect at projectile impact point
									var explosion = game.addChild(LK.getAsset('efecto_electricidad', {
										anchorX: 0.5,
										anchorY: 0.5,
										x: proj.x,
										y: proj.y,
										width: 240,
										height: 240
									}));
									explosion.alpha = 0.9;
									// Animate explosion - scale up and fade out
									tween(explosion, {
										scaleX: 3.0,
										scaleY: 3.0,
										alpha: 0
									}, {
										duration: 400,
										easing: tween.easeOut,
										onFinish: function onFinish() {
											explosion.destroy();
										}
									});
									// Light warrior tier 2 - create second explosion at 300 units away
									if (self.element === 'light' && self.tier === 2 && self.canSecondExplosion) {
										// Calculate direction vector from projectile to enemy for horizontal distance
										var dirX = enemy.x - proj.x;
										var distance = Math.sqrt(dirX * dirX + Math.pow(enemy.y - proj.y, 2));
										var normalizedX = dirX / distance;
										// Create second explosion 300 units away horizontally, same Y as first explosion
										var secondExplosionX = proj.x + normalizedX * 300;
										var secondExplosionY = proj.y; // Same Y position as first explosion
										var secondExplosion = game.addChild(LK.getAsset('efecto_electricidad', {
											anchorX: 0.5,
											anchorY: 0.5,
											x: secondExplosionX,
											y: secondExplosionY,
											width: 240,
											height: 240
										}));
										secondExplosion.alpha = 0.9;
										secondExplosion.tint = 0xffff88; // Slightly yellow tint for second explosion
										// Animate second explosion
										tween(secondExplosion, {
											scaleX: 3.0,
											scaleY: 3.0,
											alpha: 0
										}, {
											duration: 400,
											easing: tween.easeOut,
											onFinish: function onFinish() {
												secondExplosion.destroy();
											}
										});
										// Apply area damage around second explosion
										for (var ae2 = 0; ae2 < enemies.length; ae2++) {
											var areaEnemy2 = enemies[ae2];
											var areaDistance2 = Math.sqrt(Math.pow(secondExplosionX - areaEnemy2.x, 2) + Math.pow(secondExplosionY - areaEnemy2.y, 2));
											if (areaDistance2 < 300) {
												areaEnemy2.takeDamage(self.damage);
											}
										}
									}
									// Create electric particles expanding from explosion center
									for (var particleIndex = 0; particleIndex < 12; particleIndex++) {
										var angle = particleIndex / 12 * Math.PI * 2; // Distribute evenly in circle
										var distance = 150 + Math.random() * 100;
										var particleEndX = proj.x + Math.cos(angle) * distance;
										var particleEndY = proj.y + Math.sin(angle) * distance;
										var electricParticle = game.addChild(LK.getAsset('efecto_electricidad', {
											anchorX: 0.5,
											anchorY: 0.5,
											x: proj.x,
											y: proj.y,
											width: 20 + Math.random() * 20,
											height: 20 + Math.random() * 20
										}));
										electricParticle.alpha = 0.8;
										// Animate particles expanding outward and fading
										tween(electricParticle, {
											x: particleEndX,
											y: particleEndY,
											alpha: 0,
											scaleX: 0.2,
											scaleY: 0.2
										}, {
											duration: 300 + Math.random() * 200,
											easing: tween.easeOut,
											onFinish: function onFinish() {
												electricParticle.destroy();
											}
										});
									}
									// Lightning area damage - increased damage for area effect
									for (var ae = 0; ae < enemies.length; ae++) {
										var areaEnemy = enemies[ae];
										var areaDistance = Math.sqrt(Math.pow(proj.x - areaEnemy.x, 2) + Math.pow(proj.y - areaEnemy.y, 2));
										if (areaDistance < 600) {
											areaEnemy.takeDamage(1); // Set damage to 1 for area effect
										}
									}
								} else {
									// Handle wind warrior special effects
									if (self.element === 'wind') {
										// Apply base damage first
										var finalDamage = self.damage + (self.auraDamageBonus || 0);
										// Tier 5: Check if enemy has already been attacked by this warrior
										if (self.tier === 5) {
											// Check if this enemy has already been attacked by this specific warrior
											if (self.attackedEnemies && self.attackedEnemies.indexOf(enemy) !== -1) {
												// Enemy already attacked, skip damage and effects
												proj.destroy();
												self.projectiles.splice(p, 1);
												projectileDestroyed = true;
												break;
											}
											// Mark this enemy as attacked by this warrior before dealing damage
											if (self.attackedEnemies) {
												self.attackedEnemies.push(enemy);
											}
										}
										enemy.takeDamage(finalDamage);
										// Tier 3: Apply esmeralda with 50% probability
										if (self.tier === 3) {
											// Apply emerald statue effect with 50% probability
											if (Math.random() < 0.5) {
												enemy.enemigo_oro = true;
											}
										}
										// Tier 2: Golden statue effect
										if (proj.goldenStatueChance && Math.random() < proj.goldenStatueChance) {
											enemy.isGoldenStatue = true;
											enemy.enemigo_oro = true; // Set golden statue variable
											enemy.activar_movimiento = false;
											enemy.canAttack = false;
											// Remove golden statue effect after some time (permanent for now)
										}
										// Tier 4: Apply sleep effect first, then emerald statue effect, then convert enemy with 33% chance
										else if (self.tier === 4) {
											// Apply sleep effect first
											enemy.dormido = true;
											// Then apply emerald statue effect
											enemy.enemigo_oro = true;
											// Call conversion function with 33% probability
											if (Math.random() < 0.33) {
												convertir_enemigos_esmeralda(enemy);
											}
										}
										// Tier 5: Apply esmeralda and vortex effects
										else if (self.tier === 5) {
											// Apply emerald statue effect
											enemy.enemigo_oro = true;
											// Apply vortex effect
											enemy.vortice = true;
											// Create tornado image at enemy center
											var tornado = game.addChild(LK.getAsset('tornado', {
												anchorX: 0.5,
												anchorY: 0.5,
												x: enemy.x,
												y: enemy.y,
												width: 500,
												height: 500
											}));
											tornado.alpha = 0.5;
											// Store tornado reference in enemy
											enemy.tornado = tornado;
											// Start 10-second vortex damage timer
											var vortexDamageTimer = 0;
											var vortexDamageInterval = LK.setInterval(function () {
												if (enemy && enemy.vortice && enemy.health > 0) {
													// Deal 10% of max health as damage
													var vortexDamage = Math.ceil(enemy.maxHealth * 0.1);
													enemy.takeDamage(vortexDamage);
													// Update tornado position to follow enemy
													if (tornado) {
														tornado.x = enemy.x;
														tornado.y = enemy.y;
													}
													vortexDamageTimer += 1000; // Increment by 1 second
													// Check if 10 seconds have passed
													if (vortexDamageTimer >= 10000) {
														// Remove vortex effect after 10 seconds
														enemy.vortice = false;
														if (tornado) {
															tornado.destroy();
														}
														enemy.tornado = null;
														LK.clearInterval(vortexDamageInterval);
													}
												} else {
													// Clean up if enemy is destroyed
													if (tornado) {
														tornado.destroy();
													}
													enemy.tornado = null;
													LK.clearInterval(vortexDamageInterval);
												}
											}, 1000); // Every 1 second
										}
									} else if (self.element === 'water') {
										enemy.takeDamage(self.damage);
									} else {
										// Apply aura damage bonus if affected by water warrior aura
										var finalDamage = self.damage + (self.auraDamageBonus || 0);
										enemy.takeDamage(finalDamage);
									}
								}
								proj.destroy();
								self.projectiles.splice(p, 1);
								projectileDestroyed = true;
								break;
							}
						}
					}
					// Remove projectiles that go off screen only if not already destroyed
					if (!projectileDestroyed && (proj.x > 4500 || proj.x < -500 || proj.y > 3500 || proj.y < -500)) {
						proj.destroy();
						self.projectiles.splice(p, 1);
					}
				}
			}
			// Set activar_movimiento based on combat state and element type
			if (inCombat && self.element !== 'wind') {
				// Stop movement for all elements except wind when in combat range
				self.activar_movimiento = false;
			} else {
				// Allow movement when not in combat, and always allow movement for wind warriors
				self.activar_movimiento = true;
			}
			// Special case: Wind warriors always maintain movement, even during combat
			if (self.element === 'wind') {
				self.activar_movimiento = true;
			}
			// Apply movement based on activar_movimiento flag
			// Wind warriors ignore tower position blocking and maintain movement
			if (!self.activar_movimiento || atTowerPosition && self.element !== 'wind') {
				self.speed = 0;
			} else {
				// Resume normal movement - use individual warrior's original speed instead of overriding with base speed
				// Only restore to base speed if warrior doesn't have an individual speed set
				if (!self.originalSpeed) {
					// Store the original speed set during warrior creation
					if (self.element === 'fire') {
						self.originalSpeed = 2.2;
					} else if (self.element === 'water') {
						self.originalSpeed = 1.8;
					} else if (self.element === 'earth') {
						self.originalSpeed = 1.5;
					} else if (self.element === 'light') {
						self.originalSpeed = 2.5;
					} else if (self.element === 'wind') {
						self.originalSpeed = self.speed; // Use the speed already set during creation
					} else {
						self.originalSpeed = 2; // Default
					}
				}
				self.speed = self.originalSpeed;
			}
			// Earth warrior wall creation (tier 3+)
			if (self.element === 'earth' && self.tier >= 3 && self.canCreateWalls && self.distancia_recorrida !== undefined) {
				// Check if we've traveled 1100 units to create a wall
				if (self.distancia_recorrida >= 1100) {
					// Determine wall asset and size based on tier
					var wallAsset, wallWidth, wallHeight;
					if (self.tier === 3) {
						wallAsset = 'muro_tierra';
						wallWidth = 360; // Normal size
						wallHeight = 393;
					} else if (self.tier === 4) {
						wallAsset = 'muro_tierra_nivel_2';
						wallWidth = 540; // 50% bigger
						wallHeight = 590;
					} else if (self.tier === 5) {
						wallAsset = 'muro_tierra_nivel_3';
						wallWidth = 720; // 100% bigger
						wallHeight = 786;
					}
					// Create wall positioned like a warrior unit
					var wall = game.addChild(LK.getAsset(wallAsset, {
						anchorX: 0.5,
						anchorY: 0.5,
						x: self.x,
						y: 2186,
						// Ground level - centered like warriors
						width: wallWidth,
						height: wallHeight
					}));
					wall.alpha = 0.75; // 75% opacity
					wall.isWall = true;
					wall.health = self.wallHealth;
					wall.maxHealth = self.wallHealth;
					wall.activar_movimiento = false; // Cannot move like warriors
					wall.canAttack = false; // Cannot attack like warriors
					// Create green health bar for wall (50% larger and visible)
					var wallHealthBar = LK.getAsset('warriorHealthBar', {
						width: 180,
						height: 24
					});
					wallHealthBar.anchor.set(0.5, 0.5);
					wallHealthBar.x = 0; // Centered above wall
					wallHealthBar.y = -200; // Move much higher above wall
					wallHealthBar.alpha = 1.0; // Ensure full visibility
					// Add health bar directly to game instead of wall to ensure it's on top
					game.addChild(wallHealthBar);
					wall.healthBar = wallHealthBar;
					// Update health bar position when wall position changes
					wall.updateHealthBarPosition = function () {
						if (this.healthBar) {
							this.healthBar.x = this.x;
							this.healthBar.y = this.y - 200;
						}
					};
					wall.updateHealthBarPosition();
					wall.takeDamage = function (damage) {
						this.health -= damage;
						var healthPercent = this.health / this.maxHealth;
						if (this.healthBar) {
							this.healthBar.scaleX = healthPercent;
						}
						// Health bar color is already green from warriorHealthBar asset - no tinting needed
						// Flash wall red when taking damage
						tween(this.children[0], {
							tint: 0xff0000
						}, {
							duration: 200,
							onFinish: function () {
								tween(this.children[0], {
									tint: 0xffffff
								}, {
									duration: 200
								});
							}.bind(this)
						});
						// Create debris particles when wall takes damage
						var particleCount = damage * 8; // Scale particles with damage amount
						for (var debrisIndex = 0; debrisIndex < particleCount; debrisIndex++) {
							// 180-degree spread pattern (forward facing)
							var angle = (debrisIndex / particleCount - 0.5) * Math.PI; // Spread from -90 to +90 degrees
							var force = (150 + Math.random() * 200) * 3; // Random force
							var velocityX = Math.cos(angle) * force;
							var velocityY = Math.sin(angle) * force;
							var debrisParticle = game.addChild(LK.getAsset('escombros_torre_enemiga', {
								anchorX: 0.5,
								anchorY: 0.5,
								x: this.x,
								y: this.y - 100,
								width: (40 + Math.random() * 30) * 3,
								height: (40 + Math.random() * 30) * 3,
								rotation: Math.random() * Math.PI * 2
							}));
							debrisParticle.alpha = 0.9;
							debrisParticle.tint = 0x8B4513; // Brown color for earth debris
							// Add physics properties
							debrisParticle.velocityX = velocityX * 0.015; // Scale down for smooth movement
							debrisParticle.velocityY = velocityY * 0.015;
							debrisParticle.gravity = 0.6; // Gravity effect
							// Animate debris particles with physics
							tween(debrisParticle, {
								y: this.y + 150 + debrisParticle.velocityY * 80,
								x: this.x + debrisParticle.velocityX * 80,
								alpha: 0,
								rotation: debrisParticle.rotation + Math.PI * 3,
								scaleX: 0.1,
								scaleY: 0.1
							}, {
								duration: 1500 + Math.random() * 800,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									debrisParticle.destroy();
								}
							});
						}
						if (this.health <= 0) {
							// Clean up health bar before destroying wall
							if (this.healthBar) {
								this.healthBar.destroy();
								this.healthBar = null;
							}
							this.destroy();
						}
					};
					// Wall update function - acts like a stationary warrior
					wall.update = function () {
						// Update health bar position to stay above wall
						this.updateHealthBarPosition();
						// Check collision with enemies using warrior-like collision detection
						for (var e = 0; e < enemies.length; e++) {
							var enemy = enemies[e];
							// Use similar collision detection as warriors but with wall dimensions
							var wallColliderWidth = 240 * 0.5; // Half of wall width like warriors
							var enemyColliderWidth = 280 * 0.5; // Half of enemy width
							var distance = Math.sqrt(Math.pow(this.x - enemy.x, 2) + Math.pow(this.y - enemy.y, 2));
							if (distance < 200) {
								// Enemy in combat range with wall
								if (enemy.attackCooldown <= 0) {
									this.takeDamage(enemy.damage);
									enemy.attackCooldown = 80;
								}
								// Stop enemy movement when in combat with wall
								enemy.speed = 0;
								enemy.inCombat = true;
							} else if (distance > 350) {
								// Enemy far from wall, can resume movement
								if (!enemy.inCombat) {
									enemy.speed = 1.5;
								}
							}
						}
					};
					// Reset distance counter to 0 after creating wall
					self.distancia_recorrida = 0;
					self.updateStatsDisplay(); // Update display to show reset counter
				}
			}
			// Light warrior tier 5 tracking clouds - create one cloud per enemy
			if (self.element === 'light' && self.tier === 5 && self.canTrackingClouds) {
				// Check every 2 seconds (120 frames)
				if (LK.ticks % 120 === 0) {
					// Create a cloud for each enemy on the map
					for (var enemyIndex = 0; enemyIndex < enemies.length; enemyIndex++) {
						var targetEnemy = enemies[enemyIndex];
						// Check if this enemy already has a tracking cloud
						var hasCloud = false;
						for (var childIndex = 0; childIndex < game.children.length; childIndex++) {
							var child = game.children[childIndex];
							if (child.isTrackingCloud && child.targetEnemy === targetEnemy) {
								hasCloud = true;
								break;
							}
						}
						// Only create cloud if enemy doesn't have one
						if (!hasCloud) {
							var trackingCloud = game.addChild(LK.getAsset('shape', {
								anchorX: 0.5,
								anchorY: 0.5,
								x: targetEnemy.x,
								y: targetEnemy.y - 300,
								width: 280,
								height: 180
							}));
							trackingCloud.alpha = 0.8;
							trackingCloud.tint = 0x1a1aff; // 90% blue tint
							trackingCloud.targetEnemy = targetEnemy;
							trackingCloud.attackTimer = 0;
							trackingCloud.isTrackingCloud = true;
							trackingCloud.creatorDamage = 5; // Store tier 5 damage value at creation time
							trackingCloud.seguimiento_nube = false; // Tier 5 clouds don't retarget, destroy when enemy dies
							// Removed text display for cleaner visual appearance
							// Tracking cloud update function
							trackingCloud.update = function () {
								// Follow target enemy in X axis, stay 300 units above
								if (this.targetEnemy && !this.targetEnemy.isBeingDestroyed && this.targetEnemy.health > 0) {
									if (this.seguimiento_nube) {
										// Smooth movement for tracking clouds (tier 3)
										tween(this, {
											x: this.targetEnemy.x
										}, {
											duration: 200,
											easing: tween.easeOut
										});
									} else {
										// Instant movement for non-tracking clouds (tier 5)
										this.x = this.targetEnemy.x;
									}
								} else {
									// Target is destroyed, remove cloud (tier 5 behavior)
									this.destroy();
									return;
								}
								this.attackTimer++;
								// Attack every 1 second (60 frames)
								if (this.attackTimer >= 60) {
									this.attackTimer = 0;
									// Create lightning strike
									var lightning = game.addChild(LK.getAsset('rayo_electrico', {
										anchorX: 0.5,
										anchorY: 0.5,
										x: this.targetEnemy.x,
										y: this.targetEnemy.y,
										width: 300,
										height: 900
									}));
									lightning.alpha = 0.9;
									// Animate lightning
									tween(lightning, {
										scaleX: 2.0,
										scaleY: 0.1,
										alpha: 0
									}, {
										duration: 400,
										easing: tween.easeOut,
										onFinish: function onFinish() {
											lightning.destroy();
										}
									});
									// Store target health before damage to detect kills
									var targetHealthBefore = this.targetEnemy.health;
									// Direct hit damage to target using stored creator damage
									var directDamage = this.creatorDamage || 5; // Use stored damage or fallback to 5
									this.targetEnemy.takeDamage(directDamage);
									// Check if target died and this is the second cloud
									if (this.targetEnemy.health <= 0 && this.seguimiento_nube) {
										// Determine which cloud this is
										var cloudIndex = -1;
										var tier3Clouds = [];
										for (var childIndex = 0; childIndex < game.children.length; childIndex++) {
											var child = game.children[childIndex];
											if (child.createdByWarrior === this.createdByWarrior && child.seguimiento_nube === true) {
												tier3Clouds.push(child);
											}
										}
										// Find this cloud's index
										for (var i = 0; i < tier3Clouds.length; i++) {
											if (tier3Clouds[i] === this) {
												cloudIndex = i;
												break;
											}
										}
										// If this is the second cloud and it killed its target, find new farthest enemy
										if (cloudIndex === 1) {
											var farthestDistance = 0;
											var farthestEnemy = null;
											for (var e = 0; e < enemies.length; e++) {
												var enemy = enemies[e];
												if (enemy !== this.targetEnemy && enemy.health > 0 && !enemy.isBeingDestroyed) {
													var distanceToTower = Math.sqrt(Math.pow(enemyTower.x - enemy.x, 2) + Math.pow(enemyTower.y - enemy.y, 2));
													if (distanceToTower > farthestDistance) {
														farthestEnemy = enemy;
														farthestDistance = distanceToTower;
													}
												}
											}
											// Retarget to farthest enemy if found
											if (farthestEnemy) {
												this.targetEnemy = farthestEnemy;
											}
										}
									}
									// Explosion damage to nearby enemies (600 unit radius)
									var explosionX = this.targetEnemy.x;
									var explosionY = this.targetEnemy.y;
									for (var e = 0; e < enemies.length; e++) {
										var enemy = enemies[e];
										if (enemy !== this.targetEnemy) {
											var distance = Math.sqrt(Math.pow(explosionX - enemy.x, 2) + Math.pow(explosionY - enemy.y, 2));
											if (distance < 600) {
												// Use stored creator damage from cloud creation time
												var areaDamage = this.creatorDamage || 5; // Use stored damage or fallback to 5
												enemy.takeDamage(areaDamage); // 5 damage for area effect
											}
										}
									}
									// Create invisible explosion collider for area damage detection
									var explosionCollider = {
										x: explosionX,
										y: explosionY,
										radius: 600
									};
									// Create invisible explosion for additional area damage detection
									var invisibleExplosion = {
										x: explosionX,
										y: explosionY,
										radius: 600,
										damage: this.creatorDamage || 5
									};
									// Apply area damage to all enemies within 600-unit radius using invisible explosion
									for (var explosionIndex2 = 0; explosionIndex2 < enemies.length; explosionIndex2++) {
										var explosionEnemy2 = enemies[explosionIndex2];
										var explosionDistance2 = Math.sqrt(Math.pow(invisibleExplosion.x - explosionEnemy2.x, 2) + Math.pow(invisibleExplosion.y - explosionEnemy2.y, 2));
										if (explosionDistance2 < invisibleExplosion.radius) {
											// Apply damage from invisible explosion
											explosionEnemy2.takeDamage(invisibleExplosion.damage); // 5 damage for explosion area effect
										}
									}
									// Create explosion visual effect
									var explosion = game.addChild(LK.getAsset('efecto_electricidad', {
										anchorX: 0.5,
										anchorY: 0.5,
										x: explosionX,
										y: explosionY,
										width: 200,
										height: 200
									}));
									explosion.alpha = 0.8;
									tween(explosion, {
										scaleX: 3.0,
										scaleY: 3.0,
										alpha: 0
									}, {
										duration: 600,
										easing: tween.easeOut,
										onFinish: function onFinish() {
											explosion.destroy();
										}
									});
								}
							};
						}
					}
				}
			}
			// Light warrior tier 4 laser beam attack
			if (self.element === 'light' && self.tier === 4 && self.canLaserBeam) {
				// Fire laser beam every 10 seconds (600 frames)
				if (LK.ticks % 600 === 0) {
					// Create laser beam from warrior position to far right of map using rayo_amarillo image asset
					var laserBeam = game.addChild(LK.getAsset('rayo_amarillo', {
						anchorX: 0.0,
						anchorY: 0.5,
						x: self.x,
						y: self.y,
						width: 4000,
						height: 50
					}));
					laserBeam.alpha = 0.9;
					// Animate laser beam appearance and fade
					tween(laserBeam, {
						scaleY: 3.0,
						alpha: 1.0
					}, {
						duration: 200,
						onFinish: function onFinish() {
							tween(laserBeam, {
								alpha: 0,
								scaleY: 0.1
							}, {
								duration: 800,
								onFinish: function onFinish() {
									laserBeam.destroy();
								}
							});
						}
					});
					// Deal damage to all enemies in laser path
					for (var e = 0; e < enemies.length; e++) {
						var enemy = enemies[e];
						// Check if enemy is in laser path (Y coordinate within beam height)
						var yDistance = Math.abs(enemy.y - self.y);
						var xDistance = enemy.x - self.x;
						if (yDistance < 100 && xDistance > 0 && xDistance < 4000) {
							var finalDamage = self.damage + (self.auraDamageBonus || 0);
							enemy.takeDamage(finalDamage);
						}
					}
					showCombinationMessage('¡RAYO LASER GOKU ACTIVADO!');
				}
			}
			// Light warrior tier 3 cloud generation - only for existing warriors
			if (self.element === 'light' && self.tier === 3 && self.canCreateClouds && !self.cloudsCreated) {
				// Create 2 clouds only once when warrior is spawned
				self.cloudsCreated = true;
				for (var cloudIndex = 0; cloudIndex < 2; cloudIndex++) {
					// Create cloud positioned at enemy base with different offsets
					var cloudOffset = cloudIndex === 0 ? 300 : 500;
					var cloudXOffset = cloudIndex === 0 ? -300 : -600;
					var lightCloud = game.addChild(LK.getAsset('shape', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: enemyTower.x + cloudXOffset,
						y: self.y - cloudOffset,
						width: 300,
						height: 200
					}));
					lightCloud.alpha = 0.7;
					lightCloud.tint = 0x1a1aff; // 90% blue tint
					lightCloud.targetEnemy = null; // Will be assigned dynamically
					lightCloud.attackTimer = 0;
					lightCloud.createdByWarrior = self; // Reference to the warrior that created this cloud
					lightCloud.creatorDamage = self.damage; // Store creator's damage at creation time
					lightCloud.seguimiento_nube = true; // Tier 3 clouds have tracking behavior
					// Removed text display for cleaner visual appearance
					// Cloud update function
					lightCloud.update = function () {
						// Check if creator warrior still exists
						if (!this.createdByWarrior || this.createdByWarrior.isBeingDestroyed || this.createdByWarrior.health <= 0) {
							// Creator destroyed, remove cloud
							this.destroy();
							return;
						}
						// Find target enemy for tracking behavior
						if (this.seguimiento_nube) {
							var targetEnemy = null;
							// Determine which cloud this is based on creation order
							var cloudIndex = -1;
							var tier3Clouds = [];
							for (var childIndex = 0; childIndex < game.children.length; childIndex++) {
								var child = game.children[childIndex];
								if (child.createdByWarrior === this.createdByWarrior && child.seguimiento_nube === true) {
									tier3Clouds.push(child);
								}
							}
							// Find this cloud's index
							for (var i = 0; i < tier3Clouds.length; i++) {
								if (tier3Clouds[i] === this) {
									cloudIndex = i;
									break;
								}
							}
							if (cloudIndex === 0) {
								// First cloud: target closest enemy to tower
								var closestDistance = Infinity;
								for (var i = 0; i < enemies.length; i++) {
									var enemy = enemies[i];
									var distanceToTower = Math.sqrt(Math.pow(enemyTower.x - enemy.x, 2) + Math.pow(enemyTower.y - enemy.y, 2));
									if (distanceToTower < closestDistance) {
										targetEnemy = enemy;
										closestDistance = distanceToTower;
									}
								}
							} else if (cloudIndex === 1) {
								// Second cloud: target farthest enemy if no current target or current target is dead
								if (!this.targetEnemy || this.targetEnemy.health <= 0 || this.targetEnemy.isBeingDestroyed) {
									var farthestDistance = 0;
									for (var i = 0; i < enemies.length; i++) {
										var enemy = enemies[i];
										var distanceToTower = Math.sqrt(Math.pow(enemyTower.x - enemy.x, 2) + Math.pow(enemyTower.y - enemy.y, 2));
										if (distanceToTower > farthestDistance) {
											targetEnemy = enemy;
											farthestDistance = distanceToTower;
										}
									}
								} else {
									// Keep current target if still alive
									targetEnemy = this.targetEnemy;
								}
							}
							// Update target and follow
							if (targetEnemy) {
								this.targetEnemy = targetEnemy;
								if (this.seguimiento_nube) {
									// Smooth movement for tracking clouds
									tween(this, {
										x: this.targetEnemy.x
									}, {
										duration: 200,
										easing: tween.easeOut
									});
								} else {
									// Instant movement for non-tracking clouds
									this.x = this.targetEnemy.x;
								}
							}
						}
						this.attackTimer++;
						// Attack every 2 seconds (120 frames)
						if (this.attackTimer >= 120 && this.targetEnemy) {
							this.attackTimer = 0;
							// Create lightning bolt projectile
							var lightning = game.addChild(LK.getAsset('rayo_electrico', {
								anchorX: 0.5,
								anchorY: 0.5,
								x: this.targetEnemy.x,
								y: this.targetEnemy.y,
								width: 300,
								height: 900
							}));
							lightning.alpha = 0.9;
							// Animate lightning strike
							tween(lightning, {
								scaleY: 0.1,
								alpha: 0
							}, {
								duration: 300,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									lightning.destroy();
								}
							});
							// Area damage at impact point
							for (var e = 0; e < enemies.length; e++) {
								var enemy = enemies[e];
								var distance = Math.sqrt(Math.pow(this.x - enemy.x, 2) + Math.pow(this.y + 300 - enemy.y, 2));
								if (distance < 300) {
									// Use stored creator damage from cloud creation time
									var areaDamage = this.creatorDamage || 3; // Use stored damage or fallback to 3
									enemy.takeDamage(areaDamage);
									// Debug logging to verify area damage application
									console.log("Tier 3 cloud area damage applied:", areaDamage, "to enemy at distance:", Math.round(distance));
								}
							}
							// Create invisible explosion collider for area damage detection
							var explosionCollider = {
								x: this.x,
								y: this.y + 300,
								radius: 300
							};
							// Create invisible explosion for additional area damage detection
							var invisibleExplosion = {
								x: this.x,
								y: this.y + 300,
								radius: 300,
								damage: this.creatorDamage || 3
							};
							// Apply area damage to all enemies within 300-unit radius using invisible explosion
							for (var explosionIndex = 0; explosionIndex < enemies.length; explosionIndex++) {
								var explosionEnemy = enemies[explosionIndex];
								var explosionDistance = Math.sqrt(Math.pow(invisibleExplosion.x - explosionEnemy.x, 2) + Math.pow(invisibleExplosion.y - explosionEnemy.y, 2));
								if (explosionDistance < invisibleExplosion.radius) {
									// Apply damage from invisible explosion
									explosionEnemy.takeDamage(invisibleExplosion.damage); // 3 damage for explosion area effect
								}
							}
							// Create explosion visual effect - 200x200 size
							var explosion = game.addChild(LK.getAsset('efecto_electricidad', {
								anchorX: 0.5,
								anchorY: 0.5,
								x: this.x,
								y: this.y + 300,
								width: 200,
								height: 200
							}));
							explosion.alpha = 0.8;
							tween(explosion, {
								scaleX: 3.0,
								scaleY: 3.0,
								alpha: 0
							}, {
								duration: 600,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									explosion.destroy();
								}
							});
						}
					};
				}
			}
			// Wind warrior tier 3 spore generation
			if (self.element === 'wind' && self.tier === 3) {
				// Generate spores every 30 frames (0.5 seconds)
				if (LK.ticks % 30 === 0) {
					// Create 2-3 spores
					var numSpores = 2 + Math.floor(Math.random() * 2);
					for (var sporeIndex = 0; sporeIndex < numSpores; sporeIndex++) {
						var espora = new Espora(self);
						game.addChild(espora);
						esporas.push(espora);
					}
				}
			}
			// Wind warrior tier 5 enemy dragging and tower destruction
			if (self.element === 'earth' && self.tier === 5) {
				// Drag enemies backward every second
				if (LK.ticks % 60 === 0) {
					// Every second
					for (var e = 0; e < enemies.length; e++) {
						var enemy = enemies[e];
						var distance = Math.sqrt(Math.pow(self.x - enemy.x, 2) + Math.pow(self.y - enemy.y, 2));
						if (distance < 600) {
							// Push enemy forward 300 units smoothly (away from our towers)
							var targetX = enemy.x + 300;
							tween(enemy, {
								x: targetX
							}, {
								duration: 1000,
								// 1 second
								easing: tween.easeOut
							});
							// Deal damage each second of dragging
							enemy.takeDamage(self.damage);
							// Visual effect for dragging
							tween(enemy.children[0], {
								tint: 0x8b4513
							}, {
								duration: 200,
								onFinish: function onFinish() {
									tween(enemy.children[0], {
										tint: 0xffffff
									}, {
										duration: 200
									});
								}
							});
						}
					}
				}
				// Check if close to enemy tower for self-destruction
				var towerDistance = Math.sqrt(Math.pow(self.x - enemyTower.x, 2) + Math.pow(self.y - enemyTower.y, 2));
				if (towerDistance < 800 && self.canSelfDestruct) {
					// Self-destruct and become wall with 250 health
					showCombinationMessage('¡GUERRERO TIERRA SE SACRIFICA POR LA DEFENSA!');
					// Create mega wall positioned like a warrior unit
					var megaWall = game.addChild(LK.getAsset('muro_tierra_nivel_3', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: self.x,
						y: 2186,
						width: 720,
						// 100% larger wall (level 3)
						height: 786
					}));
					megaWall.alpha = 0.75; // 75% opacity
					megaWall.isWall = true;
					megaWall.health = 2000;
					megaWall.maxHealth = 2000;
					megaWall.activar_movimiento = false; // Cannot move like warriors
					megaWall.canAttack = false; // Cannot attack like warriors
					// Create green health bar for mega wall (50% larger and visible)
					var megaWallHealthBar = LK.getAsset('warriorHealthBar', {
						width: 216,
						height: 32
					});
					megaWallHealthBar.anchor.set(0.5, 0.5);
					megaWallHealthBar.x = 0; // Centered above mega wall
					megaWallHealthBar.y = -280; // Move much higher above mega wall
					megaWallHealthBar.alpha = 1.0; // Ensure full visibility
					// Add health bar directly to game instead of mega wall to ensure it's on top
					game.addChild(megaWallHealthBar);
					megaWall.healthBar = megaWallHealthBar;
					// Update health bar position when mega wall position changes
					megaWall.updateHealthBarPosition = function () {
						if (this.healthBar) {
							this.healthBar.x = this.x;
							this.healthBar.y = this.y - 280;
						}
					};
					megaWall.updateHealthBarPosition();
					megaWall.takeDamage = function (damage) {
						this.health -= damage;
						var healthPercent = this.health / this.maxHealth;
						if (this.healthBar) {
							this.healthBar.scaleX = healthPercent;
						}
						// Health bar color is already green from warriorHealthBar asset - no tinting needed
						// Flash mega wall red when taking damage
						tween(this.children[0], {
							tint: 0xff0000
						}, {
							duration: 200,
							onFinish: function () {
								tween(this.children[0], {
									tint: 0xffffff
								}, {
									duration: 200
								});
							}.bind(this)
						});
						// Create debris particles when mega wall takes damage
						var particleCount = damage * 12; // More particles for mega wall
						for (var debrisIndex = 0; debrisIndex < particleCount; debrisIndex++) {
							// 180-degree spread pattern (forward facing)
							var angle = (debrisIndex / particleCount - 0.5) * Math.PI; // Spread from -90 to +90 degrees
							var force = (200 + Math.random() * 250) * 4; // Stronger force for mega wall
							var velocityX = Math.cos(angle) * force;
							var velocityY = Math.sin(angle) * force;
							var debrisParticle = game.addChild(LK.getAsset('escombros_torre_enemiga', {
								anchorX: 0.5,
								anchorY: 0.5,
								x: this.x,
								y: this.y - 150,
								width: (50 + Math.random() * 40) * 4,
								height: (50 + Math.random() * 40) * 4,
								rotation: Math.random() * Math.PI * 2
							}));
							debrisParticle.alpha = 0.9;
							debrisParticle.tint = 0x8B4513; // Brown color for earth debris
							// Add physics properties
							debrisParticle.velocityX = velocityX * 0.02; // Scale down for smooth movement
							debrisParticle.velocityY = velocityY * 0.02;
							debrisParticle.gravity = 0.8; // Gravity effect
							// Animate debris particles with physics
							tween(debrisParticle, {
								y: this.y + 200 + debrisParticle.velocityY * 100,
								x: this.x + debrisParticle.velocityX * 100,
								alpha: 0,
								rotation: debrisParticle.rotation + Math.PI * 4,
								scaleX: 0.1,
								scaleY: 0.1
							}, {
								duration: 2000 + Math.random() * 1000,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									debrisParticle.destroy();
								}
							});
						}
						if (this.health <= 0) {
							// Clean up health bar before destroying mega wall
							if (this.healthBar) {
								this.healthBar.destroy();
								this.healthBar = null;
							}
							this.destroy();
						}
					};
					// Mega wall update function - acts like a stationary warrior
					megaWall.update = function () {
						// Update health bar position to stay above mega wall
						this.updateHealthBarPosition();
						// Check collision with enemies using warrior-like collision detection
						for (var e = 0; e < enemies.length; e++) {
							var enemy = enemies[e];
							// Use similar collision detection as warriors but with mega wall dimensions
							var megaWallColliderWidth = 360 * 0.5; // Half of mega wall width like warriors
							var enemyColliderWidth = 280 * 0.5; // Half of enemy width
							var distance = Math.sqrt(Math.pow(this.x - enemy.x, 2) + Math.pow(this.y - enemy.y, 2));
							if (distance < 250) {
								// Enemy in combat range with mega wall
								if (enemy.attackCooldown <= 0) {
									this.takeDamage(enemy.damage);
									enemy.attackCooldown = 80;
								}
								// Stop enemy movement when in combat with mega wall
								enemy.speed = 0;
								enemy.inCombat = true;
							} else if (distance > 450) {
								// Enemy far from mega wall, can resume movement
								if (!enemy.inCombat) {
									enemy.speed = 1.5;
								}
							}
						}
					};
					// Remove warrior from game
					self.isBeingDestroyed = true;
					var index = warriors.indexOf(self);
					if (index > -1) {
						warriors.splice(index, 1);
					}
					self.destroy();
					return; // Exit update after self-destruction
				}
			}
			// Check collision with enemy tower - use separate x and y collision detection for flying units
			var towerColliderRadius = 700; // Fixed collider size, not scaled with tower
			var warriorColliderWidth = 288 * 0.5; // Half of warrior width
			var warriorColliderHeight = 288; // Full warrior height
			// Increase collider height for tier 4 light warriors
			if (self.element === 'light' && self.tier === 4) {
				warriorColliderHeight = 288 + 500; // Add 500 pixels to height
			}
			var towerDistance = Math.sqrt(Math.pow(self.x - enemyTower.x, 2) + Math.pow(self.y - enemyTower.y, 2));
			var xDistance = Math.abs(self.x - enemyTower.x);
			var yDistance = Math.abs(self.y - enemyTower.y);
			// Debug collision for wind warriors
			if (self.element === 'wind') {
				collisionDebugText.setText('Wind Warrior - XDist: ' + Math.round(xDistance) + ' YDist: ' + Math.round(yDistance) + ' Pos: (' + Math.round(self.x) + ',' + Math.round(self.y) + ')');
			}
			// Use different collision detection for flying units vs ground units
			var collisionDetected = false;
			if (self.isFlying) {
				// For flying units, use x-distance only (ignore y difference)
				collisionDetected = xDistance < towerColliderRadius;
			} else {
				// For ground units, use traditional distance-based collision
				collisionDetected = towerDistance < towerColliderRadius;
			}
			if (collisionDetected && !self.isBeingDestroyed) {
				// Debug when collision happens
				if (self.element === 'wind') {
					collisionDebugText.setText('WIND COLLISION! XDist: ' + Math.round(xDistance) + ' Damage: ' + self.damage);
				}
				// Deal damage to tower first - always attack regardless of cooldown when touching tower
				self.attackTower();
				// Mark as being destroyed to prevent multiple collision detections
				self.isBeingDestroyed = true;
				// Remove from warriors array immediately
				var index = warriors.indexOf(self);
				if (index > -1) {
					warriors.splice(index, 1);
				}
				// Warrior self-destructs when touching the tower - immediate destruction
				self.destroy();
				return; // Exit update to prevent further execution after destruction
			}
			// Check projectile collision with enemy tower for ranged units - tower is invulnerable to projectiles
			if (self.isRanged) {
				for (var p = self.projectiles.length - 1; p >= 0; p--) {
					var proj = self.projectiles[p];
					var projTowerDistance = Math.sqrt(Math.pow(proj.x - enemyTower.x, 2) + Math.pow(proj.y - enemyTower.y, 2));
					if (projTowerDistance < 700) {
						// Fixed collider radius
						// Projectile hit the tower but tower is invulnerable - just destroy projectile
						proj.destroy();
						self.projectiles.splice(p, 1);
					}
				}
			}
			// Check if warrior is off-screen and destroy
			if (self.x < -500 || self.x > 4500 || self.y > 3500) {
				self.destroy();
				var index = warriors.indexOf(self);
				if (index > -1) {
					warriors.splice(index, 1);
				}
				return; // Exit update to prevent further execution
			}
			// Update health bar
			var healthPercent = self.health / self.maxHealth;
			self.healthBar.scaleX = healthPercent;
			self.healthBar.tint = healthPercent > 0.5 ? 0x00ff00 : healthPercent > 0.25 ? 0xffff00 : 0xff0000;
		}
	};
	self.attack = function (target) {
		self.attackCooldown = self.baseCooldown || 60; // Use tier-based cooldown
		if (target === enemyTower) {
			self.attackTower();
		} else if (self.isRanged) {
			// Light tier 4 warriors use laser beam instead of projectiles
			if (self.element === 'light' && self.tier === 4) {
				// Laser beam attack is handled in update method, not here
				return; // Exit without creating projectiles
			} else if (self.element === 'water' && self.tier === 4) {
				// Create mini-wave that travels 800 units with larger size (same as tier 5)
				var miniWave = game.addChild(LK.getAsset('ola', {
					anchorX: 0.0,
					anchorY: 0.5,
					x: self.x - 400,
					y: self.y,
					width: 800,
					height: 500
				}));
				miniWave.tint = 0x00ffff;
				miniWave.alpha = 0.8;
				// Store wave damage for collision detection
				var finalWaveDamage = self.damage + (self.auraDamageBonus || 0);
				miniWave.finalWaveDamage = finalWaveDamage;
				// Track which enemies and allies have been hit by this wave
				miniWave.hitEnemies = [];
				miniWave.healedAllies = [];
				// Add wave update method for collision detection
				miniWave.update = function () {
					// Check collision with enemies - only once per enemy per wave
					for (var e = 0; e < enemies.length; e++) {
						var enemy = enemies[e];
						// Check if enemy hasn't been hit by this specific wave yet
						if (miniWave.hitEnemies.indexOf(enemy) === -1) {
							// Check collision between wave and enemy - use thin collider positioned at center of image
							var waveCenterX = miniWave.x + miniWave.width * 0.5; // Center of wave image
							var waveCenterY = miniWave.y; // Center Y position
							var waveDistance = Math.sqrt(Math.pow(waveCenterX - enemy.x, 2) + Math.pow(waveCenterY - enemy.y, 2));
							if (waveDistance < 50) {
								// Thin collision radius of 50 units for precise detection
								// Enemy is hit by wave - mark immediately to prevent multiple hits
								miniWave.hitEnemies.push(enemy);
								// Always deal damage when hit by mini-wave - use base damage only (6)
								enemy.takeDamage(6); // Fixed damage of 6 for mini-waves 
								// Set miniola_colision to true and update enemy stats
								enemy.miniola_colision = true;
								enemy.updateStatsDisplay();
								// Set immunity timer for 1 second using setTimeout
								LK.setTimeout(function () {
									enemy.miniola_colision = false;
									enemy.updateStatsDisplay();
								}, 1000);
								// Create splash effect at impact using salpicadura asset
								var splash = game.addChild(LK.getAsset('salpicadura', {
									anchorX: 0.5,
									anchorY: 0.5,
									x: enemy.x,
									y: enemy.y,
									width: 300,
									height: 300
								}));
								splash.alpha = 0.9;
								splash.tint = 0x00aaff;
								// Animate splash with scale and fade
								tween(splash, {
									scaleX: 2.5,
									scaleY: 2.5,
									alpha: 0,
									rotation: Math.PI * 0.5
								}, {
									duration: 600,
									easing: tween.easeOut,
									onFinish: function onFinish() {
										splash.destroy();
									}
								});
								// Create additional water droplet particles around the splash
								for (var dropletIndex = 0; dropletIndex < 8; dropletIndex++) {
									var angle = dropletIndex / 8 * Math.PI * 2;
									var distance = 80 + Math.random() * 60;
									var dropletEndX = enemy.x + Math.cos(angle) * distance;
									var dropletEndY = enemy.y + Math.sin(angle) * distance;
									var droplet = game.addChild(LK.getAsset('salpicadura', {
										anchorX: 0.5,
										anchorY: 0.5,
										x: enemy.x,
										y: enemy.y,
										width: 40 + Math.random() * 30,
										height: 40 + Math.random() * 30
									}));
									droplet.alpha = 0.7;
									droplet.tint = 0x1e90ff;
									// Animate droplets spreading outward and fading
									tween(droplet, {
										x: dropletEndX,
										y: dropletEndY,
										alpha: 0,
										scaleX: 0.3,
										scaleY: 0.3,
										rotation: Math.random() * Math.PI * 2
									}, {
										duration: 400 + Math.random() * 200,
										easing: tween.easeOut,
										onFinish: function onFinish() {
											droplet.destroy();
										}
									});
								}
							}
						}
					}
					// Check collision with allies for healing
					for (var w = 0; w < warriors.length; w++) {
						var ally = warriors[w];
						// Check if ally hasn't been healed by this wave yet
						if (miniWave.healedAllies.indexOf(ally) === -1) {
							// Check collision between wave and ally - use thin collider positioned at center of image
							var waveCenterX = miniWave.x + miniWave.width * 0.5; // Center of wave image
							var waveCenterY = miniWave.y; // Center Y position
							var allyDistance = Math.sqrt(Math.pow(waveCenterX - ally.x, 2) + Math.pow(waveCenterY - ally.y, 2));
							if (allyDistance < 50) {
								// Thin collision radius of 50 units for precise detection
								// Ally is healed by wave - mark immediately to prevent multiple heals
								miniWave.healedAllies.push(ally);
								// Heal ally if not at full health
								if (ally.health < ally.maxHealth) {
									// Heal for exactly 10 (6 base + 4 bonus)
									ally.health = Math.min(ally.health + 10, ally.maxHealth);
									// Healing effect
									tween(ally.children[0], {
										tint: 0x00ff88
									}, {
										duration: 200,
										onFinish: function onFinish() {
											tween(ally.children[0], {
												tint: 0xffffff
											}, {
												duration: 200
											});
										}
									});
									// Create healing particles
									for (var particleIndex = 0; particleIndex < 6; particleIndex++) {
										var particle = game.addChild(LK.getAsset('particulas_curacion', {
											anchorX: 0.5,
											anchorY: 0.5,
											x: ally.x + (Math.random() - 0.5) * 80,
											y: ally.y + (Math.random() - 0.5) * 80,
											width: 80 + Math.random() * 40,
											height: 80 + Math.random() * 40
										}));
										particle.alpha = 0.8;
										tween(particle, {
											y: ally.y - 100 - Math.random() * 50,
											alpha: 0,
											scaleX: 0.2,
											scaleY: 0.2
										}, {
											duration: 800,
											easing: tween.easeOut,
											onFinish: function onFinish() {
												particle.destroy();
											}
										});
									}
								}
							}
						}
					}
				};
				// Animate wave across 800 units distance
				tween(miniWave, {
					x: self.x + 800,
					scaleX: 1.5
				}, {
					duration: 1500,
					easing: tween.linear,
					onFinish: function onFinish() {
						miniWave.destroy();
					}
				});
				self.projectiles.push(miniWave);
				// Play water projectile sound
				playRandomProjectileSound(self.element);
				return; // Exit after creating mini-wave
			} else {
				// Regular projectiles for other ranged units
				var projectileSize = 120; // Larger projectiles for better visibility (doubled from 60)
				var projectileAsset = 'projectile'; // Default projectile
				if (self.element === 'light' && self.tier === 3) {
					projectileAsset = 'proyectil_electricidad'; // Light tier 3 shoots electricity projectile
				} else if (self.element === 'light') {
					projectileAsset = 'proyectil_electricidad';
				} else if (self.element === 'wind' && self.tier === 3) {
					projectileAsset = 'esporas'; // Use spore image for wind tier 3
				} else if (self.element === 'wind' && self.tier === 4) {
					projectileAsset = 'lanza'; // Use lanza image for wind tier 4
				}
				var projectile = game.addChild(LK.getAsset(projectileAsset, {
					anchorX: 0.5,
					anchorY: 0.5,
					x: self.x,
					y: self.y - 20,
					// Start slightly above warrior
					width: projectileSize,
					height: projectileSize
				}));
				// Calculate direction to target
				var dx = target.x - self.x;
				var dy = target.y - self.y;
				var distance = Math.sqrt(dx * dx + dy * dy);
				var speed = 10; // Increased speed for better gameplay
				projectile.speedX = dx / distance * speed;
				projectile.speedY = dy / distance * speed;
				// Set initial rotation for lanza projectiles to match aim direction
				if (self.element === 'wind' && self.tier === 4 && projectileAsset === 'lanza') {
					projectile.rotation = Math.atan2(dy, dx);
					// Make lanza thinner and double the size
					projectile.width = projectileSize * 2; // Double the width
					projectile.height = projectileSize * 0.6; // Double the height relative to thinned version (30% * 2)
				}
				// Set projectile appearance based on element
				if (self.element === 'light') {
					projectile.alpha = 0.9; // Slightly transparent for glow effect
					// Add pulsing effect for lightning
					tween(projectile, {
						scaleX: 1.3,
						scaleY: 1.3
					}, {
						duration: 300,
						yoyo: true,
						repeat: -1
					});
				} else if (self.element === 'wind') {
					projectile.alpha = 0.8;
					// Add spinning effect for wind (except tier 4 lanza)
					if (self.tier !== 4) {
						tween(projectile, {
							rotation: Math.PI * 2
						}, {
							duration: 500,
							repeat: -1
						});
					}
					// Add tier-specific projectile properties
					if (self.tier === 2) {
						projectile.goldenStatueChance = self.goldenStatueChance;
					} else if (self.tier === 4) {
						projectile.emeraldSlaveChance = self.emeraldSlaveChance;
						projectile.sleepDuration = self.sleepDuration;
					}
				} else if (self.element === 'water') {
					projectile.tint = 0x1e90ff; // Sea blue for water (DodgerBlue)
					projectile.alpha = 0.85;
					// Add wobbling effect for water
					tween(projectile, {
						scaleX: 1.2,
						scaleY: 0.8
					}, {
						duration: 200,
						yoyo: true,
						repeat: -1
					});
				}
				self.projectiles.push(projectile);
				// Auto-destroy projectile after 5 seconds to prevent map clutter
				tween(projectile, {
					alpha: projectile.alpha // Dummy property to track time
				}, {
					duration: 5000,
					// 5 seconds
					onFinish: function onFinish() {
						// Find and remove projectile from array
						var index = self.projectiles.indexOf(projectile);
						if (index > -1) {
							self.projectiles.splice(index, 1);
						}
						// Destroy the projectile
						projectile.destroy();
					}
				});
				// Play element-specific projectile sound
				playRandomProjectileSound(self.element);
				return; // Exit after creating projectile to prevent melee sound
			}
		} else {
			// Melee combat - deal damage directly to target
			var finalDamage = self.damage + (self.auraDamageBonus || 0);
			target.takeDamage(finalDamage);
			// Fire warriors with burn ability (tier 3+)
			if (self.element === 'fire' && self.canBurn && target.takeBurnDamage) {
				target.takeBurnDamage(0, self.burnDuration, self.burnDamage); // No initial damage since we already dealt damage above
			}
			// Fire tier 4 warriors have area damage with fire explosion visual effect
			if (self.element === 'fire' && self.canAreaDamage) {
				// Create fire explosion visual effect at target position
				var explosion = game.addChild(LK.getAsset('explosion_fuego', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: target.x,
					y: target.y,
					width: 120,
					height: 120
				}));
				explosion.alpha = 0.9;
				explosion.tint = 0xff4400; // Fire color
				// Animate explosion - scale up and fade out
				tween(explosion, {
					scaleX: 5.0,
					scaleY: 5.0,
					alpha: 0
				}, {
					duration: 800,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						explosion.destroy();
					}
				});
				// Create fire particles expanding from explosion center
				for (var particleIndex = 0; particleIndex < 16; particleIndex++) {
					var angle = particleIndex / 16 * Math.PI * 2; // Distribute evenly in circle
					var distance = 200 + Math.random() * 150;
					var particleEndX = target.x + Math.cos(angle) * distance;
					var particleEndY = target.y + Math.sin(angle) * distance;
					var fireParticle = game.addChild(LK.getAsset('explosion_fuego', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: target.x,
						y: target.y,
						width: 30 + Math.random() * 30,
						height: 30 + Math.random() * 30
					}));
					fireParticle.alpha = 0.7;
					fireParticle.tint = 0xff6600; // Orange fire color
					// Animate particles expanding outward and fading
					tween(fireParticle, {
						x: particleEndX,
						y: particleEndY,
						alpha: 0,
						scaleX: 0.2,
						scaleY: 0.2
					}, {
						duration: 600 + Math.random() * 400,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							fireParticle.destroy();
						}
					});
				}
				for (var ae = 0; ae < enemies.length; ae++) {
					var areaEnemy = enemies[ae];
					var areaDistance = Math.sqrt(Math.pow(target.x - areaEnemy.x, 2) + Math.pow(target.y - areaEnemy.y, 2));
					if (areaDistance < 400 && areaEnemy !== target) {
						if (areaEnemy.takeBurnDamage) {
							areaEnemy.takeBurnDamage(self.damage * 0.5, self.burnDuration, self.burnDamage);
						}
					}
				}
			}
			// Play sword attack sound for melee attacks
			sonidoEspadas();
		}
	};
	self.attackTower = function () {
		self.attackCooldown = 60;
		enemyTowerHealth -= self.damage;
		// Play random tower damage sound
		var towerSounds = ['sonido_torre_1', 'sonido_torre_2', 'sonido_torre_3', 'sonido_torre_4'];
		var randomIndex = Math.floor(Math.random() * towerSounds.length);
		var sound = LK.getSound(towerSounds[randomIndex]);
		sound.volume = soundValue;
		sound.play();
		// Create escombros particles when enemy tower takes damage - quantity based on damage
		var particleCount = self.damage * 12; // Multiply particle count by damage
		for (var escombrosIndex = 0; escombrosIndex < particleCount; escombrosIndex++) {
			// 360-degree explosion pattern
			var angle = escombrosIndex / particleCount * Math.PI * 2; // Distribute evenly in 360 degrees
			var force = (200 + Math.random() * 300) * 4; // Quadruple the force
			var velocityX = Math.cos(angle) * force;
			var velocityY = Math.sin(angle) * force;
			var escombrosParticle = game.addChild(LK.getAsset('escombros_torre_enemiga', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: enemyTower.x,
				y: enemyTower.y - 800,
				width: (60 + Math.random() * 40) * 5,
				height: (60 + Math.random() * 40) * 5,
				rotation: Math.random() * Math.PI * 2
			}));
			escombrosParticle.alpha = 0.9;
			escombrosParticle.tint = 0x696969; // Dark gray color for enemy debris
			// Add gravity and physics properties
			escombrosParticle.velocityX = velocityX * 0.02; // Scale down for smooth movement
			escombrosParticle.velocityY = velocityY * 0.02;
			escombrosParticle.gravity = 0.8; // Gravity effect
			// Animate escombros particles with physics
			tween(escombrosParticle, {
				y: enemyTower.y + 200 + escombrosParticle.velocityY * 100,
				x: enemyTower.x + escombrosParticle.velocityX * 100,
				alpha: 0,
				rotation: escombrosParticle.rotation + Math.PI * 4,
				scaleX: 0.1,
				scaleY: 0.1
			}, {
				duration: 2000 + Math.random() * 1000,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					escombrosParticle.destroy();
				}
			});
		}
		if (enemyTowerHealth <= 0) {
			subir_nivel();
		}
		updateTowerHealthBars();
	};
	self.takeDamage = function (damage) {
		// Earth warrior tier 4+ damage immunity
		if (self.element === 'earth' && self.tier >= 4 && self.damageImmunity && damage <= self.damageImmunity) {
			// Immune to damage - show visual feedback
			tween(self.children[0], {
				tint: 0x8b4513
			}, {
				duration: 200,
				onFinish: function onFinish() {
					tween(self.children[0], {
						tint: 0xffffff
					}, {
						duration: 200
					});
				}
			});
			return; // No damage taken
		}
		self.health -= damage;
		// Update stats display to show current health
		self.updateStatsDisplay();
		if (self.health <= 0) {
			// Remove tracking clouds when light warrior tier 3 is destroyed
			if (self.element === 'light' && self.tier === 3) {
				// Find and destroy all tracking clouds created by this warrior
				for (var childIndex = game.children.length - 1; childIndex >= 0; childIndex--) {
					var child = game.children[childIndex];
					if (child.isTrackingCloud || child.update && child.targetEnemy) {
						child.destroy();
					}
				}
			}
			// Mark as being destroyed to prevent multiple destruction attempts
			self.isBeingDestroyed = true;
			// Death animation - fade out and scale down from current tier scale
			var deathScale = self.tierScale * 0.1;
			tween(warriorGraphics, {
				alpha: 0,
				scaleX: deathScale,
				scaleY: deathScale,
				rotation: -Math.PI * 2
			}, {
				duration: 600,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
			// Only remove from warriors array if not already removed by collision detection
			if (!self.isBeingDestroyed || self.isBeingDestroyed) {
				var index = warriors.indexOf(self);
				if (index > -1) {
					warriors.splice(index, 1);
				}
			}
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
// Reset the game by creating a new game instance
var game = new LK.Game({
	backgroundColor: 0x2c3e50,
	width: 3840,
	height: 1080,
	description: "Combine elemental notes to summon warriors with unique abilities and destroy the enemy tower in this strategic summoning game. UpitMusicContest"
});
/**** 
* Game Code
****/ 
// Language toggle variable
// Reset all game variables to initial state
// English level completion sounds (levels 0-25)
// Spanish level completion sounds (levels 0-25)
// Variables globales para el control de bucle de sonidos de comics
var idioma = false;
var currentComicSound = null;
var currentSoundTimer = null;
warriors = [];
enemies = [];
meteoritos = [];
esporas = [];
globalFireModeActive = false;
fireModeTimer = 0;
playerTowerHealth = 30;
enemyTowerHealth = 10;
enemySpawnTimer = 0;
isDragging = false;
lastMouseX = 0;
cameraX = 0;
currentMana = 5;
maxMana = 5;
manaRegenTimer = 0;
miniola_colision = false;
currentCombination = [];
combinationTimer = 0;
combinationCooldown = 0;
temporaryNoteCounter = 0;
tiempoDeApocalipsis = 0;
elementList = [];
noteTimingIntervals = [];
lastNoteTime = 0;
isFirstNote = true;
initialTouchX = 0;
initialTouchY = 0;
currentTouchX = 0;
currentTouchY = 0;
musicBeatThreshold = 0;
lastBeatTime = 0;
clouds = [];
cloudSpawnTimer = 0;
settingsPanelVisible = false;
musicValue = 0.8;
soundValue = 0.8;
sensitivityValue = 0.5;
revelacionTimer = 0;
i = 0;
function _typeof3(o) {
	"@babel/helpers - typeof";
	return _typeof3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
		return typeof o;
	} : function (o) {
		return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
	}, _typeof3(o);
}
function _typeof2(o) {
	"@babel/helpers - typeof";
	return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
		return typeof o;
	} : function (o) {
		return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
	}, _typeof2(o);
}
function _typeof(o) {
	"@babel/helpers - typeof";
	return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
		return typeof o;
	} : function (o) {
		return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
	}, _typeof(o);
}
// Array de datos de enemigos para 30 niveles
// Formato: [nivel, vida, daño, velocidad_spawn_en_segundos]
var enemigos = [[1, 5, 1, 8], [2, 5, 2, 8], [3, 10, 2, 8], [4, 2, 10, 8], [5, 6, 1, 3], [6, 10, 1, 3], [7, 20, 1, 8], [8, 10, 3, 8], [9, 4, 5, 8], [10, 10, 10, 8], [11, 10, 10, 3], [12, 100, 2, 8], [13, 120, 4, 8], [14, 120, 8, 8], [15, 40, 4, 2], [16, 100, 8, 3], [17, 250, 4, 8],
// Nota: nivel 17 agregado ya que falta en los datos
[18, 250, 4, 8], [19, 300, 2, 4], [20, 500, 5, 4], [21, 250, 2, 1], [22, 1000, 5, 16], [23, 700, 5, 4], [24, 700, 11, 1], [25, 2000, 25, 8], [26, 1000, 9, 0.5], [27, 3000, 21, 8], [28, 2500, 21, 4], [29, 5000, 20, 1], [30, 100000, 20, 2], [31, 4500, 30, 6], [32, 6000, 35, 3]];
var nivel = -1;
var nivel_llegado = 0;
var pausa = true;
// Level-based unlocking system variables
var unlockedElements = []; // Array to track which elements are unlocked
var isApocalypticNotesVisible = false; // Track if apocalyptic notes should be visible
var unlockedCombinations = []; // Track which combination types are unlocked
var warriors = [];
var enemies = [];
var meteoritos = [];
var esporas = [];
// Individual dormido property will be added to each enemy instance
var globalFireModeActive = false;
var fireModeTimer = 0;
var playerTowerHealth = 10;
var enemyTowerHealth = 10;
var enemySpawnTimer = 0;
var isDragging = false;
var lastMouseX = 0;
var cameraX = 0;
var maxCameraX = 1792; // 3840 - 2048 = max scroll distance
var currentMana = 5;
var maxMana = 5;
var manaRegenTimer = 0;
var miniola_colision = false;
// Combination system variables
var currentCombination = [];
var combinationTimer = 0;
var combinationCooldown = 0;
var maxCombinationLength = 10;
var combinationWindowTime = 60; // 1 second at 60fps
var combinationResetTime = 60; // 1 second at 60fps
var temporaryNoteCounter = 0; // Helper counter for tracking notes (1-5)
// Apocalipsis system variables
var tiempoDeApocalipsis = 0; // Timer for tracking idle time without note presses (10 seconds = 600 frames)
var apocalipsisThreshold = 600; // 10 seconds at 60fps
// Element list system for meteorite invocation
var elementList = [];
var maxElementList = 5;
// Timing interval tracking variables
var noteTimingIntervals = []; // Store time intervals between note presses
var lastNoteTime = 0; // Timestamp of last note press
var isFirstNote = true; // Track if this is the first note in a sequence
// Touch position tracking variables
var initialTouchX = 0;
var initialTouchY = 0;
var currentTouchX = 0;
var currentTouchY = 0;
// Music beat detection variables
var musicBeatThreshold = 0; // Default sensitivity threshold set to 0 - will be controlled by sensitivity button
var lastBeatTime = 0;
var beatCooldown = 15; // Reduced cooldown for more frequent detections (0.25 seconds at 60fps)
// UI Elements
var scoreText = new Text2('Score: 0', {
	size: 40,
	fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 120;
scoreText.y = 50;
LK.gui.topLeft.addChild(scoreText);
// Create level display text above mana
var levelText = new Text2('Nivel: 0', {
	size: 40,
	fill: 0xFFFF00
});
levelText.anchor.set(0, 0);
levelText.x = 1100;
levelText.y = 50;
LK.gui.topLeft.addChild(levelText);
// Create mana display
var manaText = new Text2('Mana: 5/5', {
	size: 40,
	fill: 0x00FFFF
});
manaText.anchor.set(0, 0);
manaText.x = 1100;
manaText.y = 100;
LK.gui.topLeft.addChild(manaText);
// Create mana orbs visual display
var manaOrbs = [];
for (var i = 0; i < maxMana; i++) {
	var orb = LK.getAsset('manaOrbShape', {
		width: 40,
		height: 40
	});
	orb.anchor.set(0.5, 0.5);
	orb.x = 1100 + i * 50;
	orb.y = 160;
	LK.gui.topLeft.addChild(orb);
	manaOrbs.push(orb);
}
// Settings panel state
var settingsPanelVisible = false;
var settingsBars = [];
// Settings values (0.0 to 1.0 range)
var musicValue = 0.8;
var soundValue = 0.8;
var sensitivityValue = 0.5;
// Create settings button below mana bar
var settingsButton = LK.getAsset('settingsIcon', {
	width: 80,
	height: 80
});
settingsButton.anchor.set(0.5, 0.5);
settingsButton.x = 1300; // Move slightly to the right
settingsButton.y = 250; // Move down a bit more
settingsButton.alpha = 0.8;
LK.gui.topLeft.addChild(settingsButton);
//Crear boton de menu
var menubutton = LK.getAsset('MenuIcon', {
	width: 80,
	height: 80
});
menubutton.anchor.set(0.5, 0.5);
menubutton.x = 1100; // Move slightly to the right
menubutton.y = 250; // Move down a bit more
menubutton.alpha = 0.8;
LK.gui.topLeft.addChild(menubutton);
// Add menu button click handler
menubutton.down = function (x, y, obj) {
	nivel = -1;
	// Call the activar_menu function
	activar_menu();
	musiclevel();
	// Visual feedback with bounce effect
	tween(menubutton, {
		scaleX: 0.85,
		scaleY: 0.85,
		alpha: 0.6,
		rotation: Math.PI * 0.1
	}, {
		duration: 150,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(menubutton, {
				scaleX: 1.05,
				scaleY: 1.05,
				alpha: 0.9,
				rotation: 0
			}, {
				duration: 150,
				easing: tween.bounceOut,
				onFinish: function onFinish() {
					tween(menubutton, {
						scaleX: 1.0,
						scaleY: 1.0,
						alpha: 0.8
					}, {
						duration: 100
					});
				}
			});
		}
	});
};
// Create pause button next to settings button
var pauseButton = LK.getAsset('PausarIcon', {
	width: 80,
	height: 80
});
pauseButton.anchor.set(0.5, 0.5);
pauseButton.x = 1200; // Position to the right of settings button
pauseButton.y = 250; // Same Y position as settings button
pauseButton.alpha = 0.8;
LK.gui.topLeft.addChild(pauseButton);
// Create pause button text
var pauseButtonText = new Text2('||', {
	size: 50,
	fill: 0xffffff
});
pauseButtonText.anchor.set(0.5, 0.5);
pauseButton.addChild(pauseButtonText);
// Ensure pauseButtonText is rendered on top of pauseButton
LK.gui.topLeft.removeChild(pauseButton);
LK.gui.topLeft.addChild(pauseButton);
// Create music volume text input
var musicVolumeInput = new Text2('Volumen Música: 80', {
	size: 30,
	fill: 0xFFFFFF
});
musicVolumeInput.anchor.set(0.5, 0.5);
musicVolumeInput.x = 1220;
musicVolumeInput.y = 430;
musicVolumeInput.alpha = 0;
LK.gui.topLeft.addChild(musicVolumeInput);
// Store all settings elements
settingsBars = [musicVolumeInput];
// Function to update music volume
function updateMusicVolume(value) {
	// Parse and validate the input value
	var volumeNumber = parseInt(value);
	if (isNaN(volumeNumber)) {
		volumeNumber = 80;
	}
	volumeNumber = Math.max(0, Math.min(100, volumeNumber));
	musicValue = volumeNumber / 100;
	musicVolumeInput.setText('Volumen Música: ' + volumeNumber);
	// Apply music volume changes immediately
	LK.stopMusic();
	musiclevel();
}
// Music volume input interaction
musicVolumeInput.down = function (x, y, obj) {
	// Simple interaction for now - could be enhanced with actual text input
	var currentVolume = Math.round(musicValue * 100);
	var newVolume = (currentVolume + 10) % 110; // Cycle through 0-100 by 10s
	updateMusicVolume(newVolume);
};
settingsButton.down = function (x, y, obj) {
	// Play settings click sound with centralized control like music - stop and restart with current volume
	LK.getSound('settings_click').stop(); // Stop any currently playing instance
	var settingsSound = LK.getSound('settings_click');
	settingsSound.volume = soundValue * 0.7; // Apply current soundValue with 70% modifier
	settingsSound.play();
	// Visual feedback with bounce effect
	tween(settingsButton, {
		scaleX: 0.85,
		scaleY: 0.85,
		alpha: 0.6,
		rotation: Math.PI * 0.1
	}, {
		duration: 150,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(settingsButton, {
				scaleX: 1.05,
				scaleY: 1.05,
				alpha: 0.9,
				rotation: 0
			}, {
				duration: 150,
				easing: tween.bounceOut,
				onFinish: function onFinish() {
					tween(settingsButton, {
						scaleX: 1.0,
						scaleY: 1.0,
						alpha: 0.8
					}, {
						duration: 100
					});
				}
			});
		}
	});
	// Toggle settings panel with staggered animations
	if (settingsPanelVisible) {
		// Hide settings panel with staggered fade out
		settingsPanelVisible = false;
		for (var i = 0; i < settingsBars.length; i++) {
			var delay = i * 30; // Stagger each element by 30ms
			tween(settingsBars[i], {
				alpha: 0,
				y: settingsBars[i].y - 20,
				scaleX: 0.8,
				scaleY: 0.8
			}, {
				duration: 300,
				delay: delay,
				easing: tween.easeInOut
			});
		}
	} else {
		// Show settings panel with bouncy entrance
		settingsPanelVisible = true;
		for (var i = 0; i < settingsBars.length; i++) {
			var delay = i * 40; // Stagger each element by 40ms
			var targetY = settingsBars[i].y;
			settingsBars[i].y = targetY - 30;
			settingsBars[i].scaleX = 0.6;
			settingsBars[i].scaleY = 0.6;
			tween(settingsBars[i], {
				alpha: 1,
				y: targetY,
				scaleX: 1.0,
				scaleY: 1.0
			}, {
				duration: 400,
				delay: delay,
				easing: tween.elasticOut
			});
		}
	}
};
pauseButton.down = function (x, y, obj) {
	// Play settings click sound
	LK.getSound('settings_click').stop(); // Stop any currently playing instance
	var pauseSound = LK.getSound('settings_click');
	pauseSound.volume = soundValue * 0.7; // Apply current soundValue with 70% modifier
	pauseSound.play();
	// Toggle pause state
	pausa = !pausa;
	// Update button text and appearance based on pause state
	if (pausa) {
		pauseButtonText.setText('||'); // Pause symbol
		pauseButton.tint = 0xff4444; // Red tint when paused
		// Switch to menu music when paused
	} else {
		pauseButtonText.setText('▶'); // Play symbol
		pauseButton.tint = 0xffffff; // Green tint when playing
		// Switch back to regular music when unpaused
	}
	// Visual feedback with bounce effect
	tween(pauseButton, {
		scaleX: 0.85,
		scaleY: 0.85,
		alpha: 0.6,
		rotation: Math.PI * 0.1
	}, {
		duration: 150,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(pauseButton, {
				scaleX: 1.05,
				scaleY: 1.05,
				alpha: 0.9,
				rotation: 0
			}, {
				duration: 150,
				easing: tween.bounceOut,
				onFinish: function onFinish() {
					tween(pauseButton, {
						scaleX: 1.0,
						scaleY: 1.0,
						alpha: 0.8
					}, {
						duration: 100
					});
				}
			});
		}
	});
};
// Create black background for comic system in GUI layer
var fondoNegro = LK.getAsset('fondo_negro', {
	anchorX: 0.0,
	anchorY: 0.0,
	x: 0,
	y: 0,
	width: 2048,
	height: 2732
});
fondoNegro.alpha = 0; // Initially invisible
LK.gui.addChild(fondoNegro);
// Create f_m image to cover full screen on GUI layer
var fmImage = LK.getAsset('f_m', {
	anchorX: 0.0,
	anchorY: 0.0,
	x: 0,
	y: 0,
	width: 1548,
	height: 1932
});
fmImage.alpha = 1.0; // Fully visible
LK.gui.addChild(fmImage);
// Create language toggle button above f_m image
var languageButton = LK.getAsset('IdiomaIcon', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 1200,
	y: 1750,
	width: 300,
	height: 100
});
languageButton.alpha = 0.9;
// Add language button after f_m but before fondo_negro
var fmImageIndex = LK.gui.children.indexOf(fmImage);
if (fmImageIndex >= 0) {
	LK.gui.addChildAt(languageButton, fmImageIndex + 1);
} else {
	LK.gui.addChild(languageButton);
}
// Create language button text
var languageButtonText = new Text2('Change to English', {
	size: 32,
	fill: 0xffffff,
	font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
});
languageButtonText.anchor.set(0.5, 0.5);
languageButtonText.x = 1200;
languageButtonText.y = 1750;
languageButtonText.alpha = 1;
// Add language button text after language button but before fondo_negro
var languageButtonIndex = LK.gui.children.indexOf(languageButton);
if (languageButtonIndex >= 0) {
	LK.gui.addChildAt(languageButtonText, languageButtonIndex + 1);
} else {
	LK.gui.addChild(languageButtonText);
}
// Language button interaction
languageButton.down = function (x, y, obj) {
	// Toggle language
	idioma = !idioma;
	// Update button text based on current language
	if (idioma) {
		// Currently English, show option to change to Spanish
		languageButtonText.setText('Cambiar a español');
	} else {
		// Currently Spanish, show option to change to English
		languageButtonText.setText('Change to English');
	}
	// Visual feedback with bounce effect
	tween(languageButton, {
		scaleX: 0.85,
		scaleY: 0.85,
		alpha: 0.6
	}, {
		duration: 150,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(languageButton, {
				scaleX: 1.05,
				scaleY: 1.05,
				alpha: 1.0
			}, {
				duration: 150,
				easing: tween.bounceOut,
				onFinish: function onFinish() {
					tween(languageButton, {
						scaleX: 1.0,
						scaleY: 1.0,
						alpha: 0.9
					}, {
						duration: 100
					});
				}
			});
		}
	});
	doblaje();
	musiclevel();
};
// Create "jugar" button on top of f_m image
var jugarButton = LK.getAsset('jugar', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 700,
	y: 600,
	width: 500,
	height: 300
});
jugarButton.alpha = 0.9;
LK.gui.addChild(jugarButton);
// Add button interaction
jugarButton.down = function (x, y, obj) {
	// Visual feedback with bounce effect
	tween(jugarButton, {
		scaleX: 0.85,
		scaleY: 0.85,
		alpha: 0.6,
		rotation: Math.PI * 0.05
	}, {
		duration: 150,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(jugarButton, {
				scaleX: 1.05,
				scaleY: 1.05,
				alpha: 1,
				rotation: 0
			}, {
				duration: 150,
				easing: tween.bounceOut,
				onFinish: function onFinish() {
					tween(jugarButton, {
						scaleX: 1.0,
						scaleY: 1.0,
						alpha: 0.9
					}, {
						duration: 100,
						onFinish: function onFinish() {
							// Create 30 level selection buttons above the l_m image
							var levelButtons = [];
							for (var i = 0; i < 30; i++) {
								var levelButton = LK.getAsset('boton_nivel', {
									anchorX: 0.5,
									anchorY: 0.5,
									x: 300 + i % 8 * 120,
									// 8 buttons per row, spaced 120 pixels apart
									y: 900 + Math.floor(i / 8) * 120,
									// 4 rows, spaced 120 pixels apart
									width: 100,
									height: 100
								});
								// Set button properties
								levelButton.nivel = i; // Level 0-29
								levelButton.boton_habilitado = i <= nivel_llegado; // Enable if level reached
								// Use correct asset based on enabled state
								if (!levelButton.boton_habilitado) {
									levelButton.destroy();
									levelButton = LK.getAsset('boton_nivel_desactivado', {
										anchorX: 0.5,
										anchorY: 0.5,
										x: 300 + i % 8 * 120,
										y: 900 + Math.floor(i / 8) * 120,
										width: 100,
										height: 100,
										alpha: 0.5
									});
									levelButton.nivel = i;
									levelButton.boton_habilitado = false;
								}
								// Add level number text with persistent visibility
								var buttonText = new Text2(i.toString(), {
									size: 70,
									fill: 0xffffff
								});
								buttonText.anchor.set(0.5, 0.5);
								buttonText.alpha = 1.0; // Ensure text is fully visible
								buttonText.x = 300 + i % 8 * 120; // Position same as button
								buttonText.y = 900 + Math.floor(i / 8) * 120; // Position same as button
								// Store reference to prevent garbage collection
								levelButton.levelText = buttonText;
								// Add click handler only for enabled buttons
								if (levelButton.boton_habilitado) {
									levelButton.down = function (x, y, obj) {
										destroy_mapa();
										// Set nivel variable to the selected button's level
										nivel = this.nivel;
										console.log("Level " + this.nivel + " selected, nivel set to: " + nivel);
										// Update the global level display text (not the button's own text)
										levelText.setText('Nivel: ' + nivel);
										// Update unlocking system based on selected level
										updateLevelUnlocks();
										// Reset towers with their function when level is selected
										// Calculate new tower health: 10 + (10 * nivel)
										var newTowerHealth = 10 * nivel;
										playerTowerHealth = newTowerHealth;
										enemyTowerHealth = newTowerHealth;
										//Ejecutar music
										musiclevel();
										// Update tower health bars and reset scale to full size
										updateTowerHealthBars();
										// Reset tower scales to full size (1.0)
										tween.stop(playerTower, {
											scaleX: true,
											scaleY: true
										});
										tween.stop(enemyTower, {
											scaleX: true,
											scaleY: true
										});
										tween(playerTower, {
											scaleX: 1.0,
											scaleY: 1.0
										}, {
											duration: 500,
											easing: tween.easeInOut
										});
										tween(enemyTower, {
											scaleX: 1.0,
											scaleY: 1.0
										}, {
											duration: 500,
											easing: tween.easeInOut
										});
										// Hide l_m image
										fmImage.visible = false;
										// Hide jugar button
										jugarButton.visible = false;
										// Hide all level buttons and their text
										for (var j = 0; j < levelButtons.length; j++) {
											if (levelButtons[j] && levelButtons[j].parent) {
												levelButtons[j].visible = false;
											}
											// Hide buttonText as well
											if (levelButtons[j] && levelButtons[j].levelText) {
												levelButtons[j].levelText.visible = false;
											}
										}
										// Set pausar to false
										pausa = false;
										// Change pause button to play state
										pauseButtonText.setText('▶'); // Play symbol
										pauseButton.tint = 0xffffff; // Green tint when playing
										// Audio al dar clic
										doblaje();
									};
								}
								// Add buttons to GUI layer to ensure they appear above l_m image
								LK.gui.addChild(levelButton);
								levelButtons.push(levelButton);
								// Add buttonText after levelButton to ensure it appears on top
								LK.gui.addChild(buttonText);
								// Force text to stay visible
								buttonText.visible = true;
							}
						}
					});
				}
			});
		}
	});
};
function doblaje() {
	var levelSound = null; // Initialize levelSound variable
	// Stop any currently playing level sounds by stopping all potential level sounds
	if (currentComicSound) {
		currentComicSound.stop();
	}
	// Stop all level sounds at function start
	var allLevelSounds = ['Level_1_en', 'Level_2_en', 'Level_3_en', 'Level_4_en', 'Level_5_en', 'Level_6_en', 'Level_7_en', 'Level_8_en', 'Level_9_en', 'Level_10_en', 'Level_11_en', 'Level_12_en', 'Level_13_en', 'Level_14_en', 'Level_15_en', 'Level_16_en', 'Level_17_en', 'Level_18_en', 'Level_19_en', 'Level_20_en', 'Level_21_en', 'Level_22_en', 'Level_23_en', 'Level_24_en', 'Level_25_en', 'Level_26_en', 'Level_1_es', 'Level_2_es', 'Level_3_es', 'Level_4_es', 'Level_5_es', 'Level_6_es', 'Level_7_es', 'Level_8_es', 'Level_9_es', 'Level_10_es', 'Level_11_es', 'Level_12_es', 'Level_13_es', 'Level_14_es', 'Level_15_es', 'Level_16_es', 'Level_17_es', 'Level_18_es', 'Level_19_es', 'Level_20_es', 'Level_21_es', 'Level_22_es', 'Level_23_es', 'Level_24_es', 'Level_25_es', 'Level_26_es'];
	for (var i = 0; i < allLevelSounds.length; i++) {
		try {
			var sound = LK.getSound(allLevelSounds[i]);
			if (sound && typeof sound.stop === 'function') {
				sound.stop();
			}
		} catch (e) {
			// Ignore errors for sounds that don't exist
		}
	}
	if (idioma) {
		if (nivel == 1) {
			levelSound = LK.getSound('Level_1_en');
		}
		if (nivel == 2) {
			levelSound = LK.getSound('Level_2_en');
		}
		if (nivel == 3) {
			levelSound = LK.getSound('Level_3_en');
		}
		if (nivel == 4) {
			levelSound = LK.getSound('Level_4_en');
		}
		if (nivel == 5) {
			levelSound = LK.getSound('Level_5_en');
		}
		if (nivel == 6) {
			levelSound = LK.getSound('Level_6_en');
		}
		if (nivel == 7) {
			levelSound = LK.getSound('Level_7_en');
		}
		if (nivel == 8) {
			levelSound = LK.getSound('Level_8_en');
		}
		if (nivel == 9) {
			levelSound = LK.getSound('Level_9_en');
		}
		if (nivel == 10) {
			levelSound = LK.getSound('Level_10_en');
		}
		if (nivel == 11) {
			levelSound = LK.getSound('Level_11_en');
		}
		if (nivel == 12) {
			levelSound = LK.getSound('Level_12_en');
		}
		if (nivel == 13) {
			levelSound = LK.getSound('Level_13_en');
		}
		if (nivel == 14) {
			levelSound = LK.getSound('Level_14_en');
		}
		if (nivel == 15) {
			levelSound = LK.getSound('Level_15_en');
		}
		if (nivel == 16) {
			levelSound = LK.getSound('Level_16_en');
		}
		if (nivel == 17) {
			levelSound = LK.getSound('Level_17_en');
		}
		if (nivel == 18) {
			levelSound = LK.getSound('Level_18_en');
		}
		if (nivel == 19) {
			levelSound = LK.getSound('Level_19_en');
		}
		if (nivel == 20) {
			levelSound = LK.getSound('Level_20_en');
		}
		if (nivel == 21) {
			levelSound = LK.getSound('Level_21_en');
		}
		if (nivel == 22) {
			levelSound = LK.getSound('Level_22_en');
		}
		if (nivel == 23) {
			levelSound = LK.getSound('Level_23_en');
		}
		if (nivel == 24) {
			levelSound = LK.getSound('Level_24_en');
		}
		if (nivel == 25) {
			levelSound = LK.getSound('Level_25_en');
		}
		if (nivel == 26) {
			levelSound = LK.getSound('Level_26_en');
		}
	} else {
		if (nivel == 1) {
			levelSound = LK.getSound('Level_1_es');
		}
		if (nivel == 2) {
			levelSound = LK.getSound('Level_2_es');
		}
		if (nivel == 3) {
			levelSound = LK.getSound('Level_3_es');
		}
		if (nivel == 4) {
			levelSound = LK.getSound('Level_4_es');
		}
		if (nivel == 5) {
			levelSound = LK.getSound('Level_5_es');
		}
		if (nivel == 6) {
			levelSound = LK.getSound('Level_6_es');
		}
		if (nivel == 7) {
			levelSound = LK.getSound('Level_7_es');
		}
		if (nivel == 8) {
			levelSound = LK.getSound('Level_8_es');
		}
		if (nivel == 9) {
			levelSound = LK.getSound('Level_9_es');
		}
		if (nivel == 10) {
			levelSound = LK.getSound('Level_10_es');
		}
		if (nivel == 11) {
			levelSound = LK.getSound('Level_11_es');
		}
		if (nivel == 12) {
			levelSound = LK.getSound('Level_12_es');
		}
		if (nivel == 13) {
			levelSound = LK.getSound('Level_13_es');
		}
		if (nivel == 14) {
			levelSound = LK.getSound('Level_14_es');
		}
		if (nivel == 15) {
			levelSound = LK.getSound('Level_15_es');
		}
		if (nivel == 16) {
			levelSound = LK.getSound('Level_16_es');
		}
		if (nivel == 17) {
			levelSound = LK.getSound('Level_17_es');
		}
		if (nivel == 18) {
			levelSound = LK.getSound('Level_18_es');
		}
		if (nivel == 19) {
			levelSound = LK.getSound('Level_19_es');
		}
		if (nivel == 20) {
			levelSound = LK.getSound('Level_20_es');
		}
		if (nivel == 21) {
			levelSound = LK.getSound('Level_21_es');
		}
		if (nivel == 22) {
			levelSound = LK.getSound('Level_22_es');
		}
		if (nivel == 23) {
			levelSound = LK.getSound('Level_23_es');
		}
		if (nivel == 24) {
			levelSound = LK.getSound('Level_24_es');
		}
		if (nivel == 25) {
			levelSound = LK.getSound('Level_25_es');
		}
		if (nivel == 26) {
			levelSound = LK.getSound('Level_26_es');
		}
	}
	// Only play sound if levelSound was successfully assigned and is valid
	if (levelSound && typeof levelSound.volume !== 'undefined') {
		levelSound.volume = soundValue;
		levelSound.play();
	}
}
// Create collision debug text in center of game
var collisionDebugText = new Text2(/*'Collision Debug'*/'', {
	size: 60,
	fill: 0xFFFF00
});
collisionDebugText.anchor.set(0.5, 0.5);
collisionDebugText.x = 1024; // Center of screen width (2048/2)
collisionDebugText.y = 1366; // Center of screen height (2732/2)
game.addChild(collisionDebugText);
// Create audio debug text to show real-time values
var audioDebugText = new Text2(/*'Audio: 0.00 | Threshold: 0.15 | Diff: 0.00'*/'', {
	size: 40,
	fill: 0x00FFFF
});
audioDebugText.anchor.set(0.5, 0.5);
audioDebugText.x = 1024; // Center of screen width
audioDebugText.y = 1200; // Above collision debug text
game.addChild(audioDebugText);
// Create touch position debug text
var touchDebugText = new Text2(/*'Touch Info: Initial(0,0) Current(0,0)'*/'', {
	size: 40,
	fill: 0xFF00FF
});
touchDebugText.anchor.set(0.5, 0.5);
touchDebugText.x = 1024; // Center of screen width
touchDebugText.y = 1500; // Below collision debug text
game.addChild(touchDebugText);
// Create combination message text
var combinationMessageText = new Text2('', {
	size: 60,
	fill: 0xFFFF00
});
combinationMessageText.anchor.set(0.5, 0.5);
combinationMessageText.x = 1024; // Center of screen width
combinationMessageText.y = 800; // Above other debug texts
combinationMessageText.alpha = 0;
game.addChild(combinationMessageText);
// Create temporary note counter info text
var tempCounterInfoText = new Text2(/*'Notas presionadas: 0'*/'', {
	size: 40,
	fill: 0x00FF00
});
tempCounterInfoText.anchor.set(0.5, 0.5);
tempCounterInfoText.x = 1024; // Center of screen width
tempCounterInfoText.y = 600; // Above combination message text
game.addChild(tempCounterInfoText);
// Create element list display text
var elementListText = new Text2(/*'Lista de Elementos: []'*/'', {
	size: 45,
	fill: 0xFFD700
});
elementListText.anchor.set(0.5, 0.5);
elementListText.x = 1024; // Center of screen width
elementListText.y = 400; // Above temp counter text
game.addChild(elementListText);
// Create comic counter display text
var numberComic = new Text2(/*'Comic: 0/11'*/'' / {
	size: 40,
	fill: 0xFF00FF
});
numberComic.anchor.set(0.5, 0.5);
numberComic.x = 1024; // Center of screen width
numberComic.y = 350; // Above element list text
game.addChild(numberComic);
// Create timing intervals info text
var timingIntervalsText = new Text2(/*'Intervalos: []'*/'', {
	size: 35,
	fill: 0xFFAA00
});
timingIntervalsText.anchor.set(0.5, 0.5);
timingIntervalsText.x = 1024; // Center of screen width
timingIntervalsText.y = 500; // Above temp counter text
game.addChild(timingIntervalsText);
// Create sky background - always behind everything
var skyBackground = game.addChildAt(LK.getAsset('cielo', {
	anchorX: 0.0,
	anchorY: 0.0,
	x: 0,
	y: 0,
	width: 3840,
	height: 2732
}), 0); // Add at index 0 to be behind everything
// Create tiled ground floor
var groundTiles = [];
var tileSize = 592.704; // Size of each ground tile (increased by 5% more)
var groundY = 2732; // Position at bottom of screen
var groundHeight = 728.6; // Extend height to fill bottom gap (tileSize + 136 pixels)
var numTiles = Math.ceil(3840 / tileSize) + 2; // Cover full width plus extra for seamless tiling
for (var i = 0; i < numTiles; i++) {
	var groundTile = game.addChild(LK.getAsset('ground', {
		anchorX: 0.0,
		anchorY: 1.0,
		x: i * tileSize,
		y: groundY,
		width: tileSize,
		height: groundHeight
	}));
	groundTiles.push(groundTile);
}
// Create red overlay for fire mode (initially hidden)
var fireOverlay = game.addChild(LK.getAsset('healthBar', {
	anchorX: 0.0,
	anchorY: 0.0,
	x: 0,
	y: 0,
	width: 3840,
	height: 2732
}));
fireOverlay.tint = 0xff0000; // Red color
fireOverlay.alpha = 0; // Initially hidden
// Create towers (horizontal layout)
var playerTower = game.addChild(LK.getAsset('playerTower', {
	anchorX: 0.5,
	anchorY: 1.0,
	x: 250,
	y: 2559,
	width: 1200,
	height: 1728
}));
var enemyTower = game.addChild(LK.getAsset('enemyTower', {
	anchorX: 0.5,
	anchorY: 1.0,
	x: 3590,
	y: 2559,
	width: 1200,
	height: 1728
}));
// Tower health bars
var playerTowerHealthBar = LK.getAsset('playerTowerHealthBar', {
	width: 1200,
	height: 160
});
playerTowerHealthBar.anchor.set(0.5, 0.5);
playerTowerHealthBar.x = playerTower.x;
playerTowerHealthBar.y = playerTower.y - 1840;
game.addChild(playerTowerHealthBar);
// Player tower health text centered on health bar
var playerTowerHealthText = new Text2('10/10', {
	size: 80,
	fill: 0xFFFFFF
});
playerTowerHealthText.anchor.set(0.5, 0.5);
playerTowerHealthText.x = playerTowerHealthBar.x;
playerTowerHealthText.y = playerTowerHealthBar.y;
game.addChild(playerTowerHealthText);
var enemyTowerHealthBar = LK.getAsset('enemyTowerHealthBar', {
	width: 1200,
	height: 160
});
enemyTowerHealthBar.anchor.set(0.5, 0.5);
enemyTowerHealthBar.x = enemyTower.x;
enemyTowerHealthBar.y = enemyTower.y - 1840;
game.addChild(enemyTowerHealthBar);
// Enemy tower health text centered on health bar
var enemyTowerHealthText = new Text2('10/10', {
	size: 80,
	fill: 0xFFFFFF
});
enemyTowerHealthText.anchor.set(0.5, 0.5);
enemyTowerHealthText.x = enemyTowerHealthBar.x;
enemyTowerHealthText.y = enemyTowerHealthBar.y;
game.addChild(enemyTowerHealthText);
// Create elemental notes (horizontal layout at top left) - show all elements
var elements = ['fire', 'water', 'earth', 'wind', 'light'];
var notes = [];
for (var i = 0; i < elements.length; i++) {
	var note = new ElementalNote(elements[i], 0, 0);
	LK.gui.topLeft.addChild(note);
	// Make buttons smaller
	note.scaleX = 0.4;
	note.scaleY = 0.4;
	// Position buttons horizontally in upper left with proper spacing (moved 50% right total)
	note.x = 234 + i * 140; // Start at x:234 (moved from 180), space buttons 140 pixels apart
	note.y = 120; // Fixed y position in upper area
	notes.push(note);
}
// Create five apocalyptic note images below the elemental notes
var casillas = [];
for (var i = 0; i < 5; i++) {
	var casilla = LK.getAsset('nota_apocalitica', {
		width: 60,
		height: 60,
		anchorX: 0.5,
		anchorY: 0.5
	});
	casilla.x = 409 + i * 70; // Moved left 25 units (from 434 to 409)
	casilla.y = 220; // Moved down 20 units (from 200 to 220)
	LK.gui.topLeft.addChild(casilla);
	casillas.push(casilla);
}
// Create camera control buttons
var leftButton = LK.getAsset('leftCameraButton', {
	width: 100,
	height: 100
});
leftButton.anchor.set(0.5, 0.5);
leftButton.alpha = 0.5; // 50% transparency
LK.gui.left.addChild(leftButton);
var leftButtonText = new Text2('<', {
	size: 60,
	fill: 0xffffff
});
leftButtonText.anchor.set(0.5, 0.5);
leftButton.addChild(leftButtonText);
var rightButton = LK.getAsset('rightCameraButton', {
	width: 100,
	height: 100
});
rightButton.anchor.set(0.5, 0.5);
rightButton.alpha = 0.5; // 50% transparency
LK.gui.right.addChild(rightButton);
var rightButtonText = new Text2('>', {
	size: 60,
	fill: 0xffffff
});
rightButtonText.anchor.set(0.5, 0.5);
rightButton.addChild(rightButtonText);
function notePressed(element) {
	// Check if element is unlocked
	if (unlockedElements.indexOf(element) === -1) {
		showCombinationMessage('Elemento ' + element.toUpperCase() + ' no desbloqueado');
		return;
	}
	// Reset apocalypse timer when any note is pressed
	tiempoDeApocalipsis = 0;
	// If this is the start of a new combination, clear previous timing data
	if (currentCombination.length === 0) {
		noteTimingIntervals = [];
		isFirstNote = true;
		lastNoteTime = 0;
	}
	// Record timing for interval tracking
	var currentTime = Date.now();
	if (isFirstNote) {
		// First note - record time and initialize with 0 interval
		lastNoteTime = currentTime;
		isFirstNote = false;
		noteTimingIntervals = [0]; // Initialize with 0 for first note
	} else {
		// Calculate interval since last note
		var interval = currentTime - lastNoteTime;
		noteTimingIntervals.push(interval);
		lastNoteTime = currentTime;
	}
	// Update timing intervals display
	var intervalsDisplay = noteTimingIntervals.length > 0 ? 'Intervalos: [' + noteTimingIntervals.map(function (interval) {
		return Math.round(interval) + 'ms';
	}).join(', ') + ']' : 'Intervalos: []';
	timingIntervalsText.setText(intervalsDisplay);
	// Element list is now managed separately by crea_combinacion_meteorito function
	// Do not add pressed notes to element list
	// Increment temporary counter
	temporaryNoteCounter++;
	// Add element to current combination
	addToCombination(element);
	// Check if current combination exactly matches the required meteorite sequence
	if (currentCombination.length === 5) {
		var hasMatchingCombination = true;
		for (var i = 0; i < 5; i++) {
			if (currentCombination[i] !== elementList[i]) {
				hasMatchingCombination = false;
				break;
			}
		}
		if (hasMatchingCombination) {
			// Current combination matches the required meteorite notes - invoke meteorite and set mana to zero
			currentMana = 0;
			updateManaDisplay();
			// Summon meteorite
			summonMeteorito();
			showCombinationMessage('¡METEORITO INVOCADO CON 5 ELEMENTOS!');
			// Reset combination
			resetCombination();
			temporaryNoteCounter = 0;
			enableNoteButtons();
			return;
		}
	}
	// Disable buttons if temporary counter equals or exceeds available mana
	if (temporaryNoteCounter >= currentMana) {
		disableAllNoteButtons();
	}
	// Only process immediately if we've reached max combination length
	if (currentCombination.length >= maxCombinationLength) {
		processCombination();
	}
}
function spawnEnemy() {
	if (pausa == false) {
		var enemy = new Enemy();
		enemy.x = enemyTower.x - 300;
		enemy.y = 2186; // Spawn on ground level
		enemy.onGround = true; // Start on ground
		game.addChild(enemy);
		enemies.push(enemy);
	}
}
function summonMeteorito() {
	var meteorito = new Meteorito();
	meteorito.x = 0; // Start at x=0
	meteorito.y = 0; // Start at y=0
	game.addChild(meteorito);
	meteoritos.push(meteorito);
	// Add mana equal to apocalyptic letters (5-i) when meteorite is invoked
	var manaToAdd = 5 - i;
	currentMana = Math.min(currentMana + manaToAdd, maxMana);
	updateManaDisplay();
}
function updateTowerHealthBars() {
	// Calculate max health: 10 + (10 * nivel)
	var maxHealth = 10 * nivel;
	var playerHealthPercent = Math.max(0, playerTowerHealth / maxHealth);
	var enemyHealthPercent = Math.max(0, enemyTowerHealth / maxHealth);
	playerTowerHealthBar.scaleX = playerHealthPercent;
	enemyTowerHealthBar.scaleX = enemyHealthPercent;
	// Update tower health text displays
	playerTowerHealthText.setText(playerTowerHealth + '/' + maxHealth);
	enemyTowerHealthText.setText(enemyTowerHealth + '/' + maxHealth);
	// Scale towers based on health - minimum scale of 0.3 (30%), maximum 1.0 (100%)
	var playerTowerScale = 0.3 + playerHealthPercent * 0.7; // 0.3 to 1.0 range
	var enemyTowerScale = 0.3 + enemyHealthPercent * 0.7; // 0.3 to 1.0 range
	// Apply scaling to towers
	tween.stop(playerTower, {
		scaleX: true,
		scaleY: true
	});
	tween.stop(enemyTower, {
		scaleX: true,
		scaleY: true
	});
	tween(playerTower, {
		scaleX: playerTowerScale,
		scaleY: playerTowerScale
	}, {
		duration: 500,
		easing: tween.easeInOut
	});
	tween(enemyTower, {
		scaleX: enemyTowerScale,
		scaleY: enemyTowerScale
	}, {
		duration: 500,
		easing: tween.easeInOut
	});
}
function subir_nivel() {
	// Increment level
	nivel++;
	// Update nivel_llegado if current nivel is greater
	if (nivel > nivel_llegado) {
		nivel_llegado = nivel;
	}
	// Update level display
	levelText.setText('Nivel: ' + nivel);
	// Update unlocking system for new level
	updateLevelUnlocks();
	// Calculate new tower health: 10 + (10 * nivel)
	var newTowerHealth = 10 * nivel;
	// Reset enemy tower health and scale
	enemyTowerHealth = newTowerHealth;
	// Reset player tower health and scale
	playerTowerHealth = newTowerHealth;
	// Add 5 mana when level is completed
	currentMana = Math.min(currentMana + 5, maxMana);
	updateManaDisplay();
	// Reset apocalyptic notes
	ocultar_notas_apocalitica();
	// Destroy all enemies instantly
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		enemy.destroy();
		enemies.splice(i, 1);
	}
	// Destroy all warriors instantly
	for (var i = warriors.length - 1; i >= 0; i--) {
		var warrior = warriors[i];
		warrior.isBeingDestroyed = true;
		warrior.destroy();
		warriors.splice(i, 1);
	}
	// Reset tower scales to full size (1.0)
	tween.stop(playerTower, {
		scaleX: true,
		scaleY: true
	});
	tween.stop(enemyTower, {
		scaleX: true,
		scaleY: true
	});
	tween(playerTower, {
		scaleX: 1.0,
		scaleY: 1.0
	}, {
		duration: 1000,
		easing: tween.easeInOut
	});
	tween(enemyTower, {
		scaleX: 1.0,
		scaleY: 1.0
	}, {
		duration: 1000,
		easing: tween.easeInOut
	});
	// Update health bars and health text to reflect reset values
	updateTowerHealthBars();
	// Show level advancement message
	showCombinationMessage('¡NIVEL ' + nivel + ' COMPLETADO! Torres restauradas');
	doblaje();
	levelSound = LK.getSound('ganar');
	levelSound.volume = soundValue;
	levelSound.play();
	musiclevel();
}
function updateManaDisplay() {
	// Update text
	manaText.setText('Mana: ' + currentMana + '/' + maxMana);
	// Update orb visuals
	for (var i = 0; i < manaOrbs.length; i++) {
		if (i < currentMana) {
			manaOrbs[i].alpha = 1.0; // Full opacity for available mana
			manaOrbs[i].tint = 0x00FFFF; // Cyan color
		} else {
			manaOrbs[i].alpha = 0.3; // Low opacity for depleted mana
			manaOrbs[i].tint = 0x666666; // Gray color
		}
	}
	// Update note button states based on mana and current combination length
	var requiredMana = currentCombination.length + 1; // Mana needed to add one more note
	for (var i = 0; i < notes.length; i++) {
		if (currentMana < requiredMana) {
			notes[i].alpha = 0.5; // Grayed out when not enough mana
			notes[i].isDisabled = true;
		} else {
			notes[i].alpha = 1.0; // Normal when mana available
			notes[i].isDisabled = false;
		}
	}
}
function playRandomCombatSound() {
	var combatSounds = ['combatir_1', 'combatir_2', 'combatir_3', 'combatir_4'];
	var randomIndex = Math.floor(Math.random() * combatSounds.length);
	var sound = LK.getSound(combatSounds[randomIndex]);
	sound.volume = soundValue;
	sound.play();
}
function sonidoEspadas() {
	var sound = LK.getSound('attack');
	sound.volume = soundValue;
	sound.play();
}
function playRandomProjectileSound(element) {
	var projectileSounds = [];
	if (element === 'water') {
		projectileSounds = ['sonido_proyectil_agua_1', 'sonido_proyectil_agua_2', 'sonido_proyectil_agua_3', 'sonido_proyectil_agua_4'];
	} else if (element === 'wind') {
		projectileSounds = ['sonido_proyectil_viento_1', 'sonido_proyectil_viento_2', 'sonido_proyectil_viento_3', 'sonido_proyectil_viento_4'];
	} else if (element === 'light') {
		projectileSounds = ['sonido_proyectil_energia_1', 'sonido_proyectil_energia_2', 'sonido_proyectil_energia_3', 'sonido_proyectil_energia_4'];
	}
	if (projectileSounds.length > 0) {
		var randomIndex = Math.floor(Math.random() * projectileSounds.length);
		var sound = LK.getSound(projectileSounds[randomIndex]);
		sound.volume = soundValue;
		sound.play();
	}
}
function disableAllNoteButtons() {
	for (var i = 0; i < notes.length; i++) {
		notes[i].isDisabled = true;
		notes[i].alpha = 0.5; // Visual feedback
	}
}
function enableNoteButtons() {
	// Re-enable buttons only if we have enough mana
	updateManaDisplay();
}
function addToCombination(element) {
	currentCombination.push(element);
	combinationTimer = combinationWindowTime;
	combinationCooldown = combinationResetTime;
	// Show current combination
	showCombinationMessage('Combinación: [' + currentCombination.join(', ') + ']');
}
function processCombination() {
	if (currentCombination.length === 0) {
		return;
	}
	// Store combination and timing intervals for melody playback before reset
	var combinationForMelody = currentCombination.slice(); // Create a copy
	var timingIntervalsForMelody = noteTimingIntervals.slice(); // Create a copy of intervals
	// Check if combination is valid
	if (isValidCombination(currentCombination)) {
		// Execute the combination
		executeCombination(currentCombination);
		// Play melody after successful summoning with preserved intervals
		playMelodySequenceWithIntervals(combinationForMelody, timingIntervalsForMelody);
	} else {
		// Show invalid combination message
		showCombinationMessage('Combinación no existente');
	}
	// Reset combination only (element list is managed by crea_combinacion_meteorito)
	// elementList is not reset here - only when meteorite is successfully invoked
	resetCombination();
	// Re-enable buttons after 1 second (invocation phase)
	LK.setTimeout(function () {
		temporaryNoteCounter = 0; // Reset helper counter after invocation phase
		enableNoteButtons();
	}, 1000);
}
function isValidCombination(combination) {
	// Check if combination length is unlocked
	if (unlockedCombinations.indexOf(combination.length) === -1) {
		return false;
	}
	// Single element combinations are valid
	if (combination.length === 1) {
		var element = combination[0];
		return element === 'fire' || element === 'water' || element === 'earth' || element === 'wind' || element === 'light';
	}
	// Check for meteorite combination first (exactly fire, water, earth, wind, light sequence)
	if (combination.length === 5) {
		var requiredSequence = ['fire', 'water', 'earth', 'wind', 'light'];
		var isMeteorite = true;
		for (var i = 0; i < combination.length; i++) {
			if (combination[i] !== requiredSequence[i]) {
				isMeteorite = false;
				break;
			}
		}
		if (isMeteorite) {
			return true; // Perfect meteorite sequence match
		}
		// If not meteorite sequence, check if all elements are the same for tier 5
		var firstElement = combination[0];
		for (var i = 0; i < combination.length; i++) {
			if (combination[i] !== firstElement) {
				return false;
			}
		}
		// Valid elements for multi-note combinations
		return firstElement === 'fire' || firstElement === 'water' || firstElement === 'earth' || firstElement === 'wind' || firstElement === 'light';
	}
	// Multiple element combinations (2-4 notes of same element)
	if (combination.length >= 2 && combination.length <= 4) {
		var firstElement = combination[0];
		// Check if all elements are the same
		for (var i = 0; i < combination.length; i++) {
			if (combination[i] !== firstElement) {
				return false;
			}
		}
		// Valid elements for multi-note combinations
		return firstElement === 'fire' || firstElement === 'water' || firstElement === 'earth' || firstElement === 'wind' || firstElement === 'light';
	}
	return false;
}
function executeCombination(combination) {
	// Check if we have enough mana for this combination
	if (currentMana < combination.length) {
		showCombinationMessage('No hay suficiente mana');
		return;
	}
	// Consume mana based on combination length
	currentMana -= combination.length;
	updateManaDisplay();
	if (combination.length === 1) {
		// Single element summon
		var element = combination[0];
		summonWarrior(element, 1);
		showCombinationMessage('¡' + element.toUpperCase() + ' nivel 1 invocado!');
	} else if (combination.length >= 2 && combination.length <= 4) {
		// Multiple element combination - create higher tier warrior (2-4 notes)
		var element = combination[0]; // All elements should be the same
		var level = combination.length;
		summonWarrior(element, level);
		showCombinationMessage('¡' + element.toUpperCase() + ' nivel ' + level + ' invocado!');
	} else if (combination.length === 5) {
		// Check if it's the meteorite sequence
		var requiredSequence = ['fire', 'water', 'earth', 'wind', 'light'];
		var isMeteorite = true;
		for (var i = 0; i < combination.length; i++) {
			if (combination[i] !== requiredSequence[i]) {
				isMeteorite = false;
				break;
			}
		}
		if (isMeteorite) {
			// Meteorite combination - summon destructive meteorite with mixed elements
			summonMeteorito();
			showCombinationMessage('¡METEORITO ELEMENTAL INVOCADO!');
		} else {
			// Regular 5-note same element combination
			var element = combination[0];
			summonWarrior(element, 5);
			showCombinationMessage('¡' + element.toUpperCase() + ' nivel 5 invocado!');
		}
	}
}
function summonWarrior(element, tier) {
	// Default tier to 1 if not specified
	if (tier === undefined) {
		tier = 1;
	}
	// Create elemental warrior based on the element and tier
	var warrior = new Warrior(element, tier);
	warrior.x = playerTower.x + 300;
	warrior.y = 2186; // Spawn on ground level
	warrior.onGround = true; // Start on ground
	// Add elemental-specific visual effects on spawn
	var warriorGraphics = warrior.children[0]; // Get the warrior graphics
	if (element === 'water') {
		// Water splash effect - blue particles
		var summonScale = warrior.tierScale * 1.5;
		tween(warriorGraphics, {
			tint: 0x0066ff,
			scaleX: summonScale,
			scaleY: summonScale
		}, {
			duration: 300,
			onFinish: function onFinish() {
				tween(warriorGraphics, {
					tint: 0xffffff,
					scaleX: warrior.tierScale,
					scaleY: warrior.tierScale
				}, {
					duration: 200
				});
			}
		});
	} else if (element === 'earth') {
		// Earth rumble effect - brown particles
		var originalY = warriorGraphics.y;
		tween(warriorGraphics, {
			tint: 0x8b4513,
			y: originalY - 50
		}, {
			duration: 200,
			onFinish: function onFinish() {
				tween(warriorGraphics, {
					tint: 0xffffff,
					y: originalY
				}, {
					duration: 200
				});
			}
		});
	} else if (element === 'fire') {
		// Fire burst effect - red/orange flames
		var summonScale = warrior.tierScale * 1.3;
		tween(warriorGraphics, {
			tint: 0xff4400,
			scaleX: summonScale,
			scaleY: summonScale,
			rotation: Math.PI * 0.1
		}, {
			duration: 250,
			onFinish: function onFinish() {
				tween(warriorGraphics, {
					tint: 0xffffff,
					scaleX: warrior.tierScale,
					scaleY: warrior.tierScale,
					rotation: 0
				}, {
					duration: 150
				});
			}
		});
	} else if (element === 'light') {
		// Lightning effect - bright yellow flash
		var summonScale = warrior.tierScale * 1.2;
		tween(warriorGraphics, {
			tint: 0xffff00,
			alpha: 1.5,
			scaleX: summonScale,
			scaleY: summonScale
		}, {
			duration: 150,
			onFinish: function onFinish() {
				tween(warriorGraphics, {
					tint: 0xffffff,
					alpha: 1.0,
					scaleX: warrior.tierScale,
					scaleY: warrior.tierScale
				}, {
					duration: 100
				});
			}
		});
	} else if (element === 'wind') {
		// Wind swirl effect - green spiral
		var summonScale = warrior.tierScale * 1.1;
		tween(warriorGraphics, {
			tint: 0x44ff44,
			rotation: Math.PI * 2,
			scaleX: summonScale,
			scaleY: summonScale
		}, {
			duration: 400,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(warriorGraphics, {
					tint: 0xffffff,
					rotation: 0,
					scaleX: warrior.tierScale,
					scaleY: warrior.tierScale
				}, {
					duration: 200
				});
			}
		});
	}
	game.addChild(warrior);
	warriors.push(warrior);
	var sound = LK.getSound('summon');
	sound.volume = soundValue;
	sound.play();
	// Add jump effect to all units when any warrior is summoned
	// Make all warriors jump
	for (var i = 0; i < warriors.length; i++) {
		var jumpWarrior = warriors[i];
		// Store current Y position if not already stored
		if (jumpWarrior.baseY === 0) {
			jumpWarrior.baseY = jumpWarrior.y;
		}
		// Apply jump tween - go up then back down
		tween(jumpWarrior, {
			y: jumpWarrior.baseY - 100
		}, {
			duration: 200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(jumpWarrior, {
					y: jumpWarrior.baseY
				}, {
					duration: 200,
					easing: tween.easeIn
				});
			}
		});
	}
	// Make all enemies jump
	for (var i = 0; i < enemies.length; i++) {
		var jumpEnemy = enemies[i];
		// Store current Y position if not already stored
		if (jumpEnemy.baseY === 0) {
			jumpEnemy.baseY = jumpEnemy.y;
		}
		// Apply jump tween - go up then back down
		tween(jumpEnemy, {
			y: jumpEnemy.baseY - 100
		}, {
			duration: 200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(jumpEnemy, {
					y: jumpEnemy.baseY
				}, {
					duration: 200,
					easing: tween.easeIn
				});
			}
		});
	}
}
function playMelodySequenceWithIntervals(combination, intervals) {
	// Wait 1 second before starting melody playback to differentiate from invocation
	LK.setTimeout(function () {
		// Play notes sequentially using cumulative timing
		var cumulativeDelay = 0;
		for (var i = 0; i < combination.length; i++) {
			var element = combination[i];
			// First note plays immediately (0ms), subsequent notes use intervals
			var delay = i === 0 ? 0 : cumulativeDelay;
			// Use setTimeout with closure to preserve the element value
			(function (noteElement, currentDelay) {
				LK.setTimeout(function () {
					// Play the appropriate elemental note sound with controlled volume
					if (noteElement === 'fire') {
						var fireSound = LK.getSound('Nota_Fire2');
						fireSound.volume = 0.1;
						fireSound.play();
					} else if (noteElement === 'water') {
						var waterSound = LK.getSound('Nota_Water2');
						waterSound.volume = soundValue;
						waterSound.play();
					} else if (noteElement === 'earth') {
						var earthSound = LK.getSound('Nota_Earth2');
						earthSound.volume = soundValue;
						earthSound.play();
					} else if (noteElement === 'wind') {
						var windSound = LK.getSound('Nota_Wind2');
						windSound.volume = soundValue;
						windSound.play();
					} else if (noteElement === 'light') {
						var lightSound = LK.getSound('Nota_Light2');
						lightSound.volume = soundValue;
						lightSound.play();
					} else {
						var summonSound = LK.getSound('summon2');
						summonSound.volume = soundValue;
						summonSound.play();
					}
				}, currentDelay);
			})(element, delay);
			// Add interval for next note (skip first note since it's 0)
			if (i < intervals.length && i > 0) {
				cumulativeDelay += intervals[i];
			} else if (i === 0 && intervals.length > 1) {
				// For first note, set cumulative delay to the second interval
				cumulativeDelay = intervals[1];
			}
		}
	}, 500); // 0.5 second delay before melody playback
}
function playMelodySequence(combination) {
	// Wait 1 second before starting melody playback to differentiate from invocation
	LK.setTimeout(function () {
		// Play each note in the combination using recorded timing intervals
		var cumulativeDelay = 0;
		for (var i = 0; i < combination.length; i++) {
			var element = combination[i];
			var delay = cumulativeDelay;
			// Use setTimeout with closure to preserve the element value
			(function (noteElement, currentDelay) {
				LK.setTimeout(function () {
					// Play the appropriate elemental note sound with controlled volume
					if (noteElement === 'fire') {
						var fireSound = LK.getSound('Nota_Fire2');
						fireSound.volume = 0.1;
						fireSound.play();
					} else if (noteElement === 'water') {
						var waterSound = LK.getSound('Nota_Water2');
						waterSound.volume = soundValue;
						waterSound.play();
					} else if (noteElement === 'earth') {
						var earthSound = LK.getSound('Nota_Earth2');
						earthSound.volume = soundValue;
						earthSound.play();
					} else if (noteElement === 'wind') {
						var windSound = LK.getSound('Nota_Wind2');
						windSound.volume = soundValue;
						windSound.play();
					} else if (noteElement === 'light') {
						var lightSound = LK.getSound('Nota_Light2');
						lightSound.volume = soundValue;
						lightSound.play();
					} else {
						var summonSound = LK.getSound('summon2');
						summonSound.volume = soundValue;
						summonSound.play();
					}
				}, currentDelay);
			})(element, delay);
			// Update cumulative delay for next note
			if (i < noteTimingIntervals.length) {
				cumulativeDelay += noteTimingIntervals[i];
			} else if (i > 0) {
				// Fallback to 200ms if no interval recorded
				cumulativeDelay += 200;
			}
		}
	}, 1000); // 1 second delay before melody playback
}
function updateElementListDisplay() {
	/*var listDisplay = 'Lista de Elementos: [' + elementList.map(function (el) {
		return el.toUpperCase();
	}).join(', ') + '] (' + elementList.length + '/' + maxElementList + ')';
	elementListText.setText(listDisplay);*/
}
function resetCombination() {
	currentCombination = [];
	combinationTimer = 0;
	combinationCooldown = 0;
	temporaryNoteCounter = 0; // Reset helper counter
	// Don't reset timing intervals here - they should persist until new combination starts
	// Only reset when a new note is pressed
	// Update display only when actually clearing intervals
}
function showCombinationMessage(message) {
	// Remove from game layer if it exists there
	if (combinationMessageText.parent === game) {
		game.removeChild(combinationMessageText);
	}
	// Add to GUI layer to ensure it's always on top
	if (combinationMessageText.parent !== LK.gui) {
		LK.gui.addChild(combinationMessageText);
	}
	combinationMessageText.setText(message);
	combinationMessageText.alpha = 1.0;
	// Fade out message after 2 seconds
	tween(combinationMessageText, {
		alpha: 0
	}, {
		duration: 2000
	});
}
function changeGroundTexture(assetName) {
	// Change ground texture for all tiles
	for (var g = 0; g < groundTiles.length; g++) {
		var oldTile = groundTiles[g];
		// Find the correct index to insert the new tile behind all existing ground tiles
		var insertIndex = 0;
		// Count existing ground tiles to place new tile behind them
		for (var childIndex = 0; childIndex < game.children.length; childIndex++) {
			var child = game.children[childIndex];
			// Check if this child is a ground tile by comparing properties
			if (child.anchor && child.anchor.x === 0.0 && child.anchor.y === 1.0 && child.y === 2732) {
				insertIndex = childIndex + 1; // Place after this ground tile
			}
		}
		var newTile = game.addChildAt(LK.getAsset(assetName, {
			anchorX: 0.0,
			anchorY: 1.0,
			x: oldTile.x,
			y: oldTile.y,
			width: oldTile.width,
			height: oldTile.height
		}), insertIndex);
		// Add tween to smoothly transition between textures
		newTile.alpha = 0;
		tween(newTile, {
			alpha: 1
		}, {
			duration: 500,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				oldTile.destroy();
			}
		});
		groundTiles[g] = newTile;
	}
}
game.down = function (x, y, obj) {
	// Check if comic system is active and handle comic progression
	if (comicActive) {
		nextComic();
		return;
	}
	// Handle initial touch in game layer directly
	// Store initial touch position for debug
	initialTouchX = x;
	initialTouchY = y;
	currentTouchX = x;
	currentTouchY = y;
	if (touchDebugText && typeof touchDebugText.setText === 'function') {
		touchDebugText.setText(/*'Touch Info: Initial(' + Math.round(x) + ',' + Math.round(y) + ') Current(' + Math.round(x) + ',' + Math.round(y) + ')'*/'');
	}
	if (obj.event && obj.event.button === 2) {
		// Right mouse button
		isDragging = true;
		lastMouseX = x;
		obj.event.preventDefault(); // Prevent context menu
	}
};
leftButton.down = function (x, y, obj) {
	// Move camera left
	cameraX -= 100;
	cameraX = Math.max(0, Math.min(cameraX, maxCameraX));
	game.x = -cameraX;
	// Visual feedback
	tween(leftButton, {
		scaleX: 0.9,
		scaleY: 0.9
	}, {
		duration: 100,
		onFinish: function onFinish() {
			tween(leftButton, {
				scaleX: 1.0,
				scaleY: 1.0
			}, {
				duration: 100
			});
		}
	});
};
rightButton.down = function (x, y, obj) {
	// Move camera right
	cameraX += 100;
	cameraX = Math.max(0, Math.min(cameraX, maxCameraX));
	game.x = -cameraX;
	// Visual feedback
	tween(rightButton, {
		scaleX: 0.9,
		scaleY: 0.9
	}, {
		duration: 100,
		onFinish: function onFinish() {
			tween(rightButton, {
				scaleX: 1.0,
				scaleY: 1.0
			}, {
				duration: 100
			});
		}
	});
};
game.up = function (x, y, obj) {
	if (obj.event && obj.event.button === 2) {
		// Right mouse button
		isDragging = false;
	}
};
game.move = function (x, y, obj) {
	if (isDragging) {
		var deltaX = lastMouseX - x;
		cameraX += deltaX;
		cameraX = Math.max(0, Math.min(cameraX, maxCameraX));
		game.x = -cameraX;
		lastMouseX = x;
	}
	// Update current touch position for debug (game coordinates)
	currentTouchX = x;
	currentTouchY = y;
	// Update debug text with both initial and current positions
	if (touchDebugText && typeof touchDebugText.setText === 'function') {
		/*touchDebugText.setText('Game Move - Initial(' + Math.round(initialTouchX) + ',' + Math.round(initialTouchY) + ') Current(' + Math.round(currentTouchX) + ',' + Math.round(currentTouchY) + ')');*/
	}
};
// Add GUI move handler for touch tracking
LK.gui.topLeft.move = function (x, y, obj) {
	// Update current touch position for debug (GUI coordinates)
	currentTouchX = x;
	currentTouchY = y;
	// Update debug text with both initial and current positions
	if (touchDebugText && typeof touchDebugText.setText === 'function') {
		touchDebugText.setText(/*'GUI Move - Initial(' + Math.round(initialTouchX) + ',' + Math.round(initialTouchY) + ') Current(' + Math.round(currentTouchX) + ',' + Math.round(currentTouchY) + ')'*/'');
	}
};
// Cloud system for background decoration
var clouds = [];
var cloudSpawnTimer = 0;
function createCloud() {
	var cloud = new Nube();
	cloud.x = -200; // Start off-screen left
	// Create clouds randomly between y=0 and y=1000 with depth layering
	cloud.y = Math.random() * 2000; // Random position between y=0 and y=2000
	cloud.startFloating(); // Start floating animation after position is set
	// Determine if cloud is background (behind game) or foreground (in front of game)
	var isBackground = Math.random() < 0.6; // 60% chance to be background
	if (isBackground) {
		// Background clouds - behind game elements, more transparent
		// Scale already randomized in Nube constructor, apply additional uniform background scaling
		var additionalScale = 0.5 + Math.random() * 0.6; // Apply additional 50-110% scaling
		cloud.scaleX *= additionalScale;
		cloud.scaleY *= additionalScale;
		cloud.alpha = 0.4 + Math.random() * 0.5; // Random opacity between 40% and 90%
		cloud.children[0].tint = 0xE0E0E0; // Slightly darker for background effect
		// Add background clouds before other game elements
		game.addChildAt(cloud, 0); // Add at index 0 to be behind everything
	} else {
		// Foreground clouds - in front of game elements, more visible
		// Scale already randomized in Nube constructor, apply additional uniform foreground scaling
		var additionalScale = 0.8 + Math.random() * 0.8; // Apply additional 80-160% scaling
		cloud.scaleX *= additionalScale;
		cloud.scaleY *= additionalScale;
		cloud.alpha = 0.4 + Math.random() * 0.5; // Random opacity between 40% and 90%
		cloud.children[0].tint = 0xF8F8F8; // Brighter for foreground effect
		// Add foreground clouds on top of game elements
		game.addChild(cloud); // Add normally to be in front
	}
	// Vary speed based on position for depth effect
	if (cloud.y < 600) {
		// Higher clouds move slower (distance effect)
		cloud.baseSpeed = cloud.baseSpeed * 0.5;
	} else if (cloud.y > 1400) {
		// Lower clouds move faster (proximity effect)
		cloud.baseSpeed = cloud.baseSpeed * 1.5;
	}
	clouds.push(cloud);
}
function updateClouds() {
	// Note: Cloud movement is now handled by the Nube class update method
	// Spawn new clouds periodically
	cloudSpawnTimer++;
	if (cloudSpawnTimer >= 300 + Math.random() * 600) {
		// Every 5-15 seconds
		createCloud();
		cloudSpawnTimer = 0;
	}
}
// Create initial clouds
for (var i = 0; i < 24; i++) {
	// Doubled number for better coverage
	var cloud = new Nube();
	cloud.x = Math.random() * 4000; // Random initial position across screen
	// Create clouds randomly between y=0 and y=1000 with depth layering
	cloud.y = Math.random() * 2000; // Random position between y=0 and y=2000
	cloud.startFloating(); // Start floating animation after position is set
	// Determine if cloud is background (behind game) or foreground (in front of game)
	var isBackground = Math.random() < 0.6; // 60% chance to be background
	if (isBackground) {
		// Background clouds - behind game elements, more transparent
		// Scale already randomized in Nube constructor, apply additional uniform background scaling
		var additionalScale = 0.5 + Math.random() * 0.6; // Apply additional 50-110% scaling
		cloud.scaleX *= additionalScale;
		cloud.scaleY *= additionalScale;
		cloud.alpha = 0.4 + Math.random() * 0.5; // Random opacity between 40% and 90%
		cloud.children[0].tint = 0xE0E0E0; // Slightly darker for background effect
		// Add background clouds before other game elements
		game.addChildAt(cloud, 0); // Add at index 0 to be behind everything
	} else {
		// Foreground clouds - in front of game elements, more visible
		// Scale already randomized in Nube constructor, apply additional uniform foreground scaling
		var additionalScale = 0.8 + Math.random() * 0.8; // Apply additional 80-160% scaling
		cloud.scaleX *= additionalScale;
		cloud.scaleY *= additionalScale;
		cloud.alpha = 0.4 + Math.random() * 0.5; // Random opacity between 40% and 90%
		cloud.children[0].tint = 0xF8F8F8; // Brighter for foreground effect
		// Add foreground clouds on top of game elements
		game.addChild(cloud); // Add normally to be in front
	}
	// Vary speed based on position for depth effect
	if (cloud.y < 600) {
		// Higher clouds move slower (distance effect)
		cloud.baseSpeed = cloud.baseSpeed * 0.5;
	} else if (cloud.y > 1400) {
		// Lower clouds move faster (proximity effect)
		cloud.baseSpeed = cloud.baseSpeed * 1.5;
	}
	clouds.push(cloud);
}
// Function to simulate music beat detection based on game timing
function getGameMusicLevel() {
	// Simulate music beats based on game ticks and music timing
	// Create a beat pattern that varies over time
	var beatPattern = Math.sin(LK.ticks * 0.1) * 0.3 + 0.5; // Base sine wave
	var strongBeat = Math.sin(LK.ticks * 0.05) * 0.4; // Slower variation for stronger beats
	var randomVariation = (Math.random() - 0.5) * 0.2; // Add some randomness
	// Combine patterns to create realistic music-like variation
	var musicLevel = beatPattern + strongBeat + randomVariation;
	// Ensure the value stays within realistic bounds (0.0 to 1.0)
	musicLevel = Math.max(0, Math.min(1, musicLevel));
	return musicLevel;
}
// Function to initialize element list (lista meteorito)
function initializeElementList() {
	elementList = ['fire', 'water', 'earth', 'wind', 'light'];
	updateElementListDisplay();
}
// Function to create random meteorite combination
function crea_combinacion_meteorito() {
	for (var i = 0; i < 5; i++) {
		// Generate random integer between 0.49 and 5.49, then make it integer
		var randomNumber = Math.floor(Math.random() * 5) + 1; // This gives us 1-5
		var element;
		if (randomNumber === 1) {
			element = 'fire';
		} else if (randomNumber === 2) {
			element = 'water';
		} else if (randomNumber === 3) {
			element = 'earth';
		} else if (randomNumber === 4) {
			element = 'wind';
		} else if (randomNumber === 5) {
			element = 'light';
		}
		elementList.push(element);
	}
	updateElementListDisplay();
}
// Initialize element list with corresponding notes at game start
crea_combinacion_meteorito();
// Start background music with initial volume from slider
musiclevel();
// Timer for apocalyptic note revelation (every 10 seconds = 600 frames at 60fps)
var revelacionTimer = 0;
game.update = function () {
	// Check if level is 0 and comic system should activate (only at level 0)
	if (nivel === 0 && !comicActive) {
		activateComicSystem();
	}
	// Deactivate comic system if nivel is not -1 and comic is active
	if (nivel !== -1 && comicActive) {
		comicActive = false;
		clearComicImages();
		fondoNegro.alpha = 0; // Hide black background
		pausa = false;
	}
	// Hide/show language button and text based on comic state
	if (comicActive) {
		languageButton.visible = false;
		languageButtonText.visible = false;
	} else {
		languageButton.visible = true;
		languageButtonText.visible = true;
	}
	// Music beat detection and character synchronization
	var audioLevel = getGameMusicLevel();
	// Calculate sensitivity difference for debug display
	var sensitivityDifference = Math.max(0, audioLevel - musicBeatThreshold);
	// Update audio debug text in real-time
	if (audioDebugText && typeof audioDebugText.setText === 'function') {
		/*audioDebugText.setText('Audio: ' + audioLevel.toFixed(3) + ' | Threshold: ' + musicBeatThreshold.toFixed(2) + ' | Diff: ' + sensitivityDifference.toFixed(3));*/
	}
	// Update revelacion timer and call function every 10 seconds
	if (pausa == false) {
		if (nivel >= 6) {
			revelacionTimer++;
			if (revelacionTimer >= 600) {
				// 10 seconds at 60fps
				revelacion_nota_apocalitica();
				revelacionTimer = 0;
			}
		}
	}
	// Enhanced beat detection with multiple triggers
	var beatDetected = false;
	// Primary beat detection - only when audio level reaches 1
	if (audioLevel >= 1.0 && LK.ticks - lastBeatTime > beatCooldown) {
		beatDetected = true;
	}
	// Remove fallback timer-based beat detection to prevent constant particle spam
	if (beatDetected) {
		// Beat detected - activate effect on all characters
		lastBeatTime = LK.ticks;
		// Activate effect on warriors
		for (var i = 0; i < warriors.length; i++) {
			warriors[i].beatEffectTimer = 120; // 2 seconds of sine wave effect
		}
		// Activate effect on enemies only if they're not golden statues
		for (var i = 0; i < enemies.length; i++) {
			if (!enemies[i].enemigo_oro) {
				enemies[i].beatEffectTimer = 120; // 2 seconds of sine wave effect
			}
		}
		// Activate particle effects on towers instead of scaling
		// Create particles around player tower in cone shape
		for (var p = 0; p < 24; p++) {
			// Calculate cone angle - wider at the top, narrower at bottom
			var angle = (Math.random() - 0.5) * Math.PI * 0.5; // 90 degree cone spread
			var distance = Math.random() * 300 + 100; // Random distance from center
			var startX = playerTower.x + Math.sin(angle) * (distance * 0.3); // Narrow at bottom
			var endX = playerTower.x + Math.sin(angle) * distance; // Wide at top
			var playerTowerCurrentScale = playerTower.scaleX; // Get current tower scale
			var scaledOffsetY = (1728 - 50) * playerTowerCurrentScale; // Scale the Y offset
			var particle = game.addChild(LK.getAsset('particula_torre_jugador', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: startX + 100,
				y: playerTower.y - scaledOffsetY,
				width: 300 + Math.random() * 200,
				height: 300 + Math.random() * 200,
				rotation: Math.PI
			}));
			particle.alpha = 0.8;
			// Animate particles upward to the sky in cone shape and fade out
			tween(particle, {
				y: playerTower.y - 2000 - Math.random() * 500,
				x: endX + 100,
				alpha: 0,
				scaleX: 0.2,
				scaleY: 0.2
			}, {
				duration: 3000 + Math.random() * 500,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					particle.destroy();
				}
			});
		}
		// Create particles around enemy tower in cone shape
		for (var p = 0; p < 24; p++) {
			// Calculate cone angle - wider at the top, narrower at bottom
			var angle = (Math.random() - 0.5) * Math.PI * 0.5; // 90 degree cone spread
			var distance = Math.random() * 300 + 100; // Random distance from center
			var startX = enemyTower.x + Math.sin(angle) * (distance * 0.3); // Narrow at bottom
			var endX = enemyTower.x + Math.sin(angle) * distance; // Wide at top
			var enemyTowerCurrentScale = enemyTower.scaleX; // Get current tower scale
			var scaledOffsetY = (1728 - 50) * enemyTowerCurrentScale; // Scale the Y offset
			var particle = game.addChild(LK.getAsset('particula_torre_enemiga', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: startX,
				y: enemyTower.y - scaledOffsetY,
				width: 300 + Math.random() * 200,
				height: 300 + Math.random() * 200,
				rotation: Math.PI
			}));
			particle.alpha = 0.8;
			// Animate particles upward to the sky in cone shape and fade out
			tween(particle, {
				y: enemyTower.y - 2000 - Math.random() * 500,
				x: endX,
				alpha: 0,
				scaleX: 0.2,
				scaleY: 0.2
			}, {
				duration: 3000 + Math.random() * 500,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					particle.destroy();
				}
			});
		}
	}
	// Mana regeneration - every 10 seconds (600 frames at 60fps)
	if (pausa == false) {
		manaRegenTimer++;
		if (manaRegenTimer >= 600) {
			if (currentMana < maxMana) {
				currentMana++;
				updateManaDisplay();
			}
			manaRegenTimer = 0;
		}
	}
	// Spawn enemies periodically
	enemySpawnTimer++;
	if (enemySpawnTimer >= 500) {
		// Every 8.3 seconds
		spawnEnemy();
		enemySpawnTimer = 0;
	}
	// Clean up off-screen warriors
	for (var i = warriors.length - 1; i >= 0; i--) {
		var warrior = warriors[i];
		if (warrior.x > 4000) {
			warrior.destroy();
			warriors.splice(i, 1);
		}
	}
	// Clean up off-screen enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		if (enemy.x < -200) {
			enemy.destroy();
			enemies.splice(i, 1);
		}
	}
	// Clean up off-screen spores
	for (var i = esporas.length - 1; i >= 0; i--) {
		var espora = esporas[i];
		if (espora.x < -500 || espora.x > 4500 || espora.y > 3500) {
			espora.destroy();
			esporas.splice(i, 1);
		}
	}
	// Update cloud system
	updateClouds();
	// Update temporary counter info text
	/*tempCounterInfoText.setText('Notas presionadas: ' + temporaryNoteCounter);*/
	// Check if any fire tier 5 warriors exist
	var hasTier5FireWarrior = false;
	for (var w = 0; w < warriors.length; w++) {
		var warrior = warriors[w];
		if (warrior.element === 'fire' && warrior.tier === 5) {
			hasTier5FireWarrior = true;
			break;
		}
	}
	// Activate fire mode if tier 5 fire warrior exists and mode is not active
	if (hasTier5FireWarrior && !globalFireModeActive) {
		globalFireModeActive = true;
		showCombinationMessage('¡MODO FUEGO ACTIVADO!');
		// Activate red visual effects
		tween(fireOverlay, {
			alpha: 0.2
		}, {
			duration: 500,
			easing: tween.easeInOut
		});
		// Apply red tint to towers
		tween(playerTower, {
			tint: 0xff6666
		}, {
			duration: 500,
			easing: tween.easeInOut
		});
		tween(enemyTower, {
			tint: 0xff6666
		}, {
			duration: 500,
			easing: tween.easeInOut
		});
		// Change ground texture to fire ground
		changeGroundTexture('tileground');
		// Apply red tint to clouds
		for (var c = 0; c < clouds.length; c++) {
			// Store original tint if not already stored
			if (!clouds[c].children[0].originalTint) {
				clouds[c].children[0].originalTint = clouds[c].children[0].tint;
			}
			tween(clouds[c].children[0], {
				tint: 0xff8888
			}, {
				duration: 500,
				easing: tween.easeInOut
			});
		}
	}
	// Deactivate fire mode if no tier 5 fire warriors exist and mode is active
	if (!hasTier5FireWarrior && globalFireModeActive) {
		globalFireModeActive = false;
		showCombinationMessage('Modo fuego desactivado');
		// Fade out red overlay and tints
		tween(fireOverlay, {
			alpha: 0
		}, {
			duration: 1000,
			easing: tween.easeOut
		});
		// Remove red tint from towers
		tween(playerTower, {
			tint: 0xffffff
		}, {
			duration: 1000,
			easing: tween.easeOut
		});
		tween(enemyTower, {
			tint: 0xffffff
		}, {
			duration: 1000,
			easing: tween.easeOut
		});
		// Change ground texture back to normal
		changeGroundTexture('ground');
		// Remove red tint from clouds
		for (var c = 0; c < clouds.length; c++) {
			tween(clouds[c].children[0], {
				tint: clouds[c].children[0].originalTint || 0xF0F0F0
			}, {
				duration: 1000,
				easing: tween.easeOut
			});
		}
	}
	// Process global fire mode effects only if active
	if (globalFireModeActive) {
		// Apply fire damage to all enemies every second
		if (LK.ticks % 60 === 0) {
			for (var i = 0; i < enemies.length; i++) {
				var enemy = enemies[i];
				if (enemy.takeBurnDamage) {
					enemy.takeBurnDamage(0, 1000, 6); // No initial damage, 1 second burn for 6 damage
				}
			}
		}
	}
	// Update apocalypse timer
	tiempoDeApocalipsis++;
	if (tiempoDeApocalipsis >= apocalipsisThreshold) {
		// 5 seconds of no note presses - trigger apocalypse music
		musicaDelApocalipsis();
		tiempoDeApocalipsis = 0; // Reset timer after triggering
	}
	// Update combination system timers
	if (combinationTimer > 0) {
		combinationTimer--;
		if (combinationTimer <= 0 && currentCombination.length > 0) {
			// Time window expired, process current combination
			processCombination();
		}
	}
	if (combinationCooldown > 0) {
		combinationCooldown--;
		if (combinationCooldown <= 0 && currentCombination.length > 0) {
			// Reset timeout reached, clear combination
			showCombinationMessage('Tiempo agotado - Combinación reiniciada');
			resetCombination();
			// Re-enable buttons after timeout
			enableNoteButtons();
		}
	}
};
// Variable i for counting revealed apocalyptic notes
var i = 0;
// Comic system variables
var comicActive = false;
var currentComicIndex = 0;
var comicImages = [];
var maxComics = 11;
function revelacion_nota_apocalitica() {
	// Only reveal if i is less than 5 (cannot have more than i=5)
	if (i >= 5) {
		return; // Exit if we've already revealed all 5 notes
	}
	// Get the element from elementList based on current counter i
	if (i < elementList.length) {
		var element = elementList[i];
		// Get the corresponding note image for this element
		var noteImageId = element + 'Note';
		// Update the apocalyptic note casilla with the element's note image
		if (casillas[i]) {
			// Remove current asset and add new one
			casillas[i].destroy();
			// Create new note asset with the element's image
			var newCasilla = LK.getAsset(noteImageId, {
				width: 60,
				height: 60,
				anchorX: 0.5,
				anchorY: 0.5
			});
			newCasilla.x = 409 + i * 70; // Same positioning as original
			newCasilla.y = 220;
			LK.gui.topLeft.addChild(newCasilla);
			casillas[i] = newCasilla;
		}
	}
	// Increment counter by 1 each time function is called
	i++;
}
function ocultar_notas_apocalitica() {
	// Reset counter i to 0
	i = 0;
	// Hide all apocalyptic notes by restoring default lock image
	for (var j = 0; j < casillas.length; j++) {
		if (casillas[j]) {
			// Remove current note image
			casillas[j].destroy();
			// Create new default lock image
			var newCasilla = LK.getAsset('nota_apocalitica', {
				width: 60,
				height: 60,
				anchorX: 0.5,
				anchorY: 0.5
			});
			newCasilla.x = 409 + j * 70; // Same positioning as original
			newCasilla.y = 220;
			LK.gui.topLeft.addChild(newCasilla);
			casillas[j] = newCasilla;
		}
	}
}
function convertir_enemigos_esmeralda(enemy) {
	// Store enemy attributes before destruction
	var enemyImageName = 'enemyUnit'; // Get the enemy's image name
	var enemyDamage = enemy.damage;
	var enemyHealth = enemy.health;
	var enemyMaxHealth = enemy.maxHealth;
	var enemySpeed = enemy.speed;
	var enemyAttackCooldown = enemy.attackCooldown || 80;
	var enemyPosition = {
		x: enemy.x,
		y: enemy.y
	};
	var isFlying = false; // Enemies are ground units
	var isRanged = false; // Enemies are melee units
	var attackRange = 250; // Melee range
	// Instantly destroy the enemy
	enemy.destroy();
	var index = enemies.indexOf(enemy);
	if (index > -1) {
		enemies.splice(index, 1);
	}
	// Create a new warrior with enemy attributes using Warrior class structure
	var convertedWarrior = new Container();
	var warriorGraphics = convertedWarrior.attachAsset('enemyUnit', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 280,
		height: 280
	});
	// Apply mirror effect (flip horizontally)
	warriorGraphics.scaleX = -1;
	// Set inherited attributes from enemy
	convertedWarrior.element = 'converted';
	convertedWarrior.tier = 1;
	convertedWarrior.health = enemyHealth;
	convertedWarrior.maxHealth = enemyMaxHealth;
	convertedWarrior.damage = enemyDamage;
	convertedWarrior.speed = enemySpeed;
	convertedWarrior.attackCooldown = 0;
	convertedWarrior.baseCooldown = enemyAttackCooldown;
	convertedWarrior.target = null;
	convertedWarrior.isBeingDestroyed = false;
	convertedWarrior.activar_movimiento = true; // Enable movement
	convertedWarrior.aumento_velocidad = 0;
	// Physics properties
	convertedWarrior.velocityY = 0;
	convertedWarrior.onGround = true;
	convertedWarrior.gravity = 0.5;
	convertedWarrior.baseY = enemyPosition.y;
	convertedWarrior.beatEffectTimer = 0;
	// Set combat properties based on enemy type
	convertedWarrior.isFlying = isFlying;
	convertedWarrior.isRanged = isRanged;
	convertedWarrior.canAttack = true; // Enable attack ability
	convertedWarrior.ataque_jugador = true; // Enable player attack
	convertedWarrior.movimiento_enemigo = true; // Enable enemy targeting movement
	if (isRanged) {
		convertedWarrior.projectiles = [];
	}
	// Position the converted warrior
	convertedWarrior.x = enemyPosition.x;
	convertedWarrior.y = enemyPosition.y;
	// Health bar
	var healthBar = LK.getAsset('warriorHealthBar', {
		width: 120,
		height: 16
	});
	healthBar.anchor.set(0.5, 0.5);
	healthBar.y = -100;
	convertedWarrior.addChild(healthBar);
	convertedWarrior.healthBar = healthBar;
	// Stats text
	var statsText = new Text2('', {
		size: 48,
		fill: 0xFFFFFF,
		font: "'GillSans-Bold',Impact,'Arial Black',Tahoma"
	});
	statsText.anchor.set(0.5, 0.5);
	statsText.y = 120;
	convertedWarrior.addChild(statsText);
	convertedWarrior.statsText = statsText;
	// Update stats display function
	convertedWarrior.updateStatsDisplay = function () {
		if (pausa == false) {
			var range = isRanged ? 600 : 250;
			var totalSpeed = convertedWarrior.speed + (convertedWarrior.aumento_velocidad || 0);
			var statsString = convertedWarrior.health + '-' + convertedWarrior.damage + '-' + totalSpeed + '-' + range + '-' + convertedWarrior.baseCooldown;
			convertedWarrior.statsText.setText(statsString);
		}
	};
	// Initialize stats display
	convertedWarrior.updateStatsDisplay();
	// Update function - full warrior behavior like normal warriors
	convertedWarrior.update = function () {
		if (pausa == false) {
			// Set base Y position for beat effect
			if (convertedWarrior.baseY === 0) {
				convertedWarrior.baseY = 2186; // Ground level
			}
			// Apply beat effect if active
			if (convertedWarrior.beatEffectTimer > 0) {
				convertedWarrior.beatEffectTimer--;
				// Get current audio level and calculate rotation strength based on sensitivity difference
				var audioLevel = getGameMusicLevel();
				var sensitivityDifference = Math.max(0, audioLevel - musicBeatThreshold);
				if (sensitivityDifference > 0) {
					var rotationAmount = Math.sin((120 - convertedWarrior.beatEffectTimer) * 0.3) * sensitivityDifference * 0.785;
					warriorGraphics.rotation = rotationAmount;
				} else {
					warriorGraphics.rotation = 0; // No rotation when no difference
				}
			} else {
				warriorGraphics.rotation = 0; // Reset rotation when effect ends
				// Apply gravity only to non-flying units
				if (!convertedWarrior.isFlying && !convertedWarrior.onGround) {
					convertedWarrior.velocityY += convertedWarrior.gravity;
					convertedWarrior.y += convertedWarrior.velocityY;
				}
				// Ground collision for non-flying units
				var groundY = 2186;
				if (!convertedWarrior.isFlying && convertedWarrior.y >= groundY) {
					convertedWarrior.y = groundY;
					convertedWarrior.baseY = groundY; // Update base position
					convertedWarrior.velocityY = 0;
					convertedWarrior.onGround = true;
				} else if (!convertedWarrior.isFlying) {
					convertedWarrior.onGround = false;
				}
			}
			// Move towards enemy tower only if movement is enabled
			if (!convertedWarrior.target && convertedWarrior.activar_movimiento) {
				var totalSpeed = convertedWarrior.speed + (convertedWarrior.aumento_velocidad || 0);
				convertedWarrior.x += totalSpeed;
			}
			// Attack logic
			if (convertedWarrior.attackCooldown > 0) {
				convertedWarrior.attackCooldown--;
			}
			// Check for enemies to attack and combat engagement
			var inCombat = false;
			var attackRange = 250; // Melee range for converted warriors
			for (var i = 0; i < enemies.length; i++) {
				var enemy = enemies[i];
				// Use half width for warrior and enemy colliders but keep full height
				var warriorColliderWidth = 280 * 0.5; // Half of converted warrior width
				var enemyColliderWidth = 280 * 0.5; // Half of enemy width
				var distance = Math.sqrt(Math.pow(convertedWarrior.x - enemy.x, 2) + Math.pow(convertedWarrior.y - enemy.y, 2));
				if (distance < attackRange) {
					// Mark as in combat to stop movement
					inCombat = true;
					// Attack if cooldown is ready
					if (convertedWarrior.attackCooldown <= 0 && convertedWarrior.canAttack && convertedWarrior.ataque_jugador) {
						convertedWarrior.attack(enemy);
						// Attack animation - flash red and scale up
						tween(warriorGraphics, {
							tint: 0xff0000,
							scaleX: -1.4,
							scaleY: 1.4
						}, {
							duration: 300,
							onFinish: function onFinish() {
								tween(warriorGraphics, {
									tint: 0xffffff,
									scaleX: -1.0,
									scaleY: 1.0
								}, {
									duration: 300
								});
							}
						});
					}
					break;
				}
			}
			// Check if warrior is at the tower x position - stop movement to focus on tower attack
			var atTowerPosition = Math.abs(convertedWarrior.x - enemyTower.x) <= 50;
			// Set activar_movimiento based on combat state
			if (inCombat || atTowerPosition) {
				// Stop movement when in combat range or at tower
				convertedWarrior.activar_movimiento = false;
			} else {
				// Allow movement when not in combat
				convertedWarrior.activar_movimiento = true;
				convertedWarrior.movimiento_enemigo = true;
			}
			// Apply movement based on activar_movimiento flag
			if (!convertedWarrior.activar_movimiento || atTowerPosition) {
				convertedWarrior.speed = 0;
			} else {
				// Resume normal movement with inherited speed from enemy
				convertedWarrior.speed = enemySpeed;
			}
			// Check collision with enemy tower - use separate x and y collision detection
			var towerColliderRadius = 700; // Fixed collider size, not scaled with tower
			var warriorColliderWidth = 280 * 0.5; // Half of warrior width
			var warriorColliderHeight = 280; // Full warrior height
			var towerDistance = Math.sqrt(Math.pow(convertedWarrior.x - enemyTower.x, 2) + Math.pow(convertedWarrior.y - enemyTower.y, 2));
			// Use traditional distance-based collision for converted warriors
			var collisionDetected = towerDistance < towerColliderRadius;
			if (collisionDetected && !convertedWarrior.isBeingDestroyed) {
				// Deal damage to tower first - always attack regardless of cooldown when touching tower
				convertedWarrior.attackTower();
				// Mark as being destroyed to prevent multiple collision detections
				convertedWarrior.isBeingDestroyed = true;
				// Remove from warriors array immediately
				var index = warriors.indexOf(convertedWarrior);
				if (index > -1) {
					warriors.splice(index, 1);
				}
				// Warrior self-destructs when touching the tower - immediate destruction
				convertedWarrior.destroy();
				return; // Exit update to prevent further execution after destruction
			}
			// Check if warrior is off-screen and destroy
			if (convertedWarrior.x < -500 || convertedWarrior.x > 4500 || convertedWarrior.y > 3500) {
				convertedWarrior.destroy();
				var index = warriors.indexOf(convertedWarrior);
				if (index > -1) {
					warriors.splice(index, 1);
				}
				return; // Exit update to prevent further execution
			}
			// Update health bar
			var healthPercent = convertedWarrior.health / convertedWarrior.maxHealth;
			convertedWarrior.healthBar.scaleX = healthPercent;
			convertedWarrior.healthBar.tint = healthPercent > 0.5 ? 0x00ff00 : healthPercent > 0.25 ? 0xffff00 : 0xff0000;
		}
	};
	// Attack function
	convertedWarrior.attack = function (target) {
		convertedWarrior.attackCooldown = convertedWarrior.baseCooldown;
		if (target === enemyTower) {
			convertedWarrior.attackTower();
		} else {
			target.takeDamage(convertedWarrior.damage);
		}
	};
	// Attack tower function
	convertedWarrior.attackTower = function () {
		convertedWarrior.attackCooldown = convertedWarrior.baseCooldown;
		enemyTowerHealth -= convertedWarrior.damage;
		// Play tower damage sound
		var towerSounds = ['sonido_torre_1', 'sonido_torre_2', 'sonido_torre_3', 'sonido_torre_4'];
		var randomIndex = Math.floor(Math.random() * towerSounds.length);
		var sound = LK.getSound(towerSounds[randomIndex]);
		sound.volume = soundValue;
		sound.play();
		if (enemyTowerHealth <= 0) {
			subir_nivel();
		}
		updateTowerHealthBars();
	};
	// Take damage function
	convertedWarrior.takeDamage = function (damage) {
		convertedWarrior.health -= damage;
		convertedWarrior.updateStatsDisplay();
		if (convertedWarrior.health <= 0) {
			convertedWarrior.isBeingDestroyed = true;
			var index = warriors.indexOf(convertedWarrior);
			if (index > -1) {
				warriors.splice(index, 1);
			}
			convertedWarrior.destroy();
		}
	};
	// Add to game and warriors array
	game.addChild(convertedWarrior);
	warriors.push(convertedWarrior);
	// Visual conversion effect
	tween(warriorGraphics, {
		tint: 0x00ff00,
		scaleX: -1.2,
		scaleY: 1.2
	}, {
		duration: 300,
		onFinish: function onFinish() {
			tween(warriorGraphics, {
				tint: 0xffffff,
				scaleX: -1.0,
				scaleY: 1.0
			}, {
				duration: 200
			});
		}
	});
}
function volterar(enemy) {
	console.log("volterar:", enemy.x, enemy.y);
	var enemyGraphics = enemy.children[0]; // Get the enemy graphics
	if (enemyGraphics) {
		// Check current mirror state and toggle
		if (enemyGraphics.scaleX > 0) {
			// Currently not mirrored, make it mirrored
			console.log("Enemy was not mirrored, now making it mirrored");
			enemyGraphics.scaleX = -Math.abs(enemyGraphics.scaleX);
		} else {
			// Currently mirrored, make it not mirrored
			console.log("Enemy was mirrored, now making it not mirrored");
			enemyGraphics.scaleX = Math.abs(enemyGraphics.scaleX);
		}
	}
}
function activateComicSystem() {
	// Only activate if we're at level 0
	if (nivel !== 0) {
		return;
	}
	// Set nivel to -1 for comic mode
	nivel = -1;
	levelText.setText('Nivel: ' + nivel);
	// Pause the game
	pausa = true;
	comicActive = true;
	// Make black background visible when comic is active
	fondoNegro.alpha = 1.0;
	currentComicIndex = 0;
	// Show first comic
	showCurrentComic();
}
function showCurrentComic() {
	// Only show comics if comic is active (nivel -1)
	if (!comicActive) {
		return;
	}
	// Update comic counter display
	/*numberComic.setText('Comic: ' + (currentComicIndex + 1) + '/' + maxComics);*/
	// Clear any existing comic images
	clearComicImages();
	if (currentComicIndex < maxComics) {
		// Detener sonido anterior si existe
		if (currentComicSound) {
			currentComicSound.stop();
		}
		if (currentSoundTimer) {
			LK.clearTimeout(currentSoundTimer);
		}
		// Play comic sound when showing each comic with looping
		var comicSoundName = 'comic' + (currentComicIndex + 1) + '_sound';
		var comicSound = LK.getSound(comicSoundName);
		if (comicSound && typeof comicSound.volume !== 'undefined') {
			// Configurar bucle manual con repetición cada 3 segundos
			var _loopComicSound = function loopComicSound() {
				if (currentComicSound && comicActive && currentComicIndex < maxComics) {
					currentComicSound.volume = soundValue;
					currentComicSound.play();
					currentSoundTimer = LK.setTimeout(_loopComicSound, 3000); // Repetir cada 3 segundos
				}
			}; // Iniciar el bucle después de 3 segundos
			comicSound.volume = soundValue;
			comicSound.play();
			// Guardar referencia del sonido actual
			currentComicSound = comicSound;
			currentSoundTimer = LK.setTimeout(_loopComicSound, 3000);
		}
		// Create current comic image
		var comicAssetName = 'comic' + (currentComicIndex + 1);
		var comicImage = LK.getAsset(comicAssetName, {
			anchorX: 0.0,
			anchorY: 0.0,
			x: 0,
			y: 0,
			width: 1450,
			height: 1932,
			alpha: 0
		});
		comicImage.isComicImage = true;
		// Add click handler to comic image
		comicImage.down = function (x, y, obj) {
			nextComic();
		};
		// Add to GUI layer (covers full screen) in front of everything
		LK.gui.addChild(comicImage);
		comicImages.push(comicImage);
		// Make comic visible with fade in effect using tween
		tween(comicImage, {
			alpha: 1.0
		}, {
			duration: 500,
			easing: tween.easeInOut
		});
	}
}
function nextComic() {
	currentComicIndex++;
	if (currentComicIndex >= maxComics) {
		// All comics shown, end comic system
		endComicSystem();
	} else {
		// Show next comic
		showCurrentComic();
	}
}
function clearComicImages() {
	// Detener sonido de comic actual cuando se limpian las imágenes
	if (currentComicSound) {
		currentComicSound.stop();
		currentComicSound = null;
	}
	if (currentSoundTimer) {
		LK.clearTimeout(currentSoundTimer);
		currentSoundTimer = null;
	}
	// Remove all existing comic images
	for (var i = comicImages.length - 1; i >= 0; i--) {
		var comicImg = comicImages[i];
		if (comicImg && comicImg.parent) {
			comicImg.destroy();
		}
		comicImages.splice(i, 1);
	}
}
function endComicSystem() {
	// Detener cualquier sonido de comic al terminar el sistema
	if (currentComicSound) {
		currentComicSound.stop();
		currentComicSound = null;
	}
	if (currentSoundTimer) {
		LK.clearTimeout(currentSoundTimer);
		currentSoundTimer = null;
	}
	// Clear comic images
	clearComicImages();
	// Hide comic counter
	/*numberComic.setText('Comic: 0/11');*/
	// Hide black background when comic ends
	fondoNegro.alpha = 0;
	// Advance to level 1
	nivel = 1;
	levelText.setText('Nivel: ' + nivel);
	// Update unlocking system BEFORE updating other systems
	updateLevelUnlocks();
	// Reset comic system
	comicActive = false;
	currentComicIndex = 0;
	// Unpause the game
	pausa = false;
	// Calculate new tower health for level 1
	var newTowerHealth = 10 * nivel;
	playerTowerHealth = newTowerHealth;
	enemyTowerHealth = newTowerHealth;
	updateTowerHealthBars();
	// Show completion message
	showCombinationMessage('¡COMIC COMPLETADO! Fuego desbloqueado');
	doblaje();
	musiclevel();
	if (nivel > nivel_llegado) {
		nivel_llegado = nivel;
	}
}
function resetGame() {
	// Reset comic system variables
	comicActive = false;
	currentComicIndex = 0;
	clearComicImages();
	// Reset all game variables to initial state
	warriors = [];
	enemies = [];
	meteoritos = [];
	esporas = [];
	globalFireModeActive = false;
	fireModeTimer = 0;
	playerTowerHealth = 10 * nivel; // Reset to level-appropriate health
	enemyTowerHealth = 10 * nivel; // Reset to level-appropriate health
	enemySpawnTimer = 0;
	isDragging = false;
	lastMouseX = 0;
	cameraX = 0;
	currentMana = 5;
	maxMana = 5;
	manaRegenTimer = 0;
	miniola_colision = false;
	currentCombination = [];
	combinationTimer = 0;
	combinationCooldown = 0;
	temporaryNoteCounter = 0;
	tiempoDeApocalipsis = 0;
	elementList = [];
	noteTimingIntervals = [];
	lastNoteTime = 0;
	isFirstNote = true;
	initialTouchX = 0;
	initialTouchY = 0;
	currentTouchX = 0;
	currentTouchY = 0;
	musicBeatThreshold = 0;
	lastBeatTime = 0;
	clouds = [];
	cloudSpawnTimer = 0;
	revelacionTimer = 0;
	i = 0;
	// Destroy all existing game objects
	for (var w = warriors.length - 1; w >= 0; w--) {
		var warrior = warriors[w];
		warrior.isBeingDestroyed = true;
		warrior.destroy();
		warriors.splice(w, 1);
	}
	for (var e = enemies.length - 1; e >= 0; e--) {
		var enemy = enemies[e];
		enemy.destroy();
		enemies.splice(e, 1);
	}
	for (var m = meteoritos.length - 1; m >= 0; m--) {
		var meteorito = meteoritos[m];
		meteorito.destroy();
		meteoritos.splice(m, 1);
	}
	for (var s = esporas.length - 1; s >= 0; s--) {
		var espora = esporas[s];
		espora.destroy();
		esporas.splice(s, 1);
	}
	for (var c = clouds.length - 1; c >= 0; c--) {
		var cloud = clouds[c];
		cloud.destroy();
		clouds.splice(c, 1);
	}
	// Reset towers to full health and scale
	updateTowerHealthBars();
	tween.stop(playerTower, {
		scaleX: true,
		scaleY: true
	});
	tween.stop(enemyTower, {
		scaleX: true,
		scaleY: true
	});
	tween(playerTower, {
		scaleX: 1.0,
		scaleY: 1.0,
		tint: 0xffffff
	}, {
		duration: 1000,
		easing: tween.easeInOut
	});
	tween(enemyTower, {
		scaleX: 1.0,
		scaleY: 1.0,
		tint: 0xffffff
	}, {
		duration: 1000,
		easing: tween.easeInOut
	});
	// Reset fire overlay
	tween(fireOverlay, {
		alpha: 0
	}, {
		duration: 500
	});
	// Reset ground texture
	changeGroundTexture('ground');
	// Reset clouds tint
	for (var c = 0; c < clouds.length; c++) {
		if (clouds[c] && clouds[c].children[0]) {
			tween(clouds[c].children[0], {
				tint: clouds[c].children[0].originalTint || 0xF0F0F0
			}, {
				duration: 500
			});
		}
	}
	// Reset camera position
	cameraX = 0;
	game.x = 0;
	// Reset apocalyptic notes
	ocultar_notas_apocalitica();
	// Reset mana display
	updateManaDisplay();
	// Create new meteorite combination
	crea_combinacion_meteorito();
	// Re-enable note buttons
	enableNoteButtons();
	// Show reset message
	showCombinationMessage('¡JUEGO REINICIADO!');
	// Pause game
	pausa = true;
	currentMana = maxMana;
	updateManaDisplay();
}
function musicaDelApocalipsis() {
	// Don't play apocalyptic music if game is paused or apocalyptic notes are not visible
	if (pausa || !isApocalypticNotesVisible) {
		return;
	}
	// Play the meteorite element list with 0.5s intervals between notes
	var combinationForMelody = elementList.slice(); // Create a copy of elementList
	// Create intervals array with 0.5s (500ms) between each note
	var intervalsForMelody = [];
	for (var i = 0; i < combinationForMelody.length; i++) {
		if (i === 0) {
			intervalsForMelody.push(0); // First note plays immediately
		} else {
			intervalsForMelody.push(500); // 0.5s = 500ms delay between notes
		}
	}
	// Play the melody sequence with the meteorite combination
	playMelodySequenceWithIntervals(combinationForMelody, intervalsForMelody);
	// Show apocalypse message
	showCombinationMessage('¡MÚSICA DEL APOCALIPSIS - MELODÍA DEL METEORITO!');
}
// Add reset button functionality to pause button with long press
var pauseButtonLongPressTimer = 0;
var pauseButtonPressed = false;
pauseButton.down = function (x, y, obj) {
	pauseButtonPressed = true;
	pauseButtonLongPressTimer = 0;
	// Start checking for long press
	var longPressCheck = LK.setInterval(function () {
		if (pauseButtonPressed) {
			pauseButtonLongPressTimer += 100; // Check every 100ms
			if (pauseButtonLongPressTimer >= 2000) {
				// 2 seconds = long press
				// Long press detected - reset game
				pauseButtonPressed = false;
				LK.clearInterval(longPressCheck);
				resetGame();
				return;
			}
		} else {
			LK.clearInterval(longPressCheck);
		}
	}, 100);
	// Play settings click sound
	LK.getSound('settings_click').stop(); // Stop any currently playing instance
	var pauseSound = LK.getSound('settings_click');
	pauseSound.volume = soundValue * 0.7; // Apply current soundValue with 70% modifier
	pauseSound.play();
	// Visual feedback with bounce effect
	tween(pauseButton, {
		scaleX: 0.85,
		scaleY: 0.85,
		alpha: 0.6,
		rotation: Math.PI * 0.1
	}, {
		duration: 150,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(pauseButton, {
				scaleX: 1.05,
				scaleY: 1.05,
				alpha: 0.9,
				rotation: 0
			}, {
				duration: 150,
				easing: tween.bounceOut,
				onFinish: function onFinish() {
					tween(pauseButton, {
						scaleX: 1.0,
						scaleY: 1.0,
						alpha: 0.8
					}, {
						duration: 100
					});
				}
			});
		}
	});
};
pauseButton.up = function (x, y, obj) {
	if (pauseButtonPressed && pauseButtonLongPressTimer < 2000) {
		// Short press - just toggle pause
		pausa = !pausa;
		// Update button text and appearance based on pause state
		if (pausa) {
			pauseButtonText.setText('||'); // Pause symbol
			pauseButton.tint = 0xff4444; // Red tint when paused
		} else {
			pauseButtonText.setText('▶'); // Play symbol
			pauseButton.tint = 0xffffff; // Green tint when playing
		}
	}
	pauseButtonPressed = false;
};
function musiclevel() {
	// Stop all music before starting new music
	LK.stopMusic();
	if (nivel == -1) {
		if (idioma) {
			LK.playMusic('music_menu_en', {
				volume: musicValue
			});
		} else {
			LK.playMusic('music_menu_es', {
				volume: musicValue
			});
		}
	} else if (nivel == 0) {
		LK.playMusic('musicId', {
			volume: musicValue
		});
	} else {
		// Select random music from available tracks
		var musicTracks = ['Music1', 'Music2', 'Music3', 'Music4', 'Music5', 'Music7', 'Music8'];
		var randomIndex = Math.floor(Math.random() * musicTracks.length);
		var selectedMusic = musicTracks[randomIndex];
		LK.playMusic(selectedMusic, {
			volume: musicValue
		});
	}
}
function updateLevelUnlocks() {
	// Reset unlocked systems
	unlockedElements = [];
	unlockedCombinations = [];
	isApocalypticNotesVisible = false;
	// Set max mana based on level
	if (nivel <= 0) {
		maxMana = 1;
	} else if (nivel == 1) {
		maxMana = 1;
		unlockedElements = ['fire'];
		unlockedCombinations = [1]; // Single combinations only
	} else if (nivel == 2) {
		maxMana = 2;
		unlockedElements = ['fire', 'water'];
		unlockedCombinations = [1];
	} else if (nivel == 3) {
		maxMana = 3;
		unlockedElements = ['fire', 'water', 'earth'];
		unlockedCombinations = [1];
	} else if (nivel == 4) {
		maxMana = 4;
		unlockedElements = ['fire', 'water', 'earth', 'wind'];
		unlockedCombinations = [1];
	} else if (nivel == 5) {
		maxMana = 5;
		unlockedElements = ['fire', 'water', 'earth', 'wind', 'light'];
		unlockedCombinations = [1];
	} else if (nivel == 6) {
		maxMana = 5;
		unlockedElements = ['fire', 'water', 'earth', 'wind', 'light'];
		unlockedCombinations = [1];
		isApocalypticNotesVisible = true;
	} else if (nivel == 7) {
		maxMana = 5;
		unlockedElements = ['fire', 'water', 'earth', 'wind', 'light'];
		unlockedCombinations = [1, 2]; // Single and double combinations
		isApocalypticNotesVisible = true;
	} else if (nivel >= 8 && nivel <= 11) {
		maxMana = 5;
		unlockedElements = ['fire', 'water', 'earth', 'wind', 'light'];
		unlockedCombinations = [1, 2];
		isApocalypticNotesVisible = true;
	} else if (nivel >= 12 && nivel <= 16) {
		maxMana = 5;
		unlockedElements = ['fire', 'water', 'earth', 'wind', 'light'];
		unlockedCombinations = [1, 2, 3]; // Single, double, and triple combinations
		isApocalypticNotesVisible = true;
	} else if (nivel >= 17 && nivel <= 21) {
		maxMana = 5;
		unlockedElements = ['fire', 'water', 'earth', 'wind', 'light'];
		unlockedCombinations = [1, 2, 3, 4]; // Single through quadruple combinations
		isApocalypticNotesVisible = true;
	} else {
		// Level 22 and above - everything unlocked
		maxMana = 5;
		unlockedElements = ['fire', 'water', 'earth', 'wind', 'light'];
		unlockedCombinations = [1, 2, 3, 4, 5]; // All combinations including quintuple
		isApocalypticNotesVisible = true;
	}
	// Ensure current mana doesn't exceed new max
	currentMana = Math.min(currentMana, maxMana);
	// Update visual elements
	updateNoteVisibility();
	updateApocalypticNotesVisibility();
	updateManaDisplay();
}
function updateNoteVisibility() {
	// Update note button functionality based on unlocked elements
	for (var i = 0; i < notes.length; i++) {
		var note = notes[i];
		var element = note.element;
		if (unlockedElements.indexOf(element) === -1) {
			// Element not unlocked - disable but keep original graphics
			note.alpha = 0.5;
			note.isDisabled = true;
			// Create silver note overlay if it doesn't exist
			if (!note.silverNote) {
				var silverNote = LK.getAsset('nota_plateada', {
					anchorX: 0.5,
					anchorY: 0.5,
					scaleX: 0.4,
					scaleY: 0.4
				});
				silverNote.x = note.x;
				silverNote.y = note.y;
				silverNote.alpha = 0.8;
				LK.gui.topLeft.addChild(silverNote);
				note.silverNote = silverNote;
			}
		} else {
			// Element unlocked - enable note and destroy silver note
			note.alpha = 1.0;
			note.isDisabled = false;
			// Destroy silver note overlay if it exists
			if (note.silverNote) {
				note.silverNote.destroy();
				note.silverNote = null;
			}
		}
	}
}
function updateApocalypticNotesVisibility() {
	// Show/hide apocalyptic notes based on level
	for (var i = 0; i < casillas.length; i++) {
		if (casillas[i]) {
			casillas[i].visible = isApocalypticNotesVisible;
		}
	}
}
function destroy_mapa() {
	// Destroy all warriors
	for (var i = warriors.length - 1; i >= 0; i--) {
		var warrior = warriors[i];
		warrior.isBeingDestroyed = true;
		warrior.destroy();
		warriors.splice(i, 1);
	}
	// Destroy all enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		enemy.destroy();
		enemies.splice(i, 1);
	}
	// Set mana to maximum
	currentMana = maxMana;
	updateManaDisplay();
}
function activar_menu() {
	// Make f_m image visible
	fmImage.visible = true;
	// Make jugar button visible
	jugarButton.visible = true;
}
; ===================================================================
--- original.js
+++ change.js
@@ -5382,8 +5382,16 @@
 	// Only reset when a new note is pressed
 	// Update display only when actually clearing intervals
 }
 function showCombinationMessage(message) {
+	// Remove from game layer if it exists there
+	if (combinationMessageText.parent === game) {
+		game.removeChild(combinationMessageText);
+	}
+	// Add to GUI layer to ensure it's always on top
+	if (combinationMessageText.parent !== LK.gui) {
+		LK.gui.addChild(combinationMessageText);
+	}
 	combinationMessageText.setText(message);
 	combinationMessageText.alpha = 1.0;
 	// Fade out message after 2 seconds
 	tween(combinationMessageText, {
@@ -5440,9 +5448,9 @@
 	initialTouchY = y;
 	currentTouchX = x;
 	currentTouchY = y;
 	if (touchDebugText && typeof touchDebugText.setText === 'function') {
-		touchDebugText.setText(/*'Touch Info: Initial(' + Math.round(x) + ',' + Math.round(y) + ') Current(' + Math.round(x) + ',' + Math.round(y) + ')'*/);
+		touchDebugText.setText(/*'Touch Info: Initial(' + Math.round(x) + ',' + Math.round(y) + ') Current(' + Math.round(x) + ',' + Math.round(y) + ')'*/'');
 	}
 	if (obj.event && obj.event.button === 2) {
 		// Right mouse button
 		isDragging = true;
@@ -5520,9 +5528,9 @@
 	currentTouchX = x;
 	currentTouchY = y;
 	// Update debug text with both initial and current positions
 	if (touchDebugText && typeof touchDebugText.setText === 'function') {
-		touchDebugText.setText('GUI Move - Initial(' + Math.round(initialTouchX) + ',' + Math.round(initialTouchY) + ') Current(' + Math.round(currentTouchX) + ',' + Math.round(currentTouchY) + ')');
+		touchDebugText.setText(/*'GUI Move - Initial(' + Math.round(initialTouchX) + ',' + Math.round(initialTouchY) + ') Current(' + Math.round(currentTouchX) + ',' + Math.round(currentTouchY) + ')'*/'');
 	}
 };
 // Cloud system for background decoration
 var clouds = [];
:quality(85)/https://cdn.frvr.ai/685b3af231ce512dc65a7a0a.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, ademas sera un El lagarto azul de Gorgona humanoide. Va tener una armadura roja con efetos de llamitas pequeñas. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b3da331ce512dc65a7a24.png%3F3) 
 Genérame una Rana de dardo venenosa guerra azteca con eso patrones estilo pixelar, con una apariencia maligna. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b4fc631ce512dc65a7aeb.png%3F3) 
 geerame una esmeralda pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b54d031ce512dc65a7b39.png%3F3) 
 Generame una boton con dentro de forma de una nota musical con efectos de agua.. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b550931ce512dc65a7b47.png%3F3) 
 Generame una boton con dentro de forma de una nota musical con efectos de fuego .. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b554031ce512dc65a7b51.png%3F3) 
 Generame una boton con dentro de forma de una nota musical con efectos de energia. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b556f31ce512dc65a7b5d.png%3F3) 
 Generame una boton con dentro de forma de una nota musical con efectos de viento. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b55a231ce512dc65a7b6b.png%3F3) 
 Generame una boton con dentro de forma de una nota musical con efectos de tierra. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b563431ce512dc65a7b7d.png%3F3) 
 Generame un guerrero voaldor Colibrí esmeralda del Chiribiquete estilo azteca con patrones, estilo pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b571d31ce512dc65a7ba1.png%3F3) 
 Generame un guerrero meduza cone fectos de agua, que cura como mago, estilo pixelar, ambeintado a lo azteca. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b579c31ce512dc65a7bae.png%3F3) 
 Generame un jaguar guerrero con efectos de energia estilo magico, pixelar, con ambientacion azteca. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b5d2331ce512dc65a7bec.png%3F3) 
 Proyectil agua pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b669431ce512dc65a7c50.png%3F3) 
 Luz oscura particulas, moradas. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b66d131ce512dc65a7c66.png%3F3) 
 Particula de luz. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b6a5931ce512dc65a7cc3.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/685b6a9331ce512dc65a7ccf.png%3F3) 
 Generame una piedras corrupta
:quality(85)/https://cdn.frvr.ai/685b763831ce512dc65a7d06.png%3F3) 
 Genérame una MONO TITÍ guerra azteca con eso patrones estilo pixelar, con una apariencia maligna.. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b768e31ce512dc65a7d12.png%3F3) 
 Genérame un Tucan guerra azteca con eso patrones estilo pixelar, con una apariencia maligna. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685b7b3f31ce512dc65a7d2f.png%3F3) 
 Un signo de más en verde. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685c9e26ac7a3749965a467b.png%3F3) 
 Un proyectil de electricidad pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685ca093ac7a3749965a46d2.png%3F3) 
 Generame una explosion de este proyectil de forma circular
:quality(85)/https://cdn.frvr.ai/685ca1ceac7a3749965a46e1.png%3F3) 
 Creame una nubes pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685ca59fac7a3749965a4700.png%3F3) 
 Una tuerca pixelar como boton. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685d8f4929ca41c35dd69ba7.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, ademas sera un Tortuga de ciénaga colombiana humanoide. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685d914f29ca41c35dd69bc5.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/685d91da29ca41c35dd69bcd.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, ademas sera una iguana humanoide, con efectos de fuego. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685d929529ca41c35dd69bd8.png%3F3) 
 Agregale efectos de fuego pero en un fondo de alto contraste, mejor dicho solo pono mas rojo y llmas en la espada
:quality(85)/https://cdn.frvr.ai/685da50129ca41c35dd69c34.png%3F3) 
 Agregale lava y fuego a esta textrua
:quality(85)/https://cdn.frvr.ai/685daae029ca41c35dd69c6d.png%3F3) 
 Creame una explosion de fuego pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685dad7229ca41c35dd69c92.png%3F3) 
 agregale un poquito de ver y azul sin perder la identidad de l aimagen, solo cuadrar colores
:quality(85)/https://cdn.frvr.ai/685daec729ca41c35dd69ccc.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, además será una Pez loro, con efectos de AGUA. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685daf0829ca41c35dd69cd8.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, además será una Cangrejo violinista, con efectos de AGUA. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685daf9a29ca41c35dd69cfc.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, además será una Delfin Rosado con efectos de AGUA. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685dbc2b29ca41c35dd69e04.png%3F3) 
 Generame unm meteorito pixelar elemental con todos los elementos. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685df9f564208b06a890966a.png%3F3) 
 particulas rosadas, de poder. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685dfa2164208b06a8909673.png%3F3) 
 Haz este candando con los 5 ewlementos, fuego tierra, agua, aire, energia
:quality(85)/https://cdn.frvr.ai/685e053d5e0b136f4792374f.png%3F3) 
 Creame un cielo pixelar hermoso, sin sol ni nubes, ni montañas, nia rboles. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685e127933ba9e358f9b7086.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/685e1cfb5e0b136f47923849.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/685e1d525e0b136f4792385a.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/685e1d8d5e0b136f47923866.png%3F3) 
 Generame una montañas pixelar en fondo blanco. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685e1ddc5e0b136f47923870.png%3F3) 
 Generame una montañas de selva pixelar en fondo blanco, cercanas. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685e1fd65e0b136f47923881.png%3F3) 
 Generame un muro pixelar de tierra isometrico con aptornes aztecas. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685e21615e0b136f479238a1.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, además será un animal Tapir, con efectos de tierra, cargando un gran escudo o muro.. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685e21b25e0b136f479238b2.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/685e21f05e0b136f479238bb.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, además será un animal Anaconda verde, con efectos de tierra, cargando un gran escudo o muro.. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685e22605e0b136f479238c8.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, además será un animal manati con efectos de tierra, cargando un enrome muro. gigante. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685e22ce5e0b136f479238d4.png%3F3) 
 uan flor pixelar para plantar, sin matera sola una hermosa flor. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685f41160f689da525d14a58.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, además será un Cóndor de los Andes, unidad voladora con alas, con efectos de viento. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685f42470f689da525d14a7b.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, además será una Mariposa alas de vidrio (Greta oto), unidad voladora con alas, con efectos de viento. Tiene que ser un animal.. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685f432ec2e2c8be1fbd3619.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, además será Murciélago frugívoro, unidad voladora con alas, con efectos de viento. Tiene que ser un animal.. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685f43e7c2e2c8be1fbd362c.png%3F3) 
 Generame un guerrero azteca con patrones, estilo pixelar, además será Tucán toco , unidad voladora con alas, con efectos de viento. Tiene que ser un animal.. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685f4904de96845b6a629dbc.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/685f57d9138d5714bb5b0597.png%3F3) 
 Gotas de agua pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685f6145138d5714bb5b05c5.png%3F3) 
 Genrame un muro con mas detalle que se vea superior es decir un nivel mas fuerte.
:quality(85)/https://cdn.frvr.ai/685f7c635e0b136f47924ba0.png%3F3) 
 Generame una particula de espora pixela rt. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685f83855e0b136f47924c13.png%3F3) 
 z de sueño pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/686023a59573cd17dfbc2aba.png%3F3) 
 Generame una lanza pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68603e7e502808a78c0b0699.png%3F3) 
 Creame un tornado pixelar en un fondo azul, para elimianrlo despues. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/686060e6a98151715020d386.png%3F3) 
 Hazme el rayo de color amarillo
:quality(85)/https://cdn.frvr.ai/6860a4ba8033ff08ed757c48.png%3F3) 
 Creame un boton de este personaje extilo pixelar cuadrado
:quality(85)/https://cdn.frvr.ai/6860a5cbe029fd8094c52aa9.png%3F3) 
 POnlo trizte el perosnaje y gris el boton
:quality(85)/https://cdn.frvr.ai/6860b34c2add77fdfe57ae86.png%3F3) 
 Jugar
:quality(85)/https://cdn.frvr.ai/6861ac94d76d012a89eac914.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6862155d335426a7d85f3ad5.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/68621783335426a7d85f3ad7.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6862ec72335426a7d85f3ba2.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/68632a54c6e68f494b83fba3.png%3F3) 
 Pon una casa
:quality(85)/https://cdn.frvr.ai/68632aacc6e68f494b83fbb0.png%3F3) 
 deja todo naranaja
:quality(85)/https://cdn.frvr.ai/6865a4596f71f6a969428721.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6865da1a8235fab16f0b69dd.png%3F3) 
 Genérame una Jaguar guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad cuerpo a cuerpo. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865da4c8235fab16f0b69e9.png%3F3) 
 Genérame una Oso de Anteojos guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad cuerpo a cuerpo. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865dac98235fab16f0b69fe.png%3F3) 
 Genérame una Pecari de collar guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad cuerpo a cuerpo. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865db038235fab16f0b6a09.png%3F3) 
 Genérame una Puma guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad cuerpo a cuerpo. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865db388235fab16f0b6a15.png%3F3) 
 Genérame una Tayra guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad cuerpo a cuerpo. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865db808235fab16f0b6a20.png%3F3) 
 Genérame una Nutria Neotropical guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad cuerpo a cuerpo. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865dbbc8235fab16f0b6a2d.png%3F3) 
 Genérame una Caiman llanero guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad cuerpo a cuerpo. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865dbf38235fab16f0b6a38.png%3F3) 
 Genérame una Capibara guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad cuerpo a cuerpo. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865dc498235fab16f0b6a43.png%3F3) 
 Genérame una Zorro Cangrejero guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad cuerpo a cuerpo. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865dd718235fab16f0b6a57.png%3F3) 
 Genérame una Demonio de Tasmnia guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. POderes, super rojo y rabioso, como un ejfe final. Animal. No tiene arams solo una gran y poderosa mordida. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865df608235fab16f0b6a6f.png%3F3) 
 Genérame una olibrí Esmeralda Andina guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad aerea con alas. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865df928235fab16f0b6a7a.png%3F3) 
 Genérame una Zopilote Rey guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad aerea con alas. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865dfc28235fab16f0b6a86.png%3F3) 
 Genérame una Paujil guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad aerea con alas. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865dff38235fab16f0b6a8f.png%3F3) 
 Genérame una Halcon Murcielago guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad aerea con alas. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e02a8235fab16f0b6a9d.png%3F3) 
 Genérame una Buho de anteojos guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad aerea con alas. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e05f8235fab16f0b6aa5.png%3F3) 
 Genérame una Mariposa monarca guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad aerea con alas. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e0928235fab16f0b6ab3.png%3F3) 
 Genérame una Chicharra guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad aerea con alas. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e0bf8235fab16f0b6abe.png%3F3) 
 Genérame una paloma guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad aerea con alas. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e2a48235fab16f0b6ac9.png%3F3) 
 Genérame una Rana de Cristal guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad a distancia, con un arco o cerbatana. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e2f98235fab16f0b6ad4.png%3F3) 
 Genérame una Iguana Verde guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad a distancia, con un arco o cerbatana. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e33f8235fab16f0b6ae2.png%3F3) 
 Genérame una Boa de arcoiris guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad a distancia, con un arco o cerbatana. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e3b28235fab16f0b6af7.png%3F3) 
 Genérame una Ciempies gigante amazonico guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad a distancia, con un arco o cerbatana. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e42e8235fab16f0b6b0e.png%3F3) 
 Genérame una Escorpion Colombiano guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad a distancia, con un arco o cerbatana. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e4558235fab16f0b6b18.png%3F3) 
 Genérame una Araña guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad a distancia, con un arco o cerbatana. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e4858235fab16f0b6b26.png%3F3) 
 Genérame una Pez leon guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad a distancia, con cerbatana. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e4bd8235fab16f0b6b31.png%3F3) 
 Genérame una Serpiente coral guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad a distancia, con cerbatana. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e4fe8235fab16f0b6b39.png%3F3) 
 Genérame una Rana de dardo venenosa guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad a distancia, con cerbatana. Animal. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6865e67b8235fab16f0b6b47.png%3F3) 
 Genérame un hipopotamo guerrero azteca con eso patrones, estilo pixelar, con una apariencia maligna, ojos rojos, rabioso. Unidad cuerpo a cuerpo. Animal.. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68670251fb9e054f6797e5dc.png%3F3) 
 Flecha maligna, de color rojo, pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68672a3f2905e57457509d49.png%3F3) 
 Luna llena blanca, pixelar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68672a752905e57457509d51.png%3F3) 
 sol pixelart. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68673ce299b57bda22f8ca8d.png%3F3) 
 Un cielo noche pixelar 16:04 con estrellas. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6868bb0b298ae6a067237776.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6868bfaa9a1c69e29baa9f76.png%3F3) 
 Hazme un boton pixelar azteca, que diga Fin. In-Game asset. 2d. High contrast. No shadows
Nota_Fire
Sound effect
tower_damage
Sound effect
combat
Sound effect
enemy_death
Sound effect
combatir_1
Sound effect
Music
Music
combatir_2
Sound effect
combatir_3
Sound effect
combatir_4
Sound effect
attack
Sound effect
Nota_Water
Sound effect
Nota_Earth
Sound effect
Nota_Wind
Sound effect
Nota_Light
Sound effect
sonido_torre_2
Sound effect
sonido_torre_3
Sound effect
sonido_torre_4
Sound effect
sonido_torre_1
Sound effect
sonido_proyectil_agua_1
Sound effect
sonido_proyectil_agua_2
Sound effect
sonido_proyectil_agua_3
Sound effect
sonido_proyectil_agua_4
Sound effect
sonido_proyectil_viento_1
Sound effect
sonido_proyectil_viento_2
Sound effect
sonido_proyectil_viento_3
Sound effect
sonido_proyectil_viento_4
Sound effect
sonido_proyectil_energia_1
Sound effect
sonido_proyectil_energia_2
Sound effect
sonido_proyectil_energia_3
Sound effect
sonido_proyectil_energia_4
Sound effect
settings_click
Sound effect
burn_sound
Sound effect
musicId
Music
Level_1_en
Sound effect
Level_1_es
Sound effect
Level_2_en
Sound effect
Level_3_en
Sound effect
Level_4_en
Sound effect
Level_5_en
Sound effect
Level_6_en
Sound effect
Level_7_en
Sound effect
Level_9_en
Sound effect
Level_10_en
Sound effect
Level_11_en
Sound effect
Level_12_en
Sound effect
Level_13_en
Sound effect
Level_14_en
Sound effect
Level_15_en
Sound effect
Level_16_en
Sound effect
Level_17_en
Sound effect
Level_18_en
Sound effect
Level_19_en
Sound effect
Level_20_en
Sound effect
Level_21_en
Sound effect
Level_22_en
Sound effect
Level_23_en
Sound effect
Level_24_en
Sound effect
Level_25_en
Sound effect
Level_26_en
Sound effect
Level_2_es
Sound effect
Level_3_es
Sound effect
Level_4_es
Sound effect
Level_5_es
Sound effect
Level_6_es
Sound effect
Level_7_es
Sound effect
Level_8_es
Sound effect
Level_9_es
Sound effect
Level_10_es
Sound effect
Level_11_es
Sound effect
Level_12_es
Sound effect
Level_13_es
Sound effect
Level_14_es
Sound effect
Level_15_es
Sound effect
Level_16_es
Sound effect
Level_17_es
Sound effect
Level_18_es
Sound effect
Level_19_es
Sound effect
Level_20_es
Sound effect
Level_21_es
Sound effect
Level_22_es
Sound effect
Level_23_es
Sound effect
Level_24_es
Sound effect
Level_25_es
Sound effect
Level_26_es
Sound effect
Level_8_en
Sound effect
ganar
Sound effect
comic1_sound
Sound effect
comic2_sound
Sound effect
comic3_sound
Sound effect
comic4_sound
Sound effect
comic5_sound
Sound effect
comic6_sound
Sound effect
comic7_sound
Sound effect
comic8_sound
Sound effect
comic9_sound
Sound effect
comic10_sound
Sound effect
comic11_sound
Sound effect
music_menu_en
Music
music_menu_es
Music
Music2
Music
Music3
Music
Music4
Music
Music5
Music
Music8
Music
Music7
Music
Nota_Earth2
Sound effect
Nota_Fire2
Sound effect
Nota_Light2
Sound effect
Nota_Water2
Sound effect
Nota_Wind2
Sound effect
explosion_meteorito
Sound effect
muerte_guerrero
Sound effect
MusicVictoria
Music