/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bubble = Container.expand(function () { var self = Container.call(this); self.bubbleType = 'normal'; self.speed = 2; self.size = 1; self.popped = false; var bubbleGraphics = self.attachAsset('bubble', { anchorX: 0.5, anchorY: 0.5 }); self.setType = function (type, size) { self.bubbleType = type; self.size = size || 1; if (type === 'golden') { self.removeChildren(); bubbleGraphics = self.attachAsset('goldenBubble', { anchorX: 0.5, anchorY: 0.5 }); bubbleGraphics.tint = 0xFFD700; // Add pulsing animation for golden bubbles self.pulseAnimation = function () { if (!self.popped) { tween(self, { scaleX: self.size * 2.2, scaleY: self.size * 2.2 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { if (!self.popped) { tween(self, { scaleX: self.size * 2.0, scaleY: self.size * 2.0 }, { duration: 800, easing: tween.easeInOut, onFinish: self.pulseAnimation }); } } }); } }; } else if (size < 1) { self.removeChildren(); bubbleGraphics = self.attachAsset('smallBubble', { anchorX: 0.5, anchorY: 0.5 }); var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xFDAA4C, 0xA8E6CF]; bubbleGraphics.tint = colors[Math.floor(Math.random() * colors.length)]; } else { var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xFDAA4C, 0xA8E6CF]; bubbleGraphics.tint = colors[Math.floor(Math.random() * colors.length)]; } self.scaleX = self.scaleY = self.size * 2.0; // Start pulsing animation for golden bubbles if (type === 'golden') { LK.setTimeout(self.pulseAnimation, 100); } }; self.pop = function () { if (self.popped) { return []; } self.popped = true; var newBubbles = []; if (self.bubbleType === 'golden') { LK.getSound('goldPop').play(); } else { LK.getSound('pop').play(); } tween(self, { scaleX: self.size * 2.4, scaleY: self.size * 2.4, alpha: 0 }, { duration: 300, easing: tween.easeOut }); if (self.size >= 1 && self.bubbleType !== 'golden') { var numBubbles = 2 + Math.floor(Math.random() * 2); for (var i = 0; i < numBubbles; i++) { var angle = Math.PI * 2 / numBubbles * i; newBubbles.push({ x: self.x + Math.cos(angle) * 80, y: self.y + Math.sin(angle) * 80, size: 0.5, delay: i * 100 }); } } return newBubbles; }; self.update = function () { if (!self.popped) { self.y -= self.speed; self.x += Math.sin(LK.ticks * 0.02 + self.y * 0.01) * 1.5; // Add particle trail for golden bubbles and occasionally for normal bubbles if (self.bubbleType === 'golden' && LK.ticks % 3 === 0 || self.bubbleType !== 'golden' && LK.ticks % 12 === 0 && Math.random() < 0.6) { // Create 2-4 trail particles per spawn for golden, 1-2 for normal var trailCount = self.bubbleType === 'golden' ? 2 + Math.floor(Math.random() * 3) : 1 + Math.floor(Math.random() * 2); for (var t = 0; t < trailCount; t++) { var trailParticle = new Particle(); trailParticle.x = self.x + (Math.random() - 0.5) * 30; trailParticle.y = self.y + (Math.random() - 0.5) * 30; trailParticle.speed *= 0.3 + Math.random() * 0.4; trailParticle.life = 0.3 + Math.random() * 0.4; trailParticle.decay *= 1.5 + Math.random() * 1; trailParticle.scaleX = trailParticle.scaleY = 0.1 + Math.random() * 0.4; if (self.bubbleType === 'golden') { var goldenColors = [0xFFD700, 0xFFA500, 0xFFFF00]; trailParticle.children[0].tint = goldenColors[Math.floor(Math.random() * goldenColors.length)]; } particles.push(trailParticle); game.addChild(trailParticle); } } } }; self.down = function (x, y, obj) { if (!self.popped) { game.popBubble(self); } }; return self; }); var Particle = Container.expand(function () { var self = Container.call(this); self.speed = 3 + Math.random() * 4; self.angle = Math.random() * Math.PI * 2; self.life = 1.0; self.decay = 0.02 + Math.random() * 0.02; var particleGraphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); // Random size and color self.scaleX = self.scaleY = 0.3 + Math.random() * 0.4; var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xFDAA4C, 0xA8E6CF, 0xFFD700, 0xFF1493, 0x32CD32, 0xFF4500, 0x9370DB]; particleGraphics.tint = colors[Math.floor(Math.random() * colors.length)]; self.update = function () { // Move particle self.x += Math.cos(self.angle) * self.speed; self.y += Math.sin(self.angle) * self.speed; // Apply gravity self.angle += 0.05; self.speed *= 0.98; // Fade out self.life -= self.decay; self.alpha = self.life; self.scaleX = self.scaleY = self.life * (0.3 + Math.random() * 0.4); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1A237E }); /**** * Game Code ****/ game.setBackgroundColor(0x0D47A1); // Add background image var background = game.attachAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); // Add decorative small bubbles to background var backgroundBubbles = []; for (var i = 0; i < 15; i++) { var bgBubble = background.attachAsset('smallBubble', { anchorX: 0.5, anchorY: 0.5 }); bgBubble.x = Math.random() * 2048; bgBubble.y = Math.random() * 2732; bgBubble.alpha = 0.3; bgBubble.scaleX = bgBubble.scaleY = 0.5 + Math.random() * 0.5; var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xFDAA4C, 0xA8E6CF]; bgBubble.tint = colors[Math.floor(Math.random() * colors.length)]; bgBubble.baseY = bgBubble.y; bgBubble.floatSpeed = 0.5 + Math.random() * 1; bgBubble.floatRange = 20 + Math.random() * 30; backgroundBubbles.push(bgBubble); } var bubbles = []; var particles = []; var missedBubbles = 0; var speedMultiplier = 1; var lastSpeedIncrease = 0; var comboCount = 0; var lastPopTime = 0; var scoreTxt = new Text2('0', { size: 150, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var missedTxt = new Text2('Missed: 0/10', { size: 100, fill: 0xFF6B6B }); missedTxt.anchor.set(1, 0); missedTxt.x = -20; LK.gui.topRight.addChild(missedTxt); var comboTxt = new Text2('', { size: 120, fill: 0xFFD700 }); comboTxt.anchor.set(0.5, 0.5); LK.gui.center.addChild(comboTxt); game.popBubble = function (bubble) { var currentTime = Date.now(); if (currentTime - lastPopTime < 1000) { comboCount++; if (comboCount > 2) { LK.getSound('combo').play(); comboTxt.setText('Combo x' + comboCount + '!'); comboTxt.alpha = 1; tween(comboTxt, { alpha: 0 }, { duration: 1000, easing: tween.easeOut }); } } else { comboCount = 1; } lastPopTime = currentTime; // Create particles when bubble pops var particleCount = bubble.bubbleType === 'golden' ? 200 : bubble.size >= 1 ? 150 : 100; spawnParticles(bubble.x, bubble.y, particleCount, bubble.bubbleType); // Add explosive particle burst effect with multiple waves var explosionWaves = bubble.bubbleType === 'golden' ? 8 : 5; var explosionParticlesPerWave = bubble.bubbleType === 'golden' ? 80 : 50; for (var wave = 0; wave < explosionWaves; wave++) { LK.setTimeout(function (waveIndex) { return function () { for (var e = 0; e < explosionParticlesPerWave; e++) { var explosionParticle = new Particle(); explosionParticle.x = bubble.x + (Math.random() - 0.5) * waveIndex * 20; explosionParticle.y = bubble.y + (Math.random() - 0.5) * waveIndex * 20; // Create radial explosion pattern var angle = Math.PI * 2 / explosionParticlesPerWave * e + waveIndex * 0.3; var speed = (8 + Math.random() * 12) * (1 + waveIndex * 0.5); explosionParticle.speed = speed; explosionParticle.angle = angle; // Make explosion particles much larger and more dramatic explosionParticle.scaleX = explosionParticle.scaleY = (2.5 + Math.random() * 2.0) * (1 + waveIndex * 0.5); // Enhanced effects for golden bubbles if (bubble.bubbleType === 'golden') { explosionParticle.speed *= 1.8; explosionParticle.scaleX = explosionParticle.scaleY = (3.5 + Math.random() * 2.5) * (1 + waveIndex * 0.6); var goldenColors = [0xFFD700, 0xFFA500, 0xFFFF00]; explosionParticle.children[0].tint = goldenColors[Math.floor(Math.random() * goldenColors.length)]; } // Add explosive spawn animation explosionParticle.alpha = 0; var originalScale = explosionParticle.scaleX; explosionParticle.scaleX = explosionParticle.scaleY = 0; tween(explosionParticle, { alpha: 1, scaleX: originalScale, scaleY: originalScale }, { duration: 80 + Math.random() * 120, easing: tween.bounceOut }); particles.push(explosionParticle); game.addChild(explosionParticle); } }; }(wave), wave * 50); } var points = 10; if (bubble.bubbleType === 'golden') { points = 100; clearAllBubbles(); } else { points *= comboCount; if (bubble.size < 1) { points = Math.floor(points * 0.5); } } LK.setScore(LK.getScore() + points); scoreTxt.setText(LK.getScore()); // Game is now infinite - no win condition var newBubbleData = bubble.pop(); for (var i = 0; i < newBubbleData.length; i++) { var data = newBubbleData[i]; var newBubble = new Bubble(); newBubble.setType('normal', data.size); newBubble.x = data.x; newBubble.y = data.y; newBubble.speed = speedMultiplier * 2; // Add bouncy spawn animation with delay newBubble.scaleX = newBubble.scaleY = 0; LK.setTimeout(function (bubble) { return function () { tween(bubble, { scaleX: bubble.size * 2.0, scaleY: bubble.size * 2.0 }, { duration: 400, easing: tween.bounceOut }); }; }(newBubble), data.delay || 0); bubbles.push(newBubble); game.addChild(newBubble); } }; function clearAllBubbles() { // Add screen shake effect var originalX = game.x; var originalY = game.y; var shakeIntensity = 10; var shakeDuration = 500; var shakeCount = 0; var maxShakes = 20; var shakeInterval = LK.setInterval(function () { if (shakeCount < maxShakes) { game.x = originalX + (Math.random() - 0.5) * shakeIntensity; game.y = originalY + (Math.random() - 0.5) * shakeIntensity; shakeCount++; } else { game.x = originalX; game.y = originalY; LK.clearInterval(shakeInterval); } }, shakeDuration / maxShakes); for (var i = bubbles.length - 1; i >= 0; i--) { var bubble = bubbles[i]; if (!bubble.popped) { // Create extra particles for the clear effect spawnParticles(bubble.x, bubble.y, 12, 'golden'); bubble.pop(); LK.setScore(LK.getScore() + 5); } } // Add celebration burst at screen center spawnParticles(1024, 1366, 300, 'golden'); // Add additional burst effects around the screen spawnParticles(512, 1000, 200, 'golden'); spawnParticles(1536, 1000, 200, 'golden'); spawnParticles(1024, 800, 250, 'golden'); scoreTxt.setText(LK.getScore()); } function spawnParticles(x, y, count, bubbleType) { // Create multiple waves of particles for more spectacular effect var waves = bubbleType === 'golden' ? 10 : 6; var particlesPerWave = Math.ceil(count / waves); for (var wave = 0; wave < waves; wave++) { LK.setTimeout(function (waveIndex) { return function () { for (var i = 0; i < particlesPerWave; i++) { var particle = new Particle(); var spreadRadius = 40 + waveIndex * 20; particle.x = x + (Math.random() - 0.5) * spreadRadius; particle.y = y + (Math.random() - 0.5) * spreadRadius; // Golden bubbles create more spectacular particles // Add spawn animation with wave delay particle.alpha = 0; particle.scaleX = particle.scaleY = 0; tween(particle, { alpha: 1, scaleX: particle.scaleX || 0.3 + Math.random() * 0.4, scaleY: particle.scaleY || 0.3 + Math.random() * 0.4 }, { duration: 150 + waveIndex * 50, easing: tween.bounceOut }); particles.push(particle); game.addChild(particle); } }; }(wave), wave * 80); } } function spawnBubble() { var bubble = new Bubble(); if (Math.random() < 0.05) { bubble.setType('golden'); } else { bubble.setType('normal'); } bubble.x = 200 + Math.random() * (2048 - 400); bubble.y = 2732 + 100; bubble.speed = speedMultiplier * (2 + Math.random() * 2); // Add spawn animation bubble.scaleX = bubble.scaleY = 0; tween(bubble, { scaleX: bubble.size * 2.0, scaleY: bubble.size * 2.0 }, { duration: 500, easing: tween.elasticOut }); bubbles.push(bubble); game.addChild(bubble); } game.update = function () { // Animate background bubbles with smooth tween for (var j = 0; j < backgroundBubbles.length; j++) { var bgBubble = backgroundBubbles[j]; bgBubble.y = bgBubble.baseY + Math.sin(LK.ticks * 0.01 * bgBubble.floatSpeed) * bgBubble.floatRange; // Add subtle rotation animation if (!bgBubble.rotationTween) { bgBubble.rotationTween = true; tween(bgBubble, { rotation: Math.PI * 2 }, { duration: 10000 + Math.random() * 5000, easing: tween.linear, onFinish: function onFinish() { bgBubble.rotation = 0; bgBubble.rotationTween = false; } }); } } if (LK.ticks - lastSpeedIncrease > 1800) { speedMultiplier += 0.2; lastSpeedIncrease = LK.ticks; } if (LK.ticks % Math.floor(80 / speedMultiplier) === 0) { spawnBubble(); } for (var i = bubbles.length - 1; i >= 0; i--) { var bubble = bubbles[i]; if (bubble.lastY === undefined) { bubble.lastY = bubble.y; } if (bubble.lastY > -100 && bubble.y <= -100 && !bubble.popped) { missedBubbles++; missedTxt.setText('Missed: ' + missedBubbles + '/10'); if (missedBubbles >= 10) { LK.showGameOver(); } bubble.destroy(); bubbles.splice(i, 1); continue; } if (bubble.popped && bubble.alpha <= 0) { bubble.destroy(); bubbles.splice(i, 1); continue; } bubble.lastY = bubble.y; } // Update and cleanup particles for (var p = particles.length - 1; p >= 0; p--) { var particle = particles[p]; if (particle.life <= 0 || particle.alpha <= 0) { particle.destroy(); particles.splice(p, 1); continue; } } }; LK.playMusic('bgmusic');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bubble = Container.expand(function () {
var self = Container.call(this);
self.bubbleType = 'normal';
self.speed = 2;
self.size = 1;
self.popped = false;
var bubbleGraphics = self.attachAsset('bubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.setType = function (type, size) {
self.bubbleType = type;
self.size = size || 1;
if (type === 'golden') {
self.removeChildren();
bubbleGraphics = self.attachAsset('goldenBubble', {
anchorX: 0.5,
anchorY: 0.5
});
bubbleGraphics.tint = 0xFFD700;
// Add pulsing animation for golden bubbles
self.pulseAnimation = function () {
if (!self.popped) {
tween(self, {
scaleX: self.size * 2.2,
scaleY: self.size * 2.2
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!self.popped) {
tween(self, {
scaleX: self.size * 2.0,
scaleY: self.size * 2.0
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: self.pulseAnimation
});
}
}
});
}
};
} else if (size < 1) {
self.removeChildren();
bubbleGraphics = self.attachAsset('smallBubble', {
anchorX: 0.5,
anchorY: 0.5
});
var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xFDAA4C, 0xA8E6CF];
bubbleGraphics.tint = colors[Math.floor(Math.random() * colors.length)];
} else {
var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xFDAA4C, 0xA8E6CF];
bubbleGraphics.tint = colors[Math.floor(Math.random() * colors.length)];
}
self.scaleX = self.scaleY = self.size * 2.0;
// Start pulsing animation for golden bubbles
if (type === 'golden') {
LK.setTimeout(self.pulseAnimation, 100);
}
};
self.pop = function () {
if (self.popped) {
return [];
}
self.popped = true;
var newBubbles = [];
if (self.bubbleType === 'golden') {
LK.getSound('goldPop').play();
} else {
LK.getSound('pop').play();
}
tween(self, {
scaleX: self.size * 2.4,
scaleY: self.size * 2.4,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut
});
if (self.size >= 1 && self.bubbleType !== 'golden') {
var numBubbles = 2 + Math.floor(Math.random() * 2);
for (var i = 0; i < numBubbles; i++) {
var angle = Math.PI * 2 / numBubbles * i;
newBubbles.push({
x: self.x + Math.cos(angle) * 80,
y: self.y + Math.sin(angle) * 80,
size: 0.5,
delay: i * 100
});
}
}
return newBubbles;
};
self.update = function () {
if (!self.popped) {
self.y -= self.speed;
self.x += Math.sin(LK.ticks * 0.02 + self.y * 0.01) * 1.5;
// Add particle trail for golden bubbles and occasionally for normal bubbles
if (self.bubbleType === 'golden' && LK.ticks % 3 === 0 || self.bubbleType !== 'golden' && LK.ticks % 12 === 0 && Math.random() < 0.6) {
// Create 2-4 trail particles per spawn for golden, 1-2 for normal
var trailCount = self.bubbleType === 'golden' ? 2 + Math.floor(Math.random() * 3) : 1 + Math.floor(Math.random() * 2);
for (var t = 0; t < trailCount; t++) {
var trailParticle = new Particle();
trailParticle.x = self.x + (Math.random() - 0.5) * 30;
trailParticle.y = self.y + (Math.random() - 0.5) * 30;
trailParticle.speed *= 0.3 + Math.random() * 0.4;
trailParticle.life = 0.3 + Math.random() * 0.4;
trailParticle.decay *= 1.5 + Math.random() * 1;
trailParticle.scaleX = trailParticle.scaleY = 0.1 + Math.random() * 0.4;
if (self.bubbleType === 'golden') {
var goldenColors = [0xFFD700, 0xFFA500, 0xFFFF00];
trailParticle.children[0].tint = goldenColors[Math.floor(Math.random() * goldenColors.length)];
}
particles.push(trailParticle);
game.addChild(trailParticle);
}
}
}
};
self.down = function (x, y, obj) {
if (!self.popped) {
game.popBubble(self);
}
};
return self;
});
var Particle = Container.expand(function () {
var self = Container.call(this);
self.speed = 3 + Math.random() * 4;
self.angle = Math.random() * Math.PI * 2;
self.life = 1.0;
self.decay = 0.02 + Math.random() * 0.02;
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
// Random size and color
self.scaleX = self.scaleY = 0.3 + Math.random() * 0.4;
var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xFDAA4C, 0xA8E6CF, 0xFFD700, 0xFF1493, 0x32CD32, 0xFF4500, 0x9370DB];
particleGraphics.tint = colors[Math.floor(Math.random() * colors.length)];
self.update = function () {
// Move particle
self.x += Math.cos(self.angle) * self.speed;
self.y += Math.sin(self.angle) * self.speed;
// Apply gravity
self.angle += 0.05;
self.speed *= 0.98;
// Fade out
self.life -= self.decay;
self.alpha = self.life;
self.scaleX = self.scaleY = self.life * (0.3 + Math.random() * 0.4);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1A237E
});
/****
* Game Code
****/
game.setBackgroundColor(0x0D47A1);
// Add background image
var background = game.attachAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
// Add decorative small bubbles to background
var backgroundBubbles = [];
for (var i = 0; i < 15; i++) {
var bgBubble = background.attachAsset('smallBubble', {
anchorX: 0.5,
anchorY: 0.5
});
bgBubble.x = Math.random() * 2048;
bgBubble.y = Math.random() * 2732;
bgBubble.alpha = 0.3;
bgBubble.scaleX = bgBubble.scaleY = 0.5 + Math.random() * 0.5;
var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0xFDAA4C, 0xA8E6CF];
bgBubble.tint = colors[Math.floor(Math.random() * colors.length)];
bgBubble.baseY = bgBubble.y;
bgBubble.floatSpeed = 0.5 + Math.random() * 1;
bgBubble.floatRange = 20 + Math.random() * 30;
backgroundBubbles.push(bgBubble);
}
var bubbles = [];
var particles = [];
var missedBubbles = 0;
var speedMultiplier = 1;
var lastSpeedIncrease = 0;
var comboCount = 0;
var lastPopTime = 0;
var scoreTxt = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var missedTxt = new Text2('Missed: 0/10', {
size: 100,
fill: 0xFF6B6B
});
missedTxt.anchor.set(1, 0);
missedTxt.x = -20;
LK.gui.topRight.addChild(missedTxt);
var comboTxt = new Text2('', {
size: 120,
fill: 0xFFD700
});
comboTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(comboTxt);
game.popBubble = function (bubble) {
var currentTime = Date.now();
if (currentTime - lastPopTime < 1000) {
comboCount++;
if (comboCount > 2) {
LK.getSound('combo').play();
comboTxt.setText('Combo x' + comboCount + '!');
comboTxt.alpha = 1;
tween(comboTxt, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut
});
}
} else {
comboCount = 1;
}
lastPopTime = currentTime;
// Create particles when bubble pops
var particleCount = bubble.bubbleType === 'golden' ? 200 : bubble.size >= 1 ? 150 : 100;
spawnParticles(bubble.x, bubble.y, particleCount, bubble.bubbleType);
// Add explosive particle burst effect with multiple waves
var explosionWaves = bubble.bubbleType === 'golden' ? 8 : 5;
var explosionParticlesPerWave = bubble.bubbleType === 'golden' ? 80 : 50;
for (var wave = 0; wave < explosionWaves; wave++) {
LK.setTimeout(function (waveIndex) {
return function () {
for (var e = 0; e < explosionParticlesPerWave; e++) {
var explosionParticle = new Particle();
explosionParticle.x = bubble.x + (Math.random() - 0.5) * waveIndex * 20;
explosionParticle.y = bubble.y + (Math.random() - 0.5) * waveIndex * 20;
// Create radial explosion pattern
var angle = Math.PI * 2 / explosionParticlesPerWave * e + waveIndex * 0.3;
var speed = (8 + Math.random() * 12) * (1 + waveIndex * 0.5);
explosionParticle.speed = speed;
explosionParticle.angle = angle;
// Make explosion particles much larger and more dramatic
explosionParticle.scaleX = explosionParticle.scaleY = (2.5 + Math.random() * 2.0) * (1 + waveIndex * 0.5);
// Enhanced effects for golden bubbles
if (bubble.bubbleType === 'golden') {
explosionParticle.speed *= 1.8;
explosionParticle.scaleX = explosionParticle.scaleY = (3.5 + Math.random() * 2.5) * (1 + waveIndex * 0.6);
var goldenColors = [0xFFD700, 0xFFA500, 0xFFFF00];
explosionParticle.children[0].tint = goldenColors[Math.floor(Math.random() * goldenColors.length)];
}
// Add explosive spawn animation
explosionParticle.alpha = 0;
var originalScale = explosionParticle.scaleX;
explosionParticle.scaleX = explosionParticle.scaleY = 0;
tween(explosionParticle, {
alpha: 1,
scaleX: originalScale,
scaleY: originalScale
}, {
duration: 80 + Math.random() * 120,
easing: tween.bounceOut
});
particles.push(explosionParticle);
game.addChild(explosionParticle);
}
};
}(wave), wave * 50);
}
var points = 10;
if (bubble.bubbleType === 'golden') {
points = 100;
clearAllBubbles();
} else {
points *= comboCount;
if (bubble.size < 1) {
points = Math.floor(points * 0.5);
}
}
LK.setScore(LK.getScore() + points);
scoreTxt.setText(LK.getScore());
// Game is now infinite - no win condition
var newBubbleData = bubble.pop();
for (var i = 0; i < newBubbleData.length; i++) {
var data = newBubbleData[i];
var newBubble = new Bubble();
newBubble.setType('normal', data.size);
newBubble.x = data.x;
newBubble.y = data.y;
newBubble.speed = speedMultiplier * 2;
// Add bouncy spawn animation with delay
newBubble.scaleX = newBubble.scaleY = 0;
LK.setTimeout(function (bubble) {
return function () {
tween(bubble, {
scaleX: bubble.size * 2.0,
scaleY: bubble.size * 2.0
}, {
duration: 400,
easing: tween.bounceOut
});
};
}(newBubble), data.delay || 0);
bubbles.push(newBubble);
game.addChild(newBubble);
}
};
function clearAllBubbles() {
// Add screen shake effect
var originalX = game.x;
var originalY = game.y;
var shakeIntensity = 10;
var shakeDuration = 500;
var shakeCount = 0;
var maxShakes = 20;
var shakeInterval = LK.setInterval(function () {
if (shakeCount < maxShakes) {
game.x = originalX + (Math.random() - 0.5) * shakeIntensity;
game.y = originalY + (Math.random() - 0.5) * shakeIntensity;
shakeCount++;
} else {
game.x = originalX;
game.y = originalY;
LK.clearInterval(shakeInterval);
}
}, shakeDuration / maxShakes);
for (var i = bubbles.length - 1; i >= 0; i--) {
var bubble = bubbles[i];
if (!bubble.popped) {
// Create extra particles for the clear effect
spawnParticles(bubble.x, bubble.y, 12, 'golden');
bubble.pop();
LK.setScore(LK.getScore() + 5);
}
}
// Add celebration burst at screen center
spawnParticles(1024, 1366, 300, 'golden');
// Add additional burst effects around the screen
spawnParticles(512, 1000, 200, 'golden');
spawnParticles(1536, 1000, 200, 'golden');
spawnParticles(1024, 800, 250, 'golden');
scoreTxt.setText(LK.getScore());
}
function spawnParticles(x, y, count, bubbleType) {
// Create multiple waves of particles for more spectacular effect
var waves = bubbleType === 'golden' ? 10 : 6;
var particlesPerWave = Math.ceil(count / waves);
for (var wave = 0; wave < waves; wave++) {
LK.setTimeout(function (waveIndex) {
return function () {
for (var i = 0; i < particlesPerWave; i++) {
var particle = new Particle();
var spreadRadius = 40 + waveIndex * 20;
particle.x = x + (Math.random() - 0.5) * spreadRadius;
particle.y = y + (Math.random() - 0.5) * spreadRadius;
// Golden bubbles create more spectacular particles
// Add spawn animation with wave delay
particle.alpha = 0;
particle.scaleX = particle.scaleY = 0;
tween(particle, {
alpha: 1,
scaleX: particle.scaleX || 0.3 + Math.random() * 0.4,
scaleY: particle.scaleY || 0.3 + Math.random() * 0.4
}, {
duration: 150 + waveIndex * 50,
easing: tween.bounceOut
});
particles.push(particle);
game.addChild(particle);
}
};
}(wave), wave * 80);
}
}
function spawnBubble() {
var bubble = new Bubble();
if (Math.random() < 0.05) {
bubble.setType('golden');
} else {
bubble.setType('normal');
}
bubble.x = 200 + Math.random() * (2048 - 400);
bubble.y = 2732 + 100;
bubble.speed = speedMultiplier * (2 + Math.random() * 2);
// Add spawn animation
bubble.scaleX = bubble.scaleY = 0;
tween(bubble, {
scaleX: bubble.size * 2.0,
scaleY: bubble.size * 2.0
}, {
duration: 500,
easing: tween.elasticOut
});
bubbles.push(bubble);
game.addChild(bubble);
}
game.update = function () {
// Animate background bubbles with smooth tween
for (var j = 0; j < backgroundBubbles.length; j++) {
var bgBubble = backgroundBubbles[j];
bgBubble.y = bgBubble.baseY + Math.sin(LK.ticks * 0.01 * bgBubble.floatSpeed) * bgBubble.floatRange;
// Add subtle rotation animation
if (!bgBubble.rotationTween) {
bgBubble.rotationTween = true;
tween(bgBubble, {
rotation: Math.PI * 2
}, {
duration: 10000 + Math.random() * 5000,
easing: tween.linear,
onFinish: function onFinish() {
bgBubble.rotation = 0;
bgBubble.rotationTween = false;
}
});
}
}
if (LK.ticks - lastSpeedIncrease > 1800) {
speedMultiplier += 0.2;
lastSpeedIncrease = LK.ticks;
}
if (LK.ticks % Math.floor(80 / speedMultiplier) === 0) {
spawnBubble();
}
for (var i = bubbles.length - 1; i >= 0; i--) {
var bubble = bubbles[i];
if (bubble.lastY === undefined) {
bubble.lastY = bubble.y;
}
if (bubble.lastY > -100 && bubble.y <= -100 && !bubble.popped) {
missedBubbles++;
missedTxt.setText('Missed: ' + missedBubbles + '/10');
if (missedBubbles >= 10) {
LK.showGameOver();
}
bubble.destroy();
bubbles.splice(i, 1);
continue;
}
if (bubble.popped && bubble.alpha <= 0) {
bubble.destroy();
bubbles.splice(i, 1);
continue;
}
bubble.lastY = bubble.y;
}
// Update and cleanup particles
for (var p = particles.length - 1; p >= 0; p--) {
var particle = particles[p];
if (particle.life <= 0 || particle.alpha <= 0) {
particle.destroy();
particles.splice(p, 1);
continue;
}
}
};
LK.playMusic('bgmusic');