User prompt
enemy fall out to bottom after hit ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
more enemy appear
User prompt
enemy loop
User prompt
fix game
User prompt
fix enemy spawn
User prompt
boss escape out to upper screen after hit by player
User prompt
make enemy fall out to bottom screen after hit
User prompt
make enemy fall after hit ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'ReferenceError: currentWave is not defined' in or related to this line: 'currentWave++;' Line Number: 75
User prompt
bullet change to white color
User prompt
delete wave asset. make loop game logic
User prompt
fix wave
User prompt
fix collor bullet to yellow
User prompt
add background asset
User prompt
enemy are spider. make animation enemy the spider walking to player ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
enemy one shoot dead. boss 5x shoot dead
User prompt
change rule. no dash attack. make be a shooter game
User prompt
delete auto shoot
User prompt
delete hazzard asset
User prompt
fix auto shoot
User prompt
add new logic. player can auto shoot
User prompt
player get more strenght
User prompt
reduce enemy appear
User prompt
more speed dash ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Boss = Container.expand(function () {
	var self = Container.call(this);
	var bossGraphic = self.attachAsset('boss', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 1.5;
	self.health = 10;
	self.attackCooldown = 0;
	self.attackPattern = 0;
	self.scoreValue = 2000;
	self.active = true;
	self.init = function (x, y) {
		self.x = x;
		self.y = y;
		return self;
	};
	self.takeDamage = function () {
		if (!self.active) {
			return;
		}
		// Increased damage based on hero's dash combo
		var damageAmount = 1;
		if (hero && hero.consecutiveDashes > 0) {
			damageAmount = Math.min(3, 1 + Math.floor(hero.consecutiveDashes / 2));
		}
		self.health -= damageAmount;
		// Flash boss
		LK.effects.flashObject(self, 0xffffff, 300);
		LK.getSound('hit').play();
		if (self.health <= 0) {
			self.die();
		} else {
			// Speed up as health decreases
			self.speed = 1.5 + (10 - self.health) * 0.2;
		}
	};
	self.die = function () {
		if (!self.active) {
			return;
		}
		self.active = false;
		LK.getSound('bossDeath').play();
		// Flash and fade out
		LK.effects.flashObject(self, 0xffff00, 500);
		tween(self, {
			alpha: 0
		}, {
			duration: 1000,
			onFinish: function onFinish() {
				self.destroy();
			}
		});
		currentWave++;
		bossDefeated = true;
		nextWaveTimer = 180; // 3 seconds until next wave
		return self.scoreValue;
	};
	self.update = function () {
		if (!self.active) {
			return;
		}
		// Move toward hero but more intelligently
		if (hero) {
			var dx = hero.x - self.x;
			var dy = hero.y - self.y;
			var dist = Math.sqrt(dx * dx + dy * dy);
			// Different movement patterns
			if (self.attackPattern === 0) {
				// Direct approach
				if (dist > 0) {
					self.x += dx / dist * self.speed;
					self.y += dy / dist * self.speed;
				}
			} else if (self.attackPattern === 1) {
				// Circle around
				var angle = Math.atan2(dy, dx) + Math.PI / 4;
				self.x += Math.cos(angle) * self.speed * 1.5;
				self.y += Math.sin(angle) * self.speed * 1.5;
			} else if (self.attackPattern === 2) {
				// Charge attack
				if (self.attackCooldown > 30) {
					self.x += dx / dist * self.speed * 2.5;
					self.y += dy / dist * self.speed * 2.5;
				} else {
					// Wait
				}
			}
			// Check for collision with hero
			if (hero.invulnerable <= 0 && !hero.isDashing) {
				if (self.intersects(hero)) {
					hero.takeDamage();
				}
			}
		}
		// Attack pattern cooldown
		self.attackCooldown--;
		if (self.attackCooldown <= 0) {
			self.attackPattern = (self.attackPattern + 1) % 3;
			self.attackCooldown = 120; // 2 seconds per pattern
		}
		// Keep within screen bounds
		self.x = Math.max(100, Math.min(2048 - 100, self.x));
		self.y = Math.max(100, Math.min(2732 - 100, self.y));
	};
	return self;
});
var DashTrail = Container.expand(function () {
	var self = Container.call(this);
	var trailGraphic = self.attachAsset('dashTrail', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.7
	});
	self.init = function (x, y) {
		self.x = x;
		self.y = y;
		self.lifetime = 20; // frames the trail will live
		return self;
	};
	self.update = function () {
		self.lifetime--;
		trailGraphic.alpha = self.lifetime / 20 * 0.7;
		if (self.lifetime <= 0) {
			self.destroy();
		}
	};
	return self;
});
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphic = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 2;
	self.health = 1;
	self.scoreValue = 100;
	self.active = true;
	self.init = function (x, y) {
		self.x = x;
		self.y = y;
		return self;
	};
	self.takeDamage = function () {
		if (!self.active) {
			return;
		}
		// Increased damage when hero has consecutive dashes
		var damageAmount = 1;
		if (hero && hero.consecutiveDashes > 0) {
			damageAmount = Math.min(3, 1 + hero.consecutiveDashes);
		}
		self.health -= damageAmount;
		if (self.health <= 0) {
			self.die();
		} else {
			// Flash enemy
			LK.effects.flashObject(self, 0xffffff, 200);
		}
	};
	self.die = function () {
		if (!self.active) {
			return;
		}
		self.active = false;
		LK.getSound('hit').play();
		// Flash and fade out
		tween(self, {
			alpha: 0
		}, {
			duration: 300,
			onFinish: function onFinish() {
				self.destroy();
			}
		});
		return self.scoreValue;
	};
	self.update = function () {
		if (!self.active) {
			return;
		}
		// Move toward hero
		if (hero && !hero.isDashing) {
			var dx = hero.x - self.x;
			var dy = hero.y - self.y;
			var dist = Math.sqrt(dx * dx + dy * dy);
			if (dist > 0) {
				self.x += dx / dist * self.speed;
				self.y += dy / dist * self.speed;
			}
		}
		// Check for collision with hero
		if (hero && !hero.isDashing && hero.invulnerable <= 0) {
			if (self.intersects(hero)) {
				hero.takeDamage();
			}
		}
	};
	return self;
});
var Hazard = Container.expand(function () {
	var self = Container.call(this);
	var hazardGraphic = self.attachAsset('hazard', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.active = true;
	self.rotateSpeed = 0.03;
	self.init = function (x, y) {
		self.x = x;
		self.y = y;
		return self;
	};
	self.update = function () {
		if (!self.active) {
			return;
		}
		// Rotate hazard
		hazardGraphic.rotation += self.rotateSpeed;
		// Check for collision with hero
		if (hero && hero.invulnerable <= 0 && self.intersects(hero)) {
			if (hero.isDashing) {
				// Destroy hazard if hero is dashing
				self.destroy();
				self.active = false;
			} else {
				hero.takeDamage();
			}
		}
	};
	return self;
});
var Hero = Container.expand(function () {
	var self = Container.call(this);
	var heroGraphic = self.attachAsset('hero', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Add touch event handler to toggle auto-shooting
	self.down = function (x, y, obj) {
		self.autoShootEnabled = !self.autoShootEnabled;
		// Visual feedback when toggling
		tween(heroGraphic, {
			tint: self.autoShootEnabled ? 0x3498db : 0xcccccc,
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 200,
			onFinish: function onFinish() {
				tween(heroGraphic, {
					// Don't reset tint here, let the update method handle it
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 200
				});
			}
		});
		// Play sound for feedback
		LK.getSound('powerup').play();
		// Show auto-shoot status text with better visibility
		var statusTxt = new Text2(self.autoShootEnabled ? 'Auto-Shoot ON' : 'Auto-Shoot OFF', {
			size: 80,
			fill: self.autoShootEnabled ? 0x3498db : 0xcccccc
		});
		statusTxt.anchor.set(0.5, 0.5);
		statusTxt.x = self.x;
		statusTxt.y = self.y - 120;
		game.addChild(statusTxt);
		// Fade out the text with better animation
		tween(statusTxt, {
			alpha: 0,
			y: statusTxt.y - 80,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 1000,
			onFinish: function onFinish() {
				statusTxt.destroy();
			}
		});
	};
	self.dashSpeed = 60;
	self.dashDistance = 700;
	self.isDashing = false;
	self.dashCooldown = 0;
	self.health = 3;
	self.invulnerable = 0;
	self.combo = 0;
	self.score = 0;
	self.consecutiveDashes = 0;
	self.powerBoost = 1; // Base power multiplier
	self.lastDashTime = 0;
	self.autoShootEnabled = true; // Enable auto-shooting by default
	self.shootCooldown = 0; // Cooldown timer for auto-shooting
	self.shootInterval = 30; // Frames between auto-shots (0.5 seconds)
	self.dashToPoint = function (targetX, targetY) {
		if (self.dashCooldown > 0 || self.isDashing) {
			return;
		}
		var dx = targetX - self.x;
		var dy = targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Normalize direction
		var dirX = dx / distance;
		var dirY = dy / distance;
		// Set dash parameters
		self.isDashing = true;
		self.dashDirection = {
			x: dirX,
			y: dirY
		};
		self.dashRemaining = self.dashDistance;
		// Check if this is a quick consecutive dash
		var currentTime = LK.ticks;
		if (currentTime - self.lastDashTime < 30) {
			self.consecutiveDashes++;
			// Bonus speed for consecutive dashes (up to 50% bonus)
			var speedBonus = Math.min(0.5, self.consecutiveDashes * 0.1);
			self.dashSpeed = 60 * (1 + speedBonus);
			self.dashCooldown = Math.max(5, 10 - self.consecutiveDashes); // reduced cooldown for consecutive dashes
		} else {
			self.consecutiveDashes = 0;
			self.dashSpeed = 60;
			self.dashCooldown = 10; // standard cooldown
		}
		self.lastDashTime = currentTime;
		// Visual dash effect
		tween(heroGraphic, {
			scaleX: 1.3,
			scaleY: 0.7
		}, {
			duration: 200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(heroGraphic, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 300,
					easing: tween.elasticOut
				});
			}
		});
		// Play dash sound
		LK.getSound('dash').play();
	};
	self.takeDamage = function () {
		if (self.invulnerable > 0) {
			return;
		}
		self.health--;
		self.invulnerable = 60; // invulnerable for 1 second
		self.combo = 0; // Reset combo
		// Flash hero red
		LK.effects.flashObject(self, 0xff0000, 500);
		// Play damage sound
		LK.getSound('damage').play();
		if (self.health <= 0) {
			LK.showGameOver();
		}
	};
	self.addScore = function (points) {
		self.combo++;
		var comboMultiplier = Math.min(4, 1 + self.combo * 0.1);
		var scoreToAdd = Math.floor(points * comboMultiplier);
		self.score += scoreToAdd;
		LK.setScore(self.score);
	};
	self.update = function () {
		// Handle dash movement
		if (self.isDashing) {
			var moveX = self.dashDirection.x * self.dashSpeed;
			var moveY = self.dashDirection.y * self.dashSpeed;
			self.x += moveX;
			self.y += moveY;
			self.dashRemaining -= self.dashSpeed;
			// Create enhanced trail effect based on power boost
			if (LK.ticks % 1 === 0) {
				var trail = new DashTrail().init(self.x, self.y);
				// Trail size based on power boost and randomness
				var trailScale = (0.8 + Math.random() * 0.5) * (1 + (self.powerBoost - 1) * 0.5);
				trail.scale.set(trailScale, trailScale);
				// Tint trail based on power level
				if (self.powerBoost > 1) {
					trail.tint = 0xFF5500;
				}
				game.addChild(trail);
				trails.push(trail);
			}
			// End dash if we've gone far enough
			if (self.dashRemaining <= 0) {
				self.isDashing = false;
			}
		}
		// Auto-shooting functionality
		if (self.autoShootEnabled && !self.isDashing) {
			if (self.shootCooldown <= 0) {
				// Find closest enemy to target
				var closestEnemy = null;
				var closestDistance = Infinity;
				for (var i = 0; i < enemies.length; i++) {
					if (enemies[i] && enemies[i].active) {
						var dx = enemies[i].x - self.x;
						var dy = enemies[i].y - self.y;
						var distance = Math.sqrt(dx * dx + dy * dy);
						if (distance < closestDistance) {
							closestDistance = distance;
							closestEnemy = enemies[i];
						}
					}
				}
				// If we found an enemy, shoot at it
				if (closestEnemy && closestDistance < 1000) {
					// Only shoot if enemy is within range
					// Calculate direction to enemy
					var dx = closestEnemy.x - self.x;
					var dy = closestEnemy.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					// Normalize direction
					var dirX = dx / distance;
					var dirY = dy / distance;
					// Create auto-dash effect towards enemy but shorter than normal dash
					var targetX = self.x + dirX * Math.min(distance * 0.8, 400);
					var targetY = self.y + dirY * Math.min(distance * 0.8, 400);
					// Auto dash with a shorter distance
					self.dashToPoint(targetX, targetY);
					// Reset shoot cooldown, reduced based on power boost
					self.shootCooldown = Math.max(10, self.shootInterval - self.powerBoost * 5);
				}
			} else {
				self.shootCooldown--;
			}
		}
		// Keep within screen bounds
		self.x = Math.max(50, Math.min(2048 - 50, self.x));
		self.y = Math.max(50, Math.min(2732 - 50, self.y));
		// Cooldowns
		if (self.dashCooldown > 0) {
			self.dashCooldown--;
		}
		if (self.invulnerable > 0) {
			self.invulnerable--;
			// Flicker effect during invulnerability
			heroGraphic.alpha = LK.ticks % 6 < 3 ? 0.4 : 1;
		} else {
			// Show auto-shoot status with a subtle visual indicator
			if (self.autoShootEnabled) {
				// Subtle pulse effect when auto-shoot is enabled
				var pulseScale = 1 + Math.sin(LK.ticks * 0.05) * 0.05;
				heroGraphic.alpha = 1;
				heroGraphic.tint = 0x3498db; // Light blue tint for auto-shoot
			} else {
				heroGraphic.alpha = 1;
				heroGraphic.tint = 0xFFFFFF; // Normal color when disabled
			}
		}
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerUpGraphic = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.type = 'health'; // Default type
	self.active = true;
	self.lifetime = 300; // 5 seconds
	self.init = function (x, y, type) {
		self.x = x;
		self.y = y;
		self.type = type || self.type;
		// Set color based on type
		if (self.type === 'health') {
			powerUpGraphic.tint = 0x2ecc71; // Green
		} else if (self.type === 'speed') {
			powerUpGraphic.tint = 0x3498db; // Blue
		} else if (self.type === 'power') {
			powerUpGraphic.tint = 0xe74c3c; // Red
		} else if (self.type === 'strength') {
			powerUpGraphic.tint = 0x9b59b6; // Purple
		}
		return self;
	};
	self.collect = function () {
		if (!self.active) {
			return;
		}
		self.active = false;
		LK.getSound('powerup').play();
		if (self.type === 'health' && hero.health < 3) {
			hero.health++;
		} else if (self.type === 'speed') {
			hero.dashSpeed = 80; // Even faster dash
			hero.dashDistance = 900; // Even longer dash
			// Visual indicator of speed boost
			tween(hero, {
				alpha: 0.7
			}, {
				duration: 200,
				onFinish: function onFinish() {
					tween(hero, {
						alpha: 1
					}, {
						duration: 200
					});
				}
			});
			// Reset after 10 seconds
			LK.setTimeout(function () {
				if (hero) {
					hero.dashSpeed = 60;
					hero.dashDistance = 700;
				}
			}, 10000);
		} else if (self.type === 'strength') {
			// Increase hero's attack strength more permanently
			hero.powerBoost = Math.min(5, hero.powerBoost + 1);
			// Visual indicator of strength boost
			tween(hero, {
				tint: 0x9b59b6
			}, {
				duration: 500,
				onFinish: function onFinish() {
					tween(hero, {
						tint: 0xFFFFFF
					}, {
						duration: 500
					});
				}
			});
			// Show strength level
			var strengthTxt = new Text2('STRENGTH +' + hero.powerBoost + '!', {
				size: 80,
				fill: 0x9b59b6
			});
			strengthTxt.anchor.set(0.5, 0.5);
			strengthTxt.x = 2048 / 2;
			strengthTxt.y = 2732 / 2;
			game.addChild(strengthTxt);
			// Fade out the text
			tween(strengthTxt, {
				alpha: 0,
				y: strengthTxt.y - 100
			}, {
				duration: 1500,
				onFinish: function onFinish() {
					strengthTxt.destroy();
				}
			});
		} else if (self.type === 'power') {
			// Clear all enemies
			for (var i = enemies.length - 1; i >= 0; i--) {
				if (enemies[i].active) {
					var points = enemies[i].die();
					hero.addScore(points);
				}
			}
			// Increase hero's attack strength
			hero.powerBoost = 3;
			// Visual indicator of power boost
			tween(hero, {
				tint: 0xFF0000
			}, {
				duration: 300
			});
			// Reset after 10 seconds
			LK.setTimeout(function () {
				if (hero) {
					hero.powerBoost = 1;
					tween(hero, {
						tint: 0xFFFFFF
					}, {
						duration: 500
					});
				}
			}, 10000);
		}
		// Flash and fade out
		tween(self, {
			alpha: 0,
			scaleX: 2,
			scaleY: 2
		}, {
			duration: 300,
			onFinish: function onFinish() {
				self.destroy();
			}
		});
	};
	self.update = function () {
		if (!self.active) {
			return;
		}
		// Floating animation
		self.y += Math.sin(LK.ticks * 0.1) * 0.5;
		// Rotate slowly
		powerUpGraphic.rotation += 0.02;
		// Check for collision with hero
		if (hero && (hero.intersects(self) || hero.isDashing && self.distanceTo(hero) < 100)) {
			self.collect();
		}
		// Expire after lifetime
		self.lifetime--;
		if (self.lifetime <= 0) {
			tween(self, {
				alpha: 0
			}, {
				duration: 300,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
			self.active = false;
		}
	};
	self.distanceTo = function (target) {
		var dx = target.x - self.x;
		var dy = target.y - self.y;
		return Math.sqrt(dx * dx + dy * dy);
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000022
});
/**** 
* Game Code
****/ 
// Game state variables
var hero;
var enemies = [];
var powerUps = [];
var hazards = [];
var trails = [];
var currentWave = 1;
var nextWaveTimer = 0;
var spawnTimer = 0;
var bossDefeated = false;
var swipeStart = {
	x: 0,
	y: 0
};
var isSwipeActive = false;
// UI elements
var scoreTxt;
var waveTxt;
var healthTxt;
var comboTxt;
// Game constants
var SPAWN_INTERVAL = 120; // Frames between enemy spawns (increased from 60)
var POWER_UP_CHANCE = 0.15; // Chance to spawn power-up on enemy defeat
var WAVE_ENEMY_COUNT = 5; // Enemies per wave (reduced from 10)
// Initialize game elements
function initGame() {
	// Create hero
	hero = new Hero();
	hero.x = 2048 / 2;
	hero.y = 2732 / 2;
	game.addChild(hero);
	// Show auto-shoot enabled status at start
	var autoShootTxt = new Text2('Auto-Shoot Enabled', {
		size: 60,
		fill: 0x3498db
	});
	autoShootTxt.anchor.set(0.5, 0.5);
	autoShootTxt.x = 2048 / 2;
	autoShootTxt.y = 2732 / 2 + 200;
	game.addChild(autoShootTxt);
	// Fade out the text
	tween(autoShootTxt, {
		alpha: 0,
		y: autoShootTxt.y - 50
	}, {
		duration: 2000,
		onFinish: function onFinish() {
			autoShootTxt.destroy();
		}
	});
	// Create UI elements
	scoreTxt = new Text2('Score: 0', {
		size: 60,
		fill: 0xFFFFFF
	});
	scoreTxt.anchor.set(0, 0);
	LK.gui.topRight.addChild(scoreTxt);
	waveTxt = new Text2('Wave: 1', {
		size: 60,
		fill: 0xFFFFFF
	});
	waveTxt.anchor.set(1, 0);
	LK.gui.top.addChild(waveTxt);
	healthTxt = new Text2('❤️❤️❤️', {
		size: 60,
		fill: 0xFFFFFF
	});
	healthTxt.anchor.set(0, 0);
	LK.gui.bottom.addChild(healthTxt);
	comboTxt = new Text2('Combo: 0x', {
		size: 60,
		fill: 0xFFFFFF
	});
	comboTxt.anchor.set(1, 0);
	LK.gui.bottom.addChild(comboTxt);
	// Start the first wave
	startNewWave();
	// Play background music
	LK.playMusic('gameMusic', {
		fade: {
			start: 0,
			end: 0.5,
			duration: 1000
		}
	});
}
// Start a new wave of enemies
function startNewWave() {
	waveTxt.setText('Wave: ' + currentWave);
	if (currentWave % 3 === 0) {
		// Boss wave
		spawnBoss();
	} else {
		// Regular wave
		spawnTimer = 0;
	}
	// Add some hazards
	for (var i = 0; i < Math.min(currentWave, 5); i++) {
		spawnHazard();
	}
}
// Spawn a regular enemy
function spawnEnemy() {
	// Enforce a maximum number of enemies
	if (enemies.length >= 10) {
		return;
	}
	var edge = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left
	var x, y;
	switch (edge) {
		case 0:
			// Top
			x = Math.random() * 2048;
			y = -50;
			break;
		case 1:
			// Right
			x = 2048 + 50;
			y = Math.random() * 2732;
			break;
		case 2:
			// Bottom
			x = Math.random() * 2048;
			y = 2732 + 50;
			break;
		case 3:
			// Left
			x = -50;
			y = Math.random() * 2732;
			break;
	}
	var enemy = new Enemy().init(x, y);
	enemy.speed = 2 + currentWave * 0.3; // Speed increases with wave
	if (currentWave > 2) {
		enemy.health = Math.min(3, 1 + Math.floor(currentWave / 3));
	}
	game.addChild(enemy);
	enemies.push(enemy);
}
// Spawn a boss
function spawnBoss() {
	var boss = new Boss().init(2048 / 2, -200);
	boss.health = 10 + currentWave / 3;
	game.addChild(boss);
	enemies.push(boss);
	// Make a dramatic entrance
	tween(boss, {
		y: 400
	}, {
		duration: 2000,
		easing: tween.bounceOut
	});
}
// Spawn a hazard
function spawnHazard() {
	var x = 200 + Math.random() * (2048 - 400);
	var y = 200 + Math.random() * (2732 - 400);
	// Make sure it's not too close to the hero
	var dx = x - hero.x;
	var dy = y - hero.y;
	if (Math.sqrt(dx * dx + dy * dy) < 300) {
		x = x < 1024 ? x + 600 : x - 600;
		y = y < 1366 ? y + 600 : y - 600;
	}
	var hazard = new Hazard().init(x, y);
	game.addChild(hazard);
	hazards.push(hazard);
}
// Spawn a power-up
function spawnPowerUp(x, y) {
	var types = ['health', 'speed', 'power', 'strength'];
	var type = types[Math.floor(Math.random() * types.length)];
	var powerUp = new PowerUp().init(x, y, type);
	game.addChild(powerUp);
	powerUps.push(powerUp);
}
// Handle touch/mouse down
game.down = function (x, y, obj) {
	isSwipeActive = true;
	swipeStart.x = x;
	swipeStart.y = y;
};
// Handle touch/mouse up
game.up = function (x, y, obj) {
	if (isSwipeActive) {
		// Calculate swipe direction and distance
		var dx = x - swipeStart.x;
		var dy = y - swipeStart.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// If it's a significant swipe, dash in that direction
		if (distance > 50) {
			// Calculate target point to dash towards
			var targetX = hero.x + dx * 2;
			var targetY = hero.y + dy * 2;
			hero.dashToPoint(targetX, targetY);
		}
		isSwipeActive = false;
	}
};
// Handle touch/mouse move
game.move = function (x, y, obj) {
	// We'll use swipe up/down instead of tracking movement
};
// Main game update loop
game.update = function () {
	// Update UI
	scoreTxt.setText('Score: ' + LK.getScore());
	comboTxt.setText('Combo: ' + hero.combo + 'x');
	// Update health display
	var healthStr = '';
	for (var i = 0; i < hero.health; i++) {
		healthStr += '❤️';
	}
	healthTxt.setText(healthStr);
	// Spawn enemies
	if (currentWave % 3 !== 0 || bossDefeated) {
		spawnTimer++;
		if (spawnTimer >= SPAWN_INTERVAL && enemies.length < WAVE_ENEMY_COUNT + Math.min(5, currentWave)) {
			// 40% chance to skip spawning
			if (Math.random() > 0.4) {
				spawnEnemy();
			}
			spawnTimer = 0;
		}
	}
	// Handle next wave
	if (nextWaveTimer > 0) {
		nextWaveTimer--;
		if (nextWaveTimer === 0) {
			bossDefeated = false;
			startNewWave();
		}
	} else if (enemies.length === 0 && currentWave % 3 !== 0) {
		// Wave completed
		currentWave++;
		nextWaveTimer = 120; // 2 seconds until next wave
	}
	// Update game objects
	updateGameObjects();
	// Detect collisions between hero dash and enemies
	if (hero.isDashing) {
		// Increase dash hit area based on power boost
		var extraHitArea = (hero.powerBoost - 1) * 30;
		for (var i = enemies.length - 1; i >= 0; i--) {
			var enemy = enemies[i];
			// Check for collision with expanded hit area for power boost
			var dx = enemy.x - hero.x;
			var dy = enemy.y - hero.y;
			var dist = Math.sqrt(dx * dx + dy * dy);
			var hitRange = 80 + extraHitArea; // Base hit range plus power boost extra area
			if (enemy.active && (hero.intersects(enemy) || dist < hitRange)) {
				enemy.takeDamage();
				if (enemy.health <= 0) {
					// Award points
					hero.addScore(enemy.scoreValue * hero.powerBoost); // Multiply score by power boost
					// Maybe spawn a power-up
					if (Math.random() < POWER_UP_CHANCE) {
						spawnPowerUp(enemy.x, enemy.y);
					}
					// Remove enemy from array
					enemies.splice(i, 1);
				}
			}
		}
	}
	// Clean up destroyed objects
	cleanupDestroyedObjects();
};
// Update all game objects
function updateGameObjects() {
	// Update hero
	if (hero) {
		hero.update();
	}
	// Update enemies
	for (var i = 0; i < enemies.length; i++) {
		if (enemies[i]) {
			enemies[i].update();
		}
	}
	// Update power-ups
	for (var i = 0; i < powerUps.length; i++) {
		if (powerUps[i]) {
			powerUps[i].update();
		}
	}
	// Update hazards
	for (var i = 0; i < hazards.length; i++) {
		if (hazards[i]) {
			hazards[i].update();
		}
	}
	// Update trails
	for (var i = 0; i < trails.length; i++) {
		if (trails[i]) {
			trails[i].update();
		}
	}
}
// Clean up destroyed objects
function cleanupDestroyedObjects() {
	// Clean up destroyed enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		if (!enemies[i] || !enemies[i].parent) {
			enemies.splice(i, 1);
		}
	}
	// Clean up destroyed power-ups
	for (var i = powerUps.length - 1; i >= 0; i--) {
		if (!powerUps[i] || !powerUps[i].parent) {
			powerUps.splice(i, 1);
		}
	}
	// Clean up destroyed hazards
	for (var i = hazards.length - 1; i >= 0; i--) {
		if (!hazards[i] || !hazards[i].parent) {
			hazards.splice(i, 1);
		}
	}
	// Clean up destroyed trails
	for (var i = trails.length - 1; i >= 0; i--) {
		if (!trails[i] || !trails[i].parent) {
			trails.splice(i, 1);
		}
	}
}
// Initialize the game
initGame(); ===================================================================
--- original.js
+++ change.js
@@ -257,29 +257,33 @@
 		}, {
 			duration: 200,
 			onFinish: function onFinish() {
 				tween(heroGraphic, {
-					tint: 0xFFFFFF,
+					// Don't reset tint here, let the update method handle it
 					scaleX: 1,
 					scaleY: 1
 				}, {
 					duration: 200
 				});
 			}
 		});
