User prompt
The animation did not work. All I saw was a blinking dot and no line stretching out from it. Also the soldier clone did not spawn.
User prompt
I didn’t see the tv affect when the soldier clone spawned. Also remember the clone should not move until the animation is complete.
User prompt
Let’s redo the tv affect a little bit. The effect should start basically as a dot that stretches into a horizontal line that’s twice as wide as the soldier clone asset. Then the line should compress to half its width and the soldier clone should stretch vertically from behind the line until it’s at all size. During this it should not move until animation is complete.
User prompt
The scanlines for the soldier clone spawn should be smaller, only twice the size of the soldier clone horizontally and the soldier clone should asset should start in a squished state behind the line until gradually stretching out to full size.
User prompt
Can you create a TVTurnOnEffect class that uses white scanlines and scaling to create a retro TV power-on animation? It should start as a thin horizontal line and expand vertically while showing scanline effects. This will be used when spawning Soldier Clones.
Code edit (4 edits merged)
Please save this source code
User prompt
Increase the time before Blaster begins laser sequence.
Code edit (8 edits merged)
Please save this source code
User prompt
Replace laser mechanic start sliding with this: LaserMechanic.prototype.startSliding = function () { this.isSliding = true; this.slideStartTime = LK.ticks; };
User prompt
Replace laser mechanic update firing with this: LaserMechanic.prototype.updateFiring = function () { if (!this.isFiring) return; var fireProgress = (LK.ticks - this.fireStartTime) / this.fireDuration; if (fireProgress <= 1) { // Add new segments quickly until desired length if (this.segments.length < 20 && LK.ticks % 2 === 0) { // Adjust segment count and speed var lastSegment = this.segments[this.segments.length - 1]; var segment = new LaserBeamSegment(); // Position new segment based on last one segment.x = lastSegment.x - Math.sin(this.rotation) * segment.height; segment.y = lastSegment.y + Math.cos(this.rotation) * segment.height; segment.rotation = this.rotation; game.addChild(segment); this.segments.push(segment); } } else { this.isFiring = false; this.startSliding(); } };
User prompt
Replace laser mechanic start firing with this: LaserMechanic.prototype.startFiring = function () { if (!this.origin || !this.targetX || !this.targetY || this.isFiring) { return; } this.isFiring = true; this.fireStartTime = LK.ticks; // Calculate direction var dirX = this.targetX - this.origin.x; var dirY = this.targetY - this.origin.y; this.rotation = Math.atan2(dirY, dirX) - Math.PI / 2; // Create array to hold segments this.segments = []; // Create initial segment var segment = new LaserBeamSegment(); segment.x = this.origin.x; segment.y = this.origin.y; segment.rotation = this.rotation; game.addChild(segment); this.segments.push(segment); };
User prompt
Add this class to the game:var LaserBeamSegment = Container.expand(function() { var self = Container.call(this); // Attach laser segment graphic var laserGraphics = self.attachAsset('LaserBeam', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 // Each segment stays at normal scale }); // Handle own collision self.update = function() { if (CollisionManager.checkCollision(self, hero)) { if (hero.shielded) { hero.shieldLevel -= 1; if (hero.shieldLevel <= 0) { hero.shielded = false; if (hero.shieldGraphics) { hero.shieldGraphics.destroy(); hero.shieldGraphics = null; } } } else { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } } // Check clone collisions for (var i = soldierClones.length - 1; i >= 0; i--) { var clone = soldierClones[i]; if (CollisionManager.checkCollision(self, clone)) { clone.destroy(); break; } } }; return self; });
User prompt
Add 30% to the slide duration for Blaster
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Reduce the time before blaster initial laser fire.
Code edit (7 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: Can't find variable: laserBeam' in or related to this line: 'if (CollisionManager.checkCollision(laserBeam, hero)) {' Line Number: 1978
Code edit (1 edits merged)
Please save this source code
Code edit (8 edits merged)
Please save this source code
User prompt
Decrease the initial time before Blaster fires their laser
Code edit (8 edits merged)
Please save this source code
User prompt
In the laser mechanic change the collision box to visible.
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
/**** 
* Classes
****/ 
// Blaster class representing a shooting enemy
var Blaster = Container.expand(function () {
	var self = Container.call(this);
	var blasterGraphics = self.attachAsset('Blaster', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.HitPoints = 10;
	self.speed = 3;
	// Laser attack properties
	self.laserMechanic = new LaserMechanic(self, 60, 30, 39); // charge, fire, slide durations
	self.nextAttackTime = LK.ticks + randomRange(120, 240); // 2-4 seconds initial delay
	function randomRange(min, max) {
		return Math.floor(Math.random() * (max - min + 1)) + min;
	}
	self.update = function () {
		// Update laser mechanic
		self.laserMechanic.update();
		// Check if it's time for a laser attack
		if (LK.ticks >= self.nextAttackTime && !self.laserMechanic.isCharging && !self.laserMechanic.isFiring && !self.laserMechanic.isSliding && !self.laserMechanic.attackComplete) {
			self.laserMechanic.startCharge();
		}
		// Handle movement based on state
		if (self.laserMechanic.isCharging) {
			// Only rotate to track player during charge
			var directionX = hero.x - self.x;
			var directionY = hero.y - self.y;
			blasterGraphics.rotation = Math.atan2(directionY, directionX) - Math.PI / 2;
		} else if (self.laserMechanic.isFiring || self.laserMechanic.isSliding) {
			// No movement during firing and sliding
			return;
		} else {
			// Normal movement when not attacking
			// Track player position
			var directionX = hero.x - self.x;
			var directionY = hero.y - self.y;
			var distance = Math.sqrt(directionX * directionX + directionY * directionY);
			if (distance > 0) {
				self.x += directionX / distance * self.speed;
				self.y += directionY / distance * self.speed;
				blasterGraphics.rotation = Math.atan2(directionY, directionX) - Math.PI / 2;
			}
			// Set next attack time after sliding is done
			if (self.laserMechanic.isAttackComplete()) {
				self.laserMechanic.resetAttack();
				self.nextAttackTime = LK.ticks + randomRange(300, 480);
			}
		}
		// Destroy if out of screen
		if (CollisionManager.checkCollision(self, hero)) {
			// Handle collision with hero
			if (hero.shielded) {
				hero.shieldLevel -= 1;
				if (hero.shieldLevel <= 0) {
					hero.shielded = false;
					if (hero.shieldGraphics) {
						hero.shieldGraphics.destroy();
						hero.shieldGraphics = null;
					}
				} else {
					hero.shieldGraphics.tint = 0xFFFFFF;
					if (hero.shieldLevel === 2) {
						hero.shieldGraphics.tint = 0xFFFF00;
					} else if (hero.shieldLevel === 1) {
						hero.shieldGraphics.tint = 0xFFFFFF;
					}
				}
				// Destroy the enemy
				generateEnemyPieces(self, BlasterPiece, ['BlasterBottomPiece', 'BlasterLeftPiece', 'BlasterRightPiece']);
				self.destroy();
				var index = enemies.indexOf(self);
				if (index > -1) {
					enemies.splice(index, 1);
				}
			} else {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
			}
		}
		if (self.HitPoints <= 0) {
			// Create blaster pieces upon destruction
			generateEnemyPieces(self, BlasterPiece, ['BlasterBottomPiece', 'BlasterLeftPiece', 'BlasterRightPiece']);
			// Check if there's an active laser beam
			if (self.laserMechanic.laserBeam) {
				// Detach and slide the laser beam
				self.laserMechanic.detachBeam();
			}
			self.destroy();
			var index = enemies.indexOf(self);
			if (index > -1) {
				enemies.splice(index, 1);
			}
		} else if (self.y > 2732) {
			self.destroy();
			var index = enemies.indexOf(self);
			if (index > -1) {
				enemies.splice(index, 1);
				difficultyManager.onEnemyDestroyed();
			}
		}
	};
});
// BlasterPiece class for blaster destruction effect
var BlasterPiece = Container.expand(function (assetType) {
	var self = Container.call(this);
	var pieceGraphics = self.attachAsset(assetType, {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 1 // Ensure pieces are fully visible on spawn
	});
	self.speedX = (Math.random() - 0.5) * 12; // Random horizontal speed to move outwards
	self.speedY = (Math.random() - 0.5) * 12; // Random vertical speed to move outwards
	self.alphaDecay = 0.02; // Rate at which the piece fades out
	self.update = function () {
		self.x += self.speedX;
		self.y += self.speedY;
		pieceGraphics.rotation += Math.random() * 0.1 - 0.05; // Add slight random rotation
		pieceGraphics.alpha -= self.alphaDecay;
		if (pieceGraphics.alpha <= 0) {
			self.destroy();
		}
	};
});
var BombBlast = Container.expand(function () {
	var self = Container.call(this);
	var blastGraphics = self.attachAsset('BombBlast', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.scaleX = 0.1;
	self.scaleY = 0.1;
	self.update = function () {
		self.scaleX += 0.5;
		self.scaleY += 0.5;
		blastGraphics.scale.x = self.scaleX;
		blastGraphics.scale.y = self.scaleY;
		if (self.scaleX >= 10) {
			self.destroy();
		}
	};
});
// Bruiser class representing a tougher enemy
var Bruiser = Container.expand(function () {
	var self = Container.call(this);
	var bruiserGraphics = self.attachAsset('Bruiser', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.HitPoints = 20; // Double the hit points for Bruiser
	self.speed = 5;
	self.update = function () {
		// Implement mechanical stomping movement
		if (LK.ticks % 80 < 20) {
			bruiserGraphics.scale.x = 1.1;
			bruiserGraphics.scale.y = 0.9;
			bruiserGraphics.rotation = 0.1; // Tilt right
		} else if (LK.ticks % 80 < 40) {
			bruiserGraphics.scale.x = 1.0;
			bruiserGraphics.scale.y = 1.0;
			bruiserGraphics.rotation = 0;
		} else if (LK.ticks % 80 < 60) {
			bruiserGraphics.scale.x = 1.1;
			bruiserGraphics.scale.y = 0.9;
			bruiserGraphics.rotation = -0.1; // Tilt left
		} else {
			bruiserGraphics.scale.x = 1.0;
			bruiserGraphics.scale.y = 1.0;
			bruiserGraphics.rotation = 0;
		}
		// Move downwards only during tilt phases
		if (LK.ticks % 80 < 20 || LK.ticks % 80 >= 40 && LK.ticks % 80 < 60) {
			// Check for nearby enemies and adjust path to avoid collisions
			var nearbyEnemy = enemies.find(function (enemy) {
				return enemy !== self && Math.abs(enemy.x - self.x) < 100 && Math.abs(enemy.y - self.y) < 100;
			});
			if (nearbyEnemy) {
				self.x += (self.x < nearbyEnemy.x ? -1 : 1) * self.speed; // Move away from the nearby enemy
			} else {
				self.y += self.speed;
			}
		}
		if (CollisionManager.checkCollision(self, hero)) {
			// Handle collision with hero
			if (hero.shielded) {
				hero.shieldLevel -= 1;
				if (hero.shieldLevel <= 0) {
					hero.shielded = false;
					if (hero.shieldGraphics) {
						hero.shieldGraphics.destroy();
						hero.shieldGraphics = null;
					}
				} else {
					hero.shieldGraphics.tint = 0xFFFFFF;
					if (hero.shieldLevel === 2) {
						hero.shieldGraphics.tint = 0xFFFF00;
					} else if (hero.shieldLevel === 1) {
						hero.shieldGraphics.tint = 0xFFFFFF;
					}
				}
				// Destroy the enemy
				generateEnemyPieces(self, BruiserPiece, ['BruiserCenterPart', 'BruiserLeftPart', 'BruiserRightPart']);
				self.destroy();
				var index = enemies.indexOf(self);
				if (index > -1) {
					enemies.splice(index, 1);
				}
			} else {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
			}
		}
		if (self.HitPoints <= 0) {
			// Create bruiser pieces upon destruction
			generateEnemyPieces(self, BruiserPiece, ['BruiserCenterPart', 'BruiserLeftPart', 'BruiserRightPart']);
			self.destroy();
			var index = enemies.indexOf(self);
			if (index > -1) {
				enemies.splice(index, 1);
			}
		} else if (self.y > 2732) {
			self.destroy();
			var index = enemies.indexOf(self);
			if (index > -1) {
				enemies.splice(index, 1);
				difficultyManager.onEnemyDestroyed();
			}
		}
	};
});
// BruiserPiece class for bruiser destruction effect
var BruiserPiece = Container.expand(function (assetType) {
	var self = Container.call(this);
	var pieceGraphics = self.attachAsset(assetType, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = -Math.random() * 6 + 3; // Switch direction of horizontal speed
	self.speedY = Math.random() * 4 - 2; // Random vertical speed
	self.alphaDecay = 0.02; // Rate at which the piece fades out
	self.update = function () {
		self.x += self.speedX;
		self.y += self.speedY;
		pieceGraphics.rotation += Math.random() * 0.1 - 0.05; // Add slight random rotation
		pieceGraphics.alpha -= self.alphaDecay;
		if (pieceGraphics.alpha <= 0) {
			self.destroy();
		}
	};
});
var DifficultyManager = Container.expand(function () {
	var self = Container.call(this);
	self.currentDifficulty = 1;
	self.baseDifficulty = 1;
	self.activeEnemies = 0;
	self.maxEnemies = 30;
	self.roadStartX = 2048 * 0.21;
	self.roadWidth = 2048 * 0.55;
	// Wave patterns for different difficulty levels
	self.wavePatterns = {
		1: {
			drones: Math.ceil(6 * 1.3),
			bruisers: 0,
			blasters: 0,
			raiders: 0
		},
		2: {
			drones: Math.ceil(8 * 1.3),
			bruisers: 0,
			blasters: 0,
			raiders: 1
		},
		3: {
			drones: Math.ceil(8 * 1.3),
			bruisers: 1,
			blasters: 0,
			raiders: 2
		},
		4: {
			drones: Math.ceil(10 * 1.3),
			bruisers: 1,
			blasters: 1,
			raiders: 2
		},
		5: {
			drones: Math.ceil(12 * 1.3),
			bruisers: 1,
			blasters: 1,
			raiders: 3
		},
		6: {
			drones: Math.ceil(14 * 1.3),
			bruisers: 2,
			blasters: 1,
			raiders: 3
		},
		7: {
			drones: Math.ceil(16 * 1.3),
			bruisers: 2,
			blasters: 2,
			raiders: 4
		}
	};
	// Spawn quota to track needed spawns
	self.spawnQuota = {
		drones: 0,
		bruisers: 0,
		blasters: 0,
		raiders: 0
	};
	self.update = function () {
		var timeScale = Math.floor(LK.ticks / 1800);
		self.baseDifficulty = 1 + timeScale * 0.2;
		if (LK.ticks % 300 === 0) {
			var powerLevel = self.calculatePlayerPower();
			self.updateDifficulty(powerLevel);
		}
		// Fast spawn check for drones
		if (LK.ticks % 45 === 0 && self.canSpawnEnemy()) {
			// Twice as fast
			if (self.spawnQuota.drones > 0) {
				self.spawnEnemy('drone');
			}
		}
		// Regular spawn check for other enemies
		if (LK.ticks % 60 === 0 && self.canSpawnEnemy()) {
			var enemyType = self.getNextEnemyType();
			if (enemyType && enemyType !== 'drone') {
				self.spawnEnemy(enemyType);
			}
		}
	};
	self.updateDifficulty = function (powerLevel) {
		var totalPower = powerLevel * self.baseDifficulty;
		// Match to wave pattern keys 1-7
		if (totalPower >= 10) {
			self.currentDifficulty = 7;
		} else if (totalPower >= 8) {
			self.currentDifficulty = 6;
		} else if (totalPower >= 6) {
			self.currentDifficulty = 5;
		} else if (totalPower >= 4.5) {
			self.currentDifficulty = 4;
		} else if (totalPower >= 3) {
			self.currentDifficulty = 3;
		} else if (totalPower >= 2) {
			self.currentDifficulty = 2;
		} else {
			self.currentDifficulty = 1;
		}
		self.updateSpawnQuota();
	};
	self.getSpawnX = function () {
		return self.roadStartX + Math.random() * self.roadWidth;
	};
	self.getEnemyStrength = function () {
		// Remove enemy HP scaling with difficulty
		return 1;
	};
	self.updateSpawnQuota = function () {
		var pattern = self.wavePatterns[self.currentDifficulty] || self.wavePatterns[6]; // Default to highest if overflow
		self.spawnQuota.drones = pattern.drones;
		self.spawnQuota.bruisers = pattern.bruisers;
		self.spawnQuota.blasters = pattern.blasters;
		self.spawnQuota.raiders = pattern.raiders;
	};
	this.calculatePlayerPower = function () {
		var power = 1; // Base power level
		// Weapon power contribution (max level is 3 now)
		if (powerUpManager && powerUpManager.currentPowerLevel) {
			power += (powerUpManager.currentPowerLevel - 1) * 0.5; // Reduced from 0.8
		}
		// Clone contribution (max 4 clones)
		if (soldierClones && soldierClones.length) {
			power += soldierClones.length * 0.4; // Reduced from 0.6
		}
		// Drone contribution (max 3 drones)
		if (playerDrones && playerDrones.length) {
			power += playerDrones.length * 0.4; // Reduced from 0.6
		}
		return power;
	};
	self.canSpawnEnemy = function () {
		return self.activeEnemies < self.maxEnemies;
	};
	self.spawnEnemy = function (enemyType) {
		if (!self.canSpawnEnemy()) {
			return;
		}
		var enemy;
		switch (enemyType) {
			case 'drone':
				var redDroneChance = Math.min(self.currentDifficulty * 0.1, 0.3);
				if (Math.random() < redDroneChance) {
					enemy = new RedDrone();
				} else {
					enemy = new Drone();
				}
				break;
			case 'bruiser':
				enemy = new Bruiser();
				break;
			case 'blaster':
				enemy = new Blaster();
				break;
			case 'raider':
				enemy = new Raider();
				var spawnSide = Math.random() < 0.5;
				enemy.x = spawnSide ? -100 : 2148;
				enemy.y = Math.random() * (2732 * 0.3);
				enemy.spawnSide = spawnSide ? 'left' : 'right'; // Tell Raider which side it spawned from
				break;
			default:
				return;
		}
		// Increase enemy HP based on difficulty
		enemy.HitPoints *= self.getEnemyStrength();
		// Only set default spawn position for non-raiders
		if (enemyType !== 'raider') {
			enemy.x = self.getSpawnX();
			enemy.y = -enemy.height;
		}
		enemies.push(enemy);
		game.addChild(enemy);
		self.activeEnemies++;
	};
	self.getNextEnemyType = function () {
		// Get all available enemy types with remaining quota
		var availableTypes = [];
		if (self.spawnQuota.drones > 0) {
			availableTypes.push('drone');
		}
		if (self.spawnQuota.bruisers > 0) {
			availableTypes.push('bruiser');
		}
		if (self.spawnQuota.raiders > 0) {
			availableTypes.push('raider');
		}
		if (self.spawnQuota.blasters > 0) {
			availableTypes.push('blaster');
		}
		if (availableTypes.length === 0) {
			return null;
		}
		// Randomly select from available types
		var selectedType = availableTypes[Math.floor(Math.random() * availableTypes.length)];
		// Decrease the appropriate quota
		self.spawnQuota[selectedType + 's']--;
		return selectedType;
	};
	self.onEnemyDestroyed = function () {
		self.activeEnemies--;
		if (self.spawnQuota.drones === 0 && self.spawnQuota.bruisers === 0 && self.spawnQuota.blasters === 0 && self.spawnQuota.raiders === 0) {
			self.updateSpawnQuota();
		}
	};
});
// Enemy class representing the enemy robots
var Drone = Container.expand(function () {
	var self = Container.call(this);
	var droneGraphics = self.attachAsset('Drone', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.HitPoints = 1;
	self.randomOffset = Math.random() * 100; // Random timing for each drone
	self.speed = 2.75;
	self.update = function () {
		// Add robotic hover effects
		// Check for nearby enemies and adjust path to avoid collisions
		var nearbyEnemy = enemies.find(function (enemy) {
			return enemy !== self && Math.abs(enemy.x - self.x) < 100 && Math.abs(enemy.y - self.y) < 100;
		});
		if (nearbyEnemy) {
			self.x += (self.x < nearbyEnemy.x ? -1 : 1) * self.speed; // Move away from the nearby enemy
		} else {
			self.y += self.speed * (Math.random() > 0.1 ? 1 : 0); // Brief pauses in downward movement
		}
		self.x += Math.sin(LK.ticks / 10 + self.randomOffset) * 2; // Small jerky side-to-side movements
		if (Math.random() > 0.95) {
			self.x += Math.random() * 4 - 2; // Quick position corrections
		}
		// Pulse effect on hit
		if (self.pulseEffect) {
			droneGraphics.scale.x = 1.2;
			droneGraphics.scale.y = 1.2;
			self.pulseEffect = false;
		} else {
			droneGraphics.scale.x = 1.0;
			droneGraphics.scale.y = 1.0;
		}
		if (CollisionManager.checkCollision(self, hero)) {
			// Handle collision with hero
			if (hero.shielded) {
				hero.shieldLevel -= 1;
				if (hero.shieldLevel <= 0) {
					hero.shielded = false;
					if (hero.shieldGraphics) {
						hero.shieldGraphics.destroy();
						hero.shieldGraphics = null;
					}
				} else {
					hero.shieldGraphics.tint = 0xFFFFFF;
					if (hero.shieldLevel === 2) {
						hero.shieldGraphics.tint = 0xFFFF00;
					} else if (hero.shieldLevel === 1) {
						hero.shieldGraphics.tint = 0xFFFFFF;
					}
				}
				// Destroy the enemy
				generateEnemyPieces(self, DronePiece, ['DroneCenterPart', 'DroneLeftPart', 'DroneRightPart']);
				self.destroy();
				var index = enemies.indexOf(self);
				if (index > -1) {
					enemies.splice(index, 1);
				}
			} else {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
			}
		}
		if (self.HitPoints <= 0) {
			// Create drone pieces upon destruction
			generateEnemyPieces(self, DronePiece, ['DroneCenterPart', 'DroneLeftPart', 'DroneRightPart']);
			self.destroy();
			var index = enemies.indexOf(self);
			if (index > -1) {
				enemies.splice(index, 1);
			}
		} else if (self.y > 2732) {
			self.destroy();
			var index = enemies.indexOf(self);
			if (index > -1) {
				enemies.splice(index, 1);
				difficultyManager.onEnemyDestroyed();
			}
		}
	};
});
// DronePiece class for drone destruction effect
var DronePiece = Container.expand(function (assetType) {
	var self = Container.call(this);
	var pieceGraphics = self.attachAsset(assetType, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = Math.random() * 6 - 3; // Increased random horizontal speed
	self.speedY = Math.random() * 4 - 2; // Random vertical speed
	self.alphaDecay = 0.02; // Rate at which the piece fades out
	self.update = function () {
		self.x += self.speedX;
		self.y += self.speedY;
		pieceGraphics.rotation += Math.random() * 0.1 - 0.05; // Add slight random rotation
		pieceGraphics.alpha -= self.alphaDecay;
		if (pieceGraphics.alpha <= 0) {
			self.destroy();
		}
	};
});
// Dust class for dust particles
var Dust = Container.expand(function () {
	var self = Container.call(this);
	var dustGraphics = self.attachAsset('Dust', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	dustGraphics.alpha = 0.75;
	self.speed = Math.random() * 3 + 1;
	self.rotationSpeed = Math.random() * 0.02 - 0.01; // Random rotation speed between -0.01 and 0.01
	self.direction = Math.random() * Math.PI * 0.5;
	self.update = function () {
		self.y += self.speed;
		self.x += Math.sin(self.direction) * self.speed; // Add slight X travel based on direction
		self.rotation += self.rotationSpeed; // Add rotation
		dustGraphics.alpha -= 0.01; // fade out at a medium pace
		if (self.y > 2732 || dustGraphics.alpha <= 0) {
			self.destroy();
		}
	};
});
// Assets will be automatically created and loaded by the LK engine based on their usage in the code.
// Hero class representing the player's spaceship
var Hero = Container.expand(function () {
	var self = Container.call(this);
	self.prevX = self.x; // Initialize prevX with the current x position
	var heroGraphics = self.attachAsset('hero', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 10;
	self.soldierCloneCount = 0; // Initialize soldier clone count
	self.droneCount = 0; // Initialize drone count
	self.shielded = false; // Initialize shielded state
	self.shieldLevel = 0; // Initialize shield level
	self.shieldGraphics = null; // Placeholder for shield asset
	self.update = function () {
		if (self.shielded && self.shieldGraphics) {
			self.shieldGraphics.rotation += 0.01; // Rotate shield slowly
			// Adjust shield size to cover hero asset and increase by 10%
			var scaleFactor = Math.max(heroGraphics.width / self.shieldGraphics.width, heroGraphics.height / self.shieldGraphics.height) * 1.1;
			self.shieldGraphics.scale.x = scaleFactor;
			self.shieldGraphics.scale.y = scaleFactor;
			// Move shield graphics to the layer directly underneath hero
			self.addChildAt(self.shieldGraphics, 0);
			// Update shield tint based on shield level
			self.shieldGraphics.tint = 0xFF0000; // Red tint for level 1
			if (self.shieldLevel === 2) {
				self.shieldGraphics.tint = 0xFFFF00; // Yellow tint for level 2
			} else if (self.shieldLevel === 3) {
				self.shieldGraphics.tint = 0x00FF00; // Green tint for level 3
			}
		}
		if (self.y > 2375) {
			self.y -= self.speed;
		}
		// Add rotation based on movement direction
		if (self.x > self.prevX) {
			self.rotation += Math.PI / 180 * 1; // Rotate 1 degree to the right
			if (self.rotation > Math.PI / 180 * 5) {
				self.rotation = Math.PI / 180 * 5;
			}
		} else if (self.x < self.prevX) {
			self.rotation -= Math.PI / 180 * 1; // Rotate 1 degree to the left
			if (self.rotation < Math.PI / 180 * -5) {
				self.rotation = Math.PI / 180 * -5;
			}
		} else {
			if (self.rotation > 0) {
				self.rotation -= Math.PI / 180 * 1;
				if (self.rotation < 0) {
					self.rotation = 0;
				}
			} else if (self.rotation < 0) {
				self.rotation += Math.PI / 180 * 1;
				if (self.rotation > 0) {
					self.rotation = 0;
				}
			}
		}
		self.prevX = self.x; // Store the current x position for the next frame
		// Removed pulsing scale effect for hero
		self.scale.x = 1.0;
	};
	// Method to handle shooting
	self.shootBehavior = powerUpManager.defaultBehavior; // Set initial behavior
	// Method to handle shooting
	self.shoot = function () {
		self.shootBehavior.call(self);
	};
});
// Bullet class for hero's bullets
var HeroBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('heroBullet1', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -15;
	self.Type = 'standard'; // Default type for bullets
	self.Power = powerUpManager.currentPowerLevel || 1; // Initialize power level from PowerUpManager
	self.update = function () {
		// Move in direction of rotation
		self.y += Math.cos(self.rotation) * self.speed;
		self.x += Math.sin(self.rotation) * self.speed;
		// Adjust out-of-bounds check for angled movement
		if (self.y < 0 || self.x < 0 || self.x > 2048) {
			self.destroy();
			var index = heroBullets.indexOf(self);
			if (index > -1) {
				heroBullets.splice(index, 1);
			}
		}
	};
	self.updateVisual = function () {
		if (bulletGraphics) {
			self.removeChild(bulletGraphics);
		}
		var assetId = 'heroBullet' + Math.min(self.Power, 3);
		console.log("Loading bullet asset: " + assetId);
		bulletGraphics = self.attachAsset(assetId, {
			anchorX: 0.5,
			anchorY: 0.5
		});
	};
});
var LaserBeamSegment = Container.expand(function () {
	var self = Container.call(this);
	// Attach laser segment graphic
	var laserGraphics = self.attachAsset('LaserBeam', {
		anchorX: 0.5,
		anchorY: 0,
		scaleX: 1,
		scaleY: 1 // Each segment stays at normal scale
	});
	// Handle own collision
	self.update = function () {
		if (CollisionManager.checkCollision(self, hero)) {
			if (hero.shielded) {
				hero.shieldLevel -= 1;
				if (hero.shieldLevel <= 0) {
					hero.shielded = false;
					if (hero.shieldGraphics) {
						hero.shieldGraphics.destroy();
						hero.shieldGraphics = null;
					}
				}
			} else {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
			}
		}
		// Check clone collisions
		for (var i = soldierClones.length - 1; i >= 0; i--) {
			var clone = soldierClones[i];
			if (CollisionManager.checkCollision(self, clone)) {
				clone.destroy();
				break;
			}
		}
	};
	return self;
});
var PlayerDrone = Container.expand(function () {
	var self = Container.call(this);
	var droneGraphics = self.attachAsset('PlayerDrone', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.9,
		scaleX: 0.75,
		scaleY: 0.75
	});
	self.angle = 0; // Orbital angle
	self.orbitRadius = 200; // Further increased distance from hero
	self.orbitSpeed = 0.03; // Increased speed of rotation
	self.health = 1;
	self.lastCollisionFrame = 0;
	self.update = function () {
		// Orbit around hero
		self.angle += self.orbitSpeed;
		self.x = hero.x + Math.cos(self.angle) * self.orbitRadius;
		self.y = hero.y + Math.sin(self.angle) * self.orbitRadius;
		// Check collisions
		if (LK.ticks > self.lastCollisionFrame) {
			for (var i = 0; i < enemies.length; i++) {
				if (CollisionManager.checkCollision(self, enemies[i])) {
					self.lastCollisionFrame = LK.ticks;
					self.destroy();
					return;
				}
			}
		}
		// Auto-fire
		if (LK.ticks % 18 == 0) {
			self.shoot();
		}
	};
	self.shoot = function () {
		var bullet = new HeroBullet();
		bullet.x = self.x;
		bullet.y = self.y;
		bullet.Power = 1; // Always power level 1
		bullet.updateVisual();
		heroBullets.push(bullet);
		game.addChild(bullet);
	};
});
// PowerUp class for handling power-up movement and collection
var PowerUp = Container.expand(function (assetType, spawnSide) {
	var self = Container.call(this);
	var powerUpGraphics = self.attachAsset(assetType, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 5; // Increased speed at which the power-up moves down the screen
	self.movementPhase = 'ENTRY';
	self.spawnSide = spawnSide; // Pass this in constructor
	self.update = function () {
		if (self.movementPhase === 'ENTRY') {
			self.x += self.spawnSide === 'LEFT' ? self.speed : -self.speed;
			if (Math.abs(self.x - 1024) < 5) {
				// Check if near center
				self.movementPhase = 'DESCENT';
				self.x = 1024; // Snap to center
			}
		} else {
			self.y += self.speed;
		}
		// Check if the power-up is collected by the hero
		if (self.intersects(hero)) {
			switch (assetType) {
				case 'SoldierCloneIcon':
					if (soldierClones.length < 4) {
						hero.soldierCloneCount++;
						var newClone = new SoldierClone();
						// Spawn directly in combat position ahead of hero
						newClone.x = 1024; // Center of screen
						newClone.y = hero.y - 200; // Fixed distance ahead
						newClone.zIndex = hero.zIndex - 1;
						// Add TV turn-on effect
						var tvEffect = new TVTurnOnEffect();
						tvEffect.soldierClone = newClone; // Reference to the soldier clone
						tvEffect.x = newClone.x;
						tvEffect.y = newClone.y;
						backgroundContainer.addChild(tvEffect);
						// Add soldier clone to the game after TV effect completes
						LK.setTimeout(function () {
							soldierClones.push(newClone);
							game.addChild(newClone);
						}, tvEffect.animationDuration * 16.67); // Convert frames to milliseconds
						// Add TV turn-on effect
						var tvEffect = new TVTurnOnEffect();
						tvEffect.soldierClone = newClone; // Reference to the soldier clone
						tvEffect.x = newClone.x;
						tvEffect.y = newClone.y;
						backgroundContainer.addChild(tvEffect);
					}
					break;
				case 'PlayerDroneIcon':
					if (hero.droneCount < 3) {
						// Maximum 3 drones
						hero.droneCount = hero.droneCount || 0;
						hero.droneCount++;
						var newDrone = new PlayerDrone();
						// Set initial angle based on drone count
						newDrone.angle = (hero.droneCount - 1) * (Math.PI * 2 / 3);
						playerDrones.push(newDrone);
						backgroundContainer.addChild(newDrone);
					}
					break;
				case 'WeaponPowerIcon':
					powerUpManager.currentPowerLevel = Math.min(powerUpManager.currentPowerLevel + 1, 4);
					console.log("Power up collected. New level: " + powerUpManager.currentPowerLevel);
					break;
				case 'ShieldIcon':
					if (!hero.shielded) {
						hero.shielded = true;
						hero.shieldGraphics = hero.attachAsset('heroShield', {
							anchorX: 0.5,
							anchorY: 0.5,
							alpha: 0.5 // Set opacity to 50%
						});
					}
					hero.shieldLevel = Math.min(hero.shieldLevel + 1, 3); // Increase shield level to a max of 3
					// Change shield tint based on shield level
					hero.shieldGraphics.tint = 0xFF0000; // Red tint for level 1
					if (hero.shieldLevel === 2) {
						hero.shieldGraphics.tint = 0xFFFF00; // Yellow tint for level 2
					} else if (hero.shieldLevel === 3) {
						hero.shieldGraphics.tint = 0x00FF00; // Green tint for level 3
					}
					break;
				case 'BombIcon':
					powerUpManager.switchPowerUp(PowerUpTypes.BOMB);
					powerUpManager.bombBehavior();
					break;
			}
			hero.shootBehavior = powerUpManager.getCurrentPowerBehavior();
			soldierClones.forEach(function (clone) {
				clone.shootBehavior = hero.shootBehavior;
			});
			self.destroy();
		}
		// Destroy if out of screen
		if (self.y > 2732) {
			self.destroy();
		}
	};
});
var PowerUpSpawner = Container.expand(function () {
	var self = Container.call(this);
	var timeSinceStart = 0;
	var timeSinceLastSpawn = 0;
	var spawnSide = 'LEFT';
	self.update = function () {
		timeSinceStart += 1;
		timeSinceLastSpawn += 1;
		// First spawn at 10 seconds (assuming 60 FPS)
		if (timeSinceStart === 600) {
			self.spawnPowerUp(self.getRandomPowerUp());
		}
		// Subsequent spawns every 30 seconds
		else if (timeSinceLastSpawn >= 1800) {
			self.spawnPowerUp(self.getRandomPowerUp());
			timeSinceLastSpawn = 0;
		}
	};
	self.getRandomPowerUp = function () {
		var powerUps = ['SoldierCloneIcon', 'WeaponPowerIcon', 'ShieldIcon', 'PlayerDroneIcon'];
		if (hero.shieldLevel === 3) {
			powerUps = powerUps.filter(function (powerUp) {
				return powerUp !== 'ShieldIcon';
			});
		}
		if (powerUpManager.currentPowerLevel === 3) {
			powerUps = powerUps.filter(function (powerUp) {
				return powerUp !== 'WeaponPowerIcon';
			});
		}
		if (difficultyManager.currentDifficulty > 4) {
			powerUps.push('BombIcon');
		}
		return powerUps[Math.floor(Math.random() * powerUps.length)];
	};
	self.spawnPowerUp = function (assetType) {
		var currentSpawnSide = spawnSide; // Get current value before toggling
		var powerUp = new PowerUp(assetType, currentSpawnSide);
		powerUp.x = currentSpawnSide === 'LEFT' ? 0 : 2048;
		powerUp.y = 200; // Spawn above screen but not too high
		backgroundContainer.addChild(powerUp);
		spawnSide = currentSpawnSide === 'LEFT' ? 'RIGHT' : 'LEFT'; // Toggle for next spawn
	};
});
var Raider = Container.expand(function () {
	var self = Container.call(this);
	var raiderGraphics = self.attachAsset('BotBiker', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Raider specific properties
	self.HitPoints = 5;
	self.speed = 3;
	self.shootInterval = 66; // Reduced firing frequency by 10%
	self.lastShotTime = 0;
	self.trackingDelay = 30; // Delay before adjusting aim
	self.trackingTime = 0; // Time since last tracking adjustment
	self.targetRotation = raiderGraphics.rotation; // Target rotation for tracking
	self.entryPhase = true; // Track if we're still in entry animation
	self.speed = 3;
	self.rotationSpeed = 0.05;
	self.horizontalSpeed = 6; // Faster horizontal movement during entry
	// Add scaling properties
	self.maxTilt = 0.3; // How much to scale for tilt effect
	self.baseScale = 1; // Normal scale
	self.spawnSide = Math.random() < 0.5 ? 'left' : 'right';
	// Set initial rotation based on spawn side
	raiderGraphics.rotation = self.spawnSide === 'left' ? -Math.PI / 4 : Math.PI / 4;
	self.update = function () {
		if (self.entryPhase) {
			// Entry movement
			if (self.spawnSide === 'left') {
				self.x += self.horizontalSpeed;
				raiderGraphics.rotation = Math.min(raiderGraphics.rotation + self.rotationSpeed, 0);
				// Scale for tilt effect
				raiderGraphics.scale.x = self.baseScale - self.maxTilt;
				if (self.x >= 600) {
					// Move further onto road
					self.entryPhase = false;
					raiderGraphics.scale.x = self.baseScale;
				}
			} else {
				self.x -= self.horizontalSpeed;
				raiderGraphics.rotation = Math.max(raiderGraphics.rotation - self.rotationSpeed, 0);
				// Scale for tilt effect
				raiderGraphics.scale.x = self.baseScale - self.maxTilt;
				if (self.x <= 1448) {
					// 2048 - 600
					self.entryPhase = false;
					raiderGraphics.scale.x = self.baseScale;
				}
			}
		} else {
			self.y += self.speed * 0.25; // Reduce speed by 75% after entry
			// Move back and forth across the road
			if (self.spawnSide === 'left') {
				self.x += self.horizontalSpeed;
				if (self.x >= 1448) {
					// Right boundary
					self.spawnSide = 'right';
				}
			} else {
				self.x -= self.horizontalSpeed;
				if (self.x <= 600) {
					// Left boundary
					self.spawnSide = 'left';
				}
			}
			// Tracking logic
			if (self.trackingTime >= self.trackingDelay) {
				var directionX = hero.x - self.x;
				var directionY = hero.y - self.y;
				self.targetRotation = Math.atan2(directionY, directionX) - Math.PI / 2;
				self.trackingTime = 0;
			} else {
				self.trackingTime++;
			}
			// Swivel towards target rotation
			raiderGraphics.rotation += (self.targetRotation - raiderGraphics.rotation) * 0.1;
			// Shooting logic
			if (LK.ticks - self.lastShotTime > self.shootInterval) {
				self.shoot();
				self.lastShotTime = LK.ticks;
			}
		}
		// Keep collision handling
		if (CollisionManager.checkCollision(self, hero)) {
			// [Keep existing collision code]
		}
		// Keep destruction logic
		if (self.HitPoints <= 0) {
			// Create raider pieces upon destruction
			generateEnemyPieces(self, RaiderPiece, ['RaiderTop', 'RaiderBottom']);
			difficultyManager.onEnemyDestroyed();
		} else if (self.y > 2732) {
			// [Keep existing out-of-bounds code]
			difficultyManager.onEnemyDestroyed();
		}
	};
	self.shoot = function () {
		if (self.spawnSide === 'left') {
			var bullet = new RaiderBullet();
			bullet.x = self.x;
			bullet.y = self.y + raiderGraphics.height / 2;
			bullet.rotation = raiderGraphics.rotation;
			game.addChild(bullet);
			self.spawnSide = self.spawnSide === 'left' ? 'right' : 'left'; // Alternate sides
		} else {
			var rightShot = new RaiderBullet();
			rightShot.x = self.x + raiderGraphics.width / 4;
			rightShot.y = self.y + raiderGraphics.height / 2;
			game.addChild(rightShot);
			self.spawnSide = 'left'; // Switch to left for next shot
		}
	};
});
var RaiderBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('heroBullet1', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -15 * 0.75; // 75% of hero bullet speed
	self.update = function () {
		self.y -= Math.cos(self.rotation) * self.speed;
		self.x += Math.sin(self.rotation) * self.speed;
		// Check collision with hero
		if (CollisionManager.checkCollision(self, hero)) {
			if (hero.shielded) {
				hero.shieldLevel -= 1;
				if (hero.shieldLevel <= 0) {
					hero.shielded = false;
					if (hero.shieldGraphics) {
						hero.shieldGraphics.destroy();
						hero.shieldGraphics = null;
					}
				} else {
					hero.shieldGraphics.tint = 0xFFFFFF;
					if (hero.shieldLevel === 2) {
						hero.shieldGraphics.tint = 0xFFFF00;
					} else if (hero.shieldLevel === 1) {
						hero.shieldGraphics.tint = 0xFFFFFF;
					}
				}
			} else {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
			}
			self.destroy();
			return;
		}
		// Check collision with soldier clones
		for (var i = soldierClones.length - 1; i >= 0; i--) {
			var clone = soldierClones[i];
			if (CollisionManager.checkCollision(self, clone)) {
				clone.destroy();
				hero.soldierCloneCount--; // Decrease hero clone count
				self.destroy();
				break;
			}
		}
		if (self.y > 2732) {
			self.destroy();
		}
	};
});
// RaiderPiece class for raider destruction effect
var RaiderPiece = Container.expand(function (assetType) {
	var self = Container.call(this);
	var pieceGraphics = self.attachAsset(assetType, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = (Math.random() - 0.5) * 10; // Random horizontal speed
	self.speedY = (Math.random() - 0.5) * 10; // Random vertical speed
	self.alphaDecay = 0.02; // Rate at which the piece fades out
	self.update = function () {
		self.x += self.speedX;
		self.y += self.speedY;
		pieceGraphics.rotation += Math.random() * 0.1 - 0.05; // Add slight random rotation
		pieceGraphics.alpha -= self.alphaDecay;
		if (pieceGraphics.alpha <= 0) {
			self.destroy();
		}
	};
});
// RailingLeft class for the scrolling left railing
var RailingLeft = Container.expand(function (assetType) {
	var self = Container.call(this);
	var railingGraphics = self.attachAsset(assetType, {
		anchorX: 0.5,
		anchorY: 0
	});
	self.speed = 2;
	self.update = function () {
		self.y += self.speed;
		if (self.y >= 2732) {
			self.y = -2732;
		}
	};
});
// RailingRight class for the scrolling right railing
var RailingRight = Container.expand(function (assetType) {
	var self = Container.call(this);
	var railingGraphics = self.attachAsset(assetType, {
		anchorX: 0.5,
		anchorY: 0
	});
	self.speed = 2;
	self.update = function () {
		self.y += self.speed;
		if (self.y >= 2732) {
			self.y = -2732;
		}
	};
});
var RedDrone = Container.expand(function () {
	var self = Container.call(this);
	var droneGraphics = self.attachAsset('Drone', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Apply red tint to graphics
	droneGraphics.tint = 0xFF0000;
	// Set aggressive properties
	self.HitPoints = 4;
	self.randomOffset = Math.random() * 100;
	self.speed = 4; // Faster than regular drone
	self.update = function () {
		if (hero) {
			// Chase the hero
			if (self.x < hero.x) {
				self.x += self.speed;
			} else if (self.x > hero.x) {
				self.x -= self.speed;
			}
			self.y += self.speed;
		}
		// Keep pulse effect from base drone
		if (self.pulseEffect) {
			droneGraphics.scale.x = 1.2;
			droneGraphics.scale.y = 1.2;
			self.pulseEffect = false;
		} else {
			droneGraphics.scale.x = 1.0;
			droneGraphics.scale.y = 1.0;
		}
		// Copy collision checks from base Drone
		if (CollisionManager.checkCollision(self, hero)) {
			if (hero.shielded) {
				hero.shieldLevel -= 1;
				if (hero.shieldLevel <= 0) {
					hero.shielded = false;
					if (hero.shieldGraphics) {
						hero.shieldGraphics.destroy();
						hero.shieldGraphics = null;
					}
				} else {
					hero.shieldGraphics.tint = 0xFFFFFF;
					if (hero.shieldLevel === 2) {
						hero.shieldGraphics.tint = 0xFFFF00;
					} else if (hero.shieldLevel === 1) {
						hero.shieldGraphics.tint = 0xFFFFFF;
					}
				}
				generateEnemyPieces(self, DronePiece, ['DroneCenterPart', 'DroneLeftPart', 'DroneRightPart']);
				self.destroy();
				var index = enemies.indexOf(self);
				if (index > -1) {
					enemies.splice(index, 1);
				}
			} else {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
			}
		}
		if (self.HitPoints <= 0) {
			generateEnemyPieces(self, DronePiece, ['DroneCenterPart', 'DroneLeftPart', 'DroneRightPart']);
			self.destroy();
			var index = enemies.indexOf(self);
			if (index > -1) {
				enemies.splice(index, 1);
				difficultyManager.onEnemyDestroyed();
			}
		} else if (self.y > 2732) {
			self.destroy();
			var index = enemies.indexOf(self);
			if (index > -1) {
				enemies.splice(index, 1);
				difficultyManager.onEnemyDestroyed();
			}
		}
	};
});
// RoadScroll class for the scrolling road
var RoadScroll = Container.expand(function (assetType) {
	var self = Container.call(this);
	var roadGraphics = self.attachAsset(assetType, {
		anchorX: 0.5,
		anchorY: 0
	});
	if (assetType === 'CityBackgroundHD') {
		self.speed = 1;
	} else {
		self.speed = 2;
	}
	self.update = function () {
		self.y += self.speed;
		if (self.y >= 2732) {
			self.y = -2732;
		}
	};
});
// SoldierClone class representing a clone of the player's character
var SoldierClone = Container.expand(function () {
	var self = Container.call(this);
	// Removed self.side property
	var cloneGraphics = self.attachAsset('hero', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.7,
		scaleX: 0.75,
		scaleY: 0.75
	});
	self.roadLeft = 2048 * 0.21;
	self.roadRight = 2048 * 0.76;
	self.moveSpeed = 4.5;
	self.health = 1;
	self.isImmune = false;
	self.dodgeSpeed = 5;
	self.dodgeCooldown = 0;
	self.forwardOffset = 150 + Math.random() * 50; // Variable distance ahead
	self.horizontalPhase = Math.random() * Math.PI * 2; // Different horizontal movement phase
	// Removed self.offset property
	self.update = function () {
		// Maintain forward position
		self.y = hero.y - 200;
		// Handle dodge cooldown
		if (self.dodgeCooldown > 0) {
			self.dodgeCooldown--;
		}
		// Check for bullets to dodge
		var needsToDodge = false;
		// Check for bullets to dodge
		if (self.dodgeCooldown <= 0) {
			enemies.forEach(function (enemy) {
				if (enemy instanceof RaiderBullet) {
					// Create a projected position of where bullet will be
					var projectedY = enemy.y + (enemy.speed || 0) * 10; // Look 10 frames ahead
					var projectedBullet = {
						x: enemy.x,
						y: projectedY,
						width: enemy.width,
						height: enemy.height
					};
					if (CollisionManager.checkCollision(self, projectedBullet)) {
						needsToDodge = true;
						// Dodge in opposite direction of bullet's X position relative to clone
						var dodgeDirection = enemy.x > self.x ? -1 : 1;
						var newX = self.x + self.dodgeSpeed * dodgeDirection;
						// Stay within road
						if (newX > self.roadLeft && newX < self.roadRight) {
							self.x = newX;
						}
						self.dodgeCooldown = 30;
					}
				}
			});
		}
		// Only target enemies if not dodging
		// In the movement code
		if (!needsToDodge) {
			var nearestEnemy = null;
			var nearestDist = Infinity;
			enemies.forEach(function (enemy) {
				if (enemy.y > self.y) {
					return;
				}
				var dist = Math.sqrt(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2));
				if (dist < nearestDist) {
					nearestDist = dist;
					nearestEnemy = enemy;
				}
			});
			// If no target, maintain forward position with slight variation
			if (!nearestEnemy) {
				var horizontalWobble = Math.sin(LK.ticks * 0.03 + self.horizontalPhase) * 25;
				var targetX = Math.min(Math.max(hero.x + horizontalWobble, self.roadLeft), self.roadRight);
				var targetY = hero.y - self.forwardOffset;
				// Smooth movement towards target
				self.x += (targetX - self.x) * 0.1;
				self.y += (targetY - self.y) * 0.1;
			} else {
				// When targeting enemy, maintain some spacing between clones
				var targetX = nearestEnemy.x + Math.sin(LK.ticks * 0.03 + self.horizontalPhase) * 20;
				targetX = Math.min(Math.max(targetX, self.roadLeft), self.roadRight);
				self.x += (targetX - self.x) * 0.1;
			}
		}
		// Check collisions once per frame
		if (!self.isImmune && LK.ticks > self.lastCollisionFrame) {
			for (var i = 0; i < enemies.length; i++) {
				if (CollisionManager.checkCollision(self, enemies[i])) {
					self.lastCollisionFrame = LK.ticks;
					self.destroy();
					return;
				}
			}
		}
		self.shoot();
	};
	self.destroy = function () {
		// Remove bullets associated with this clone
		for (var i = heroBullets.length - 1; i >= 0; i--) {
			if (heroBullets[i].x === self.x && heroBullets[i].y === self.y - self.height / 2) {
				heroBullets[i].destroy();
				heroBullets.splice(i, 1);
			}
		}
		// Removed side-based immunity code
		// Update soldier clone count and array
		var index = soldierClones.indexOf(self);
		if (index > -1) {
			soldierClones.splice(index, 1);
			hero.soldierCloneCount--;
		}
		// Call original destroy method
		Container.prototype.destroy.call(self);
	};
	// Method to handle shooting
	self.shoot = function () {
		if (LK.ticks % 18 == 0) {
			// Match hero's fire rate
			var newBullet = new HeroBullet(); // Use the same bullet type as the hero
			newBullet.x = self.x; // Create bullets at the clone's current position
			newBullet.y = self.y - self.height / 2;
			newBullet.Power = heroBullets.length > 0 ? heroBullets[0].Power : 1; // Match hero's bullet power
			newBullet.updateVisual(); // Update bullet visuals based on power
			heroBullets.push(newBullet); // Add the new bullets to the game's bullet array
			game.addChild(newBullet);
		}
	};
});
var TVTurnOnEffect = Container.expand(function () {
	var self = Container.call(this);
	// Attach white pixel asset for scanline effect
	var scanlineGraphics = self.attachAsset('whitePixel', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.01,
		// Start as a dot
		scaleY: 0.01 // Start as a dot
	});
	// Animation properties
	self.animationDuration = 60; // Duration in frames
	self.startTime = LK.ticks;
	// Update function for animation
	self.update = function () {
		var progress = (LK.ticks - self.startTime) / self.animationDuration;
		if (progress <= 1) {
			if (self.soldierClone) {
				self.soldierClone.x = self.x;
				self.soldierClone.y = self.y;
			}
			if (progress <= 0.5) {
				// Stretch from a dot to a horizontal line
				scanlineGraphics.scaleX = 0.01 + progress * 3.98; // Expand to twice the width of the soldier clone
				scanlineGraphics.scaleY = 0.01; // Keep as a line
			} else {
				// Compress to half its width and expand soldier clone
				scanlineGraphics.scaleX = 2.0 - (progress - 0.5) * 2.0; // Compress to half width
				if (self.soldierClone) {
					self.soldierClone.scaleY = 0.01 + (progress - 0.5) * 1.98; // Stretch soldier clone vertically
				}
			}
			// Add scanline effect by adjusting alpha
			scanlineGraphics.alpha = 0.5 + Math.sin(progress * Math.PI * 10) * 0.5;
		} else {
			// Destroy effect after animation completes
			if (self.soldierClone) {
				self.soldierClone.scaleY = 1.0; // Ensure soldier clone is at full size
			}
			self.destroy();
		}
	};
	return self;
});
// TitleScreen class for the title screen
var TitleScreen = Container.expand(function () {
	var self = Container.call(this);
	// Attach game logo
	var logo = self.attachAsset('GameLogoHD', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	logo.x = 2048 / 2;
	logo.y = 2732 / 2 - 200;
	// Attach play button
	var playButton = self.attachAsset('PlayButton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	playButton.x = 2048 / 2;
	playButton.y = logo.y + logo.height / 2 + playButton.height / 2 + 50;
	// Event handler for play button
	playButton.down = function (x, y, obj) {
		isTitle = false;
		isStarted = true;
		self.destroy();
		startGame();
	};
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000 //Init game with black background
});
/**** 
* Game Code
****/ 
var playerDrones = [];
function _typeof(o) {
	"@babel/helpers - typeof";
	return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
		return typeof o;
	} : function (o) {
		return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
	}, _typeof(o);
}
function ownKeys(e, r) {
	var t = Object.keys(e);
	if (Object.getOwnPropertySymbols) {
		var o = Object.getOwnPropertySymbols(e);
		r && (o = o.filter(function (r) {
			return Object.getOwnPropertyDescriptor(e, r).enumerable;
		})), t.push.apply(t, o);
	}
	return t;
}
function _objectSpread(e) {
	for (var r = 1; r < arguments.length; r++) {
		var t = null != arguments[r] ? arguments[r] : {};
		r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
			_defineProperty(e, r, t[r]);
		}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
			Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
		});
	}
	return e;
}
function _defineProperty(e, r, t) {
	return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
		value: t,
		enumerable: !0,
		configurable: !0,
		writable: !0
	}) : e[r] = t, e;
}
function _toPropertyKey(t) {
	var i = _toPrimitive(t, "string");
	return "symbol" == _typeof(i) ? i : i + "";
}
function _toPrimitive(t, r) {
	if ("object" != _typeof(t) || !t) {
		return t;
	}
	var e = t[Symbol.toPrimitive];
	if (void 0 !== e) {
		var i = e.call(t, r || "default");
		if ("object" != _typeof(i)) {
			return i;
		}
		throw new TypeError("@@toPrimitive must return a primitive value.");
	}
	return ("string" === r ? String : Number)(t);
}
function generateEnemyPieces(enemy, pieceClass, pieceTypes) {
	pieceTypes.forEach(function (pieceType, index) {
		var piece = new pieceClass(pieceType);
		piece.x = enemy.x + (index - 1) * 40; // Spread pieces horizontally
		piece.y = enemy.y;
		game.addChild(piece);
	});
}
var CollisionManager = {
	checkCollision: function checkCollision(obj1, obj2) {
		// Special case for laser beam
		if (obj1.constructor.name === 'LaserBeam' || obj1 === 'LaserBeam') {
			// Line segment collision
			var laser = activeLaserBeams.find(function (l) {
				return l.laserBeam === obj1;
			});
			if (!laser) {
				return false;
			}
			// Get laser start and end points
			var laserLength = obj1.height * obj1.scaleY;
			var startX = obj1.x;
			var startY = obj1.y;
			var endX = startX - Math.sin(obj1.rotation) * laserLength;
			var endY = startY + Math.cos(obj1.rotation) * laserLength;
			// Get target radius for collision
			var targetRadius = Math.min(obj2.width, obj2.height) * 0.4;
			// Check if point-to-line distance is less than target radius
			var dx = endX - startX;
			var dy = endY - startY;
			var len = Math.sqrt(dx * dx + dy * dy);
			// Get point to line segment distance
			var t = ((obj2.x - startX) * dx + (obj2.y - startY) * dy) / (len * len);
			t = Math.max(0, Math.min(1, t));
			var nearestX = startX + t * dx;
			var nearestY = startY + t * dy;
			// Check distance from nearest point
			var distance = Math.sqrt((obj2.x - nearestX) * (obj2.x - nearestX) + (obj2.y - nearestY) * (obj2.y - nearestY));
			return distance < targetRadius;
		}
		return this.circleCollision(obj1, obj2);
	},
	getObjectRadius: function getObjectRadius(obj) {
		var width = obj.width;
		var height = obj.height;
		return Math.min(width, height) * 0.4;
	},
	circleCollision: function circleCollision(obj1, obj2) {
		var radius1 = this.getObjectRadius(obj1);
		var radius2 = this.getObjectRadius(obj2);
		var dx = obj1.x - obj2.x;
		var dy = obj1.y - obj2.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		return distance < radius1 + radius2;
	}
};
var PowerUpTypes = {
	DEFAULT: 'DEFAULT',
	SOLDIER_CLONE: 'SOLDIER_CLONE',
	SHIELD: 'SHIELD',
	WEAPON_POWER: 'WEAPON_POWER',
	BOMB: 'BOMB',
	// Add bomb type
	PLAYER_DRONE: 'PLAYER_DRONE' // Add player drone type
};
// PowerUpManager class to manage power-ups
// Initialize the city background for parallax effect
var PowerUpManager = function PowerUpManager() {
	this.currentPowerUp = PowerUpTypes.DEFAULT;
	this.currentPowerLevel = 1; // Initialize power level to default value
	this.switchPowerUp = function (newPowerUp) {
		if (PowerUpTypes[newPowerUp]) {
			this.currentPowerUp = newPowerUp;
		}
	};
	this.getCurrentPowerBehavior = function () {
		switch (this.currentPowerUp) {
			case PowerUpTypes.SOLDIER_CLONE:
				return this.soldierCloneBehavior;
			case PowerUpTypes.BOMB:
				return this.bombBehavior;
			default:
				return this.defaultBehavior;
		}
	};
	this.defaultBehavior = function () {
		var bullet = new HeroBullet();
		bullet.x = hero.x;
		bullet.y = hero.y - hero.height / 2;
		bullet.Power = powerUpManager.currentPowerLevel || 1; // Use saved power level from PowerUpManager
		bullet.updateVisual(); // Update the visual after setting power
		heroBullets.push(bullet);
		game.addChild(bullet);
		console.log("Created bullet with power: " + bullet.Power);
	};
	this.soldierCloneBehavior = function () {
		// Soldier clone behavior
		// Removed clone spawning logic
	};
	this.bombBehavior = function () {
		var blast = new BombBlast();
		blast.x = 1024;
		blast.y = 1366;
		blast.zIndex = 2000; // Ensure BombBlast is on a visible layer
		game.addChild(blast);
		// Kill enemies
		for (var i = enemies.length - 1; i >= 0; i--) {
			if (enemies[i] && enemies[i].y > 0) {
				enemies[i].HitPoints = 0;
				// Generate pieces based on enemy type
				if (enemies[i] instanceof Drone || enemies[i] instanceof RedDrone) {
					generateEnemyPieces(enemies[i], DronePiece, ['DroneCenterPart', 'DroneLeftPart', 'DroneRightPart']);
				} else if (enemies[i] instanceof Bruiser) {
					generateEnemyPieces(enemies[i], BruiserPiece, ['BruiserCenterPart', 'BruiserLeftPart', 'BruiserRightPart']);
				} else if (enemies[i] instanceof Blaster) {
					generateEnemyPieces(enemies[i], BlasterPiece, ['BlasterBottomPiece', 'BlasterLeftPiece', 'BlasterRightPiece']);
				} else if (enemies[i] instanceof Raider) {
					generateEnemyPieces(enemies[i], RaiderPiece, ['RaiderTop', 'RaiderBottom']);
				}
				enemies[i].destroy();
				enemies.splice(i, 1);
				difficultyManager.onEnemyDestroyed();
			}
		}
		// Flash effect after blast is created
		LK.setTimeout(function () {
			var flash = new Container();
			var flashGraphics = flash.attachAsset('whitePixel', {
				anchorX: 0.5,
				anchorY: 0.5,
				scaleX: 20,
				scaleY: 30
			});
			flash.x = game.width / 2;
			flash.y = game.height / 2;
			flash.alpha = 0.8;
			game.addChild(flash);
			LK.setTimeout(function () {
				flash.destroy();
			}, 100);
		}, 100);
		// Screen shake
		var originalX = game.x;
		var shakeAmount = 30; // Increase shake intensity
		var shakeDuration = 100; // Increase shake duration
		game.x += shakeAmount;
		LK.setTimeout(function () {
			game.x -= shakeAmount * 2;
			LK.setTimeout(function () {
				game.x += shakeAmount;
				LK.setTimeout(function () {
					game.x -= shakeAmount * 2;
					LK.setTimeout(function () {
						game.x += shakeAmount;
						LK.setTimeout(function () {
							game.x = originalX;
						}, shakeDuration);
					}, shakeDuration);
				}, shakeDuration);
			}, shakeDuration);
		}, shakeDuration);
	};
};
// PowerUpTypes enum/constants
var PowerUpTypes = {
	DEFAULT: 'DEFAULT',
	LASER_BEAM: 'LASER_BEAM',
	ROCKETS: 'ROCKETS',
	DRONE: 'DRONE',
	SOLDIER_CLONE: 'SOLDIER_CLONE',
	SHIELD: 'SHIELD',
	// Add shield power-up type
	WEAPON_POWER: 'WEAPON_POWER'
};
var LaserMechanic = function LaserMechanic(origin, chargeDuration, fireDuration, slideOffDuration) {
	this.origin = origin;
	this.chargeDuration = chargeDuration;
	this.fireDuration = fireDuration;
	this.slideOffDuration = slideOffDuration;
	// State tracking
	this.isCharging = false;
	this.isFiring = false;
	this.isSliding = false;
	// Timing
	this.chargeStartTime = null;
	this.fireStartTime = null;
	this.slideStartTime = null;
	// Flag to indicate attack completion
	this.attackComplete = false;
	// Assets
	this.chargeEffect = null;
	this.laserBeam = null;
	var index = activeLaserBeams.indexOf(this);
	if (index > -1) {
		activeLaserBeams.splice(index, 1);
	}
	// Method to start charging
	LaserMechanic.prototype.startCharge = function () {
		if (this.isCharging || this.isFiring || this.isSliding) {
			return;
		}
		this.isCharging = true;
		this.chargeStartTime = LK.ticks;
		// Create charge effect
		this.chargeEffect = LK.getAsset('LaserCharge', {
			anchorX: 0.5,
			anchorY: 0.5,
			alpha: 0.5,
			scale: {
				x: 0.5,
				y: 0.5
			}
		});
		if (this.origin) {
			this.chargeEffect.y += this.origin.height * 0.1; // Move charge effect down by 10% of origin's height
			this.origin.addChild(this.chargeEffect);
		}
	};
	// Target
	this.targetX = null;
	this.targetY = null;
	// Method to update charge progress
	LaserMechanic.prototype.updateCharge = function () {
		if (!this.isCharging) {
			return;
		}
		var chargeProgress = (LK.ticks - this.chargeStartTime) / this.chargeDuration;
		// Update charge effect
		this.chargeEffect.alpha = 0.5 + chargeProgress * 0.5; // Fade in
		this.chargeEffect.scale.x = 0.5 + chargeProgress * 1.5; // Grow outward
		this.chargeEffect.scale.y = 0.5 + chargeProgress * 1.5;
		// Capture target position at 2/3 through charge
		if (chargeProgress >= 0.67 && !this.targetX) {
			this.targetX = hero.x;
			this.targetY = hero.y;
		}
		// Check if charge is complete
		if (chargeProgress >= 1) {
			if (this.origin && this.chargeEffect) {
				this.origin.removeChild(this.chargeEffect);
			}
			this.chargeEffect = null;
			this.isCharging = false;
			this.startFiring(); // Add this line to transition to firing phase
		}
	};
};
var cityBackground1 = game.addChild(new RoadScroll('CityBackgroundHD'));
var cityBackground2 = game.addChild(new RoadScroll('CityBackgroundHD'));
cityBackground1.x = 2048 / 2;
cityBackground2.x = 2048 / 2;
cityBackground1.y = 0;
cityBackground2.y = -2732;
// Initialize the road instances
var road1 = game.addChild(new RoadScroll('Road'));
var road2 = game.addChild(new RoadScroll('Road2'));
road2.x = 2048 / 2;
road1.x = 2048 / 2;
road1.y = 0;
road2.y = -2732;
// Initialize the left railing instances
var railingLeft1 = game.addChild(new RailingLeft('RailingStart'));
var railingLeft2 = game.addChild(new RailingLeft('RailingEnd'));
railingLeft1.x = 2048 * 0.16;
railingLeft2.x = 2048 * 0.16;
railingLeft1.y = 0;
railingLeft2.y = -2732;
// Initialize the right railing instances
var railingRight1 = game.addChild(new RailingRight('RailingEnd'));
var railingRight2 = game.addChild(new RailingRight('RailingStart'));
railingRight1.x = 2048 * 0.81; // Moved left by 3%
railingRight2.x = 2048 * 0.81; // Moved left by 3%
railingRight1.y = 0;
railingRight2.y = -2732;
// Initialize game state variables
var isTitle = true;
var isStarted = false;
// Initialize title screen
if (isTitle) {
	var titleScreen = game.addChild(new TitleScreen());
}
// Initialize variables
var backgroundContainer;
var hero;
var enemies = [];
var heroBullets = [];
var soldierClones = [];
var powerUpManager = new PowerUpManager(); // Initialize powerUpManager
powerUpManager.currentPowerLevel = 1; // Track current power level at start
// Function to start the game
function startGame() {
	// Initialize background container
	backgroundContainer = new Container();
	game.addChild(backgroundContainer);
	difficultyManager = new DifficultyManager();
	difficultyManager.updateSpawnQuota();
	// Initialize hero
	hero = game.addChild(new Hero());
	// Initialize PowerUpSpawner
	var powerUpSpawner = new PowerUpSpawner();
	backgroundContainer.addChild(powerUpSpawner);
	hero.soldierCloneCount = soldierClones.length; // Set initial soldier clone count
	hero.x = 2048 / 2;
	hero.y = 2732 + hero.height;
	hero.shielded = true; // Start hero with shield
	hero.shieldLevel = 3; // Set shield level to 3
	hero.shieldGraphics = hero.attachAsset('heroShield', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5 // Set opacity to 50%
	});
	hero.shieldGraphics.tint = 0xFF0000; // Red tint for level 3 shield
	// Initialize enemies, bullets, and laser beams arrays
	enemies = [];
	heroBullets = [];
	activeLaserBeams = [];
	hero.shootBehavior = powerUpManager.getCurrentPowerBehavior().bind(hero);
}
// Function to handle game updates
game.update = function () {
	soldierClones.forEach(function (clone) {
		clone.shootBehavior = hero.shootBehavior;
	});
	cityBackground1.update();
	cityBackground2.update();
	// Update the road instances
	road1.update();
	road2.update();
	// Update the left railing instances
	railingLeft1.update();
	railingLeft2.update();
	// Update the right railing instances
	railingRight1.update();
	railingRight2.update();
	if (isStarted) {
		if (dragNode) {
			hero.x = dragNode.x;
			hero.y = dragNode.y;
		}
		// Update enemies
		if (!enemies) {
			return;
		} // Ensure enemies array is initialized
		for (var i = enemies.length - 1; i >= 0; i--) {
			if (enemies[i]) {
				enemies[i].update();
			}
			if (enemies[i] && CollisionManager.checkCollision(enemies[i], hero)) {
				if (hero.shielded) {
					hero.shieldLevel -= 1;
					if (hero.shieldLevel <= 0) {
						hero.shielded = false;
						if (hero.shieldGraphics) {
							hero.shieldGraphics.destroy();
							hero.shieldGraphics = null;
						}
					} else {
						// Update shield tint based on new shield level
						hero.shieldGraphics.tint = 0xFF0000; // Red tint for level 1
						if (hero.shieldLevel === 2) {
							hero.shieldGraphics.tint = 0xFFFF00; // Yellow tint for level 2
						} else if (hero.shieldLevel === 3) {
							hero.shieldGraphics.tint = 0x00FF00; // Green tint for level 3
						}
					}
					// Destroy enemy into pieces
					if (enemies[i] instanceof Drone) {
						generateEnemyPieces(enemies[i], DronePiece, ['DroneCenterPart', 'DroneLeftPart', 'DroneRightPart']);
					} else if (enemies[i] instanceof Bruiser) {
						generateEnemyPieces(enemies[i], BruiserPiece, ['BruiserCenterPart', 'BruiserLeftPart', 'BruiserRightPart']);
					} else if (enemies[i] instanceof Blaster) {
						generateEnemyPieces(enemies[i], BlasterPiece, ['BlasterBottomPiece', 'BlasterLeftPiece', 'BlasterRightPiece']);
					}
					enemies[i].destroy();
					enemies.splice(i, 1);
					difficultyManager.onEnemyDestroyed();
				} else {
					LK.effects.flashScreen(0xff0000, 1000);
					LK.showGameOver();
				}
			}
		}
		for (var l = activeLaserBeams.length - 1; l >= 0; l--) {
			var laser = activeLaserBeams[l];
			if (laser.laserBeam) {
				// Get laser's line segment
				var length = laser.laserBeam.height * laser.laserBeam.scaleY;
				var startX = laser.laserBeam.x;
				var startY = laser.laserBeam.y;
				var endX = startX - Math.sin(laser.laserBeam.rotation) * length;
				var endY = startY + Math.cos(laser.laserBeam.rotation) * length;
				// Get hero's circle
				var heroRadius = Math.min(hero.width, hero.height) * 0.4;
				// Check distance from hero to laser line
				var dx = endX - startX;
				var dy = endY - startY;
				var len = Math.sqrt(dx * dx + dy * dy);
				// Project hero position onto laser line
				var t = ((hero.x - startX) * dx + (hero.y - startY) * dy) / (len * len);
				t = Math.max(0, Math.min(1, t)); // Clamp to line segment
				// Get nearest point on line
				var nearestX = startX + t * dx;
				var nearestY = startY + t * dy;
				// Check distance
				var distance = Math.sqrt((hero.x - nearestX) * (hero.x - nearestX) + (hero.y - nearestY) * (hero.y - nearestY));
				if (distance < heroRadius) {
					// Use existing collision handling
					if (hero.shielded) {
						hero.shieldLevel -= 1;
						if (hero.shieldLevel <= 0) {
							hero.shielded = false;
							if (hero.shieldGraphics) {
								hero.shieldGraphics.destroy();
								hero.shieldGraphics = null;
							}
						} else {
							hero.shieldGraphics.tint = 0xFFFFFF;
							if (hero.shieldLevel === 2) {
								hero.shieldGraphics.tint = 0xFFFF00;
							} else if (hero.shieldLevel === 1) {
								hero.shieldGraphics.tint = 0xFFFFFF;
							}
						}
					} else {
						LK.effects.flashScreen(0xff0000, 1000);
						LK.showGameOver();
					}
				}
				// Do the same for clones
				for (var i = soldierClones.length - 1; i >= 0; i--) {
					var clone = soldierClones[i];
					var cloneRadius = Math.min(clone.width, clone.height) * 0.4;
					t = ((clone.x - startX) * dx + (clone.y - startY) * dy) / (len * len);
					t = Math.max(0, Math.min(1, t));
					nearestX = startX + t * dx;
					nearestY = startY + t * dy;
					distance = Math.sqrt((clone.x - nearestX) * (clone.x - nearestX) + (clone.y - nearestY) * (clone.y - nearestY));
					if (distance < cloneRadius) {
						clone.destroy();
						break;
					}
				}
			}
			laser.update();
			if (laser.isAttackComplete()) {
				if (laser.laserBeam) {
					laser.laserBeam.destroy();
				}
				activeLaserBeams.splice(l, 1);
			}
		}
		difficultyManager.update();
		// Update hero bullets
		for (var j = heroBullets.length - 1; j >= 0; j--) {
			heroBullets[j].update();
			for (var k = enemies.length - 1; k >= 0; k--) {
				if (heroBullets[j] && CollisionManager.checkCollision(heroBullets[j], enemies[k]) && enemies[k].y > 0) {
					enemies[k].HitPoints -= heroBullets[j].Power;
					// Apply an increased push back effect
					if (!(enemies[k] instanceof Bruiser)) {
						enemies[k].y -= 12; // Push the drone upwards slightly more
					}
					enemies[k].pulseEffect = true; // Trigger pulse effect
					// Removed tracerTail reference
					heroBullets[j].destroy();
					heroBullets.splice(j, 1);
					if (enemies[k].HitPoints <= 0) {
						if (enemies[k] instanceof Drone || enemies[k] instanceof RedDrone) {
							generateEnemyPieces(enemies[k], DronePiece, ['DroneCenterPart', 'DroneLeftPart', 'DroneRightPart']);
						} else if (enemies[k] instanceof Bruiser) {
							generateEnemyPieces(enemies[k], BruiserPiece, ['BruiserCenterPart', 'BruiserLeftPart', 'BruiserRightPart']);
						} else if (enemies[k] instanceof Blaster) {
							// In Blaster's destroy method or where Blaster destruction is handled
							if (this.laserMechanic) {
								this.laserMechanic.origin = null; // Detach from Blaster
								if (this.laserMechanic.isFiring) {
									// If it's firing, transition to sliding
									this.laserMechanic.startSliding();
								}
								// Don't destroy the laser mechanic - let it clean itself up
							}
							generateEnemyPieces(enemies[k], BlasterPiece, ['BlasterBottomPiece', 'BlasterLeftPiece', 'BlasterRightPiece']);
						} else if (enemies[k] instanceof Raider) {
							generateEnemyPieces(enemies[k], RaiderPiece, ['RaiderTop', 'RaiderBottom']);
						}
						enemies[k].destroy();
						enemies.splice(k, 1);
						difficultyManager.onEnemyDestroyed();
						LK.setScore(LK.getScore() + 1);
						scoreTxt.setText(LK.getScore());
					}
					break;
				}
			}
		}
		// Fire bullets using current power-up behavior
		if (LK.ticks % 18 == 0) {
			if (hero && hero.shootBehavior) {
				hero.shootBehavior();
			}
		}
		// Generate dust particles in sync with player pulsing
		if (LK.ticks % 24 == 0) {
			var newDust = new Dust();
			newDust.x = hero.x - hero.width / 4; // Move dust spawn position right half as much as the last move
			newDust.y = hero.y + hero.height / 2 * 0.93; // Move dust spawn point up 3% more
			game.addChild(newDust);
		} else if (LK.ticks % 24 == 12) {
			var newDust = new Dust();
			newDust.x = hero.x + hero.width / 4; // Create another dust spawn point an equal distance in from the right of the player asset
			newDust.y = hero.y + hero.height / 2 * 0.93; // Move dust spawn point up 3% more
			game.addChild(newDust);
		}
	}
};
// Handle touch input for hero movement
var dragNode = null;
game.down = function (x, y, obj) {
	if (isStarted) {
		dragNode = {
			x: hero.x,
			y: hero.y
		};
		// Add a tilt-back effect during initial movement
		hero.rotation = x > hero.x ? Math.PI / 180 * -1 : Math.PI / 180 * 1;
	}
};
game.move = function (x, y, obj) {
	if (isStarted && dragNode) {
		// Add a slight delay to the drag control to make the player feel like it has more weight
		dragNode.x += (x - dragNode.x) * 0.1;
		dragNode.y = hero.y; // Lock the y position to the hero's initial y position
	}
};
game.up = function (x, y, obj) {
	dragNode = null;
};
// Display score
var scoreTxt = new Text2('0', {
	size: 150,
	fill: "#ffffff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.setText(LK.getScore());
LaserMechanic.prototype.startFiring = function () {
	if (!this.origin || !this.targetX || !this.targetY || this.isFiring) {
		return;
	}
	this.isFiring = true;
	this.fireStartTime = LK.ticks;
	// Calculate direction
	var dirX = this.targetX - this.origin.x;
	var dirY = this.targetY - this.origin.y;
	this.rotation = Math.atan2(dirY, dirX) - Math.PI / 2;
	// Create array to hold segments
	this.segments = [];
	// Create initial segment with adjusted position
	var segment = new LaserBeamSegment();
	// Match the origin point of the Blaster
	segment.x = this.origin.x;
	segment.y = this.origin.y + this.origin.height * 0.1; // Small offset like original
	segment.rotation = this.rotation;
	game.addChild(segment);
	this.segments.push(segment);
};
LaserMechanic.prototype.updateFiring = function () {
	if (!this.isFiring) {
		return;
	}
	var fireProgress = (LK.ticks - this.fireStartTime) / this.fireDuration;
	if (fireProgress <= 1) {
		// Add new segments quickly until desired length
		if (this.segments.length < 20 && LK.ticks % 2 === 0) {
			// Adjust segment count and speed
			var lastSegment = this.segments[this.segments.length - 1];
			var segment = new LaserBeamSegment();
			// Position new segment based on last one
			segment.x = lastSegment.x - Math.sin(this.rotation) * segment.height;
			segment.y = lastSegment.y + Math.cos(this.rotation) * segment.height;
			segment.rotation = this.rotation;
			game.addChild(segment);
			this.segments.push(segment);
		}
	} else {
		this.isFiring = false;
		this.startSliding();
	}
};
LaserMechanic.prototype.startSliding = function () {
	this.isSliding = true;
	this.slideStartTime = LK.ticks;
};
LaserMechanic.prototype.updateSliding = function () {
	if (!this.isSliding) {
		return;
	}
	var slideProgress = (LK.ticks - this.slideStartTime) / this.slideOffDuration;
	if (slideProgress <= 1) {
		// Move all segments
		var allOffScreen = true;
		for (var i = 0; i < this.segments.length; i++) {
			var segment = this.segments[i];
			segment.x += -Math.sin(this.rotation) * 20;
			segment.y += Math.cos(this.rotation) * 20;
			// Check if any segment is still on screen
			if (segment.y > 0 && segment.y < 2048 && segment.x > 0 && segment.x < 2048) {
				allOffScreen = false;
			}
		}
		// If all segments are off screen, clean up early
		if (allOffScreen) {
			slideProgress = 1;
		}
	}
	if (slideProgress > 1) {
		// Clean up all segments
		for (var i = this.segments.length - 1; i >= 0; i--) {
			game.removeChild(this.segments[i]);
		}
		this.segments = [];
		this.isSliding = false;
		this.attackComplete = true;
	}
};
// Method to reset attack states
LaserMechanic.prototype.resetAttack = function () {
	this.isCharging = false;
	this.isFiring = false;
	this.isSliding = false;
	this.targetX = null;
	this.targetY = null;
	this.attackComplete = false;
	return true;
};
LaserMechanic.prototype.update = function () {
	// Add state validation
	if (!this.isCharging && !this.isFiring && !this.isSliding && this.laserBeam) {
		// If we have a beam but no state, force sliding state
		this.isSliding = true;
		this.slideStartTime = LK.ticks;
	}
	// Your existing debug marker
	var stateMarker = LK.getAsset('LaserCharge', {
		anchorX: 0.5,
		anchorY: 0.5,
		scale: {
			x: 1,
			y: 1
		},
		alpha: 0.8,
		tint: this.isCharging ? 0xFF0000 : this.isFiring ? 0x00FF00 : 0x0000FF
	});
	stateMarker.x = 50;
	stateMarker.y = 50;
	game.addChild(stateMarker);
	if (this.isCharging) {
		this.updateCharge();
	} else if (this.isFiring) {
		this.updateFiring();
	} else if (this.isSliding || this.laserBeam) {
		this.updateSliding();
	}
};
// Method to check if the attack sequence is complete
LaserMechanic.prototype.isAttackComplete = function () {
	return this.attackComplete;
};
LaserMechanic.prototype.detachBeam = function () {
	if (this.laserBeam) {
		// Detach laser from origin
		this.origin = null;
		// Force laser into sliding phase
		this.startSliding();
	}
}; ===================================================================
--- original.js
+++ change.js
@@ -803,9 +803,13 @@
 						tvEffect.soldierClone = newClone; // Reference to the soldier clone
 						tvEffect.x = newClone.x;
 						tvEffect.y = newClone.y;
 						backgroundContainer.addChild(tvEffect);
-						soldierClones.push(newClone);
+						// Add soldier clone to the game after TV effect completes
+						LK.setTimeout(function () {
+							soldierClones.push(newClone);
+							game.addChild(newClone);
+						}, tvEffect.animationDuration * 16.67); // Convert frames to milliseconds
 						// Add TV turn-on effect
 						var tvEffect = new TVTurnOnEffect();
 						tvEffect.soldierClone = newClone; // Reference to the soldier clone
 						tvEffect.x = newClone.x;
@@ -1367,22 +1371,26 @@
 			if (self.soldierClone) {
 				self.soldierClone.x = self.x;
 				self.soldierClone.y = self.y;
 			}
-			// Stretch into a horizontal line
-			scanlineGraphics.scaleX = 0.01 + progress * 1.99; // Expand to twice the width of the soldier clone
-			scanlineGraphics.scaleY = 0.01; // Keep as a line
-			// Compress to half its width
-			if (progress > 0.5) {
-				scanlineGraphics.scaleX = 1.0 - (progress - 0.5) * 0.5; // Compress to half width
+			if (progress <= 0.5) {
+				// Stretch from a dot to a horizontal line
+				scanlineGraphics.scaleX = 0.01 + progress * 3.98; // Expand to twice the width of the soldier clone
+				scanlineGraphics.scaleY = 0.01; // Keep as a line
+			} else {
+				// Compress to half its width and expand soldier clone
+				scanlineGraphics.scaleX = 2.0 - (progress - 0.5) * 2.0; // Compress to half width
 				if (self.soldierClone) {
 					self.soldierClone.scaleY = 0.01 + (progress - 0.5) * 1.98; // Stretch soldier clone vertically
 				}
 			}
 			// Add scanline effect by adjusting alpha
 			scanlineGraphics.alpha = 0.5 + Math.sin(progress * Math.PI * 10) * 0.5;
 		} else {
 			// Destroy effect after animation completes
+			if (self.soldierClone) {
+				self.soldierClone.scaleY = 1.0; // Ensure soldier clone is at full size
+			}
 			self.destroy();
 		}
 	};
 	return self;
 View of a futuristic soldier from directly overhead. White armor with blue glowing cyberpunk details. Holding weapon forward.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 
 The lights of a futuristic city in the dark at night. Very high above it looking straight down like from an airplane or a map. Background for an endlessly scrolling game.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 A big button that say Play to start playing a game. Use neon cyberpunk style.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 Overhead view. A hovering robot with a tapered midsection with two bulky arms with claw like hands and a giant red “eye” on top of its body. Looking straight down. Cyberpunk, black with red glowing highlights.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 
 
 Overhead view. A heavily armored attack robot. Two arms with large gauntlet type fists. Four large red glowing eyes. Three distinct parts, body and two arms. Symmetrical design. Birds Eye view above them looking down on their head. Simple shapes. Low detail. Cyberpunk, black with red glowing highlights.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 
 
 
 A red glowing line. Bright red core with subtle outer glow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 
 
 
 
 
 
 
 
 
 
 A blue transparent dome type shield. Simple graphics. Low details. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 A ring of nuclear fire seen from overhead. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 A thin robot with goggles riding a hover-bike. Twin blaster guns mounted on front. Top down view. Birds Eye view. Cyberpunk with red glowing highlights... Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 
 
 Battle drone, circular. White with blue glowing highlights. Birds Eye view from overhead. Cyberpunk. Simple shapes.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 GameTheme
Music
TitleTheme
Music
HeroBlaster
Sound effect
Explosion
Sound effect
PowerUp
Sound effect
CloneSoldier
Sound effect
WeaponPowerUp
Sound effect
Drone
Sound effect
BinaryStorm
Sound effect
LaserCharge
Sound effect
LaserFire
Sound effect
BruiserStomp
Sound effect
RaiderSwoop
Sound effect
ShieldLevelUp
Sound effect
HeroHit
Sound effect
HeroScream
Sound effect