User prompt
stop background music on game over
User prompt
make sure gameover sound is only played once
Code edit (2 edits merged)
Please save this source code
User prompt
wait one second after playing gameover sound before showing game over
User prompt
change music to gameover before game over
User prompt
play gameover sound when before game over pops up
User prompt
make flash screen game white
User prompt
use lk.setscore to track final score
User prompt
show final score in the game over message from the lk engine
User prompt
create a final score for the game. that final score is the result of the miles traveled plus 100 extra points per each coin collected
User prompt
add 100 pixels of space between miles travelled, coins and final score
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'setText')' in or related to this line: 'milesTxt.setText(Math.floor(milesTraveled));' Line Number: 1444
User prompt
when game over screen is loaded, first should miles and final score for 1 second and keep coins hidden. then start decreasing miles and increasing final score. after that is done, show coins.
User prompt
Please fix the bug: 'Timeout.tick error: finalScoreText is not defined' in or related to this line: 'finalScoreText.setText('Final Score: ' + currentFinalScore);' Line Number: 144
User prompt
instead of ccounting upwards, miles on gmae over screen should go from the number they were on game over to 0, and while doing that, final score should be increasing from 0 to the miles number
Code edit (1 edits merged)
Please save this source code
User prompt
game over animationo should make it come from the back forward, from very small to big
User prompt
add space bteween miles coins and final score
User prompt
add animation on how game over text appears
User prompt
game over text should be higher
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'setText')' in or related to this line: 'milesTxt.setText(Math.floor(milesTraveled));' Line Number: 1422
User prompt
remove miles and coins background image ont he top right when game over is up
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'setText')' in or related to this line: 'milesTxt.setText(Math.floor(milesTraveled));' Line Number: 1405
User prompt
destroy miles and coinis counter on the top right when game over screen is up
/**** 
* Classes
****/ 
// Define the SmallObstacle class
var BigObstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('bigobstacle', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: 0xa8ed15 // Apply tint #a8ed15
	});
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
// Define the Coin class
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
		// Floating effect
		self.y += Math.sin(LK.ticks / 20) * 0.5;
		// Size changing effect
		self.scale.x = 1 + Math.sin(LK.ticks / 20) * 0.05;
		self.scale.y = 1 + Math.sin(LK.ticks / 20) * 0.05;
	};
});
// Define the GameOverScreen class
var GameOverScreen = Container.expand(function () {
	var self = Container.call(this);
	var background = self.attachAsset('new_miles_background_id', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 2732 / 2,
		scaleX: 2048 / 100,
		scaleY: 2732 / 100,
		alpha: 1.0,
		// Set alpha to 1.0 to ensure background is not transparent
		tint: 0x000000 // Set background color to black
	});
	self.addChildAt(background, self.children.length);
	var gameOverText = new Text2('Game Over', {
		size: 300,
		fill: "#83de44",
		stroke: "#000000",
		strokeThickness: 10,
		border: true,
		borderColor: "#000000",
		borderWidth: 5
	});
	gameOverText.anchor.set(0.5, 0.5);
	gameOverText.x = 2048 / 2;
	gameOverText.y = 2732 / 2 - 600; // Start above the final position
	gameOverText.scale.set(0.1, 0.1); // Start very small
	self.addChildAt(gameOverText, 1);
	// Animate the game over text to move down to its final position and scale up
	var animationDuration = 60; // Duration in frames (1 second at 60 FPS)
	var animationStepY = (2732 / 2 - 400 - gameOverText.y) / animationDuration;
	var animationStepScale = (1 - gameOverText.scale.x) / animationDuration;
	var animationInterval = LK.setInterval(function () {
		if (animationDuration > 0) {
			gameOverText.y += animationStepY;
			gameOverText.scale.x += animationStepScale;
			gameOverText.scale.y += animationStepScale;
			animationDuration--;
		} else {
			LK.clearInterval(animationInterval);
		}
	}, 16.67); // Update every frame (16.67ms for 60 FPS)
	var milesText = new Text2('Miles: 0', {
		size: 100,
		fill: "#ffffff",
		stroke: "#000000",
		strokeThickness: 5,
		border: true,
		borderColor: "#000000",
		borderWidth: 3
	});
	milesText.anchor.set(0.5, 0.5);
	milesText.x = 2048 / 2;
	milesText.y = 2732 / 2 + 50;
	self.addChild(milesText);
	// Animate miles counter from 0 to milesTraveled
	var currentMiles = Math.floor(milesTraveled);
	var currentFinalScore = 0;
	var milesInterval = LK.setInterval(function () {
		if (currentMiles > 0) {
			currentMiles -= Math.ceil(Math.floor(milesTraveled) / 30); // Decrement quickly
			if (currentMiles < 0) {
				currentMiles = 0;
			}
			milesText.setText('Miles: ' + currentMiles);
			currentFinalScore = Math.floor(milesTraveled) - currentMiles;
			finalScoreText.setText('Final Score: ' + currentFinalScore);
		} else {
			LK.clearInterval(milesInterval);
			var coinsText = new Text2('Coins: 0', {
				size: 100,
				fill: "#ffffff",
				stroke: "#000000",
				strokeThickness: 5,
				border: true,
				borderColor: "#000000",
				borderWidth: 3
			});
			coinsText.anchor.set(0.5, 0.5);
			coinsText.x = 2048 / 2;
			coinsText.y = 2732 / 2 + 150;
			self.addChild(coinsText);
			var currentCoins = 0;
			var coinsInterval = LK.setInterval(function () {
				if (currentCoins < score) {
					currentCoins += Math.ceil(score / 30); // Increment quickly
					if (currentCoins > score) {
						currentCoins = score;
					}
					coinsText.setText('Coins: ' + currentCoins);
				} else {
					LK.clearInterval(coinsInterval);
					var finalScoreText = new Text2('Final Score: 0', {
						size: 100,
						fill: "#ffffff",
						stroke: "#000000",
						strokeThickness: 5,
						border: true,
						borderColor: "#000000",
						borderWidth: 3
					});
					finalScoreText.anchor.set(0.5, 0.5);
					finalScoreText.x = 2048 / 2;
					finalScoreText.y = 2732 / 2 + 250;
					self.addChild(finalScoreText);
					var finalScore = Math.floor(milesTraveled) + score * 100;
					var currentFinalScore = 0;
					var finalScoreInterval = LK.setInterval(function () {
						if (currentFinalScore < finalScore) {
							currentFinalScore += Math.ceil(finalScore / 30); // Increment quickly
							if (currentFinalScore > finalScore) {
								currentFinalScore = finalScore;
							}
							finalScoreText.setText('Final Score: ' + currentFinalScore);
						} else {
							LK.clearInterval(finalScoreInterval);
						}
					}, 30);
				}
			}, 30);
		}
	}, 30);
});
// Define the LaneSeparator class
var LaneSeparator = Container.expand(function () {
	var self = Container.call(this);
	var separatorGraphics = self.attachAsset('lineobstacle', {
		anchorX: 0.5,
		anchorY: 0.0,
		// Adjust anchor to top
		width: 20,
		height: 2732 // Set the height to cover the entire screen height
	});
	separatorGraphics.height = 2732; // Ensure the height covers the entire screen height
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
// Define the LeftLaneOutline class
var LeftLaneOutline = Container.expand(function () {
	var self = Container.call(this);
	var outlineGraphics = self.attachAsset('lineobstacle', {
		anchorX: 0.5,
		anchorY: 0.0,
		width: 20,
		height: 2732 // Set the height to cover the entire screen height
	});
	outlineGraphics.height = 2732; // Ensure the height covers the entire screen height
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
// Define the LeftPlayer class
var LeftPlayer = Container.expand(function () {
	var self = Container.call(this);
	var leftPlayerGraphics = self.attachAsset('leftplayer', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 15;
	self.update = function () {
		// Add any specific update logic for LeftPlayer here
		if (LK.ticks % 4 == 0 && !gameOverScreen) {
			var trail = new Trail();
			trail.scale.x = 0.5;
			trail.scale.y = 0.5;
			if (self && self.x !== undefined) {
				trail.x = self.x;
			} else {
				trail.x = 0;
			}
			trail.y = self && self.y !== undefined ? self.y + (leftPlayerGraphics ? leftPlayerGraphics.height / 2 : 0) : 0;
			game.addChildAt(trail, game.getChildIndex(self));
		}
	};
});
var LineObstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacleline', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: 0xa8ed15 // Apply tint #a8ed15
	});
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
// Define the Obstacle class
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: 0xa8ed15 // Apply tint #a8ed15
	});
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
// Define the Particle class
var Particle = Container.expand(function () {
	var self = Container.call(this);
	var particleGraphics = self.attachAsset('particle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = Math.random() * 5 + 2; // Random speed for each particle
	self.direction = Math.random() * Math.PI * 2; // Random direction for each particle
	self.update = function () {
		self.x += Math.cos(self.direction) * self.speed; // Move the particle in the direction
		self.y += Math.sin(self.direction) * self.speed;
		self.alpha -= 0.01; // Fade out the particle
		if (self.alpha <= 0) {
			self.destroy();
		}
	};
});
// Define the Player class
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 15;
	self.shield = null;
	self.transitionToLane = function (targetX) {
		self.isMoving = true;
		self.targetX = targetX;
		if (self.x < self.targetX) {
			playerGraphics.rotation = Math.PI / 4; // Rotate player 45 degrees to the direction of movement
		} else {
			playerGraphics.rotation = -Math.PI / 4; // Rotate player -45 degrees to the direction of movement
		}
	};
	self.update = function () {
		if (self.isInvulnerable) {
			self.invulnerableTimer--;
			if (!self.shield) {
				self.shield = self.addChild(LK.getAsset('shield', {
					anchorX: 0.5,
					anchorY: 0.5,
					alpha: 0.5 // Set shield transparency
				}));
				// Add countdown text over the shield
				self.shieldCountdown = new Text2('10', {
					size: 100,
					fill: "#ffffff",
					stroke: "#000000",
					strokeThickness: 5,
					border: true,
					borderColor: "#000000",
					borderWidth: 3
				});
				self.shieldCountdown.anchor.set(0.5, 0.5);
				self.shieldCountdown.x = 0;
				self.shieldCountdown.y = 0;
				self.shield.addChild(self.shieldCountdown);
				// Play powerup sound when shield is activated
				LK.getSound('powerup').play();
			}
			if (leftPlayer && !leftPlayer.shield) {
				leftPlayer.shield = leftPlayer.addChild(LK.getAsset('shield', {
					anchorX: 0.5,
					anchorY: 0.5,
					alpha: 0.5 // Set shield transparency
				}));
				// Play powerup sound when left player's shield is activated
				LK.getSound('powerup').play();
			}
			if (rightPlayer && !rightPlayer.shield) {
				rightPlayer.shield = rightPlayer.addChild(LK.getAsset('shield', {
					anchorX: 0.5,
					anchorY: 0.5,
					alpha: 0.5 // Set shield transparency
				}));
				// Play powerup sound when right player's shield is activated
				LK.getSound('powerup').play();
			}
			if (self.invulnerableTimer <= 0) {
				self.isInvulnerable = false;
				if (self.shield) {
					self.shield.destroy();
					self.shield = null;
				}
				if (leftPlayer && leftPlayer.shield) {
					leftPlayer.shield.destroy();
					leftPlayer.shield = null;
				}
				if (rightPlayer && rightPlayer.shield) {
					rightPlayer.shield.destroy();
					rightPlayer.shield = null;
				}
			} else {
				// Update countdown text
				if (self.shieldCountdown) {
					self.shieldCountdown.setText(Math.ceil(self.invulnerableTimer / 120));
				}
			}
		}
		if (self.isMoving) {
			if (Math.abs(self.x - self.targetX) < self.speed) {
				self.x = self.targetX;
				self.isMoving = false;
			} else {
				self.x += (self.targetX - self.x) * 0.1; // Smooth movement using linear interpolation
				playerGraphics.rotation = self.x < self.targetX ? Math.PI / 4 : -Math.PI / 4; // Rotate player 45 degrees to the direction of movement
			}
		} else {
			// Smoothly transition player rotation back to its original position
			if (playerGraphics.rotation > 0) {
				playerGraphics.rotation -= 0.1;
			} else if (playerGraphics.rotation < 0) {
				playerGraphics.rotation += 0.1;
			}
			if (Math.abs(playerGraphics.rotation) < 0.1) {
				playerGraphics.rotation = 0; // Reset rotation when player is not moving
			}
		}
		if (!self.isJumping && self.visible && !gameOverScreen && !gameOverScreen) {
			if (self.isMoving && LK.ticks % 1 == 0) {
				var trail = new Trail();
				trail.x = self.x;
				trail.y = self.y + playerGraphics.height / 2;
				game.addChild(trail);
			} else if (LK.ticks % 4 == 0) {
				var trail = new Trail();
				trail.x = self.x;
				trail.y = self.y + playerGraphics.height / 2;
				game.addChild(trail);
			}
		}
		if (self.isJumping) {
			if (self.y > self.jumpPeakY && !self.isFalling) {
				self.y -= self.jumpSpeed;
				playerGraphics.scale.x += 0.01; // Increase player size when moving up
				playerGraphics.scale.y += 0.01;
				if (self.shield) {
					self.shield.scale.x += 0.01; // Increase shield size when moving up
					self.shield.scale.y += 0.01;
				}
			} else {
				self.isFalling = true;
				self.y += self.jumpSpeed;
				playerGraphics.scale.x -= 0.01; // Decrease player size when falling down
				playerGraphics.scale.y -= 0.01;
				if (self.shield) {
					self.shield.scale.x -= 0.01; // Decrease shield size when falling down
					self.shield.scale.y -= 0.01;
				}
				if (self.y >= self.jumpStartY) {
					self.y = self.jumpStartY;
					self.isJumping = false;
					self.isFalling = false;
					playerGraphics.scale.x = 1; // Reset player size when not jumping
					playerGraphics.scale.y = 1;
					if (self.shield) {
						self.shield.scale.x = 1; // Reset shield size when not jumping
						self.shield.scale.y = 1;
					}
					// Destroy the player's shadow
					shadow.destroy();
				}
			}
		}
		// Update shadow rotation to match player rotation
		if (shadow) {
			shadow.rotation = playerGraphics.rotation;
		}
		// Ensure player is always on top if it is a child of the game
		if (game.children.includes(self)) {
			game.setChildIndex(self, game.children.length - 1);
		}
	};
	self.moveLeft = function () {
		if (!gameStarted) {
			for (var i = 0; i < starfield.length; i++) {
				starfield[i].update();
			}
			return;
		}
		if (self.lane > 0 && !self.isMoving && !leftPlayer && !rightPlayer) {
			self.lane--;
			self.transitionToLane(lanes[self.lane]);
			LK.getSound('swipe').play();
			LK.getSound('swipe').play();
		}
	};
	self.moveRight = function () {
		if (!gameStarted) {
			return;
		} // Prevent player movement when the home screen is up
		if (self.lane < 2 && !self.isMoving && !leftPlayer && !rightPlayer) {
			self.lane++;
			self.transitionToLane(lanes[self.lane]);
			LK.getSound('swipe').play();
		}
	};
	self.jump = function () {
		if (!self.isMoving && !self.isJumping && !leftPlayer && !rightPlayer) {
			self.isJumping = true;
			self.jumpStartY = self.y;
			self.jumpPeakY = self.y - 250; // Increase jump height
			self.jumpSpeed = 4;
			// Create the player's shadow
			shadow = new Shadow();
			shadow.x = self.x;
			shadow.y = self.y;
			game.addChild(shadow);
			// Play jump sound when player jumps
			LK.getSound('jump').play();
		}
	};
});
var PlayerParticle = Container.expand(function () {
	var self = Container.call(this);
	var particleGraphics = self.attachAsset('particle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = Math.random() * 5 + 2; // Random speed for each particle
	self.direction = Math.random() * Math.PI * 2; // Random direction for each particle
	self.update = function () {
		self.x += Math.cos(self.direction) * self.speed; // Move the particle in the direction
		self.y += Math.sin(self.direction) * self.speed;
		self.alpha -= 0.01; // Fade out the particle
		if (self.alpha <= 0) {
			self.destroy();
		}
	};
});
// Define the PowerUp class
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerUpGraphics = self.attachAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
// Define the PowerUpCenterLane class
var PowerUpCenterLane = Container.expand(function () {
	var self = Container.call(this);
	var powerUpGraphics = self.attachAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
// Define the RightLaneOutline class
var RightLaneOutline = Container.expand(function () {
	var self = Container.call(this);
	var outlineGraphics = self.attachAsset('lineobstacle', {
		anchorX: 0.5,
		anchorY: 0.0,
		width: 20,
		height: 2732 // Set the height to cover the entire screen height
	});
	outlineGraphics.height = 2732; // Ensure the height covers the entire screen height
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
// Define the RightPlayer class
var RightPlayer = Container.expand(function () {
	var self = Container.call(this);
	var rightPlayerGraphics = self.attachAsset('rightplayer', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 15;
	self.update = function () {
		// Add any specific update logic for RightPlayer here
		if (LK.ticks % 4 == 0 && !gameOverScreen) {
			var trail = new Trail();
			trail.scale.x = 0.5;
			trail.scale.y = 0.5;
			if (self && self.x !== undefined) {
				trail.x = self.x;
			} else {
				trail.x = 0;
			}
			trail.y = self && self.y !== undefined ? self.y + (rightPlayerGraphics ? rightPlayerGraphics.height / 2 : 0) : 0;
			game.addChildAt(trail, game.getChildIndex(self));
		}
	};
});
//<Assets used in the game will automatically appear here>
// Define the Shadow class
var Shadow = Container.expand(function () {
	var self = Container.call(this);
	var shadowGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: 0x000000 // Set the color to black
	});
	shadowGraphics.alpha = 0.5; // Dim the shadow
	self.update = function () {
		// The shadow's size changes based on the player's y position
		var scale = 1 - (player.y - self.y) / 1000;
		self.scale.x = scale;
		self.scale.y = scale;
		// Update the shadow's position to match the player's position
		self.x = player.x;
		// Rotate the shadow to match the player's rotation
		if (player.playerGraphics) {
			shadowGraphics.rotation = player.playerGraphics.rotation;
		}
	};
});
// Define the LineObstacle class
var SmallObstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: 0xa8ed15 // Apply tint #a8ed15
	});
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
// Define the SmallObstacleCenterCoinSides class
var SmallObstacleCenterCoinSides = Container.expand(function () {
	var self = Container.call(this);
	var smallObstacle = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: 0xa8ed15 // Apply tint #a8ed15
	});
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
var SmallObstacleMiddlePowerUpLeftCoinRight = Container.expand(function () {
	var self = Container.call(this);
	var smallObstacleMiddle = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5,
		tint: 0xa8ed15 // Apply tint #a8ed15
	});
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
var Star = Container.expand(function () {
	var self = Container.call(this);
	var starGraphics = self.attachAsset('star', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = Math.random() * 2 + 1; // Random speed for each star
	self.scale.set(Math.random() * 1.5 + 0.5); // Random size between 0.5 and 2.0
	self.update = function () {
		self.y += self.speed;
		if (self.y > 2732) {
			self.y = -self.height;
			self.x = Math.random() * 2048;
		}
	};
});
// Function to spawn SmallObstacle in the center and Coins on the sides
var TextObstacle = Container.expand(function (customText) {
	var self = Container.call(this);
	var textGraphics = new Text2(customText || 'Sample Text', {
		size: 120,
		fill: "#ffffff",
		align: "center",
		stroke: "#000000",
		strokeThickness: 10,
		border: true,
		borderColor: "#000000",
		borderWidth: 5
	});
	textGraphics.anchor.set(0.5, 0.5);
	self.addChild(textGraphics);
	self.speed = gameSpeed;
	self.update = function () {
		self.y += self.speed;
		self.hitbox = null; // Ensure TextObstacle does not collide with player
		if (self.y > 2732 + self.height / 2) {
			self.destroy();
		}
	};
});
// Function to spawn SmallObstacle
// Define the Trail class
var Trail = Container.expand(function () {
	var self = Container.call(this);
	var trailGraphics = self.attachAsset('trail', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.5
	});
	self.speed = 5;
	self.update = function () {
		self.y += self.speed;
		self.alpha -= 0.02; // Fade out the trail faster
		self.scale.x -= 0.02; // Shrink the trail faster
		self.scale.y -= 0.02; // Shrink the trail faster
		if (self.y > 2732 || self.alpha <= 0 || self.scale.x <= 0 || self.scale.y <= 0) {
			self.destroy();
		}
	};
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x303030 //Init game with darker grey background
});
/**** 
* Game Code
****/ 
var gameOverScreen = null;
function spawnSmallObstacleMiddlePowerUpLeftCoinRight() {
	var smallObstacleMiddle = new SmallObstacleMiddlePowerUpLeftCoinRight();
	smallObstacleMiddle.x = lanes[1]; // Middle lane
	smallObstacleMiddle.y = -smallObstacleMiddle.height * 2;
	smallObstacleMiddle.speed = gameSpeed; // Ensure constant speed
	if (!obstacles) {
		obstacles = [];
	}
	obstacles.push(smallObstacleMiddle);
	game.addChild(smallObstacleMiddle);
	var powerUpLeft = new PowerUp();
	powerUpLeft.x = lanes[0]; // Left lane
	powerUpLeft.y = -powerUpLeft.height * 2;
	powerUpLeft.speed = gameSpeed; // Ensure constant speed
	if (!powerups) {
		powerups = [];
	}
	powerups.push(powerUpLeft);
	game.addChild(powerUpLeft);
	var coinRight = new Coin();
	coinRight.x = lanes[2]; // Right lane
	coinRight.y = -coinRight.height * 2;
	coinRight.speed = gameSpeed; // Ensure constant speed
	if (!coins) {
		coins = [];
	}
	coins.push(coinRight);
	game.addChild(coinRight);
}
// New asset for obstacle line
function checkBoundingBoxCollision(obj1, obj2) {
	var obj1Bounds = obj1.getBounds();
	var obj2Bounds = obj2.getBounds();
	var forgivenessX = obj1Bounds.width * 0.1;
	var forgivenessY = obj1Bounds.height * 0.1;
	return obj1Bounds.x < obj2Bounds.x + obj2Bounds.width - forgivenessX && obj1Bounds.x + obj1Bounds.width > obj2Bounds.x + forgivenessX && obj1Bounds.y < obj2Bounds.y + obj2Bounds.height - forgivenessY && obj1Bounds.y + obj1Bounds.height > obj2Bounds.y + forgivenessY;
}
// Function to spawn PowerUp in the center lane
function spawnPowerUpCenterLane() {
	var powerUpCenterLane = new PowerUpCenterLane();
	powerUpCenterLane.x = lanes[1]; // Center lane
	powerUpCenterLane.y = -powerUpCenterLane.height * 2;
	if (!powerups) {
		powerups = [];
	}
	powerups.push(powerUpCenterLane);
	game.addChild(powerUpCenterLane);
}
// Create main menu container
var mainMenu = new Container();
game.addChildAt(mainMenu, game.children.length);
// Play background music on main menu
LK.playMusic('backgroundmusic');
// Create title text with background button
var titleButton = new Container();
titleButton.update = function () {
	if (LK.ticks % 120 < 60) {
		titleButton.scale.x += 0.0001;
		titleButton.scale.y += 0.0001;
	} else {
		titleButton.scale.x -= 0.0001;
		titleButton.scale.y -= 0.0001;
	}
};
// Removed titleBackground box
var titleImage = LK.getAsset('homeTitle', {
	anchorX: 0.5,
	anchorY: 0.5
});
titleButton.addChild(titleImage);
// Ensure lanes array is properly initialized before accessing its elements
if (!lanes || lanes.length < 3) {
	console.error("Lanes array is not properly initialized.");
	lanes = [2048 / 4, 2048 / 2, 2048 / 4 * 3]; // Reinitialize lanes array
}
titleButton.x = lanes[1]; // Center the title button over the middle lane
titleButton.y = 2732 / 4;
mainMenu.addChild(titleButton);
// Create mode 1 button with background
var mode1Button = new Container();
mode1Button.update = function () {
	if (LK.ticks % 120 < 60) {
		mode1Button.scale.x += 0.0001;
		mode1Button.scale.y += 0.0001;
	} else {
		mode1Button.scale.x -= 0.0001;
		mode1Button.scale.y -= 0.0001;
	}
};
// Removed mode1ButtonBackground box
var mode1ButtonImage = LK.getAsset('menu1', {
	anchorX: 0.5,
	anchorY: 0.5
});
mode1Button.addChild(mode1ButtonImage);
mode1Button.x = lanes[1]; // Center the mode 1 button over the middle lane
mode1Button.y = 2732 / 2;
mainMenu.addChildAt(mode1Button, mainMenu.children.length);
// Create mode 2 button with background
var mode2Button = new Container();
mode2Button.update = function () {
	if (LK.ticks % 120 < 60) {
		mode2Button.scale.x += 0.0001;
		mode2Button.scale.y += 0.0001;
	} else {
		mode2Button.scale.x -= 0.0001;
		mode2Button.scale.y -= 0.0001;
	}
};
// Removed mode2ButtonBackground box
var mode2ButtonImage = LK.getAsset('menu2', {
	anchorX: 0.5,
	anchorY: 0.5
});
mode2Button.addChild(mode2ButtonImage);
mode2Button.x = lanes[1]; // Center the mode 2 button over the middle lane
mode2Button.y = 2732 / 2 + 400;
mainMenu.addChildAt(mode2Button, mainMenu.children.length);
// Add event listeners for buttons
mode1Button.down = function () {
	LK.getSound('select').play();
	startGame('mode1');
};
mode2Button.down = function () {
	LK.getSound('select').play();
	startGame('mode2');
};
// Function to start the game
function startGame(mode) {
	mainMenu.visible = false;
	scoreTxt.visible = true; // Show score when game starts
	scoreBackground.visible = true; // Show score background when game starts
	milesTxt.visible = true; // Show miles when game starts
	milesBackground.visible = true; // Show miles background when game starts
	// Background music is already playing from the main menu
	// Initialize game elements based on selected mode
	obstacleSpawnOrder = []; // Reset obstacleSpawnOrder to default
	if (mode === 'mode1') {
		// Initialize mode 1 specific elements
		obstacleSpawnOrder = [{
			type: 'TextObstacle',
			interval: 100,
			text: 'Swipe LEFT or RIGHT!'
		}, {
			type: 'SmallObstacle',
			interval: 100
		}, {
			type: 'SmallObstacleLeftMiddleCoinRight',
			interval: 100
		}, {
			type: 'SmallObstacleRightCenterCoinLeft',
			interval: 100
		}, {
			type: 'TextObstacle',
			interval: 100,
			text: 'Swipe UP to JUMP!'
		}, {
			type: 'LineObstacle',
			interval: 100
		}, {
			type: 'SmallObstaclesSidesCoinMiddle',
			interval: 100
		}, {
			type: 'TextObstacle',
			interval: 100,
			text: 'Swipe DOWN to SPLIT!'
		}, {
			type: 'BigObstacle',
			interval: 150
		}, {
			type: 'SmallObstaclesSidesCoinMiddle',
			interval: 100
		}, {
			type: 'TextObstacle',
			interval: 100,
			text: 'Collect SHIELD!'
		}, {
			type: 'PowerUpCenterLane',
			interval: 100
		}, {
			type: 'ObstacleLine',
			interval: 50
		}, {
			type: 'ObstacleLine',
			interval: 50
		}, {
			type: 'ObstacleLine',
			interval: 50
		}, {
			type: 'TextObstacle',
			interval: 100,
			text: 'You are READY!'
		}];
	} else if (mode === 'mode2') {
		// Initialize mode 2 specific elements
		obstacleSpawnOrder = [{
			type: 'SmallObstacle',
			interval: 100
		}, {
			type: 'SmallObstacleLeftMiddleCoinRight',
			interval: 100
		}, {
			type: 'SmallObstacleRightCenterCoinLeft',
			interval: 100
		}, {
			type: 'LineObstacle',
			interval: 100
		}, {
			type: 'SmallObstacleCenterCoinLeftPowerUpRight',
			interval: 100
		}, {
			type: 'SmallObstaclesSidesCoinMiddle',
			interval: 100
		}, {
			type: 'SmallObstacleCenterCoinSides',
			interval: 100
		}, {
			type: 'SmallObstacleMiddlePowerUpLeftCoinRight',
			interval: 100
		}, {
			type: 'BigObstacle',
			interval: 150
		}];
		obstacleSpawnOrder = obstacleSpawnOrder.sort(function () {
			return Math.random() - 0.5;
		});
	}
	// Start the game
	var timeout = LK.setTimeout(function () {
		gameStarted = true;
	}, 500);
}
// Function to spawn TextObstacle
function spawnTextObstacle(customText) {
	var textObstacle = new TextObstacle(customText);
	textObstacle.x = 2048 / 2; // Center the TextObstacle
	textObstacle.y = -textObstacle.height * 2;
	if (!obstacles) {
		obstacles = [];
	}
	obstacles.push(textObstacle);
	game.addChild(textObstacle);
}
// Function to spawn powerups
function spawnPowerUp(lane) {
	var powerup = new PowerUp();
	powerup.lane = lane;
	powerup.x = lanes[powerup.lane];
	powerup.y = -powerup.height * 2;
	powerups.push(powerup);
	game.addChild(powerup);
}
// Initialize gameStarted flag
var gameStarted = false;
// Initialize array for powerups
var powerups = [];
// Initialize shadow
var shadow;
// Initialize lanes
var lanes = [2048 / 4, 2048 / 2, 2048 / 4 * 3];
// Ensure lanes array is properly initialized before accessing its elements
if (!lanes || lanes.length < 3) {
	console.error("Lanes array is not properly initialized.");
	lanes = [2048 / 4, 2048 / 2, 2048 / 4 * 3]; // Reinitialize lanes array
}
// Ensure lanes array is properly initialized before accessing its elements
if (!lanes || lanes.length < 3) {
	console.error("Lanes array is not properly initialized.");
	lanes = [2048 / 4, 2048 / 2, 2048 / 4 * 3]; // Reinitialize lanes array
}
// Initialize starfield
// Initialize lane separators
var laneSeparators = [];
for (var i = 1; i < lanes.length; i++) {
	var separator = new LaneSeparator();
	separator.x = (lanes[i - 1] + lanes[i]) / 2; // Position separator between lanes
	separator.y = 0;
	laneSeparators.push(separator);
	game.addChildAt(separator, 0); // Add lane separators at the bottom of the z axis
}
// Initialize lane outlines
var leftLaneOutline = new LeftLaneOutline();
leftLaneOutline.x = lanes[0] - (lanes[1] - lanes[0]) / 2; // Position left outline to the left of the first lane
leftLaneOutline.y = 0;
game.addChildAt(leftLaneOutline, 0); // Add left lane outline at the bottom of the z axis
var rightLaneOutline = new RightLaneOutline();
rightLaneOutline.x = lanes[2] + (lanes[2] - lanes[1]) / 2; // Position right outline to the right of the last lane
rightLaneOutline.y = 0;
game.addChildAt(rightLaneOutline, 0); // Add right lane outline at the bottom of the z axis
// Initialize player
var player = game.addChild(new Player());
player.hitbox = [player];
player.lane = 1; // Start in the middle lane
player.x = lanes[player.lane];
player.y = 2732 - 200 - 350;
// Declare left and right players
var leftPlayer;
var rightPlayer;
// Initialize arrays for obstacles and coins
var obstacles = [];
var coins = [];
// Initialize split duration timer
var splitDuration = 120; // Duration in frames (2 seconds at 60 FPS)
var splitTimer = 0;
// Initialize score
var score = 0;
// Initialize final score
var finalScore = 0;
// Initialize game speed
var gameSpeed = 5;
// Initialize global spawn interval
var globalSpawnInterval = 120; // Default interval in frames (2 seconds at 60 FPS)
var scoreTxt = null;
scoreTxt = new Text2('0', {
	size: 50,
	fill: "#ffffff",
	stroke: "#000000",
	strokeThickness: 5,
	border: true,
	borderColor: "#000000",
	borderWidth: 3
});
var scoreBackground = LK.getAsset('scoreBackground', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: scoreTxt.x + 550,
	y: scoreTxt.y + scoreTxt.height / 2 + 200
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.x += 600;
scoreTxt.y += 200;
scoreTxt.visible = false; // Hide score on main menu
scoreBackground.visible = false; // Hide score background on main menu
LK.gui.top.addChild(scoreBackground);
LK.gui.top.addChild(scoreTxt);
// Configuration for defining the order in which obstacles will spawn
var obstacleSpawnOrder = [{
	type: 'TextObstacle',
	// New TextObstacle type
	interval: 100,
	text: 'Swipe LEFT or RIGHT!' // Custom text for TextObstacle
}, {
	type: 'SmallObstacle',
	interval: 100
}, {
	type: 'SmallObstacleLeftMiddleCoinRight',
	interval: 100
}, {
	type: 'SmallObstacleRightCenterCoinLeft',
	interval: 100
}, {
	type: 'TextObstacle',
	// New TextObstacle type
	interval: 100,
	text: 'Swipe UP to JUMP!' // Custom text for TextObstacle
}, {
	type: 'LineObstacle',
	interval: 100
}, {
	type: 'SmallObstacleCenterCoinLeftPowerUpRight',
	interval: 100
}, {
	type: 'SmallObstaclesSidesCoinMiddle',
	interval: 100
}, {
	type: 'TextObstacle',
	// New TextObstacle type
	interval: 100,
	text: 'Swipe DOWN to SPLIT!' // Custom text for TextObstacle
}, {
	type: 'BigObstacle',
	interval: 100
}, {
	type: 'SmallObstaclesSidesCoinMiddle',
	interval: 100
}, {
	type: 'LineObstacle',
	interval: 100
}, {
	type: 'SmallObstacleRightCenterCoinLeft',
	interval: 100
}, {
	type: 'TextObstacle',
	// New TextObstacle type
	interval: 100,
	text: 'Avoid the Obstacles!' // Custom text for TextObstacle
}];
var currentObstacleIndex = 0;
var obstacleSpawnTimer = 0;
var obstacleSpawnOrderRandom = [{
	type: 'SmallObstacle',
	interval: 100
}, {
	type: 'SmallObstacleLeftMiddleCoinRight',
	interval: 100
}, {
	type: 'SmallObstacleRightCenterCoinLeft',
	interval: 100
}, {
	type: 'LineObstacle',
	interval: 100
}, {
	type: 'SmallObstacleCenterCoinLeftPowerUpRight',
	interval: 100
}, {
	type: 'SmallObstaclesSidesCoinMiddle',
	interval: 100
}, {
	type: 'SmallObstacleCenterCoinSides',
	interval: 100
}, {
	type: 'BigObstacle',
	interval: 150
}];
// Initialize queue for predicting next obstacle
var obstacleQueue = [];
// Function to spawn obstacles
function spawnObstacle(lane) {
	var obstacle;
	if (lane === undefined) {
		obstacle = new LineObstacle();
		obstacle.x = 2048 / 2; // Center the LineObstacle
	} else {
		obstacle = new Obstacle();
		obstacle.lane = lane;
		obstacle.x = lanes[obstacle.lane];
	}
	obstacle.y = -obstacle.height * 2;
	obstacle.speed = gameSpeed; // Ensure constant speed
	if (!obstacles) {
		obstacles = [];
	}
	obstacles.push(obstacle);
	game.addChild(obstacle);
}
// Function to spawn BigObstacle with specific rules
function spawnBigObstacle() {
	var bigObstacle = new BigObstacle();
	bigObstacle.x = 2048 / 2; // Center the BigObstacle
	bigObstacle.y = -bigObstacle.height / 4;
	if (!obstacles) {
		obstacles = [];
	}
	obstacles.push(bigObstacle);
	game.addChild(bigObstacle);
}
// Function to spawn coins
function spawnCoin(lane) {
	var coin = new Coin();
	coin.lane = lane;
	coin.x = lanes[coin.lane];
	coin.y = -coin.height * 2;
	coins.push(coin);
	game.addChild(coin);
}
// Function to spawn powerups
// Handle swipe events for player movement
var touchStartX = 0;
var touchStartY = 0;
game.down = function (x, y, obj) {
	if (!gameStarted) {
		return;
	} // Prevent player movement when the home screen is up
	touchStartX = x;
	touchStartY = y;
};
game.up = function (x, y, obj) {
	if (!gameStarted) {
		return;
	} // Prevent player movement when the home screen is up
	if (Math.abs(y - touchStartY) > Math.abs(x - touchStartX)) {
		if (y < touchStartY && !leftPlayer && !rightPlayer) {
			player.jump();
		} else if (y > touchStartY && !leftPlayer && !rightPlayer && !player.isJumping && player.lane === 1) {
			// Animate leftPlayer and rightPlayer to move to the sides
			var leftTargetX = player.x - 650;
			var rightTargetX = player.x + 550;
			var animationDuration = 20; // Duration in frames (0.33 seconds at 60 FPS)
			if (!leftPlayer) {
				leftPlayer = new LeftPlayer();
				leftPlayer.x = player.x;
				leftPlayer.y = player.y;
				game.addChild(leftPlayer);
			}
			if (!rightPlayer) {
				rightPlayer = new RightPlayer();
				rightPlayer.x = player.x;
				rightPlayer.y = player.y;
				game.addChild(rightPlayer);
			}
			// Play swipe sound when player splits
			LK.getSound('swipe').play();
			player.visible = false; // Hide the original player
			player.hitbox = [leftPlayer, rightPlayer]; // Move player hitbox to left and right players
			// Initialize update functions after adding to game
			if (!leftPlayer) {
				leftPlayer = new LeftPlayer();
				leftPlayer.x = player.x;
				leftPlayer.y = player.y;
				game.addChild(leftPlayer);
				leftPlayer.update = function () {
					if (animationDuration > 0) {
						leftPlayer.x += (leftTargetX - leftPlayer.x) / animationDuration;
						animationDuration--;
					}
					if (LK.ticks % 4 == 0) {
						var trail = new Trail();
						trail.scale.x = 0.5;
						trail.scale.y = 0.5;
						if (leftPlayer && leftPlayer.x !== undefined) {
							trail.x = leftPlayer.x;
						} else {
							trail.x = 0;
						}
						trail.y = this.y + (leftPlayer.height ? leftPlayer.height / 2 : 0);
						game.addChildAt(trail, game.getChildIndex(this));
					}
				};
			}
			if (!rightPlayer) {
				rightPlayer = new RightPlayer();
				rightPlayer.x = player.x;
				rightPlayer.y = player.y;
				game.addChild(rightPlayer);
				if (!rightPlayer) {
					rightPlayer = new RightPlayer();
					rightPlayer.x = player.x;
					rightPlayer.y = player.y;
					game.addChild(rightPlayer);
					rightPlayer.update = function () {
						if (animationDuration > 0) {
							rightPlayer.x += (rightTargetX - rightPlayer.x) / animationDuration;
							animationDuration--;
						}
						if (LK.ticks % 4 == 0) {
							var trail = new Trail();
							trail.scale.x = 0.5;
							trail.scale.y = 0.5;
							if (rightPlayer && rightPlayer.x !== undefined) {
								trail.x = rightPlayer.x;
							} else {
								trail.x = 0;
							}
							trail.y = this.y + (rightPlayer.height ? rightPlayer.height / 2 : 0);
							game.addChildAt(trail, game.getChildIndex(this));
						}
					};
				}
				// Initialize update functions after adding to game
				leftPlayer.update = function () {
					if (animationDuration > 0) {
						leftPlayer.x += (leftTargetX - leftPlayer.x) * 0.1; // Smooth movement using linear interpolation
						animationDuration--;
						titleButton.update = function () {
							if (LK.ticks % 60 < 30) {
								titleButton.y += 1;
							} else {
								titleButton.y -= 1;
							}
						};
						if (LK.ticks % 4 == 0) {
							var trail = new Trail();
							trail.scale.x = 0.5;
							trail.scale.y = 0.5;
							trail.x = leftPlayer ? leftPlayer.x : 0;
							trail.y = leftPlayer && leftPlayer.height ? leftPlayer.y + leftPlayer.height / 2 : 0;
							game.addChildAt(trail, game.getChildIndex(leftPlayer));
						}
					}
					;
				};
				rightPlayer.update = function () {
					if (animationDuration > 0) {
						rightPlayer.x += (rightTargetX - rightPlayer.x) * 0.1; // Smooth movement using linear interpolation
						animationDuration--;
					}
					mode1Button.update = function () {
						if (LK.ticks % 60 < 30) {
							mode1Button.y += 1;
						} else {
							mode1Button.y -= 1;
						}
					};
					if (LK.ticks % 4 == 0) {
						var trail = new Trail();
						trail.scale.x = 0.5;
						trail.scale.y = 0.5;
						trail.x = rightPlayer ? rightPlayer.x : 0;
						trail.y = rightPlayer && rightPlayer.height ? rightPlayer.y + rightPlayer.height / 2 : 0;
						game.addChildAt(trail, game.getChildIndex(rightPlayer));
					}
				};
			}
			;
			// Initialize update functions after adding to game
			leftPlayer.update = function () {
				if (animationDuration > 0) {
					leftPlayer.x += (leftTargetX - leftPlayer.x) / animationDuration;
					animationDuration--;
				}
				mode2Button.update = function () {
					if (LK.ticks % 60 < 30) {
						mode2Button.y += 1;
					} else {
						mode2Button.y -= 1;
					}
				};
				if (LK.ticks % 4 == 0) {
					var trail = new Trail();
					trail.scale.x = 0.5;
					trail.scale.y = 0.5;
					trail.x = leftPlayer.x;
					trail.y = leftPlayer && leftPlayer.y !== undefined ? leftPlayer.y + (leftPlayer.height ? leftPlayer.height / 2 : 0) : 0;
					game.addChildAt(trail, game.getChildIndex(leftPlayer));
				}
			};
			rightPlayer.update = function () {
				if (animationDuration > 0) {
					rightPlayer.x += (rightTargetX - rightPlayer.x) / animationDuration;
					animationDuration--;
				}
				// Add any specific update logic for RightPlayer here
				if (LK.ticks % 4 == 0) {
					var trail = new Trail();
					trail.scale.x = 0.5;
					trail.scale.y = 0.5;
					trail.x = rightPlayer ? rightPlayer.x : 0;
					trail.y = rightPlayer.y + rightPlayer.height / 2;
					game.addChildAt(trail, game.getChildIndex(rightPlayer));
				}
			};
			// Initialize update functions after adding to game
			leftPlayer.update = function () {
				if (animationDuration > 0) {
					leftPlayer.x += (leftTargetX - leftPlayer.x) / animationDuration;
					animationDuration--;
				}
				// Add any specific update logic for LeftPlayer here
				if (LK.ticks % 4 == 0) {
					var trail = new Trail();
					trail.scale.x = 0.5;
					trail.scale.y = 0.5;
					trail.x = leftPlayer ? leftPlayer.x : 0;
					trail.y = leftPlayer && leftPlayer.y !== undefined ? leftPlayer.y + (leftPlayer.height ? leftPlayer.height / 2 : 0) : 0;
					game.addChildAt(trail, game.getChildIndex(leftPlayer));
				}
			};
			rightPlayer.update = function () {
				if (animationDuration > 0) {
					rightPlayer.x += (rightTargetX - rightPlayer.x) / animationDuration;
					animationDuration--;
				}
				// Add any specific update logic for RightPlayer here
				if (LK.ticks % 4 == 0) {
					var trail = new Trail();
					trail.scale.x = 0.5;
					trail.scale.y = 0.5;
					trail.x = rightPlayer.x;
					trail.y = rightPlayer.y + rightPlayer.height / 2;
					game.addChildAt(trail, game.getChildIndex(rightPlayer));
				}
			};
		}
		// Start split timer
		splitTimer = splitDuration;
	} else {
		if (x < touchStartX) {
			player.moveLeft();
		} else {
			player.moveRight();
		}
	}
};
// Update game logic
game.update = function () {
	// Update title button
	if (titleButton.update) {
		titleButton.update();
	}
	// Update miles traveled
	milesTraveled += gameSpeed / 30; // Increase the speed at which miles are counted
	if (milesTxt) {
		if (milesTxt) {
			if (milesTxt) {
				if (milesTxt) {
					if (milesTxt) {
						if (milesTxt) {
							if (milesTxt) {
								milesTxt.setText(Math.floor(milesTraveled));
							}
						}
					}
				}
			}
		}
	}
	// Update mode1 button
	mode1Button.update();
	// Update mode2 button
	mode2Button.update();
	// Update miles traveled
	milesTraveled += gameSpeed / 30; // Increase the speed at which miles are counted
	milesTxt.setText(Math.floor(milesTraveled));
	if (gameOverScreen) {
		if (milesTxt) {
			milesTxt.destroy();
			milesTxt = null;
		}
		if (milesBackground) {
			milesBackground.destroy();
			milesBackground = null;
		}
		if (scoreTxt) {
			scoreTxt.destroy();
			scoreTxt = null;
		}
		if (scoreBackground) {
			scoreBackground.destroy();
			scoreBackground = null;
		}
	}
	if (!gameStarted) {
		// Update starfield
		return;
	}
	// Update lane separators
	for (var i = 0; i < laneSeparators.length; i++) {
		laneSeparators[i].update();
		laneSeparators[i].children[0].height = 2732; // Ensure the height covers the entire screen height
	}
	// Update player
	player.update();
	// Increase game speed and decrease global spawn interval over time
	if (LK.ticks % 600 == 0) {
		// Increase speed every 10 seconds
		gameSpeed *= 1.05; // Increase speed by 5%
		// Decrease global spawn interval to make spawns more frequent
		globalSpawnInterval = Math.max(30, globalSpawnInterval - 10); // Ensure interval doesn't go below 30 frames (0.5 seconds)
	}
	// Update obstacles, coins, and powerups
	for (var i = powerups.length - 1; i >= 0; i--) {
		if (!gameOverScreen) {
			powerups[i].y += gameSpeed;
			powerups[i].update();
		} else {
			powerups[i].speed = 0;
		}
		if (player && !player.isJumping && player.hitbox && player.hitbox.some(function (hitbox) {
			return hitbox.intersects(powerups[i]);
		})) {
			player.isInvulnerable = true;
			player.invulnerableTimer = 600; // 10 seconds at 60 FPS
			if (leftPlayer && leftPlayer.update) {
				leftPlayer.isInvulnerable = true;
				leftPlayer.invulnerableTimer = 600;
			}
			if (rightPlayer && rightPlayer.update) {
				rightPlayer.isInvulnerable = true;
				rightPlayer.invulnerableTimer = 600;
			}
			powerups[i].destroy();
			powerups.splice(i, 1);
		}
	}
	for (var i = obstacles.length - 1; i >= 0; i--) {
		if (!gameOverScreen) {
			obstacles[i].y += gameSpeed;
			obstacles[i].update();
		} else {
			obstacles[i].speed = 0;
		}
		if (!player.isJumping && player.hitbox && player.hitbox && player.hitbox.some(function (hitbox) {
			return checkBoundingBoxCollision(hitbox, obstacles[i]) && obstacles[i].hitbox !== null;
		})) {
			if (player.isInvulnerable || gameOverScreen) {
				obstacleSpawnOrder = [];
				if (gameOverScreen) {
					game.setChildIndex(gameOverScreen, game.children.length - 1);
				}
				// Spawn particles
				for (var j = 0; j < 20; j++) {
					// Increase the number of particles to 20
					var particle = new Particle();
					particle.x = obstacles[i].x;
					particle.y = obstacles[i].y;
					particle.scale.set(1.5); // Increase the size of the particles
					particle.tint = 0x82ee3a; // Set particle color to #82ee3a
					game.addChild(particle);
				}
				// Play destroy sound when an obstacle is destroyed by the player with the shield
				LK.getSound('destroy').play();
				obstacles[i].destroy();
				obstacles.splice(i, 1);
			} else {
				gameOverScreen = new GameOverScreen();
				game.addChild(gameOverScreen);
				game.setChildIndex(gameOverScreen, game.children.length - 1);
				// Create particles for player destruction effect
				for (var j = 0; j < 30; j++) {
					var particle = new PlayerParticle();
					particle.x = player.x;
					particle.y = player.y;
					game.addChild(particle);
				}
				// Play destroy sound when game over screen appears
				LK.getSound('destroy').play();
				// Disable all hitboxes
				player.hitbox = null;
				if (leftPlayer) {
					leftPlayer.hitbox = null;
				}
				if (rightPlayer) {
					rightPlayer.hitbox = null;
				}
				for (var k = 0; k < obstacles.length; k++) {
					obstacles[k].hitbox = null;
				}
				for (var l = 0; l < coins.length; l++) {
					coins[l].hitbox = null;
				}
				for (var m = 0; m < powerups.length; m++) {
					powerups[m].hitbox = null;
				}
				LK.setTimeout(function () {
					LK.showGameOver();
				}, 5000);
			}
		}
	}
	// Handle obstacle spawning based on configuration
	obstacleSpawnTimer++;
	if (obstacleSpawnOrder.length > 0 && obstacleSpawnTimer >= obstacleSpawnOrder[currentObstacleIndex].interval) {
		var obstacleType = obstacleSpawnOrder[currentObstacleIndex].type;
		if (obstacleType === 'BigObstacle') {
			spawnBigObstacle();
		} else if (obstacleType === 'LineObstacle') {
			spawnObstacle();
		} else if (obstacleType === 'Obstacle') {
			spawnObstacle();
		} else if (obstacleType === 'SmallObstacle') {
			spawnSmallObstacle();
		} else if (obstacleType === 'SmallObstacleLeftMiddleCoinRight') {
			spawnSmallObstacleLeftMiddleCoinRight();
		} else if (obstacleType === 'SmallObstacleRightCenterCoinLeft') {
			spawnSmallObstacleRightCenterCoinLeft();
		} else if (obstacleType === 'SmallObstacleCenterCoinLeftPowerUpRight') {
			spawnSmallObstacleCenterCoinLeftPowerUpRight();
		} else if (obstacleType === 'TextObstacle') {
			var customText = obstacleSpawnOrder[currentObstacleIndex].text || 'Default Text';
			spawnTextObstacle(customText);
		} else if (obstacleType === 'ObstacleLine') {
			spawnObstacleLine();
		} else if (obstacleType === 'SmallObstaclesSidesCoinMiddle') {
			spawnSmallObstaclesSidesCoinMiddle();
		} else if (obstacleType === 'SmallObstacleCenterCoinSides') {
			spawnSmallObstacleCenterCoinSides();
		} else if (obstacleType === 'SmallObstacleMiddlePowerUpLeftCoinRight') {
			spawnSmallObstacleMiddlePowerUpLeftCoinRight();
		} else if (obstacleType === 'PowerUpCenterLane') {
			spawnPowerUpCenterLane();
		}
		currentObstacleIndex++;
		if (currentObstacleIndex >= obstacleSpawnOrder.length) {
			currentObstacleIndex = 0;
			if (obstacleSpawnOrder === obstacleSpawnOrderRandom) {
				obstacleSpawnOrder = obstacleSpawnOrderRandom.sort(function () {
					return Math.random() - 0.5;
				});
			} else {
				obstacleSpawnOrder = obstacleSpawnOrderRandom;
			}
		}
		obstacleSpawnTimer = 0;
	}
	// Handle split duration and animate back to center
	if (splitTimer > 0) {
		splitTimer--;
		if (splitTimer === 0) {
			// Animate leftPlayer and rightPlayer back to the center
			var centerX = player.x;
			var animationDuration = 20; // Duration in frames (0.33 seconds at 60 FPS)
			// Initialize update functions after adding to game
			leftPlayer.update = function () {
				if (animationDuration > 0) {
					leftPlayer.x += (centerX - leftPlayer.x) * 0.1; // Smooth movement using linear interpolation
					animationDuration--;
				} else {
					leftPlayer.destroy();
					leftPlayer = null;
					player.visible = true;
					player.hitbox = [player]; // Reset player hitbox to original player
					// Play swipe sound when player merges back together
					LK.getSound('swipe').play();
				}
				// Add any specific update logic for LeftPlayer here
				if (LK.ticks % 4 == 0) {
					var trail = new Trail();
					trail.scale.x = 0.5;
					trail.scale.y = 0.5;
					trail.x = leftPlayer ? leftPlayer.x : 0;
					trail.y = leftPlayer.y + leftPlayer.height / 2;
					game.addChildAt(trail, game.getChildIndex(leftPlayer));
				}
			};
			rightPlayer.update = function () {
				if (animationDuration > 0) {
					rightPlayer.x += (centerX - rightPlayer.x) * 0.1; // Smooth movement using linear interpolation
					animationDuration--;
				} else {
					rightPlayer.destroy();
					rightPlayer = null;
					player.visible = true;
					player.hitbox = [player]; // Reset player hitbox to original player
					// Play swipe sound when player merges back together
					LK.getSound('swipe').play();
				}
				// Add any specific update logic for RightPlayer here
				if (LK.ticks % 4 == 0) {
					var trail = new Trail();
					trail.scale.x = 0.5;
					trail.scale.y = 0.5;
					trail.x = rightPlayer ? rightPlayer.x : 0;
					trail.y = rightPlayer.y + rightPlayer.height / 2;
					game.addChildAt(trail, game.getChildIndex(rightPlayer));
				}
			};
		}
	}
	for (var i = coins.length - 1; i >= 0; i--) {
		if (!gameOverScreen) {
			coins[i].y += gameSpeed;
			coins[i].update();
		} else {
			coins[i].speed = 0;
		}
		if (player && !player.isJumping && player.hitbox && player.hitbox.some(function (hitbox) {
			return checkBoundingBoxCollision(hitbox, coins[i]);
		})) {
			score += 1;
			scoreTxt.setText(score);
			// Play bling sound
			LK.getSound('bling').play();
			// Spawn particles
			for (var j = 0; j < 10; j++) {
				var particle = new Particle();
				particle.x = coins[i].x;
				particle.y = coins[i].y;
				particle.tint = coins[i].children[0].tint; // Inherit color from the coin
				game.addChild(particle);
			}
			coins[i].destroy();
			coins.splice(i, 1);
		}
	}
	for (var i = powerups.length - 1; i >= 0; i--) {
		powerups[i].y += gameSpeed;
		powerups[i].update();
		if (player && !player.isJumping && player.hitbox && player.hitbox.some(function (hitbox) {
			return checkBoundingBoxCollision(hitbox, powerups[i]);
		})) {
			player.isInvulnerable = true;
			player.invulnerableTimer = 600; // 10 seconds at 60 FPS
			LK.getSound('powerup').play(); // Play powerup sound
			LK.getSound('powerup').play(); // Play powerup sound
			powerups[i].destroy();
			powerups.splice(i, 1);
		}
	}
	// Automatic spawning of obstacles, coins, and powerups has been removed
};
// Function to spawn SmallObstacle
function spawnSmallObstacle() {
	var smallObstacle = new SmallObstacle();
	smallObstacle.x = 2048 / 2; // Center the SmallObstacle
	smallObstacle.y = -smallObstacle.height * 2;
	smallObstacle.speed = gameSpeed; // Ensure constant speed
	if (!obstacles) {
		obstacles = [];
	}
	obstacles.push(smallObstacle);
	game.addChild(smallObstacle);
}
// Function to spawn SmallObstacle on left and middle lanes, and Coin on right lane
function spawnSmallObstacleLeftMiddleCoinRight() {
	var smallObstacleLeft = new SmallObstacle();
	var smallObstacleMiddle = new SmallObstacle();
	var coinRight = new Coin();
	smallObstacleLeft.x = lanes[0]; // Left lane
	smallObstacleMiddle.x = lanes[1]; // Middle lane
	coinRight.x = lanes[2]; // Right lane
	smallObstacleLeft.y = smallObstacleMiddle.y = coinRight.y = -smallObstacleLeft.height * 2;
	if (!obstacles) {
		obstacles = [];
	}
	if (!coins) {
		coins = [];
	}
	obstacles.push(smallObstacleLeft);
	obstacles.push(smallObstacleMiddle);
	coins.push(coinRight);
	game.addChild(smallObstacleLeft);
	game.addChild(smallObstacleMiddle);
	game.addChild(coinRight);
	// Ensure both obstacles and coin have the same speed
	var obstacleSpeed = gameSpeed;
	smallObstacleLeft.speed = smallObstacleMiddle.speed = coinRight.speed = obstacleSpeed;
	// Attach the obstacles together
	smallObstacleLeft.update = function () {
		this.y += this.speed;
		smallObstacleMiddle.y = this.y; // Move middle obstacle with left obstacle
		if (this.y > 2732 + this.height / 2) {
			this.destroy();
			smallObstacleMiddle.destroy();
		}
	};
	smallObstacleMiddle.update = function () {
		// Empty update function to prevent individual movement
	};
}
// Function to spawn SmallObstacle on right and center lanes, and Coin on left lane
function spawnSmallObstacleRightCenterCoinLeft() {
	var smallObstacleRight = new SmallObstacle();
	var smallObstacleCenter = new SmallObstacle();
	var coinLeft = new Coin();
	smallObstacleRight.x = lanes[2]; // Right lane
	smallObstacleCenter.x = lanes[1]; // Center lane
	coinLeft.x = lanes[0]; // Left lane
	smallObstacleRight.y = smallObstacleCenter.y = coinLeft.y = -smallObstacleRight.height * 2;
	if (!obstacles) {
		obstacles = [];
	}
	if (!coins) {
		coins = [];
	}
	obstacles.push(smallObstacleRight);
	obstacles.push(smallObstacleCenter);
	coins.push(coinLeft);
	game.addChild(smallObstacleRight);
	game.addChild(smallObstacleCenter);
	game.addChild(coinLeft);
	// Ensure both obstacles and coin have the same speed
	var obstacleSpeed = gameSpeed;
	smallObstacleRight.speed = smallObstacleCenter.speed = coinLeft.speed = obstacleSpeed;
	// Attach the obstacles together
	smallObstacleRight.update = function () {
		this.y += this.speed;
		smallObstacleCenter.y = this.y; // Move center obstacle with right obstacle
		if (this.y > 2732 + this.height / 2) {
			this.destroy();
			smallObstacleCenter.destroy();
		}
	};
	smallObstacleCenter.update = function () {
		// Empty update function to prevent individual movement
	};
}
// Function to spawn a line of obstacles
function spawnObstacleLine() {
	for (var i = 0; i < lanes.length; i++) {
		var obstacle = new Obstacle();
		obstacle.x = lanes[i];
		obstacle.y = -obstacle.height * 2;
		if (!obstacles) {
			obstacles = [];
		}
		obstacles.push(obstacle);
		game.addChild(obstacle);
	}
}
function spawnSmallObstacleCenterCoinLeftPowerUpRight() {
	var smallObstacleCenter = new SmallObstacle();
	smallObstacleCenter.x = lanes[1]; // Center lane
	smallObstacleCenter.y = -smallObstacleCenter.height * 2;
	smallObstacleCenter.speed = gameSpeed; // Ensure constant speed
	if (!obstacles) {
		obstacles = [];
	}
	obstacles.push(smallObstacleCenter);
	game.addChild(smallObstacleCenter);
	var coinLeft = new Coin();
	coinLeft.x = lanes[0]; // Left lane
	coinLeft.y = -coinLeft.height * 2;
	coinLeft.speed = gameSpeed; // Ensure constant speed
	if (!coins) {
		coins = [];
	}
	coins.push(coinLeft);
	game.addChild(coinLeft);
	var powerUpRight = new PowerUp();
	powerUpRight.x = lanes[2]; // Right lane
	powerUpRight.y = -powerUpRight.height * 2;
	powerUpRight.speed = gameSpeed; // Ensure constant speed
	if (!powerups) {
		powerups = [];
	}
	powerups.push(powerUpRight);
	game.addChild(powerUpRight);
}
// Function to spawn SmallObstacles on the sides and a Coin in the middle
function spawnSmallObstaclesSidesCoinMiddle() {
	var smallObstacleLeft = new SmallObstacle();
	smallObstacleLeft.x = lanes[0]; // Left lane
	smallObstacleLeft.y = -smallObstacleLeft.height * 2;
	smallObstacleLeft.speed = gameSpeed; // Ensure constant speed
	if (!obstacles) {
		obstacles = [];
	}
	obstacles.push(smallObstacleLeft);
	game.addChild(smallObstacleLeft);
	var smallObstacleRight = new SmallObstacle();
	smallObstacleRight.x = lanes[2]; // Right lane
	smallObstacleRight.y = -smallObstacleRight.height * 2;
	smallObstacleRight.speed = gameSpeed; // Ensure constant speed
	obstacles.push(smallObstacleRight);
	game.addChild(smallObstacleRight);
	var coinMiddle = new Coin();
	coinMiddle.x = lanes[1]; // Middle lane
	coinMiddle.y = -coinMiddle.height * 2;
	coinMiddle.speed = gameSpeed; // Ensure constant speed
	if (!coins) {
		coins = [];
	}
	coins.push(coinMiddle);
	game.addChild(coinMiddle);
}
// Function to spawn SmallObstacle in the center and Coins on the sides
function spawnSmallObstacleCenterCoinSides() {
	var smallObstacleCenter = new SmallObstacleCenterCoinSides();
	smallObstacleCenter.x = lanes[1]; // Center lane
	smallObstacleCenter.y = -smallObstacleCenter.height * 2;
	smallObstacleCenter.speed = gameSpeed; // Ensure constant speed
	if (!obstacles) {
		obstacles = [];
	}
	obstacles.push(smallObstacleCenter);
	game.addChild(smallObstacleCenter);
	var coinLeft = new Coin();
	coinLeft.x = lanes[0]; // Left lane
	coinLeft.y = -coinLeft.height * 2;
	coinLeft.speed = gameSpeed; // Ensure constant speed
	if (!coins) {
		coins = [];
	}
	coins.push(coinLeft);
	game.addChild(coinLeft);
	var coinRight = new Coin();
	coinRight.x = lanes[2]; // Right lane
	coinRight.y = -coinRight.height * 2;
	coinRight.speed = gameSpeed; // Ensure constant speed
	coins.push(coinRight);
	game.addChild(coinRight);
}
var starfield = [];
for (var i = 0; i < 25; i++) {
	var star = new Star();
	star.scale.set(Math.random() * 1.5 + 0.5); // Random size between 0.5 and 2.0
	star.x = Math.random() * 2048;
	star.y = Math.random() * 2732;
	star.scale.set(Math.random() * 1.5 + 0.5); // Random size between 0.5 and 2.0
	starfield.push(star);
	game.addChildAt(star, 0); // Add stars at the bottom of the z axis
}
// Initialize miles traveled
var milesTraveled = 0;
// Create miles traveled text
var milesTxt = null;
milesTxt = new Text2('Miles: 0', {
	size: 100,
	fill: "#ffffff",
	stroke: "#000000",
	strokeThickness: 5,
	border: true,
	borderColor: "#000000",
	borderWidth: 3
});
milesTxt.anchor.set(1, 0); // Anchor to the top-right corner
milesTxt.x = 2048; // Position at the top-right corner
milesTxt.y = 0;
LK.gui.topRight.addChild(milesTxt);
// Initialize miles traveled
var milesTraveled = 0;
// Create miles traveled text
var milesTxt = new Text2('0', {
	size: 50,
	fill: "#ffffff",
	stroke: "#000000",
	strokeThickness: 5,
	border: true,
	borderColor: "#000000",
	borderWidth: 3
});
var milesBackground = LK.getAsset('milesBackground', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: scoreTxt.x - 50,
	y: scoreTxt.y - 90
});
milesTxt.anchor.set(0.5, 0);
milesTxt.x = scoreTxt.x - 10;
milesTxt.y = scoreTxt.y - 120;
milesTxt.visible = false; // Hide miles on main menu
milesBackground.visible = false; // Hide miles background on main menu
LK.gui.top.addChild(milesBackground);
LK.gui.top.addChild(milesTxt); ===================================================================
--- original.js
+++ change.js
@@ -52,9 +52,9 @@
 		tint: 0x000000 // Set background color to black
 	});
 	self.addChildAt(background, self.children.length);
 	var gameOverText = new Text2('Game Over', {
-		size: 400,
+		size: 300,
 		fill: "#83de44",
 		stroke: "#000000",
 		strokeThickness: 10,
 		border: true,
@@ -93,20 +93,22 @@
 	milesText.x = 2048 / 2;
 	milesText.y = 2732 / 2 + 50;
 	self.addChild(milesText);
 	// Animate miles counter from 0 to milesTraveled
-	var currentMiles = 0;
+	var currentMiles = Math.floor(milesTraveled);
+	var currentFinalScore = 0;
 	var milesInterval = LK.setInterval(function () {
-		if (currentMiles < Math.floor(milesTraveled)) {
-			currentMiles += Math.ceil(Math.floor(milesTraveled) / 30); // Increment quickly
-			if (currentMiles > Math.floor(milesTraveled)) {
-				currentMiles = Math.floor(milesTraveled);
+		if (currentMiles > 0) {
+			currentMiles -= Math.ceil(Math.floor(milesTraveled) / 30); // Decrement quickly
+			if (currentMiles < 0) {
+				currentMiles = 0;
 			}
 			milesText.setText('Miles: ' + currentMiles);
+			currentFinalScore = Math.floor(milesTraveled) - currentMiles;
+			finalScoreText.setText('Final Score: ' + currentFinalScore);
 		} else {
 			LK.clearInterval(milesInterval);
 			var coinsText = new Text2('Coins: 0', {
-				// Animate coins counter from 0 to score after miles are done
 				size: 100,
 				fill: "#ffffff",
 				stroke: "#000000",
 				strokeThickness: 5,
@@ -128,9 +130,8 @@
 					coinsText.setText('Coins: ' + currentCoins);
 				} else {
 					LK.clearInterval(coinsInterval);
 					var finalScoreText = new Text2('Final Score: 0', {
-						// Animate final score counter from 0 to final score after coins are done
 						size: 100,
 						fill: "#ffffff",
 						stroke: "#000000",
 						strokeThickness: 5,
@@ -142,9 +143,8 @@
 					finalScoreText.x = 2048 / 2;
 					finalScoreText.y = 2732 / 2 + 250;
 					self.addChild(finalScoreText);
 					var finalScore = Math.floor(milesTraveled) + score * 100;
-					// Animate final score counter from 0 to final score
 					var currentFinalScore = 0;
 					var finalScoreInterval = LK.setInterval(function () {
 						if (currentFinalScore < finalScore) {
 							currentFinalScore += Math.ceil(finalScore / 30); // Increment quickly
@@ -154,13 +154,13 @@
 							finalScoreText.setText('Final Score: ' + currentFinalScore);
 						} else {
 							LK.clearInterval(finalScoreInterval);
 						}
-					}, 30); // Update every 30ms
+					}, 30);
 				}
-			}, 30); // Update every 30ms
+			}, 30);
 		}
-	}, 30); // Update every 30ms
+	}, 30);
 });
 // Define the LaneSeparator class
 var LaneSeparator = Container.expand(function () {
 	var self = Container.call(this);
:quality(85)/https://cdn.frvr.ai/66de8daed88e3b2f9d0d351d.png%3F3) 
 cartoon white circle. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/66de9502d88e3b2f9d0d353b.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/66de950cd88e3b2f9d0d353f.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/66de963fd88e3b2f9d0d354a.png%3F3) 
 cartoon light blue circle. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/66dea3d513f4e3322754d739.png%3F3) 
 cartoon white square. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/66debcf2db9f488945f51665.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/66debcfcdb9f488945f51669.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/66debd0ddb9f488945f5166d.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/66df0274876eb28d122afd62.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/66df1409876eb28d122afd83.png%3F3) 
 black rectangle
:quality(85)/https://cdn.frvr.ai/66e802ebf1cf1fab5fecc015.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/66f3cf9c820d0de862b6a096.png%3F3)