-		// Show auto-shoot status text
+		// Play sound for feedback
+		LK.getSound('powerup').play();
+		// Show auto-shoot status text with better visibility
 		var statusTxt = new Text2(self.autoShootEnabled ? 'Auto-Shoot ON' : 'Auto-Shoot OFF', {
-			size: 60,
+			size: 80,
 			fill: self.autoShootEnabled ? 0x3498db : 0xcccccc
 		});
 		statusTxt.anchor.set(0.5, 0.5);
 		statusTxt.x = self.x;
-		statusTxt.y = self.y - 100;
+		statusTxt.y = self.y - 120;
 		game.addChild(statusTxt);
-		// Fade out the text
+		// Fade out the text with better animation
 		tween(statusTxt, {
 			alpha: 0,
-			y: statusTxt.y - 50
+			y: statusTxt.y - 80,
+			scaleX: 1.5,
+			scaleY: 1.5
 		}, {
 			duration: 1000,
 			onFinish: function onFinish() {
 				statusTxt.destroy();
@@ -416,9 +420,10 @@
 						}
 					}
 				}
 				// If we found an enemy, shoot at it
-				if (closestEnemy) {
+				if (closestEnemy && closestDistance < 1000) {
+					// Only shoot if enemy is within range
 					// Calculate direction to enemy
 					var dx = closestEnemy.x - self.x;
 					var dy = closestEnemy.y - self.y;
 					var distance = Math.sqrt(dx * dx + dy * dy);
@@ -448,9 +453,18 @@
 			self.invulnerable--;
 			// Flicker effect during invulnerability
 			heroGraphic.alpha = LK.ticks % 6 < 3 ? 0.4 : 1;
 		} else {
-			heroGraphic.alpha = 1;
+			// Show auto-shoot status with a subtle visual indicator
+			if (self.autoShootEnabled) {
+				// Subtle pulse effect when auto-shoot is enabled
+				var pulseScale = 1 + Math.sin(LK.ticks * 0.05) * 0.05;
+				heroGraphic.alpha = 1;
+				heroGraphic.tint = 0x3498db; // Light blue tint for auto-shoot
+			} else {
+				heroGraphic.alpha = 1;
+				heroGraphic.tint = 0xFFFFFF; // Normal color when disabled
+			}
 		}
 	};
 	return self;
 });
 colored spider. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 white silk web. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 amazing spider web on tree branch. anime image. green landscape Single Game Texture. In-Game asset. 2d.
 flyn lady bug 2d cartoon objek. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 flyin evil woodpecker bird. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows