/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 1.0
});
var colors = [0xff69b4, 0x00bfff, 0x32cd32, 0xff4500, 0x9370db];
characterGraphics.tint = colors[Math.floor(Math.random() * colors.length)];
self.cheer = function () {
tween(self, {
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
tween(characterGraphics, {
rotation: -0.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(characterGraphics, {
rotation: 0.2
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(characterGraphics, {
rotation: 0
}, {
duration: 100,
easing: tween.easeIn
});
}
});
}
});
};
return self;
});
var Firework = Container.expand(function () {
var self = Container.call(this);
var fireworkTypes = ['firework', 'firework2', 'firework3', 'firework4', 'firework5'];
var randomType = fireworkTypes[Math.floor(Math.random() * fireworkTypes.length)];
var fireworkGraphics = self.attachAsset(randomType, {
anchorX: 0.5,
anchorY: 0.5
});
self.hasExploded = false;
self.scale = 0.1;
// Animate firework appearance
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeOut
});
// Add gentle floating animation
tween(fireworkGraphics, {
rotation: Math.PI * 2
}, {
duration: 3000,
easing: tween.linear
});
self.explode = function () {
if (self.hasExploded) return;
self.hasExploded = true;
// Create explosion particles
for (var i = 0; i < 12; i++) {
var particle = LK.getAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
var angle = i / 12 * Math.PI * 2;
var speed = 150 + Math.random() * 100;
var targetX = self.x + Math.cos(angle) * speed;
var targetY = self.y + Math.sin(angle) * speed;
particle.x = self.x;
particle.y = self.y;
particle.tint = fireworkGraphics.tint || 0xffffff;
game.addChild(particle);
particles.push(particle);
tween(particle, {
x: targetX,
y: targetY,
alpha: 0
}, {
duration: 800 + Math.random() * 400,
easing: tween.easeOut,
onFinish: function onFinish() {
if (particle.parent) {
particle.destroy();
var index = particles.indexOf(particle);
if (index > -1) particles.splice(index, 1);
}
}
});
}
// Flash effect
tween(fireworkGraphics, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut
});
LK.getSound('fireworkPop').play();
};
self.down = function (x, y, obj) {
self.explode();
tapsCompleted++;
LK.setScore(tapsCompleted);
updateProgressCounter();
// Check for celebration milestones
if (tapsCompleted % 7 === 0 && tapsCompleted < 31) {
triggerMilestoneCelebration();
}
if (tapsCompleted >= 31) {
triggerFinalCelebration();
}
// Remove from fireworks array and destroy
var index = fireworks.indexOf(self);
if (index > -1) fireworks.splice(index, 1);
setTimeout(function () {
if (self.parent) self.destroy();
}, 500);
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
starGraphics.alpha = 0.6 + Math.random() * 0.4;
// Twinkling animation
var _twinkle = function twinkle() {
tween(starGraphics, {
alpha: 0.2
}, {
duration: 1000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(starGraphics, {
alpha: 0.8
}, {
duration: 1000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: _twinkle
});
}
});
};
_twinkle();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a2e
});
/****
* Game Code
****/
var fireworks = [];
var particles = [];
var characters = [];
var stars = [];
var confettiPieces = [];
var balloons = [];
var tapsCompleted = 0;
var celebrationLevel = 0;
var gameCompleted = false;
var fireworkSpawnTimer = 0;
// Create progress counter
var progressText = new Text2('Fireworks: 0/31', {
size: 80,
fill: 0xFFFFFF
});
progressText.anchor.set(0.5, 0);
LK.gui.top.addChild(progressText);
// Create background stars
for (var i = 0; i < 50; i++) {
var star = new Star();
star.x = Math.random() * 2048;
star.y = Math.random() * 1800;
stars.push(star);
game.addChild(star);
}
// Create characters at bottom
for (var i = 0; i < 4; i++) {
var character = new Character();
character.x = 300 + i * 350;
character.y = 2700;
characters.push(character);
game.addChild(character);
}
function updateProgressCounter() {
progressText.setText('Fireworks: ' + tapsCompleted + '/31');
}
function spawnFirework() {
if (gameCompleted) return;
var firework = new Firework();
firework.x = 200 + Math.random() * 1648;
firework.y = 300 + Math.random() * 1000;
fireworks.push(firework);
game.addChild(firework);
// Auto-remove untapped fireworks after 5 seconds
setTimeout(function () {
if (!firework.hasExploded && firework.parent) {
tween(firework, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
if (firework.parent) {
firework.destroy();
var index = fireworks.indexOf(firework);
if (index > -1) fireworks.splice(index, 1);
}
}
});
}
}, 5000);
}
function triggerMilestoneCelebration() {
celebrationLevel++;
// Characters cheer
for (var i = 0; i < characters.length; i++) {
characters[i].cheer();
}
// Spawn some confetti
for (var i = 0; i < 15; i++) {
setTimeout(function () {
spawnConfetti();
}, i * 50);
}
LK.getSound('celebration').play();
}
function triggerFinalCelebration() {
if (gameCompleted) return;
gameCompleted = true;
// Massive confetti shower
for (var i = 0; i < 100; i++) {
setTimeout(function () {
spawnConfetti();
}, i * 30);
}
// Spawn balloons
for (var i = 0; i < 8; i++) {
setTimeout(function () {
spawnBalloon();
}, i * 200);
}
// All characters cheer
for (var i = 0; i < characters.length; i++) {
setTimeout(function (character) {
character.cheer();
}, i * 100, characters[i]);
}
// Flash screen effect
LK.effects.flashScreen(0xffd700, 2000);
progressText.setText('๐ CELEBRATION COMPLETE! ๐');
LK.getSound('celebration').play();
}
function spawnConfetti() {
var confetti = LK.getAsset('confetti', {
anchorX: 0.5,
anchorY: 0.5
});
var colors = [0xff6b6b, 0x4ecdc4, 0xffe66d, 0xa8e6cf, 0xff8b94, 0xffd93d];
confetti.tint = colors[Math.floor(Math.random() * colors.length)];
confetti.x = Math.random() * 2048;
confetti.y = -50;
confetti.rotation = Math.random() * Math.PI * 2;
game.addChild(confetti);
confettiPieces.push(confetti);
var fallSpeed = 1000 + Math.random() * 1500;
var sway = (Math.random() - 0.5) * 400;
tween(confetti, {
y: 2800,
x: confetti.x + sway,
rotation: confetti.rotation + Math.PI * 4
}, {
duration: fallSpeed,
easing: tween.easeIn,
onFinish: function onFinish() {
if (confetti.parent) {
confetti.destroy();
var index = confettiPieces.indexOf(confetti);
if (index > -1) confettiPieces.splice(index, 1);
}
}
});
}
function spawnBalloon() {
var balloon = LK.getAsset('balloon', {
anchorX: 0.5,
anchorY: 1.0
});
var colors = [0xff6b6b, 0x4ecdc4, 0xffe66d, 0xa8e6cf, 0xff8b94];
balloon.tint = colors[Math.floor(Math.random() * colors.length)];
balloon.x = 200 + Math.random() * 1648;
balloon.y = 2800;
game.addChild(balloon);
balloons.push(balloon);
var floatSpeed = 3000 + Math.random() * 2000;
var drift = (Math.random() - 0.5) * 300;
tween(balloon, {
y: -100,
x: balloon.x + drift
}, {
duration: floatSpeed,
easing: tween.easeOut,
onFinish: function onFinish() {
if (balloon.parent) {
balloon.destroy();
var index = balloons.indexOf(balloon);
if (index > -1) balloons.splice(index, 1);
}
}
});
}
// Start background music
LK.playMusic('bgmusic');
game.update = function () {
fireworkSpawnTimer++;
// Spawn fireworks every 60-120 ticks (1-2 seconds)
if (!gameCompleted && fireworkSpawnTimer >= 60 + Math.random() * 60) {
spawnFirework();
fireworkSpawnTimer = 0;
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 1.0
});
var colors = [0xff69b4, 0x00bfff, 0x32cd32, 0xff4500, 0x9370db];
characterGraphics.tint = colors[Math.floor(Math.random() * colors.length)];
self.cheer = function () {
tween(self, {
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
tween(characterGraphics, {
rotation: -0.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(characterGraphics, {
rotation: 0.2
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(characterGraphics, {
rotation: 0
}, {
duration: 100,
easing: tween.easeIn
});
}
});
}
});
};
return self;
});
var Firework = Container.expand(function () {
var self = Container.call(this);
var fireworkTypes = ['firework', 'firework2', 'firework3', 'firework4', 'firework5'];
var randomType = fireworkTypes[Math.floor(Math.random() * fireworkTypes.length)];
var fireworkGraphics = self.attachAsset(randomType, {
anchorX: 0.5,
anchorY: 0.5
});
self.hasExploded = false;
self.scale = 0.1;
// Animate firework appearance
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeOut
});
// Add gentle floating animation
tween(fireworkGraphics, {
rotation: Math.PI * 2
}, {
duration: 3000,
easing: tween.linear
});
self.explode = function () {
if (self.hasExploded) return;
self.hasExploded = true;
// Create explosion particles
for (var i = 0; i < 12; i++) {
var particle = LK.getAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
var angle = i / 12 * Math.PI * 2;
var speed = 150 + Math.random() * 100;
var targetX = self.x + Math.cos(angle) * speed;
var targetY = self.y + Math.sin(angle) * speed;
particle.x = self.x;
particle.y = self.y;
particle.tint = fireworkGraphics.tint || 0xffffff;
game.addChild(particle);
particles.push(particle);
tween(particle, {
x: targetX,
y: targetY,
alpha: 0
}, {
duration: 800 + Math.random() * 400,
easing: tween.easeOut,
onFinish: function onFinish() {
if (particle.parent) {
particle.destroy();
var index = particles.indexOf(particle);
if (index > -1) particles.splice(index, 1);
}
}
});
}
// Flash effect
tween(fireworkGraphics, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut
});
LK.getSound('fireworkPop').play();
};
self.down = function (x, y, obj) {
self.explode();
tapsCompleted++;
LK.setScore(tapsCompleted);
updateProgressCounter();
// Check for celebration milestones
if (tapsCompleted % 7 === 0 && tapsCompleted < 31) {
triggerMilestoneCelebration();
}
if (tapsCompleted >= 31) {
triggerFinalCelebration();
}
// Remove from fireworks array and destroy
var index = fireworks.indexOf(self);
if (index > -1) fireworks.splice(index, 1);
setTimeout(function () {
if (self.parent) self.destroy();
}, 500);
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
starGraphics.alpha = 0.6 + Math.random() * 0.4;
// Twinkling animation
var _twinkle = function twinkle() {
tween(starGraphics, {
alpha: 0.2
}, {
duration: 1000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(starGraphics, {
alpha: 0.8
}, {
duration: 1000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: _twinkle
});
}
});
};
_twinkle();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a2e
});
/****
* Game Code
****/
var fireworks = [];
var particles = [];
var characters = [];
var stars = [];
var confettiPieces = [];
var balloons = [];
var tapsCompleted = 0;
var celebrationLevel = 0;
var gameCompleted = false;
var fireworkSpawnTimer = 0;
// Create progress counter
var progressText = new Text2('Fireworks: 0/31', {
size: 80,
fill: 0xFFFFFF
});
progressText.anchor.set(0.5, 0);
LK.gui.top.addChild(progressText);
// Create background stars
for (var i = 0; i < 50; i++) {
var star = new Star();
star.x = Math.random() * 2048;
star.y = Math.random() * 1800;
stars.push(star);
game.addChild(star);
}
// Create characters at bottom
for (var i = 0; i < 4; i++) {
var character = new Character();
character.x = 300 + i * 350;
character.y = 2700;
characters.push(character);
game.addChild(character);
}
function updateProgressCounter() {
progressText.setText('Fireworks: ' + tapsCompleted + '/31');
}
function spawnFirework() {
if (gameCompleted) return;
var firework = new Firework();
firework.x = 200 + Math.random() * 1648;
firework.y = 300 + Math.random() * 1000;
fireworks.push(firework);
game.addChild(firework);
// Auto-remove untapped fireworks after 5 seconds
setTimeout(function () {
if (!firework.hasExploded && firework.parent) {
tween(firework, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
if (firework.parent) {
firework.destroy();
var index = fireworks.indexOf(firework);
if (index > -1) fireworks.splice(index, 1);
}
}
});
}
}, 5000);
}
function triggerMilestoneCelebration() {
celebrationLevel++;
// Characters cheer
for (var i = 0; i < characters.length; i++) {
characters[i].cheer();
}
// Spawn some confetti
for (var i = 0; i < 15; i++) {
setTimeout(function () {
spawnConfetti();
}, i * 50);
}
LK.getSound('celebration').play();
}
function triggerFinalCelebration() {
if (gameCompleted) return;
gameCompleted = true;
// Massive confetti shower
for (var i = 0; i < 100; i++) {
setTimeout(function () {
spawnConfetti();
}, i * 30);
}
// Spawn balloons
for (var i = 0; i < 8; i++) {
setTimeout(function () {
spawnBalloon();
}, i * 200);
}
// All characters cheer
for (var i = 0; i < characters.length; i++) {
setTimeout(function (character) {
character.cheer();
}, i * 100, characters[i]);
}
// Flash screen effect
LK.effects.flashScreen(0xffd700, 2000);
progressText.setText('๐ CELEBRATION COMPLETE! ๐');
LK.getSound('celebration').play();
}
function spawnConfetti() {
var confetti = LK.getAsset('confetti', {
anchorX: 0.5,
anchorY: 0.5
});
var colors = [0xff6b6b, 0x4ecdc4, 0xffe66d, 0xa8e6cf, 0xff8b94, 0xffd93d];
confetti.tint = colors[Math.floor(Math.random() * colors.length)];
confetti.x = Math.random() * 2048;
confetti.y = -50;
confetti.rotation = Math.random() * Math.PI * 2;
game.addChild(confetti);
confettiPieces.push(confetti);
var fallSpeed = 1000 + Math.random() * 1500;
var sway = (Math.random() - 0.5) * 400;
tween(confetti, {
y: 2800,
x: confetti.x + sway,
rotation: confetti.rotation + Math.PI * 4
}, {
duration: fallSpeed,
easing: tween.easeIn,
onFinish: function onFinish() {
if (confetti.parent) {
confetti.destroy();
var index = confettiPieces.indexOf(confetti);
if (index > -1) confettiPieces.splice(index, 1);
}
}
});
}
function spawnBalloon() {
var balloon = LK.getAsset('balloon', {
anchorX: 0.5,
anchorY: 1.0
});
var colors = [0xff6b6b, 0x4ecdc4, 0xffe66d, 0xa8e6cf, 0xff8b94];
balloon.tint = colors[Math.floor(Math.random() * colors.length)];
balloon.x = 200 + Math.random() * 1648;
balloon.y = 2800;
game.addChild(balloon);
balloons.push(balloon);
var floatSpeed = 3000 + Math.random() * 2000;
var drift = (Math.random() - 0.5) * 300;
tween(balloon, {
y: -100,
x: balloon.x + drift
}, {
duration: floatSpeed,
easing: tween.easeOut,
onFinish: function onFinish() {
if (balloon.parent) {
balloon.destroy();
var index = balloons.indexOf(balloon);
if (index > -1) balloons.splice(index, 1);
}
}
});
}
// Start background music
LK.playMusic('bgmusic');
game.update = function () {
fireworkSpawnTimer++;
// Spawn fireworks every 60-120 ticks (1-2 seconds)
if (!gameCompleted && fireworkSpawnTimer >= 60 + Math.random() * 60) {
spawnFirework();
fireworkSpawnTimer = 0;
}
};