/**** 
* 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
						//adjust the event counter as an event has been completed
						if (eventCounter > 0) {
							eventCounter--;
						}
						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
						destroySpikeys(); //destroy all the spikeys as there will be no power ups to destroy those. 
						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
		// Instantiate objwindup in the center of the enemy
		objWindup = LK.getAsset('objwindup', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		LK.getSound('snd_windup').play();
		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 + 550;
			game.addChild(objLaser);
			game.addChild(objLaser); // Ensure objLaser is added to the game
			LK.getSound('snd_enemy').play(); // Play snd_enemy sound
			// 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);
			LK.getSound('snd_enemy').play(); // Play snd_enemy sound
			// 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 () {
		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
			});
			LK.getSound('snd_sphere').play();
			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);
	if (self) {
		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
							destroySpikeys();
							// 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] instanceof ObjSPIKEY) {
							obstacles[i].destroy();
							obstacles.splice(i, 1);
						}
					} else if (obstacles[i] instanceof ObjSPIKEY) {
						if (self.isDashing && self.intersects(obstacles[i])) {
							var explosion = new ParticleExplosion(obstacles[i].x, obstacles[i].y);
							game.addChild(explosion);
							LK.getSound('snd_spikey').play(); // Play snd_spikey sound
							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);
	if (self) {
		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.alpha = 1; // Ensure objspikey is always visible
	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;
			//adjust the event counter as an event has been completed
			if (eventCounter > 0) {
				eventCounter--;
			}
			// 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
			destroySpikeys();
			// 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;
	if (self) {
		self.on('destroy', function () {
			LK.clearInterval(self.erraticMovementInterval);
			LK.clearInterval(self.relocationInterval);
			LK.clearInterval(catchTimerInterval);
			game.removeChild(catchTimerTxt);
			LK.getSound('snd_drone').play(); // Play snd_drone sound
		});
	}
});
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);
				LK.getSound('snd_spikey').play();
				self.collisionObject.destroy(); // Destroy the custom collision object
				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.25; // Set collision object alpha to 25%
	collisionGraphics.tint = 0x000000; // Set collision object color to black
});
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
****/ 
LK.setTimeout(function () {
	var messageText = new Text2('Sending orders your way!\n(Hold to dash and break the bubbles)', {
		size: 75,
		fill: "#FFFFFF",
		stroke: "#000000",
		strokeThickness: 5,
		fontWeight: 'bolder'
	});
	messageText.anchor.set(0.5, 0.5);
	messageText.x = hero.width / 2 + 600; // Position the message in front of the hero
	hero.addChild(messageText);
	// Fade out the message after 5 seconds
	LK.setTimeout(function () {
		var fadeOutInterval = LK.setInterval(function () {
			messageText.alpha -= 0.05;
			if (messageText.alpha <= 0) {
				LK.clearInterval(fadeOutInterval);
				messageText.destroy();
			}
		}, 50); // Approximately 20 FPS
	}, 5000);
}, 5500); // Show message 5.5 seconds after game starts
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 eventCounter = randomIntFromInterval(1, 3);
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 generateObjSPIKEY = function generateObjSPIKEY() {
	generateObjGO;
	var lenSpikey = obstacles.filter(function (obstacle) {
		return obstacle instanceof ObjSPIKEY;
	}).length;
	if (distanceTraveled < 500) {
		if (lenSpikey >= 1) {
			return;
		}
	} else if (distanceTraveled < 1000) {
		if (lenSpikey >= 2) {
			return;
		}
	} else {
		if (lenSpikey >= 3) {
			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);
};
function destroySpikeys() {
	for (var i = obstacles.length - 1; i >= 0; i--) {
		if (obstacles[i] instanceof ObjSPIKEY) {
			if (obstacles[i]) {
				var explosion = new ParticleExplosion(obstacles[i].x, obstacles[i].y);
				game.addChild(explosion);
				obstacles[i].destroy();
				obstacles.splice(i, 1);
				LK.getSound('snd_spikey').play();
			}
		}
	}
}
var objSPIKEYGenerationInterval = LK.setInterval(generateObjSPIKEY, 8000);
var objSpikeyIncrease1 = false;
var objSpikeyIncrease2 = false;
var objSPIKEYGenerationInterval2 = 0;
var objSPIKEYGenerationInterval3 = 0;
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;
	if (collisionCounter >= 1) {
		destroyAllObjs();
	}
}
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);
		if (bootText) {
			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);
	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);
		LK.clearInterval(objSPIKEYGenerationInterval2);
		LK.clearInterval(objSPIKEYGenerationInterval3);
		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;
