/****
* 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();
}
};