User prompt
los enemigos van muy rapido has que sean mas lentos
User prompt
cuando se termina el tutorial se muestra la configuracion por unos segundos, quita eso
User prompt
cuando en el tutorial le doy a omitir se muestra el menu principal y despues se muestra el juego
User prompt
haz que las pantallas del tutorial no avancen hasta que se presione la pantalla
User prompt
el texto en el tutorial no entra en la panatalla
User prompt
haz que el juego se pause cuando el tutorial esta pasando
User prompt
arreglalo
User prompt
arreglalo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
cuando entro al tutorial no pasa nada
User prompt
crea un tutorial ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
haz los numeros de damage mas visibles ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
haz que los efectos de impacto sean mas satifactorios ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
haz que el campeon no salga antes del enemigo 40
User prompt
haz que el campeon no salga antes del enemigo 40
User prompt
haz que el ogro berserker no salga antes del enemigo 30
User prompt
haz que el berseker no salga antes del enemigo 30
User prompt
haz que el eskeleto de elite no salga antes del enemigo 20
User prompt
haz que el campeon no pueda salir antes del enemigo 30
User prompt
haz que en los primeros 20 enemigos no salgan enemigos especiales
User prompt
haz que cuando se active el combo solo diga combo
User prompt
ahora cuando elimines 3 enemigos del mismo camino el siguiente proyectil hara doble damage
User prompt
cuando se eliminen 3 enemigos de un mismo camino de manera consecutiva haz el siguiente tiro tenga doble de damage
User prompt
haz que cada vez que se muestre el menu de mejoras los enemigos llegeun un poco mas lento
User prompt
muesta un indicador para el cooldown en los hechizos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'vibrate')' in or related to this line: 'if (navigator.vibrate) {' Line Number: 356
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.bobOffset = Math.random() * Math.PI * 2;
	self.initialY = 0;
	self.update = function () {
		if (self.initialY === 0) {
			self.initialY = self.y;
		}
		// Only do bobbing animation and collection if not animating to coin counter
		if (!self.isAnimating) {
			// Bobbing animation
			self.y = self.initialY + Math.sin(LK.ticks * 0.1 + self.bobOffset) * 10;
			// Check collection by knight
			if (knight && self.intersects(knight)) {
				self.collect();
			}
		}
	};
	self.collect = function () {
		LK.getSound('coinCollect').play();
		LK.setScore(LK.getScore() + 5);
		coinCounter++;
		coinText.setText('Coins: ' + coinCounter);
		// Update medal statistics
		if (!storage.totalCoins) storage.totalCoins = 0;
		storage.totalCoins++;
		// Remove from coins array
		for (var i = coins.length - 1; i >= 0; i--) {
			if (coins[i] === self) {
				coins.splice(i, 1);
				break;
			}
		}
		self.destroy();
	};
	return self;
});
// Game arrays to track objects
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	// Animation system for skeleton
	self.currentFrame = 1;
	self.animationTimer = 0;
	self.animationSpeed = 15; // Change frame every 15 ticks (250ms at 60fps)
	self.animationState = 'walking'; // walking, attacking, dying, idle
	// Create all skeleton graphics frames and store them
	self.skeletonFrames = [];
	for (var i = 1; i <= 4; i++) {
		var frameGraphics = self.attachAsset('esqueleto' + i, {
			anchorX: 0.5,
			anchorY: 1.0,
			scaleX: 2.0,
			scaleY: 2.0
		});
		frameGraphics.visible = i === 1; // Only show first frame initially
		self.skeletonFrames.push(frameGraphics);
	}
	// Create invisible hitbox with double size
	var hitbox = self.attachAsset('esqueleto1', {
		anchorX: 0.5,
		anchorY: 1.0,
		scaleX: 4,
		scaleY: 4
	});
	hitbox.alpha = 0; // Make hitbox invisible
	self.health = 1;
	self.maxHealth = 1;
	self.speed = 7;
	// Note: health, maxHealth and speed will be overridden by difficulty system
	self.lastX = 0;
	self.frozen = false;
	self.frozenTimer = 0;
	self.update = function () {
		// Skip all movement and collision if enemy is dying
		if (self.isDying) {
			return;
		}
		// Reduce speed when upgrade menu is visible
		var speedMultiplier = 1.0;
		if (upgradeMenu && upgradeMenu.visible) {
			speedMultiplier = 0.3; // 70% speed reduction
		}
		// Animation system - cycle through skeleton frames based on state
		self.animationTimer++;
		var frameSpeed = self.animationSpeed;
		if (self.animationState === 'attacking') {
			frameSpeed = 8; // Faster animation for attacking
		} else if (self.animationState === 'dying') {
			frameSpeed = 20; // Slower animation for dying
		} else if (self.animationState === 'idle') {
			frameSpeed = 25; // Very slow animation for idle
		}
		if (self.animationTimer >= frameSpeed) {
			self.animationTimer = 0;
			// Hide current frame
			self.skeletonFrames[self.currentFrame - 1].visible = false;
			// Move to next frame based on animation state
			if (self.animationState === 'walking') {
				self.currentFrame++;
				if (self.currentFrame > 4) {
					self.currentFrame = 1;
				}
			} else if (self.animationState === 'attacking') {
				// Cycle through frames 2-4 for attacking
				self.currentFrame++;
				if (self.currentFrame > 4) {
					self.currentFrame = 2;
				}
			} else if (self.animationState === 'dying') {
				// Play frames 3-4 once for dying
				if (self.currentFrame < 4) {
					self.currentFrame++;
				}
			} else if (self.animationState === 'idle') {
				// Cycle between frames 1-2 for idle
				self.currentFrame = self.currentFrame === 1 ? 2 : 1;
			}
			// Show new frame
			self.skeletonFrames[self.currentFrame - 1].visible = true;
		}
		// Progressive speed increase - increase speed by 50% over 10 seconds
		if (!self.speedTweenStarted) {
			self.speedTweenStarted = true;
			var targetSpeed = self.speed * 2.5; // Increase speed by 150%
			tween(self, {
				speed: targetSpeed
			}, {
				duration: 10000,
				// 10 seconds
				easing: tween.easeOut
			});
		}
		// Handle frozen state
		if (self.frozen) {
			self.frozenTimer--;
			if (self.frozenTimer <= 0) {
				self.frozen = false;
			}
			return; // Skip movement when frozen
		}
		// Always move directly toward the wizard to ensure enemies reach the player
		if (wizard) {
			// Calculate direction from enemy to wizard
			var dx = wizard.x - self.x;
			var dy = wizard.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				// Normalize direction and apply speed with upgrade menu speed reduction
				self.x += dx / distance * self.speed * speedMultiplier;
				self.y += dy / distance * self.speed * speedMultiplier;
			}
			// Face toward the wizard - flip horizontally based on wizard position
			if (dx < 0) {
				// Wizard is to the left - flip to face left
				for (var frameIdx = 0; frameIdx < self.skeletonFrames.length; frameIdx++) {
					self.skeletonFrames[frameIdx].scaleX = -2.0; // Flip to face left
				}
			} else {
				// Wizard is to the right - face right
				for (var frameIdx = 0; frameIdx < self.skeletonFrames.length; frameIdx++) {
					self.skeletonFrames[frameIdx].scaleX = 2.0; // Normal orientation to face right
				}
			}
		} else {
			// Fallback: move down if wizard doesn't exist
			self.y += self.speed * speedMultiplier;
		}
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		// Change animation state to attacking when hit
		self.animationState = 'attacking';
		// Flash red when hit
		LK.effects.flashObject(self, 0xFF0000, 200);
		// Create damage indicator
		var damageText = new Text2('-' + damage, {
			size: 80,
			fill: 0xFF4444,
			font: "monospace"
		});
		damageText.anchor.set(0.5, 0.5);
		damageText.x = self.x + (Math.random() - 0.5) * 60;
		damageText.y = self.y - 40;
		game.addChild(damageText);
		// Animate damage text floating up and fading out
		tween(damageText, {
			y: damageText.y - 120,
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 1000,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				damageText.destroy();
			}
		});
		// Create main impact effect
		var impactEffect = game.addChild(LK.getAsset('projectileGlow', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: self.x,
			y: self.y,
			scaleX: 0.5,
			scaleY: 0.5
		}));
		impactEffect.tint = 0xFFFFFF;
		impactEffect.alpha = 0.9;
		// Animate impact effect
		tween(impactEffect, {
			scaleX: 2.5,
			scaleY: 2.5,
			alpha: 0
		}, {
			duration: 300,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				impactEffect.destroy();
			}
		});
		// Reduced particle effects for better performance
		for (var particleIdx = 0; particleIdx < 3; particleIdx++) {
			var particle = game.addChild(LK.getAsset('spell', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: self.x,
				y: self.y,
				scaleX: 0.5,
				scaleY: 0.5
			}));
			particle.tint = 0x44aaff;
			particle.alpha = 0.8;
			// Random particle direction
			var angle = particleIdx / 3 * Math.PI * 2;
			var speed = 30;
			var targetX = self.x + Math.cos(angle) * speed;
			var targetY = self.y + Math.sin(angle) * speed;
			// Animate particle
			tween(particle, {
				x: targetX,
				y: targetY,
				scaleX: 0.1,
				scaleY: 0.1,
				alpha: 0
			}, {
				duration: 300,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					particle.destroy();
				}
			});
		}
		// Return to walking animation after brief attacking animation
		tween({}, {}, {
			duration: 300,
			onFinish: function onFinish() {
				if (self.animationState === 'attacking') {
					self.animationState = 'walking';
				}
			}
		});
		// Check if enemy should die based on health
		if (self.health <= 0) {
			self.die();
		}
	};
	self.down = function (x, y, obj) {
		// Add haptic vibration when enemy is tapped
		if (typeof LK.vibrate === 'function') {
			LK.vibrate(50); // Short 50ms vibration
		}
		// Set this enemy as the selected target
		selectedEnemy = self;
		// Visual feedback for selection
		LK.effects.flashObject(self, 0xFFFF00, 500); // Yellow flash to indicate selection
		// Create projectile from wizard to enemy when enemy is tapped
		if (wizard && projectiles.length < 10) {
			// Limit projectiles to prevent spam
			var projectile = game.addChild(new Projectile());
			projectile.x = wizard.x;
			projectile.y = wizard.y;
			// Calculate direction from wizard to enemy
			var dx = self.x - wizard.x;
			var dy = self.y - wizard.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				projectile.direction.x = dx / distance;
				projectile.direction.y = dy / distance;
			}
			projectile.targetEnemy = self; // Set the target for this projectile
			projectiles.push(projectile);
			LK.getSound('spellCast').play();
		}
	};
	self.die = function () {
		// Change animation state to dying
		self.animationState = 'dying';
		self.currentFrame = 3; // Start dying animation from frame 3
		// Play pain sound when enemy dies
		LK.getSound('painSound').play();
		// Add screen shake for enemy death
		var shakeIntensity = 8;
		var originalX = game.x;
		var originalY = game.y;
		tween(game, {
			x: originalX + shakeIntensity,
			y: originalY + shakeIntensity * 0.5
		}, {
			duration: 30,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(game, {
					x: originalX - shakeIntensity * 0.6,
					y: originalY - shakeIntensity * 0.3
				}, {
					duration: 25,
					easing: tween.easeInOut,
					onFinish: function onFinish() {
						tween(game, {
							x: originalX,
							y: originalY
						}, {
							duration: 20,
							easing: tween.easeIn
						});
					}
				});
			}
		});
		// Start death animation sequence
		self.isDying = true;
		// Animate enemy death with fade out and scale down
		tween(self, {
			alpha: 0,
			scaleX: 0.3,
			scaleY: 0.3,
			rotation: Math.PI * 0.5
		}, {
			duration: 800,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// After death animation completes, execute all death logic
				// Drop coin
				var coin = game.addChild(new Coin());
				coin.x = self.x;
				coin.y = self.y - 50;
				coin.isAnimating = true;
				coins.push(coin);
				// Animate coin moving toward coin counter
				var coinTargetX = 120 + coinText.width / 2;
				var coinTargetY = 90 + coinText.height / 2;
				tween(coin, {
					x: coinTargetX,
					y: coinTargetY,
					scaleX: 0.5,
					scaleY: 0.5
				}, {
					duration: 1000,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Apply difficulty-specific coin rewards
						var selectedDifficulty = storage.difficulty || 'NORMAL';
						var coinReward = 1;
						if (selectedDifficulty === 'FACIL') {
							coinReward = Math.floor(1.5); // 50% more coins (rounded down)
						} else if (selectedDifficulty === 'DIFICIL') {
							coinReward = Math.max(1, Math.floor(0.75)); // 25% fewer coins (minimum 1)
						}
						// Increment coin counter after animation
						coinCounter += coinReward;
						coinText.setText('Coins: ' + coinCounter);
						// Easy mode healing chance
						if (selectedDifficulty === 'FACIL' && Math.random() < 0.15) {
							wizard.health = Math.min(wizard.health + 5, wizard.maxHealth);
							updateHealthBar();
							// Visual feedback for healing
							LK.effects.flashObject(wizard, 0x00FF00, 200);
						}
						// Remove coin from array and destroy
						for (var i = coins.length - 1; i >= 0; i--) {
							if (coins[i] === coin) {
								coins.splice(i, 1);
								break;
							}
						}
						coin.destroy();
					}
				});
				// Increment enemy kill counter
				enemyKillCounter++;
				killCountText.setText('Puntuacion: ' + enemyKillCounter);
				// Update path combo system
				if (self.pathIndex !== undefined) {
					pathKillCounts[self.pathIndex]++;
					// Check if we've killed 3 enemies from this path
					if (pathKillCounts[self.pathIndex] >= 3) {
						// Reset the count for this path
						pathKillCounts[self.pathIndex] = 0;
						// Enable double damage for next projectile
						nextProjectileDoubleDamage = true;
						// Visual feedback for combo achievement
						LK.effects.flashScreen(0xFFD700, 500); // Golden flash
						// Create combo text indicator
						var comboText = new Text2('combo', {
							size: 120,
							fill: 0xFFD700,
							font: "monospace"
						});
						comboText.anchor.set(0.5, 0.5);
						comboText.x = 2048 / 2;
						comboText.y = 2732 / 2 - 200;
						game.addChild(comboText);
						// Animate combo text
						tween(comboText, {
							scaleX: 1.5,
							scaleY: 1.5,
							alpha: 0
						}, {
							duration: 1500,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								comboText.destroy();
							}
						});
					}
				}
				// Update medal statistics
				if (!storage.totalKills) storage.totalKills = 0;
				storage.totalKills++;
				// Add experience to wizard
				wizard.gainExperience(25);
				// Life drain upgrade - 20% chance to give 20 HP
				if (wizard.lifeDrainLevel && wizard.lifeDrainLevel > 0) {
					var drainChance = Math.random();
					if (drainChance < 0.20) {
						// 20% chance
						wizard.health = Math.min(wizard.health + 20, wizard.maxHealth); // Always give 20 HP
						updateHealthBar();
						// Visual feedback for life drain
						LK.effects.flashObject(wizard, 0x00FF00, 300);
					}
				}
				// Clear selected enemy if this was the target
				if (selectedEnemy === self) {
					selectedEnemy = null;
				}
				// Remove from enemies array
				for (var i = enemies.length - 1; i >= 0; i--) {
					if (enemies[i] === self) {
						enemies.splice(i, 1);
						break;
					}
				}
				self.destroy();
				LK.setScore(LK.getScore() + 10);
			}
		});
	};
	return self;
});
var EnergyBeam = Container.expand(function () {
	var self = Container.call(this);
	// Create beam visual using projectile glow
	var beamGraphics = self.attachAsset('projectileGlow', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.0,
		scaleY: 1.0
	});
	beamGraphics.tint = 0x00ffff; // Cyan color
	beamGraphics.alpha = 0.9;
	self.speed = 60;
	self.direction = {
		x: 0,
		y: 0
	};
	self.targetEnemy = null;
	self.lastIntersecting = false;
	self.update = function () {
		// Move toward target
		self.x += self.direction.x * self.speed;
		self.y += self.direction.y * self.speed;
		// Rotate beam to point toward movement direction
		var angle = Math.atan2(self.direction.y, self.direction.x);
		beamGraphics.rotation = angle;
		// Remove if off screen
		if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
			self.destroy();
			return;
		}
		// Check collision with target enemy (but never with wizard)
		if (self.targetEnemy && self.targetEnemy.parent && self.targetEnemy !== wizard) {
			var currentIntersecting = self.intersects(self.targetEnemy);
			if (!self.lastIntersecting && currentIntersecting) {
				// Hit the target enemy
				// Calculate damage based on spell power upgrade
				var damage = 100;
				if (wizard && wizard.spellPowerLevel && wizard.spellPowerLevel > 0) {
					// Check if target is an ogre and we're before enemy 35
					if (self.targetEnemy && self.targetEnemy.ogreFrames && enemyKillCounter < 35) {
						// Always kill ogres in one hit until enemy 35
						damage = self.targetEnemy.health + 1; // Ensure one-hit kill
					} else {
						damage = 200; // Double damage when spell power is active
					}
				}
				self.targetEnemy.takeDamage(damage);
				self.destroy();
				return;
			}
			self.lastIntersecting = currentIntersecting;
		} else {
			// Target destroyed, remove beam
			self.destroy();
		}
	};
	return self;
});
var EnergyOrb = Container.expand(function () {
	var self = Container.call(this);
	// Create energy sphere visual
	var sphereGraphics = self.attachAsset('energySphere', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 1.5
	});
	// Add glowing effect
	sphereGraphics.alpha = 0.8;
	self.attackTimer = 0;
	self.attackInterval = 180; // 3 seconds at 60fps
	self.orbitalAngle = 0;
	self.orbitalRadius = 120;
	self.update = function () {
		// Pause energy orb when upgrade menu is visible
		if (upgradeMenu && upgradeMenu.visible) {
			return;
		}
		// Keep sphere at wizard's position (stationary relative to wizard)
		if (wizard) {
			self.x = wizard.x + 140; // Position further to the right side of wizard
			self.y = wizard.y - 20; // Position slightly lower relative to wizard
		}
		// Pulsing glow effect
		var pulse = 1 + Math.sin(LK.ticks * 0.2) * 0.3;
		sphereGraphics.scaleX = 1.5 * pulse;
		sphereGraphics.scaleY = 1.5 * pulse;
		// Attack timer - keep original interval regardless of upgrades
		self.attackTimer++;
		if (self.attackTimer >= 180) {
			// Fixed at 3 seconds
			self.attackTimer = 0;
			self.attackClosestEnemy();
		}
	};
	self.attackClosestEnemy = function () {
		var closestEnemy = null;
		var closestDistance = Infinity;
		// Check all enemy types for closest one
		var allEnemies = enemies.concat(ogres).concat(knights).concat(miniBosses);
		for (var i = 0; i < allEnemies.length; i++) {
			var enemy = allEnemies[i];
			var dx = enemy.x - self.x;
			var dy = enemy.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < closestDistance) {
				closestDistance = distance;
				closestEnemy = enemy;
			}
		}
		// Attack closest enemy if found
		if (closestEnemy) {
			// Create energy beam projectile
			var energyBeam = game.addChild(new EnergyBeam());
			energyBeam.x = self.x;
			energyBeam.y = self.y;
			energyBeam.targetEnemy = closestEnemy;
			// Calculate direction to target
			var dx = closestEnemy.x - self.x;
			var dy = closestEnemy.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				energyBeam.direction.x = dx / distance;
				energyBeam.direction.y = dy / distance;
			}
			// Flash effect on sphere when attacking
			tween(sphereGraphics, {
				scaleX: 2.5,
				scaleY: 2.5,
				alpha: 1.0
			}, {
				duration: 200,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					tween(sphereGraphics, {
						scaleX: 1.5,
						scaleY: 1.5,
						alpha: 0.8
					}, {
						duration: 200,
						easing: tween.easeIn
					});
				}
			});
			LK.getSound('spellCast').play();
		}
	};
	return self;
});
var FireBall = Container.expand(function () {
	var self = Container.call(this);
	// Create fire ball visual using projectile glow with fire colors
	var fireBallGraphics = self.attachAsset('projectileGlow', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.5,
		scaleY: 1.5
	});
	fireBallGraphics.tint = 0xFF4500; // Orange-red fire color
	fireBallGraphics.alpha = 0.9;
	self.speed = 40;
	self.direction = {
		x: 0,
		y: 0
	};
	self.lastIntersecting = {};
	self.update = function () {
		// Move fire ball
		self.x += self.direction.x * self.speed;
		self.y += self.direction.y * self.speed;
		// Add fire flickering effect
		var flicker = 1 + Math.sin(LK.ticks * 0.4) * 0.3;
		fireBallGraphics.scaleX = 1.5 * flicker;
		fireBallGraphics.scaleY = 1.5 * flicker;
		// Rotate fire ball
		fireBallGraphics.rotation += 0.2;
		// Remove if off screen
		if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
			self.destroy();
			return;
		}
		// Check collision with all enemy types (but never with wizard)
		var allEnemies = enemies.concat(ogres).concat(knights).concat(miniBosses);
		for (var i = 0; i < allEnemies.length; i++) {
			var enemy = allEnemies[i];
			// Skip collision check with wizard
			if (enemy === wizard) {
				continue;
			}
			if (!self.lastIntersecting[i]) {
				self.lastIntersecting[i] = false;
			}
			var currentIntersecting = self.intersects(enemy);
			if (!self.lastIntersecting[i] && currentIntersecting) {
				// Hit enemy - deal fire damage
				var damage = 150; // High damage for fire ball
				enemy.takeDamage(damage);
				// Create fire explosion effect
				LK.effects.flashObject(enemy, 0xFF4500, 400);
				// Create additional fire visual effect
				var fireEffect = game.addChild(LK.getAsset('projectileGlow', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: enemy.x,
					y: enemy.y,
					scaleX: 3,
					scaleY: 3
				}));
				fireEffect.tint = 0xFF6600;
				fireEffect.alpha = 0.8;
				// Animate fire effect
				tween(fireEffect, {
					scaleX: 6,
					scaleY: 6,
					alpha: 0
				}, {
					duration: 600,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						fireEffect.destroy();
					}
				});
				// Reduced fire trail particles for better performance
				for (var fireIdx = 0; fireIdx < 6; fireIdx++) {
					var fireParticle = game.addChild(LK.getAsset('projectileGlow', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: enemy.x,
						y: enemy.y,
						scaleX: 0.6,
						scaleY: 0.6
					}));
					fireParticle.tint = 0xFF4500;
					fireParticle.alpha = 0.9;
					// Random fire particle direction
					var fireAngle = fireIdx / 6 * Math.PI * 2;
					var fireSpeed = 50;
					var fireTargetX = enemy.x + Math.cos(fireAngle) * fireSpeed;
					var fireTargetY = enemy.y + Math.sin(fireAngle) * fireSpeed;
					// Animate fire particle
					tween(fireParticle, {
						x: fireTargetX,
						y: fireTargetY,
						scaleX: 0.1,
						scaleY: 0.1,
						alpha: 0
					}, {
						duration: 400,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							fireParticle.destroy();
						}
					});
				}
				self.destroy();
				return;
			}
			self.lastIntersecting[i] = currentIntersecting;
		}
	};
	return self;
});
var GameMenu = Container.expand(function () {
	var self = Container.call(this);
	// Menu background image instead of cave background
	var menuBg = self.attachAsset('menuBackground', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 2732 / 2,
		scaleX: 4.0,
		scaleY: 4.0
	});
	menuBg.alpha = 1.0;
	// Title text
	var titleText = new Text2('WIZARD DEFENDER', {
		size: 150,
		fill: 0xFFD700,
		font: "monospace"
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 2048 / 2;
	titleText.y = 800;
	self.addChild(titleText);
	// Instructions text
	var instructionsText = new Text2('TAP PATHS TO CAST SPELLS\nDEFEND YOUR CASTLE!', {
		size: 80,
		fill: 0xFFFFFF,
		font: "monospace"
	});
	instructionsText.anchor.set(0.5, 0.5);
	instructionsText.x = 2048 / 2;
	instructionsText.y = 1200;
	self.addChild(instructionsText);
	// Start button
	var startButton = self.attachAsset('wizard1', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 1500,
		scaleX: 2,
		scaleY: 2
	});
	var startButtonText = new Text2('START GAME', {
		size: 100,
		fill: 0x000000,
		font: "monospace"
	});
	startButtonText.anchor.set(0.5, 0.5);
	startButtonText.x = 2048 / 2;
	startButtonText.y = 1600;
	self.addChild(startButtonText);
	// Configuration button
	var configButton = self.attachAsset('pathSelector', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 1800,
		scaleX: 4,
		scaleY: 2
	});
	configButton.tint = 0x4169E1;
	var configButtonText = new Text2('CONFIGURACION', {
		size: 80,
		fill: 0xFFFFFF,
		font: "monospace"
	});
	configButtonText.anchor.set(0.5, 0.5);
	configButtonText.x = 2048 / 2;
	configButtonText.y = 1800;
	self.addChild(configButtonText);
	// Shop button
	var shopButton = self.attachAsset('pathSelector', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 2000,
		scaleX: 4,
		scaleY: 2
	});
	shopButton.tint = 0xFF6B35;
	var shopButtonText = new Text2('TIENDA', {
		size: 80,
		fill: 0xFFFFFF,
		font: "monospace"
	});
	shopButtonText.anchor.set(0.5, 0.5);
	shopButtonText.x = 2048 / 2;
	shopButtonText.y = 2000;
	self.addChild(shopButtonText);
	// Medals button
	var medalsButton = self.attachAsset('pathSelector', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 2200,
		scaleX: 4,
		scaleY: 2
	});
	medalsButton.tint = 0x9B59B6;
	var medalsButtonText = new Text2('MEDALLAS', {
		size: 80,
		fill: 0xFFFFFF,
		font: "monospace"
	});
	medalsButtonText.anchor.set(0.5, 0.5);
	medalsButtonText.x = 2048 / 2;
	medalsButtonText.y = 2200;
	self.addChild(medalsButtonText);
	// Button interaction
	self.down = function (x, y, obj) {
		// Handle configuration menu interactions
		if (self.configMode) {
			// Music volume adjustment
			if (y >= 1150 && y <= 1250) {
				var currentMusicVolume = storage.musicVolume || 0.7;
				var newMusicVolume = Math.min(1.0, currentMusicVolume + 0.1);
				if (newMusicVolume > 1.0) newMusicVolume = 0.0;
				storage.musicVolume = newMusicVolume;
				self.musicVolumeText.setText('VOLUMEN MUSICA: ' + Math.round(newMusicVolume * 100) + '%');
				return;
			}
			// Sound volume adjustment
			if (y >= 1350 && y <= 1450) {
				var currentSoundVolume = storage.soundVolume || 1.0;
				var newSoundVolume = Math.min(1.0, currentSoundVolume + 0.1);
				if (newSoundVolume > 1.0) newSoundVolume = 0.0;
				storage.soundVolume = newSoundVolume;
				self.soundVolumeText.setText('VOLUMEN SONIDO: ' + Math.round(newSoundVolume * 100) + '%');
				return;
			}
			// Difficulty adjustment
			if (y >= 1550 && y <= 1650) {
				var currentDifficulty = storage.difficulty || 'NORMAL';
				var difficulties = ['FACIL', 'NORMAL', 'DIFICIL'];
				var currentIndex = difficulties.indexOf(currentDifficulty);
				var newIndex = (currentIndex + 1) % difficulties.length;
				var newDifficulty = difficulties[newIndex];
				storage.difficulty = newDifficulty;
				self.difficultyText.setText('DIFICULTAD: ' + newDifficulty);
				return;
			}
			// Back button
			if (y >= 1950 && y <= 2050) {
				self.hideConfigMenu();
				return;
			}
			// Block all other interactions when config menu is active
			return;
		}
		// Handle shop menu interactions
		if (self.shopMode) {
			// Shop item purchase buttons
			for (var i = 0; i < 3; i++) {
				var itemY = 1100 + i * 200;
				if (y >= itemY - 50 && y <= itemY + 50 && x >= 2048 / 2 + 200 && x <= 2048 / 2 + 400) {
					// Purchase item logic
					var shopItems = [{
						name: 'POCION SALUD',
						cost: 10
					}, {
						name: 'ESCUDO MAGICO',
						cost: 15
					}, {
						name: 'ESPADA MALDITA',
						cost: 20
					}];
					var item = shopItems[i];
					if (coinCounter >= item.cost) {
						coinCounter -= item.cost;
						// Apply item effect based on type
						if (i === 0) {
							// Health potion
							if (wizard) {
								wizard.health = Math.min(wizard.health + 50, wizard.maxHealth);
								updateHealthBar();
							}
						} else if (i === 1) {
							// Magic shield
							if (wizard) {
								wizard.shieldActive = true;
								wizard.maxShieldHits = 3;
								wizard.currentShieldHits = 0;
							}
						} else if (i === 2) {
							// Cursed sword - temporary damage boost
							if (wizard) {
								wizard.tempDamageBoost = true;
								wizard.tempDamageTimer = 1800; // 30 seconds at 60fps
							}
						}
						LK.effects.flashScreen(0x00FF00, 300);
					} else {
						LK.effects.flashScreen(0xFF0000, 300);
					}
					return;
				}
			}
			// Shop back button
			if (y >= 1950 && y <= 2050) {
				self.hideShop();
				return;
			}
			// Block all other interactions when shop menu is active
			return;
		}
		// Check if configuration button was clicked
		if (y >= 1700 && y <= 1900 && x >= 2048 / 2 - 200 && x <= 2048 / 2 + 200) {
			// Show configuration menu
			self.showConfigMenu();
		} else if (y >= 1900 && y <= 2100 && x >= 2048 / 2 - 200 && x <= 2048 / 2 + 200) {
			// Show shop menu
			self.showShop();
		} else if (y >= 2100 && y <= 2300 && x >= 2048 / 2 - 200 && x <= 2048 / 2 + 200) {
			// Show medals menu
			if (prestigeMedals) {
				prestigeMedals.showMedals();
			}
		} else if (y >= 1450 && y <= 1650) {
			// Start the game by hiding menu
			self.startGame();
		}
	};
	self.showConfigMenu = function () {
		// Create configuration overlay
		if (!self.configOverlay) {
			self.configOverlay = self.addChild(LK.getAsset('startMenuBackground', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: 2048 / 2,
				y: 2732 / 2,
				scaleX: 1.0,
				scaleY: 1.0
			}));
			self.configOverlay.alpha = 1.0;
			self.configOverlay.tint = 0x000000;
			// Config title
			var configTitle = new Text2('CONFIGURACION', {
				size: 120,
				fill: 0xFFD700,
				font: "monospace"
			});
			configTitle.anchor.set(0.5, 0.5);
			configTitle.x = 2048 / 2;
			configTitle.y = 800;
			self.addChild(configTitle);
			self.configTitle = configTitle;
			// Music volume setting
			var musicVolumeText = new Text2('VOLUMEN MUSICA: ' + Math.round((storage.musicVolume || 0.7) * 100) + '%', {
				size: 80,
				fill: 0xFFFFFF,
				font: "monospace"
			});
			musicVolumeText.anchor.set(0.5, 0.5);
			musicVolumeText.x = 2048 / 2;
			musicVolumeText.y = 1200;
			self.addChild(musicVolumeText);
			self.musicVolumeText = musicVolumeText;
			// Sound volume setting
			var soundVolumeText = new Text2('VOLUMEN SONIDO: ' + Math.round((storage.soundVolume || 1.0) * 100) + '%', {
				size: 80,
				fill: 0xFFFFFF,
				font: "monospace"
			});
			soundVolumeText.anchor.set(0.5, 0.5);
			soundVolumeText.x = 2048 / 2;
			soundVolumeText.y = 1400;
			self.addChild(soundVolumeText);
			self.soundVolumeText = soundVolumeText;
			// Difficulty setting
			var difficultyText = new Text2('DIFICULTAD: ' + (storage.difficulty || 'NORMAL'), {
				size: 80,
				fill: 0xFFFFFF,
				font: "monospace"
			});
			difficultyText.anchor.set(0.5, 0.5);
			difficultyText.x = 2048 / 2;
			difficultyText.y = 1600;
			self.addChild(difficultyText);
			self.difficultyText = difficultyText;
			// Back button
			var backButton = self.attachAsset('coin', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: 2048 / 2,
				y: 2000,
				scaleX: 2,
				scaleY: 2
			});
			backButton.tint = 0x00FF00;
			self.backButton = backButton;
			var backText = new Text2('VOLVER', {
				size: 80,
				fill: 0xFFFFFF,
				font: "monospace"
			});
			backText.anchor.set(0.5, 0.5);
			backText.x = 2048 / 2;
			backText.y = 2000;
			self.addChild(backText);
			self.backText = backText;
		}
		self.configOverlay.visible = true;
		self.configMode = true;
	};
	self.hideConfigMenu = function () {
		if (self.configOverlay) {
			self.configOverlay.destroy();
			self.configOverlay = null;
		}
		// Remove all configuration text elements
		if (self.musicVolumeText) {
			self.musicVolumeText.destroy();
			self.musicVolumeText = null;
		}
		if (self.soundVolumeText) {
			self.soundVolumeText.destroy();
			self.soundVolumeText = null;
		}
		if (self.difficultyText) {
			self.difficultyText.destroy();
			self.difficultyText = null;
		}
		// Remove back button elements
		if (self.backButton) {
			self.backButton.destroy();
			self.backButton = null;
		}
		if (self.backText) {
			self.backText.destroy();
			self.backText = null;
		}
		// Remove configuration title
		if (self.configTitle) {
			self.configTitle.destroy();
			self.configTitle = null;
		}
		// Remove all configuration children that were added
		for (var i = self.children.length - 1; i >= 0; i--) {
			var child = self.children[i];
			// Remove config-related elements (title, texts, buttons created in showConfigMenu)
			if (child.setText && child.text && (child.text.includes('CONFIGURACION') || child.text.includes('VOLUMEN') || child.text.includes('DIFICULTAD') || child.text.includes('VOLVER'))) {
				child.destroy();
			}
		}
		self.configMode = false;
		// Reset to show main menu elements
		self.visible = true;
	};
	self.showShop = function () {
		// Create shop overlay
		if (!self.shopOverlay) {
			self.shopOverlay = self.addChild(LK.getAsset('startMenuBackground', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: 2048 / 2,
				y: 2732 / 2,
				scaleX: 1.0,
				scaleY: 1.0
			}));
			self.shopOverlay.alpha = 1.0;
			self.shopOverlay.tint = 0x000033;
			// Shop title
			var shopTitle = new Text2('TIENDA', {
				size: 120,
				fill: 0xFFD700,
				font: "monospace"
			});
			shopTitle.anchor.set(0.5, 0.5);
			shopTitle.x = 2048 / 2;
			shopTitle.y = 800;
			self.addChild(shopTitle);
			self.shopTitle = shopTitle;
			// Shop items
			var shopItems = [{
				name: 'POCION SALUD',
				description: 'Restaura 50 HP',
				cost: 10,
				icon: 'energySphere'
			}, {
				name: 'ESCUDO MAGICO',
				description: 'Bloquea 3 ataques',
				cost: 15,
				icon: 'shield'
			}, {
				name: 'ESPADA MALDITA',
				description: 'Daño x2 por 30s',
				cost: 20,
				icon: 'spell'
			}];
			// Initialize shop elements arrays if not exists
			if (!self.shopIcons) self.shopIcons = [];
			if (!self.shopTexts) self.shopTexts = [];
			if (!self.shopBuyButtons) self.shopBuyButtons = [];
			if (!self.shopBuyTexts) self.shopBuyTexts = [];
			// Display shop items
			for (var i = 0; i < shopItems.length; i++) {
				var item = shopItems[i];
				var yPos = 1100 + i * 200;
				// Item icon
				var itemIcon = self.attachAsset(item.icon, {
					anchorX: 0.5,
					anchorY: 0.5,
					x: 2048 / 2 - 300,
					y: yPos,
					scaleX: 2,
					scaleY: 2
				});
				itemIcon.tint = 0xFFD700;
				self.shopIcons.push(itemIcon);
				// Item text
				var itemText = new Text2(item.name + '\n' + item.description + '\nCosto: ' + item.cost + ' monedas', {
					size: 60,
					fill: 0xFFFFFF,
					font: "monospace"
				});
				itemText.anchor.set(0, 0.5);
				itemText.x = 2048 / 2 - 200;
				itemText.y = yPos;
				self.addChild(itemText);
				self.shopTexts.push(itemText);
				// Buy button
				var buyButton = self.attachAsset('coin', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: 2048 / 2 + 300,
					y: yPos,
					scaleX: 2,
					scaleY: 2
				});
				buyButton.tint = 0x00FF00;
				buyButton.itemIndex = i;
				self.shopBuyButtons.push(buyButton);
				var buyText = new Text2('COMPRAR', {
					size: 50,
					fill: 0xFFFFFF,
					font: "monospace"
				});
				buyText.anchor.set(0.5, 0.5);
				buyText.x = 2048 / 2 + 300;
				buyText.y = yPos;
				self.addChild(buyText);
				self.shopBuyTexts.push(buyText);
			}
			// Back button
			var shopBackButton = self.attachAsset('coin', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: 2048 / 2,
				y: 2000,
				scaleX: 2,
				scaleY: 2
			});
			shopBackButton.tint = 0x00FF00;
			self.shopBackButton = shopBackButton;
			var shopBackText = new Text2('VOLVER', {
				size: 80,
				fill: 0xFFFFFF,
				font: "monospace"
			});
			shopBackText.anchor.set(0.5, 0.5);
			shopBackText.x = 2048 / 2;
			shopBackText.y = 2000;
			self.addChild(shopBackText);
			self.shopBackText = shopBackText;
		}
		self.shopOverlay.visible = true;
		self.shopMode = true;
	};
	self.hideShop = function () {
		if (self.shopOverlay) {
			self.shopOverlay.destroy();
			self.shopOverlay = null;
		}
		// Remove shop title
		if (self.shopTitle) {
			self.shopTitle.destroy();
			self.shopTitle = null;
		}
		// Remove shop back button elements
		if (self.shopBackButton) {
			self.shopBackButton.destroy();
			self.shopBackButton = null;
		}
		if (self.shopBackText) {
			self.shopBackText.destroy();
			self.shopBackText = null;
		}
		// Remove all shop icons
		if (self.shopIcons) {
			for (var i = 0; i < self.shopIcons.length; i++) {
				if (self.shopIcons[i]) {
					self.shopIcons[i].destroy();
				}
			}
			self.shopIcons = [];
		}
		// Remove all shop texts
		if (self.shopTexts) {
			for (var i = 0; i < self.shopTexts.length; i++) {
				if (self.shopTexts[i]) {
					self.shopTexts[i].destroy();
				}
			}
			self.shopTexts = [];
		}
		// Remove all shop buy buttons
		if (self.shopBuyButtons) {
			for (var i = 0; i < self.shopBuyButtons.length; i++) {
				if (self.shopBuyButtons[i]) {
					self.shopBuyButtons[i].destroy();
				}
			}
			self.shopBuyButtons = [];
		}
		// Remove all shop buy texts
		if (self.shopBuyTexts) {
			for (var i = 0; i < self.shopBuyTexts.length; i++) {
				if (self.shopBuyTexts[i]) {
					self.shopBuyTexts[i].destroy();
				}
			}
			self.shopBuyTexts = [];
		}
		// Remove all shop children that were added
		for (var i = self.children.length - 1; i >= 0; i--) {
			var child = self.children[i];
			// Remove shop-related elements
			if (child.setText && child.text && (child.text.includes('TIENDA') || child.text.includes('POCION') || child.text.includes('ESCUDO') || child.text.includes('ESPADA') || child.text.includes('COMPRAR'))) {
				child.destroy();
			}
		}
		self.shopMode = false;
		// Reset to show main menu elements
		self.visible = true;
	};
	self.startGame = function () {
		// Hide menu and start game
		self.visible = false;
		gameStarted = true;
		// Show cave background when game starts
		if (backgroundMap) {
			backgroundMap.visible = true;
		}
		// Show all game elements
		wizard.visible = true;
		for (var i = 0; i < paths.length; i++) {
			paths[i].visible = true;
		}
		// Show all stone path segments and make them visible
		for (var i = 0; i < game.children.length; i++) {
			var child = game.children[i];
			if (child.pathIndex !== undefined && child !== paths[child.pathIndex]) {
				child.visible = true;
				// Check if it's a stone path segment or path number
				if (child.alpha !== undefined && child.setText === undefined) {
					child.alpha = 0; // Keep stone paths invisible
				}
			}
		}
		coinText.visible = true;
		killCountText.visible = true;
		tapText.visible = true;
		healthBarBg.visible = true;
		healthBar.visible = true;
		healthText.visible = true;
		// Start medieval music with user's volume setting
		var musicVolume = storage.musicVolume || 0.7;
		LK.playMusic('medievalTheme', {
			volume: musicVolume,
			fade: {
				start: 0,
				end: musicVolume,
				duration: 2000
			}
		});
	};
	return self;
});
var Knight = Container.expand(function () {
	var self = Container.call(this);
	// Animation system for knight
	self.currentFrame = 1;
	self.animationTimer = 0;
	self.animationSpeed = 22; // Change frame every 22 ticks (367ms at 60fps)
	self.animationState = 'walking'; // walking, attacking, dying, idle
	// Create all knight graphics frames and store them
	self.knightFrames = [];
	for (var i = 1; i <= 4; i++) {
		var frameGraphics = self.attachAsset('knight' + i, {
			anchorX: 0.5,
			anchorY: 1.0,
			scaleX: 2.0,
			scaleY: 2.0
		});
		frameGraphics.visible = i === 1; // Only show first frame initially
		self.knightFrames.push(frameGraphics);
	}
	// Create invisible hitbox with double size
	var hitbox = self.attachAsset('knight1', {
		anchorX: 0.5,
		anchorY: 1.0,
		scaleX: 4,
		scaleY: 4
	});
	hitbox.alpha = 0; // Make hitbox invisible
	self.health = 3;
	self.maxHealth = 3;
	self.speed = 7;
	// Note: health, maxHealth and speed will be overridden by difficulty system
	self.lastX = 0;
	self.frozen = false;
	self.frozenTimer = 0;
	self.update = function () {
		// Skip all movement and collision if knight is dying
		if (self.isDying) {
			return;
		}
		// Reduce speed when upgrade menu is visible
		var speedMultiplier = 1.0;
		if (upgradeMenu && upgradeMenu.visible) {
			speedMultiplier = 0.3; // 70% speed reduction
		}
		// Animation system - cycle through knight frames based on state
		self.animationTimer++;
		var frameSpeed = self.animationSpeed;
		if (self.animationState === 'attacking') {
			frameSpeed = 12; // Faster animation for attacking
		} else if (self.animationState === 'dying') {
			frameSpeed = 28; // Slower animation for dying
		} else if (self.animationState === 'idle') {
			frameSpeed = 35; // Very slow animation for idle
		}
		if (self.animationTimer >= frameSpeed) {
			self.animationTimer = 0;
			// Hide current frame
			self.knightFrames[self.currentFrame - 1].visible = false;
			// Move to next frame based on animation state
			if (self.animationState === 'walking') {
				self.currentFrame++;
				if (self.currentFrame > 4) {
					self.currentFrame = 1;
				}
			} else if (self.animationState === 'attacking') {
				// Cycle through frames 2-4 for attacking
				self.currentFrame++;
				if (self.currentFrame > 4) {
					self.currentFrame = 2;
				}
			} else if (self.animationState === 'dying') {
				// Play frames 3-4 once for dying
				if (self.currentFrame < 4) {
					self.currentFrame++;
				}
			} else if (self.animationState === 'idle') {
				// Cycle between frames 1-2 for idle
				self.currentFrame = self.currentFrame === 1 ? 2 : 1;
			}
			// Show new frame
			self.knightFrames[self.currentFrame - 1].visible = true;
		}
		// Progressive speed increase - increase speed by 150% over 10 seconds
		if (!self.speedTweenStarted) {
			self.speedTweenStarted = true;
			var targetSpeed = self.speed * 2.5; // Increase speed by 150%
			tween(self, {
				speed: targetSpeed
			}, {
				duration: 10000,
				// 10 seconds
				easing: tween.easeOut
			});
		}
		// Handle frozen state
		if (self.frozen) {
			self.frozenTimer--;
			if (self.frozenTimer <= 0) {
				self.frozen = false;
			}
			return; // Skip movement when frozen
		}
		// Always move directly toward the wizard to ensure knights reach the player
		if (wizard) {
			// Calculate direction from knight to wizard
			var dx = wizard.x - self.x;
			var dy = wizard.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				// Normalize direction and apply speed with upgrade menu speed reduction
				self.x += dx / distance * self.speed * speedMultiplier;
				self.y += dy / distance * self.speed * speedMultiplier;
			}
			// Face toward the wizard - flip horizontally based on wizard position
			if (dx < 0) {
				// Wizard is to the left - flip to face left
				for (var frameIdx = 0; frameIdx < self.knightFrames.length; frameIdx++) {
					self.knightFrames[frameIdx].scaleX = -2.0; // Flip to face left
				}
			} else {
				// Wizard is to the right - face right
				for (var frameIdx = 0; frameIdx < self.knightFrames.length; frameIdx++) {
					self.knightFrames[frameIdx].scaleX = 2.0; // Normal orientation to face right
				}
			}
		} else {
			// Fallback: move down if wizard doesn't exist
			self.y += self.speed * speedMultiplier;
		}
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		// Change animation state to attacking when hit
		self.animationState = 'attacking';
		// Flash red when hit
		LK.effects.flashObject(self, 0xFF0000, 200);
		// Create damage indicator
		var damageText = new Text2('-' + damage, {
			size: 100,
			fill: 0xFFD700,
			font: "monospace"
		});
		damageText.anchor.set(0.5, 0.5);
		damageText.x = self.x + (Math.random() - 0.5) * 80;
		damageText.y = self.y - 60;
		game.addChild(damageText);
		// Animate damage text floating up and fading out
		tween(damageText, {
			y: damageText.y - 160,
			alpha: 0,
			scaleX: 1.4,
			scaleY: 1.4
		}, {
			duration: 1400,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				damageText.destroy();
			}
		});
		// Create impact effect
		var impactEffect = game.addChild(LK.getAsset('projectileGlow', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: self.x,
			y: self.y,
			scaleX: 0.8,
			scaleY: 0.8
		}));
		impactEffect.tint = 0xFFD700;
		impactEffect.alpha = 0.9;
		// Animate impact effect with sparks
		tween(impactEffect, {
			scaleX: 3.0,
			scaleY: 3.0,
			alpha: 0
		}, {
			duration: 400,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				impactEffect.destroy();
			}
		});
		// Return to walking animation after brief attacking animation
		tween({}, {}, {
			duration: 500,
			onFinish: function onFinish() {
				if (self.animationState === 'attacking') {
					self.animationState = 'walking';
				}
			}
		});
		// Check if knight should die based on health
		if (self.health <= 0) {
			self.die();
		}
	};
	self.down = function (x, y, obj) {
		// Add haptic vibration when knight is tapped
		if (typeof LK.vibrate === 'function') {
			LK.vibrate(100); // Strong 100ms vibration for armored enemy
		}
		// Set this knight as the selected target
		selectedEnemy = self;
		// Visual feedback for selection
		LK.effects.flashObject(self, 0xFFFF00, 500); // Yellow flash to indicate selection
		// Create projectile from wizard to knight when knight is tapped
		if (wizard && projectiles.length < 10) {
			// Limit projectiles to prevent spam
			var projectile = game.addChild(new Projectile());
			projectile.x = wizard.x;
			projectile.y = wizard.y;
			// Calculate direction from wizard to knight
			var dx = self.x - wizard.x;
			var dy = self.y - wizard.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				projectile.direction.x = dx / distance;
				projectile.direction.y = dy / distance;
			}
			projectile.targetEnemy = self; // Set the target for this projectile
			projectiles.push(projectile);
			LK.getSound('spellCast').play();
		}
	};
	self.die = function () {
		// Change animation state to dying
		self.animationState = 'dying';
		self.currentFrame = 3; // Start dying animation from frame 3
		// Play pain sound when knight dies
		LK.getSound('painSound').play();
		// Start death animation sequence
		self.isDying = true;
		// Animate knight death with dramatic fall effect
		tween(self, {
			alpha: 0,
			scaleX: 0.2,
			scaleY: 0.2,
			rotation: Math.PI * 0.8,
			y: self.y + 50
		}, {
			duration: 1000,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// After death animation completes, execute all death logic
				// Drop coin
				var coin = game.addChild(new Coin());
				coin.x = self.x;
				coin.y = self.y - 50;
				coin.isAnimating = true;
				coins.push(coin);
				// Animate coin moving toward coin counter
				var coinTargetX = 120 + coinText.width / 2;
				var coinTargetY = 90 + coinText.height / 2;
				tween(coin, {
					x: coinTargetX,
					y: coinTargetY,
					scaleX: 0.5,
					scaleY: 0.5
				}, {
					duration: 1000,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Apply difficulty-specific coin rewards
						var selectedDifficulty = storage.difficulty || 'NORMAL';
						var coinReward = 1;
						if (selectedDifficulty === 'FACIL') {
							coinReward = Math.floor(1.5); // 50% more coins (rounded down)
						} else if (selectedDifficulty === 'DIFICIL') {
							coinReward = Math.max(1, Math.floor(0.75)); // 25% fewer coins (minimum 1)
						}
						// Increment coin counter after animation
						coinCounter += coinReward;
						coinText.setText('Coins: ' + coinCounter);
						// Easy mode healing chance
						if (selectedDifficulty === 'FACIL' && Math.random() < 0.15) {
							wizard.health = Math.min(wizard.health + 5, wizard.maxHealth);
							updateHealthBar();
							// Visual feedback for healing
							LK.effects.flashObject(wizard, 0x00FF00, 200);
						}
						// Remove coin from array and destroy
						for (var i = coins.length - 1; i >= 0; i--) {
							if (coins[i] === coin) {
								coins.splice(i, 1);
								break;
							}
						}
						coin.destroy();
					}
				});
				// Increment enemy kill counter
				enemyKillCounter++;
				killCountText.setText('Puntuacion: ' + enemyKillCounter);
				// Update path combo system
				if (self.pathIndex !== undefined) {
					pathKillCounts[self.pathIndex]++;
					// Check if we've killed 3 enemies from this path
					if (pathKillCounts[self.pathIndex] >= 3) {
						// Reset the count for this path
						pathKillCounts[self.pathIndex] = 0;
						// Enable double damage for next projectile
						nextProjectileDoubleDamage = true;
						// Visual feedback for combo achievement
						LK.effects.flashScreen(0xFFD700, 500); // Golden flash
						// Create combo text indicator
						var comboText = new Text2('combo', {
							size: 120,
							fill: 0xFFD700,
							font: "monospace"
						});
						comboText.anchor.set(0.5, 0.5);
						comboText.x = 2048 / 2;
						comboText.y = 2732 / 2 - 200;
						game.addChild(comboText);
						// Animate combo text
						tween(comboText, {
							scaleX: 1.5,
							scaleY: 1.5,
							alpha: 0
						}, {
							duration: 1500,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								comboText.destroy();
							}
						});
					}
				}
				// Add experience to wizard
				wizard.gainExperience(25);
				// Life drain upgrade - 20% chance to give 20 HP
				if (wizard.lifeDrainLevel && wizard.lifeDrainLevel > 0) {
					var drainChance = Math.random();
					if (drainChance < 0.20) {
						// 20% chance
						wizard.health = Math.min(wizard.health + 20, wizard.maxHealth); // Always give 20 HP
						updateHealthBar();
						// Visual feedback for life drain
						LK.effects.flashObject(wizard, 0x00FF00, 300);
					}
				}
				// Clear selected enemy if this was the target
				if (selectedEnemy === self) {
					selectedEnemy = null;
				}
				// Remove from knights array
				for (var i = knights.length - 1; i >= 0; i--) {
					if (knights[i] === self) {
						knights.splice(i, 1);
						break;
					}
				}
				self.destroy();
				LK.setScore(LK.getScore() + 20);
			}
		});
	};
	return self;
});
var MiniBoss = Container.expand(function () {
	var self = Container.call(this);
	// Animation system for mini boss
	self.currentFrame = 1;
	self.animationTimer = 0;
	self.animationSpeed = 12; // Faster animation for menacing effect
	self.animationState = 'walking'; // walking, attacking, dying, idle
	// Create all mini boss graphics frames using knight frames but larger
	self.bossFrames = [];
	for (var i = 1; i <= 4; i++) {
		var frameGraphics = self.attachAsset('knight' + i, {
			anchorX: 0.5,
			anchorY: 1.0,
			scaleX: 4.0,
			scaleY: 4.0
		});
		frameGraphics.visible = i === 1; // Only show first frame initially
		frameGraphics.tint = 0x8B0000; // Dark red tint for mini boss
		self.bossFrames.push(frameGraphics);
	}
	// Create invisible hitbox with large size
	var hitbox = self.attachAsset('knight1', {
		anchorX: 0.5,
		anchorY: 1.0,
		scaleX: 8,
		scaleY: 8
	});
	hitbox.alpha = 0; // Make hitbox invisible
	// Create health bar background - positioned statically at top of screen
	self.healthBarBg = game.addChild(LK.getAsset('miniBossHealthBarBg', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 200,
		scaleX: 1.0,
		scaleY: 1.0
	}));
	// Create health bar foreground - positioned statically at top of screen
	self.healthBarFg = game.addChild(LK.getAsset('miniBossHealthBar', {
		anchorX: 0.0,
		anchorY: 0.5,
		x: 2048 / 2 - 200,
		y: 200,
		scaleX: 1.0,
		scaleY: 1.0
	}));
	// Create health text - positioned statically at top of screen
	self.healthText = new Text2('Boss Health: 1000/1000', {
		size: 40,
		fill: 0xFFFFFF,
		font: "monospace"
	});
	self.healthText.anchor.set(0.5, 0.5);
	self.healthText.x = 2048 / 2;
	self.healthText.y = 150;
	game.addChild(self.healthText);
	self.health = 3000; // Very high health for mini boss
	self.maxHealth = 3000;
	self.speed = 4;
	self.lastX = 0;
	self.frozen = false;
	self.frozenTimer = 0;
	self.specialAttackTimer = 0;
	self.update = function () {
		// Skip all movement and collision if mini boss is dying
		if (self.isDying) {
			return;
		}
		// Reduce speed when upgrade menu is visible
		var speedMultiplier = 1.0;
		if (upgradeMenu && upgradeMenu.visible) {
			speedMultiplier = 0.3; // 70% speed reduction
		}
		// Animation system - cycle through boss frames based on state
		self.animationTimer++;
		var frameSpeed = self.animationSpeed;
		if (self.animationState === 'attacking') {
			frameSpeed = 6; // Very fast animation for attacking
		} else if (self.animationState === 'dying') {
			frameSpeed = 30; // Slower animation for dying
		}
		if (self.animationTimer >= frameSpeed) {
			self.animationTimer = 0;
			// Hide current frame
			self.bossFrames[self.currentFrame - 1].visible = false;
			// Move to next frame based on animation state
			if (self.animationState === 'walking') {
				self.currentFrame++;
				if (self.currentFrame > 4) {
					self.currentFrame = 1;
				}
			} else if (self.animationState === 'attacking') {
				// Cycle through frames 2-4 for attacking
				self.currentFrame++;
				if (self.currentFrame > 4) {
					self.currentFrame = 2;
				}
			} else if (self.animationState === 'dying') {
				// Play frames 3-4 once for dying
				if (self.currentFrame < 4) {
					self.currentFrame++;
				}
			}
			// Show new frame
			self.bossFrames[self.currentFrame - 1].visible = true;
		}
		// Handle frozen state
		if (self.frozen) {
			self.frozenTimer--;
			if (self.frozenTimer <= 0) {
				self.frozen = false;
			}
			return; // Skip movement when frozen
		}
		// No special attacks for mini boss
		// Move toward wizard with steady pace
		if (wizard) {
			// Calculate direction from mini boss to wizard
			var dx = wizard.x - self.x;
			var dy = wizard.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				// Normalize direction and apply speed with upgrade menu speed reduction
				self.x += dx / distance * self.speed * speedMultiplier;
				self.y += dy / distance * self.speed * speedMultiplier;
			}
			// Face toward the wizard - flip horizontally based on wizard position
			if (dx < 0) {
				// Wizard is to the left - flip to face left
				for (var frameIdx = 0; frameIdx < self.bossFrames.length; frameIdx++) {
					self.bossFrames[frameIdx].scaleX = -4.0; // Flip to face left
				}
			} else {
				// Wizard is to the right - face right
				for (var frameIdx = 0; frameIdx < self.bossFrames.length; frameIdx++) {
					self.bossFrames[frameIdx].scaleX = 4.0; // Normal orientation to face right
				}
			}
		} else {
			// Fallback: move down if wizard doesn't exist
			self.y += self.speed * speedMultiplier;
		}
	};
	self.updateHealthBar = function () {
		var healthPercent = self.health / self.maxHealth;
		self.healthBarFg.scaleX = healthPercent;
		self.healthText.setText('Boss Health: ' + self.health + '/' + self.maxHealth);
		// Change color based on health
		if (healthPercent > 0.6) {
			self.healthBarFg.tint = 0xff0000; // Red
		} else if (healthPercent > 0.3) {
			self.healthBarFg.tint = 0xff4500; // Orange-red
		} else {
			self.healthBarFg.tint = 0x8B0000; // Dark red
		}
	};
	self.performSpecialAttack = function () {
		// Create shockwave effect that damages wizard if close
		var dx = wizard.x - self.x;
		var dy = wizard.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance < 400) {
			// Shockwave range
			wizard.takeDamage(50); // Heavy damage from shockwave
			// Visual shockwave effect
			LK.effects.flashScreen(0xFF4500, 400);
		}
		// Create visual shockwave
		var shockwave = game.addChild(LK.getAsset('projectileGlow', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: self.x,
			y: self.y,
			scaleX: 1,
			scaleY: 1
		}));
		shockwave.tint = 0xFF4500;
		shockwave.alpha = 0.8;
		// Animate shockwave expansion
		tween(shockwave, {
			scaleX: 8,
			scaleY: 8,
			alpha: 0
		}, {
			duration: 600,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				shockwave.destroy();
			}
		});
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		// Update health bar
		self.updateHealthBar();
		// Change animation state to attacking when hit
		self.animationState = 'attacking';
		// Flash red when hit
		LK.effects.flashObject(self, 0xFF0000, 200);
		// Create damage indicator for mini boss
		var damageText = new Text2('-' + damage, {
			size: 120,
			fill: 0xFF0000,
			font: "monospace"
		});
		damageText.anchor.set(0.5, 0.5);
		damageText.x = self.x + (Math.random() - 0.5) * 100;
		damageText.y = self.y - 80;
		game.addChild(damageText);
		// Animate damage text floating up and fading out
		tween(damageText, {
			y: damageText.y - 200,
			alpha: 0,
			scaleX: 1.6,
			scaleY: 1.6
		}, {
			duration: 1600,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				damageText.destroy();
			}
		});
		// Create massive impact effect
		var impactEffect = game.addChild(LK.getAsset('projectileGlow', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: self.x,
			y: self.y,
			scaleX: 2.0,
			scaleY: 2.0
		}));
		impactEffect.tint = 0xFF8C00;
		impactEffect.alpha = 1.0;
		// Animate impact effect
		tween(impactEffect, {
			scaleX: 6.0,
			scaleY: 6.0,
			alpha: 0
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				impactEffect.destroy();
			}
		});
		// Return to walking animation after brief attacking animation
		tween({}, {}, {
			duration: 400,
			onFinish: function onFinish() {
				if (self.animationState === 'attacking') {
					self.animationState = 'walking';
				}
			}
		});
		// Check if mini boss should die based on health
		if (self.health <= 0) {
			self.die();
		}
	};
	self.down = function (x, y, obj) {
		// Add haptic vibration when mini boss is tapped
		if (typeof LK.vibrate === 'function') {
			LK.vibrate([100, 50, 100]); // Double pulse for boss enemy
		}
		// Set this mini boss as the selected target
		selectedEnemy = self;
		// Visual feedback for selection
		LK.effects.flashObject(self, 0xFFFF00, 500); // Yellow flash to indicate selection
		// Create projectile from wizard to mini boss when tapped
		if (wizard && projectiles.length < 10) {
			// Limit projectiles to prevent spam
			var projectile = game.addChild(new Projectile());
			projectile.x = wizard.x;
			projectile.y = wizard.y;
			// Calculate direction from wizard to mini boss
			var dx = self.x - wizard.x;
			var dy = self.y - wizard.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				projectile.direction.x = dx / distance;
				projectile.direction.y = dy / distance;
			}
			projectile.targetEnemy = self; // Set the target for this projectile
			projectiles.push(projectile);
			LK.getSound('spellCast').play();
		}
	};
	self.die = function () {
		// Change animation state to dying
		self.animationState = 'dying';
		self.currentFrame = 3; // Start dying animation from frame 3
		// Play pain sound when mini boss dies
		LK.getSound('painSound').play();
		// Start death animation sequence
		self.isDying = true;
		// Massive death explosion effect
		LK.effects.flashScreen(0xFFD700, 1000); // Golden flash for mini boss death
		// Animate mini boss death with dramatic effect
		tween(self, {
			alpha: 0,
			scaleX: 0.1,
			scaleY: 0.1,
			rotation: Math.PI * 2,
			y: self.y + 100
		}, {
			duration: 1500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// After death animation completes, execute all death logic
				// Drop multiple coins
				for (var coinIdx = 0; coinIdx < 5; coinIdx++) {
					var coin = game.addChild(new Coin());
					coin.x = self.x + (Math.random() - 0.5) * 200;
					coin.y = self.y - 50 + (Math.random() - 0.5) * 100;
					coin.isAnimating = true;
					coins.push(coin);
					// Animate coin moving toward coin counter
					var coinTargetX = 120 + coinText.width / 2;
					var coinTargetY = 90 + coinText.height / 2;
					tween(coin, {
						x: coinTargetX,
						y: coinTargetY,
						scaleX: 0.5,
						scaleY: 0.5
					}, {
						duration: 1000 + coinIdx * 200,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							// Increment coin counter after animation
							coinCounter += 10; // Mini boss gives 10 coins per coin drop
							coinText.setText('Coins: ' + coinCounter);
							// Remove coin from array and destroy
							for (var i = coins.length - 1; i >= 0; i--) {
								if (coins[i] === coin) {
									coins.splice(i, 1);
									break;
								}
							}
							coin.destroy();
						}
					});
				}
				// Increment enemy kill counter
				enemyKillCounter += 10; // Mini boss counts as 10 kills
				killCountText.setText('Puntuacion: ' + enemyKillCounter);
				// Update medal statistics
				if (!storage.totalBossKills) storage.totalBossKills = 0;
				storage.totalBossKills++;
				// Add massive experience to wizard
				wizard.gainExperience(250);
				// Clear selected enemy if this was the target
				if (selectedEnemy === self) {
					selectedEnemy = null;
				}
				// Clean up static health bar elements
				if (self.healthBarBg && self.healthBarBg.parent) {
					self.healthBarBg.destroy();
				}
				if (self.healthBarFg && self.healthBarFg.parent) {
					self.healthBarFg.destroy();
				}
				if (self.healthText && self.healthText.parent) {
					self.healthText.destroy();
				}
				// Remove from mini bosses array
				for (var i = miniBosses.length - 1; i >= 0; i--) {
					if (miniBosses[i] === self) {
						miniBosses.splice(i, 1);
						break;
					}
				}
				self.destroy();
				LK.setScore(LK.getScore() + 100); // Massive score bonus
			}
		});
	};
	return self;
});
var Ogre = Container.expand(function () {
	var self = Container.call(this);
	// Animation system for ogre
	self.currentFrame = 1;
	self.animationTimer = 0;
	self.animationSpeed = 20; // Change frame every 20 ticks (333ms at 60fps)
	self.animationState = 'walking'; // walking, attacking, dying, idle
	// Create all ogre graphics frames and store them
	self.ogreFrames = [];
	for (var i = 1; i <= 4; i++) {
		var frameGraphics = self.attachAsset('ogre' + i, {
			anchorX: 0.5,
			anchorY: 1.0,
			scaleX: 2.0,
			scaleY: 2.0
		});
		frameGraphics.visible = i === 1; // Only show first frame initially
		self.ogreFrames.push(frameGraphics);
	}
	// Create invisible hitbox with double size
	var hitbox = self.attachAsset('ogre1', {
		anchorX: 0.5,
		anchorY: 1.0,
		scaleX: 4,
		scaleY: 4
	});
	hitbox.alpha = 0; // Make hitbox invisible
	self.health = 2;
	self.maxHealth = 2;
	self.speed = 7;
	// Note: health, maxHealth and speed will be overridden by difficulty system
	self.lastX = 0;
	self.frozen = false;
	self.frozenTimer = 0;
	self.update = function () {
		// Skip all movement and collision if ogre is dying
		if (self.isDying) {
			return;
		}
		// Reduce speed when upgrade menu is visible
		var speedMultiplier = 1.0;
		if (upgradeMenu && upgradeMenu.visible) {
			speedMultiplier = 0.3; // 70% speed reduction
		}
		// Animation system - cycle through ogre frames based on state
		self.animationTimer++;
		var frameSpeed = self.animationSpeed;
		if (self.animationState === 'attacking') {
			frameSpeed = 10; // Faster animation for attacking
		} else if (self.animationState === 'dying') {
			frameSpeed = 25; // Slower animation for dying
		} else if (self.animationState === 'idle') {
			frameSpeed = 30; // Very slow animation for idle
		}
		if (self.animationTimer >= frameSpeed) {
			self.animationTimer = 0;
			// Hide current frame
			self.ogreFrames[self.currentFrame - 1].visible = false;
			// Move to next frame based on animation state
			if (self.animationState === 'walking') {
				self.currentFrame++;
				if (self.currentFrame > 4) {
					self.currentFrame = 1;
				}
			} else if (self.animationState === 'attacking') {
				// Cycle through frames 2-4 for attacking
				self.currentFrame++;
				if (self.currentFrame > 4) {
					self.currentFrame = 2;
				}
			} else if (self.animationState === 'dying') {
				// Play frames 3-4 once for dying
				if (self.currentFrame < 4) {
					self.currentFrame++;
				}
			} else if (self.animationState === 'idle') {
				// Cycle between frames 1-2 for idle
				self.currentFrame = self.currentFrame === 1 ? 2 : 1;
			}
			// Show new frame
			self.ogreFrames[self.currentFrame - 1].visible = true;
		}
		// Progressive speed increase - increase speed by 150% over 10 seconds
		if (!self.speedTweenStarted) {
			self.speedTweenStarted = true;
			var targetSpeed = self.speed * 2.5; // Increase speed by 150%
			tween(self, {
				speed: targetSpeed
			}, {
				duration: 10000,
				// 10 seconds
				easing: tween.easeOut
			});
		}
		// Handle frozen state
		if (self.frozen) {
			self.frozenTimer--;
			if (self.frozenTimer <= 0) {
				self.frozen = false;
			}
			return; // Skip movement when frozen
		}
		// Always move directly toward the wizard to ensure ogres reach the player
		if (wizard) {
			// Calculate direction from ogre to wizard
			var dx = wizard.x - self.x;
			var dy = wizard.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				// Normalize direction and apply speed with upgrade menu speed reduction
				self.x += dx / distance * self.speed * speedMultiplier;
				self.y += dy / distance * self.speed * speedMultiplier;
			}
			// Face toward the wizard - flip horizontally based on wizard position
			if (dx < 0) {
				// Wizard is to the left - flip to face left
				for (var frameIdx = 0; frameIdx < self.ogreFrames.length; frameIdx++) {
					self.ogreFrames[frameIdx].scaleX = -2.0; // Flip to face left
				}
			} else {
				// Wizard is to the right - face right
				for (var frameIdx = 0; frameIdx < self.ogreFrames.length; frameIdx++) {
					self.ogreFrames[frameIdx].scaleX = 2.0; // Normal orientation to face right
				}
			}
		} else {
			// Fallback: move down if wizard doesn't exist
			self.y += self.speed * speedMultiplier;
		}
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		// Change animation state to attacking when hit
		self.animationState = 'attacking';
		// Flash red when hit
		LK.effects.flashObject(self, 0xFF0000, 200);
		// Create damage indicator
		var damageText = new Text2('-' + damage, {
			size: 90,
			fill: 0xFF6600,
			font: "monospace"
		});
		damageText.anchor.set(0.5, 0.5);
		damageText.x = self.x + (Math.random() - 0.5) * 70;
		damageText.y = self.y - 50;
		game.addChild(damageText);
		// Animate damage text floating up and fading out
		tween(damageText, {
			y: damageText.y - 140,
			alpha: 0,
			scaleX: 1.3,
			scaleY: 1.3
		}, {
			duration: 1200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				damageText.destroy();
			}
		});
		// Create impact effect
		var impactEffect = game.addChild(LK.getAsset('projectileGlow', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: self.x,
			y: self.y,
			scaleX: 1.0,
			scaleY: 1.0
		}));
		impactEffect.tint = 0xFF4500;
		impactEffect.alpha = 1.0;
		// Animate impact effect with explosion
		tween(impactEffect, {
			scaleX: 4.0,
			scaleY: 4.0,
			alpha: 0
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				impactEffect.destroy();
			}
		});
		// Return to walking animation after brief attacking animation
		tween({}, {}, {
			duration: 400,
			onFinish: function onFinish() {
				if (self.animationState === 'attacking') {
					self.animationState = 'walking';
				}
			}
		});
		// Check if ogre should die based on health
		if (self.health <= 0) {
			self.die();
		}
	};
	self.down = function (x, y, obj) {
		// Add haptic vibration when ogre is tapped
		if (typeof LK.vibrate === 'function') {
			LK.vibrate(75); // Medium 75ms vibration for stronger enemy
		}
		// Set this ogre as the selected target
		selectedEnemy = self;
		// Visual feedback for selection
		LK.effects.flashObject(self, 0xFFFF00, 500); // Yellow flash to indicate selection
		// Create projectile from wizard to ogre when ogre is tapped
		if (wizard && projectiles.length < 10) {
			// Limit projectiles to prevent spam
			var projectile = game.addChild(new Projectile());
			projectile.x = wizard.x;
			projectile.y = wizard.y;
			// Calculate direction from wizard to ogre
			var dx = self.x - wizard.x;
			var dy = self.y - wizard.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				projectile.direction.x = dx / distance;
				projectile.direction.y = dy / distance;
			}
			projectile.targetEnemy = self; // Set the target for this projectile
			projectiles.push(projectile);
			LK.getSound('spellCast').play();
		}
	};
	self.die = function () {
		// Change animation state to dying
		self.animationState = 'dying';
		self.currentFrame = 3; // Start dying animation from frame 3
		// Play pain sound when ogre dies
		LK.getSound('painSound').play();
		// Start death animation sequence
		self.isDying = true;
		// Animate ogre death with heavy collapse effect
		tween(self, {
			alpha: 0,
			scaleX: 0.1,
			scaleY: 0.1,
			rotation: Math.PI * 1.2,
			y: self.y + 80
		}, {
			duration: 1200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// After death animation completes, execute all death logic
				// Drop coin
				var coin = game.addChild(new Coin());
				coin.x = self.x;
				coin.y = self.y - 50;
				coin.isAnimating = true;
				coins.push(coin);
				// Animate coin moving toward coin counter
				var coinTargetX = 120 + coinText.width / 2;
				var coinTargetY = 90 + coinText.height / 2;
				tween(coin, {
					x: coinTargetX,
					y: coinTargetY,
					scaleX: 0.5,
					scaleY: 0.5
				}, {
					duration: 1000,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Apply difficulty-specific coin rewards
						var selectedDifficulty = storage.difficulty || 'NORMAL';
						var coinReward = 1;
						if (selectedDifficulty === 'FACIL') {
							coinReward = Math.floor(1.5); // 50% more coins (rounded down)
						} else if (selectedDifficulty === 'DIFICIL') {
							coinReward = Math.max(1, Math.floor(0.75)); // 25% fewer coins (minimum 1)
						}
						// Increment coin counter after animation
						coinCounter += coinReward;
						coinText.setText('Coins: ' + coinCounter);
						// Easy mode healing chance
						if (selectedDifficulty === 'FACIL' && Math.random() < 0.15) {
							wizard.health = Math.min(wizard.health + 5, wizard.maxHealth);
							updateHealthBar();
							// Visual feedback for healing
							LK.effects.flashObject(wizard, 0x00FF00, 200);
						}
						// Remove coin from array and destroy
						for (var i = coins.length - 1; i >= 0; i--) {
							if (coins[i] === coin) {
								coins.splice(i, 1);
								break;
							}
						}
						coin.destroy();
					}
				});
				// Increment enemy kill counter
				enemyKillCounter++;
				killCountText.setText('Puntuacion: ' + enemyKillCounter);
				// Update path combo system
				if (self.pathIndex !== undefined) {
					pathKillCounts[self.pathIndex]++;
					// Check if we've killed 3 enemies from this path
					if (pathKillCounts[self.pathIndex] >= 3) {
						// Reset the count for this path
						pathKillCounts[self.pathIndex] = 0;
						// Enable double damage for next projectile
						nextProjectileDoubleDamage = true;
						// Visual feedback for combo achievement
						LK.effects.flashScreen(0xFFD700, 500); // Golden flash
						// Create combo text indicator
						var comboText = new Text2('combo', {
							size: 120,
							fill: 0xFFD700,
							font: "monospace"
						});
						comboText.anchor.set(0.5, 0.5);
						comboText.x = 2048 / 2;
						comboText.y = 2732 / 2 - 200;
						game.addChild(comboText);
						// Animate combo text
						tween(comboText, {
							scaleX: 1.5,
							scaleY: 1.5,
							alpha: 0
						}, {
							duration: 1500,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								comboText.destroy();
							}
						});
					}
				}
				// Add experience to wizard
				wizard.gainExperience(25);
				// Life drain upgrade - 20% chance to give 20 HP
				if (wizard.lifeDrainLevel && wizard.lifeDrainLevel > 0) {
					var drainChance = Math.random();
					if (drainChance < 0.20) {
						// 20% chance
						wizard.health = Math.min(wizard.health + 20, wizard.maxHealth); // Always give 20 HP
						updateHealthBar();
						// Visual feedback for life drain
						LK.effects.flashObject(wizard, 0x00FF00, 300);
					}
				}
				// Clear selected enemy if this was the target
				if (selectedEnemy === self) {
					selectedEnemy = null;
				}
				// Remove from ogres array
				for (var i = ogres.length - 1; i >= 0; i--) {
					if (ogres[i] === self) {
						ogres.splice(i, 1);
						break;
					}
				}
				self.destroy();
				LK.setScore(LK.getScore() + 15);
			}
		});
	};
	return self;
});
var Orb = Container.expand(function () {
	var self = Container.call(this);
	// Create orb visual using energy sphere
	var orbGraphics = self.attachAsset('energySphere', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.4,
		scaleY: 0.4
	});
	orbGraphics.tint = 0xFFD700; // Golden color for orbs
	orbGraphics.alpha = 0.9;
	self.orbitalAngle = 0; // Starting angle for this orb
	self.orbitalRadius = 880; // Distance from wizard - doubled again for even more separation
	self.rotationSpeed = 0.025; // How fast orbs rotate - halved for slower movement
	self.update = function () {
		// Pause orb when upgrade menu is visible
		if (upgradeMenu && upgradeMenu.visible) {
			return;
		}
		// Rotate around wizard
		if (wizard) {
			self.orbitalAngle += self.rotationSpeed;
			self.x = wizard.x + Math.cos(self.orbitalAngle) * self.orbitalRadius;
			self.y = wizard.y + Math.sin(self.orbitalAngle) * self.orbitalRadius - 240; // Position orb much higher up
		}
		// Add pulsing effect
		var pulse = 1 + Math.sin(LK.ticks * 0.3) * 0.2;
		orbGraphics.scaleX = 0.4 * pulse;
		orbGraphics.scaleY = 0.4 * pulse;
		// Check collision with enemies using collision state tracking (but never with wizard)
		var allEnemies = enemies.concat(ogres).concat(knights).concat(miniBosses);
		for (var i = 0; i < allEnemies.length; i++) {
			var enemy = allEnemies[i];
			// Skip collision check with wizard
			if (enemy === wizard) {
				continue;
			}
			// Initialize collision tracking for this enemy if not exists
			if (!self.lastIntersecting) {
				self.lastIntersecting = {};
			}
			if (self.lastIntersecting[i] === undefined) {
				self.lastIntersecting[i] = false;
			}
			var currentIntersecting = self.intersects(enemy);
			if (!self.lastIntersecting[i] && currentIntersecting) {
				// Deal damage to enemy on contact transition (first contact only)
				enemy.takeDamage(50);
				// Visual effect for orb hit
				LK.effects.flashObject(self, 0xFFFFFF, 200);
				// Create orb impact effect
				var orbImpact = game.addChild(LK.getAsset('energySphere', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: enemy.x,
					y: enemy.y,
					scaleX: 0.3,
					scaleY: 0.3
				}));
				orbImpact.tint = 0xFFD700;
				orbImpact.alpha = 0.8;
				// Animate orb impact
				tween(orbImpact, {
					scaleX: 1.5,
					scaleY: 1.5,
					alpha: 0
				}, {
					duration: 250,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						orbImpact.destroy();
					}
				});
			}
			// Update collision state for this enemy
			self.lastIntersecting[i] = currentIntersecting;
		}
	};
	return self;
});
var PrestigeMedals = Container.expand(function () {
	var self = Container.call(this);
	// Background
	var medalsBg = self.attachAsset('startMenuBackground', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 2732 / 2,
		scaleX: 1.0,
		scaleY: 1.0
	});
	medalsBg.alpha = 1.0;
	medalsBg.tint = 0x1a1a2e;
	// Title
	var titleText = new Text2('MEDALLAS DE PRESTIGIO', {
		size: 120,
		fill: 0xFFD700,
		font: "monospace"
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 2048 / 2;
	titleText.y = 600;
	self.addChild(titleText);
	// Initialize medals data if not exists
	if (!storage.medals) {
		storage.medals = {};
	}
	// Medal definitions
	var medalDefinitions = [{
		id: 'firstKill',
		name: 'PRIMER ENEMIGO',
		description: 'Mata tu primer esqueleto',
		requirement: 'Eliminar 1 enemigo',
		icon: 'esqueleto1',
		unlocked: false
	}, {
		id: 'tenKills',
		name: 'CAZADOR',
		description: 'Mata 10 enemigos',
		requirement: 'Eliminar 10 enemigos',
		icon: 'spell',
		unlocked: false
	}, {
		id: 'survivorMedal',
		name: 'SUPERVIVIENTE',
		description: 'Mata 25 enemigos',
		requirement: 'Eliminar 25 enemigos',
		icon: 'knight1',
		unlocked: false
	}, {
		id: 'masterWizard',
		name: 'MAESTRO HECHICERO',
		description: 'Mata 50 enemigos',
		requirement: 'Eliminar 50 enemigos',
		icon: 'wizard1',
		unlocked: false
	}, {
		id: 'coinCollector',
		name: 'COLECCIONISTA',
		description: 'Consigue 100 monedas',
		requirement: 'Conseguir 100 monedas',
		icon: 'coin',
		unlocked: false
	}, {
		id: 'bossSlayer',
		name: 'MATA JEFES',
		description: 'Derrota un mini jefe',
		requirement: 'Eliminar mini jefe',
		icon: 'ogre1',
		unlocked: false
	}, {
		id: 'legendary',
		name: 'LEGENDARIO',
		description: 'Mata 100 enemigos',
		requirement: 'Eliminar 100 enemigos',
		icon: 'energySphere',
		unlocked: false
	}, {
		id: 'deathCheater',
		name: 'BURLANDO LA MUERTE',
		description: 'Revive cuando mueres',
		requirement: 'Activar revival',
		icon: 'shield',
		unlocked: false
	}, {
		id: 'upgradeExpert',
		name: 'EXPERTO EN MEJORAS',
		description: 'Compra 5 mejoras',
		requirement: 'Comprar 5 mejoras',
		icon: 'pathSelector',
		unlocked: false
	}];
	// Store references for cleanup
	self.medalIcons = [];
	self.medalTexts = [];
	self.medalBorders = [];
	// Check and update medal status
	self.updateMedals = function () {
		// Get current game stats
		var totalKills = storage.totalKills || 0;
		var totalCoins = storage.totalCoins || 0;
		var totalBossKills = storage.totalBossKills || 0;
		var totalRevives = storage.totalRevives || 0;
		var totalUpgrades = storage.totalUpgrades || 0;
		// Check each medal
		for (var i = 0; i < medalDefinitions.length; i++) {
			var medal = medalDefinitions[i];
			var isUnlocked = false;
			switch (medal.id) {
				case 'firstKill':
					isUnlocked = totalKills >= 1;
					break;
				case 'tenKills':
					isUnlocked = totalKills >= 10;
					break;
				case 'survivorMedal':
					isUnlocked = totalKills >= 25;
					break;
				case 'masterWizard':
					isUnlocked = totalKills >= 50;
					break;
				case 'coinCollector':
					isUnlocked = totalCoins >= 100;
					break;
				case 'bossSlayer':
					isUnlocked = totalBossKills >= 1;
					break;
				case 'legendary':
					isUnlocked = totalKills >= 100;
					break;
				case 'deathCheater':
					isUnlocked = totalRevives >= 1;
					break;
				case 'upgradeExpert':
					isUnlocked = totalUpgrades >= 5;
					break;
			}
			// Update storage
			storage.medals[medal.id] = isUnlocked;
			medal.unlocked = isUnlocked;
		}
	};
	// Display medals
	self.displayMedals = function () {
		var medalRows = 3;
		var medalCols = 3;
		var startX = 2048 / 2 - 400;
		var startY = 1000;
		var medalSpacing = 300;
		for (var i = 0; i < medalDefinitions.length; i++) {
			var medal = medalDefinitions[i];
			var row = Math.floor(i / medalCols);
			var col = i % medalCols;
			var medalX = startX + col * medalSpacing;
			var medalY = startY + row * medalSpacing;
			// Medal background/border
			var medalBorder = self.attachAsset('pathSelector', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: medalX,
				y: medalY,
				scaleX: 3,
				scaleY: 3
			});
			medalBorder.tint = medal.unlocked ? 0xFFD700 : 0x555555;
			medalBorder.alpha = medal.unlocked ? 1.0 : 0.5;
			self.medalBorders.push(medalBorder);
			// Medal icon
			var medalIcon = self.attachAsset(medal.icon, {
				anchorX: 0.5,
				anchorY: 0.5,
				x: medalX,
				y: medalY,
				scaleX: 1.5,
				scaleY: 1.5
			});
			medalIcon.tint = medal.unlocked ? 0xFFFFFF : 0x333333;
			medalIcon.alpha = medal.unlocked ? 1.0 : 0.3;
			self.medalIcons.push(medalIcon);
			// Medal text
			var medalText = new Text2(medal.name + '\n' + medal.description, {
				size: 30,
				fill: medal.unlocked ? 0xFFFFFF : 0x666666,
				font: "monospace"
			});
			medalText.anchor.set(0.5, 0);
			medalText.x = medalX;
			medalText.y = medalY + 80;
			self.addChild(medalText);
			self.medalTexts.push(medalText);
			// Add shine effect for unlocked medals
			if (medal.unlocked) {
				var shine = self.attachAsset('projectileGlow', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: medalX,
					y: medalY,
					scaleX: 2,
					scaleY: 2
				});
				shine.alpha = 0.3;
				shine.tint = 0xFFD700;
				// Animate shine
				tween(shine, {
					rotation: Math.PI * 2,
					alpha: 0.1
				}, {
					duration: 2000,
					easing: tween.linear,
					loop: true
				});
			}
		}
	};
	// Back button
	var backButton = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 2400,
		scaleX: 2,
		scaleY: 2
	});
	backButton.tint = 0x00FF00;
	var backText = new Text2('VOLVER', {
		size: 80,
		fill: 0xFFFFFF,
		font: "monospace"
	});
	backText.anchor.set(0.5, 0.5);
	backText.x = 2048 / 2;
	backText.y = 2400;
	self.addChild(backText);
	// Handle interactions
	self.down = function (x, y, obj) {
		// Check back button
		if (y >= 2300 && y <= 2500 && x >= 2048 / 2 - 100 && x <= 2048 / 2 + 100) {
			self.hideMedals();
		}
	};
	self.showMedals = function () {
		self.updateMedals();
		self.displayMedals();
		self.visible = true;
	};
	self.hideMedals = function () {
		// Clean up medal elements
		for (var i = 0; i < self.medalIcons.length; i++) {
			if (self.medalIcons[i]) {
				self.medalIcons[i].destroy();
			}
		}
		for (var i = 0; i < self.medalTexts.length; i++) {
			if (self.medalTexts[i]) {
				self.medalTexts[i].destroy();
			}
		}
		for (var i = 0; i < self.medalBorders.length; i++) {
			if (self.medalBorders[i]) {
				self.medalBorders[i].destroy();
			}
		}
		self.medalIcons = [];
		self.medalTexts = [];
		self.medalBorders = [];
		self.visible = false;
	};
	return self;
});
var Projectile = Container.expand(function () {
	var self = Container.call(this);
	// Create glowing light effect behind projectile
	var lightGlow = self.attachAsset('projectileGlow', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 2.0,
		scaleY: 2.0
	});
	lightGlow.alpha = 0.15;
	lightGlow.tint = 0x44aaff; // Blue-white glow
	// Animate the glow effect
	tween(lightGlow, {
		scaleX: 3.5,
		scaleY: 3.5,
		alpha: 0.05
	}, {
		duration: 800,
		easing: tween.easeInOut
	});
	tween(lightGlow, {
		rotation: Math.PI * 4
	}, {
		duration: 1000,
		easing: tween.linear
	});
	var projectileGraphics = self.attachAsset('projectile', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 3.0,
		scaleY: 3.0
	});
	// Create spell trail array
	self.trailSegments = [];
	self.maxTrailSegments = 8;
	self.trailTimer = 0;
	self.speed = 50;
	self.direction = {
		x: 0,
		y: 0
	};
	self.lastIntersecting = {};
	self.targetEnemy = null; // The specific enemy this projectile should damage
	self.update = function () {
		// Move projectile
		self.x += self.direction.x * self.speed;
		self.y += self.direction.y * self.speed;
		// Rotate projectile to point towards movement direction
		var angle = Math.atan2(self.direction.y, self.direction.x);
		projectileGraphics.rotation = angle + Math.PI / 2; // Add 90 degrees so top points forward
		// Simplified visual effect - no trail system for better performance
		// Remove if off screen
		if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
			self.removeFromGame();
			return;
		}
		// Only check collision with the target enemy if one is set
		if (self.targetEnemy && self.targetEnemy.parent) {
			if (!self.lastIntersecting.target) {
				self.lastIntersecting.target = false;
			}
			var currentTargetIntersecting = self.intersects(self.targetEnemy);
			if (!self.lastIntersecting.target && currentTargetIntersecting) {
				// Hit the target enemy
				// Calculate damage based on spell power upgrade
				var damage = 100;
				if (wizard && wizard.spellPowerLevel && wizard.spellPowerLevel > 0) {
					// Check if target is an ogre and we're before enemy 35
					if (self.targetEnemy && self.targetEnemy.ogreFrames && enemyKillCounter < 35) {
						// Always kill ogres in one hit until enemy 35
						damage = self.targetEnemy.health + 1; // Ensure one-hit kill
					} else {
						damage = 200; // Double damage when spell power is active
					}
				}
				// Apply combo double damage if active
				if (nextProjectileDoubleDamage) {
					damage *= 2; // Double the damage
					nextProjectileDoubleDamage = false; // Reset the flag after use
					// Visual feedback for combo damage
					LK.effects.flashObject(self.targetEnemy, 0xFFD700, 300); // Golden flash on enemy
					// Create special combo damage indicator
					var comboDamageText = new Text2('COMBO x2!', {
						size: 100,
						fill: 0xFFD700,
						font: "monospace"
					});
					comboDamageText.anchor.set(0.5, 0.5);
					comboDamageText.x = self.targetEnemy.x;
					comboDamageText.y = self.targetEnemy.y - 80;
					game.addChild(comboDamageText);
					// Animate combo damage text
					tween(comboDamageText, {
						y: comboDamageText.y - 150,
						scaleX: 1.8,
						scaleY: 1.8,
						alpha: 0
					}, {
						duration: 1000,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							comboDamageText.destroy();
						}
					});
				}
				self.targetEnemy.takeDamage(damage);
				self.removeFromGame();
				return;
			}
			self.lastIntersecting.target = currentTargetIntersecting;
		}
	};
	self.removeFromGame = function () {
		// Clean up trail segments
		for (var i = 0; i < self.trailSegments.length; i++) {
			var segment = self.trailSegments[i];
			if (segment && segment.parent) {
				segment.destroy();
			}
		}
		self.trailSegments = [];
		// Remove from projectiles array
		for (var i = projectiles.length - 1; i >= 0; i--) {
			if (projectiles[i] === self) {
				projectiles.splice(i, 1);
				break;
			}
		}
		self.destroy();
	};
	return self;
});
var UpgradeMenu = Container.expand(function () {
	var self = Container.call(this);
	// Set high z-index to ensure menu appears above all game elements
	self.zIndex = 1000;
	// Cooldown system for upgrade menu
	self.cooldownDuration = 120; // 2 seconds at 60fps
	self.cooldownTimer = 0;
	// Background removed - no overlay needed
	// Title text
	var titleText = new Text2('UPGRADES', {
		size: 120,
		fill: 0xFFD700,
		font: "monospace"
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 2048 / 2;
	titleText.y = 1050;
	self.addChild(titleText);
	// Initialize upgrade cost
	self.upgradeCost = 5;
	// Store references to upgrade text elements for updates
	self.upgradeTextElements = [];
	// Upgrade options - expanded to 10 upgrades
	var upgradeOptions = [{
		name: 'SHIELD',
		description: 'Block 1 attack'
	}, {
		name: 'HEALTH BOOST',
		description: 'More health'
	}, {
		name: 'LIFE DRAIN',
		description: '5% chance +10 HP'
	}, {
		name: 'ENERGY SPHERE',
		description: 'Auto-attack every 3s'
	}, {
		name: 'FORCE PUSH',
		description: 'Push enemies back'
	}, {
		name: 'SPELL POWER',
		description: 'Double damage'
	}, {
		name: 'THORNS',
		description: 'Spikes on all paths'
	}, {
		name: 'FIRE BALL',
		description: 'Launch fire ball every 3s'
	}, {
		name: 'FREEZE PULSE',
		description: 'Freeze all enemies'
	}, {
		name: 'ORBS',
		description: 'Orbs rotate around player'
	}];
	// Select 3 alternating upgrades from the available options
	var selectedUpgrades = [];
	var availableIndices = [];
	for (var i = 0; i < upgradeOptions.length; i++) {
		availableIndices.push(i);
	}
	// Track which upgrades were shown last time
	if (!self.lastShownUpgrades) {
		self.lastShownUpgrades = [];
	}
	// Remove previously shown upgrades from available options if possible
	if (self.lastShownUpgrades.length > 0 && availableIndices.length > 3) {
		for (var lastIdx = 0; lastIdx < self.lastShownUpgrades.length; lastIdx++) {
			var indexToRemove = availableIndices.indexOf(self.lastShownUpgrades[lastIdx]);
			if (indexToRemove !== -1) {
				availableIndices.splice(indexToRemove, 1);
			}
		}
	}
	// If we don't have enough unique options, add back some previously shown ones
	if (availableIndices.length < 3) {
		availableIndices = [];
		for (var i = 0; i < upgradeOptions.length; i++) {
			availableIndices.push(i);
		}
	}
	// Randomly select 3 unique upgrades from available options
	for (var selection = 0; selection < 3; selection++) {
		var randomIndex = Math.floor(Math.random() * availableIndices.length);
		selectedUpgrades.push(availableIndices[randomIndex]);
		availableIndices.splice(randomIndex, 1);
	}
	// Store current selection for next time
	self.lastShownUpgrades = selectedUpgrades.slice(); // Copy array
	self.selectedUpgradeIndices = selectedUpgrades; // Store for reference
	// Create upgrade buttons in single row layout for 3 upgrades
	for (var i = 0; i < selectedUpgrades.length; i++) {
		var upgradeIndex = selectedUpgrades[i];
		var upgrade = upgradeOptions[upgradeIndex];
		// Calculate position in single row, 3-column grid
		var xPos = 2048 / 2 - 500 + i * 500; // Space 3 upgrades across screen width with more separation
		var yPos = 1400; // Single row positioned lower
		// Upgrade button background
		var upgradeBtn = self.attachAsset('pathSelector', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: xPos,
			y: yPos,
			scaleX: 6,
			scaleY: 4.5
		});
		upgradeBtn.upgradeIndex = upgradeIndex;
		upgradeBtn.displayIndex = i; // Store display index for touch detection
		upgradeBtn.tint = 0x8B008B;
		// Upgrade text
		var upgradeText = new Text2(upgrade.name + '\n' + upgrade.description + '\nCost: ' + self.upgradeCost + ' coins', {
			size: 40,
			fill: 0xFFFFFF,
			font: "monospace"
		});
		upgradeText.anchor.set(0.5, 0.5);
		upgradeText.x = xPos;
		upgradeText.y = yPos;
		upgradeText.upgradeIndex = upgradeIndex; // Store actual upgrade index for reference
		upgradeText.displayIndex = i; // Store display index for touch detection
		upgradeText.upgradeName = upgrade.name;
		upgradeText.upgradeDescription = upgrade.description;
		self.addChild(upgradeText);
		self.upgradeTextElements.push(upgradeText); // Store reference for updates
	}
	// Close button
	var closeBtn = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 1900,
		scaleX: 2,
		scaleY: 2
	});
	closeBtn.tint = 0xFF0000;
	var closeText = new Text2('CLOSE', {
		size: 80,
		fill: 0xFFFFFF,
		font: "monospace"
	});
	closeText.anchor.set(0.5, 0.5);
	closeText.x = 2048 / 2;
	closeText.y = 1900;
	self.addChild(closeText);
	// Method to refresh upgrade selection for alternating
	self.refreshUpgradeSelection = function () {
		var upgradeOptions = [{
			name: 'SHIELD',
			key: 'shield',
			baseDesc: 'Block 1 attack',
			improvedDesc: 'Block 2 attacks + regen'
		}, {
			name: 'HEALTH BOOST',
			key: 'healthBoost',
			baseDesc: 'More health',
			improvedDesc: 'Much more health'
		}, {
			name: 'LIFE DRAIN',
			key: 'lifeDrain',
			baseDesc: '20% chance +20 HP',
			improvedDesc: '20% chance +20 HP'
		}, {
			name: 'ENERGY SPHERE',
			key: 'energySphere',
			baseDesc: 'Auto-attack every 3s',
			improvedDesc: 'Auto-attack every 2s'
		}, {
			name: 'FORCE PUSH',
			key: 'forcePush',
			baseDesc: 'Push enemies back',
			improvedDesc: 'Stronger push + damage'
		}, {
			name: 'SPELL POWER',
			key: 'spellPower',
			baseDesc: 'Double damage',
			improvedDesc: 'Triple damage'
		}, {
			name: 'THORNS',
			key: 'thorns',
			baseDesc: 'Spikes on all paths',
			improvedDesc: 'Stronger spikes + faster'
		}, {
			name: 'FIRE BALL',
			key: 'fireBall',
			baseDesc: 'Launch fire ball every 3s',
			improvedDesc: 'Launch fire ball every 2s'
		}, {
			name: 'FREEZE PULSE',
			key: 'freezePulse',
			baseDesc: 'Freeze all enemies',
			improvedDesc: 'Freeze longer + damage'
		}, {
			name: 'ORBS',
			key: 'orbs',
			baseDesc: 'Orbs rotate around player',
			improvedDesc: 'More orbs + faster rotation'
		}];
		// Select new alternating upgrades
		var selectedUpgrades = [];
		var availableIndices = [];
		for (var i = 0; i < upgradeOptions.length; i++) {
			availableIndices.push(i);
		}
		// Remove previously shown upgrades from available options if possible
		if (self.lastShownUpgrades && self.lastShownUpgrades.length > 0 && availableIndices.length > 3) {
			for (var lastIdx = 0; lastIdx < self.lastShownUpgrades.length; lastIdx++) {
				var indexToRemove = availableIndices.indexOf(self.lastShownUpgrades[lastIdx]);
				if (indexToRemove !== -1) {
					availableIndices.splice(indexToRemove, 1);
				}
			}
		}
		// If we don't have enough unique options, add back some previously shown ones
		if (availableIndices.length < 3) {
			availableIndices = [];
			for (var i = 0; i < upgradeOptions.length; i++) {
				availableIndices.push(i);
			}
		}
		// Select 3 unique upgrades from available options
		for (var selection = 0; selection < 3; selection++) {
			var randomIndex = Math.floor(Math.random() * availableIndices.length);
			selectedUpgrades.push(availableIndices[randomIndex]);
			availableIndices.splice(randomIndex, 1);
		}
		// Store current selection for next time
		self.lastShownUpgrades = selectedUpgrades.slice();
		self.selectedUpgradeIndices = selectedUpgrades;
		// Update upgrade text elements with new selections
		for (var i = 0; i < self.upgradeTextElements.length && i < selectedUpgrades.length; i++) {
			var upgradeIndex = selectedUpgrades[i];
			var upgrade = upgradeOptions[upgradeIndex];
			var textElement = self.upgradeTextElements[i];
			// Update the text element properties
			textElement.upgradeIndex = upgradeIndex;
			textElement.displayIndex = i;
			textElement.upgradeName = upgrade.name;
			textElement.upgradeDescription = upgrade.baseDesc;
		}
	};
	// Method to update upgrade text with new costs and show improved versions
	self.updateUpgradeCosts = function () {
		// First refresh the upgrade selection to ensure alternating upgrades
		self.refreshUpgradeSelection();
		var upgradeOptions = [{
			name: 'SHIELD',
			key: 'shield',
			baseDesc: 'Block 1 attack',
			improvedDesc: 'Block 2 attacks + regen'
		}, {
			name: 'HEALTH BOOST',
			key: 'healthBoost',
			baseDesc: 'More health',
			improvedDesc: 'Much more health'
		}, {
			name: 'LIFE DRAIN',
			key: 'lifeDrain',
			baseDesc: '20% chance +20 HP',
			improvedDesc: '20% chance +20 HP'
		}, {
			name: 'ENERGY SPHERE',
			key: 'energySphere',
			baseDesc: 'Auto-attack every 3s',
			improvedDesc: 'Auto-attack every 2s'
		}, {
			name: 'FORCE PUSH',
			key: 'forcePush',
			baseDesc: 'Push enemies back',
			improvedDesc: 'Stronger push + damage'
		}, {
			name: 'SPELL POWER',
			key: 'spellPower',
			baseDesc: 'Double damage',
			improvedDesc: 'Triple damage'
		}, {
			name: 'THORNS',
			key: 'thorns',
			baseDesc: 'Spikes on all paths',
			improvedDesc: 'Stronger spikes + faster'
		}, {
			name: 'FIRE BALL',
			key: 'fireBall',
			baseDesc: 'Launch fire ball every 3s',
			improvedDesc: 'Launch fire ball every 2s'
		}, {
			name: 'FREEZE PULSE',
			key: 'freezePulse',
			baseDesc: 'Freeze all enemies',
			improvedDesc: 'Freeze longer + damage'
		}, {
			name: 'ORBS',
			key: 'orbs',
			baseDesc: 'Orbs rotate around player',
			improvedDesc: 'More orbs + faster rotation'
		}];
		// Randomly select one upgrade to have modified cost (20% chance)
		var hasModifiedCost = Math.random() < 0.20; // 20% probability
		var modifiedCostIndex = hasModifiedCost ? Math.floor(Math.random() * 3) : -1; // Random upgrade among the 3
		for (var i = 0; i < self.upgradeTextElements.length; i++) {
			var textElement = self.upgradeTextElements[i];
			var upgradeIndex = textElement.upgradeIndex; // Use stored upgrade index
			var upgrade = upgradeOptions[upgradeIndex];
			var currentLevel = upgradeLevels[upgrade.key];
			// Calculate cost for this upgrade
			var upgradeCost = self.upgradeCost;
			if (i === modifiedCostIndex) {
				upgradeCost = Math.floor(self.upgradeCost * 0.95); // 5% decrease, rounded down
			}
			// Show improved version if already purchased
			var description = currentLevel > 0 ? upgrade.improvedDesc : upgrade.baseDesc;
			var levelText = currentLevel > 0 ? ' (LV' + (currentLevel + 1) + ')' : '';
			textElement.setText(upgrade.name + levelText + '\n' + description + '\nCost: ' + upgradeCost + ' coins');
			textElement.upgradeName = upgrade.name;
			textElement.upgradeDescription = description;
			textElement.actualCost = upgradeCost; // Store the actual cost for purchase logic
		}
	};
	// Update method for cooldown timer
	self.update = function () {
		if (self.cooldownTimer > 0) {
			self.cooldownTimer--;
			// Apply visual feedback during cooldown
			var cooldownAlpha = 0.3 + self.cooldownTimer / self.cooldownDuration * 0.7;
			self.alpha = cooldownAlpha;
		} else {
			self.alpha = 1.0; // Full opacity when cooldown is over
		}
	};
	// Handle upgrade purchases
	self.down = function (x, y, obj) {
		// Check if cooldown is active
		if (self.cooldownTimer > 0) {
			// Flash red to indicate cooldown is active
			LK.effects.flashScreen(0xFF0000, 200);
			return; // Exit early if cooldown is active
		}
		// Determine which upgrade was clicked based on 3-upgrade layout
		var upgradeIndex = -1;
		// Check which upgrade cell was clicked (single row, 3 columns)
		for (var i = 0; i < 3; i++) {
			var cellX = 2048 / 2 - 500 + i * 500; // Calculate cell center X for 3-upgrade layout with more separation
			var cellY = 1400; // Single row Y position
			var cellWidth = 400; // Touch area width - increased to match new spacing
			var cellHeight = 250; // Touch area height
			// Check if click is within this cell
			if (x >= cellX - cellWidth / 2 && x <= cellX + cellWidth / 2 && y >= cellY - cellHeight / 2 && y <= cellY + cellHeight / 2) {
				upgradeIndex = self.selectedUpgradeIndices[i]; // Get actual upgrade index from selected list
				break;
			}
		}
		// Check if upgrade button was clicked
		if (upgradeIndex !== -1) {
			// Close menu immediately when any upgrade option is selected
			self.closeMenu();
			// Get the actual cost from the text element
			var actualCost = self.upgradeTextElements[0].actualCost || self.upgradeCost || 5; // Default fallback
			for (var textIdx = 0; textIdx < self.upgradeTextElements.length; textIdx++) {
				if (self.upgradeTextElements[textIdx].displayIndex === Math.floor(upgradeIndex / 1)) {
					actualCost = self.upgradeTextElements[textIdx].actualCost || self.upgradeCost || 5;
					break;
				}
			}
			// Find the correct text element by matching the upgrade selection
			for (var cellIdx = 0; cellIdx < 3; cellIdx++) {
				var cellX = 2048 / 2 - 500 + cellIdx * 500;
				var cellY = 1400;
				var cellWidth = 400;
				var cellHeight = 250;
				if (x >= cellX - cellWidth / 2 && x <= cellX + cellWidth / 2 && y >= cellY - cellHeight / 2 && y <= cellY + cellHeight / 2) {
					actualCost = self.upgradeTextElements[cellIdx].actualCost || self.upgradeCost || 5;
					break;
				}
			}
			if (coinCounter >= actualCost) {
				coinCounter -= actualCost;
				coinText.setText('Coins: ' + coinCounter);
				// Apply upgrade based on index
				switch (upgradeIndex) {
					case 0:
						// Shield upgrade
						upgradeLevels.shield++;
						if (upgradeLevels.shield === 1) {
							// First level: Basic shield
							wizard.shieldActive = true;
							wizard.maxShieldHits = 1;
							wizard.currentShieldHits = 0;
						} else {
							// Improved level: Double shield + regeneration
							wizard.shieldActive = true;
							wizard.maxShieldHits = 2;
							wizard.currentShieldHits = 0;
							wizard.shieldRegen = true; // Enable shield regeneration
						}
						// Visual feedback for shield activation
						LK.effects.flashObject(wizard, 0x00BFFF, 500);
						// Create shield activation particles
						for (var shieldIdx = 0; shieldIdx < 10; shieldIdx++) {
							var shieldParticle = game.addChild(LK.getAsset('shield', {
								anchorX: 0.5,
								anchorY: 0.5,
								x: wizard.x + (Math.random() - 0.5) * 200,
								y: wizard.y + (Math.random() - 0.5) * 200,
								scaleX: 0.5,
								scaleY: 0.5
							}));
							shieldParticle.tint = 0x00BFFF;
							shieldParticle.alpha = 0.8;
							// Animate shield particles
							tween(shieldParticle, {
								scaleX: 1.5,
								scaleY: 1.5,
								alpha: 0
							}, {
								duration: 500 + Math.random() * 300,
								easing: tween.easeOut,
								onFinish: function onFinish() {
									shieldParticle.destroy();
								}
							});
						}
						// Add shield activation animation effect
						tween(wizard.shieldGraphics, {
							scaleX: 5,
							scaleY: 5,
							alpha: 1.0
						}, {
							duration: 400,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								tween(wizard.shieldGraphics, {
									scaleX: 3,
									scaleY: 3,
									alpha: 0.7
								}, {
									duration: 300,
									easing: tween.easeIn
								});
							}
						});
						break;
					case 1:
						// Health Boost upgrade
						upgradeLevels.healthBoost++;
						var healthIncrease = 40;
						wizard.maxHealth += healthIncrease;
						wizard.health = Math.min(wizard.health + healthIncrease, wizard.maxHealth);
						updateHealthBar();
						break;
					case 2:
						// Life Drain upgrade
						upgradeLevels.lifeDrain++;
						if (!wizard.lifeDrainLevel) {
							wizard.lifeDrainLevel = 0;
						}
						wizard.lifeDrainLevel = upgradeLevels.lifeDrain;
						break;
					case 3:
						// Energy Sphere upgrade
						upgradeLevels.energySphere++;
						if (upgradeLevels.energySphere === 1) {
							// First level: Create energy sphere
							if (!wizard.energySphere) {
								wizard.energySphere = game.addChild(new EnergyOrb());
							}
						}
						// Visual feedback for energy sphere activation
						LK.effects.flashObject(wizard, 0x00FFFF, 500);
						break;
					case 4:
						// Force Push upgrade
						upgradeLevels.forcePush++;
						if (!wizard.forcePushLevel) {
							wizard.forcePushLevel = 0;
							wizard.forcePushTimer = 0;
						}
						wizard.forcePushLevel = upgradeLevels.forcePush;
						// Visual feedback for force push
						LK.effects.flashObject(wizard, 0xFFFF00, 500);
						break;
					case 5:
						// Spell Power upgrade
						upgradeLevels.spellPower++;
						if (!wizard.spellPowerLevel) {
							wizard.spellPowerLevel = 0;
						}
						wizard.spellPowerLevel = upgradeLevels.spellPower;
						// Visual feedback for spell power
						LK.effects.flashObject(wizard, 0xFF4500, 500);
						break;
					case 6:
						// Thorns upgrade
						upgradeLevels.thorns++;
						if (!wizard.thornsLevel) {
							wizard.thornsLevel = 0;
							wizard.thornsTimer = 0;
						}
						wizard.thornsLevel = upgradeLevels.thorns;
						// Visual feedback for thorns
						LK.effects.flashObject(wizard, 0x8B4513, 500);
						break;
					case 7:
						// Fire Ball upgrade
						upgradeLevels.fireBall++;
						if (!wizard.fireBallLevel) {
							wizard.fireBallLevel = 0;
							wizard.fireBallTimer = 0;
						}
						wizard.fireBallLevel = upgradeLevels.fireBall;
						// Visual feedback for fire ball
						LK.effects.flashObject(wizard, 0xFF4500, 500);
						break;
					case 8:
						// Freeze Pulse upgrade
						upgradeLevels.freezePulse++;
						if (!wizard.freezePulseLevel) {
							wizard.freezePulseLevel = 0;
							wizard.freezePulseTimer = 0;
						}
						wizard.freezePulseLevel = upgradeLevels.freezePulse;
						// Visual feedback for freeze pulse
						LK.effects.flashObject(wizard, 0x87CEEB, 500);
						break;
					case 9:
						// Orbs upgrade
						upgradeLevels.orbs++;
						if (!wizard.orbLevel) {
							wizard.orbLevel = 0;
							wizard.orbs = []; // Array to store orb instances
						}
						wizard.orbLevel++;
						// Create new orb
						var newOrb = game.addChild(new Orb());
						// Set starting angle based on number of orbs for even distribution
						newOrb.orbitalAngle = wizard.orbs.length * (Math.PI * 2) / (wizard.orbLevel + 1);
						wizard.orbs.push(newOrb);
						// Redistribute existing orbs evenly
						for (var orbIdx = 0; orbIdx < wizard.orbs.length; orbIdx++) {
							wizard.orbs[orbIdx].orbitalAngle = orbIdx * (Math.PI * 2) / wizard.orbs.length;
						}
						// Visual feedback for orb upgrade
						LK.effects.flashObject(wizard, 0xFFD700, 500);
						break;
				}
				// Visual feedback - flash the upgrade area green
				LK.effects.flashScreen(0x00FF00, 300);
				// Update medal statistics
				if (!storage.totalUpgrades) storage.totalUpgrades = 0;
				storage.totalUpgrades++;
			} else {
				// Not enough coins - flash red
				LK.effects.flashScreen(0xFF0000, 300);
			}
		} else if (y >= 1750 && y <= 2050) {
			// Close button area clicked
			self.closeMenu();
		}
	};
	self.closeMenu = function () {
		self.visible = false;
		gameStarted = true;
		// Resume appropriate music based on game progress
		if (enemyKillCounter >= 25) {
			LK.playMusic('mysticalAmbient', {
				volume: 0.6,
				fade: {
					start: 0,
					end: 0.6,
					duration: 1000
				}
			});
		} else if (enemyKillCounter >= 10) {
			LK.playMusic('epicBattle', {
				volume: 0.8,
				fade: {
					start: 0,
					end: 0.8,
					duration: 1000
				}
			});
		} else {
			LK.playMusic('medievalTheme', {
				volume: 0.7,
				fade: {
					start: 0,
					end: 0.7,
					duration: 1000
				}
			});
		}
	};
	return self;
});
var Wizard = Container.expand(function () {
	var self = Container.call(this);
	// Animation system for wizard
	self.currentFrame = 1;
	self.animationTimer = 0;
	self.animationSpeed = 18; // Change frame every 18 ticks (300ms at 60fps)
	// Create all wizard graphics frames and store them
	self.wizardFrames = [];
	for (var i = 1; i <= 4; i++) {
		var frameGraphics = self.attachAsset('wizard' + i, {
			anchorX: 0.5,
			anchorY: 1.0,
			scaleX: 2.5,
			scaleY: 2.5
		});
		frameGraphics.visible = i === 1; // Only show first frame initially
		self.wizardFrames.push(frameGraphics);
	}
	// Create invisible hitbox with much smaller size for more precise collision
	var hitbox = self.attachAsset('wizard1', {
		anchorX: 0.3,
		anchorY: 1.0,
		scaleX: 0.25,
		// Much smaller size for very precise collision
		scaleY: 0.3 // Much smaller size for very precise collision
	});
	hitbox.alpha = 0; // Make hitbox invisible
	// Position hitbox slightly to the right to reduce left side
	hitbox.x = 15; // Offset hitbox to the right
	// Create shield visual effect
	self.shieldGraphics = self.attachAsset('shield', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 3,
		scaleY: 3
	});
	self.shieldGraphics.alpha = 0.7;
	self.shieldGraphics.visible = false;
	self.attackCooldown = 0;
	self.level = 1;
	self.experience = 0;
	self.health = 100;
	self.maxHealth = 100;
	self.spellPowerLevel = 0; // Track spell power upgrades
	self.shieldActive = false; // Track shield status
	self.orbLevel = 0; // Track orb upgrades
	self.orbs = []; // Array to store orb instances
	// Override intersects method to use smaller hitbox
	self.intersects = function (other) {
		return hitbox.intersects(other);
	};
	self.update = function () {
		// Pause all upgrades when upgrade menu is visible
		if (upgradeMenu && upgradeMenu.visible) {
			return;
		}
		if (self.attackCooldown > 0) {
			self.attackCooldown--;
		}
		// Update shield visibility based on shield status
		self.shieldGraphics.visible = self.shieldActive;
		if (self.shieldActive) {
			// Animate shield with pulsing effect
			var pulse = 1 + Math.sin(LK.ticks * 0.15) * 0.2;
			self.shieldGraphics.scaleX = 3 * pulse;
			self.shieldGraphics.scaleY = 3 * pulse;
			// Slowly rotate shield
			self.shieldGraphics.rotation += 0.03;
			// Add glowing effect
			self.shieldGraphics.alpha = 0.6 + Math.sin(LK.ticks * 0.1) * 0.2;
		}
		// Force Push upgrade - push all enemies backward every 4 seconds
		if (self.forcePushLevel && self.forcePushLevel > 0) {
			if (!self.forcePushTimer) {
				self.forcePushTimer = 0;
			}
			self.forcePushTimer++;
			if (self.forcePushTimer >= 240) {
				// 4 seconds at 60fps
				self.forcePushTimer = 0;
				self.activateForcePush();
			}
		}
		// Freeze Pulse upgrade - freeze all enemies every 4 seconds
		if (self.freezePulseLevel && self.freezePulseLevel > 0) {
			if (!self.freezePulseTimer) {
				self.freezePulseTimer = 0;
			}
			self.freezePulseTimer++;
			if (self.freezePulseTimer >= 240) {
				// 4 seconds at 60fps
				self.freezePulseTimer = 0;
				self.activateFreezePulse();
			}
		}
		// Fire Ball upgrade - launch fire ball with improved timing
		if (self.fireBallLevel && self.fireBallLevel > 0) {
			if (!self.fireBallTimer) {
				self.fireBallTimer = 0;
			}
			self.fireBallTimer++;
			var fireBallInterval = upgradeLevels.fireBall > 1 ? 120 : 180; // 2s vs 3s
			if (self.fireBallTimer >= fireBallInterval) {
				self.fireBallTimer = 0;
				self.launchFireBall();
			}
		}
		// Thorns upgrade - spawn spikes along all paths every 3 seconds
		if (self.thornsLevel && self.thornsLevel > 0) {
			if (!self.thornsTimer) {
				self.thornsTimer = 0;
			}
			self.thornsTimer++;
			if (self.thornsTimer >= 180) {
				// Always 3 seconds (180 ticks at 60fps)
				self.thornsTimer = 0;
				self.activateThorns();
			}
		}
		// Animation system - cycle through wizard frames
		self.animationTimer++;
		if (self.animationTimer >= self.animationSpeed) {
			self.animationTimer = 0;
			// Hide current frame
			self.wizardFrames[self.currentFrame - 1].visible = false;
			// Move to next frame
			self.currentFrame++;
			if (self.currentFrame > 4) {
				self.currentFrame = 1;
			}
			// Show new frame
			self.wizardFrames[self.currentFrame - 1].visible = true;
		}
	};
	self.attack = function (direction) {
		if (self.attackCooldown <= 0) {
			// Default direction if none specified
			if (direction === undefined) {
				direction = 0; // Default to center path
			}
			// Get attack angle based on path direction
			var attackAngle = pathAngles[direction];
			var attackDistance = 100;
			// Calculate spell position based on attack direction
			var spellX = self.x + Math.cos(attackAngle) * attackDistance;
			var spellY = self.y + Math.sin(attackAngle) * attackDistance;
			// Create spell effect
			var spell = game.addChild(LK.getAsset('spell', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: spellX,
				y: spellY,
				scaleX: 0.5,
				scaleY: 0.5
			}));
			// Animate spell with magical effects
			tween(spell, {
				scaleX: 2,
				scaleY: 2,
				alpha: 0
			}, {
				duration: 500,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					spell.destroy();
				}
			});
			// Add rotation animation to spell
			tween(spell, {
				rotation: Math.PI * 2
			}, {
				duration: 500,
				easing: tween.linear
			});
			self.attackCooldown = 30; // 0.5 seconds at 60fps
			LK.getSound('spellCast').play();
			// Base damage without spell power upgrades
			var totalDamage = 1;
			// Attack enemies in the specified direction/path
			for (var i = enemies.length - 1; i >= 0; i--) {
				var enemy = enemies[i];
				if (enemy.pathIndex === direction) {
					// Only hit enemies on exact same path - no distance validation
					enemy.takeDamage(totalDamage);
				}
			}
			// Attack ogres in the specified direction/path
			for (var i = ogres.length - 1; i >= 0; i--) {
				var ogre = ogres[i];
				if (ogre.pathIndex === direction) {
					// Only hit ogres on exact same path - no distance validation
					ogre.takeDamage(totalDamage);
				}
			}
			// Attack knights in the specified direction/path
			for (var i = knights.length - 1; i >= 0; i--) {
				var knight = knights[i];
				if (knight.pathIndex === direction) {
					// Only hit knights on exact same path - no distance validation
					knight.takeDamage(totalDamage);
				}
			}
			return true;
		}
		return false;
	};
	self.gainExperience = function (amount) {
		self.experience += amount;
		var expNeeded = self.level * 100;
		if (self.experience >= expNeeded) {
			self.levelUp();
		}
	};
	self.levelUp = function () {
		self.level++;
		self.experience = 0;
		// Visual level up effect
		LK.effects.flashObject(self, 0xFFD700, 500);
	};
	self.takeDamage = function (damage) {
		// Check if shield is active
		if (self.shieldActive) {
			// Initialize shield properties if not set
			if (self.maxShieldHits === undefined) {
				self.maxShieldHits = 1;
				self.currentShieldHits = 0;
			}
			// Increment shield hits
			self.currentShieldHits++;
			// Visual feedback for shield use
			LK.effects.flashObject(self, 0x00BFFF, 300);
			// Check if shield is depleted
			if (self.currentShieldHits >= self.maxShieldHits) {
				self.shieldActive = false;
				// Start shield regeneration timer
				var regenTime = self.shieldRegen ? 5000 : 10000; // Faster regen if improved
				tween({}, {}, {
					duration: regenTime,
					onFinish: function onFinish() {
						// Regenerate shield
						self.shieldActive = true;
						self.currentShieldHits = 0;
						// Visual feedback for shield regeneration
						LK.effects.flashObject(self, 0x00BFFF, 500);
						// Add shield regeneration animation
						tween(self.shieldGraphics, {
							scaleX: 5,
							scaleY: 5,
							alpha: 1.0
						}, {
							duration: 600,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								tween(self.shieldGraphics, {
									scaleX: 3,
									scaleY: 3,
									alpha: 0.7
								}, {
									duration: 400,
									easing: tween.easeIn
								});
							}
						});
					}
				});
			}
			// No damage taken, shield absorbed it
			return;
		}
		self.health -= damage;
		if (self.health <= 0) {
			self.health = 0;
			// 10% chance to revive when dying
			var reviveChance = Math.random();
			if (reviveChance < 0.10) {
				// Revival successful!
				self.health = Math.floor(self.maxHealth * 0.5); // Revive with 50% health
				// Destroy ALL enemies when revival activates (no distance restriction)
				var allEnemies = enemies.concat(ogres).concat(knights).concat(miniBosses);
				for (var enemyIdx = allEnemies.length - 1; enemyIdx >= 0; enemyIdx--) {
					var enemy = allEnemies[enemyIdx];
					// Create destruction effect for each enemy
					LK.effects.flashObject(enemy, 0xFFD700, 500);
					// Create golden explosion particles
					for (var particleIdx = 0; particleIdx < 8; particleIdx++) {
						var destructionParticle = game.addChild(LK.getAsset('energySphere', {
							anchorX: 0.5,
							anchorY: 0.5,
							x: enemy.x,
							y: enemy.y,
							scaleX: 0.5,
							scaleY: 0.5
						}));
						destructionParticle.tint = 0xFFD700;
						destructionParticle.alpha = 0.9;
						// Random explosion direction
						var explosionAngle = particleIdx / 8 * Math.PI * 2;
						var explosionSpeed = 60 + Math.random() * 40;
						var explosionTargetX = enemy.x + Math.cos(explosionAngle) * explosionSpeed;
						var explosionTargetY = enemy.y + Math.sin(explosionAngle) * explosionSpeed;
						// Animate explosion particle
						tween(destructionParticle, {
							x: explosionTargetX,
							y: explosionTargetY,
							scaleX: 0.1,
							scaleY: 0.1,
							alpha: 0
						}, {
							duration: 400 + Math.random() * 200,
							easing: tween.easeOut,
							onFinish: function onFinish() {
								destructionParticle.destroy();
							}
						});
					}
					// Kill ALL enemies instantly by calling die() method
					enemy.die();
				}
				// Visual effects for revival
				LK.effects.flashScreen(0x00FF00, 1500); // Green flash for revival
				LK.effects.flashObject(self, 0xFFD700, 1000); // Golden flash on wizard
				// Reduced revival particles for better performance
				for (var reviveIdx = 0; reviveIdx < 8; reviveIdx++) {
					var reviveParticle = game.addChild(LK.getAsset('energySphere', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: self.x + (Math.random() - 0.5) * 200,
						y: self.y + (Math.random() - 0.5) * 200,
						scaleX: 1.0,
						scaleY: 1.0
					}));
					reviveParticle.tint = 0x00FF00;
					reviveParticle.alpha = 0.9;
					// Animate revival particles toward wizard
					tween(reviveParticle, {
						x: self.x,
						y: self.y,
						scaleX: 0.3,
						scaleY: 0.3,
						alpha: 0
					}, {
						duration: 600,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							reviveParticle.destroy();
						}
					});
				}
				// Create healing aura effect
				var healingAura = game.addChild(LK.getAsset('shield', {
					anchorX: 0.5,
					anchorY: 0.5,
					x: self.x,
					y: self.y,
					scaleX: 1,
					scaleY: 1
				}));
				healingAura.tint = 0x00FF00;
				healingAura.alpha = 0.8;
				// Animate healing aura expansion
				tween(healingAura, {
					scaleX: 8,
					scaleY: 8,
					alpha: 0
				}, {
					duration: 1200,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						healingAura.destroy();
					}
				});
				// Play spell cast sound for revival
				LK.getSound('spellCast').play();
				// Update health bar to show revival
				updateHealthBar();
				// Update medal statistics
				if (!storage.totalRevives) storage.totalRevives = 0;
				storage.totalRevives++;
			} else {
				// Game over when health reaches 0 and no revival
				LK.effects.flashScreen(0xFF0000, 1000);
				LK.showGameOver();
			}
		}
		// Update health bar
		updateHealthBar();
		// Simplified screen shake for better performance
		var shakeIntensity = 15;
		var originalX = game.x;
		var originalY = game.y;
		// Simple single shake effect
		tween(game, {
			x: originalX + shakeIntensity,
			y: originalY + shakeIntensity * 0.5
		}, {
			duration: 100,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(game, {
					x: originalX,
					y: originalY
				}, {
					duration: 100,
					easing: tween.easeIn
				});
			}
		});
		// Flash red when hit
		LK.effects.flashObject(self, 0xFF0000, 200);
	};
	self.activateForcePush = function () {
		// Visual effect for force push activation
		LK.effects.flashScreen(0x8A2BE2, 300); // Purple flash
		LK.effects.flashObject(self, 0x8A2BE2, 500); // Purple flash on wizard
		// Push back all enemies with improved effects
		var allEnemies = enemies.concat(ogres).concat(knights).concat(miniBosses);
		for (var i = 0; i < allEnemies.length; i++) {
			var enemy = allEnemies[i];
			// Calculate direction from wizard to enemy
			var dx = enemy.x - self.x;
			var dy = enemy.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				// Improved force push: stronger push and damage
				var pushDistance = upgradeLevels.forcePush > 1 ? 300 : 200; // Stronger push
				var pushX = dx / distance * pushDistance;
				var pushY = dy / distance * pushDistance;
				// Calculate new position
				var newX = enemy.x + pushX;
				var newY = enemy.y + pushY;
				// Ensure enemies don't go off screen
				newX = Math.max(50, Math.min(1998, newX));
				newY = Math.max(-100, Math.min(2732, newY));
				// Animate the push effect
				tween(enemy, {
					x: newX,
					y: newY
				}, {
					duration: 300,
					easing: tween.easeOut
				});
				// Improved force push: deal damage
				if (upgradeLevels.forcePush > 1) {
					enemy.takeDamage(50);
				}
				// Visual effect on each enemy
				LK.effects.flashObject(enemy, 0x8A2BE2, 200);
			}
		}
	};
	self.activateFreezePulse = function () {
		// Visual effect for freeze pulse activation
		LK.effects.flashScreen(0x87CEEB, 500); // Light blue flash
		LK.effects.flashObject(self, 0x87CEEB, 700); // Light blue flash on wizard
		// Play freeze sound effect
		LK.getSound('iceFreeze').play();
		// Freeze all enemies with improved effects
		var allEnemies = enemies.concat(ogres).concat(knights).concat(miniBosses);
		for (var i = 0; i < allEnemies.length; i++) {
			var enemy = allEnemies[i];
			// Improved freeze: longer duration and damage
			var freezeDuration = upgradeLevels.freezePulse > 1 ? 120 : 60; // 2s vs 1s
			enemy.frozen = true;
			enemy.frozenTimer = freezeDuration;
			// Improved freeze: deal damage
			if (upgradeLevels.freezePulse > 1) {
				enemy.takeDamage(30);
			}
			// Visual freeze effect - tint enemy light blue
			tween(enemy, {
				tint: 0x87CEEB
			}, {
				duration: 100,
				easing: tween.easeOut
			});
			// Reduced ice crystal particles for better performance
			if (i % 2 === 0) {
				// Only create effects for every other enemy
				for (var iceIdx = 0; iceIdx < 3; iceIdx++) {
					var iceCrystal = game.addChild(LK.getAsset('spell', {
						anchorX: 0.5,
						anchorY: 0.5,
						x: enemy.x + (Math.random() - 0.5) * 60,
						y: enemy.y + (Math.random() - 0.5) * 60,
						scaleX: 1.0,
						scaleY: 1.0
					}));
					iceCrystal.tint = 0x87CEEB;
					iceCrystal.alpha = 0.9;
					// Create floating ice effect
					tween(iceCrystal, {
						y: iceCrystal.y - 30,
						scaleX: 0.3,
						scaleY: 0.3,
						alpha: 0
					}, {
						duration: 600,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							iceCrystal.destroy();
						}
					});
				}
			}
			// Remove freeze tint after frozen state ends
			var visualDuration = upgradeLevels.freezePulse > 1 ? 2000 : 1000;
			tween({}, {}, {
				duration: visualDuration,
				onFinish: function onFinish() {
					if (enemy && enemy.parent) {
						// Remove freeze tint after frozen effect ends
						tween(enemy, {
							tint: 0xFFFFFF
						}, {
							duration: 200,
							easing: tween.easeIn
						});
					}
				}
			});
		}
	};
	self.activateThorns = function () {
		// Visual effect for thorns activation
		LK.effects.flashScreen(0x8B4513, 300); // Brown flash
		LK.effects.flashObject(self, 0x8B4513, 500); // Brown flash on wizard
		// Find the closest enemy to the wizard
		var closestEnemy = null;
		var closestDistance = Infinity;
		var allEnemies = enemies.concat(ogres).concat(knights).concat(miniBosses);
		for (var i = 0; i < allEnemies.length; i++) {
			var enemy = allEnemies[i];
			var dx = enemy.x - self.x;
			var dy = enemy.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < closestDistance) {
				closestDistance = distance;
				closestEnemy = enemy;
			}
		}
		// Only create spikes if there is a closest enemy
		if (!closestEnemy) {
			LK.getSound('spellCast').play();
			return;
		}
		// Create spikes only along the closest enemy's path
		var pathIdx = closestEnemy.pathIndex;
		var pathAngle = pathAngles[pathIdx];
		// Calculate spawn position for this path (same as enemy spawning)
		var spawnX, spawnY;
		if (pathIdx === 0) {
			// Center path - spawn at top edge
			spawnX = 2048 / 2;
			spawnY = -100;
		} else if (pathIdx === 1) {
			// Path 2 - spawn at top right edge
			spawnX = 2048 + 50;
			spawnY = -50;
		} else if (pathIdx === 2) {
			// Path 3 - spawn at top left edge
			spawnX = -50;
			spawnY = -50;
		} else if (pathIdx === 3) {
			// Path 4 - spawn at left edge
			spawnX = -100;
			spawnY = 2732 / 2 + 400;
		} else if (pathIdx === 4) {
			// Path 5 - spawn at right edge
			spawnX = 2048 + 100;
			spawnY = 2732 / 2 + 400;
		}
		// Calculate wizard position (same as enemy targeting)
		var wizardX = self.x;
		var wizardY = self.y;
		// Calculate path distance and divide into 3 sections with gaps
		var pathDistance = Math.sqrt((spawnX - wizardX) * (spawnX - wizardX) + (spawnY - wizardY) * (spawnY - wizardY));
		var sectionLength = pathDistance / 5; // Each section is 1/5 of total path
		var gapLength = pathDistance / 10; // Gaps are 1/10 of total path
		// Define 3 sections along the path with gaps between them
		var sections = [{
			start: 0.1,
			end: 0.3
		},
		// First section: 10% to 30% along path
		{
			start: 0.45,
			end: 0.65
		},
		// Second section: 45% to 65% along path
		{
			start: 0.8,
			end: 1.0
		} // Third section: 80% to 100% along path
		];
		// Create spikes in reverse sequential order: last section, then middle, then first
		var sectionOrder = [2, 1, 0]; // Create sections starting from farthest outward toward wizard
		for (var orderIdx = 0; orderIdx < sectionOrder.length; orderIdx++) {
			var sectionIdx = sectionOrder[orderIdx];
			var section = sections[sectionIdx];
			var sectionStartDistance = pathDistance * section.start;
			var sectionEndDistance = pathDistance * section.end;
			var spikeSpacing = 150; // Distance between spikes within each section
			// Calculate number of spikes in this section
			var sectionLength = sectionEndDistance - sectionStartDistance;
			var numSpikesInSection = Math.floor(sectionLength / spikeSpacing);
			// Calculate delay for sequential appearance
			var baseDelay = orderIdx * 300; // 300ms delay between sections
			// Create spikes within this section with sequential timing
			for (var s = 0; s < numSpikesInSection; s++) {
				var spikeDistanceInSection = s * spikeSpacing + spikeSpacing / 2;
				var totalSpikeDistance = sectionStartDistance + spikeDistanceInSection;
				var progress = totalSpikeDistance / pathDistance;
				var spikeX = spawnX + (wizardX - spawnX) * progress;
				var spikeY = spawnY + (wizardY - spawnY) * progress;
				// Only create spike if position is within game bounds
				if (spikeX >= 0 && spikeX <= 2048 && spikeY >= 0 && spikeY <= 2732) {
					// Create spike with delay
					(function (delayTime, spikeX, spikeY, pathIdx) {
						tween({}, {}, {
							duration: delayTime,
							onFinish: function onFinish() {
								var spike = game.addChild(LK.getAsset('spell', {
									anchorX: 0.5,
									anchorY: 0.5,
									x: spikeX,
									y: spikeY,
									scaleX: 0.1,
									scaleY: 0.1
								}));
								spike.tint = 0x8B4513; // Brown color for thorns
								spike.pathIndex = pathIdx;
								// Initialize hit tracking for this spike
								spike.hitEnemies = [];
								// Set spike to be visible immediately
								spike.alpha = 1.0;
								spike.scaleX = 1.5;
								spike.scaleY = 1.5;
								// Animate spike emerging from ground
								tween(spike, {
									scaleX: 2.5,
									scaleY: 2.5,
									alpha: 1.0
								}, {
									duration: 200,
									easing: tween.easeOut,
									onFinish: function onFinish() {
										// Spike stays for a moment then disappears
										tween(spike, {
											scaleX: 0.1,
											scaleY: 0.1,
											alpha: 0
										}, {
											duration: 800,
											easing: tween.easeIn,
											onFinish: function onFinish() {
												spike.destroy();
											}
										});
									}
								});
							}
						});
					})(baseDelay + s * 50, spikeX, spikeY, pathIdx); // 50ms delay between spikes in same section
				}
			}
		}
		LK.getSound('spellCast').play();
	};
	self.launchFireBall = function () {
		// Visual effect for fire ball launch
		LK.effects.flashScreen(0xFF4500, 300); // Orange flash
		LK.effects.flashObject(self, 0xFF4500, 500); // Orange flash on wizard
		// Create fire ball projectile at wizard position
		var fireBall = game.addChild(new FireBall());
		fireBall.x = self.x;
		fireBall.y = self.y;
		// Find closest enemy to target
		var closestEnemy = null;
		var closestDistance = Infinity;
		var allEnemies = enemies.concat(ogres).concat(knights).concat(miniBosses);
		for (var i = 0; i < allEnemies.length; i++) {
			var enemy = allEnemies[i];
			var dx = enemy.x - self.x;
			var dy = enemy.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < closestDistance) {
				closestDistance = distance;
				closestEnemy = enemy;
			}
		}
		// Set fire ball direction toward closest enemy or default direction
		if (closestEnemy) {
			var dx = closestEnemy.x - self.x;
			var dy = closestEnemy.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				fireBall.direction.x = dx / distance;
				fireBall.direction.y = dy / distance;
			}
		} else {
			// Default direction upward if no enemies
			fireBall.direction.x = 0;
			fireBall.direction.y = -1;
		}
		LK.getSound('spellCast').play();
		LK.getSound('fireWhoosh').play();
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000 // Black background for pixel art
});
/**** 
* Game Code
****/ 
// Game state variables
var gameStarted = false;
var gameMenu;
var upgradeMenu;
var upgradeMenuShown = false;
var secondUpgradeMenuShown = false;
var thirdUpgradeMenuShown = false;
var fourthUpgradeMenuShown = false;
var selectedEnemy = null; // Track currently selected enemy for projectile targeting
var energySphere = null; // Track energy sphere instance
// Upgrade level tracking system
var upgradeLevels = {
	shield: 0,
	healthBoost: 0,
	lifeDrain: 0,
	energySphere: 0,
	forcePush: 0,
	spellPower: 0,
	thorns: 0,
	fireBall: 0,
	freezePulse: 0,
	orbs: 0
};
// Game arrays to track objects
var enemies = [];
var ogres = [];
var knights = [];
var miniBosses = [];
var coins = [];
var projectiles = [];
// Path combo system variables
var pathKillCounts = [0, 0, 0, 0, 0]; // Track kills per path (5 paths)
var nextProjectileDoubleDamage = false; // Flag for double damage on next projectile
// Create and show game menu
gameMenu = game.addChild(new GameMenu());
// Create upgrade menu (initially hidden)
upgradeMenu = game.addChild(new UpgradeMenu());
upgradeMenu.visible = false;
// Create prestige medals menu (initially hidden)
var prestigeMedals = game.addChild(new PrestigeMedals());
prestigeMedals.visible = false;
// Create 5 stone paths leading toward the wizard position
var paths = [];
var knightX = 2048 / 2;
var knightY = 2732 - 250;
// Create paths: all pointing toward the wizard position
var pathAngles = [-Math.PI / 2,
// Center (straight down toward wizard)
-Math.PI / 3,
// Diagonal right toward wizard
-2 * Math.PI / 3,
// Diagonal left toward wizard
Math.PI / 6,
// Path 4: opposite to path 2 (diagonal left)
5 * Math.PI / 6 // Path 5: opposite to path 3 (diagonal right)
]; // 5 paths: all directed toward wizard position
// Create multiple stone segments for each path to form visible stone roads
for (var p = 0; p < 5; p++) {
	var angle = pathAngles[p];
	// Calculate distance from spawn point to wizard position
	var wizardX = knightX;
	var wizardY = 2732 - 600; // Wizard position
	var spawnDistance = p === 0 ? 2000 : p === 3 || p === 4 ? 1200 : 1800; // Distance from wizard to spawn point
	// Set spawn points to screen edges for all paths
	var spawnX, spawnY;
	if (p === 0) {
		// Center path - spawn at top edge
		spawnX = 2048 / 2;
		spawnY = -100;
	} else if (p === 1) {
		// Path 2 - spawn at top right edge
		spawnX = 2048 + 50;
		spawnY = -50;
	} else if (p === 2) {
		// Path 3 - spawn at top left edge
		spawnX = -50;
		spawnY = -50;
	} else if (p === 3) {
		// Path 4 - spawn at left edge
		spawnX = -100;
		spawnY = 2732 / 2 + 400;
	} else if (p === 4) {
		// Path 5 - spawn at right edge
		spawnX = 2048 + 100;
		spawnY = 2732 / 2 + 400;
	}
	// Calculate actual path length from spawn point to wizard
	var actualPathLength = Math.sqrt((spawnX - wizardX) * (spawnX - wizardX) + (spawnY - wizardY) * (spawnY - wizardY));
	var segmentSize = 120; // Size of each stone segment
	var numSegments = Math.floor(actualPathLength / segmentSize);
	// Create individual stone segments along the path from spawn point toward wizard
	for (var s = 0; s < numSegments; s++) {
		var segmentDistance = s * segmentSize + segmentSize / 2;
		var segmentX = spawnX - Math.cos(angle) * segmentDistance;
		var segmentY = spawnY - Math.sin(angle) * segmentDistance;
		// Only create segments that are within the visible game area
		if (segmentX >= -100 && segmentX <= 2148 && segmentY >= -100 && segmentY <= 2832) {
			// Create stone path segment
			var stoneSegment = game.addChild(LK.getAsset('stonePath', {
				anchorX: 0.5,
				anchorY: 0.5,
				x: segmentX,
				y: segmentY,
				scaleX: 2.0,
				scaleY: 2.0,
				rotation: angle + Math.PI / 2 // Rotate stone to align with path
			}));
			// Make stone paths completely invisible
			stoneSegment.alpha = 0; // Make completely invisible
			stoneSegment.visible = false; // Initially hidden, will be shown when game starts
			stoneSegment.pathIndex = p;
		}
	}
}
// Create invisible path collision areas for touch detection
for (var p = 0; p < 5; p++) {
	var angle = pathAngles[p];
	// Calculate distance from spawn point to wizard position
	var wizardX = knightX;
	var wizardY = 2732 - 600; // Wizard position
	var spawnDistance = p === 0 ? 3000 : p === 3 || p === 4 ? 1200 : 1800; // Distance from wizard to spawn point
	var spawnX = wizardX + Math.cos(angle) * spawnDistance;
	var spawnY = wizardY + Math.sin(angle) * spawnDistance;
	// Move all spawn points to screen edges
	if (p === 0) {
		// Center path - spawn at top edge
		spawnX = 2048 / 2;
		spawnY = -100;
	} else if (p === 1) {
		// Path 2 - spawn at top right edge
		spawnX = 2048 + 50;
		spawnY = -50;
	} else if (p === 2) {
		// Path 3 - spawn at top left edge
		spawnX = -50;
		spawnY = -50;
	} else if (p === 3) {
		// Path 4 - spawn at left edge
		spawnX = -100;
		spawnY = 2732 / 2 + 400;
	} else if (p === 4) {
		// Path 5 - spawn at right edge
		spawnX = 2048 + 100;
		spawnY = 2732 / 2 + 400;
	}
	// Calculate actual path length from spawn point to wizard
	var actualPathLength = Math.sqrt((spawnX - wizardX) * (spawnX - wizardX) + (spawnY - wizardY) * (spawnY - wizardY));
	var centerX = (spawnX + wizardX) / 2;
	var centerY = (spawnY + wizardY) / 2;
	// Create invisible collision path
	var path = game.addChild(LK.getAsset('pathSelector', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: centerX,
		y: centerY,
		scaleX: 4,
		scaleY: actualPathLength / 60,
		rotation: angle + Math.PI / 2
	}));
	// Make collision path completely invisible
	path.alpha = 0;
	path.visible = false;
	path.pathIndex = p;
	// Add numbered text label for each path
	var pathNumber = new Text2((p + 1).toString(), {
		size: 120,
		fill: 0xFFD700,
		font: "monospace"
	});
	pathNumber.anchor.set(0.5, 0.5);
	// Position number directly at spawn point
	pathNumber.x = spawnX;
	pathNumber.y = spawnY - 80; // Position slightly above spawn point
	pathNumber.visible = false; // Initially hidden, will be shown when game starts
	pathNumber.pathIndex = p;
	game.addChild(pathNumber);
	// Add touch handler for directional attacks
	path.down = function (x, y, obj) {
		// Attack in this path's direction
		wizard.attack(obj.pathIndex);
		// Visual feedback - no flash for invisible paths
		// Paths remain invisible when tapped
	};
	paths.push(path);
}
// Pixel art scaling handled by engine automatically
// Set fondodelacueva as the actual game background
var backgroundMap = game.addChild(LK.getAsset('fondodelacueva', {
	anchorX: 0,
	anchorY: 0,
	scaleX: 19.5,
	scaleY: 26.0,
	x: 0,
	y: 0
}));
// Send background to the back but use a less extreme z-index
backgroundMap.zIndex = -100;
// Hide background initially during menu
backgroundMap.visible = false;
backgroundMap.alpha = 1.0;
// Create wizard
var wizard = game.addChild(new Wizard());
wizard.x = knightX;
wizard.y = 2732 - 600; // Position wizard higher on screen
wizard.visible = false;
// UI Elements
// Removed scoreText and levelText to eliminate stray characters in top right
var coinCounter = 0;
var enemyKillCounter = 0;
var coinText = new Text2('Coins: 0', {
	size: 60,
	fill: 0xFFD700,
	font: "monospace"
});
coinText.anchor.set(0, 0);
LK.gui.topLeft.addChild(coinText);
coinText.x = 120;
coinText.y = 90;
coinText.visible = false;
var killCountText = new Text2('Puntuacion: 0', {
	size: 60,
	fill: 0xFF6B6B,
	font: "monospace"
});
killCountText.anchor.set(0, 0);
LK.gui.topLeft.addChild(killCountText);
killCountText.x = 120;
killCountText.y = 150;
killCountText.visible = false;
var tapText = new Text2('TAP TO CAST SPELLS!', {
	size: 100,
	fill: 0xFF6B6B,
	font: "monospace"
});
tapText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(tapText);
tapText.y = -200;
tapText.visible = false;
// Health bar UI
var healthBarBg = LK.getAsset('healthBarBg', {
	anchorX: 0,
	anchorY: 0
});
LK.gui.topLeft.addChild(healthBarBg);
healthBarBg.x = 120;
healthBarBg.y = 20;
healthBarBg.visible = false;
var healthBar = LK.getAsset('healthBar', {
	anchorX: 0,
	anchorY: 0
});
LK.gui.topLeft.addChild(healthBar);
healthBar.x = 120;
healthBar.y = 20;
healthBar.visible = false;
var healthText = new Text2('Health: 100/100', {
	size: 50,
	fill: 0xFFFFFF,
	font: "monospace"
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120;
healthText.y = 50;
healthText.visible = false;
function updateHealthBar() {
	var healthPercent = wizard.health / wizard.maxHealth;
	healthBar.scaleX = healthPercent;
	healthText.setText('Health: ' + wizard.health + '/' + wizard.maxHealth);
	// Change color based on health
	if (healthPercent > 0.6) {
		healthBar.tint = 0x00ff00; // Green
	} else if (healthPercent > 0.3) {
		healthBar.tint = 0xffff00; // Yellow
	} else {
		healthBar.tint = 0xff0000; // Red
	}
}
// Enemy spawning variables
var enemySpawnTimer = 0;
var lastSpawnedPath = -1; // Track the last spawned path
var consecutiveSpawns = 0; // Track consecutive spawns from same path
// Cooldown system variables
var pathLastSpawnTime = [-1, -1, -1, -1, -1]; // Track last spawn time for each path
var pathConsecutiveSpawns = [0, 0, 0, 0, 0]; // Track consecutive spawns per path
var pathCooldownDuration = 300; // 5 seconds at 60fps
// Game input handling
game.down = function (x, y, obj) {
	// Check if a path was tapped for directional attack
	var pathTapped = false;
	for (var p = 0; p < paths.length; p++) {
		var path = paths[p];
		// Convert tap position to path's local coordinates
		var localPos = path.toLocal({
			x: x,
			y: y
		});
		// Check if tap is within path bounds
		if (Math.abs(localPos.x) < path.width / 2 && Math.abs(localPos.y) < path.height / 2) {
			// Attack in this path's direction
			wizard.attack(path.pathIndex);
			pathTapped = true;
			break;
		}
	}
	// No default attack - player must tap a path to attack
};
// Main game update loop
game.update = function () {
	// Sort children by z-index to ensure proper rendering order
	game.children.sort(function (a, b) {
		return (a.zIndex || 0) - (b.zIndex || 0);
	});
	// Only update game logic if game has started
	if (!gameStarted) {
		return;
	}
	// Change music to epic battle theme at 10 enemies killed
	if (enemyKillCounter === 10) {
		LK.playMusic('epicBattle', {
			volume: 0.8,
			fade: {
				start: 0,
				end: 0.8,
				duration: 1500
			}
		});
	}
	// Change to mystical ambient music at 25 enemies killed
	if (enemyKillCounter === 25) {
		LK.playMusic('mysticalAmbient', {
			volume: 0.6,
			fade: {
				start: 0,
				end: 0.6,
				duration: 2000
			}
		});
	}
	// Show upgrade menu after 12 enemies are killed
	if (enemyKillCounter >= 12 && !upgradeMenuShown) {
		upgradeMenuShown = true;
		// Increase upgrade costs by 5 coins when menu is shown
		if (!upgradeMenu.upgradeCost) {
			upgradeMenu.upgradeCost = 5; // Initial cost
		}
		upgradeMenu.upgradeCost += 5; // Increase by 5 coins each time
		// Update all upgrade text to show new costs
		upgradeMenu.updateUpgradeCosts();
		upgradeMenu.visible = true;
		upgradeMenu.cooldownTimer = upgradeMenu.cooldownDuration; // Start 2-second cooldown
		gameStarted = false; // Pause game while menu is open
		// Keep music playing during upgrade menu
		// Clear all enemies on screen when upgrade menu is shown
		for (var i = enemies.length - 1; i >= 0; i--) {
			var enemy = enemies[i];
			enemies.splice(i, 1);
			enemy.destroy();
		}
		// Clear all ogres on screen when upgrade menu is shown
		for (var i = ogres.length - 1; i >= 0; i--) {
			var ogre = ogres[i];
			ogres.splice(i, 1);
			ogre.destroy();
		}
		// Clear all knights on screen when upgrade menu is shown
		for (var i = knights.length - 1; i >= 0; i--) {
			var knight = knights[i];
			knights.splice(i, 1);
			knight.destroy();
		}
	}
	// Show upgrade menu again after 35 enemies are killed
	if (enemyKillCounter >= 35 && upgradeMenuShown && !secondUpgradeMenuShown) {
		secondUpgradeMenuShown = true;
		// Increase upgrade costs by 5 coins when menu is shown
		if (!upgradeMenu.upgradeCost) {
			upgradeMenu.upgradeCost = 5; // Initial cost
		}
		upgradeMenu.upgradeCost += 5; // Increase by 5 coins each time
		// Update all upgrade text to show new costs
		upgradeMenu.updateUpgradeCosts();
		upgradeMenu.visible = true;
		upgradeMenu.cooldownTimer = upgradeMenu.cooldownDuration; // Start 2-second cooldown
		gameStarted = false; // Pause game while menu is open
		// Keep music playing during upgrade menu
		// Clear all enemies on screen when upgrade menu is shown
		for (var i = enemies.length - 1; i >= 0; i--) {
			var enemy = enemies[i];
			enemies.splice(i, 1);
			enemy.destroy();
		}
		// Clear all ogres on screen when upgrade menu is shown
		for (var i = ogres.length - 1; i >= 0; i--) {
			var ogre = ogres[i];
			ogres.splice(i, 1);
			ogre.destroy();
		}
		// Clear all knights on screen when upgrade menu is shown
		for (var i = knights.length - 1; i >= 0; i--) {
			var knight = knights[i];
			knights.splice(i, 1);
			knight.destroy();
		}
	}
	// Show third upgrade menu after 50 enemies are killed
	if (enemyKillCounter >= 50 && secondUpgradeMenuShown && !thirdUpgradeMenuShown) {
		thirdUpgradeMenuShown = true;
		// Increase upgrade costs by 5 coins when menu is shown
		if (!upgradeMenu.upgradeCost) {
			upgradeMenu.upgradeCost = 5; // Initial cost
		}
		upgradeMenu.upgradeCost += 5; // Increase by 5 coins each time
		// Update all upgrade text to show new costs
		upgradeMenu.updateUpgradeCosts();
		upgradeMenu.visible = true;
		upgradeMenu.cooldownTimer = upgradeMenu.cooldownDuration; // Start 2-second cooldown
		gameStarted = false; // Pause game while menu is open
		// Keep music playing during upgrade menu
		// Clear all enemies on screen when upgrade menu is shown
		for (var i = enemies.length - 1; i >= 0; i--) {
			var enemy = enemies[i];
			enemies.splice(i, 1);
			enemy.destroy();
		}
		// Clear all ogres on screen when upgrade menu is shown
		for (var i = ogres.length - 1; i >= 0; i--) {
			var ogre = ogres[i];
			ogres.splice(i, 1);
			ogre.destroy();
		}
		// Clear all knights on screen when upgrade menu is shown
		for (var i = knights.length - 1; i >= 0; i--) {
			var knight = knights[i];
			knights.splice(i, 1);
			knight.destroy();
		}
	}
	// Show fourth upgrade menu after 70 enemies are killed
	if (enemyKillCounter >= 70 && thirdUpgradeMenuShown && !fourthUpgradeMenuShown) {
		fourthUpgradeMenuShown = true;
		// Increase upgrade costs by 5 coins when menu is shown
		if (!upgradeMenu.upgradeCost) {
			upgradeMenu.upgradeCost = 5; // Initial cost
		}
		upgradeMenu.upgradeCost += 5; // Increase by 5 coins each time
		// Update all upgrade text to show new costs
		upgradeMenu.updateUpgradeCosts();
		upgradeMenu.visible = true;
		upgradeMenu.cooldownTimer = upgradeMenu.cooldownDuration; // Start 2-second cooldown
		gameStarted = false; // Pause game while menu is open
		// Keep music playing during upgrade menu
		// Clear all enemies on screen when upgrade menu is shown
		for (var i = enemies.length - 1; i >= 0; i--) {
			var enemy = enemies[i];
			enemies.splice(i, 1);
			enemy.destroy();
		}
		// Clear all ogres on screen when upgrade menu is shown
		for (var i = ogres.length - 1; i >= 0; i--) {
			var ogre = ogres[i];
			ogres.splice(i, 1);
			ogre.destroy();
		}
		// Clear all knights on screen when upgrade menu is shown
		for (var i = knights.length - 1; i >= 0; i--) {
			var knight = knights[i];
			knights.splice(i, 1);
			knight.destroy();
		}
	}
	// Reset consecutive spawns for paths that have cooled down (runs every frame)
	for (var pathIdx = 0; pathIdx < 5; pathIdx++) {
		// Check if enough time has passed since last spawn (cooldown expired)
		if (pathLastSpawnTime[pathIdx] !== -1 && LK.ticks - pathLastSpawnTime[pathIdx] > pathCooldownDuration) {
			// Reset consecutive spawns for this path due to cooldown
			pathConsecutiveSpawns[pathIdx] = 0;
		}
	}
	// Get stored difficulty setting
	var selectedDifficulty = storage.difficulty || 'NORMAL';
	var difficultyLevel = Math.floor(enemyKillCounter / 10); // Every 10 kills increases difficulty
	// Apply unique difficulty modifiers
	var currentSpawnRate, enemyHealthMultiplier, enemySpeedMultiplier;
	var specialMechanics = {};
	if (selectedDifficulty === 'FACIL') {
		// EASY: Slower enemies, less health, longer spawn intervals
		currentSpawnRate = Math.max(60, 120 - difficultyLevel * 5); // Much slower spawning
		enemyHealthMultiplier = 1; // No health scaling over time
		enemySpeedMultiplier = 1 + difficultyLevel * 0.20; // 20% speed increase per level
		specialMechanics.bonusCoins = true; // 50% more coins
		specialMechanics.healingChance = 0.15; // 15% chance to heal 5 HP on enemy kill
	} else if (selectedDifficulty === 'NORMAL') {
		// NORMAL: Balanced progression
		currentSpawnRate = Math.max(40, 90 - difficultyLevel * 6); // Standard spawning
		enemyHealthMultiplier = 1; // No health scaling over time
		enemySpeedMultiplier = 1 + difficultyLevel * 0.30; // 30% speed increase per level
		specialMechanics.standardRewards = true;
	} else if (selectedDifficulty === 'DIFICIL') {
		// HARD: Faster enemies, more health, shorter spawn intervals, special enemy abilities
		currentSpawnRate = Math.max(20, 60 - difficultyLevel * 4); // Much faster spawning
		enemyHealthMultiplier = 1; // No health scaling over time
		enemySpeedMultiplier = 1 + difficultyLevel * 0.50; // 50% speed increase per level
		specialMechanics.eliteEnemies = true; // 20% chance for elite enemies with double stats
		specialMechanics.aggressiveAI = true; // Enemies move more directly toward wizard
		specialMechanics.reducedCoins = true; // 25% fewer coins
	}
	// Spawn enemies (but not when mini boss is present) - limit total enemies for performance
	enemySpawnTimer++;
	var totalEnemies = enemies.length + ogres.length + knights.length + miniBosses.length;
	if (enemySpawnTimer >= currentSpawnRate && miniBosses.length === 0 && totalEnemies < 15) {
		enemySpawnTimer = 0;
		var enemy = game.addChild(new Enemy());
		// Apply base stats with difficulty scaling
		var baseHealth = 100;
		var baseSpeed = 3;
		// Apply difficulty-specific modifiers
		if (selectedDifficulty === 'FACIL') {
			enemy.health = Math.floor(baseHealth * 0.8 * enemyHealthMultiplier); // 20% less base health
			enemy.speed = baseSpeed * 0.9 * enemySpeedMultiplier; // 10% slower base speed
		} else if (selectedDifficulty === 'NORMAL') {
			enemy.health = Math.floor(baseHealth * enemyHealthMultiplier);
			enemy.speed = baseSpeed * enemySpeedMultiplier;
		} else if (selectedDifficulty === 'DIFICIL') {
			enemy.health = 100; // Set skeleton health to 100 in hard difficulty
			enemy.speed = baseSpeed * 1.1 * enemySpeedMultiplier; // 10% faster base speed
			// 20% chance for elite enemy in hard mode (only after enemy 20)
			if (Math.random() < 0.20 && enemyKillCounter >= 20) {
				enemy.health *= 2; // Double health for elite
				enemy.speed *= 1.3; // 30% faster for elite
				// Visual indicator for elite enemy
				for (var frameIdx = 0; frameIdx < enemy.skeletonFrames.length; frameIdx++) {
					enemy.skeletonFrames[frameIdx].tint = 0xFF6600; // Orange tint for elite
				}
			}
		}
		enemy.maxHealth = enemy.health;
		// Spawn enemy at a random path entrance
		var randomPathIndex;
		if (enemyKillCounter < 5) {
			// First 5 enemies spawn from center path only
			randomPathIndex = 0; // Center path
		} else {
			// After 5 enemies, spawn from any path but limit consecutive spawns with cooldown system
			// Build available paths list
			var availablePaths = [];
			for (var pathIdx = 0; pathIdx < 5; pathIdx++) {
				// If path has spawned less than 2 consecutive times, it's available
				if (pathConsecutiveSpawns[pathIdx] < 2) {
					availablePaths.push(pathIdx);
				}
			}
			// If no paths available, reset ALL paths to ensure balanced distribution
			if (availablePaths.length === 0) {
				// Reset all paths' consecutive spawn counters
				for (var pathIdx = 0; pathIdx < 5; pathIdx++) {
					pathConsecutiveSpawns[pathIdx] = 0;
					availablePaths.push(pathIdx);
				}
			}
			randomPathIndex = availablePaths[Math.floor(Math.random() * availablePaths.length)];
		}
		// Update path-specific spawn tracking
		// Always increment consecutive spawns for the selected path
		pathConsecutiveSpawns[randomPathIndex]++;
		// Update path spawn time and global tracking
		pathLastSpawnTime[randomPathIndex] = LK.ticks;
		lastSpawnedPath = randomPathIndex;
		consecutiveSpawns = pathConsecutiveSpawns[randomPathIndex];
		var pathAngle = pathAngles[randomPathIndex];
		// Store the path information on the enemy
		enemy.pathIndex = randomPathIndex;
		enemy.pathAngle = pathAngle;
		// Calculate spawn position at screen edges
		if (randomPathIndex === 0) {
			// Center path - spawn at top edge
			enemy.x = 2048 / 2;
			enemy.y = -100;
		} else if (randomPathIndex === 1) {
			// Path 2 - spawn at top right edge
			enemy.x = 2048 + 50;
			enemy.y = -50;
		} else if (randomPathIndex === 2) {
			// Path 3 - spawn at top left edge
			enemy.x = -50;
			enemy.y = -50;
		} else if (randomPathIndex === 3) {
			// Path 4 - spawn at left edge
			enemy.x = -100;
			enemy.y = 2732 / 2 + 400;
		} else if (randomPathIndex === 4) {
			// Path 5 - spawn at right edge
			enemy.x = 2048 + 100;
			enemy.y = 2732 / 2 + 400;
		}
		// Make sure enemies spawn within screen bounds
		enemy.x = Math.max(50, Math.min(1998, enemy.x));
		enemy.y = Math.max(-200, Math.min(2732 + 100, enemy.y));
		enemy.lastX = enemy.x;
		enemies.push(enemy);
		// Play ambient enemy growl sound
		if (Math.random() < 0.3) {
			LK.getSound('enemyGrowl').play();
		}
	}
	// Spawn ogres after 15 seconds (900 ticks at 60fps) but not when mini boss is present
	var ogreSpawnInterval = selectedDifficulty === 'FACIL' ? 240 : selectedDifficulty === 'DIFICIL' ? 120 : 180;
	if (LK.ticks >= 900 && LK.ticks % ogreSpawnInterval === 0 && miniBosses.length === 0) {
		// Spawn interval varies by difficulty
		var ogre = game.addChild(new Ogre());
		// Apply difficulty scaling to ogre stats
		var baseOgreHealth = 200;
		var baseOgreSpeed = 2.5;
		if (selectedDifficulty === 'FACIL') {
			ogre.health = Math.floor(baseOgreHealth * 0.8 * enemyHealthMultiplier);
			ogre.speed = baseOgreSpeed * 0.9 * enemySpeedMultiplier;
		} else if (selectedDifficulty === 'NORMAL') {
			ogre.health = Math.floor(baseOgreHealth * enemyHealthMultiplier);
			ogre.speed = baseOgreSpeed * enemySpeedMultiplier;
		} else if (selectedDifficulty === 'DIFICIL') {
			ogre.health = 200; // Set ogre health to 200 in hard difficulty
			ogre.speed = baseOgreSpeed * 1.2 * enemySpeedMultiplier;
			// 15% chance for berserker ogre in hard mode
			if (Math.random() < 0.15) {
				ogre.health *= 1.5;
				ogre.speed *= 1.4;
				// Visual indicator for berserker ogre
				for (var frameIdx = 0; frameIdx < ogre.ogreFrames.length; frameIdx++) {
					ogre.ogreFrames[frameIdx].tint = 0xFF0000; // Red tint for berserker
				}
			}
		}
		ogre.maxHealth = ogre.health;
		// Spawn ogre at a random path entrance
		var ogrePathIndex = Math.floor(Math.random() * 5);
		var ogrePathAngle = pathAngles[ogrePathIndex];
		// Store the path information on the ogre
		ogre.pathIndex = ogrePathIndex;
		ogre.pathAngle = ogrePathAngle;
		// Calculate spawn position at screen edges
		if (ogrePathIndex === 0) {
			// Center path - spawn at top edge
			ogre.x = 2048 / 2;
			ogre.y = -100;
		} else if (ogrePathIndex === 1) {
			// Path 2 - spawn at top right edge
			ogre.x = 2048 + 50;
			ogre.y = -50;
		} else if (ogrePathIndex === 2) {
			// Path 3 - spawn at top left edge
			ogre.x = -50;
			ogre.y = -50;
		} else if (ogrePathIndex === 3) {
			// Path 4 - spawn at left edge
			ogre.x = -100;
			ogre.y = 2732 / 2 + 400;
		} else if (ogrePathIndex === 4) {
			// Path 5 - spawn at right edge
			ogre.x = 2048 + 100;
			ogre.y = 2732 / 2 + 400;
		}
		// Make sure ogres spawn within screen bounds
		ogre.x = Math.max(50, Math.min(1998, ogre.x));
		ogre.y = Math.max(-200, Math.min(2732 + 100, ogre.y));
		ogre.lastX = ogre.x;
		ogres.push(ogre);
	}
	// Spawn knights after 30 enemies killed but not when mini boss is present
	var knightSpawnInterval = selectedDifficulty === 'FACIL' ? 420 : selectedDifficulty === 'DIFICIL' ? 240 : 300;
	var knightStartThreshold = selectedDifficulty === 'FACIL' ? 40 : selectedDifficulty === 'DIFICIL' ? 20 : 30;
	if (enemyKillCounter >= knightStartThreshold && LK.ticks % knightSpawnInterval === 0 && miniBosses.length === 0) {
		// Spawn timing and threshold varies by difficulty
		var knight = game.addChild(new Knight());
		// Apply difficulty scaling to knight stats
		var baseKnightHealth = 300;
		var baseKnightSpeed = 2;
		if (selectedDifficulty === 'FACIL') {
			knight.health = Math.floor(baseKnightHealth * 0.7 * enemyHealthMultiplier);
			knight.speed = baseKnightSpeed * 0.8 * enemySpeedMultiplier;
		} else if (selectedDifficulty === 'NORMAL') {
			knight.health = Math.floor(baseKnightHealth * enemyHealthMultiplier);
			knight.speed = baseKnightSpeed * enemySpeedMultiplier;
		} else if (selectedDifficulty === 'DIFICIL') {
			knight.health = 300; // Set knight health to 300 in hard difficulty
			knight.speed = baseKnightSpeed * 1.3 * enemySpeedMultiplier;
			// 10% chance for champion knight in hard mode (only after enemy 30)
			if (Math.random() < 0.10 && enemyKillCounter >= 30) {
				knight.health = 500; // Champion knight has 500 health
				knight.speed *= 1.5;
				// Visual indicator for champion knight
				for (var frameIdx = 0; frameIdx < knight.knightFrames.length; frameIdx++) {
					knight.knightFrames[frameIdx].tint = 0xFFD700; // Gold tint for champion
				}
			}
		}
		knight.maxHealth = knight.health;
		// Spawn knight at a random path entrance
		var knightPathIndex = Math.floor(Math.random() * 5);
		var knightPathAngle = pathAngles[knightPathIndex];
		// Store the path information on the knight
		knight.pathIndex = knightPathIndex;
		knight.pathAngle = knightPathAngle;
		// Calculate spawn position at screen edges
		if (knightPathIndex === 0) {
			// Center path - spawn at top edge
			knight.x = 2048 / 2;
			knight.y = -100;
		} else if (knightPathIndex === 1) {
			// Path 2 - spawn at top right edge
			knight.x = 2048 + 50;
			knight.y = -50;
		} else if (knightPathIndex === 2) {
			// Path 3 - spawn at top left edge
			knight.x = -50;
			knight.y = -50;
		} else if (knightPathIndex === 3) {
			// Path 4 - spawn at left edge
			knight.x = -100;
			knight.y = 2732 / 2 + 400;
		} else if (knightPathIndex === 4) {
			// Path 5 - spawn at right edge
			knight.x = 2048 + 100;
			knight.y = 2732 / 2 + 400;
		}
		// Make sure knights spawn within screen bounds
		knight.x = Math.max(50, Math.min(1998, knight.x));
		knight.y = Math.max(-200, Math.min(2732 + 100, knight.y));
		knight.lastX = knight.x;
		knights.push(knight);
	}
	// Spawn mini boss after 100 enemies killed
	if (enemyKillCounter >= 100 && miniBosses.length === 0) {
		var miniBoss = game.addChild(new MiniBoss());
		// Mini boss spawns from center path
		miniBoss.x = 2048 / 2;
		miniBoss.y = -200; // Spawn slightly higher up
		miniBoss.pathIndex = 0; // Center path
		miniBoss.pathAngle = pathAngles[0];
		miniBoss.lastX = miniBoss.x;
		// Initialize health bar
		miniBoss.updateHealthBar();
		miniBosses.push(miniBoss);
		// Visual announcement for mini boss arrival
		LK.effects.flashScreen(0x8B0000, 1000); // Dark red flash
	}
	// Check enemy-knight collisions and cleanup off-screen enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		// Remove enemies that went off-screen at bottom
		if (enemy.y > 2732 + 100) {
			enemies.splice(i, 1);
			enemy.destroy();
			continue;
		}
		// Initialize lastIntersecting if not set
		if (enemy.lastIntersecting === undefined) {
			enemy.lastIntersecting = false;
		}
		// Check for collision transition (only if enemy is not dying)
		var currentIntersecting = wizard.intersects(enemy);
		if (!enemy.lastIntersecting && currentIntersecting && !enemy.isDying) {
			// Damage wizard when enemy touches for the first time
			wizard.takeDamage(20);
			// Remove enemy after dealing damage
			enemies.splice(i, 1);
			enemy.destroy();
			continue;
		}
		// Update last intersecting state
		enemy.lastIntersecting = currentIntersecting;
	}
	// Check ogre-wizard collisions and cleanup off-screen ogres
	for (var i = ogres.length - 1; i >= 0; i--) {
		var ogre = ogres[i];
		// Remove ogres that went off-screen at bottom
		if (ogre.y > 2732 + 100) {
			ogres.splice(i, 1);
			ogre.destroy();
			continue;
		}
		// Initialize lastIntersecting if not set
		if (ogre.lastIntersecting === undefined) {
			ogre.lastIntersecting = false;
		}
		// Check for collision transition (only if ogre is not dying)
		var currentOgreIntersecting = wizard.intersects(ogre);
		if (!ogre.lastIntersecting && currentOgreIntersecting && !ogre.isDying) {
			// Damage wizard when ogre touches for the first time
			wizard.takeDamage(30); // Ogres deal 30 damage
			// Remove ogre after dealing damage
			ogres.splice(i, 1);
			ogre.destroy();
			continue;
		}
		// Update last intersecting state
		ogre.lastIntersecting = currentOgreIntersecting;
	}
	// Check knight-wizard collisions and cleanup off-screen knights
	for (var i = knights.length - 1; i >= 0; i--) {
		var knight = knights[i];
		// Remove knights that went off-screen at bottom
		if (knight.y > 2732 + 100) {
			knights.splice(i, 1);
			knight.destroy();
			continue;
		}
		// Initialize lastIntersecting if not set
		if (knight.lastIntersecting === undefined) {
			knight.lastIntersecting = false;
		}
		// Check for collision transition (only if knight is not dying)
		var currentKnightIntersecting = wizard.intersects(knight);
		if (!knight.lastIntersecting && currentKnightIntersecting && !knight.isDying) {
			// Damage wizard when knight touches for the first time
			wizard.takeDamage(40); // Knights deal 40 damage
			// Remove knight after dealing damage
			knights.splice(i, 1);
			knight.destroy();
			continue;
		}
		// Update last intersecting state
		knight.lastIntersecting = currentKnightIntersecting;
	}
	// Check mini boss-wizard collisions and cleanup off-screen mini bosses
	for (var i = miniBosses.length - 1; i >= 0; i--) {
		var miniBoss = miniBosses[i];
		// Remove mini bosses that went off-screen at bottom
		if (miniBoss.y > 2732 + 100) {
			miniBosses.splice(i, 1);
			miniBoss.destroy();
			continue;
		}
		// Initialize lastIntersecting if not set
		if (miniBoss.lastIntersecting === undefined) {
			miniBoss.lastIntersecting = false;
		}
		// Check for collision transition (only if mini boss is not dying)
		var currentMiniBossIntersecting = wizard.intersects(miniBoss);
		if (!miniBoss.lastIntersecting && currentMiniBossIntersecting && !miniBoss.isDying) {
			// Damage wizard when mini boss touches for the first time
			wizard.takeDamage(75); // Mini boss deals massive damage
			// Don't remove mini boss after dealing damage - it stays alive
		}
		// Update last intersecting state
		miniBoss.lastIntersecting = currentMiniBossIntersecting;
	}
	// Check thorns spike collisions with all enemies continuously
	var allSpikes = [];
	for (var childIdx = 0; childIdx < game.children.length; childIdx++) {
		var child = game.children[childIdx];
		// Check if this child is a spike (has hitEnemies array and brown tint)
		if (child.hitEnemies && child.tint === 0x8B4513) {
			allSpikes.push(child);
		}
	}
	for (var spikeIdx = 0; spikeIdx < allSpikes.length; spikeIdx++) {
		var spike = allSpikes[spikeIdx];
		var allEnemies = enemies.concat(ogres).concat(knights).concat(miniBosses);
		for (var enemyIdx = 0; enemyIdx < allEnemies.length; enemyIdx++) {
			var enemy = allEnemies[enemyIdx];
			// Only hit enemies that haven't been hit by this spike yet and are not dying
			if (spike.intersects(enemy) && spike.hitEnemies.indexOf(enemy) === -1 && !enemy.isDying) {
				var thornDamage = 100; // Always deal 100 damage
				enemy.takeDamage(thornDamage);
				LK.effects.flashObject(enemy, 0x8B4513, 300);
				// Mark this enemy as hit by this spike
				spike.hitEnemies.push(enemy);
			}
		}
	}
	// Make tap text pulse
	var pulse = 1 + Math.sin(LK.ticks * 0.1) * 0.2;
	tapText.scale.set(pulse, pulse);
};
// Remove tap text after 5 seconds
tween({}, {}, {
	duration: 5000,
	onFinish: function onFinish() {
		if (tapText && tapText.parent) {
			tapText.destroy();
		}
	}
}); ===================================================================
--- original.js
+++ change.js
@@ -4723,10 +4723,10 @@
 			enemy.speed = baseSpeed * enemySpeedMultiplier;
 		} else if (selectedDifficulty === 'DIFICIL') {
 			enemy.health = 100; // Set skeleton health to 100 in hard difficulty
 			enemy.speed = baseSpeed * 1.1 * enemySpeedMultiplier; // 10% faster base speed
-			// 20% chance for elite enemy in hard mode
-			if (Math.random() < 0.20) {
+			// 20% chance for elite enemy in hard mode (only after enemy 20)
+			if (Math.random() < 0.20 && enemyKillCounter >= 20) {
 				enemy.health *= 2; // Double health for elite
 				enemy.speed *= 1.3; // 30% faster for elite
 				// Visual indicator for elite enemy
 				for (var frameIdx = 0; frameIdx < enemy.skeletonFrames.length; frameIdx++) {