var objNightFilter;
var lastNightFilterDistance = 0;
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])) {
			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();
			destroySpikeys();
			isEventOngoing = true;
			// Ensure event text is displayed
			var eventsNight = ['Catch', 'Survive'];
			var eventsDay = ['Avoid', 'Collect'];
			//get a random number between 0 and 1 to get the index randomly selected. 
			var indexEvent = Math.round(Math.random());
			// set the random events selection depending on the background that is present. 
			//night we want a random between catcha and survive. 
			if (objNightFilter) {
				randomEvent = eventsNight[indexEvent];
			}
			//if we are during the day we want to choose between avoid and collect
			else {
				randomEvent = eventsDay[indexEvent];
			}
			//set the event text once an event type has been selected.
			eventTxt.setText('Event: ' + 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') {
				// Ensure at least one objjump is generated when the avoid event begins
				generateObjJUMP();
				// 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;
				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);
					isEventOngoing = false;
					objDataCounter = 0;
					collectCounterTxt.setText(objDataCounter.toString() + "/10");
					game.removeChild(collectCounterTxt);
					eventTxt.setText('Event: None');
					randomEvent = "";
					distanceTraveled += 100; // Add 100 to the distance
					//adjust the event counter as an event has been completed
					if (eventCounter > 0) {
						eventCounter--;
					}
					// 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
					destroySpikeys(); //destroy the spikeys as there will be no power ups to be able to destroy them
					// 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) {
		// Add objnightfilter every 100 distance
		if (distanceTraveled < 100) {
			if (objNightFilter) {
				objNightFilter.destroy();
				objNightFilter = undefined;
			}
		} else {
			//we check if the event counter is 0;
			//if we have reached 0 and there is no night filter we want to add the night filter and reset the counter
			//that way for the next switch we will be able to have the number to decrease until we get to the day time. 
			console.log("event counter: " + eventCounter + "  objnightfilter" + objNightFilter);
			if (eventCounter <= 0 && !objNightFilter) {
				eventCounter = randomIntFromInterval(1, 3);
				objNightFilter = LK.getAsset('objnightfilter', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				objNightFilter.alpha = 0.6; // Set transparency to 80%
				objNightFilter.x = game.width / 2;
				objNightFilter.y = game.height / 2;
				game.addChildAt(objNightFilter, game.getChildIndex(parallaxCity) + 1); // Ensure objNightFilter is above parallaxCity
			}
			//here we reset the event counter and we remove the night filter
			//that way the new counter for the next event decrease is going to be there. 
			else if (eventCounter <= 0 && objNightFilter) {
				eventCounter = randomIntFromInterval(1, 3);
				objNightFilter.destroy();
				objNightFilter = undefined;
			}
		}
		//adjusting the distance that is being traveled.
		distanceTraveled += distanceTraveledIncrement;
		distanceTxt.setText('Distance: ' + Math.floor(distanceTraveled).toString());
		//if the distance traveled is above 500 add a second spikey generation
		if (distanceTraveled > 500 && objSpikeyIncrease1 == false) {
			objSPIKEYGenerationInterval2 = LK.setInterval(generateObjSPIKEY, 6000);
			objSpikeyIncrease1 = true;
		}
		//if the distance traveled if above 1000 add a third spikey generation
		if (distanceTraveled > 1000 && objSpikeyIncrease2 == false) {
			objSPIKEYGenerationInterval3 = LK.setInterval(generateObjSPIKEY, 11000);
		}
	}
	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 randomIntFromInterval(min, max) {
	// min and max included 
	return Math.floor(Math.random() * (max - min + 1) + min);
}
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);
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;
		//adjust the event counter as an event has been completed
		if (eventCounter > 0) {
			eventCounter--;
		}
		LK.getSound('snd_powerup').play();
		LK.getSound('snd_nice').play();
		destroyAllObjs(); //destroy the power ups
		destroySpikeys(); //destroy the spikeys
		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);
	}
};
if (self) {
	self.on('destroy', function () {
		LK.getSound('snd_spikey').play();
	});
} /**** 
* 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
						//adjust the event counter as an event has been completed
						if (eventCounter > 0) {
							eventCounter--;
						}
						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
						destroySpikeys(); //destroy all the spikeys as there will be no power ups to destroy those. 
						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
		// Instantiate objwindup in the center of the enemy
		objWindup = LK.getAsset('objwindup', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		LK.getSound('snd_windup').play();
		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 + 550;
			game.addChild(objLaser);
			game.addChild(objLaser); // Ensure objLaser is added to the game
			LK.getSound('snd_enemy').play(); // Play snd_enemy sound
			// 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);
			LK.getSound('snd_enemy').play(); // Play snd_enemy sound
			// 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 () {
		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
			});
			LK.getSound('snd_sphere').play();
			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);
	if (self) {
		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
							destroySpikeys();
							// 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] instanceof ObjSPIKEY) {
							obstacles[i].destroy();
							obstacles.splice(i, 1);
						}
					} else if (obstacles[i] instanceof ObjSPIKEY) {
						if (self.isDashing && self.intersects(obstacles[i])) {
							var explosion = new ParticleExplosion(obstacles[i].x, obstacles[i].y);
							game.addChild(explosion);
							LK.getSound('snd_spikey').play(); // Play snd_spikey sound
							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);
	if (self) {
		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.alpha = 1; // Ensure objspikey is always visible
	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;
			//adjust the event counter as an event has been completed
			if (eventCounter > 0) {
				eventCounter--;
			}
			// 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
			destroySpikeys();
			// 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;
	if (self) {
		self.on('destroy', function () {
			LK.clearInterval(self.erraticMovementInterval);
			LK.clearInterval(self.relocationInterval);
			LK.clearInterval(catchTimerInterval);
			game.removeChild(catchTimerTxt);
			LK.getSound('snd_drone').play(); // Play snd_drone sound
		});
	}
});
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);
				LK.getSound('snd_spikey').play();
				self.collisionObject.destroy(); // Destroy the custom collision object
				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.25; // Set collision object alpha to 25%
	collisionGraphics.tint = 0x000000; // Set collision object color to black
});
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
****/ 
LK.setTimeout(function () {
	var messageText = new Text2('Sending orders your way!\n(Hold to dash and break the bubbles)', {
		size: 75,
		fill: "#FFFFFF",
		stroke: "#000000",
		strokeThickness: 5,
		fontWeight: 'bolder'
	});
	messageText.anchor.set(0.5, 0.5);
	messageText.x = hero.width / 2 + 600; // Position the message in front of the hero
	hero.addChild(messageText);
	// Fade out the message after 5 seconds
	LK.setTimeout(function () {
		var fadeOutInterval = LK.setInterval(function () {
			messageText.alpha -= 0.05;
			if (messageText.alpha <= 0) {
				LK.clearInterval(fadeOutInterval);
				messageText.destroy();
			}
		}, 50); // Approximately 20 FPS
	}, 5000);
}, 5500); // Show message 5.5 seconds after game starts
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 eventCounter = randomIntFromInterval(1, 3);
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 generateObjSPIKEY = function generateObjSPIKEY() {
	generateObjGO;
	var lenSpikey = obstacles.filter(function (obstacle) {
		return obstacle instanceof ObjSPIKEY;
	}).length;
	if (distanceTraveled < 500) {
		if (lenSpikey >= 1) {
			return;
		}
	} else if (distanceTraveled < 1000) {
		if (lenSpikey >= 2) {
			return;
		}
	} else {
		if (lenSpikey >= 3) {
			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);
};
function destroySpikeys() {
	for (var i = obstacles.length - 1; i >= 0; i--) {
		if (obstacles[i] instanceof ObjSPIKEY) {
			if (obstacles[i]) {
				var explosion = new ParticleExplosion(obstacles[i].x, obstacles[i].y);
				game.addChild(explosion);
				obstacles[i].destroy();
				obstacles.splice(i, 1);
				LK.getSound('snd_spikey').play();
			}
		}
	}
}
var objSPIKEYGenerationInterval = LK.setInterval(generateObjSPIKEY, 8000);
var objSpikeyIncrease1 = false;
var objSpikeyIncrease2 = false;
var objSPIKEYGenerationInterval2 = 0;
var objSPIKEYGenerationInterval3 = 0;
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;
	if (collisionCounter >= 1) {
		destroyAllObjs();
	}
}
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);
		if (bootText) {
			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);
	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);
		LK.clearInterval(objSPIKEYGenerationInterval2);
		LK.clearInterval(objSPIKEYGenerationInterval3);
		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;
