/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var PopStar = Container.expand(function () { var self = Container.call(this); var popstarGraphics = self.attachAsset('popstar', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.targetX = 0; self.targetY = 0; self.isDead = false; self.hitWindow = 100; // pixels around popstar where tap is effective self.setTarget = function (x, y) { self.targetX = x; self.targetY = y; }; self.update = function () { if (self.isDead) return; // Move toward target (rapper) var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } }; self.die = function () { self.isDead = true; // Create hit effect var effect = game.addChild(LK.getAsset('hitEffect', { anchorX: 0.5, anchorY: 0.5 })); effect.x = self.x; effect.y = self.y; // Animate effect tween(effect, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 300, onFinish: function onFinish() { effect.destroy(); } }); }; return self; }); var Rapper = Container.expand(function () { var self = Container.call(this); var rapperGraphics = self.attachAsset('rapper', { anchorX: 0.5, anchorY: 0.5 }); self.health = 3; self.maxHealth = 3; self.isInvulnerable = false; self.takeDamage = function () { if (self.isInvulnerable) return; self.health--; self.isInvulnerable = true; // Flash effect when hit LK.effects.flashObject(self, 0xFF0000, 500); LK.getSound('damage').play(); // Invulnerability period LK.setTimeout(function () { self.isInvulnerable = false; }, 1000); if (self.health <= 0) { LK.showGameOver(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ game.setBackgroundColor(0x16213e); // Game variables var rapper = null; var popstars = []; var dragNode = null; var score = 0; var combo = 0; var maxCombo = 0; var spawnTimer = 0; var spawnDelay = 120; // frames between spawns var difficultyTimer = 0; // UI elements var scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); scoreTxt.x = 150; scoreTxt.y = 50; LK.gui.topLeft.addChild(scoreTxt); var comboTxt = new Text2('Combo: 0', { size: 50, fill: 0xFFD700 }); comboTxt.anchor.set(0.5, 0); comboTxt.x = 0; comboTxt.y = 50; LK.gui.top.addChild(comboTxt); var healthTxt = new Text2('Health: 3', { size: 50, fill: 0xFF6B6B }); healthTxt.anchor.set(1, 0); healthTxt.x = -150; healthTxt.y = 50; LK.gui.topRight.addChild(healthTxt); // Initialize rapper rapper = game.addChild(new Rapper()); rapper.x = 1024; rapper.y = 1366; // Spawn popstar function function spawnPopstar() { var popstar = new PopStar(); // Random spawn position on edges var side = Math.floor(Math.random() * 4); switch (side) { case 0: // Top popstar.x = Math.random() * 2048; popstar.y = -50; break; case 1: // Right popstar.x = 2098; popstar.y = Math.random() * 2732; break; case 2: // Bottom popstar.x = Math.random() * 2048; popstar.y = 2782; break; case 3: // Left popstar.x = -50; popstar.y = Math.random() * 2732; break; } popstar.setTarget(rapper.x, rapper.y); var speedBonusLevel = Math.floor(score / 200); var speedBonus = speedBonusLevel * 0.25; var baseSpeed = 1.5 + speedBonus; popstar.speed = baseSpeed + Math.random() * 1.5; popstars.push(popstar); game.addChild(popstar); } // Handle touch input function handleMove(x, y, obj) { if (dragNode) { // Keep rapper within bounds dragNode.x = Math.max(60, Math.min(1988, x)); dragNode.y = Math.max(60, Math.min(2672, y)); // Update all popstar targets for (var i = 0; i < popstars.length; i++) { popstars[i].setTarget(dragNode.x, dragNode.y); } } } game.move = handleMove; game.down = function (x, y, obj) { // Check if tapping near any popstar var hitAny = false; for (var i = popstars.length - 1; i >= 0; i--) { var popstar = popstars[i]; if (popstar.isDead) continue; var dx = x - popstar.x; var dy = y - popstar.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= popstar.hitWindow) { // Hit popstar popstar.die(); popstars.splice(i, 1); popstar.destroy(); // Update score and combo score += 10 + combo * 2; combo++; maxCombo = Math.max(maxCombo, combo); // Play sound if (combo > 1) { LK.getSound('combo').play(); } else { LK.getSound('hit').play(); } hitAny = true; break; } } if (!hitAny) { // Missed hit, reset combo combo = 0; } // Start dragging rapper dragNode = rapper; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; // Main game loop game.update = function () { // Update UI scoreTxt.setText('Score: ' + score); comboTxt.setText('Combo: ' + combo); healthTxt.setText('Health: ' + rapper.health); // Spawn popstars spawnTimer++; if (spawnTimer >= spawnDelay) { spawnPopstar(); spawnTimer = 0; } // Increase pop star speed every 200 score points var speedBonusLevel = Math.floor(score / 200); var expectedSpeedBonus = speedBonusLevel * 0.25; // Increase all popstar speeds every 100 score points by 0.5 var popstarSpeedBonusLevel = Math.floor(score / 100); var popstarSpeedBonus = popstarSpeedBonusLevel * 0.5; // Apply speed bonus to all existing popstars for (var k = 0; k < popstars.length; k++) { var currentPopstar = popstars[k]; if (!currentPopstar.isDead) { var baseSpeed = 1.5 + Math.floor(score / 200) * 0.25; currentPopstar.speed = baseSpeed + Math.random() * 1.5 + popstarSpeedBonus; } } // Update popstars for (var i = popstars.length - 1; i >= 0; i--) { var popstar = popstars[i]; // Check collision with rapper if (!popstar.isDead && rapper.intersects(popstar)) { rapper.takeDamage(); // Health is reduced, combo remains unchanged popstar.die(); popstars.splice(i, 1); popstar.destroy(); continue; } // Check collision with other popstars if (!popstar.isDead) { for (var j = i - 1; j >= 0; j--) { var otherPopstar = popstars[j]; if (!otherPopstar.isDead && popstar.intersects(otherPopstar)) { // Both popstars collide and are destroyed popstar.die(); otherPopstar.die(); // Award score for both destroyed popstars score += 15; // Bonus points for collision combo++; // Play hit sound LK.getSound('hit').play(); // Remove both popstars popstars.splice(i, 1); popstar.destroy(); popstars.splice(j, 1); otherPopstar.destroy(); // Adjust index since we removed two elements i--; // Adjust for the removed element at index j break; // Exit inner loop since this popstar is destroyed } } } // Remove popstars that are too far off screen if (popstar.x < -200 || popstar.x > 2248 || popstar.y < -200 || popstar.y > 2932) { popstars.splice(i, 1); popstar.destroy(); } } // Update score for survival if (LK.ticks % 60 === 0) { score += 1; } // Add health every 100 score points var currentHealthBonus = Math.floor(score / 100); var expectedHealth = Math.min(3 + currentHealthBonus, rapper.maxHealth + currentHealthBonus); if (rapper.health < expectedHealth) { rapper.health = expectedHealth; rapper.maxHealth = Math.max(rapper.maxHealth, expectedHealth); } // Update LK score LK.setScore(score); }; // Start background music LK.playMusic('bgmusic');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var PopStar = Container.expand(function () {
var self = Container.call(this);
var popstarGraphics = self.attachAsset('popstar', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.targetX = 0;
self.targetY = 0;
self.isDead = false;
self.hitWindow = 100; // pixels around popstar where tap is effective
self.setTarget = function (x, y) {
self.targetX = x;
self.targetY = y;
};
self.update = function () {
if (self.isDead) return;
// Move toward target (rapper)
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
self.die = function () {
self.isDead = true;
// Create hit effect
var effect = game.addChild(LK.getAsset('hitEffect', {
anchorX: 0.5,
anchorY: 0.5
}));
effect.x = self.x;
effect.y = self.y;
// Animate effect
tween(effect, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
effect.destroy();
}
});
};
return self;
});
var Rapper = Container.expand(function () {
var self = Container.call(this);
var rapperGraphics = self.attachAsset('rapper', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.maxHealth = 3;
self.isInvulnerable = false;
self.takeDamage = function () {
if (self.isInvulnerable) return;
self.health--;
self.isInvulnerable = true;
// Flash effect when hit
LK.effects.flashObject(self, 0xFF0000, 500);
LK.getSound('damage').play();
// Invulnerability period
LK.setTimeout(function () {
self.isInvulnerable = false;
}, 1000);
if (self.health <= 0) {
LK.showGameOver();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
game.setBackgroundColor(0x16213e);
// Game variables
var rapper = null;
var popstars = [];
var dragNode = null;
var score = 0;
var combo = 0;
var maxCombo = 0;
var spawnTimer = 0;
var spawnDelay = 120; // frames between spawns
var difficultyTimer = 0;
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
scoreTxt.x = 150;
scoreTxt.y = 50;
LK.gui.topLeft.addChild(scoreTxt);
var comboTxt = new Text2('Combo: 0', {
size: 50,
fill: 0xFFD700
});
comboTxt.anchor.set(0.5, 0);
comboTxt.x = 0;
comboTxt.y = 50;
LK.gui.top.addChild(comboTxt);
var healthTxt = new Text2('Health: 3', {
size: 50,
fill: 0xFF6B6B
});
healthTxt.anchor.set(1, 0);
healthTxt.x = -150;
healthTxt.y = 50;
LK.gui.topRight.addChild(healthTxt);
// Initialize rapper
rapper = game.addChild(new Rapper());
rapper.x = 1024;
rapper.y = 1366;
// Spawn popstar function
function spawnPopstar() {
var popstar = new PopStar();
// Random spawn position on edges
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
popstar.x = Math.random() * 2048;
popstar.y = -50;
break;
case 1:
// Right
popstar.x = 2098;
popstar.y = Math.random() * 2732;
break;
case 2:
// Bottom
popstar.x = Math.random() * 2048;
popstar.y = 2782;
break;
case 3:
// Left
popstar.x = -50;
popstar.y = Math.random() * 2732;
break;
}
popstar.setTarget(rapper.x, rapper.y);
var speedBonusLevel = Math.floor(score / 200);
var speedBonus = speedBonusLevel * 0.25;
var baseSpeed = 1.5 + speedBonus;
popstar.speed = baseSpeed + Math.random() * 1.5;
popstars.push(popstar);
game.addChild(popstar);
}
// Handle touch input
function handleMove(x, y, obj) {
if (dragNode) {
// Keep rapper within bounds
dragNode.x = Math.max(60, Math.min(1988, x));
dragNode.y = Math.max(60, Math.min(2672, y));
// Update all popstar targets
for (var i = 0; i < popstars.length; i++) {
popstars[i].setTarget(dragNode.x, dragNode.y);
}
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Check if tapping near any popstar
var hitAny = false;
for (var i = popstars.length - 1; i >= 0; i--) {
var popstar = popstars[i];
if (popstar.isDead) continue;
var dx = x - popstar.x;
var dy = y - popstar.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= popstar.hitWindow) {
// Hit popstar
popstar.die();
popstars.splice(i, 1);
popstar.destroy();
// Update score and combo
score += 10 + combo * 2;
combo++;
maxCombo = Math.max(maxCombo, combo);
// Play sound
if (combo > 1) {
LK.getSound('combo').play();
} else {
LK.getSound('hit').play();
}
hitAny = true;
break;
}
}
if (!hitAny) {
// Missed hit, reset combo
combo = 0;
}
// Start dragging rapper
dragNode = rapper;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
// Update UI
scoreTxt.setText('Score: ' + score);
comboTxt.setText('Combo: ' + combo);
healthTxt.setText('Health: ' + rapper.health);
// Spawn popstars
spawnTimer++;
if (spawnTimer >= spawnDelay) {
spawnPopstar();
spawnTimer = 0;
}
// Increase pop star speed every 200 score points
var speedBonusLevel = Math.floor(score / 200);
var expectedSpeedBonus = speedBonusLevel * 0.25;
// Increase all popstar speeds every 100 score points by 0.5
var popstarSpeedBonusLevel = Math.floor(score / 100);
var popstarSpeedBonus = popstarSpeedBonusLevel * 0.5;
// Apply speed bonus to all existing popstars
for (var k = 0; k < popstars.length; k++) {
var currentPopstar = popstars[k];
if (!currentPopstar.isDead) {
var baseSpeed = 1.5 + Math.floor(score / 200) * 0.25;
currentPopstar.speed = baseSpeed + Math.random() * 1.5 + popstarSpeedBonus;
}
}
// Update popstars
for (var i = popstars.length - 1; i >= 0; i--) {
var popstar = popstars[i];
// Check collision with rapper
if (!popstar.isDead && rapper.intersects(popstar)) {
rapper.takeDamage();
// Health is reduced, combo remains unchanged
popstar.die();
popstars.splice(i, 1);
popstar.destroy();
continue;
}
// Check collision with other popstars
if (!popstar.isDead) {
for (var j = i - 1; j >= 0; j--) {
var otherPopstar = popstars[j];
if (!otherPopstar.isDead && popstar.intersects(otherPopstar)) {
// Both popstars collide and are destroyed
popstar.die();
otherPopstar.die();
// Award score for both destroyed popstars
score += 15; // Bonus points for collision
combo++;
// Play hit sound
LK.getSound('hit').play();
// Remove both popstars
popstars.splice(i, 1);
popstar.destroy();
popstars.splice(j, 1);
otherPopstar.destroy();
// Adjust index since we removed two elements
i--; // Adjust for the removed element at index j
break; // Exit inner loop since this popstar is destroyed
}
}
}
// Remove popstars that are too far off screen
if (popstar.x < -200 || popstar.x > 2248 || popstar.y < -200 || popstar.y > 2932) {
popstars.splice(i, 1);
popstar.destroy();
}
}
// Update score for survival
if (LK.ticks % 60 === 0) {
score += 1;
}
// Add health every 100 score points
var currentHealthBonus = Math.floor(score / 100);
var expectedHealth = Math.min(3 + currentHealthBonus, rapper.maxHealth + currentHealthBonus);
if (rapper.health < expectedHealth) {
rapper.health = expectedHealth;
rapper.maxHealth = Math.max(rapper.maxHealth, expectedHealth);
}
// Update LK score
LK.setScore(score);
};
// Start background music
LK.playMusic('bgmusic');