User prompt
remove the old route when new created
User prompt
When the knife button is pressed, draw a route that shows the shortest distance between the enemy and the player, and display the effect where that route meets the player's asset. the knife meets the enemy in the middle of asset. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add a knife throw button. enemies take damage when knife hits them. knives are limited to 5 for each level ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the knife button is pressed, draw a route that shows the shortest distance between the enemy and the player, and display the effect where that route meets the player's asset. remove the same thing with attack button attack button only creates punch effect not any route effect ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add a knife throw button and do this when new button is pressed. also enemies take damage when knife hits them. knives are limited to 5 for each level ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the attack button is pressed, draw a route that shows the shortest distance between the enemy and the player, and display the effect where that route meets the player's asset. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
move the movement keys away from each other and prevent them from intersecting with each other
User prompt
Show a warning with an arrow on the side where the enemy is. As you move forward, the warning will change from transparent to visible and when the enemy becomes visible on the screen, the warning will disappear. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add collision to player and mobs. they collide and They don't interfere with each other.
User prompt
make all buttons bigger and add an asset for each of them
User prompt
It should move when the movement keys are hold, not when clicked.
User prompt
add buttons for all directions to move the player, add a attack button, increase attacks range
User prompt
game is not wave based. game is level based with each level contains different type and number of enemies. you move the player and the playable map is not limited with the visble screen camera follows the char as the char moves. enemies roam randomly and starts to attack the pkayer once they sees it
Code edit (1 edits merged)
Please save this source code
User prompt
Pixel Hero Adventure
Initial prompt
a pixel game like dan the man
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.collectTimer = 0;
	self.update = function () {
		// Auto-collect after short delay
		self.collectTimer++;
		if (self.collectTimer > 30) {
			// 0.5 seconds
			self.collect();
		}
		// Spin animation
		coinGraphics.rotation += 0.1;
	};
	self.collect = function () {
		LK.getSound('coin').play();
		// 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;
});
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphics = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 1.0
	});
	self.health = 2;
	self.speed = 1;
	self.attackCooldown = 0;
	self.fromLeft = true;
	self.update = function () {
		var distanceToHero = Math.sqrt(Math.pow(self.x - hero.x, 2) + Math.pow(self.y - hero.y, 2));
		var canSeeHero = distanceToHero < 300; // Line of sight range
		if (canSeeHero) {
			// Chase hero
			var dx = hero.x - self.x;
			var dy = hero.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance > 0) {
				self.x += dx / distance * self.speed;
				self.y += dy / distance * self.speed;
				// Face direction of movement
				enemyGraphics.scaleX = dx > 0 ? 1 : -1;
			}
			// Attack hero if close enough
			if (distanceToHero < 100 && self.attackCooldown <= 0) {
				hero.takeDamage();
				self.attackCooldown = 120; // 2 seconds at 60fps
			}
		} else {
			// Roam randomly
			if (!self.roamDirection || Math.random() < 0.01) {
				self.roamDirection = {
					x: (Math.random() - 0.5) * 2,
					y: (Math.random() - 0.5) * 2
				};
			}
			var newX = self.x + self.roamDirection.x * self.speed * 0.5;
			var newY = self.y + self.roamDirection.y * self.speed * 0.5;
			// Keep within level bounds
			if (newX > 100 && newX < currentLevelData.width - 100) {
				self.x = newX;
				enemyGraphics.scaleX = self.roamDirection.x > 0 ? 1 : -1;
			}
			if (newY > 1800 && newY < 2200) {
				self.y = newY;
			}
		}
		if (self.attackCooldown > 0) {
			self.attackCooldown--;
		}
	};
	self.takeDamage = function () {
		self.health--;
		LK.effects.flashObject(self, 0xffffff, 200);
		if (self.health <= 0) {
			self.die();
		}
	};
	self.die = function () {
		// Drop coin
		var coin = game.addChild(new Coin());
		coin.x = self.x;
		coin.y = self.y;
		// Add score and combo
		var baseScore = 10;
		var comboMultiplier = Math.floor(hero.comboCount / 5) + 1;
		var finalScore = baseScore * comboMultiplier;
		LK.setScore(LK.getScore() + finalScore);
		hero.addCombo();
		// Remove from enemies array
		for (var i = enemies.length - 1; i >= 0; i--) {
			if (enemies[i] === self) {
				enemies.splice(i, 1);
				break;
			}
		}
		self.destroy();
		updateScoreDisplay();
	};
	return self;
});
var Hero = Container.expand(function () {
	var self = Container.call(this);
	var heroGraphics = self.attachAsset('hero', {
		anchorX: 0.5,
		anchorY: 1.0
	});
	self.maxHealth = 5;
	self.health = self.maxHealth;
	self.isAttacking = false;
	self.invulnerable = false;
	self.damageBoost = false;
	self.comboCount = 0;
	self.attack = function (targetX) {
		if (self.isAttacking) return;
		self.isAttacking = true;
		// Face direction of attack
		if (targetX < self.x) {
			heroGraphics.scaleX = -1;
		} else {
			heroGraphics.scaleX = 1;
		}
		// Attack animation
		tween(heroGraphics, {
			scaleY: 1.2
		}, {
			duration: 100
		});
		tween(heroGraphics, {
			scaleY: 1.0
		}, {
			duration: 100,
			onFinish: function onFinish() {
				self.isAttacking = false;
			}
		});
		// Create punch effect
		var effect = game.addChild(LK.getAsset('punchEffect', {
			anchorX: 0.5,
			anchorY: 0.5,
			alpha: 0.8
		}));
		effect.x = self.x + heroGraphics.scaleX * 80;
		effect.y = self.y - 80;
		tween(effect, {
			scaleX: 2,
			scaleY: 2,
			alpha: 0
		}, {
			duration: 200,
			onFinish: function onFinish() {
				effect.destroy();
			}
		});
		LK.getSound('punch').play();
	};
	self.takeDamage = function () {
		if (self.invulnerable) return;
		self.health--;
		self.comboCount = 0;
		// Flash red when hit
		LK.effects.flashObject(self, 0xff0000, 500);
		// Temporary invulnerability
		self.invulnerable = true;
		LK.setTimeout(function () {
			self.invulnerable = false;
		}, 1000);
		LK.getSound('hit').play();
		updateHealthDisplay();
		if (self.health <= 0) {
			LK.showGameOver();
		}
	};
	self.heal = function () {
		if (self.health < self.maxHealth) {
			self.health++;
			updateHealthDisplay();
		}
	};
	self.addCombo = function () {
		self.comboCount++;
	};
	self.move = function (direction) {
		var speed = 5;
		if (direction === 'left' && self.x > 100) {
			self.x -= speed;
			heroGraphics.scaleX = -1;
		} else if (direction === 'right' && self.x < currentLevelData.width - 100) {
			self.x += speed;
			heroGraphics.scaleX = 1;
		} else if (direction === 'up' && self.y > 1800) {
			self.y -= speed;
		} else if (direction === 'down' && self.y < 2200) {
			self.y += speed;
		}
		// Update camera target
		camera.targetX = self.x - 1024;
		camera.targetY = self.y - 1366;
		// Clamp camera to level bounds
		camera.targetX = Math.max(0, Math.min(camera.targetX, currentLevelData.width - 2048));
		camera.targetY = Math.max(0, Math.min(camera.targetY, currentLevelData.height - 2732));
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerupGraphics = self.attachAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.type = 'health'; // 'health', 'invulnerable', 'damage'
	self.lifetime = 600; // 10 seconds
	self.update = function () {
		self.lifetime--;
		if (self.lifetime <= 0) {
			self.expire();
		}
		// Check collision with hero
		if (self.intersects(hero)) {
			self.collect();
		}
		// Pulse animation
		var scale = 1 + Math.sin(LK.ticks * 0.2) * 0.2;
		powerupGraphics.scaleX = scale;
		powerupGraphics.scaleY = scale;
	};
	self.collect = function () {
		LK.getSound('powerup').play();
		if (self.type === 'health') {
			hero.heal();
		} else if (self.type === 'invulnerable') {
			hero.invulnerable = true;
			LK.setTimeout(function () {
				hero.invulnerable = false;
			}, 5000);
		} else if (self.type === 'damage') {
			hero.damageBoost = true;
			LK.setTimeout(function () {
				hero.damageBoost = false;
			}, 5000);
		}
		// Remove from powerups array
		for (var i = powerups.length - 1; i >= 0; i--) {
			if (powerups[i] === self) {
				powerups.splice(i, 1);
				break;
			}
		}
		self.destroy();
	};
	self.expire = function () {
		// Remove from powerups array
		for (var i = powerups.length - 1; i >= 0; i--) {
			if (powerups[i] === self) {
				powerups.splice(i, 1);
				break;
			}
		}
		self.destroy();
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x2c3e50
});
/**** 
* Game Code
****/ 
// Game variables
var hero;
var enemies = [];
var coins = [];
var powerups = [];
var currentLevel = 1;
var levelComplete = false;
var hearts = [];
// Camera system
var camera = {
	x: 0,
	y: 0,
	targetX: 0,
	targetY: 0,
	smoothing: 0.1
};
// Level configuration
var levels = [{
	enemies: [{
		type: 'basic',
		count: 3
	}],
	width: 4096,
	height: 2732
}, {
	enemies: [{
		type: 'basic',
		count: 5
	}, {
		type: 'strong',
		count: 2
	}],
	width: 5120,
	height: 2732
}, {
	enemies: [{
		type: 'basic',
		count: 7
	}, {
		type: 'strong',
		count: 3
	}, {
		type: 'fast',
		count: 2
	}],
	width: 6144,
	height: 2732
}];
var currentLevelData = levels[0];
// UI Elements
var scoreText = new Text2('Score: 0', {
	size: 80,
	fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 150;
scoreText.y = 50;
LK.gui.topLeft.addChild(scoreText);
var levelText = new Text2('Level: 1', {
	size: 80,
	fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 50;
var comboText = new Text2('Combo: 0x', {
	size: 60,
	fill: 0xFFFF00
});
comboText.anchor.set(1, 0);
LK.gui.topRight.addChild(comboText);
comboText.x = -50;
comboText.y = 120;
// Create hero
hero = game.addChild(new Hero());
hero.x = 1024; // Center of screen
hero.y = 2200; // Near bottom
// Create health display
function updateHealthDisplay() {
	// Remove existing hearts
	for (var i = hearts.length - 1; i >= 0; i--) {
		hearts[i].destroy();
	}
	hearts = [];
	// Create new hearts
	for (var i = 0; i < hero.health; i++) {
		var heart = LK.getAsset('heart', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		heart.x = 200 + i * 80;
		heart.y = 200;
		LK.gui.topLeft.addChild(heart);
		hearts.push(heart);
	}
}
function updateScoreDisplay() {
	scoreText.setText('Score: ' + LK.getScore());
	var comboMultiplier = Math.floor(hero.comboCount / 5) + 1;
	comboText.setText('Combo: ' + comboMultiplier + 'x');
}
function initializeLevel() {
	// Clear existing enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		enemies[i].destroy();
	}
	enemies = [];
	currentLevelData = levels[currentLevel - 1] || levels[levels.length - 1];
	levelComplete = false;
	// Spawn enemies for this level
	for (var j = 0; j < currentLevelData.enemies.length; j++) {
		var enemyGroup = currentLevelData.enemies[j];
		for (var k = 0; k < enemyGroup.count; k++) {
			spawnEnemy(enemyGroup.type);
		}
	}
	levelText.setText('Level: ' + currentLevel);
}
function spawnEnemy(type) {
	var enemy = game.addChild(new Enemy());
	// Random spawn position within level bounds
	enemy.x = 200 + Math.random() * (currentLevelData.width - 400);
	enemy.y = 1900 + Math.random() * 200;
	// Set enemy properties based on type
	if (type === 'basic') {
		enemy.health = 2;
		enemy.speed = 1;
	} else if (type === 'strong') {
		enemy.health = 4;
		enemy.speed = 0.8;
		enemy.getChildAt(0).tint = 0x8b4513; // Brown tint
	} else if (type === 'fast') {
		enemy.health = 1;
		enemy.speed = 2;
		enemy.getChildAt(0).tint = 0x00ff00; // Green tint
	}
	enemies.push(enemy);
}
function spawnPowerUp() {
	var powerup = game.addChild(new PowerUp());
	powerup.x = 500 + Math.random() * 1048; // Random x position
	powerup.y = 2000; // Above ground level
	// Random powerup type
	var types = ['health', 'invulnerable', 'damage'];
	powerup.type = types[Math.floor(Math.random() * types.length)];
	// Color by type
	var powerupGraphics = powerup.getChildAt(0);
	if (powerup.type === 'health') {
		powerupGraphics.tint = 0x00ff00; // Green
	} else if (powerup.type === 'invulnerable') {
		powerupGraphics.tint = 0x0088ff; // Blue
	} else if (powerup.type === 'damage') {
		powerupGraphics.tint = 0xff8800; // Orange
	}
	powerups.push(powerup);
}
function findNearestEnemy(x, y) {
	var nearest = null;
	var shortestDistance = Infinity;
	for (var i = 0; i < enemies.length; i++) {
		var enemy = enemies[i];
		var distance = Math.sqrt(Math.pow(enemy.x - x, 2) + Math.pow(enemy.y - y, 2));
		if (distance < shortestDistance) {
			shortestDistance = distance;
			nearest = enemy;
		}
	}
	return nearest;
}
// Initialize UI
updateHealthDisplay();
updateScoreDisplay();
// Initialize first level
initializeLevel();
// Set initial camera position
camera.targetX = hero.x - 1024;
camera.targetY = hero.y - 1366;
camera.x = camera.targetX;
camera.y = camera.targetY;
// Game input
game.down = function (x, y, obj) {
	// Convert screen coordinates to world coordinates
	var worldX = x + camera.x;
	var worldY = y + camera.y;
	// Check if tap is for movement or attack
	var distanceToHero = Math.sqrt(Math.pow(worldX - hero.x, 2) + Math.pow(worldY - hero.y, 2));
	if (distanceToHero > 200) {
		// Movement - move toward tap position
		var dx = worldX - hero.x;
		var dy = worldY - hero.y;
		if (Math.abs(dx) > Math.abs(dy)) {
			hero.move(dx > 0 ? 'right' : 'left');
		} else {
			hero.move(dy > 0 ? 'down' : 'up');
		}
	} else {
		// Attack
		if (!hero.isAttacking) {
			var nearestEnemy = findNearestEnemy(worldX, worldY);
			if (nearestEnemy) {
				hero.attack(nearestEnemy.x);
				// Check if attack hits
				var distanceToEnemy = Math.sqrt(Math.pow(hero.x - nearestEnemy.x, 2) + Math.pow(hero.y - nearestEnemy.y, 2));
				if (distanceToEnemy < 150) {
					var damage = hero.damageBoost ? 2 : 1;
					for (var i = 0; i < damage; i++) {
						nearestEnemy.takeDamage();
					}
				}
			} else {
				// Attack in direction of tap
				hero.attack(worldX);
			}
		}
	}
};
// Main game loop
game.update = function () {
	// Update camera position smoothly
	camera.x += (camera.targetX - camera.x) * camera.smoothing;
	camera.y += (camera.targetY - camera.y) * camera.smoothing;
	// Apply camera position to game
	game.x = -camera.x;
	game.y = -camera.y;
	// Update all game objects
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		enemy.update();
	}
	for (var i = coins.length - 1; i >= 0; i--) {
		coins[i].update();
	}
	for (var i = powerups.length - 1; i >= 0; i--) {
		powerups[i].update();
	}
	// Check for level completion
	if (!levelComplete && enemies.length === 0) {
		levelComplete = true;
		currentLevel++;
		if (currentLevel <= levels.length) {
			// Start next level after delay
			LK.setTimeout(function () {
				initializeLevel();
			}, 2000);
		} else {
			// Game completed
			LK.showYouWin();
		}
	}
}; ===================================================================
--- original.js
+++ change.js
@@ -46,22 +46,45 @@
 	self.speed = 1;
 	self.attackCooldown = 0;
 	self.fromLeft = true;
 	self.update = function () {
-		// Move toward hero
-		if (self.fromLeft) {
-			self.x += self.speed;
-			enemyGraphics.scaleX = 1;
+		var distanceToHero = Math.sqrt(Math.pow(self.x - hero.x, 2) + Math.pow(self.y - hero.y, 2));
+		var canSeeHero = distanceToHero < 300; // Line of sight range
+		if (canSeeHero) {
+			// Chase hero
+			var dx = hero.x - self.x;
+			var dy = hero.y - self.y;
+			var distance = Math.sqrt(dx * dx + dy * dy);
+			if (distance > 0) {
+				self.x += dx / distance * self.speed;
+				self.y += dy / distance * self.speed;
+				// Face direction of movement
+				enemyGraphics.scaleX = dx > 0 ? 1 : -1;
+			}
+			// Attack hero if close enough
+			if (distanceToHero < 100 && self.attackCooldown <= 0) {
+				hero.takeDamage();
+				self.attackCooldown = 120; // 2 seconds at 60fps
+			}
 		} else {
-			self.x -= self.speed;
-			enemyGraphics.scaleX = -1;
+			// Roam randomly
+			if (!self.roamDirection || Math.random() < 0.01) {
+				self.roamDirection = {
+					x: (Math.random() - 0.5) * 2,
+					y: (Math.random() - 0.5) * 2
+				};
+			}
+			var newX = self.x + self.roamDirection.x * self.speed * 0.5;
+			var newY = self.y + self.roamDirection.y * self.speed * 0.5;
+			// Keep within level bounds
+			if (newX > 100 && newX < currentLevelData.width - 100) {
+				self.x = newX;
+				enemyGraphics.scaleX = self.roamDirection.x > 0 ? 1 : -1;
+			}
+			if (newY > 1800 && newY < 2200) {
+				self.y = newY;
+			}
 		}
-		// Attack hero if close enough
-		var distanceToHero = Math.abs(self.x - hero.x);
-		if (distanceToHero < 100 && self.attackCooldown <= 0) {
-			hero.takeDamage();
-			self.attackCooldown = 120; // 2 seconds at 60fps
-		}
 		if (self.attackCooldown > 0) {
 			self.attackCooldown--;
 		}
 	};
@@ -175,8 +198,28 @@
 	};
 	self.addCombo = function () {
 		self.comboCount++;
 	};
+	self.move = function (direction) {
+		var speed = 5;
+		if (direction === 'left' && self.x > 100) {
+			self.x -= speed;
+			heroGraphics.scaleX = -1;
+		} else if (direction === 'right' && self.x < currentLevelData.width - 100) {
+			self.x += speed;
+			heroGraphics.scaleX = 1;
+		} else if (direction === 'up' && self.y > 1800) {
+			self.y -= speed;
+		} else if (direction === 'down' && self.y < 2200) {
+			self.y += speed;
+		}
+		// Update camera target
+		camera.targetX = self.x - 1024;
+		camera.targetY = self.y - 1366;
+		// Clamp camera to level bounds
+		camera.targetX = Math.max(0, Math.min(camera.targetX, currentLevelData.width - 2048));
+		camera.targetY = Math.max(0, Math.min(camera.targetY, currentLevelData.height - 2732));
+	};
 	return self;
 });
 var PowerUp = Container.expand(function () {
 	var self = Container.call(this);
@@ -251,13 +294,52 @@
 var hero;
 var enemies = [];
 var coins = [];
 var powerups = [];
-var currentWave = 1;
-var enemiesLeftInWave = 3;
-var spawnTimer = 0;
-var powerupSpawnTimer = 0;
+var currentLevel = 1;
+var levelComplete = false;
 var hearts = [];
+// Camera system
+var camera = {
+	x: 0,
+	y: 0,
+	targetX: 0,
+	targetY: 0,
+	smoothing: 0.1
+};
+// Level configuration
+var levels = [{
+	enemies: [{
+		type: 'basic',
+		count: 3
+	}],
+	width: 4096,
+	height: 2732
+}, {
+	enemies: [{
+		type: 'basic',
+		count: 5
+	}, {
+		type: 'strong',
+		count: 2
+	}],
+	width: 5120,
+	height: 2732
+}, {
+	enemies: [{
+		type: 'basic',
+		count: 7
+	}, {
+		type: 'strong',
+		count: 3
+	}, {
+		type: 'fast',
+		count: 2
+	}],
+	width: 6144,
+	height: 2732
+}];
+var currentLevelData = levels[0];
 // UI Elements
 var scoreText = new Text2('Score: 0', {
 	size: 80,
 	fill: 0xFFFFFF
@@ -265,15 +347,15 @@
 scoreText.anchor.set(0, 0);
 scoreText.x = 150;
 scoreText.y = 50;
 LK.gui.topLeft.addChild(scoreText);
-var waveText = new Text2('Wave: 1', {
+var levelText = new Text2('Level: 1', {
 	size: 80,
 	fill: 0xFFFFFF
 });
-waveText.anchor.set(0.5, 0);
-LK.gui.top.addChild(waveText);
-waveText.y = 50;
+levelText.anchor.set(0.5, 0);
+LK.gui.top.addChild(levelText);
+levelText.y = 50;
 var comboText = new Text2('Combo: 0x', {
 	size: 60,
 	fill: 0xFFFF00
 });
@@ -308,23 +390,44 @@
 	scoreText.setText('Score: ' + LK.getScore());
 	var comboMultiplier = Math.floor(hero.comboCount / 5) + 1;
 	comboText.setText('Combo: ' + comboMultiplier + 'x');
 }
-function spawnEnemy() {
+function initializeLevel() {
+	// Clear existing enemies
+	for (var i = enemies.length - 1; i >= 0; i--) {
+		enemies[i].destroy();
+	}
+	enemies = [];
+	currentLevelData = levels[currentLevel - 1] || levels[levels.length - 1];
+	levelComplete = false;
+	// Spawn enemies for this level
+	for (var j = 0; j < currentLevelData.enemies.length; j++) {
+		var enemyGroup = currentLevelData.enemies[j];
+		for (var k = 0; k < enemyGroup.count; k++) {
+			spawnEnemy(enemyGroup.type);
+		}
+	}
+	levelText.setText('Level: ' + currentLevel);
+}
+function spawnEnemy(type) {
 	var enemy = game.addChild(new Enemy());
-	// Random spawn from left or right
-	enemy.fromLeft = Math.random() < 0.5;
-	if (enemy.fromLeft) {
-		enemy.x = -100;
-		enemy.speed = 1 + currentWave * 0.3;
-	} else {
-		enemy.x = 2148;
-		enemy.speed = 1 + currentWave * 0.3;
+	// Random spawn position within level bounds
+	enemy.x = 200 + Math.random() * (currentLevelData.width - 400);
+	enemy.y = 1900 + Math.random() * 200;
+	// Set enemy properties based on type
+	if (type === 'basic') {
+		enemy.health = 2;
+		enemy.speed = 1;
+	} else if (type === 'strong') {
+		enemy.health = 4;
+		enemy.speed = 0.8;
+		enemy.getChildAt(0).tint = 0x8b4513; // Brown tint
+	} else if (type === 'fast') {
+		enemy.health = 1;
+		enemy.speed = 2;
+		enemy.getChildAt(0).tint = 0x00ff00; // Green tint
 	}
-	enemy.y = 2200; // Same level as hero
-	enemy.health = 1 + Math.floor(currentWave / 3); // Increase health every 3 waves
 	enemies.push(enemy);
-	enemiesLeftInWave--;
 }
 function spawnPowerUp() {
 	var powerup = game.addChild(new PowerUp());
 	powerup.x = 500 + Math.random() * 1048; // Random x position
@@ -358,69 +461,82 @@
 }
 // Initialize UI
 updateHealthDisplay();
 updateScoreDisplay();
+// Initialize first level
+initializeLevel();
+// Set initial camera position
+camera.targetX = hero.x - 1024;
+camera.targetY = hero.y - 1366;
+camera.x = camera.targetX;
+camera.y = camera.targetY;
 // Game input
 game.down = function (x, y, obj) {
-	if (!hero.isAttacking) {
-		var nearestEnemy = findNearestEnemy(x, y);
-		if (nearestEnemy) {
-			hero.attack(nearestEnemy.x);
-			// Check if attack hits
-			var distanceToEnemy = Math.abs(hero.x - nearestEnemy.x);
-			if (distanceToEnemy < 150) {
-				var damage = hero.damageBoost ? 2 : 1;
-				for (var i = 0; i < damage; i++) {
-					nearestEnemy.takeDamage();
+	// Convert screen coordinates to world coordinates
+	var worldX = x + camera.x;
+	var worldY = y + camera.y;
+	// Check if tap is for movement or attack
+	var distanceToHero = Math.sqrt(Math.pow(worldX - hero.x, 2) + Math.pow(worldY - hero.y, 2));
+	if (distanceToHero > 200) {
+		// Movement - move toward tap position
+		var dx = worldX - hero.x;
+		var dy = worldY - hero.y;
+		if (Math.abs(dx) > Math.abs(dy)) {
+			hero.move(dx > 0 ? 'right' : 'left');
+		} else {
+			hero.move(dy > 0 ? 'down' : 'up');
+		}
+	} else {
+		// Attack
+		if (!hero.isAttacking) {
+			var nearestEnemy = findNearestEnemy(worldX, worldY);
+			if (nearestEnemy) {
+				hero.attack(nearestEnemy.x);
+				// Check if attack hits
+				var distanceToEnemy = Math.sqrt(Math.pow(hero.x - nearestEnemy.x, 2) + Math.pow(hero.y - nearestEnemy.y, 2));
+				if (distanceToEnemy < 150) {
+					var damage = hero.damageBoost ? 2 : 1;
+					for (var i = 0; i < damage; i++) {
+						nearestEnemy.takeDamage();
+					}
 				}
+			} else {
+				// Attack in direction of tap
+				hero.attack(worldX);
 			}
-		} else {
-			// Attack in direction of tap
-			hero.attack(x);
 		}
 	}
 };
 // Main game loop
 game.update = function () {
+	// Update camera position smoothly
+	camera.x += (camera.targetX - camera.x) * camera.smoothing;
+	camera.y += (camera.targetY - camera.y) * camera.smoothing;
+	// Apply camera position to game
+	game.x = -camera.x;
+	game.y = -camera.y;
 	// Update all game objects
 	for (var i = enemies.length - 1; i >= 0; i--) {
 		var enemy = enemies[i];
 		enemy.update();
-		// Remove if off screen
-		if (enemy.x < -200 || enemy.x > 2248) {
-			enemies.splice(i, 1);
-			enemy.destroy();
-		}
 	}
 	for (var i = coins.length - 1; i >= 0; i--) {
 		coins[i].update();
 	}
 	for (var i = powerups.length - 1; i >= 0; i--) {
 		powerups[i].update();
 	}
-	// Spawn logic
-	spawnTimer++;
-	if (spawnTimer > 180 && enemiesLeftInWave > 0) {
-		// 3 seconds between spawns
-		spawnEnemy();
-		spawnTimer = 0;
-	}
-	// Check for wave completion
-	if (enemiesLeftInWave <= 0 && enemies.length === 0) {
-		currentWave++;
-		enemiesLeftInWave = 3 + currentWave; // Increase enemies per wave
-		waveText.setText('Wave: ' + currentWave);
-		// Chance to spawn powerup on wave complete
-		if (Math.random() < 0.6) {
-			spawnPowerUp();
+	// Check for level completion
+	if (!levelComplete && enemies.length === 0) {
+		levelComplete = true;
+		currentLevel++;
+		if (currentLevel <= levels.length) {
+			// Start next level after delay
+			LK.setTimeout(function () {
+				initializeLevel();
+			}, 2000);
+		} else {
+			// Game completed
+			LK.showYouWin();
 		}
 	}
-	// Powerup spawn timer
-	powerupSpawnTimer++;
-	if (powerupSpawnTimer > 1800) {
-		// 30 seconds
-		if (Math.random() < 0.3) {
-			spawnPowerUp();
-		}
-		powerupSpawnTimer = 0;
-	}
 };
\ No newline at end of file