User prompt
can you make the texture reset more faster ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
remove any fade effects for exture reset and reset the ttextures imideatl ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
can you make the texture reset more faser and smoother to prevent flickering texture chage ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
can you add one additional walk asset to cycle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
prevent flickering asset change for a smoother and complete anim ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
the characters asset is not changing at the mment, and it is locked on base hero asset can you make a walking animthhat cycles betwen herowalk assets ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
walking animisnt working can you fixit ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
when charater is wlking the assets change between walk assets ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
can you enlarge the map verical borders
User prompt
make he walking anim via chancing charrachter asset texture ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make a walking animation to pllayer ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add a background asset for player to know whether the cahractr is movıngg or not ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
if a enemy is alerted it wont stoop followıng
User prompt
increaase the enemys attraction radius and enemy will alertd if take damage with knife
User prompt
show hwmany enemis left
User prompt
the knife asset should face to enemys when thrown ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
speed up the char
User prompt
the route should end to mob assets middle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
the knife route should start from middle of the char asset
User prompt
the knives shouldnt ricochet and deal damage to the first mob they onterfered
User prompt
speed up the knives ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
the players take damage when knife assets hits them.
User prompt
the players take damage when knife assets hits them. spped upo the knife ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
the knife should follow the route ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
remove the route 0.5 sec after creating ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** 
* 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.lastX = 0;
	self.lastY = 0;
	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) {
				var newX = self.x + dx / distance * self.speed;
				var newY = self.y + dy / distance * self.speed;
				// Check collision with other enemies before moving
				var wouldCollide = false;
				for (var i = 0; i < enemies.length; i++) {
					var otherEnemy = enemies[i];
					if (otherEnemy === self) continue; // Skip self
					var edx = newX - otherEnemy.x;
					var edy = newY - otherEnemy.y;
					var edistance = Math.sqrt(edx * edx + edy * edy);
					if (edistance < 70) {
						// Collision threshold between enemies
						wouldCollide = true;
						break;
					}
				}
				// Only move if no collision would occur
				if (!wouldCollide) {
					self.lastX = self.x;
					self.lastY = self.y;
					self.x = newX;
					self.y = newY;
				}
				// 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;
			// Check collision with other enemies before roaming
			var wouldCollide = false;
			for (var i = 0; i < enemies.length; i++) {
				var otherEnemy = enemies[i];
				if (otherEnemy === self) continue; // Skip self
				var edx = newX - otherEnemy.x;
				var edy = newY - otherEnemy.y;
				var edistance = Math.sqrt(edx * edx + edy * edy);
				if (edistance < 70) {
					// Collision threshold between enemies
					wouldCollide = true;
					break;
				}
			}
			// Keep within level bounds and check collisions
			if (!wouldCollide && newX > 100 && newX < currentLevelData.width - 100) {
				self.lastX = self.x;
				self.x = newX;
				enemyGraphics.scaleX = self.roamDirection.x > 0 ? 1 : -1;
			}
			if (!wouldCollide && newY > 1800 && newY < 2200) {
				self.lastY = self.y;
				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 EnemyWarning = Container.expand(function () {
	var self = Container.call(this);
	self.targetEnemy = null;
	self.direction = 'left'; // 'left', 'right', 'up', 'down'
	self.warningGraphics = null;
	self.lastAlpha = 0;
	self.isVisible = false;
	self.setDirection = function (direction) {
		if (self.warningGraphics) {
			self.warningGraphics.destroy();
		}
		var assetName = 'warningArrow' + direction.charAt(0).toUpperCase() + direction.slice(1);
		self.warningGraphics = self.attachAsset(assetName, {
			anchorX: 0.5,
			anchorY: 0.5,
			alpha: 0
		});
		self.direction = direction;
	};
	self.update = function () {
		if (!self.targetEnemy || !self.warningGraphics) return;
		// Check if enemy is still alive
		var enemyExists = false;
		for (var i = 0; i < enemies.length; i++) {
			if (enemies[i] === self.targetEnemy) {
				enemyExists = true;
				break;
			}
		}
		if (!enemyExists) {
			self.hide();
			return;
		}
		// Calculate distance from hero to enemy
		var distanceToHero = Math.sqrt(Math.pow(self.targetEnemy.x - hero.x, 2) + Math.pow(self.targetEnemy.y - hero.y, 2));
		// Check if enemy is visible on screen
		var enemyScreenX = self.targetEnemy.x - camera.x;
		var enemyScreenY = self.targetEnemy.y - camera.y;
		var isOnScreen = enemyScreenX >= -100 && enemyScreenX <= 2148 && enemyScreenY >= -100 && enemyScreenY <= 2832;
		if (isOnScreen) {
			self.hide();
			return;
		}
		// Calculate warning opacity based on distance (closer = more visible)
		var maxDistance = 800;
		var minDistance = 300;
		var targetAlpha = 0;
		if (distanceToHero <= maxDistance) {
			var normalizedDistance = Math.max(0, Math.min(1, (maxDistance - distanceToHero) / (maxDistance - minDistance)));
			targetAlpha = normalizedDistance * 0.8;
		}
		// Smooth alpha transition
		if (Math.abs(targetAlpha - self.lastAlpha) > 0.01) {
			tween.stop(self.warningGraphics, {
				alpha: true
			});
			tween(self.warningGraphics, {
				alpha: targetAlpha
			}, {
				duration: 200
			});
			self.lastAlpha = targetAlpha;
		}
		// Position warning at screen edge
		var screenCenterX = 1024;
		var screenCenterY = 1366;
		var dx = self.targetEnemy.x - hero.x;
		var dy = self.targetEnemy.y - hero.y;
		if (Math.abs(dx) > Math.abs(dy)) {
			// Horizontal warning
			if (dx > 0) {
				self.setDirection('right');
				self.x = screenCenterX + 900;
				self.y = screenCenterY + Math.max(-600, Math.min(600, dy * 0.5));
			} else {
				self.setDirection('left');
				self.x = screenCenterX - 900;
				self.y = screenCenterY + Math.max(-600, Math.min(600, dy * 0.5));
			}
		} else {
			// Vertical warning
			if (dy > 0) {
				self.setDirection('down');
				self.x = screenCenterX + Math.max(-800, Math.min(800, dx * 0.5));
				self.y = screenCenterY + 1200;
			} else {
				self.setDirection('up');
				self.x = screenCenterX + Math.max(-800, Math.min(800, dx * 0.5));
				self.y = screenCenterY - 1200;
			}
		}
	};
	self.hide = function () {
		if (self.warningGraphics && self.warningGraphics.alpha > 0) {
			tween.stop(self.warningGraphics, {
				alpha: true
			});
			tween(self.warningGraphics, {
				alpha: 0
			}, {
				duration: 300
			});
			self.lastAlpha = 0;
		}
	};
	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.lastX = 0;
	self.lastY = 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 = 8;
		var newX = self.x;
		var newY = self.y;
		if (direction === 'left' && self.x > 100) {
			newX = self.x - speed;
			heroGraphics.scaleX = -1;
		} else if (direction === 'right' && self.x < currentLevelData.width - 100) {
			newX = self.x + speed;
			heroGraphics.scaleX = 1;
		} else if (direction === 'up' && self.y > 1800) {
			newY = self.y - speed;
		} else if (direction === 'down' && self.y < 2200) {
			newY = self.y + speed;
		}
		// Check collision with enemies before moving
		var wouldCollide = false;
		for (var i = 0; i < enemies.length; i++) {
			var enemy = enemies[i];
			var dx = newX - enemy.x;
			var dy = newY - enemy.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < 80) {
				// Collision threshold
				wouldCollide = true;
				break;
			}
		}
		// Only move if no collision would occur
		if (!wouldCollide) {
			self.lastX = self.x;
			self.lastY = self.y;
			self.x = newX;
			self.y = newY;
		}
		// 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 Knife = Container.expand(function () {
	var self = Container.call(this);
	var knifeGraphics = self.attachAsset('knife', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 15;
	self.direction = 1; // 1 for right, -1 for left
	self.routePoints = []; // Points to follow along the route
	self.currentRouteIndex = 0; // Current target point index
	self.velocityX = 0; // Velocity for precise targeting
	self.velocityY = 0; // Velocity for precise targeting
	self.lastX = 0;
	self.lastY = 0;
	self.setRoute = function (routePoints) {
		self.routePoints = routePoints;
		self.currentRouteIndex = 0;
	};
	self.update = function () {
		self.lastX = self.x;
		self.lastY = self.y;
		// Follow route if available
		if (self.routePoints.length > 0 && self.currentRouteIndex < self.routePoints.length) {
			var targetPoint = self.routePoints[self.currentRouteIndex];
			var dx = targetPoint.x - self.x;
			var dy = targetPoint.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < 20) {
				// Close enough to current target, move to next point
				self.currentRouteIndex++;
			} else {
				// Move toward current target point
				if (distance > 0) {
					self.x += dx / distance * self.speed;
					self.y += dy / distance * self.speed;
					// Calculate rotation angle to face target direction
					var angle = Math.atan2(dy, dx);
					knifeGraphics.rotation = angle;
				}
			}
		} else if (self.velocityX !== 0 || self.velocityY !== 0) {
			// Use velocity if set, otherwise use direction-based movement
			self.x += self.velocityX;
			self.y += self.velocityY;
			// Calculate rotation for velocity-based movement
			var angle = Math.atan2(self.velocityY, self.velocityX);
			knifeGraphics.rotation = angle;
		} else {
			self.x += self.speed * self.direction;
			self.y -= 2; // Slight upward arc
			// Calculate rotation for direction-based movement
			var angle = Math.atan2(-2, self.speed * self.direction);
			knifeGraphics.rotation = angle;
		}
		// Check if knife went off screen
		if (self.x < -100 || self.x > currentLevelData.width + 100 || self.y < -100 || self.y > 2900) {
			self.destroy();
			// Remove from knives array
			for (var i = knives.length - 1; i >= 0; i--) {
				if (knives[i] === self) {
					knives.splice(i, 1);
					break;
				}
			}
		}
		// Check collision with enemies (hit enemy center)
		for (var i = 0; i < enemies.length; i++) {
			var enemy = enemies[i];
			var dx = self.x - enemy.x;
			var dy = self.y - (enemy.y - 70); // Target enemy center
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < 50) {
				// Hit enemy center - deal damage only to first enemy encountered
				enemy.takeDamage();
				self.destroy();
				// Remove from knives array
				for (var j = knives.length - 1; j >= 0; j--) {
					if (knives[j] === self) {
						knives.splice(j, 1);
						break;
					}
				}
				return; // Exit update immediately to prevent further movement or collision checks
			}
		}
	};
	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;
});
var RouteEffect = Container.expand(function () {
	var self = Container.call(this);
	self.routePoints = [];
	self.routePositions = []; // Store just the x,y coordinates for knife to follow
	self.targetEnemy = null;
	self.createRoute = function (enemy) {
		self.targetEnemy = enemy;
		self.clearRoute();
		// Calculate direct path from hero center to enemy center
		var heroStartX = hero.x;
		var heroStartY = hero.y - 80; // Middle of hero asset
		var enemyMiddleX = enemy.x;
		var enemyMiddleY = enemy.y - 70; // Middle of enemy asset (enemy height is 140, so middle is -70 from bottom)
		var dx = enemyMiddleX - heroStartX;
		var dy = enemyMiddleY - heroStartY;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 0) {
			// Create route points along the path
			var numPoints = Math.floor(distance / 50); // Point every 50 pixels
			for (var i = 0; i <= numPoints; i++) {
				var t = i / numPoints;
				var x = heroStartX + dx * t;
				var y = heroStartY + dy * t;
				var routePoint = self.addChild(LK.getAsset('routeLine', {
					anchorX: 0.5,
					anchorY: 0.5,
					alpha: 0
				}));
				routePoint.x = x;
				routePoint.y = y;
				self.routePoints.push(routePoint);
				// Store position for knife to follow
				self.routePositions.push({
					x: x,
					y: y
				});
				// Animate route points appearing with delay
				tween(routePoint, {
					alpha: 0.8,
					scaleX: 2,
					scaleY: 2
				}, {
					duration: 100 + i * 20
				});
			}
			// Add impact effect at enemy position
			var impactEffect = self.addChild(LK.getAsset('routeEffect', {
				anchorX: 0.5,
				anchorY: 0.5,
				alpha: 0,
				scaleX: 0.5,
				scaleY: 0.5
			}));
			impactEffect.x = enemyMiddleX;
			impactEffect.y = enemyMiddleY;
			self.routePoints.push(impactEffect);
			// Animate impact effect
			tween(impactEffect, {
				alpha: 1,
				scaleX: 3,
				scaleY: 3
			}, {
				duration: 300,
				easing: tween.easeOut
			});
			// Remove route after 0.5 seconds
			LK.setTimeout(function () {
				self.destroy();
				// Remove from routeEffects array
				for (var i = routeEffects.length - 1; i >= 0; i--) {
					if (routeEffects[i] === self) {
						routeEffects.splice(i, 1);
						break;
					}
				}
			}, 500);
		}
	};
	self.clearRoute = function () {
		for (var i = self.routePoints.length - 1; i >= 0; i--) {
			self.routePoints[i].destroy();
		}
		self.routePoints = [];
	};
	self.fadeOut = function () {
		for (var i = 0; i < self.routePoints.length; i++) {
			tween(self.routePoints[i], {
				alpha: 0,
				scaleX: 0.1,
				scaleY: 0.1
			}, {
				duration: 200
			});
		}
		LK.setTimeout(function () {
			self.destroy();
		}, 300);
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x2c3e50
});
/**** 
* Game Code
****/ 
// Game variables
var hero;
var enemies = [];
var coins = [];
var powerups = [];
var enemyWarnings = [];
var knives = [];
var knivesRemaining = 5;
var routeEffects = [];
var currentLevel = 1;
var levelComplete = false;
var hearts = [];
// Movement state tracking
var movementState = {
	left: false,
	right: false,
	up: false,
	down: false
};
// 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;
var knivesText = new Text2('Knives: 5', {
	size: 60,
	fill: 0x8e44ad
});
knivesText.anchor.set(1, 0);
LK.gui.topRight.addChild(knivesText);
knivesText.x = -50;
knivesText.y = 190;
// Create movement and attack buttons
var leftButton = LK.getAsset('leftButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	alpha: 0.8
});
leftButton.x = 120;
leftButton.y = -250;
LK.gui.bottomLeft.addChild(leftButton);
var rightButton = LK.getAsset('rightButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	alpha: 0.8
});
rightButton.x = 400;
rightButton.y = -250;
LK.gui.bottomLeft.addChild(rightButton);
var upButton = LK.getAsset('upButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	alpha: 0.8
});
upButton.x = 260;
upButton.y = -380;
LK.gui.bottomLeft.addChild(upButton);
var downButton = LK.getAsset('downButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	alpha: 0.8
});
downButton.x = 260;
downButton.y = -120;
LK.gui.bottomLeft.addChild(downButton);
var attackButton = LK.getAsset('attackButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	alpha: 0.9
});
attackButton.x = -150;
attackButton.y = -200;
LK.gui.bottomRight.addChild(attackButton);
var knifeButton = LK.getAsset('knifeButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	alpha: 0.9
});
knifeButton.x = -350;
knifeButton.y = -200;
LK.gui.bottomRight.addChild(knifeButton);
// 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 updateKnivesDisplay() {
	knivesText.setText('Knives: ' + knivesRemaining);
	// Update button alpha based on availability
	knifeButton.alpha = knivesRemaining > 0 ? 0.9 : 0.3;
}
function initializeLevel() {
	// Clear existing enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		enemies[i].destroy();
	}
	enemies = [];
	// Clear existing warnings
	for (var i = enemyWarnings.length - 1; i >= 0; i--) {
		enemyWarnings[i].destroy();
	}
	enemyWarnings = [];
	// Clear existing knives
	for (var i = knives.length - 1; i >= 0; i--) {
		knives[i].destroy();
	}
	knives = [];
	// Clear existing route effects
	for (var i = routeEffects.length - 1; i >= 0; i--) {
		routeEffects[i].destroy();
	}
	routeEffects = [];
	// Reset knife count
	knivesRemaining = 5;
	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);
	updateKnivesDisplay();
}
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;
}
function updateEnemyWarnings() {
	// Remove warnings for dead enemies
	for (var i = enemyWarnings.length - 1; i >= 0; i--) {
		var warning = enemyWarnings[i];
		var enemyExists = false;
		for (var j = 0; j < enemies.length; j++) {
			if (enemies[j] === warning.targetEnemy) {
				enemyExists = true;
				break;
			}
		}
		if (!enemyExists) {
			warning.destroy();
			enemyWarnings.splice(i, 1);
		}
	}
	// Create warnings for new enemies
	for (var i = 0; i < enemies.length; i++) {
		var enemy = enemies[i];
		var hasWarning = false;
		for (var j = 0; j < enemyWarnings.length; j++) {
			if (enemyWarnings[j].targetEnemy === enemy) {
				hasWarning = true;
				break;
			}
		}
		if (!hasWarning) {
			var warning = LK.gui.center.addChild(new EnemyWarning());
			warning.targetEnemy = enemy;
			warning.setDirection('left');
			enemyWarnings.push(warning);
		}
	}
}
// Initialize UI
updateHealthDisplay();
updateScoreDisplay();
updateKnivesDisplay();
// 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;
// Button event handlers
leftButton.down = function (x, y, obj) {
	movementState.left = true;
};
leftButton.up = function (x, y, obj) {
	movementState.left = false;
};
rightButton.down = function (x, y, obj) {
	movementState.right = true;
};
rightButton.up = function (x, y, obj) {
	movementState.right = false;
};
upButton.down = function (x, y, obj) {
	movementState.up = true;
};
upButton.up = function (x, y, obj) {
	movementState.up = false;
};
downButton.down = function (x, y, obj) {
	movementState.down = true;
};
downButton.up = function (x, y, obj) {
	movementState.down = false;
};
attackButton.down = function (x, y, obj) {
	if (!hero.isAttacking) {
		var nearestEnemy = findNearestEnemy(hero.x, hero.y);
		if (nearestEnemy) {
			hero.attack(nearestEnemy.x);
			// Check if attack hits with increased range
			var distanceToEnemy = Math.sqrt(Math.pow(hero.x - nearestEnemy.x, 2) + Math.pow(hero.y - nearestEnemy.y, 2));
			if (distanceToEnemy < 250) {
				// Increased from 150 to 250
				var damage = hero.damageBoost ? 2 : 1;
				for (var i = 0; i < damage; i++) {
					nearestEnemy.takeDamage();
				}
			}
		} else {
			// Attack in hero's facing direction
			hero.attack(hero.x + (hero.getChildAt(0).scaleX > 0 ? 100 : -100));
		}
	}
};
knifeButton.down = function (x, y, obj) {
	if (knivesRemaining > 0) {
		// Find nearest enemy for targeting
		var nearestEnemy = findNearestEnemy(hero.x, hero.y);
		if (nearestEnemy) {
			// Clear existing route effects before creating new one
			for (var i = routeEffects.length - 1; i >= 0; i--) {
				routeEffects[i].destroy();
				routeEffects.splice(i, 1);
			}
			// Create route visualization
			var routeEffect = game.addChild(new RouteEffect());
			routeEffect.createRoute(nearestEnemy);
			routeEffects.push(routeEffect);
			// Throw knife to follow the route
			var knife = game.addChild(new Knife());
			knife.x = hero.x;
			knife.y = hero.y - 80;
			// Set the route for the knife to follow
			knife.setRoute(routeEffect.routePositions);
			// Rotation will be handled automatically in knife update based on target direction
			knives.push(knife);
			knivesRemaining--;
			updateKnivesDisplay();
			LK.getSound('knifeThrow').play();
		} else {
			// No enemy found, throw in hero facing direction
			var knife = game.addChild(new Knife());
			knife.x = hero.x;
			knife.y = hero.y - 80;
			var heroGraphics = hero.getChildAt(0);
			knife.direction = heroGraphics.scaleX > 0 ? 1 : -1;
			// Rotation will be handled automatically in knife update based on movement direction
			knives.push(knife);
			knivesRemaining--;
			updateKnivesDisplay();
			LK.getSound('knifeThrow').play();
		}
	}
};
// Game input (fallback for screen taps outside buttons)
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 with increased range
				var distanceToEnemy = Math.sqrt(Math.pow(hero.x - nearestEnemy.x, 2) + Math.pow(hero.y - nearestEnemy.y, 2));
				if (distanceToEnemy < 250) {
					// Increased from 150 to 250
					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 () {
	// Handle continuous movement based on button states
	if (movementState.left) {
		hero.move('left');
	}
	if (movementState.right) {
		hero.move('right');
	}
	if (movementState.up) {
		hero.move('up');
	}
	if (movementState.down) {
		hero.move('down');
	}
	// 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();
	}
	for (var i = knives.length - 1; i >= 0; i--) {
		knives[i].update();
	}
	// Clean up destroyed route effects
	for (var i = routeEffects.length - 1; i >= 0; i--) {
		var routeEffect = routeEffects[i];
		if (!routeEffect.parent) {
			routeEffects.splice(i, 1);
		}
	}
	// Update enemy warnings
	updateEnemyWarnings();
	for (var i = 0; i < enemyWarnings.length; i++) {
		enemyWarnings[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
@@ -425,19 +425,26 @@
 				// Move toward current target point
 				if (distance > 0) {
 					self.x += dx / distance * self.speed;
 					self.y += dy / distance * self.speed;
-					// Face the direction of movement
-					knifeGraphics.scaleX = dx > 0 ? 1 : -1;
+					// Calculate rotation angle to face target direction
+					var angle = Math.atan2(dy, dx);
+					knifeGraphics.rotation = angle;
 				}
 			}
 		} else if (self.velocityX !== 0 || self.velocityY !== 0) {
 			// Use velocity if set, otherwise use direction-based movement
 			self.x += self.velocityX;
 			self.y += self.velocityY;
+			// Calculate rotation for velocity-based movement
+			var angle = Math.atan2(self.velocityY, self.velocityX);
+			knifeGraphics.rotation = angle;
 		} else {
 			self.x += self.speed * self.direction;
 			self.y -= 2; // Slight upward arc
+			// Calculate rotation for direction-based movement
+			var angle = Math.atan2(-2, self.speed * self.direction);
+			knifeGraphics.rotation = angle;
 		}
 		// Check if knife went off screen
 		if (self.x < -100 || self.x > currentLevelData.width + 100 || self.y < -100 || self.y > 2900) {
 			self.destroy();
@@ -1010,11 +1017,9 @@
 			knife.x = hero.x;
 			knife.y = hero.y - 80;
 			// Set the route for the knife to follow
 			knife.setRoute(routeEffect.routePositions);
-			// Face the direction of movement
-			var dx = nearestEnemy.x - hero.x;
-			knife.getChildAt(0).scaleX = dx > 0 ? 1 : -1;
+			// Rotation will be handled automatically in knife update based on target direction
 			knives.push(knife);
 			knivesRemaining--;
 			updateKnivesDisplay();
 			LK.getSound('knifeThrow').play();
@@ -1024,9 +1029,9 @@
 			knife.x = hero.x;
 			knife.y = hero.y - 80;
 			var heroGraphics = hero.getChildAt(0);
 			knife.direction = heroGraphics.scaleX > 0 ? 1 : -1;
-			knife.getChildAt(0).scaleX = knife.direction;
+			// Rotation will be handled automatically in knife update based on movement direction
 			knives.push(knife);
 			knivesRemaining--;
 			updateKnivesDisplay();
 			LK.getSound('knifeThrow').play();