/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Biker = Container.expand(function () {
	var self = Container.call(this);
	var bikerGraphics = self.attachAsset('biker', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// State variables
	self.velocity = {
		x: 0,
		y: 0
	};
	self.isJumping = false;
	self.isDead = false;
	self.gravity = 0.5;
	self.jumpForce = -20; // Increase jump force for quicker response
	self.jump = function (isHighJump) {
		if (!self.isJumping && !self.isDead) {
			self.velocity.y = isHighJump ? self.jumpForce * 2 : self.jumpForce;
			self.isJumping = isHighJump ? true : !self.isJumping;
			LK.getSound('jump').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Apply gravity
		self.velocity.y += self.gravity;
		// Update position
		self.y += self.velocity.y;
		// Cap falling speed
		if (self.velocity.y > 15) {
			self.velocity.y = 15;
		}
		// Tilt the biker based on vertical velocity
		var targetRotation = self.velocity.y * 0.03;
		bikerGraphics.rotation = targetRotation;
	};
	self.die = function () {
		if (!self.isDead) {
			self.isDead = true;
			LK.getSound('crash').play();
			// Animate the death
			tween(bikerGraphics, {
				rotation: Math.PI
			}, {
				duration: 800,
				easing: tween.bounceOut
			});
			// Flash the biker red
			LK.effects.flashObject(self, 0xff0000, 500);
			// Game over after a short delay
			LK.setTimeout(function () {
				LK.showGameOver();
			}, 1000);
		}
	};
	return self;
});
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = coinGraphics.width;
	self.height = coinGraphics.height;
	self.speed = 5;
	self.active = true;
	// Animation
	self.update = function () {
		if (!self.active) {
			return;
		}
		// Spin the coin
		coinGraphics.rotation += 0.05;
		self.x -= self.speed;
		// Remove when off screen
		if (self.x < -self.width) {
			self.active = false;
			self.destroy();
		}
	};
	self.collect = function () {
		if (self.active) {
			self.active = false;
			// Animate coin collection
			tween(self, {
				alpha: 0,
				scaleX: 1.5,
				scaleY: 1.5
			}, {
				duration: 300,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
			LK.getSound('coin').play();
			return true;
		}
		return false;
	};
	return self;
});
var Ground = Container.expand(function () {
	var self = Container.call(this);
	var groundGraphics = self.attachAsset('ground', {
		anchorX: 0,
		anchorY: 0
	});
	self.speed = 5;
	self.update = function () {
		self.x -= self.speed;
		// Loop the ground
		if (self.x <= -groundGraphics.width) {
			self.x += groundGraphics.width;
		}
	};
	return self;
});
var Jump = Container.expand(function () {
	var self = Container.call(this);
	var jumpGraphics = self.attachAsset('jump', {
		anchorX: 0.5,
		anchorY: 1.0
	});
	self.width = jumpGraphics.width;
	self.height = jumpGraphics.height;
	self.speed = 5;
	self.active = true;
	self.update = function () {
		if (!self.active) {
			return;
		}
		self.x -= self.speed;
		// Remove when off screen
		if (self.x < -self.width) {
			self.active = false;
			self.destroy();
		}
	};
	return self;
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 1.0
	});
	self.width = obstacleGraphics.width;
	self.height = obstacleGraphics.height;
	self.speed = 5;
	self.active = true;
	self.update = function () {
		if (!self.active) {
			return;
		}
		self.x -= self.speed;
		// Remove when off screen
		if (self.x < -self.width) {
			self.active = false;
			self.destroy();
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x87CEEB // Sky blue background
});
/**** 
* Game Code
****/ 
// Game variables
var biker;
var groundTiles = [];
var obstacles = [];
var jumps = [];
var coins = [];
var distance = 0;
var groundY = 2732 - 250; // Ground position from top
var gameSpeed = 5;
var spawnDistance = 0;
var lastObstaclePos = 0;
var gameActive = false;
var difficultyTimer = 0;
var coinsCollected = 0;
// Create score display
var scoreTxt = new Text2('Distance: 0m', {
	size: 80,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create coin display
var coinTxt = new Text2('Coins: 0', {
	size: 80,
	fill: 0xFFCC00
});
coinTxt.anchor.set(0.5, 0);
coinTxt.y = 100;
LK.gui.top.addChild(coinTxt);
// Initialize high score from storage
var highScore = storage.highScore || 0;
var highScoreTxt = new Text2('Best: ' + highScore + 'm', {
	size: 60,
	fill: 0xFFFFFF
});
highScoreTxt.anchor.set(1.0, 0);
highScoreTxt.y = 10;
highScoreTxt.x = -10;
LK.gui.topRight.addChild(highScoreTxt);
// Create tap to start message
var startTxt = new Text2('Tap to Start', {
	size: 120,
	fill: 0xFFFFFF
});
startTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(startTxt);
// Initialize the game elements
function initGame() {
	// Attach background image
	var background = LK.getAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 2732 / 2
	});
	game.addChild(background);
	// Reset variables
	obstacles = [];
	jumps = [];
	coins = [];
	distance = 0;
	gameSpeed = 5;
	spawnDistance = 0;
	lastObstaclePos = 0;
	gameActive = false;
	difficultyTimer = 0;
	coinsCollected = 0;
	// Update UI
	scoreTxt.setText('Distance: 0m');
	coinTxt.setText('Coins: 0');
	startTxt.visible = true;
	// Create ground
	if (groundTiles.length === 0) {
		for (var i = 0; i < 2; i++) {
			var ground = new Ground();
			ground.x = i * ground.width;
			ground.y = groundY;
			groundTiles.push(ground);
			game.addChild(ground);
		}
	} else {
		for (var i = 0; i < groundTiles.length; i++) {
			groundTiles[i].x = i * groundTiles[i].width;
		}
	}
	// Create player if not exists
	if (!biker) {
		biker = new Biker();
		game.addChild(biker);
	}
	// Position player
	biker.x = 2048 / 2; // Center the player horizontally
	biker.y = groundY - 30;
	biker.velocity = {
		x: 0,
		y: 0
	};
	biker.isJumping = false;
	biker.isDead = false;
	// Play background music
	LK.playMusic('bgMusic', {
		fade: {
			start: 0,
			end: 0.6,
			duration: 1000
		}
	});
}
// Start the game
function startGame() {
	if (!gameActive) {
		gameActive = true;
		startTxt.visible = false;
	}
}
// Spawn obstacles and collectibles
function spawnObjects() {
	if (!gameActive) {
		return;
	}
	spawnDistance += gameSpeed;
	// Minimum distance between objects
	var minDistance = 500;
	// Check if we should spawn a new object
	if (spawnDistance - lastObstaclePos > minDistance) {
		var rand = Math.random();
		// Determine what type of object to spawn
		if (rand < 0.5) {
			// Spawn obstacle
			var obstacle = new Obstacle();
			obstacle.x = 2048 + obstacle.width;
			obstacle.y = groundY;
			obstacle.speed = gameSpeed;
			obstacles.push(obstacle);
			game.addChild(obstacle);
			lastObstaclePos = spawnDistance;
		} else if (rand < 0.8) {
			// Spawn jump ramp
			var jump = new Jump();
			jump.x = 2048 + jump.width;
			jump.y = groundY;
			jump.speed = gameSpeed;
			jumps.push(jump);
			game.addChild(jump);
			lastObstaclePos = spawnDistance;
			// Spawn coin above the jump
			var coin = new Coin();
			coin.x = jump.x;
			coin.y = groundY - 150 - Math.random() * 100;
			coin.speed = gameSpeed;
			coins.push(coin);
			game.addChild(coin);
		} else {
			// Spawn just a coin
			var coin = new Coin();
			coin.x = 2048 + coin.width;
			coin.y = groundY - 100 - Math.random() * 150;
			coin.speed = gameSpeed;
			coins.push(coin);
			game.addChild(coin);
			lastObstaclePos = spawnDistance;
		}
	}
}
// Check collision with ground
function checkGroundCollision() {
	if (biker.y >= groundY - 30) {
		biker.y = groundY - 30;
		biker.velocity.y = 0;
		biker.isJumping = false;
	}
}
// Check collision with obstacles
function checkObstacleCollision() {
	if (!gameActive || biker.isDead) {
		return;
	}
	// Check obstacles
	for (var i = obstacles.length - 1; i >= 0; i--) {
		var obstacle = obstacles[i];
		if (obstacle.active && biker.intersects(obstacle)) {
			biker.die();
			return;
		}
	}
	// Check jumps (no collision, just boost)
	for (var i = jumps.length - 1; i >= 0; i--) {
		var jump = jumps[i];
		if (jump.active && biker.intersects(jump) && !biker.isJumping) {
			biker.velocity.y = biker.jumpForce * 1.2; // Extra boost from ramp
			biker.isJumping = true;
			LK.getSound('jump').play();
		}
	}
	// Check coins
	for (var i = coins.length - 1; i >= 0; i--) {
		var coin = coins[i];
		if (coin.active && biker.intersects(coin)) {
			if (coin.collect()) {
				coins.splice(i, 1);
				coinsCollected++;
				coinTxt.setText('Coins: ' + coinsCollected);
			}
		}
	}
}
// Update game difficulty
function updateDifficulty() {
	if (!gameActive) {
		return;
	}
	difficultyTimer++;
	// Increase speed every 5 seconds
	if (difficultyTimer % 300 === 0) {
		gameSpeed += 1.0;
		// Update all object speeds
		for (var i = 0; i < groundTiles.length; i++) {
			groundTiles[i].speed = gameSpeed;
		}
		for (var i = 0; i < obstacles.length; i++) {
			obstacles[i].speed = gameSpeed;
		}
		for (var i = 0; i < jumps.length; i++) {
			jumps[i].speed = gameSpeed;
		}
		for (var i = 0; i < coins.length; i++) {
			coins[i].speed = gameSpeed;
		}
	}
}
// Clean up objects that are no longer active
function cleanupObjects() {
	for (var i = obstacles.length - 1; i >= 0; i--) {
		if (!obstacles[i].active) {
			obstacles.splice(i, 1);
		}
	}
	for (var i = jumps.length - 1; i >= 0; i--) {
		if (!jumps[i].active) {
			jumps.splice(i, 1);
		}
	}
	for (var i = coins.length - 1; i >= 0; i--) {
		if (!coins[i].active) {
			coins.splice(i, 1);
		}
	}
}
// Update score
function updateScore() {
	if (gameActive && !biker.isDead) {
		distance += gameSpeed / 10;
		var distanceInt = Math.floor(distance);
		scoreTxt.setText('Distance: ' + distanceInt + 'm');
		// Update high score
		if (distanceInt > highScore) {
			highScore = distanceInt;
			highScoreTxt.setText('Best: ' + highScore + 'm');
			storage.highScore = highScore;
		}
	}
}
// Event handlers
game.down = function (x, y, obj) {
	if (!gameActive) {
		startGame();
	} else if (!biker.isDead) {
		biker.jump(y < 1700); // High jump if tap is in the upper 60% of the screen
	}
};
// Game update function
game.update = function () {
	// Initialize on first run
	if (LK.ticks === 1) {
		initGame();
	}
	// Update all game objects
	if (biker) {
		biker.update();
	}
	for (var i = 0; i < groundTiles.length; i++) {
		groundTiles[i].update();
	}
	for (var i = 0; i < obstacles.length; i++) {
		obstacles[i].update();
	}
	for (var i = 0; i < jumps.length; i++) {
		jumps[i].update();
	}
	for (var i = 0; i < coins.length; i++) {
		coins[i].update();
	}
	// Game logic
	if (gameActive) {
		checkGroundCollision();
		checkObstacleCollision();
		spawnObjects();
		updateDifficulty();
		updateScore();
		cleanupObjects();
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Biker = Container.expand(function () {
	var self = Container.call(this);
	var bikerGraphics = self.attachAsset('biker', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// State variables
	self.velocity = {
		x: 0,
		y: 0
	};
	self.isJumping = false;
	self.isDead = false;
	self.gravity = 0.5;
	self.jumpForce = -20; // Increase jump force for quicker response
	self.jump = function (isHighJump) {
		if (!self.isJumping && !self.isDead) {
			self.velocity.y = isHighJump ? self.jumpForce * 2 : self.jumpForce;
			self.isJumping = isHighJump ? true : !self.isJumping;
			LK.getSound('jump').play();
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Apply gravity
		self.velocity.y += self.gravity;
		// Update position
		self.y += self.velocity.y;
		// Cap falling speed
		if (self.velocity.y > 15) {
			self.velocity.y = 15;
		}
		// Tilt the biker based on vertical velocity
		var targetRotation = self.velocity.y * 0.03;
		bikerGraphics.rotation = targetRotation;
	};
	self.die = function () {
		if (!self.isDead) {
			self.isDead = true;
			LK.getSound('crash').play();
			// Animate the death
			tween(bikerGraphics, {
				rotation: Math.PI
			}, {
				duration: 800,
				easing: tween.bounceOut
			});
			// Flash the biker red
			LK.effects.flashObject(self, 0xff0000, 500);
			// Game over after a short delay
			LK.setTimeout(function () {
				LK.showGameOver();
			}, 1000);
		}
	};
	return self;
});
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = coinGraphics.width;
	self.height = coinGraphics.height;
	self.speed = 5;
	self.active = true;
	// Animation
	self.update = function () {
		if (!self.active) {
			return;
		}
		// Spin the coin
		coinGraphics.rotation += 0.05;
		self.x -= self.speed;
		// Remove when off screen
		if (self.x < -self.width) {
			self.active = false;
			self.destroy();
		}
	};
	self.collect = function () {
		if (self.active) {
			self.active = false;
			// Animate coin collection
			tween(self, {
				alpha: 0,
				scaleX: 1.5,
				scaleY: 1.5
			}, {
				duration: 300,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
			LK.getSound('coin').play();
			return true;
		}
		return false;
	};
	return self;
});
var Ground = Container.expand(function () {
	var self = Container.call(this);
	var groundGraphics = self.attachAsset('ground', {
		anchorX: 0,
		anchorY: 0
	});
	self.speed = 5;
	self.update = function () {
		self.x -= self.speed;
		// Loop the ground
		if (self.x <= -groundGraphics.width) {
			self.x += groundGraphics.width;
		}
	};
	return self;
});
var Jump = Container.expand(function () {
	var self = Container.call(this);
	var jumpGraphics = self.attachAsset('jump', {
		anchorX: 0.5,
		anchorY: 1.0
	});
	self.width = jumpGraphics.width;
	self.height = jumpGraphics.height;
	self.speed = 5;
	self.active = true;
	self.update = function () {
		if (!self.active) {
			return;
		}
		self.x -= self.speed;
		// Remove when off screen
		if (self.x < -self.width) {
			self.active = false;
			self.destroy();
		}
	};
	return self;
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 1.0
	});
	self.width = obstacleGraphics.width;
	self.height = obstacleGraphics.height;
	self.speed = 5;
	self.active = true;
	self.update = function () {
		if (!self.active) {
			return;
		}
		self.x -= self.speed;
		// Remove when off screen
		if (self.x < -self.width) {
			self.active = false;
			self.destroy();
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x87CEEB // Sky blue background
});
/**** 
* Game Code
****/ 
// Game variables
var biker;
var groundTiles = [];
var obstacles = [];
var jumps = [];
var coins = [];
var distance = 0;
var groundY = 2732 - 250; // Ground position from top
var gameSpeed = 5;
var spawnDistance = 0;
var lastObstaclePos = 0;
var gameActive = false;
var difficultyTimer = 0;
var coinsCollected = 0;
// Create score display
var scoreTxt = new Text2('Distance: 0m', {
	size: 80,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create coin display
var coinTxt = new Text2('Coins: 0', {
	size: 80,
	fill: 0xFFCC00
});
coinTxt.anchor.set(0.5, 0);
coinTxt.y = 100;
LK.gui.top.addChild(coinTxt);
// Initialize high score from storage
var highScore = storage.highScore || 0;
var highScoreTxt = new Text2('Best: ' + highScore + 'm', {
	size: 60,
	fill: 0xFFFFFF
});
highScoreTxt.anchor.set(1.0, 0);
highScoreTxt.y = 10;
highScoreTxt.x = -10;
LK.gui.topRight.addChild(highScoreTxt);
// Create tap to start message
var startTxt = new Text2('Tap to Start', {
	size: 120,
	fill: 0xFFFFFF
});
startTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(startTxt);
// Initialize the game elements
function initGame() {
	// Attach background image
	var background = LK.getAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 2048 / 2,
		y: 2732 / 2
	});
	game.addChild(background);
	// Reset variables
	obstacles = [];
	jumps = [];
	coins = [];
	distance = 0;
	gameSpeed = 5;
	spawnDistance = 0;
	lastObstaclePos = 0;
	gameActive = false;
	difficultyTimer = 0;
	coinsCollected = 0;
	// Update UI
	scoreTxt.setText('Distance: 0m');
	coinTxt.setText('Coins: 0');
	startTxt.visible = true;
	// Create ground
	if (groundTiles.length === 0) {
		for (var i = 0; i < 2; i++) {
			var ground = new Ground();
			ground.x = i * ground.width;
			ground.y = groundY;
			groundTiles.push(ground);
			game.addChild(ground);
		}
	} else {
		for (var i = 0; i < groundTiles.length; i++) {
			groundTiles[i].x = i * groundTiles[i].width;
		}
	}
	// Create player if not exists
	if (!biker) {
		biker = new Biker();
		game.addChild(biker);
	}
	// Position player
	biker.x = 2048 / 2; // Center the player horizontally
	biker.y = groundY - 30;
	biker.velocity = {
		x: 0,
		y: 0
	};
	biker.isJumping = false;
	biker.isDead = false;
	// Play background music
	LK.playMusic('bgMusic', {
		fade: {
			start: 0,
			end: 0.6,
			duration: 1000
		}
	});
}
// Start the game
function startGame() {
	if (!gameActive) {
		gameActive = true;
		startTxt.visible = false;
	}
}
// Spawn obstacles and collectibles
function spawnObjects() {
	if (!gameActive) {
		return;
	}
	spawnDistance += gameSpeed;
	// Minimum distance between objects
	var minDistance = 500;
	// Check if we should spawn a new object
	if (spawnDistance - lastObstaclePos > minDistance) {
		var rand = Math.random();
		// Determine what type of object to spawn
		if (rand < 0.5) {
			// Spawn obstacle
			var obstacle = new Obstacle();
			obstacle.x = 2048 + obstacle.width;
			obstacle.y = groundY;
			obstacle.speed = gameSpeed;
			obstacles.push(obstacle);
			game.addChild(obstacle);
			lastObstaclePos = spawnDistance;
		} else if (rand < 0.8) {
			// Spawn jump ramp
			var jump = new Jump();
			jump.x = 2048 + jump.width;
			jump.y = groundY;
			jump.speed = gameSpeed;
			jumps.push(jump);
			game.addChild(jump);
			lastObstaclePos = spawnDistance;
			// Spawn coin above the jump
			var coin = new Coin();
			coin.x = jump.x;
			coin.y = groundY - 150 - Math.random() * 100;
			coin.speed = gameSpeed;
			coins.push(coin);
			game.addChild(coin);
		} else {
			// Spawn just a coin
			var coin = new Coin();
			coin.x = 2048 + coin.width;
			coin.y = groundY - 100 - Math.random() * 150;
			coin.speed = gameSpeed;
			coins.push(coin);
			game.addChild(coin);
			lastObstaclePos = spawnDistance;
		}
	}
}
// Check collision with ground
function checkGroundCollision() {
	if (biker.y >= groundY - 30) {
		biker.y = groundY - 30;
		biker.velocity.y = 0;
		biker.isJumping = false;
	}
}
// Check collision with obstacles
function checkObstacleCollision() {
	if (!gameActive || biker.isDead) {
		return;
	}
	// Check obstacles
	for (var i = obstacles.length - 1; i >= 0; i--) {
		var obstacle = obstacles[i];
		if (obstacle.active && biker.intersects(obstacle)) {
			biker.die();
			return;
		}
	}
	// Check jumps (no collision, just boost)
	for (var i = jumps.length - 1; i >= 0; i--) {
		var jump = jumps[i];
		if (jump.active && biker.intersects(jump) && !biker.isJumping) {
			biker.velocity.y = biker.jumpForce * 1.2; // Extra boost from ramp
			biker.isJumping = true;
			LK.getSound('jump').play();
		}
	}
	// Check coins
	for (var i = coins.length - 1; i >= 0; i--) {
		var coin = coins[i];
		if (coin.active && biker.intersects(coin)) {
			if (coin.collect()) {
				coins.splice(i, 1);
				coinsCollected++;
				coinTxt.setText('Coins: ' + coinsCollected);
			}
		}
	}
}
// Update game difficulty
function updateDifficulty() {
	if (!gameActive) {
		return;
	}
	difficultyTimer++;
	// Increase speed every 5 seconds
	if (difficultyTimer % 300 === 0) {
		gameSpeed += 1.0;
		// Update all object speeds
		for (var i = 0; i < groundTiles.length; i++) {
			groundTiles[i].speed = gameSpeed;
		}
		for (var i = 0; i < obstacles.length; i++) {
			obstacles[i].speed = gameSpeed;
		}
		for (var i = 0; i < jumps.length; i++) {
			jumps[i].speed = gameSpeed;
		}
		for (var i = 0; i < coins.length; i++) {
			coins[i].speed = gameSpeed;
		}
	}
}
// Clean up objects that are no longer active
function cleanupObjects() {
	for (var i = obstacles.length - 1; i >= 0; i--) {
		if (!obstacles[i].active) {
			obstacles.splice(i, 1);
		}
	}
	for (var i = jumps.length - 1; i >= 0; i--) {
		if (!jumps[i].active) {
			jumps.splice(i, 1);
		}
	}
	for (var i = coins.length - 1; i >= 0; i--) {
		if (!coins[i].active) {
			coins.splice(i, 1);
		}
	}
}
// Update score
function updateScore() {
	if (gameActive && !biker.isDead) {
		distance += gameSpeed / 10;
		var distanceInt = Math.floor(distance);
		scoreTxt.setText('Distance: ' + distanceInt + 'm');
		// Update high score
		if (distanceInt > highScore) {
			highScore = distanceInt;
			highScoreTxt.setText('Best: ' + highScore + 'm');
			storage.highScore = highScore;
		}
	}
}
// Event handlers
game.down = function (x, y, obj) {
	if (!gameActive) {
		startGame();
	} else if (!biker.isDead) {
		biker.jump(y < 1700); // High jump if tap is in the upper 60% of the screen
	}
};
// Game update function
game.update = function () {
	// Initialize on first run
	if (LK.ticks === 1) {
		initGame();
	}
	// Update all game objects
	if (biker) {
		biker.update();
	}
	for (var i = 0; i < groundTiles.length; i++) {
		groundTiles[i].update();
	}
	for (var i = 0; i < obstacles.length; i++) {
		obstacles[i].update();
	}
	for (var i = 0; i < jumps.length; i++) {
		jumps[i].update();
	}
	for (var i = 0; i < coins.length; i++) {
		coins[i].update();
	}
	// Game logic
	if (gameActive) {
		checkGroundCollision();
		checkObstacleCollision();
		spawnObjects();
		updateDifficulty();
		updateScore();
		cleanupObjects();
	}
};