/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 4;
	self.collected = false;
	self.update = function () {
		self.y += self.speed;
		self.rotation += 0.1;
	};
	return self;
});
var Labubu = Container.expand(function () {
	var self = Container.call(this);
	var labubuGraphics = self.attachAsset('labubu', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.shielded = false;
	self.shieldTime = 0;
	self.update = function () {
		if (self.shielded) {
			self.shieldTime--;
			if (self.shieldTime <= 0) {
				self.shielded = false;
				labubuGraphics.tint = 0xFFFFFF;
			}
		}
	};
	self.activateShield = function () {
		self.shielded = true;
		self.shieldTime = 300; // 5 seconds at 60fps
		labubuGraphics.tint = 0x00FFFF;
	};
	return self;
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 6;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerUpGraphics = self.attachAsset('shield', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 4;
	self.collected = false;
	self.type = 'shield';
	self.update = function () {
		self.y += self.speed;
		self.rotation += 0.15;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x1a1a2e
});
/**** 
* Game Code
****/ 
var labubu = game.addChild(new Labubu());
labubu.x = 2048 / 2;
labubu.y = 2732 - 200;
var obstacles = [];
var coins = [];
var powerUps = [];
var gameSpeed = 1;
var obstacleSpawnRate = 120;
var coinSpawnRate = 180;
var powerUpSpawnRate = 600;
var comboCount = 0;
var lastObstacleTime = 0;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
	size: 80,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var coinsTxt = new Text2('Coins: ' + (storage.coins || 0), {
	size: 60,
	fill: 0xFFD700
});
coinsTxt.anchor.set(1, 0);
coinsTxt.x = -20;
coinsTxt.y = 20;
LK.gui.topRight.addChild(coinsTxt);
var comboTxt = new Text2('', {
	size: 70,
	fill: 0xFF69B4
});
comboTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(comboTxt);
// Touch controls
var dragStartX = 0;
var dragStartY = 0;
var isDragging = false;
game.down = function (x, y, obj) {
	dragStartX = x;
	dragStartY = y;
	isDragging = true;
};
game.move = function (x, y, obj) {
	if (isDragging) {
		var deltaX = x - dragStartX;
		var deltaY = y - dragStartY;
		labubu.x += deltaX * 0.5;
		labubu.y += deltaY * 0.5;
		// Keep Labubu within screen bounds
		labubu.x = Math.max(60, Math.min(2048 - 60, labubu.x));
		labubu.y = Math.max(60, Math.min(2732 - 60, labubu.y));
		dragStartX = x;
		dragStartY = y;
	}
};
game.up = function (x, y, obj) {
	isDragging = false;
};
// Initialize storage
if (storage.coins === undefined) {
	storage.coins = 0;
}
if (storage.highScore === undefined) {
	storage.highScore = 0;
}
function spawnObstacle() {
	var obstacle = new Obstacle();
	obstacle.x = Math.random() * (2048 - 160) + 80;
	obstacle.y = -50;
	obstacle.speed = 6 + gameSpeed * 2;
	obstacles.push(obstacle);
	game.addChild(obstacle);
}
function spawnCoin() {
	var coin = new Coin();
	coin.x = Math.random() * (2048 - 80) + 40;
	coin.y = -30;
	coin.speed = 4 + gameSpeed;
	coins.push(coin);
	game.addChild(coin);
}
function spawnPowerUp() {
	var powerUp = new PowerUp();
	powerUp.x = Math.random() * (2048 - 100) + 50;
	powerUp.y = -30;
	powerUp.speed = 4 + gameSpeed;
	powerUps.push(powerUp);
	game.addChild(powerUp);
}
function updateScore() {
	var currentScore = LK.getScore();
	scoreTxt.setText('Score: ' + currentScore);
	if (currentScore > storage.highScore) {
		storage.highScore = currentScore;
	}
}
function updateCombo() {
	if (comboCount > 5) {
		comboTxt.setText('COMBO x' + comboCount);
		tween(comboTxt, {
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 200,
			onFinish: function onFinish() {
				tween(comboTxt, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 200
				});
			}
		});
	} else {
		comboTxt.setText('');
	}
}
LK.playMusic('bgmusic');
game.update = function () {
	// Increase game difficulty over time
	if (LK.ticks % 600 === 0) {
		gameSpeed += 0.1;
		obstacleSpawnRate = Math.max(60, obstacleSpawnRate - 2);
	}
	// Spawn obstacles
	if (LK.ticks % Math.floor(obstacleSpawnRate / gameSpeed) === 0) {
		spawnObstacle();
	}
	// Spawn coins
	if (LK.ticks % Math.floor(coinSpawnRate / gameSpeed) === 0) {
		spawnCoin();
	}
	// Spawn power-ups
	if (LK.ticks % Math.floor(powerUpSpawnRate / gameSpeed) === 0) {
		spawnPowerUp();
	}
	// Update and check obstacles
	for (var i = obstacles.length - 1; i >= 0; i--) {
		var obstacle = obstacles[i];
		if (obstacle.lastY === undefined) obstacle.lastY = obstacle.y;
		// Remove off-screen obstacles
		if (obstacle.lastY <= 2732 && obstacle.y > 2732) {
			obstacle.destroy();
			obstacles.splice(i, 1);
			// Increment combo for successful dodge
			comboCount++;
			lastObstacleTime = LK.ticks;
			updateCombo();
			LK.setScore(LK.getScore() + 10 * Math.max(1, Math.floor(comboCount / 5)));
			updateScore();
			continue;
		}
		// Check collision with Labubu
		if (obstacle.intersects(labubu)) {
			if (!labubu.shielded) {
				LK.getSound('hit').play();
				LK.effects.flashScreen(0xFF0000, 1000);
				LK.showGameOver();
				return;
			} else {
				// Shield absorbs hit
				obstacle.destroy();
				obstacles.splice(i, 1);
				labubu.shielded = false;
				labubu.shieldTime = 0;
				LK.effects.flashObject(labubu, 0xFFFFFF, 300);
				continue;
			}
		}
		obstacle.lastY = obstacle.y;
	}
	// Update and check coins
	for (var j = coins.length - 1; j >= 0; j--) {
		var coin = coins[j];
		if (coin.lastY === undefined) coin.lastY = coin.y;
		// Remove off-screen coins
		if (coin.lastY <= 2732 && coin.y > 2732) {
			coin.destroy();
			coins.splice(j, 1);
			continue;
		}
		// Check collection
		if (!coin.collected && coin.intersects(labubu)) {
			coin.collected = true;
			LK.getSound('collect').play();
			storage.coins++;
			coinsTxt.setText('Coins: ' + storage.coins);
			tween(coin, {
				scaleX: 2,
				scaleY: 2,
				alpha: 0
			}, {
				duration: 300,
				onFinish: function onFinish() {
					coin.destroy();
				}
			});
			coins.splice(j, 1);
			LK.setScore(LK.getScore() + 50);
			updateScore();
			continue;
		}
		coin.lastY = coin.y;
	}
	// Update and check power-ups
	for (var k = powerUps.length - 1; k >= 0; k--) {
		var powerUp = powerUps[k];
		if (powerUp.lastY === undefined) powerUp.lastY = powerUp.y;
		// Remove off-screen power-ups
		if (powerUp.lastY <= 2732 && powerUp.y > 2732) {
			powerUp.destroy();
			powerUps.splice(k, 1);
			continue;
		}
		// Check collection
		if (!powerUp.collected && powerUp.intersects(labubu)) {
			powerUp.collected = true;
			LK.getSound('collect').play();
			if (powerUp.type === 'shield') {
				labubu.activateShield();
			}
			tween(powerUp, {
				scaleX: 2,
				scaleY: 2,
				alpha: 0
			}, {
				duration: 300,
				onFinish: function onFinish() {
					powerUp.destroy();
				}
			});
			powerUps.splice(k, 1);
			LK.setScore(LK.getScore() + 100);
			updateScore();
			continue;
		}
		powerUp.lastY = powerUp.y;
	}
	// Reset combo if no obstacles dodged recently
	if (LK.ticks - lastObstacleTime > 180) {
		comboCount = 0;
		updateCombo();
	}
	// Passive score increase
	if (LK.ticks % 60 === 0) {
		LK.setScore(LK.getScore() + 1);
		updateScore();
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 4;
	self.collected = false;
	self.update = function () {
		self.y += self.speed;
		self.rotation += 0.1;
	};
	return self;
});
var Labubu = Container.expand(function () {
	var self = Container.call(this);
	var labubuGraphics = self.attachAsset('labubu', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.shielded = false;
	self.shieldTime = 0;
	self.update = function () {
		if (self.shielded) {
			self.shieldTime--;
			if (self.shieldTime <= 0) {
				self.shielded = false;
				labubuGraphics.tint = 0xFFFFFF;
			}
		}
	};
	self.activateShield = function () {
		self.shielded = true;
		self.shieldTime = 300; // 5 seconds at 60fps
		labubuGraphics.tint = 0x00FFFF;
	};
	return self;
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphics = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 6;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerUpGraphics = self.attachAsset('shield', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 4;
	self.collected = false;
	self.type = 'shield';
	self.update = function () {
		self.y += self.speed;
		self.rotation += 0.15;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x1a1a2e
});
/**** 
* Game Code
****/ 
var labubu = game.addChild(new Labubu());
labubu.x = 2048 / 2;
labubu.y = 2732 - 200;
var obstacles = [];
var coins = [];
var powerUps = [];
var gameSpeed = 1;
var obstacleSpawnRate = 120;
var coinSpawnRate = 180;
var powerUpSpawnRate = 600;
var comboCount = 0;
var lastObstacleTime = 0;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
	size: 80,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var coinsTxt = new Text2('Coins: ' + (storage.coins || 0), {
	size: 60,
	fill: 0xFFD700
});
coinsTxt.anchor.set(1, 0);
coinsTxt.x = -20;
coinsTxt.y = 20;
LK.gui.topRight.addChild(coinsTxt);
var comboTxt = new Text2('', {
	size: 70,
	fill: 0xFF69B4
});
comboTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(comboTxt);
// Touch controls
var dragStartX = 0;
var dragStartY = 0;
var isDragging = false;
game.down = function (x, y, obj) {
	dragStartX = x;
	dragStartY = y;
	isDragging = true;
};
game.move = function (x, y, obj) {
	if (isDragging) {
		var deltaX = x - dragStartX;
		var deltaY = y - dragStartY;
		labubu.x += deltaX * 0.5;
		labubu.y += deltaY * 0.5;
		// Keep Labubu within screen bounds
		labubu.x = Math.max(60, Math.min(2048 - 60, labubu.x));
		labubu.y = Math.max(60, Math.min(2732 - 60, labubu.y));
		dragStartX = x;
		dragStartY = y;
	}
};
game.up = function (x, y, obj) {
	isDragging = false;
};
// Initialize storage
if (storage.coins === undefined) {
	storage.coins = 0;
}
if (storage.highScore === undefined) {
	storage.highScore = 0;
}
function spawnObstacle() {
	var obstacle = new Obstacle();
	obstacle.x = Math.random() * (2048 - 160) + 80;
	obstacle.y = -50;
	obstacle.speed = 6 + gameSpeed * 2;
	obstacles.push(obstacle);
	game.addChild(obstacle);
}
function spawnCoin() {
	var coin = new Coin();
	coin.x = Math.random() * (2048 - 80) + 40;
	coin.y = -30;
	coin.speed = 4 + gameSpeed;
	coins.push(coin);
	game.addChild(coin);
}
function spawnPowerUp() {
	var powerUp = new PowerUp();
	powerUp.x = Math.random() * (2048 - 100) + 50;
	powerUp.y = -30;
	powerUp.speed = 4 + gameSpeed;
	powerUps.push(powerUp);
	game.addChild(powerUp);
}
function updateScore() {
	var currentScore = LK.getScore();
	scoreTxt.setText('Score: ' + currentScore);
	if (currentScore > storage.highScore) {
		storage.highScore = currentScore;
	}
}
function updateCombo() {
	if (comboCount > 5) {
		comboTxt.setText('COMBO x' + comboCount);
		tween(comboTxt, {
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 200,
			onFinish: function onFinish() {
				tween(comboTxt, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 200
				});
			}
		});
	} else {
		comboTxt.setText('');
	}
}
LK.playMusic('bgmusic');
game.update = function () {
	// Increase game difficulty over time
	if (LK.ticks % 600 === 0) {
		gameSpeed += 0.1;
		obstacleSpawnRate = Math.max(60, obstacleSpawnRate - 2);
	}
	// Spawn obstacles
	if (LK.ticks % Math.floor(obstacleSpawnRate / gameSpeed) === 0) {
		spawnObstacle();
	}
	// Spawn coins
	if (LK.ticks % Math.floor(coinSpawnRate / gameSpeed) === 0) {
		spawnCoin();
	}
	// Spawn power-ups
	if (LK.ticks % Math.floor(powerUpSpawnRate / gameSpeed) === 0) {
		spawnPowerUp();
	}
	// Update and check obstacles
	for (var i = obstacles.length - 1; i >= 0; i--) {
		var obstacle = obstacles[i];
		if (obstacle.lastY === undefined) obstacle.lastY = obstacle.y;
		// Remove off-screen obstacles
		if (obstacle.lastY <= 2732 && obstacle.y > 2732) {
			obstacle.destroy();
			obstacles.splice(i, 1);
			// Increment combo for successful dodge
			comboCount++;
			lastObstacleTime = LK.ticks;
			updateCombo();
			LK.setScore(LK.getScore() + 10 * Math.max(1, Math.floor(comboCount / 5)));
			updateScore();
			continue;
		}
		// Check collision with Labubu
		if (obstacle.intersects(labubu)) {
			if (!labubu.shielded) {
				LK.getSound('hit').play();
				LK.effects.flashScreen(0xFF0000, 1000);
				LK.showGameOver();
				return;
			} else {
				// Shield absorbs hit
				obstacle.destroy();
				obstacles.splice(i, 1);
				labubu.shielded = false;
				labubu.shieldTime = 0;
				LK.effects.flashObject(labubu, 0xFFFFFF, 300);
				continue;
			}
		}
		obstacle.lastY = obstacle.y;
	}
	// Update and check coins
	for (var j = coins.length - 1; j >= 0; j--) {
		var coin = coins[j];
		if (coin.lastY === undefined) coin.lastY = coin.y;
		// Remove off-screen coins
		if (coin.lastY <= 2732 && coin.y > 2732) {
			coin.destroy();
			coins.splice(j, 1);
			continue;
		}
		// Check collection
		if (!coin.collected && coin.intersects(labubu)) {
			coin.collected = true;
			LK.getSound('collect').play();
			storage.coins++;
			coinsTxt.setText('Coins: ' + storage.coins);
			tween(coin, {
				scaleX: 2,
				scaleY: 2,
				alpha: 0
			}, {
				duration: 300,
				onFinish: function onFinish() {
					coin.destroy();
				}
			});
			coins.splice(j, 1);
			LK.setScore(LK.getScore() + 50);
			updateScore();
			continue;
		}
		coin.lastY = coin.y;
	}
	// Update and check power-ups
	for (var k = powerUps.length - 1; k >= 0; k--) {
		var powerUp = powerUps[k];
		if (powerUp.lastY === undefined) powerUp.lastY = powerUp.y;
		// Remove off-screen power-ups
		if (powerUp.lastY <= 2732 && powerUp.y > 2732) {
			powerUp.destroy();
			powerUps.splice(k, 1);
			continue;
		}
		// Check collection
		if (!powerUp.collected && powerUp.intersects(labubu)) {
			powerUp.collected = true;
			LK.getSound('collect').play();
			if (powerUp.type === 'shield') {
				labubu.activateShield();
			}
			tween(powerUp, {
				scaleX: 2,
				scaleY: 2,
				alpha: 0
			}, {
				duration: 300,
				onFinish: function onFinish() {
					powerUp.destroy();
				}
			});
			powerUps.splice(k, 1);
			LK.setScore(LK.getScore() + 100);
			updateScore();
			continue;
		}
		powerUp.lastY = powerUp.y;
	}
	// Reset combo if no obstacles dodged recently
	if (LK.ticks - lastObstacleTime > 180) {
		comboCount = 0;
		updateCombo();
	}
	// Passive score increase
	if (LK.ticks % 60 === 0) {
		LK.setScore(LK.getScore() + 1);
		updateScore();
	}
};