User prompt
objspikeys custom collision should be black
User prompt
objspikeys custom collision should be dark purple
User prompt
sometimes objspikey is invisible, fix it
User prompt
1. **Collision with Hero**: If the `ObjSPIKEY` intersects with the `hero` and the `hero` is dashing, the `ObjSPIKEY` is destroyed, and the `snd_spikey` sound is played.
User prompt
play snd_spikey when objspikey is destroyed
User prompt
play snd_sphere when objsphere is instantiated
User prompt
play sndwindup when objwindup is instantiated
User prompt
play sndsphere when objsphere is instantiated
User prompt
play snd_enemy when objlaser is instantiated
User prompt
Please fix the bug: 'Uncaught timeout callback must be a function' in or related to this line: 'var objSPIKEYGenerationInterval = LK.setInterval(generateObjSPIKEY, 8000);' Line Number: 1233
User prompt
Please fix the bug: 'timeout callback must be a function' in or related to this line: 'var objSPIKEYGenerationInterval = LK.setInterval(generateObjSPIKEY, 8000);' Line Number: 1485
User prompt
objspikey does not seem to be respawning
User prompt
If `objSPIKEY` intersects with the `hero` while the `hero` is dashing, an explosion effect is created at the collision point, and `objSPIKEY` is destroyed.
User prompt
when enemy middle right is destroyed also do this: 4. **Event Status Update**: The `isEventOngoing` flag is set to `false`, indicating that the event has ended. 5. **Event Text Update**: The `eventTxt` text object is updated to display 'Event: None', signaling that no event is currently active. 6. **Reset Random Event**: The `randomEvent` variable is reset to an empty string.
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Timeout.tick error: objLaser.update is not a function' in or related to this line: 'objLaser.update(); // Ensure objLaser update method is called every tick' Line Number: 208
User prompt
any idea why obj laser collision detection is not working?
User prompt
Add collision detection between objsphere and hero to trigger game over
User prompt
try again
User prompt
exagerate the verticality of objsphere
User prompt
instantiate objsphere above enemy middle right and move towards the y position of hero
User prompt
objsphere should spawn on the y position of hero
User prompt
Accelerate the negative x movement of objSphere
User prompt
make sure objsphere spawns on the y position of hero
User prompt
Accelerate the negative x movement of objSphere
/**** 
* Classes
****/ 
var BootText = Container.expand(function (text) {
	var self = Container.call(this);
	var bootText = self.addChild(new Text2(text, {
		size: 150,
		fill: "#FFFFFF",
		fontWeight: 'bolder',
		stroke: "#000000",
		// Black outline
		strokeThickness: 5 // Thickness of the outline
	}));
	bootText.anchor.set(0.5, 0);
	self.alpha = 0;
	self.fadeIn = function () {
		if (self.alpha < 1) {
			self.alpha += 0.05;
		}
	};
	self.fadeOut = function () {
		if (self.alpha > 0) {
			self.alpha -= 0.05;
		} else {
			self.destroy();
		}
	};
});
var EnemyMiddleRight = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphics = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.x = game.width + 200;
	self.y = game.height / 2;
	self.alpha = 0;
	self.fadeInInterval = LK.setInterval(function () {
		self.alpha += 0.05;
		if (self.alpha >= 1) {
			LK.clearInterval(self.fadeInInterval);
		}
	}, 16); // Approximately 60 FPS
	self.animate = function () {
		var targetX = game.width - 100;
		self.animationInterval = LK.setInterval(function () {
			if (self.x > targetX) {
				self.x -= animationSpeed;
			} else {
				LK.clearInterval(self.animationInterval);
				// Execute Attack Pattern A first
				self.attackPatternA();
				// Reverse animation after Attack Pattern A and B
				LK.setTimeout(function () {
					self.reverseAnimation();
				}, 16000); // Execute reverseAnimation after Attack Pattern B
			}
		}, 16); // Approximately 60 FPS
	};
	self.reverseAnimation = function () {
		var startX = game.width + 200;
		self.animationInterval = LK.setInterval(function () {
			if (self.x < startX) {
				self.x += animationSpeed;
			} else {
				LK.clearInterval(self.animationInterval);
				self.fadeOutInterval = LK.setInterval(function () {
					self.alpha -= 0.05;
					if (self.alpha <= 0) {
						LK.clearInterval(self.fadeOutInterval);
						self.visible = false;
						randomEvent = ""; // Reset random event
						eventTxt.setText('Event: None'); // Update event text
						isEventOngoing = false; // Set event status to false
						LK.getSound('snd_powerup').play(); // Play snd_powerup sound
						LK.getSound('snd_nice').play(); // Play snd_nice sound
						destroyAllObjs(); // Destroy all instances of ObjGO, ObjRALLY, ObjJUMP, ObjACCELERATE
						var originalIncrement = 1 / 60;
						var acceleratedIncrement = 1 / 15;
						distanceTraveledIncrement = acceleratedIncrement;
						var originalParallaxSpeed = parallax.speed;
						parallax.speed *= 5;
						var shakeAmplitude = 10;
						var shakeDuration = 100;
						var originalX = game.x;
						var originalY = game.y;
						var shakeInterval = LK.setInterval(function () {
							game.x = originalX + (Math.random() - 0.5) * shakeAmplitude;
							game.y = originalY + (Math.random() - 0.5) * shakeAmplitude;
						}, shakeDuration);
						LK.effects.flashScreen(0xffffff, 5000); // Flash screen for 5 seconds
						var objRush = LK.getAsset('objRush', {
							anchorX: 0.5,
							anchorY: 0.5
						});
						objRush.x = game.width / 2;
						objRush.y = game.height / 2;
						objRush.alpha = 0; // Start with alpha 0 for fade in effect
						game.addChild(objRush);
						// Fade in effect
						var fadeInInterval = LK.setInterval(function () {
							objRush.alpha += 0.05;
							if (objRush.alpha >= 1) {
								LK.clearInterval(fadeInInterval);
								// Start fade out effect after 3 seconds
								LK.setTimeout(function () {
									var fadeOutInterval = LK.setInterval(function () {
										objRush.alpha -= 0.05;
										if (objRush.alpha <= 0) {
											LK.clearInterval(fadeOutInterval);
											objRush.destroy();
										}
									}, 50); // Approximately 20 FPS
									LK.setTimeout(function () {
										distanceTraveledIncrement = originalIncrement;
										parallax.speed = originalParallaxSpeed;
										LK.clearInterval(shakeInterval);
										game.x = originalX;
										game.y = originalY;
										LK.clearInterval(shakeInterval);
										game.x = originalX;
										game.y = originalY;
									}, 5000); // Reset to normal after 5 seconds
								}, 3000);
							}
						}, 50); // Approximately 20 FPS
						distanceTraveled += 100; // Increase distanceTraveled by 100 units
					}
				}, 16); // Approximately 60 FPS
			}
		}, 16); // Approximately 60 FPS
	};
	self.attackPatternA = function () {
		// Define Attack Pattern A behavior here
		console.log("Executing Attack Pattern A");
		// Instantiate objwindup in the center of the enemy
		objWindup = LK.getAsset('objwindup', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		objWindup.x = self.x - objWindup.width / 2 - 100;
		objWindup.y = self.y - objWindup.height / 2 + 400;
		game.addChild(objWindup);
		// Add fast rotation to objwindup
		objWindup.update = function () {
			objWindup.rotation += 0.2; // Adjust the rotation speed as needed
		};
		// Keep objwindup visible for 3 seconds
		LK.setTimeout(function () {
			// Replace objwindup with objlaser
			objWindup.destroy();
			var objLaser = new ObjLaser();
			objLaser.x = self.x - objLaser.width / 2 - 175;
			objLaser.y = self.y - objLaser.height / 2 + 450;
			game.addChild(objLaser);
			game.addChild(objLaser); // Ensure objLaser is added to the game
			// Add shake effect to objlaser
			var shakeAmplitude = 12; // Amplitude of the shake
			var shakeDuration = 100; // Duration of each shake in milliseconds
			var originalX = objLaser.x;
			var originalY = objLaser.y;
			var shakeInterval = LK.setInterval(function () {
				objLaser.x = originalX + (Math.random() - 0.75) * shakeAmplitude;
				objLaser.y = originalY + (Math.random() - 0.75) * shakeAmplitude;
			}, shakeDuration);
			// Keep objlaser visible for 5 seconds
			LK.setTimeout(function () {
				objLaser.destroy();
				// Wait 1 second before starting attack pattern B
				LK.setTimeout(function () {
					self.attackPatternB();
				}, 1000);
			}, 3000);
		}, 2000);
	};
	self.attackPatternB = function () {
		console.log("Executing Attack Pattern B");
		var duration = 12000; // 12 seconds
		var interval = 3000; // 3 seconds
		var startTime = Date.now();
		var spawnSphere = function spawnSphere() {
			if (Date.now() - startTime >= duration) {
				LK.clearInterval(spawnInterval);
				return;
			}
			var objSphere = LK.getAsset('objsphere', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			objSphere.x = self.x - 300 + (Math.random() - 0.5) * 50; // Reduce randomness to X movement
			objSphere.y = self.y - 225 + (Math.random() - 0.5) * 50; // Add slight randomness to Y movement
			game.addChild(objSphere);
			var amplitude = 50; // Increase amplitude for a wider vertical arc
			var frequency = 0.01; // Adjust frequency for smoother movement
			var direction = Math.random() < 0.5 ? 1 : -1;
			objSphere.update = function () {
				objSphere.x -= 10; // Accelerate the negative x movement
				objSphere.y += Math.sin(objSphere.x * frequency) * (amplitude / 2) * direction;
				if (objSphere.x < -objSphere.width) {
					objSphere.destroy();
				}
				// Remove pulsating effect
				// Ensure objSphere stays within the vertical boundaries of the playspace
				if (objSphere.y < 0) {
					objSphere.y = 0;
				} else if (objSphere.y > game.height - objSphere.height) {
					objSphere.y = game.height - objSphere.height;
				}
				// Move towards the y position of hero
				if (objSphere.y < hero.y) {
					objSphere.y += 2; // Adjust speed as needed
				} else if (objSphere.y > hero.y) {
					objSphere.y -= 2; // Adjust speed as needed
				}
				// Check for collision with hero
				if (objSphere.intersects(hero)) {
					LK.effects.flashScreen(0xff0000, 1000); // Flash screen red for 1 second
					LK.showGameOver(); // Trigger game over
				}
			};
			game.addChild(objSphere);
		};
		var spawnInterval = LK.setInterval(spawnSphere, interval);
	};
});
var Hero = Container.expand(function () {
	var self = Container.call(this);
	self.createDashTrail = function () {
		var trailCount = 10;
		var flashDuration = 50; // Duration for each flash
		for (var i = 0; i < trailCount; i++) {
			LK.setTimeout(function () {
				var trailParticle = new Particle();
				trailParticle.x = self.x;
				trailParticle.y = self.y;
				game.addChild(trailParticle);
				var neonColors = [0x39ff14, 0xff073a, 0x00ffff, 0xffff00, 0xff00ff];
				var randomColor = neonColors[Math.floor(Math.random() * neonColors.length)];
				LK.effects.flashObject(trailParticle, randomColor, flashDuration);
			}, i * 50);
		}
	};
	var heroGraphics = self.attachAsset('hero', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 30;
	// Initialize jetfuel in the center of hero
	var jetfuel = self.attachAsset('jetfuel', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	jetfuel.x = -50;
	jetfuel.y = 50;
	self.addChildAt(jetfuel, 0);
	// Set interval to flip jetfuel's visual on the x alignment every 0.5 seconds
	self.jetfuelInterval = LK.setInterval(function () {
		jetfuel.scale.x *= -1;
	}, 250);
	self.on('destroy', function () {
		eventTxt.setText('Event: None');
		randomEvent = "";
		LK.clearInterval(self.jetfuelInterval);
	});
	self.dashSpeed = game.width / 2 / 30; // 1/2 of the screen over 0.5 seconds at 60FPS
	self.dashBackSpeed = self.dashSpeed / 2; // Accelerated return at half of the dash speed
	self.dashStartTime = 0; // Time when the dash started
	self.gravity = 1;
	self.isDashing = false;
	self.initialX = 200;
	self.animateToPosition = function () {
		var targetY = Math.max(2732 / 2, 300);
		var targetX = self.initialX;
		var animationSpeed = 10;
		if (!self.animationStarted) {
			self.animationDelay = LK.setTimeout(function () {
				self.animationStarted = true;
			}, 3000);
			self.animationStarted = false;
		}
		if (self.animationStarted) {
			if (self.y < targetY) {
				self.y += animationSpeed;
			}
			if (self.x < targetX) {
				self.x += animationSpeed;
			}
			if (self.y >= targetY && self.x >= targetX) {
				gameStarted = true; // Start the game once the hero reaches the initial position
				initializeScoreDisplay();
				startObstacleGeneration();
			}
		}
	};
	self.dash = function () {
		if (!self.isDashing && LK.ticks - self.holdStartTime >= 60 && self.x === self.initialX) {
			self.isDashing = true;
			self.dashStartTime = LK.ticks; // Save the start time of the dash
			self.savedX = self.x; // Save the current x position
			self.dashTargetX = self.x + game.width / 3 * 2; // Set the target X position for the dash, now twice as long
			// Apply dash effect
			self.createDashTrail();
			self.stopFlashing();
		}
	};
	self.isGravityFlipped = false;
	self.flipGravity = function () {
		if (!self.isDashing) {
			self.isGravityFlipped = !self.isGravityFlipped;
			self.gravity *= -1;
		}
	};
	self._move_migrated = function () {
		if (self.isHolding && LK.ticks - self.holdStartTime >= 60 && LK.ticks - self.dashStartTime > 6) {
			self.dash();
		}
		if (self.isDashing) {
			if (self.x < self.dashTargetX) {
				self.x += self.dashSpeed;
				// Check for collision with obstacles
				for (var i = obstacles.length - 1; i >= 0; i--) {
					if (self.intersects(obstacles[i])) {
						var explosion = new ParticleExplosion(obstacles[i].x, obstacles[i].y);
						game.addChild(explosion);
						if (obstacles[i] instanceof ObjGO) {
							heroGround.moveToCenterX();
							var explosion = new ParticleExplosion(obstacles[i].x, obstacles[i].y);
							game.addChild(explosion);
							var explosion = new ParticleExplosion(obstacles[i].x, obstacles[i].y);
							game.addChild(explosion);
							LK.getSound('snd_powerup').play(); // Play snd_powerup sound
							handleCollisionWithObj(); // Call handleCollisionWithObj when colliding with ObjGO
						} else if (obstacles[i] instanceof ObjRALLY) {
							heroGround.moveToInitialPosition();
							var initialHeroGroundX = heroGround.x;
							var initialHeroGroundY = heroGround.y;
							LK.getSound('snd_powerup').play(); // Play snd_powerup sound
							handleCollisionWithObj(); // Call handleCollisionWithObj when colliding with ObjRALLY
						} else if (obstacles[i] instanceof ObjJUMP) {
							brother();
							LK.getSound('snd_powerup').play(); // Play snd_powerup sound
							handleCollisionWithObj(); // Call handleCollisionWithObj when colliding with ObjJUMP
							if (heroGround.idleSpeechBubble) {
								heroGround.idleSpeechBubble.visible = false;
								LK.setTimeout(function () {
									if (heroGround.idleSpeechBubble) {
										heroGround.idleSpeechBubble.visible = true;
									}
								}, 5000);
							}
						} else if (obstacles[i] instanceof ObjACCELERATE) {
							var explosion = new ParticleExplosion(obstacles[i].x, obstacles[i].y);
							game.addChild(explosion);
							LK.getSound('snd_powerup').play(); // Play snd_powerup sound
							LK.getSound('snd_letsgo').play(); // Play snd_letsgo sound
							destroyAllObjs(); // Destroy all instances of ObjGO, ObjRALLY, and ObjJUMP
							// Temporarily increase distanceTraveled increment
							var originalIncrement = 1 / 60;
							var acceleratedIncrement = 1 / 15;
							distanceTraveledIncrement = acceleratedIncrement;
							// Temporarily increase parallax speed
							var originalParallaxSpeed = parallax.speed;
							parallax.speed *= 5;
							// Add screen shake and flash effect
							var shakeAmplitude = 10;
							var shakeDuration = 100;
							var originalX = game.x;
							var originalY = game.y;
							var shakeInterval = LK.setInterval(function () {
								game.x = originalX + (Math.random() - 0.5) * shakeAmplitude;
								game.y = originalY + (Math.random() - 0.5) * shakeAmplitude;
							}, shakeDuration);
							LK.effects.flashScreen(0xffffff, 5000); // Flash screen for 5 seconds
							// Instantiate objrush in the center of the playspace for 3 seconds with fade in and fade out effect
							var objRush = LK.getAsset('objRush', {
								anchorX: 0.5,
								anchorY: 0.5
							});
							objRush.x = game.width / 2;
							objRush.y = game.height / 2;
							objRush.alpha = 0; // Start with alpha 0 for fade in effect
							game.addChild(objRush);
							// Fade in effect
							var fadeInInterval = LK.setInterval(function () {
								objRush.alpha += 0.05;
								if (objRush.alpha >= 1) {
									LK.clearInterval(fadeInInterval);
									// Start fade out effect after 3 seconds
									LK.setTimeout(function () {
										var fadeOutInterval = LK.setInterval(function () {
											objRush.alpha -= 0.05;
											if (objRush.alpha <= 0) {
												LK.clearInterval(fadeOutInterval);
												objRush.destroy();
											}
										}, 50); // Approximately 20 FPS
									}, 3000);
								}
							}, 50); // Approximately 20 FPS
							LK.setTimeout(function () {
								distanceTraveledIncrement = originalIncrement;
								parallax.speed = originalParallaxSpeed;
								LK.clearInterval(shakeInterval);
								game.x = originalX;
								game.y = originalY;
							}, 5000); // Reset to normal after 5 seconds
						}
						if (obstacles[i]) {
							obstacles[i].destroy();
							obstacles.splice(i, 1);
						}
					}
				}
			} else {
				self.isDashing = false;
				self.dashTargetX = null; // Clear the dash target position
				// Remove dash effect
				self.tint = 0xffffff;
			}
		}
		// Gradually move back to the initial position after dashing
		// Resume normal movement after reaching saved x position
		if (!self.isDashing && self.dashTargetX === null && self.x !== self.savedX) {
			var moveBack = self.savedX < self.x ? -self.dashBackSpeed : self.dashBackSpeed;
			self.x += moveBack;
			// Clamp the hero's x position to the savedX to prevent overshooting
			if (Math.abs(self.x - self.savedX) < Math.abs(moveBack)) {
				self.x = self.savedX;
			}
		}
		// Stop vertical movement while holding down
		if (!self.isHolding && !self.isDashing) {
			self.y += self.speed * self.gravity;
			var boundaryPadding = 300; // Adjust this value to set the top boundary padding
			if (self.y < boundaryPadding) {
				self.y = boundaryPadding;
			}
			if (self.y > game.height - 800) {
				self.y = game.height - 800;
			}
		}
		// Removed game over condition when hero leaves the screen horizontally
		// Generate particle trail
		if (LK.ticks % 5 == 0 && !self.isHolding) {
			var particle = new Particle();
			particle.x = self.x;
			particle.y = self.y;
			game.addChildAt(particle, 0);
			particle.visible = true; // Ensure the particle is visible
		}
	};
	self.isHolding = false;
	self.holdStartTime = 0;
	self.startFlashing = function () {
		if (!self.flashInterval && !self.isDashing) {
			self.flashInterval = LK.setInterval(function () {
				self.scale.set(self.scale.x === 1 ? 1.5 : 1);
				self.tint = self.tint === 0x0000ff ? 0x00ffff : 0x0000ff; // Transition between blue and cyan
			}, 100); // Pulse every 100ms
		}
	};
	self.stopFlashing = function () {
		if (self.flashInterval) {
			LK.clearInterval(self.flashInterval);
			self.flashInterval = null;
			self.visible = true; // Ensure hero is visible after stopping flash
			self.tint = 0x9a3986; // Reset color to default
			self.scale.set(1); // Reset scale to default
		}
	};
	self.onHold = function () {
		if (!self.isHolding && !self.isDashing && !self.isDashing) {
			self.isHolding = true;
			self.holdStartTime = LK.ticks;
			self.startFlashing();
		}
	};
	self.onRelease = function () {
		if (self.isHolding && !self.isDashing) {
			self.dash();
		}
		self.isHolding = false;
		self.holdStartTime = 0;
		self.stopFlashing();
	};
});
var Hero_Ground = Container.expand(function () {
	var self = Container.call(this);
	var heroGroundGraphics = self.attachAsset('heroGround', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var heroGroundGraphicsB = self.attachAsset('heroGroundB', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	heroGroundGraphicsB.visible = false;
	self.addChild(heroGroundGraphicsB);
	// Set interval to switch between heroGround and heroGroundB every 0.5 seconds
	self.heroGroundInterval = LK.setInterval(function () {
		heroGroundGraphics.visible = !heroGroundGraphics.visible;
		heroGroundGraphicsB.visible = !heroGroundGraphicsB.visible;
	}, 250);
	self.on('destroy', function () {
		LK.clearInterval(self.heroGroundInterval);
		if (self.interpolationInterval) {
			LK.clearInterval(self.interpolationInterval);
		}
	});
	self.speed = 20;
	self.gravity = 1;
	self.isJumping = false;
	self.jumpSpeed = -20;
	self.jumpVelocity = 0;
	self.initialY = 200;
	self._update_migrated = function () {
		if (self.isJumping) {
			self.y += self.jumpSpeed;
			self.jumpSpeed += self.gravity;
		}
		if (self.y > game.floorLevel) {
			self.y = game.floorLevel;
			self.isJumping = false;
		}
	};
	self.moveToCenterX = function () {
		if (self.isMovingToCenter || self.isMovingToInitial) {
			return;
		} // Prevent multiple calls
		self.isMovingToCenter = true; // Set flag to indicate movement in progress
		isHeroGroundMoving = true;
		var targetX = game.width / 2 + 700;
		var interpolationSpeed = 15; // Adjust this value to control the speed of interpolation
		self.interpolationInterval = LK.setInterval(function () {
			if (Math.abs(self.x - targetX) < interpolationSpeed) {
				self.x = targetX;
				LK.clearInterval(self.interpolationInterval);
				self.isMovingToCenter = false; // Reset flag when movement is complete
				isHeroGroundMoving = false;
				// Replace movingSpeechBubble with idleSpeechBubble
				if (self.movingSpeechBubble) {
					self.movingSpeechBubble.destroy();
					self.movingSpeechBubble = null;
				}
				self.idleSpeechBubble = LK.getAsset('idleSpeechBubble', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				self.addChild(self.idleSpeechBubble);
				self.idleSpeechBubble.x = self.width / 2 - 20;
				self.idleSpeechBubble.y = -self.idleSpeechBubble.height / 2 - 125;
			} else {
				self.x += self.x < targetX ? interpolationSpeed : -interpolationSpeed;
			}
		}, 16); // Approximately 60 FPS
		// Replace idleSpeechBubble with movingSpeechBubble
		if (self.idleSpeechBubble) {
			self.idleSpeechBubble.destroy();
			self.idleSpeechBubble = null;
		}
		// Ensure only one moving speech bubble is active at a time
		if (game.activeMovingSpeechBubble) {
			game.activeMovingSpeechBubble.destroy();
		}
		self.movingSpeechBubble = LK.getAsset('movingSpeechBubble', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		self.addChild(self.movingSpeechBubble);
		self.movingSpeechBubble.x = self.width / 2 + 10;
		self.movingSpeechBubble.y = -self.movingSpeechBubble.height / 2 - 125;
		game.activeMovingSpeechBubble = self.movingSpeechBubble;
	};
	self._move_migrated = function () {
		if (self.isJumping) {
			self.y += self.jumpVelocity;
			self.jumpVelocity += self.gravity;
			if (self.y >= self.initialY) {
				self.y = self.initialY;
				self.isJumping = false;
			}
		} else {
			self.y += self.gravity;
			if (self.y > game.height - self.height / 2) {
				self.y = game.height - self.height / 2;
			}
		}
	};
	self.moveToInitialPosition = function () {
		if (self.isMovingToInitial || self.isMovingToCenter) {
			return;
		} // Prevent multiple calls
		var targetX = heroGround.initialX;
		if (Math.abs(self.x - targetX) < interpolationSpeed) {
			return; // Already at the initial position, do nothing
		}
		self.isMovingToInitial = true; // Set flag to indicate movement in progress
		isHeroGroundMoving = true;
		var interpolationSpeed = 15; // Adjust this value to control the speed of interpolation
		self.interpolationInterval = LK.setInterval(function () {
			if (Math.abs(self.x - targetX) < interpolationSpeed) {
				self.x = targetX;
				LK.clearInterval(self.interpolationInterval);
				self.isMovingToInitial = false; // Reset flag when movement is complete
				isHeroGroundMoving = false;
				// Replace movingSpeechBubble with idleSpeechBubble
				if (self.movingSpeechBubble) {
					self.movingSpeechBubble.destroy();
					self.movingSpeechBubble = null;
				}
				self.idleSpeechBubble = LK.getAsset('idleSpeechBubble', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				self.addChild(self.idleSpeechBubble);
				self.idleSpeechBubble.x = self.width / 2 - 20;
				self.idleSpeechBubble.y = -self.idleSpeechBubble.height / 2 - 125;
			} else {
				self.x += self.x < targetX ? interpolationSpeed : -interpolationSpeed;
			}
		}, 16); // Approximately 60 FPS
		// Replace idleSpeechBubble with movingSpeechBubble
		if (self.idleSpeechBubble) {
			self.idleSpeechBubble.destroy();
			self.idleSpeechBubble = null;
		}
		// Ensure only one moving speech bubble is active at a time
		if (game.activeMovingSpeechBubble) {
			game.activeMovingSpeechBubble.destroy();
		}
		self.movingSpeechBubble = LK.getAsset('movingSpeechBubble', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		self.addChild(self.movingSpeechBubble);
		self.movingSpeechBubble.x = self.width / 2 + 10;
		self.movingSpeechBubble.y = -self.movingSpeechBubble.height / 2 - 125;
		game.activeMovingSpeechBubble = self.movingSpeechBubble;
	};
});
var ObjACCELERATE = Container.expand(function () {
	var self = Container.call(this);
	var objACCELERATEGraphics = self.attachAsset('objAccelerate', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -4 - Math.random() * 3;
	self._move_migrated = function () {
		self.x += self.speed;
		if (self.x < -self.width) {
			self.x = game.width;
			var minY = 400;
			var maxY = game.height / 2 + 200;
			self.y = minY + Math.random() * (maxY - minY);
		}
		// Add hover effect
		self.y += Math.sin(LK.ticks / 10) * 2;
	};
});
var ObjCar = Container.expand(function () {
	var self = Container.call(this);
	var objCarGraphics = self.attachAsset('objcar', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -15;
	self.update = function () {
		// Check for collision with hero
		if (self.intersects(hero)) {
			LK.effects.flashScreen(0xff0000, 1000); // Flash screen red for 1 second
			LK.showGameOver(); // Trigger game over
		}
		// Check for collision with hero or heroGround
		if (self.intersects(hero) || self.intersects(heroGround)) {
			LK.effects.flashScreen(0xff0000, 1000);
			LK.showGameOver();
		}
		self.x += self.speed;
		if (self.x < -self.width) {
			self.destroy();
			isEventOngoing = false;
			eventTxt.setText('Event: None');
			randomEvent = "";
			distanceTraveled += 100;
			// Trigger acceleration effects
			LK.getSound('snd_powerup').play(); // Play snd_powerup sound
			LK.getSound('snd_nice').play(); // Play snd_nice sound
			destroyAllObjs(); // Destroy all instances of ObjGO, ObjRALLY, and ObjJUMP
			// Temporarily increase distanceTraveled increment
			var originalIncrement = 1 / 60;
			var acceleratedIncrement = 1 / 15;
			distanceTraveledIncrement = acceleratedIncrement;
			// Temporarily increase parallax speed
			var originalParallaxSpeed = parallax.speed;
			parallax.speed *= 5;
			// Add screen shake and flash effect
			var shakeAmplitude = 10;
			var shakeDuration = 100;
			var originalX = game.x;
			var originalY = game.y;
			var shakeInterval = LK.setInterval(function () {
				game.x = originalX + (Math.random() - 0.5) * shakeAmplitude;
				game.y = originalY + (Math.random() - 0.5) * shakeAmplitude;
			}, shakeDuration);
			LK.effects.flashScreen(0xffffff, 5000); // Flash screen for 5 seconds
			// Instantiate objrush in the center of the playspace for 3 seconds with fade in and fade out effect
			var objRush = LK.getAsset('objRush', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			objRush.x = game.width / 2;
			objRush.y = game.height / 2;
			objRush.alpha = 0; // Start with alpha 0 for fade in effect
			game.addChild(objRush);
			// Fade in effect
			var fadeInInterval = LK.setInterval(function () {
				objRush.alpha += 0.05;
				if (objRush.alpha >= 1) {
					LK.clearInterval(fadeInInterval);
					// Start fade out effect after 3 seconds
					LK.setTimeout(function () {
						var fadeOutInterval = LK.setInterval(function () {
							objRush.alpha -= 0.05;
							if (objRush.alpha <= 0) {
								LK.clearInterval(fadeOutInterval);
								objRush.destroy();
							}
						}, 50); // Approximately 20 FPS
					}, 3000);
				}
			}, 50); // Approximately 20 FPS
			LK.setTimeout(function () {
				distanceTraveledIncrement = originalIncrement;
				parallax.speed = originalParallaxSpeed;
				LK.clearInterval(shakeInterval);
				game.x = originalX;
				game.y = originalY;
			}, 5000); // Reset to normal after 5 seconds
		}
		if (!self.honkPlayed) {
			self.honkPlayed = true;
			LK.setTimeout(function () {
				LK.getSound('snd_carhonk').play();
			}, 500);
		}
		// Check for collision with hero or heroGround
		if (self.intersects(hero) || self.intersects(heroGround)) {
			LK.effects.flashScreen(0xff0000, 1000);
			LK.showGameOver();
		}
	};
});
var ObjData = Container.expand(function () {
	var self = Container.call(this);
	var objDataGraphics = self.attachAsset('objData', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// No speed property to ensure ObjData objects are static
	self._move_migrated = function () {
		self.y += Math.sin(LK.ticks / 10) * 2; // Add hover effect
	};
});
var ObjDrone = Container.expand(function () {
	var self = Container.call(this);
	var objDroneGraphics = self.attachAsset('objDrone', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.erraticMovementInterval = LK.setInterval(function () {
		self.x += (Math.random() - 0.5) * 10;
		self.y += (Math.random() - 0.5) * 10;
	}, 100);
	self.relocationInterval = LK.setInterval(function () {
		var targetX = game.width / 2 + Math.random() * (game.width / 2);
		var targetY = Math.random() * game.height;
		var moveSpeed = 25; // Adjust this value to control the movement speed
		var moveInterval = LK.setInterval(function () {
			var dx = targetX - self.x;
			var dy = targetY - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < moveSpeed) {
				self.x = targetX;
				self.y = targetY;
				LK.clearInterval(moveInterval);
			} else {
				self.x += dx / distance * moveSpeed;
				self.y += dy / distance * moveSpeed;
			}
		}, 16); // Approximately 60 FPS
	}, 2000);
	self.countdownStarted = false;
	self.on('destroy', function () {
		LK.clearInterval(self.erraticMovementInterval);
		LK.clearInterval(self.relocationInterval);
		LK.clearInterval(catchTimerInterval);
		game.removeChild(catchTimerTxt);
	});
});
var ObjEvents = Container.expand(function () {
	var self = Container.call(this);
	var objEventsGraphics = self.attachAsset('objEvents', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -4 - Math.random() * 3;
	self._move_migrated = function () {
		self.x += self.speed;
		if (self.x < -self.width) {
			self.x = game.width + self.width;
			self.y = game.height - heroGround.height / 2 - 50;
		}
		if (eventTxt && eventTxt.text === 'Event: None') {
			self.x = game.width + self.width;
			self.y = game.height - heroGround.height / 2 - 50;
		}
	};
});
var ObjGO = Container.expand(function () {
	var self = Container.call(this);
	var objGOGraphics = self.attachAsset('objGO', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -4 - Math.random() * 3;
	self.spawnTime = LK.ticks;
	self._move_migrated = function () {
		self.x += self.speed;
		if (self.x < -self.width) {
			self.x = game.width;
			var minY = 400;
			var maxY = game.height / 2 + 200;
			self.y = minY + Math.random() * (maxY - minY);
			return;
			return;
			return;
		}
		// Add hover effect
		self.y += Math.sin(LK.ticks / 10) * 2;
	};
});
var ObjJUMP = Container.expand(function () {
	var self = Container.call(this);
	var objJUMPGraphics = self.attachAsset('objJUMP', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -4 - Math.random() * 3;
	self._move_migrated = function () {
		self.x += self.speed;
		if (self.x < -self.width) {
			self.x = game.width;
			var heroYMin = Math.max(hero.y - hero.height / 2, 0);
			var heroYMax = Math.min(hero.y + hero.height / 2, game.height);
			self.y = heroYMin + Math.random() * (heroYMax - heroYMin);
		}
		// Add hover effect
		self.y += Math.sin(LK.ticks / 10) * 2;
	};
});
var ObjLaser = Container.expand(function () {
	var self = Container.call(this);
	var laserGraphics = self.attachAsset('objlaser', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.update = function () {
		// Check for collision with hero
		if (self.intersects(hero)) {
			LK.effects.flashScreen(0xff0000, 1000); // Flash screen red for 1 second
			LK.showGameOver(); // Trigger game over
		}
	};
});
var ObjRALLY = Container.expand(function () {
	var self = Container.call(this);
	var objRALLYGraphics = self.attachAsset('objRALLY', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -5;
	self._move_migrated = function () {
		self.x += self.speed;
		if (self.x < -self.width) {
			self.x = game.width;
			var heroYMin = Math.max(hero.y - hero.height / 2, 0);
			var heroYMax = Math.min(hero.y + hero.height / 2, game.height);
			self.y = heroYMin + Math.random() * (heroYMax - heroYMin);
		}
		// Add hover effect
		self.y += Math.sin(LK.ticks / 10) * 2;
	};
});
var ObjSPIKEY = Container.expand(function () {
	var self = Container.call(this);
	var objSPIKEYGraphics = self.attachAsset('objspikey', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -4 - Math.random() * 3;
	self.spawnTime = LK.ticks;
	self.collisionObject = self.addChild(new ObjSPIKEYCollision());
	self.collisionObject.x = 0;
	self.collisionObject.y = 0;
	self._move_migrated = function () {
		self.x += self.speed;
		if (self.x < -self.width) {
			self.x = game.width;
			var minY = 400;
			var maxY = game.height / 2 + 200;
			self.y = minY + Math.random() * (maxY - minY);
		}
		// Add hover effect
		self.y += Math.sin(LK.ticks / 10) * 2;
		// Add rotation effect
		self.rotation -= 0.05;
		// Add scaling effect
		var scaleFactor = 0.85 + Math.abs(Math.sin(LK.ticks / 60) * 0.25); // Scale between 0.85 and 1.10
		self.scale.set(scaleFactor);
		if (self.collisionObject.intersects(hero)) {
			if (hero.isDashing) {
				var explosion = new ParticleExplosion(self.x, self.y);
				game.addChild(explosion);
				self.destroy();
			} else {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
			}
		} else if (self.collisionObject.intersects(heroGround)) {
			if (isHeroGroundMoving) {
				var explosion = new ParticleExplosion(self.x, self.y);
				game.addChild(explosion);
				self.destroy();
			} else {
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
			}
		}
	};
});
var ObjSPIKEYCollision = Container.expand(function () {
	var self = Container.call(this);
	var collisionGraphics = self.attachAsset('smallCircle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	collisionGraphics.width = 50; // Adjust the width to further reduce collision size
	collisionGraphics.height = 50; // Adjust the height to further reduce collision size
	collisionGraphics.alpha = 0; // Set alpha to 0
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -5;
	self._move_migrated = function () {
		self.x += self.speed;
		if (self.x < -self.width) {
			self.x = game.width;
			var heroYMin = Math.max(hero.y - hero.height / 2, 0);
			var heroYMax = Math.min(hero.y + hero.height / 2, game.height);
			self.y = heroYMin + Math.random() * (heroYMax - heroYMin);
		}
	};
});
var Parallax = Container.expand(function () {
	var self = Container.call(this);
	var bgGraphics = self.attachAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bgGraphics.x = game.width / 2;
	bgGraphics.y = game.height - bgGraphics.height / 2;
	self.speed = -3;
	self._move_migrated = function () {
		bgGraphics.x += self.speed;
		if (!self.bgGraphics2) {
			self.bgGraphics2 = self.attachAsset('background', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			self.bgGraphics2.x = bgGraphics.x + bgGraphics.width;
			self.bgGraphics2.y = game.height - self.bgGraphics2.height / 2;
			self.addChildAt(self.bgGraphics2, 1); // Ensure bgGraphics2 is behind bgGraphics
		}
		self.bgGraphics2.x += self.speed;
		if (bgGraphics.x <= -bgGraphics.width / 2) {
			bgGraphics.x = self.bgGraphics2.x + bgGraphics.width;
		}
		if (self.bgGraphics2.x <= -self.bgGraphics2.width / 2) {
			self.bgGraphics2.x = bgGraphics.x + bgGraphics.width;
		}
	};
});
// Call the function every 15 seconds;
var ParallaxCity = Container.expand(function () {
	var self = Container.call(this);
	var cityGraphics = self.attachAsset('objcity', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	cityGraphics.x = game.width / 2;
	cityGraphics.y = game.height / 2;
	self.speed = -3;
	self._move_migrated = function () {
		cityGraphics.x += self.speed;
		if (!self.cityGraphics2) {
			self.cityGraphics2 = self.attachAsset('objcity', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			self.cityGraphics2.x = cityGraphics.x + cityGraphics.width;
			self.cityGraphics2.y = game.height / 2;
			self.addChildAt(self.cityGraphics2, 1); // Ensure cityGraphics2 is behind cityGraphics
		}
		self.cityGraphics2.x += self.speed;
		if (cityGraphics.x <= -cityGraphics.width / 2) {
			cityGraphics.x = self.cityGraphics2.x + cityGraphics.width;
		}
		if (self.cityGraphics2.x <= -self.cityGraphics2.width / 2) {
			self.cityGraphics2.x = cityGraphics.x + cityGraphics.width;
		}
	};
});
var Particle = Container.expand(function () {
	var self = Container.call(this);
	var particleGraphics = self.attachAsset('particle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var neonColors = [0x39ff14, 0xff073a, 0x00ffff, 0xffff00, 0xff00ff];
	particleGraphics.tint = neonColors[Math.floor(Math.random() * neonColors.length)];
	self.alpha = 1.0;
	self.fadeOut = function () {
		self.alpha -= 0.05;
		if (self.alpha <= 0) {
			if (self) {
				self.destroy();
			}
		}
	};
});
var Particle2 = Container.expand(function () {
	var self = Container.call(this);
	var particleGraphics = self.attachAsset('particle2', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var neonColors = [0x39ff14, 0xff073a, 0x00ffff, 0xffff00, 0xff00ff];
	particleGraphics.tint = neonColors[Math.floor(Math.random() * neonColors.length)];
	self.alpha = 1.0;
	self.fadeOut = function () {
		self.alpha -= 0.05;
		if (self.alpha <= 0) {
			if (self) {
				self.destroy();
			}
		}
	};
});
var ParticleExplosion = Container.expand(function (x, y) {
	var self = Container.call(this);
	var particles = [];
	var particleCount = 20;
	var speedRange = 20; // Further increased speed range for more exaggerated movement
	var neonColors = [0x39ff14, 0xff073a, 0x00ffff, 0xffff00, 0xff00ff];
	for (var i = 0; i < particleCount; i++) {
		var particle = new Particle2();
		particle.x = x;
		particle.y = y;
		particle.vx = (Math.random() - 0.5) * speedRange;
		particle.vy = (Math.random() - 0.5) * speedRange;
		particle.rotationSpeed = (Math.random() - 0.5) * 0.2; // Further increased rotation speed for more exaggerated movement
		particle.tint = neonColors[Math.floor(Math.random() * neonColors.length)];
		particles.push(particle);
		self.addChild(particle);
	}
	self.update = function () {
		for (var i = particles.length - 1; i >= 0; i--) {
			particles[i].x += particles[i].vx;
			particles[i].y += particles[i].vy;
			particles[i].rotation += particles[i].rotationSpeed; // Apply rotation
			particles[i].alpha -= 0.02;
			if (particles[i].alpha <= 0) {
				if (particles[i]) {
					particles[i].destroy();
					particles.splice(i, 1);
				}
			}
		}
		if (particles.length === 0) {
			self.destroy();
		}
	};
});
var objLaser = Container.expand(function () {
	var self = Container.call(this);
	var laserGraphics = self.attachAsset('objlaser', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.update = function () {
		// Check for collision with hero
		if (self.intersects(hero)) {
			LK.effects.flashScreen(0xff0000, 1000); // Flash screen red for 1 second
			LK.showGameOver(); // Trigger game over
		}
	};
	game.addChild(self); // Ensure objLaser is added to the game
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
var collectCounterTxt = new Text2('0' + "/10", {
	size: 75,
	fill: "#add8e6",
	// Light blue color
	stroke: "#000000",
	strokeThickness: 2,
	fontWeight: 'bolder'
});
collectCounterTxt.anchor.set(0.5, 0);
collectCounterTxt.x = game.width - 300;
collectCounterTxt.y = 100;
var collectTimerTxt = new Text2('20.0', {
	size: 75,
	fill: "#ffcccb",
	// Pink color
	stroke: "#000000",
	strokeThickness: 2,
	fontWeight: 'bolder' // Make the text bolder
});
collectTimerTxt.anchor.set(0.5, 0);
collectTimerTxt.x = game.width / 2;
collectTimerTxt.y = 100;
var collectTimer = 20.0;
var collectTimerInterval;
var randomEvent = "";
var catchTimer = 15.0;
var catchTimerTxt = new Text2(catchTimer.toString(), {
	size: 75,
	fill: "#ffcccb",
	// Pink color
	stroke: "#000000",
	strokeThickness: 2,
	fontWeight: 'bolder'
});
catchTimerTxt.anchor.set(0.5, 0);
catchTimerTxt.x = game.width / 2;
catchTimerTxt.y = 100;
var catchTimerInterval;
var objDataCounter = 0;
var objWindup = null;
var objWindup = null;
var objDataArray = [];
var isEventOngoing = false;
var generateObjEvents = function generateObjEvents() {
	if (isEventOngoing || obstacles.some(function (obstacle) {
		return obstacle instanceof ObjEvents;
	})) {
		return;
	}
	LK.setTimeout(function () {
		var objEvents = new ObjEvents();
		objEvents.x = game.width + objEvents.width;
		objEvents.y = game.height - heroGround.height / 2 - 50;
		obstacles.push(objEvents);
		game.addChild(objEvents);
	}, 500 + Math.random() * 2000);
};
var objSPIKEYGenerationInterval = LK.setInterval(generateObjSPIKEY, 8000);
var generateObjACCELERATE = function generateObjACCELERATE() {
	if (obstacles.filter(function (obstacle) {
		return obstacle instanceof ObjACCELERATE;
	}).length >= 1) {
		return;
	}
	// Removed minimum delay of 60 ticks for ObjACCELERATE spawning
	LK.setTimeout(function () {
		var objACCELERATE = new ObjACCELERATE();
		objACCELERATE.x = game.width;
		var minY = 300; // Top boundary
		var maxY = game.height / 2; // Adjusted bottom boundary to avoid spawning near the bottom of the playspace
		objACCELERATE.y = minY + Math.random() * (maxY - minY);
		// Ensure objACCELERATE does not spawn too close to other objects
		for (var i = 0; i < obstacles.length; i++) {
			if (Math.abs(obstacles[i].x - objACCELERATE.x) < 600) {
				objACCELERATE.x = obstacles[i].x + 600;
			}
		}
		obstacles.push(objACCELERATE);
		game.addChild(objACCELERATE);
	}, 500 + Math.random() * 2000);
};
var isHeroGroundAttached = false;
var isHeroGroundMoving = false;
var collisionCounter = 0; // Initialize the collision counter
var brother = function brother() {
	if (isHeroGroundAttached || isHeroGroundMoving) {
		return;
	}
	isHeroGroundAttached = true;
	heroGround.x = hero.x;
	heroGround.y = hero.y + hero.height / 2 + heroGround.height / 2;
	var originalX = heroGround.x;
	var originalY = heroGround.y;
	var attachInterval = LK.setInterval(function () {
		heroGround.x = hero.x;
		heroGround.y = hero.y + hero.height / 2 + heroGround.height / 2 - 125;
	}, 16); // Update position every frame (approximately 60 FPS)
	LK.setTimeout(function () {
		LK.clearInterval(attachInterval);
		heroGround.x = hero.x;
		heroGround.y = game.height - heroGround.height / 2 - 50;
		isHeroGroundAttached = false;
	}, 5000); // Detach after 5 seconds
};
// Function to handle collision and update the counter
function handleCollisionWithObj() {
	collisionCounter += 1;
	console.log("handleCollisionWithObj called, collisionCounter:", collisionCounter);
	if (collisionCounter >= 1) {
		destroyAllObjs();
		isEventOngoing = true;
	}
}
function generateObjData() {
	LK.setTimeout(function () {
		for (var i = 0; i < 10; i++) {
			(function (index) {
				LK.setTimeout(function () {
					var objData = new ObjData();
					var minX = 300;
					var maxX = game.width - 300;
					objData.x = minX + Math.random() * (maxX - minX); // Ensure ObjData objects are instantiated within the playspace with a 300-pixel boundary
					var minY = 300;
					var maxY = game.height - 300; // Ensure objData spawns within the vertical boundaries with a 300-pixel boundary
					objData.y = minY + Math.random() * (maxY - minY);
					objData.y = minY + Math.random() * (maxY - minY);
					objDataArray.push(objData);
					game.addChild(objData); // Ensure ObjData objects are instantiated on the correct layer
				}, index * 300); // Spread instantiation over 3 seconds
			})(i);
		}
	}, 1000); // Delay instantiation by 1 second
}
// Function to destroy all instances of ObjGO, ObjRALLY, and ObjJUMP
function destroyAllObjs() {
	for (var i = obstacles.length - 1; i >= 0; i--) {
		if (obstacles[i] instanceof ObjGO || obstacles[i] instanceof ObjRALLY || obstacles[i] instanceof ObjJUMP || obstacles[i] instanceof ObjACCELERATE) {
			if (obstacles[i]) {
				var explosion = new ParticleExplosion(obstacles[i].x, obstacles[i].y);
				game.addChild(explosion);
				obstacles[i].destroy();
				obstacles.splice(i, 1);
			}
		}
	}
}
var generateObjJUMP = function generateObjJUMP() {
	if (obstacles.filter(function (obstacle) {
		return obstacle instanceof ObjJUMP;
	}).length >= 2) {
		return;
	}
	// Add delay to avoid two ObjJUMP spawning on top of each other
	// Removed minimum delay of 60 ticks for ObjGO spawning
	LK.setTimeout(function () {
		var objJUMP = new ObjJUMP();
		objJUMP.x = game.width;
		var minY = 300; // Top boundary
		var maxY = game.height / 2; // Adjusted bottom boundary to avoid spawning near the bottom of the playspace
		objJUMP.y = minY + Math.random() * (maxY - minY);
		// Ensure objJUMP does not spawn too close to other objects
		for (var i = 0; i < obstacles.length; i++) {
			if (Math.abs(obstacles[i].x - objJUMP.x) < 600) {
				objJUMP.x = obstacles[i].x + 600;
			}
		}
		obstacles.push(objJUMP);
		game.addChild(objJUMP);
	}, 500 + Math.random() * 2000);
};
function startBootSequence() {
	var bootTexts = ['Work together to...', 'clear events and...', 'reach the furthest distance...'];
	var currentBootTextIndex = 0;
	var bootTextY = game.height / 2 - 250;
	var displayBootText = function displayBootText() {
		var bootText = new BootText(bootTexts[currentBootTextIndex]);
		bootText.x = game.width / 2 + 50;
		bootText.y = bootTextY + currentBootTextIndex * 150;
		game.addChild(bootText);
		var fadeInInterval = LK.setInterval(function () {
			bootText.fadeIn();
			if (bootText.alpha === 1) {
				LK.setTimeout(function () {
					bootText.fadeOut();
					LK.setTimeout(function () {
						var help2 = LK.getAsset('obj_help2', {
							anchorX: 0.5,
							anchorY: 0.5
						});
						help2.x = game.width / 2;
						help2.y = game.height / 2 - 100;
						game.addChild(help2);
						var help = LK.getAsset('obj_help1', {
							anchorX: 0.5,
							anchorY: 0.5
						});
						help.x = game.width / 2;
						help.y = game.height / 2 + 100;
						game.addChild(help);
						LK.setTimeout(function () {
							help2.destroy();
							help.destroy();
						}, 8000);
					}, 3000);
				}, 300);
			}
		}, 60);
		bootText.on('destroy', function () {
			LK.clearInterval(fadeInInterval);
		});
		currentBootTextIndex++;
		if (currentBootTextIndex < bootTexts.length) {
			LK.setTimeout(displayBootText, 1000);
		} else {
			// Instantiate help2 and help after boottext
		}
	};
	displayBootText();
}
var eventTxt = null;
activeMovingSpeechBubble = null, enemies = [], obstacles = [], parallax = null, score = 0, distanceTraveled = 0, distanceTraveledIncrement = 1 / 60, isGameOver = false, gameStarted = false;
var generateObstacle = function generateObstacle() {
	if (obstacles.filter(function (obstacle) {
		return obstacle instanceof Obstacle;
	}).length >= 1) {
		return;
	}
	// Add delay to avoid two Obstacle spawning on top of each other
	// Removed minimum delay of 60 ticks for ObjRALLY spawning
	LK.setTimeout(function () {
		var obstacle = new Obstacle();
		obstacle.x = game.width;
		var minY = 400; // Minimum Y position
		var maxY = game.height / 2 + 200; // Maximum Y position
		if (hero.x >= 0 && hero.x <= game.width) {
			var heroYMin = Math.max(hero.y - hero.height / 2, minY); // Ensure obstacle spawns within the top boundary of the hero
			var heroYMax = Math.min(hero.y + hero.height / 2, maxY); // Ensure obstacle spawns within the bottom boundary of the hero
			var randomOffset = (Math.random() - 0.5) * hero.height * 2; // Augmented random offset within 2 times the hero's height
			obstacle.y = hero.y + randomOffset;
			// Ensure obstacle stays within the game boundaries
			var obstacleHalfHeight = obstacle.height / 2;
			obstacle.y = Math.max(obstacleHalfHeight, Math.min(game.height - obstacleHalfHeight, obstacle.y));
		} else {
			obstacle.y = minY + Math.random() * (maxY - minY); // Spawn obstacle anywhere within the boundaries if hero is off screen
		}
		obstacles.push(obstacle);
		game.addChild(obstacle);
	}, 500 + Math.random() * 2000);
};
var generateObjGO = function generateObjGO() {
	if (obstacles.filter(function (obstacle) {
		return obstacle instanceof ObjGO;
	}).length >= 1) {
		return;
	}
	// Add delay to avoid two ObjGO spawning on top of each other
	// Removed minimum delay of 60 ticks for ObjJUMP spawning
	LK.setTimeout(function () {
		var objGO = new ObjGO();
		objGO.x = game.width;
		var minY = 300; // Top boundary
		var maxY = game.height / 2; // Adjusted bottom boundary to avoid spawning near the bottom of the playspace
		objGO.y = minY + Math.random() * (maxY - minY);
		// Ensure objGO does not spawn too close to other objects
		for (var i = 0; i < obstacles.length; i++) {
			if (Math.abs(obstacles[i].x - objGO.x) < 600) {
				objGO.x = obstacles[i].x + 600;
			}
		}
		obstacles.push(objGO);
		game.addChild(objGO);
	}, 500 + Math.random() * 2000);
};
var generateObjRALLY = function generateObjRALLY() {
	if (obstacles.filter(function (obstacle) {
		return obstacle instanceof ObjRALLY;
	}).length >= 1) {
		return;
	}
	// Add delay to avoid two ObjRALLY spawning on top of each other
	if (obstacles.length > 0) {
		var lastObstacle = obstacles[obstacles.length - 1];
		if (LK.ticks - lastObstacle.spawnTime < 60) {
			return;
		}
	}
	LK.setTimeout(function () {
		var objRALLY = new ObjRALLY();
		objRALLY.x = game.width;
		var minY = 300; // Top boundary
		var maxY = game.height / 2; // Adjusted bottom boundary to avoid spawning near the bottom of the playspace
		objRALLY.y = minY + Math.random() * (maxY - minY);
		// Ensure objRALLY does not spawn too close to other objects
		for (var i = 0; i < obstacles.length; i++) {
			if (Math.abs(obstacles[i].x - objRALLY.x) < 600) {
				objRALLY.x = obstacles[i].x + 600;
			}
		}
		obstacles.push(objRALLY);
		game.addChild(objRALLY);
	}, 500 + Math.random() * 2000);
};
var obstacleGenerationInterval;
function startObstacleGeneration() {
	obstacleGenerationInterval = LK.setInterval(generateObstacle, 2000);
	var objGOGenerationInterval = LK.setInterval(generateObjGO, 1500);
	var objRALLYGenerationInterval = LK.setInterval(generateObjRALLY, 2000);
	var objACCELERATEGenerationInterval = LK.setInterval(generateObjACCELERATE, 8000);
	var objJUMPGenerationInterval = LK.setInterval(generateObjJUMP, 2000);
	var objEventsGenerationInterval = LK.setInterval(generateObjEvents, 10000);
	var generateObjSPIKEY = function generateObjSPIKEY() {
		if (obstacles.filter(function (obstacle) {
			return obstacle instanceof ObjSPIKEY;
		}).length >= 1) {
			return;
		}
		LK.setTimeout(function () {
			var objSPIKEY = new ObjSPIKEY();
			objSPIKEY.x = game.width;
			var spawnChance = Math.random();
			if (spawnChance < 0.75) {
				// 75% chance to spawn on the y and x Axis of hero, but outside the playspace
				objSPIKEY.x = game.width + objSPIKEY.width;
				objSPIKEY.y = hero.y;
			} else {
				// 25% chance to spawn on hero ground, but outside the playspace
				objSPIKEY.x = game.width + objSPIKEY.width;
				objSPIKEY.y = heroGround.y;
			}
			// Ensure objSPIKEY does not spawn too close to other objects
			for (var i = 0; i < obstacles.length; i++) {
				if (Math.abs(obstacles[i].x - objSPIKEY.x) < 600) {
					objSPIKEY.x = obstacles[i].x + 600;
				}
				if (Math.abs(obstacles[i].y - objSPIKEY.y) < 600) {
					objSPIKEY.y = Math.random() < 0.5 ? obstacles[i].y - 600 : obstacles[i].y + 600;
				}
			}
			obstacles.push(objSPIKEY);
			game.addChild(objSPIKEY);
		}, 500 + Math.random() * 2000);
	};
	LK.on('gameOver', function () {
		LK.clearInterval(collectTimerInterval);
		game.removeChild(collectTimerTxt);
		LK.clearInterval(catchTimerInterval);
		game.removeChild(catchTimerTxt);
		LK.clearInterval(objJUMPGenerationInterval);
		LK.clearInterval(obstacleGenerationInterval);
		LK.clearInterval(objGOGenerationInterval);
		LK.clearInterval(objRALLYGenerationInterval);
		LK.clearInterval(objJUMPGenerationInterval);
		LK.clearInterval(objACCELERATEGenerationInterval);
		LK.clearInterval(objEventsGenerationInterval);
		LK.clearInterval(objSPIKEYGenerationInterval);
		isEventOngoing = false;
	});
}
parallax = game.addChild(new Parallax());
var originalParallaxSpeed = parallax.speed;
var parallaxSpeedIncrement = 0.05; // Speed increment per second
var parallaxSpeedUpdateInterval = 500; // Update interval in milliseconds
LK.setInterval(function () {
	parallax.speed -= parallaxSpeedIncrement;
}, parallaxSpeedUpdateInterval);
var distanceTxt;
function initializeScoreDisplay() {
	// Remove BootText from the screen
	var bootTexts = game.children.filter(function (child) {
		return child instanceof BootText;
	});
	for (var i = 0; i < bootTexts.length; i++) {
		bootTexts[i].destroy();
	}
	// Initialize score display
	distanceTxt = new Text2('Distance: 0', {
		size: 75,
		fill: "#ffffff",
		stroke: "#ffffff",
		strokeThickness: 2,
		fontWeight: 'bolder' // Make the text bolder
	});
	distanceTxt.anchor.set(0.5, 0);
	distanceTxt.x = game.width / 2; // Center the distance text horizontally
	game.addChild(distanceTxt);
	// Add event text display in the upper right corner
	eventTxt = new Text2('Event: None', {
		size: 75,
		fill: "#ffffff",
		stroke: "#ffffff",
		strokeThickness: 2,
		fontWeight: 'bolder' // Make the text bolder
	});
	eventTxt.anchor.set(1, 0); // Anchor to the top right corner
	eventTxt.x = game.width - 50; // Position it 50 pixels from the right edge
	eventTxt.y = distanceTxt.y; // Align it with the distance text
	game.addChild(eventTxt);
}
hero = game.addChild(new Hero());
var heroGround = game.addChild(new Hero_Ground());
var objGroundTrail = LK.getAsset('objGroundTrail', {
	anchorX: 0.5,
	anchorY: 0.5
});
heroGround.addChildAt(objGroundTrail, 0);
objGroundTrail.rotation = -Math.PI / 4; // Rotate 45 degrees to the left
objGroundTrail.x = heroGround.width / 2 - 200;
objGroundTrail.y = heroGround.height / 2 - 125;
// Add shake effect to objGroundTrail
var shakeAmplitude = 5; // Amplitude of the shake
var shakeDuration = 100; // Duration of each shake in milliseconds
var originalX = objGroundTrail.x;
var originalY = objGroundTrail.y;
var shakeInterval = LK.setInterval(function () {
	objGroundTrail.x = originalX + (Math.random() - 0.5) * shakeAmplitude;
	objGroundTrail.y = originalY + (Math.random() - 0.5) * shakeAmplitude;
}, shakeDuration);
heroGround.idleSpeechBubble = LK.getAsset('idleSpeechBubble', {
	anchorX: 0.5,
	anchorY: 0.5
});
heroGround.addChild(heroGround.idleSpeechBubble);
heroGround.idleSpeechBubble.x = heroGround.width / 2 + 20;
heroGround.idleSpeechBubble.y = -heroGround.idleSpeechBubble.height / 2 - 125;
heroGround.initialX = hero.x + 175;
heroGround.x = -heroGround.width;
heroGround.y = game.height - heroGround.height / 2 - 50;
hero.x = -100;
hero.y = -100;
startBootSequence();
// Instantiate help2 and help when the game starts
var help2 = LK.getAsset('obj_help2', {
	anchorX: 0.5,
	anchorY: 0.5
});
help2.x = game.width / 2 - 350;
help2.y = game.height / 2 + 700;
game.addChild(help2);
var help = LK.getAsset('obj_help1', {
	anchorX: 0.5,
	anchorY: 0.5
});
help.x = game.width / 2 + 450;
help.y = game.height / 2 + 700;
game.addChild(help);
LK.setTimeout(function () {
	help2.destroy();
	help.destroy();
}, 5375);
LK.playMusic('SynthwaveMusic', {
	loop: true
});
LK.setTimeout(function () {
	heroGround.moveToInitialPosition();
}, 3000); // Start animation after 3 seconds
// Play snd_announcer sound 5 second after the game starts
LK.setTimeout(function () {
	LK.getSound('snd_announcer').play();
}, 5000);
LK.on('tick', function () {
	if (!gameStarted) {
		hero.animateToPosition();
		return; // Skip the rest of the game logic until the animation is complete
	}
	parallax._move_migrated();
	// Ensure objwindup update method is called every tick
	if (objWindup && typeof objWindup.update === 'function') {
		objWindup.update();
	}
	if (objLaser && typeof objLaser.update === 'function') {
		objLaser.update();
	}
	parallaxCity._move_migrated();
	if (hero.visible) {
		hero._move_migrated();
	} else if (heroGround.visible) {
		heroGround._move_migrated();
	}
	for (var i = 0; i < enemies.length; i++) {
		enemies[i]._move_migrated();
	}
	for (var i = obstacles.length - 1; i >= 0; i--) {
		if (obstacles[i] && typeof obstacles[i]._move_migrated === 'function') {
			obstacles[i]._move_migrated();
		}
		if (obstacles[i] instanceof ObjDrone || obstacles[i] instanceof ObjCar) {
			obstacles[i].update();
		}
		if (obstacles[i] instanceof ObjEvents && heroGround.intersects(obstacles[i])) {
			console.log("heroGround intersected with ObjEvents at position:", {
				x: obstacles[i].x,
				y: obstacles[i].y
			});
			var explosion = new ParticleExplosion(obstacles[i].x, obstacles[i].y);
			game.addChild(explosion);
			LK.getSound('snd_walkie').play(); // Play snd_walkie sound
			obstacles[i].destroy();
			obstacles.splice(i, 1);
			handleCollisionWithObj();
			// Ensure event text is displayed
			var events = distanceTraveled <= 200 ? ['Avoid', 'Collect'] : ['Catch', 'Survive'];
			//set the random event 
			randomEvent = "Survive";
			//randomEvent = events[Math.floor(Math.random() * events.length)];
			//set the event text once an event type has been selected.
			eventTxt.setText('Event: ' + randomEvent);
			console.log("Random event selected:", randomEvent);
			if (randomEvent === 'Collect') {
				collectTimer = 20;
				var checkObjDataActive = LK.setInterval(function () {
					if (objDataArray.length > 0) {
						collectTimerTxt.setText(collectTimer.toString());
						game.addChild(collectTimerTxt);
						collectTimerInterval = LK.setInterval(function () {
							collectTimer -= 0.1;
							collectTimerTxt.setText(collectTimer.toFixed(1).toString());
							if (collectTimer <= 0) {
								LK.clearInterval(collectTimerInterval);
								LK.effects.flashScreen(0xff0000, 1000);
								LK.showGameOver();
							}
						}, 100);
						LK.clearInterval(checkObjDataActive);
					}
				}, 100);
				// Add text that says "Collect the data before the time runs out!"
				var objCollectSign = LK.getAsset('objcollectsign', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				objCollectSign.x = game.width / 2;
				objCollectSign.y = game.height / 2; // Center the sign vertically
				objCollectSign.alpha = 0; // Start with alpha 0 for fade in effect
				game.addChild(objCollectSign);
				// Fade in effect
				var fadeInInterval = LK.setInterval(function () {
					objCollectSign.alpha += 0.05;
					if (objCollectSign.alpha >= 1) {
						LK.clearInterval(fadeInInterval);
						// Start fade out effect after 2 seconds
						LK.setTimeout(function () {
							var fadeOutInterval = LK.setInterval(function () {
								objCollectSign.alpha -= 0.05;
								if (objCollectSign.alpha <= 0) {
									LK.clearInterval(fadeOutInterval);
									objCollectSign.destroy();
									generateObjData(); // Start spawning objdata after fade out
								}
							}, 60);
						}, 2000);
					}
				}, 60);
				var checkObjDataActiveForCounter = LK.setInterval(function () {
					if (objDataArray.length > 0) {
						game.addChild(collectCounterTxt);
						LK.clearInterval(checkObjDataActiveForCounter);
					}
				}, 100);
			} else if (randomEvent === 'Avoid') {
				// Instantiate objcarsign in the center of the playspace
				var objCarSign = LK.getAsset('objcarsign', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				objCarSign.x = game.width / 2;
				objCarSign.y = game.height / 2;
				objCarSign.alpha = 0; // Start with alpha 0 for fade in effect
				game.addChild(objCarSign);
				// Fade in effect
				var fadeInInterval = LK.setInterval(function () {
					objCarSign.alpha += 0.05;
					if (objCarSign.alpha >= 1) {
						LK.clearInterval(fadeInInterval);
						// Start fade out effect after 2 seconds
						LK.setTimeout(function () {
							var fadeOutInterval = LK.setInterval(function () {
								objCarSign.alpha -= 0.05;
								if (objCarSign.alpha <= 0) {
									LK.clearInterval(fadeOutInterval);
									objCarSign.destroy();
									// Randomly select a position for objheadlights
									var positions = [{
										x: game.width - 100,
										y: 800
									},
									// Upper right
									{
										x: game.width - 100,
										y: game.height - 400
									} // Bottom right
									];
									var randomPosition = positions[Math.floor(Math.random() * positions.length)];
									// Instantiate objheadlights at the selected position
									var objHeadlights = LK.getAsset('objheadlights', {
										anchorX: 0.5,
										anchorY: 0.5
									});
									objHeadlights.x = randomPosition.x;
									objHeadlights.y = randomPosition.y;
									objHeadlights.alpha = 0; // Start with alpha 0 for fade in effect
									game.addChild(objHeadlights);
									// Fade in effect
									var fadeInInterval = LK.setInterval(function () {
										objHeadlights.alpha += 0.05;
										if (objHeadlights.alpha >= 1) {
											LK.clearInterval(fadeInInterval);
											// Start fade out effect after 2 seconds
											LK.setTimeout(function () {
												var fadeOutInterval = LK.setInterval(function () {
													objHeadlights.alpha -= 0.05;
													if (objHeadlights.alpha <= 0) {
														LK.clearInterval(fadeOutInterval);
														objHeadlights.destroy();
														// Instantiate objcar at the same position as objheadlights
														var objCar = new ObjCar();
														objCar.x = objHeadlights.x;
														objCar.y = objHeadlights.y;
														game.addChild(objCar);
													}
												}, 60); // Approximately 16.67 FPS
											}, 2000);
										}
									}, 60); // Approximately 16.67 FPS
								}
							}, 60); // Approximately 16.67 FPS
						}, 2000);
					}
				}, 60); // Approximately 16.67 FPS
			}
			//catch event
			else if (randomEvent === 'Catch') {
				// Instantiate the banner in the center of the playspace
				var objCatch = LK.getAsset('objCatch', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				objCatch.x = game.width / 2;
				objCatch.y = game.height / 2;
				objCatch.alpha = 0; // Start with alpha 0 for fade in effect
				game.addChild(objCatch);
				// Fade in effect
				var fadeInInterval = LK.setInterval(function () {
					objCatch.alpha += 0.05;
					if (objCatch.alpha >= 1) {
						LK.clearInterval(fadeInInterval);
						// Start fade out effect after 2 seconds
						LK.setTimeout(function () {
							var fadeOutInterval = LK.setInterval(function () {
								objCatch.alpha -= 0.05;
								if (objCatch.alpha <= 0) {
									LK.clearInterval(fadeOutInterval);
									objCatch.destroy();
								}
							}, 50); // Approximately 20 FPS
						}, 2000);
					}
				}, 50); // Approximately 20 FPS
				//set the timer
				catchTimer = 15.0;
				catchTimerTxt.setText(catchTimer.toString());
				game.addChild(catchTimerTxt);
				LK.setTimeout(function () {
					catchTimerInterval = LK.setInterval(function () {
						catchTimer -= 0.1;
						catchTimerTxt.setText(catchTimer.toFixed(1).toString());
						if (catchTimer <= 0) {
							LK.clearInterval(catchTimerInterval);
							LK.effects.flashScreen(0xff0000, 1000);
							LK.showGameOver();
						}
					}, 100);
				}, 2000); // Start countdown after 2 seconds (fade out duration)
				//instantiate the drone
				LK.setTimeout(function () {
					// Spawn objdrone anywhere on the right portion of the screen
					var objDrone = new ObjDrone();
					objDrone.x = game.width - Math.random() * (game.width / 4);
					objDrone.y = Math.random() * game.height;
					game.addChild(objDrone);
				}, 2000); // Start spawning objdrone after 2 seconds (fade out duration)
			} else if (randomEvent === 'Survive') {
				// Instantiate objsurvivesign in the center of the playspace
				var objSurviveSign = LK.getAsset('objsurvivesign', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				objSurviveSign.x = game.width / 2;
				objSurviveSign.y = game.height / 2;
				objSurviveSign.alpha = 0; // Start with alpha 0 for fade in effect
				game.addChild(objSurviveSign);
				// Fade in effect
				var fadeInInterval = LK.setInterval(function () {
					objSurviveSign.alpha += 0.05;
					if (objSurviveSign.alpha >= 1) {
						LK.clearInterval(fadeInInterval);
						// Start fade out effect after 2 seconds
						LK.setTimeout(function () {
							var fadeOutInterval = LK.setInterval(function () {
								objSurviveSign.alpha -= 0.05;
								if (objSurviveSign.alpha <= 0) {
									LK.clearInterval(fadeOutInterval);
									objSurviveSign.destroy();
									// Spawn EnemyMiddleRight after objSurviveSign fades out
									if (enemySpawnedCount === 0) {
										enemyMiddleRight = new EnemyMiddleRight();
									}
									var enemies = [enemyMiddleRight];
									var selectedEnemies = [enemies[enemySpawnedCount % enemies.length]];
									selectedEnemies.forEach(function (enemy) {
										game.addChild(enemy);
										enemy.animate();
									});
									enemySpawnedCount += selectedEnemies.length;
									LK.setTimeout(function () {
										selectedEnemies.forEach(function (enemy) {
											enemy.destroy();
										});
										if (enemySpawnedCount >= enemies.length) {
											enemySpawnedCount = 0; // Reset the count to restart the sequence
										}
									}, 30000); // Destroy the enemies after 30 seconds
								}
							}, 60);
						}, 2000);
					}
				}, 60);
			}
			//here add the other event settings
		}
		for (var j = objDataArray.length - 1; j >= 0; j--) {
			if (objDataArray[j] && typeof objDataArray[j]._move_migrated === 'function') {
				objDataArray[j]._move_migrated();
			}
			if (hero.intersects(objDataArray[j]) || heroGround.intersects(objDataArray[j])) {
				objDataCounter += 1;
				console.log("ObjData collected, objDataCounter:", objDataCounter);
				collectCounterTxt.setText(objDataCounter.toString() + "/10");
				LK.getSound('snd_dataacquire').play(); // Play snd_dataacquire sound
				objDataArray[j].destroy();
				objDataArray.splice(j, 1);
				if (objDataCounter >= 10) {
					LK.clearInterval(collectTimerInterval);
					game.removeChild(collectTimerTxt);
					console.log("Collect event completed");
					isEventOngoing = false;
					objDataCounter = 0;
					collectCounterTxt.setText(objDataCounter.toString() + "/10");
					game.removeChild(collectCounterTxt);
					eventTxt.setText('Event: None');
					randomEvent = "";
					distanceTraveled += 100; // Add 100 to the distance
					// Trigger acceleration effects
					LK.getSound('snd_powerup').play(); // Play snd_powerup sound
					LK.getSound('snd_nice').play(); // Play snd_nice sound
					destroyAllObjs(); // Destroy all instances of ObjGO, ObjRALLY, and ObjJUMP
					// Temporarily increase distanceTraveled increment
					var originalIncrement = 1 / 60;
					var acceleratedIncrement = 1 / 15;
					distanceTraveledIncrement = acceleratedIncrement;
					// Temporarily increase parallax speed
					var originalParallaxSpeed = parallax.speed;
					parallax.speed *= 5;
					// Add screen shake and flash effect
					var shakeAmplitude = 10;
					var shakeDuration = 100;
					var originalX = game.x;
					var originalY = game.y;
					var shakeInterval = LK.setInterval(function () {
						game.x = originalX + (Math.random() - 0.5) * shakeAmplitude;
						game.y = originalY + (Math.random() - 0.5) * shakeAmplitude;
					}, shakeDuration);
					LK.effects.flashScreen(0xffffff, 5000); // Flash screen for 5 seconds
					// Instantiate objrush in the center of the playspace for 3 seconds with fade in and fade out effect
					var objRush = LK.getAsset('objRush', {
						anchorX: 0.5,
						anchorY: 0.5
					});
					objRush.x = game.width / 2;
					objRush.y = game.height / 2;
					objRush.alpha = 0; // Start with alpha 0 for fade in effect
					game.addChild(objRush);
					// Fade in effect
					var fadeInInterval = LK.setInterval(function () {
						objRush.alpha += 0.05;
						if (objRush.alpha >= 1) {
							LK.clearInterval(fadeInInterval);
							// Start fade out effect after 3 seconds
							LK.setTimeout(function () {
								var fadeOutInterval = LK.setInterval(function () {
									objRush.alpha -= 0.05;
									if (objRush.alpha <= 0) {
										LK.clearInterval(fadeOutInterval);
										objRush.destroy();
									}
								}, 50); // Approximately 20 FPS
							}, 3000);
						}
					}, 50); // Approximately 20 FPS
					LK.setTimeout(function () {
						distanceTraveledIncrement = originalIncrement;
						parallax.speed = originalParallaxSpeed;
						LK.clearInterval(shakeInterval);
						game.x = originalX;
						game.y = originalY;
					}, 5000); // Reset to normal after 5 seconds
				}
			}
		}
	}
	var particles = game.children.filter(function (child) {
		return child instanceof Particle;
	});
	for (var i = 0; i < particles.length; i++) {
		if (particles[i] instanceof ParticleExplosion) {
			particles[i].update();
		} else {
			particles[i].fadeOut();
		}
	}
	if (!isGameOver) {
		distanceTraveled += distanceTraveledIncrement;
		distanceTxt.setText('Distance: ' + Math.floor(distanceTraveled).toString());
	}
	if (isGameOver) {
		LK.effects.flashScreen(0xff0000, 1000);
		LK.showGameOver();
	}
});
game.on('down', function (x, y, obj) {
	if (hero.visible) {
		hero.flipGravity();
		hero.onHold();
	}
});
game.on('up', function (x, y, obj) {
	hero.onRelease();
});
Hero_Ground.prototype.moveToInitialPosition = function () {
	if (this.isMovingToInitial) {
		return;
	} // Prevent multiple calls
	this.isMovingToInitial = true; // Set flag to indicate movement in progress
	// Set initial position outside the play space
	this.x = -this.width;
	this.y = game.height - this.height / 2 - 100;
	var targetX = hero.x + 175;
	var interpolationSpeed = hero.speed; // Match hero's speed
	this.interpolationInterval = LK.setInterval(function () {
		if (Math.abs(this.x - targetX) < interpolationSpeed) {
			this.x = targetX;
			LK.clearInterval(this.interpolationInterval);
			this.isMovingToInitial = false; // Reset flag when movement is complete
			// Replace movingSpeechBubble with idleSpeechBubble
			if (this.movingSpeechBubble) {
				this.movingSpeechBubble.destroy();
				this.movingSpeechBubble = null;
			}
			this.idleSpeechBubble = LK.getAsset('idleSpeechBubble', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			this.addChild(this.idleSpeechBubble);
			this.idleSpeechBubble.x = this.width / 2 - 20;
			this.idleSpeechBubble.y = -this.idleSpeechBubble.height / 2 - 125;
		} else {
			this.x += this.x < targetX ? interpolationSpeed : -interpolationSpeed;
		}
	}.bind(this), 16); // Approximately 60 FPS
	// Replace idleSpeechBubble with movingSpeechBubble
	if (this.idleSpeechBubble) {
		this.idleSpeechBubble.destroy();
		this.idleSpeechBubble = null;
	}
	// Ensure only one moving speech bubble is active at a time
	if (game.activeMovingSpeechBubble) {
		game.activeMovingSpeechBubble.destroy();
	}
	this.movingSpeechBubble = LK.getAsset('movingSpeechBubble', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	this.addChild(this.movingSpeechBubble);
	this.movingSpeechBubble.x = this.width / 2 + 10;
	this.movingSpeechBubble.y = -this.movingSpeechBubble.height / 2 - 125;
	game.activeMovingSpeechBubble = this.movingSpeechBubble;
};
var animationSpeed = 2; // Define animationSpeed in the global scope
var enemyMiddleRight;
var enemySpawnedCount = 0;
function selectAndAnimateEnemy() {
	if (eventTxt && eventTxt.text && eventTxt.text.includes('Survive')) {
		if (enemySpawnedCount === 0) {
			enemyMiddleRight = new EnemyMiddleRight();
		}
		var enemies = [enemyMiddleRight];
		var selectedEnemies = [enemies[enemySpawnedCount % enemies.length]];
		selectedEnemies.forEach(function (enemy) {
			game.addChild(enemy);
			enemy.animate();
		});
		enemySpawnedCount += selectedEnemies.length;
		LK.setTimeout(function () {
			selectedEnemies.forEach(function (enemy) {
				enemy.destroy();
			});
			if (enemySpawnedCount >= enemies.length) {
				enemySpawnedCount = 0; // Reset the count to restart the sequence
			}
		}, 30000); // Destroy the enemies after 30 seconds
	}
}
LK.setInterval(selectAndAnimateEnemy, 15000);
var parallaxCity = game.addChildAt(new ParallaxCity(), 0);
var generateObjSPIKEY = function generateObjSPIKEY() {
	if (obstacles.filter(function (obstacle) {
		return obstacle instanceof ObjSPIKEY;
	}).length >= 1) {
		return;
	}
	LK.setTimeout(function () {
		var objSPIKEY = new ObjSPIKEY();
		objSPIKEY.x = game.width;
		var spawnChance = Math.random();
		if (spawnChance < 0.75) {
			// 75% chance to spawn on the y and x Axis of hero, but outside the playspace
			objSPIKEY.x = game.width + objSPIKEY.width;
			objSPIKEY.y = hero.y;
		} else {
			// 25% chance to spawn on hero ground, but outside the playspace
			objSPIKEY.x = game.width + objSPIKEY.width;
			objSPIKEY.y = heroGround.y;
		}
		// Ensure objSPIKEY does not spawn too close to other objects
		for (var i = 0; i < obstacles.length; i++) {
			if (Math.abs(obstacles[i].x - objSPIKEY.x) < 600) {
				objSPIKEY.x = obstacles[i].x + 600;
			}
			if (Math.abs(obstacles[i].y - objSPIKEY.y) < 600) {
				objSPIKEY.y = Math.random() < 0.5 ? obstacles[i].y - 600 : obstacles[i].y + 600;
			}
		}
		obstacles.push(objSPIKEY);
		game.addChild(objSPIKEY);
	}, 500 + Math.random() * 2000);
};
ObjDrone.prototype.update = function () {
	// Check for collision with hero or heroGround
	if (this.intersects(hero) || this.intersects(heroGround)) {
		this.destroy();
		catchTimer = 15.0;
		LK.clearInterval(catchTimerInterval);
		game.removeChild(catchTimerTxt);
		isEventOngoing = false;
		eventTxt.setText('Event: None');
		randomEvent = "";
		distanceTraveled += 100;
		LK.getSound('snd_powerup').play();
		LK.getSound('snd_nice').play();
		destroyAllObjs();
		var originalIncrement = 1 / 60;
		var acceleratedIncrement = 1 / 15;
		distanceTraveledIncrement = acceleratedIncrement;
		var originalParallaxSpeed = parallax.speed;
		parallax.speed *= 5;
		var shakeAmplitude = 10;
		var shakeDuration = 100;
		var originalX = game.x;
		var originalY = game.y;
		var shakeInterval = LK.setInterval(function () {
			game.x = originalX + (Math.random() - 0.5) * shakeAmplitude;
			game.y = originalY + (Math.random() - 0.5) * shakeAmplitude;
		}, shakeDuration);
		LK.effects.flashScreen(0xffffff, 5000);
		var objRush = LK.getAsset('objRush', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		objRush.x = game.width / 2;
		objRush.y = game.height / 2;
		objRush.alpha = 0;
		game.addChild(objRush);
		var fadeInInterval = LK.setInterval(function () {
			objRush.alpha += 0.05;
			if (objRush.alpha >= 1) {
				LK.clearInterval(fadeInInterval);
				LK.setTimeout(function () {
					var fadeOutInterval = LK.setInterval(function () {
						objRush.alpha -= 0.05;
						if (objRush.alpha <= 0) {
							LK.clearInterval(fadeOutInterval);
							objRush.destroy();
						}
					}, 50);
				}, 3000);
			}
		}, 50);
		LK.setTimeout(function () {
			distanceTraveledIncrement = originalIncrement;
			parallax.speed = originalParallaxSpeed;
			LK.clearInterval(shakeInterval);
			game.x = originalX;
			game.y = originalY;
		}, 5000);
	}
}; ===================================================================
--- original.js
+++ change.js
@@ -1177,8 +1177,9 @@
 		obstacles.push(objEvents);
 		game.addChild(objEvents);
 	}, 500 + Math.random() * 2000);
 };
+var objSPIKEYGenerationInterval = LK.setInterval(generateObjSPIKEY, 8000);
 var generateObjACCELERATE = function generateObjACCELERATE() {
 	if (obstacles.filter(function (obstacle) {
 		return obstacle instanceof ObjACCELERATE;
 	}).length >= 1) {
@@ -1429,9 +1430,8 @@
 	var objRALLYGenerationInterval = LK.setInterval(generateObjRALLY, 2000);
 	var objACCELERATEGenerationInterval = LK.setInterval(generateObjACCELERATE, 8000);
 	var objJUMPGenerationInterval = LK.setInterval(generateObjJUMP, 2000);
 	var objEventsGenerationInterval = LK.setInterval(generateObjEvents, 10000);
-	var objSPIKEYGenerationInterval = LK.setInterval(generateObjSPIKEY, 8000);
 	var generateObjSPIKEY = function generateObjSPIKEY() {
 		if (obstacles.filter(function (obstacle) {
 			return obstacle instanceof ObjSPIKEY;
 		}).length >= 1) {
 2d cyberpunk particle of a dash ability. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 blue jetfuel. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 
 
 
 
 
 pixel art speech bubble that says "?" neon color. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 pixel art speech bubble that says "Go" neon color. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 
 pixel art speech bubble that says "Ok" neon color.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 pixel art of a bubble a wing inside in neon color.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 pixel art bubble with 2 fast foward arrows neon color. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 Gray Cyber neon lit logo of the word Rush. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 side profile of a flying car in the art style of a 16 bit neon cyberpunk game. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 retro cyberpunk datadisk in neon colors. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 retro cyberpunk pole flag in neon colors with the words 'events' on it.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 
 
 retro sign that says "Hold to Dash" in neon colors. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 retro sign that says "Tap to Move" in neon colors.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 retro sign that says "catch" with an flying drone symbol in neon colors.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 retro flying drone in neon colors.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 retro sign that says "Survive" with an face symbol in neon colors... Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 neon colored cyberpunk round electricity. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
SynthwaveMusic
Music
snd_letsgo
Sound effect
snd_announcer
Sound effect
snd_powerup
Sound effect
snd_dataacquire
Sound effect
snd_walkie
Sound effect
snd_nice
Sound effect
snd_carhonk
Sound effect
snd_enemy
Sound effect
snd_sphere
Sound effect
snd_windup
Sound effect
snd_spikey
Sound effect
snd_drone
Sound effect