/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	level: 1,
	coins: 0,
	highScore: 0
});
/**** 
* Classes
****/ 
var GameElement = Container.expand(function () {
	var self = Container.call(this);
	self.speed = 0;
	self.active = true;
	self.type = 'none';
	self.lastIntersecting = false;
	self.setup = function (elementType, posX, speedValue) {
		self.type = elementType;
		self.speed = speedValue;
		self.x = posX;
		self.y = -200;
		if (elementType === 'coin') {
			var coinGraphic = self.attachAsset('coin', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			// Add shine animation
			self.animate = function () {
				tween(coinGraphic, {
					alpha: 0.5
				}, {
					duration: 500,
					easing: tween.linear,
					onFinish: function onFinish() {
						tween(coinGraphic, {
							alpha: 1
						}, {
							duration: 500,
							easing: tween.linear,
							onFinish: self.animate
						});
					}
				});
			};
			self.animate();
		} else if (elementType === 'obstacle') {
			self.attachAsset('obstacle', {
				anchorX: 0.5,
				anchorY: 0.5
			});
		} else if (elementType === 'enemyCar') {
			self.attachAsset('enemyCar', {
				anchorX: 0.5,
				anchorY: 0.5
			});
		}
	};
	self.update = function () {
		if (!self.active) return;
		self.y += self.speed;
		// Remove when off-screen
		if (self.y > 2732 + 100) {
			self.active = false;
		}
		// Rotate coins slightly for visual appeal
		if (self.type === 'coin') {
			self.rotation += 0.02;
		}
	};
	return self;
});
var GameUI = Container.expand(function () {
	var self = Container.call(this);
	// Create score text
	self.scoreText = new Text2('SCORE: 0', {
		size: 60,
		fill: 0xFFFFFF
	});
	self.scoreText.anchor.set(0, 0);
	self.addChild(self.scoreText);
	// Create coins text
	self.coinsText = new Text2('COINS: 0', {
		size: 60,
		fill: 0xF1C40F
	});
	self.coinsText.anchor.set(0, 0);
	self.coinsText.y = 70;
	self.addChild(self.coinsText);
	// Create level text
	self.levelText = new Text2('LEVEL: 1', {
		size: 60,
		fill: 0x2ECC71
	});
	self.levelText.anchor.set(0, 0);
	self.levelText.y = 140;
	self.addChild(self.levelText);
	// Create HP bar background
	self.hpBarBg = new Container();
	self.hpBarBg.x = 0;
	self.hpBarBg.y = 210;
	self.addChild(self.hpBarBg);
	var hpBarBgGraphic = LK.getAsset('road', {
		anchorX: 0,
		anchorY: 0,
		width: 300,
		height: 30,
		tint: 0x555555
	});
	self.hpBarBg.addChild(hpBarBgGraphic);
	// Create HP bar fill
	self.hpBarFill = new Container();
	self.hpBarFill.x = 0;
	self.hpBarFill.y = 210;
	self.addChild(self.hpBarFill);
	var hpBarFillGraphic = LK.getAsset('road', {
		anchorX: 0,
		anchorY: 0,
		width: 300,
		height: 30,
		tint: 0x27ae60
	});
	self.hpBarFill.addChild(hpBarFillGraphic);
	// Create HP text
	self.hpText = new Text2('HP: 100%', {
		size: 40,
		fill: 0xFFFFFF
	});
	self.hpText.anchor.set(0, 0.5);
	self.hpText.x = 10;
	self.hpText.y = 225;
	self.addChild(self.hpText);
	// Update UI elements
	self.update = function (score, coins, level, hp) {
		self.scoreText.setText('SCORE: ' + score);
		self.coinsText.setText('COINS: ' + coins);
		self.levelText.setText('LEVEL: ' + level);
		if (hp !== undefined) {
			// Update HP bar
			var hpPercent = Math.max(0, Math.min(100, hp));
			self.hpBarFill.children[0].width = 3 * hpPercent;
			self.hpText.setText('HP: ' + hpPercent + '%');
			// Change color based on HP level
			if (hpPercent > 60) {
				self.hpBarFill.children[0].tint = 0x27ae60; // Green
			} else if (hpPercent > 30) {
				self.hpBarFill.children[0].tint = 0xf39c12; // Orange
			} else {
				self.hpBarFill.children[0].tint = 0xe74c3c; // Red
			}
		}
	};
	return self;
});
// Game variables
var PlayerCar = Container.expand(function () {
	var self = Container.call(this);
	// Create car graphics
	var carGraphics = self.attachAsset('playerCar', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Car properties
	self.speed = 0;
	self.maxSpeed = 40; // Increased from 25
	self.acceleration = 0.5; // Increased from 0.3
	self.deceleration = 0.1;
	self.handling = 10;
	self.isAccelerating = true;
	self.hp = 100;
	self.level = 1;
	self.upgradePoints = 0;
	// Track last positions for collision detection
	self.lastX = 0;
	self.lastY = 0;
	// Control methods
	self.moveLeft = function () {
		if (self.x > roadLeftEdge + self.width / 2 + 10) {
			self.x -= self.handling;
		}
	};
	self.moveRight = function () {
		if (self.x < roadRightEdge - self.width / 2 - 10) {
			self.x += self.handling;
		}
	};
	self.update = function () {
		// Store last position
		self.lastX = self.x;
		self.lastY = self.y;
		// Update speed
		if (self.isAccelerating && self.speed < self.maxSpeed) {
			self.speed += self.acceleration;
		} else if (!self.isAccelerating && self.speed > 0) {
			self.speed -= self.deceleration;
		}
		if (self.speed < 0) self.speed = 0;
		// Apply visual effects based on speed
		var speedRatio = self.speed / self.maxSpeed;
		carGraphics.scaleX = 1 + speedRatio * 0.1;
		carGraphics.scaleY = 1 - speedRatio * 0.05;
	};
	self.crash = function () {
		self.isAccelerating = false;
		self.speed = Math.max(0, self.speed * 0.5);
		// Reduce HP
		self.hp = Math.max(0, self.hp - 20);
		// Visual feedback for crash
		LK.effects.flashObject(self, 0xff0000, 500);
		LK.getSound('crash').play();
	};
	self.upgrade = function (type, amount) {
		if (type === 'speed') {
			self.maxSpeed += amount;
		} else if (type === 'handling') {
			self.handling += amount;
		} else if (type === 'acceleration') {
			self.acceleration += amount * 0.05;
		} else if (type === 'hp') {
			self.hp = Math.min(100, self.hp + amount);
		} else if (type === 'levelUp') {
			self.level++;
			self.maxSpeed += 2;
			self.handling += 1;
			self.acceleration += 0.05;
			self.hp = 100;
			// Visual feedback for car level up
			LK.effects.flashObject(self, 0x3498db, 1000);
			// Fire projectiles when car levels up
			fireProjectiles(self.x, self.y);
		}
	};
	return self;
});
var Projectile = Container.expand(function () {
	var self = Container.call(this);
	// Projectile properties
	self.speed = 0;
	self.active = true;
	self.lastY = 0;
	// Create projectile graphics
	var projectileGraphic = self.attachAsset('playerCar', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 40,
		tint: 0x3498db
	});
	// Initialize projectile
	self.setup = function (posX, posY, speedValue) {
		self.x = posX;
		self.y = posY;
		self.lastY = posY;
		self.speed = speedValue;
		self.rotation = -Math.PI / 2; // Point upward
	};
	// Update projectile position
	self.update = function () {
		if (!self.active) return;
		self.lastY = self.y;
		self.y -= self.speed;
		// Remove when off-screen
		if (self.y < -100) {
			self.active = false;
		}
	};
	return self;
});
var RoadElement = Container.expand(function () {
	var self = Container.call(this);
	self.speed = 0;
	self.type = 'none';
	self.setup = function (elementType, speedValue) {
		self.type = elementType;
		self.speed = speedValue;
		if (elementType === 'road') {
			self.roadGraphic = self.attachAsset('road', {
				anchorX: 0.5,
				anchorY: 0
			});
		} else if (elementType === 'line') {
			self.lineGraphic = self.attachAsset('roadLine', {
				anchorX: 0.5,
				anchorY: 0.5
			});
		}
	};
	self.update = function () {
		self.y += self.speed;
		// Loop road elements
		if (self.type === 'road' && self.y > 2732) {
			self.y = -self.roadGraphic.height + 10;
		}
		// Loop road lines
		if (self.type === 'line' && self.y > 2732) {
			self.y = -100;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Initialize sound effects
// Initialize car assets
//Storage library for persistent game data
//Minimalistic tween library for animations
// Game variables
var score = 0;
var coins = storage.coins || 0;
var level = storage.level || 1;
var highScore = storage.highScore || 0;
var gameSpeed = 5 + level * 0.5;
var roadWidth = 600;
var roadLeftEdge = (2048 - roadWidth) / 2;
var roadRightEdge = roadLeftEdge + roadWidth;
var spawnTimer = 0;
var gameActive = true;
var levelProgress = 0;
var pointsToNextLevel = 1000;
// Game elements
var playerCar;
var roadElements = [];
var gameElements = [];
var projectiles = [];
var gameUI;
// Create game UI and add to GUI layer
gameUI = new GameUI();
gameUI.x = 50;
gameUI.y = 50;
LK.gui.topLeft.addChild(gameUI);
// Create road
function setupRoad() {
	// Create main road
	for (var i = 0; i < 2; i++) {
		var road = new RoadElement();
		road.setup('road', gameSpeed);
		road.x = 2048 / 2;
		road.y = i * road.roadGraphic.height - (i > 0 ? 10 : 0);
		roadElements.push(road);
		game.addChild(road);
	}
	// Create road lines
	var lineSpacing = 200;
	for (var j = 0; j < 15; j++) {
		var line = new RoadElement();
		line.setup('line', gameSpeed);
		line.x = 2048 / 2;
		line.y = j * lineSpacing;
		roadElements.push(line);
		game.addChild(line);
	}
}
// Create player car
function setupPlayer() {
	playerCar = new PlayerCar();
	playerCar.x = 2048 / 2;
	playerCar.y = 2732 - 300;
	game.addChild(playerCar);
}
// Spawn game elements (coins, obstacles, enemy cars)
function spawnGameElement() {
	if (!gameActive) return;
	// Determine what to spawn based on random chance
	var rand = Math.random();
	var type, lanePosition;
	// Calculate available lanes
	var laneWidth = roadWidth / 3;
	var lanes = [roadLeftEdge + laneWidth / 2, roadLeftEdge + laneWidth + laneWidth / 2, roadLeftEdge + laneWidth * 2 + laneWidth / 2];
	// Choose random lane
	lanePosition = lanes[Math.floor(Math.random() * lanes.length)];
	// Determine element type
	if (rand < 0.4) {
		type = 'coin';
	} else if (rand < 0.7) {
		type = 'obstacle';
	} else {
		type = 'enemyCar';
	}
	var element = new GameElement();
	element.setup(type, lanePosition, gameSpeed);
	gameElements.push(element);
	game.addChild(element);
	// Add some variation to spawn rate
	spawnTimer = 60 + Math.floor(Math.random() * 60);
}
// Initialize game
function initGame() {
	// Reset game state
	score = 0;
	levelProgress = 0;
	gameSpeed = 5 + level * 0.5;
	gameActive = true;
	// Clear existing elements
	for (var i = 0; i < roadElements.length; i++) {
		roadElements[i].destroy();
	}
	roadElements = [];
	for (var j = 0; j < gameElements.length; j++) {
		gameElements[j].destroy();
	}
	gameElements = [];
	// Clear projectiles
	for (var k = 0; k < projectiles.length; k++) {
		projectiles[k].destroy();
	}
	projectiles = [];
	clearProjectileInterval();
	// Setup game elements
	setupRoad();
	setupPlayer();
	// Update UI
	gameUI.update(score, coins, level, playerCar.hp);
}
// Update score and check for level up
function updateScore(points) {
	score += points;
	levelProgress += points;
	// Level up when enough points are collected
	if (levelProgress >= pointsToNextLevel) {
		levelUp();
	}
	// Update high score
	if (score > highScore) {
		highScore = score;
		storage.highScore = highScore;
	}
	// Update UI
	gameUI.update(score, coins, level);
}
// Handle level up
function levelUp() {
	level++;
	storage.level = level;
	levelProgress = 0;
	gameSpeed += 0.5;
	// Increase points needed for next level
	pointsToNextLevel = 1000 + level * 500;
	// Visual feedback
	LK.effects.flashScreen(0x2ecc71, 500);
	LK.getSound('levelUp').play();
	// Update road and element speeds
	for (var i = 0; i < roadElements.length; i++) {
		roadElements[i].speed = gameSpeed;
	}
	// Update UI
	gameUI.update(score, coins, level);
}
// Handle coin collection
function collectCoin(element) {
	coins++;
	storage.coins = coins;
	updateScore(50);
	// Restore some HP
	playerCar.upgrade('hp', 5);
	// Visual feedback
	LK.effects.flashObject(element, 0xf1c40f, 300);
	LK.getSound('coinCollect').play();
	// Remove coin
	element.active = false;
	game.removeChild(element);
	// Check if player can level up car
	if (coins >= playerCar.level * 10) {
		coins -= playerCar.level * 10;
		storage.coins = coins;
		playerCar.upgrade('levelUp');
		LK.effects.flashScreen(0x3498db, 500);
	}
	// Update UI with new HP
	gameUI.update(score, coins, level, playerCar.hp);
}
// Handle collision with obstacle or enemy car
function handleCollision(element) {
	playerCar.crash();
	updateScore(-100);
	// Visual feedback
	LK.effects.flashObject(element, 0xff0000, 300);
	// Remove obstacle
	element.active = false;
	game.removeChild(element);
	// Update HP display
	gameUI.update(score, coins, level, playerCar.hp);
	// Check if game over
	if (score <= 0 || playerCar.hp <= 0) {
		gameOver();
	}
}
// Fire projectiles when car levels up
var projectileInterval = null;
function fireProjectiles(startX, startY) {
	// Fire multiple projectiles in different patterns based on car level
	var count = Math.min(playerCar.level, 5); // Max 5 projectiles
	for (var i = 0; i < count; i++) {
		var projectile = new Projectile();
		var offset = (i - (count - 1) / 2) * 50; // Spread projectiles horizontally
		projectile.setup(startX + offset, startY - 50, 20);
		projectiles.push(projectile);
		game.addChild(projectile);
	}
	// Play sound effect
	LK.getSound('levelUp').play();
	// Start continuous firing if not already started
	if (!projectileInterval) {
		projectileInterval = LK.setInterval(function () {
			if (!gameActive) return;
			// Only fire if playerCar is still in game and leveled up at least once
			if (playerCar && playerCar.level > 1) {
				var count = Math.min(playerCar.level, 5);
				for (var i = 0; i < count; i++) {
					var projectile = new Projectile();
					var offset = (i - (count - 1) / 2) * 50;
					projectile.setup(playerCar.x + offset, playerCar.y - 50, 20);
					projectiles.push(projectile);
					game.addChild(projectile);
				}
			}
		}, 300); // Fire every 300ms
	}
}
// Clear projectile interval on game over or reset
function clearProjectileInterval() {
	if (projectileInterval) {
		LK.clearInterval(projectileInterval);
		projectileInterval = null;
	}
}
// Game over
function gameOver() {
	gameActive = false;
	clearProjectileInterval();
	LK.effects.flashScreen(0xe74c3c, 1000);
	LK.showGameOver();
}
// Initialize the game
initGame();
// Game update loop
game.update = function () {
	if (!gameActive) return;
	// Update player car
	playerCar.update();
	// Update road elements
	for (var i = 0; i < roadElements.length; i++) {
		roadElements[i].update();
	}
	// Update game elements and check collisions
	for (var j = gameElements.length - 1; j >= 0; j--) {
		var element = gameElements[j];
		element.update();
		// Remove inactive elements
		if (!element.active) {
			gameElements.splice(j, 1);
			continue;
		}
		// Check for collisions
		var wasIntersecting = element.lastIntersecting;
		var isIntersecting = element.intersects(playerCar);
		element.lastIntersecting = isIntersecting;
		// Handle new intersections
		if (!wasIntersecting && isIntersecting) {
			if (element.type === 'coin') {
				collectCoin(element);
			} else {
				handleCollision(element);
			}
		}
	}
	// Update projectiles and check for collisions
	for (var p = projectiles.length - 1; p >= 0; p--) {
		var projectile = projectiles[p];
		projectile.update();
		// Remove inactive projectiles
		if (!projectile.active) {
			game.removeChild(projectile);
			projectiles.splice(p, 1);
			continue;
		}
		// Check for collisions with game elements
		for (var e = gameElements.length - 1; e >= 0; e--) {
			var element = gameElements[e];
			if (element.type !== 'coin' && projectile.intersects(element)) {
				// Remove the element
				element.active = false;
				game.removeChild(element);
				gameElements.splice(e, 1);
				// Give points for destroying obstacles with projectiles
				updateScore(25);
				// Create visual effect
				LK.effects.flashObject(projectile, 0xffffff, 200);
				// Remove the projectile
				projectile.active = false;
				game.removeChild(projectile);
				projectiles.splice(p, 1);
				break;
			}
		}
	}
	// Increment score based on speed
	if (LK.ticks % 10 === 0) {
		updateScore(Math.floor(playerCar.speed));
		gameUI.update(score, coins, level, playerCar.hp);
	}
	// Spawn new game elements
	if (spawnTimer <= 0) {
		spawnGameElement();
	} else {
		spawnTimer--;
	}
	// Add points for progress
	if (LK.ticks % 60 === 0) {
		updateScore(1);
	}
};
// Touch controls
game.down = function (x, y, obj) {
	if (!gameActive) return;
	// Determine which side of the screen was touched
	if (x < 2048 / 2) {
		playerCar.moveLeft();
	} else {
		playerCar.moveRight();
	}
};
game.move = function (x, y, obj) {
	if (!gameActive) return;
	// Determine which side of the screen is being touched
	if (x < 2048 / 2) {
		playerCar.moveLeft();
	} else {
		playerCar.moveRight();
	}
};
// Set game background color
game.setBackgroundColor(0x1a1a2e); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	level: 1,
	coins: 0,
	highScore: 0
});
/**** 
* Classes
****/ 
var GameElement = Container.expand(function () {
	var self = Container.call(this);
	self.speed = 0;
	self.active = true;
	self.type = 'none';
	self.lastIntersecting = false;
	self.setup = function (elementType, posX, speedValue) {
		self.type = elementType;
		self.speed = speedValue;
		self.x = posX;
		self.y = -200;
		if (elementType === 'coin') {
			var coinGraphic = self.attachAsset('coin', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			// Add shine animation
			self.animate = function () {
				tween(coinGraphic, {
					alpha: 0.5
				}, {
					duration: 500,
					easing: tween.linear,
					onFinish: function onFinish() {
						tween(coinGraphic, {
							alpha: 1
						}, {
							duration: 500,
							easing: tween.linear,
							onFinish: self.animate
						});
					}
				});
			};
			self.animate();
		} else if (elementType === 'obstacle') {
			self.attachAsset('obstacle', {
				anchorX: 0.5,
				anchorY: 0.5
			});
		} else if (elementType === 'enemyCar') {
			self.attachAsset('enemyCar', {
				anchorX: 0.5,
				anchorY: 0.5
			});
		}
	};
	self.update = function () {
		if (!self.active) return;
		self.y += self.speed;
		// Remove when off-screen
		if (self.y > 2732 + 100) {
			self.active = false;
		}
		// Rotate coins slightly for visual appeal
		if (self.type === 'coin') {
			self.rotation += 0.02;
		}
	};
	return self;
});
var GameUI = Container.expand(function () {
	var self = Container.call(this);
	// Create score text
	self.scoreText = new Text2('SCORE: 0', {
		size: 60,
		fill: 0xFFFFFF
	});
	self.scoreText.anchor.set(0, 0);
	self.addChild(self.scoreText);
	// Create coins text
	self.coinsText = new Text2('COINS: 0', {
		size: 60,
		fill: 0xF1C40F
	});
	self.coinsText.anchor.set(0, 0);
	self.coinsText.y = 70;
	self.addChild(self.coinsText);
	// Create level text
	self.levelText = new Text2('LEVEL: 1', {
		size: 60,
		fill: 0x2ECC71
	});
	self.levelText.anchor.set(0, 0);
	self.levelText.y = 140;
	self.addChild(self.levelText);
	// Create HP bar background
	self.hpBarBg = new Container();
	self.hpBarBg.x = 0;
	self.hpBarBg.y = 210;
	self.addChild(self.hpBarBg);
	var hpBarBgGraphic = LK.getAsset('road', {
		anchorX: 0,
		anchorY: 0,
		width: 300,
		height: 30,
		tint: 0x555555
	});
	self.hpBarBg.addChild(hpBarBgGraphic);
	// Create HP bar fill
	self.hpBarFill = new Container();
	self.hpBarFill.x = 0;
	self.hpBarFill.y = 210;
	self.addChild(self.hpBarFill);
	var hpBarFillGraphic = LK.getAsset('road', {
		anchorX: 0,
		anchorY: 0,
		width: 300,
		height: 30,
		tint: 0x27ae60
	});
	self.hpBarFill.addChild(hpBarFillGraphic);
	// Create HP text
	self.hpText = new Text2('HP: 100%', {
		size: 40,
		fill: 0xFFFFFF
	});
	self.hpText.anchor.set(0, 0.5);
	self.hpText.x = 10;
	self.hpText.y = 225;
	self.addChild(self.hpText);
	// Update UI elements
	self.update = function (score, coins, level, hp) {
		self.scoreText.setText('SCORE: ' + score);
		self.coinsText.setText('COINS: ' + coins);
		self.levelText.setText('LEVEL: ' + level);
		if (hp !== undefined) {
			// Update HP bar
			var hpPercent = Math.max(0, Math.min(100, hp));
			self.hpBarFill.children[0].width = 3 * hpPercent;
			self.hpText.setText('HP: ' + hpPercent + '%');
			// Change color based on HP level
			if (hpPercent > 60) {
				self.hpBarFill.children[0].tint = 0x27ae60; // Green
			} else if (hpPercent > 30) {
				self.hpBarFill.children[0].tint = 0xf39c12; // Orange
			} else {
				self.hpBarFill.children[0].tint = 0xe74c3c; // Red
			}
		}
	};
	return self;
});
// Game variables
var PlayerCar = Container.expand(function () {
	var self = Container.call(this);
	// Create car graphics
	var carGraphics = self.attachAsset('playerCar', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Car properties
	self.speed = 0;
	self.maxSpeed = 40; // Increased from 25
	self.acceleration = 0.5; // Increased from 0.3
	self.deceleration = 0.1;
	self.handling = 10;
	self.isAccelerating = true;
	self.hp = 100;
	self.level = 1;
	self.upgradePoints = 0;
	// Track last positions for collision detection
	self.lastX = 0;
	self.lastY = 0;
	// Control methods
	self.moveLeft = function () {
		if (self.x > roadLeftEdge + self.width / 2 + 10) {
			self.x -= self.handling;
		}
	};
	self.moveRight = function () {
		if (self.x < roadRightEdge - self.width / 2 - 10) {
			self.x += self.handling;
		}
	};
	self.update = function () {
		// Store last position
		self.lastX = self.x;
		self.lastY = self.y;
		// Update speed
		if (self.isAccelerating && self.speed < self.maxSpeed) {
			self.speed += self.acceleration;
		} else if (!self.isAccelerating && self.speed > 0) {
			self.speed -= self.deceleration;
		}
		if (self.speed < 0) self.speed = 0;
		// Apply visual effects based on speed
		var speedRatio = self.speed / self.maxSpeed;
		carGraphics.scaleX = 1 + speedRatio * 0.1;
		carGraphics.scaleY = 1 - speedRatio * 0.05;
	};
	self.crash = function () {
		self.isAccelerating = false;
		self.speed = Math.max(0, self.speed * 0.5);
		// Reduce HP
		self.hp = Math.max(0, self.hp - 20);
		// Visual feedback for crash
		LK.effects.flashObject(self, 0xff0000, 500);
		LK.getSound('crash').play();
	};
	self.upgrade = function (type, amount) {
		if (type === 'speed') {
			self.maxSpeed += amount;
		} else if (type === 'handling') {
			self.handling += amount;
		} else if (type === 'acceleration') {
			self.acceleration += amount * 0.05;
		} else if (type === 'hp') {
			self.hp = Math.min(100, self.hp + amount);
		} else if (type === 'levelUp') {
			self.level++;
			self.maxSpeed += 2;
			self.handling += 1;
			self.acceleration += 0.05;
			self.hp = 100;
			// Visual feedback for car level up
			LK.effects.flashObject(self, 0x3498db, 1000);
			// Fire projectiles when car levels up
			fireProjectiles(self.x, self.y);
		}
	};
	return self;
});
var Projectile = Container.expand(function () {
	var self = Container.call(this);
	// Projectile properties
	self.speed = 0;
	self.active = true;
	self.lastY = 0;
	// Create projectile graphics
	var projectileGraphic = self.attachAsset('playerCar', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 40,
		tint: 0x3498db
	});
	// Initialize projectile
	self.setup = function (posX, posY, speedValue) {
		self.x = posX;
		self.y = posY;
		self.lastY = posY;
		self.speed = speedValue;
		self.rotation = -Math.PI / 2; // Point upward
	};
	// Update projectile position
	self.update = function () {
		if (!self.active) return;
		self.lastY = self.y;
		self.y -= self.speed;
		// Remove when off-screen
		if (self.y < -100) {
			self.active = false;
		}
	};
	return self;
});
var RoadElement = Container.expand(function () {
	var self = Container.call(this);
	self.speed = 0;
	self.type = 'none';
	self.setup = function (elementType, speedValue) {
		self.type = elementType;
		self.speed = speedValue;
		if (elementType === 'road') {
			self.roadGraphic = self.attachAsset('road', {
				anchorX: 0.5,
				anchorY: 0
			});
		} else if (elementType === 'line') {
			self.lineGraphic = self.attachAsset('roadLine', {
				anchorX: 0.5,
				anchorY: 0.5
			});
		}
	};
	self.update = function () {
		self.y += self.speed;
		// Loop road elements
		if (self.type === 'road' && self.y > 2732) {
			self.y = -self.roadGraphic.height + 10;
		}
		// Loop road lines
		if (self.type === 'line' && self.y > 2732) {
			self.y = -100;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Initialize sound effects
// Initialize car assets
//Storage library for persistent game data
//Minimalistic tween library for animations
// Game variables
var score = 0;
var coins = storage.coins || 0;
var level = storage.level || 1;
var highScore = storage.highScore || 0;
var gameSpeed = 5 + level * 0.5;
var roadWidth = 600;
var roadLeftEdge = (2048 - roadWidth) / 2;
var roadRightEdge = roadLeftEdge + roadWidth;
var spawnTimer = 0;
var gameActive = true;
var levelProgress = 0;
var pointsToNextLevel = 1000;
// Game elements
var playerCar;
var roadElements = [];
var gameElements = [];
var projectiles = [];
var gameUI;
// Create game UI and add to GUI layer
gameUI = new GameUI();
gameUI.x = 50;
gameUI.y = 50;
LK.gui.topLeft.addChild(gameUI);
// Create road
function setupRoad() {
	// Create main road
	for (var i = 0; i < 2; i++) {
		var road = new RoadElement();
		road.setup('road', gameSpeed);
		road.x = 2048 / 2;
		road.y = i * road.roadGraphic.height - (i > 0 ? 10 : 0);
		roadElements.push(road);
		game.addChild(road);
	}
	// Create road lines
	var lineSpacing = 200;
	for (var j = 0; j < 15; j++) {
		var line = new RoadElement();
		line.setup('line', gameSpeed);
		line.x = 2048 / 2;
		line.y = j * lineSpacing;
		roadElements.push(line);
		game.addChild(line);
	}
}
// Create player car
function setupPlayer() {
	playerCar = new PlayerCar();
	playerCar.x = 2048 / 2;
	playerCar.y = 2732 - 300;
	game.addChild(playerCar);
}
// Spawn game elements (coins, obstacles, enemy cars)
function spawnGameElement() {
	if (!gameActive) return;
	// Determine what to spawn based on random chance
	var rand = Math.random();
	var type, lanePosition;
	// Calculate available lanes
	var laneWidth = roadWidth / 3;
	var lanes = [roadLeftEdge + laneWidth / 2, roadLeftEdge + laneWidth + laneWidth / 2, roadLeftEdge + laneWidth * 2 + laneWidth / 2];
	// Choose random lane
	lanePosition = lanes[Math.floor(Math.random() * lanes.length)];
	// Determine element type
	if (rand < 0.4) {
		type = 'coin';
	} else if (rand < 0.7) {
		type = 'obstacle';
	} else {
		type = 'enemyCar';
	}
	var element = new GameElement();
	element.setup(type, lanePosition, gameSpeed);
	gameElements.push(element);
	game.addChild(element);
	// Add some variation to spawn rate
	spawnTimer = 60 + Math.floor(Math.random() * 60);
}
// Initialize game
function initGame() {
	// Reset game state
	score = 0;
	levelProgress = 0;
	gameSpeed = 5 + level * 0.5;
	gameActive = true;
	// Clear existing elements
	for (var i = 0; i < roadElements.length; i++) {
		roadElements[i].destroy();
	}
	roadElements = [];
	for (var j = 0; j < gameElements.length; j++) {
		gameElements[j].destroy();
	}
	gameElements = [];
	// Clear projectiles
	for (var k = 0; k < projectiles.length; k++) {
		projectiles[k].destroy();
	}
	projectiles = [];
	clearProjectileInterval();
	// Setup game elements
	setupRoad();
	setupPlayer();
	// Update UI
	gameUI.update(score, coins, level, playerCar.hp);
}
// Update score and check for level up
function updateScore(points) {
	score += points;
	levelProgress += points;
	// Level up when enough points are collected
	if (levelProgress >= pointsToNextLevel) {
		levelUp();
	}
	// Update high score
	if (score > highScore) {
		highScore = score;
		storage.highScore = highScore;
	}
	// Update UI
	gameUI.update(score, coins, level);
}
// Handle level up
function levelUp() {
	level++;
	storage.level = level;
	levelProgress = 0;
	gameSpeed += 0.5;
	// Increase points needed for next level
	pointsToNextLevel = 1000 + level * 500;
	// Visual feedback
	LK.effects.flashScreen(0x2ecc71, 500);
	LK.getSound('levelUp').play();
	// Update road and element speeds
	for (var i = 0; i < roadElements.length; i++) {
		roadElements[i].speed = gameSpeed;
	}
	// Update UI
	gameUI.update(score, coins, level);
}
// Handle coin collection
function collectCoin(element) {
	coins++;
	storage.coins = coins;
	updateScore(50);
	// Restore some HP
	playerCar.upgrade('hp', 5);
	// Visual feedback
	LK.effects.flashObject(element, 0xf1c40f, 300);
	LK.getSound('coinCollect').play();
	// Remove coin
	element.active = false;
	game.removeChild(element);
	// Check if player can level up car
	if (coins >= playerCar.level * 10) {
		coins -= playerCar.level * 10;
		storage.coins = coins;
		playerCar.upgrade('levelUp');
		LK.effects.flashScreen(0x3498db, 500);
	}
	// Update UI with new HP
	gameUI.update(score, coins, level, playerCar.hp);
}
// Handle collision with obstacle or enemy car
function handleCollision(element) {
	playerCar.crash();
	updateScore(-100);
	// Visual feedback
	LK.effects.flashObject(element, 0xff0000, 300);
	// Remove obstacle
	element.active = false;
	game.removeChild(element);
	// Update HP display
	gameUI.update(score, coins, level, playerCar.hp);
	// Check if game over
	if (score <= 0 || playerCar.hp <= 0) {
		gameOver();
	}
}
// Fire projectiles when car levels up
var projectileInterval = null;
function fireProjectiles(startX, startY) {
	// Fire multiple projectiles in different patterns based on car level
	var count = Math.min(playerCar.level, 5); // Max 5 projectiles
	for (var i = 0; i < count; i++) {
		var projectile = new Projectile();
		var offset = (i - (count - 1) / 2) * 50; // Spread projectiles horizontally
		projectile.setup(startX + offset, startY - 50, 20);
		projectiles.push(projectile);
		game.addChild(projectile);
	}
	// Play sound effect
	LK.getSound('levelUp').play();
	// Start continuous firing if not already started
	if (!projectileInterval) {
		projectileInterval = LK.setInterval(function () {
			if (!gameActive) return;
			// Only fire if playerCar is still in game and leveled up at least once
			if (playerCar && playerCar.level > 1) {
				var count = Math.min(playerCar.level, 5);
				for (var i = 0; i < count; i++) {
					var projectile = new Projectile();
					var offset = (i - (count - 1) / 2) * 50;
					projectile.setup(playerCar.x + offset, playerCar.y - 50, 20);
					projectiles.push(projectile);
					game.addChild(projectile);
				}
			}
		}, 300); // Fire every 300ms
	}
}
// Clear projectile interval on game over or reset
function clearProjectileInterval() {
	if (projectileInterval) {
		LK.clearInterval(projectileInterval);
		projectileInterval = null;
	}
}
// Game over
function gameOver() {
	gameActive = false;
	clearProjectileInterval();
	LK.effects.flashScreen(0xe74c3c, 1000);
	LK.showGameOver();
}
// Initialize the game
initGame();
// Game update loop
game.update = function () {
	if (!gameActive) return;
	// Update player car
	playerCar.update();
	// Update road elements
	for (var i = 0; i < roadElements.length; i++) {
		roadElements[i].update();
	}
	// Update game elements and check collisions
	for (var j = gameElements.length - 1; j >= 0; j--) {
		var element = gameElements[j];
		element.update();
		// Remove inactive elements
		if (!element.active) {
			gameElements.splice(j, 1);
			continue;
		}
		// Check for collisions
		var wasIntersecting = element.lastIntersecting;
		var isIntersecting = element.intersects(playerCar);
		element.lastIntersecting = isIntersecting;
		// Handle new intersections
		if (!wasIntersecting && isIntersecting) {
			if (element.type === 'coin') {
				collectCoin(element);
			} else {
				handleCollision(element);
			}
		}
	}
	// Update projectiles and check for collisions
	for (var p = projectiles.length - 1; p >= 0; p--) {
		var projectile = projectiles[p];
		projectile.update();
		// Remove inactive projectiles
		if (!projectile.active) {
			game.removeChild(projectile);
			projectiles.splice(p, 1);
			continue;
		}
		// Check for collisions with game elements
		for (var e = gameElements.length - 1; e >= 0; e--) {
			var element = gameElements[e];
			if (element.type !== 'coin' && projectile.intersects(element)) {
				// Remove the element
				element.active = false;
				game.removeChild(element);
				gameElements.splice(e, 1);
				// Give points for destroying obstacles with projectiles
				updateScore(25);
				// Create visual effect
				LK.effects.flashObject(projectile, 0xffffff, 200);
				// Remove the projectile
				projectile.active = false;
				game.removeChild(projectile);
				projectiles.splice(p, 1);
				break;
			}
		}
	}
	// Increment score based on speed
	if (LK.ticks % 10 === 0) {
		updateScore(Math.floor(playerCar.speed));
		gameUI.update(score, coins, level, playerCar.hp);
	}
	// Spawn new game elements
	if (spawnTimer <= 0) {
		spawnGameElement();
	} else {
		spawnTimer--;
	}
	// Add points for progress
	if (LK.ticks % 60 === 0) {
		updateScore(1);
	}
};
// Touch controls
game.down = function (x, y, obj) {
	if (!gameActive) return;
	// Determine which side of the screen was touched
	if (x < 2048 / 2) {
		playerCar.moveLeft();
	} else {
		playerCar.moveRight();
	}
};
game.move = function (x, y, obj) {
	if (!gameActive) return;
	// Determine which side of the screen is being touched
	if (x < 2048 / 2) {
		playerCar.moveLeft();
	} else {
		playerCar.moveRight();
	}
};
// Set game background color
game.setBackgroundColor(0x1a1a2e);