var objNightFilter;
var lastNightFilterDistance = 0;
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])) {
			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();
			destroySpikeys();
			isEventOngoing = true;
			// Ensure event text is displayed
			var eventsNight = ['Catch', 'Survive'];
			var eventsDay = ['Avoid', 'Collect'];
			//get a random number between 0 and 1 to get the index randomly selected. 
			var indexEvent = Math.round(Math.random());
			// set the random events selection depending on the background that is present. 
			//night we want a random between catcha and survive. 
			if (objNightFilter) {
				randomEvent = eventsNight[indexEvent];
			}
			//if we are during the day we want to choose between avoid and collect
			else {
				randomEvent = eventsDay[indexEvent];
			}
			//set the event text once an event type has been selected.
			eventTxt.setText('Event: ' + 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') {
				// Ensure at least one objjump is generated when the avoid event begins
				generateObjJUMP();
				// 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;
				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);
					isEventOngoing = false;
					objDataCounter = 0;
					collectCounterTxt.setText(objDataCounter.toString() + "/10");
					game.removeChild(collectCounterTxt);
					eventTxt.setText('Event: None');
					randomEvent = "";
					distanceTraveled += 100; // Add 100 to the distance
					//adjust the event counter as an event has been completed
					if (eventCounter > 0) {
						eventCounter--;
					}
					// 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
					destroySpikeys(); //destroy the spikeys as there will be no power ups to be able to destroy them
					// 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) {
		// Add objnightfilter every 100 distance
		if (distanceTraveled < 100) {
			if (objNightFilter) {
				objNightFilter.destroy();
				objNightFilter = undefined;
			}
		} else {
			//we check if the event counter is 0;
			//if we have reached 0 and there is no night filter we want to add the night filter and reset the counter
			//that way for the next switch we will be able to have the number to decrease until we get to the day time. 
			console.log("event counter: " + eventCounter + "  objnightfilter" + objNightFilter);
			if (eventCounter <= 0 && !objNightFilter) {
				eventCounter = randomIntFromInterval(1, 3);
				objNightFilter = LK.getAsset('objnightfilter', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				objNightFilter.alpha = 0.6; // Set transparency to 80%
				objNightFilter.x = game.width / 2;
				objNightFilter.y = game.height / 2;
				game.addChildAt(objNightFilter, game.getChildIndex(parallaxCity) + 1); // Ensure objNightFilter is above parallaxCity
			}
			//here we reset the event counter and we remove the night filter
			//that way the new counter for the next event decrease is going to be there. 
			else if (eventCounter <= 0 && objNightFilter) {
				eventCounter = randomIntFromInterval(1, 3);
				objNightFilter.destroy();
				objNightFilter = undefined;
			}
		}
		//adjusting the distance that is being traveled.
		distanceTraveled += distanceTraveledIncrement;
		distanceTxt.setText('Distance: ' + Math.floor(distanceTraveled).toString());
		//if the distance traveled is above 500 add a second spikey generation
		if (distanceTraveled > 500 && objSpikeyIncrease1 == false) {
			objSPIKEYGenerationInterval2 = LK.setInterval(generateObjSPIKEY, 6000);
			objSpikeyIncrease1 = true;
		}
		//if the distance traveled if above 1000 add a third spikey generation
		if (distanceTraveled > 1000 && objSpikeyIncrease2 == false) {
			objSPIKEYGenerationInterval3 = LK.setInterval(generateObjSPIKEY, 11000);
		}
	}
	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 randomIntFromInterval(min, max) {
	// min and max included 
	return Math.floor(Math.random() * (max - min + 1) + min);
}
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);
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;
		//adjust the event counter as an event has been completed
		if (eventCounter > 0) {
			eventCounter--;
		}
		LK.getSound('snd_powerup').play();
		LK.getSound('snd_nice').play();
		destroyAllObjs(); //destroy the power ups
		destroySpikeys(); //destroy the spikeys
		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);
	}
};
if (self) {
	self.on('destroy', function () {
		LK.getSound('snd_spikey').play();
	});
}
 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