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