/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bubble = Container.expand(function () {
var self = Container.call(this);
// Bubble properties
self.bubbleType = 'medium'; // small, medium, large
self.speed = 2;
self.points = 10;
self.hasEscaped = false;
self.isPopped = false;
// Visual representation
var bubbleGraphics = null;
// Initialize bubble with specific type
self.init = function (type) {
self.bubbleType = type;
switch (type) {
case 'small':
bubbleGraphics = self.attachAsset('smallBubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.points = 30;
break;
case 'medium':
bubbleGraphics = self.attachAsset('mediumBubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.points = 20;
break;
case 'large':
bubbleGraphics = self.attachAsset('largeBubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.points = 10;
break;
}
// Add subtle floating animation
tween(bubbleGraphics, {
scaleX: 1.1,
scaleY: 0.9
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(bubbleGraphics, {
scaleX: 0.9,
scaleY: 1.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!self.isPopped) {
self.init(self.bubbleType); // Restart animation
}
}
});
}
});
};
self.update = function () {
if (!self.isPopped) {
self.y -= self.speed;
// Check if bubble has escaped (reached top of screen)
if (!self.hasEscaped && self.y < -100) {
self.hasEscaped = true;
escapedBubbles++;
LK.getSound('escape').play();
}
}
};
self.pop = function () {
if (!self.isPopped) {
self.isPopped = true;
LK.setScore(LK.getScore() + self.points);
LK.getSound('pop').play();
// Pop animation
tween(bubbleGraphics, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
// Mark for removal
self.shouldRemove = true;
}
});
}
};
self.down = function (x, y, obj) {
self.pop();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var bubbles = [];
var escapedBubbles = 0;
var gameSpeed = 1;
var spawnTimer = 0;
var spawnDelay = 90; // frames between spawns
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var escapedTxt = new Text2('Escaped: 0/5', {
size: 60,
fill: 0xFFFF00
});
escapedTxt.anchor.set(1, 0);
escapedTxt.x = -50;
escapedTxt.y = 100;
LK.gui.topRight.addChild(escapedTxt);
// Spawn bubble function
function spawnBubble() {
var bubble = new Bubble();
// Random bubble type with weighted distribution
var rand = Math.random();
var bubbleType;
if (rand < 0.5) {
bubbleType = 'large';
} else if (rand < 0.8) {
bubbleType = 'medium';
} else {
bubbleType = 'small';
}
bubble.init(bubbleType);
// Random horizontal position
bubble.x = 100 + Math.random() * (2048 - 200);
bubble.y = 2732 + 100; // Start below screen
// Apply game speed modifier
bubble.speed *= gameSpeed;
bubbles.push(bubble);
game.addChild(bubble);
}
game.update = function () {
// Update score display
scoreTxt.setText('Score: ' + LK.getScore());
escapedTxt.setText('Escaped: ' + escapedBubbles + '/5');
// Check game over condition
if (escapedBubbles >= 5) {
LK.showGameOver();
return;
}
// Increase game difficulty over time
if (LK.ticks % 1800 === 0) {
// Every 30 seconds
gameSpeed += 0.2;
spawnDelay = Math.max(30, spawnDelay - 5); // Faster spawning, minimum 30 frames
}
// Spawn new bubbles
spawnTimer++;
if (spawnTimer >= spawnDelay) {
spawnBubble();
spawnTimer = 0;
}
// Update and cleanup bubbles
for (var i = bubbles.length - 1; i >= 0; i--) {
var bubble = bubbles[i];
// Remove bubbles that are off screen or marked for removal
if (bubble.shouldRemove || bubble.y < -200) {
bubble.destroy();
bubbles.splice(i, 1);
}
}
};
// Initial spawn
spawnBubble();
spawnBubble(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bubble = Container.expand(function () {
var self = Container.call(this);
// Bubble properties
self.bubbleType = 'medium'; // small, medium, large
self.speed = 2;
self.points = 10;
self.hasEscaped = false;
self.isPopped = false;
// Visual representation
var bubbleGraphics = null;
// Initialize bubble with specific type
self.init = function (type) {
self.bubbleType = type;
switch (type) {
case 'small':
bubbleGraphics = self.attachAsset('smallBubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.points = 30;
break;
case 'medium':
bubbleGraphics = self.attachAsset('mediumBubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.points = 20;
break;
case 'large':
bubbleGraphics = self.attachAsset('largeBubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.points = 10;
break;
}
// Add subtle floating animation
tween(bubbleGraphics, {
scaleX: 1.1,
scaleY: 0.9
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(bubbleGraphics, {
scaleX: 0.9,
scaleY: 1.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!self.isPopped) {
self.init(self.bubbleType); // Restart animation
}
}
});
}
});
};
self.update = function () {
if (!self.isPopped) {
self.y -= self.speed;
// Check if bubble has escaped (reached top of screen)
if (!self.hasEscaped && self.y < -100) {
self.hasEscaped = true;
escapedBubbles++;
LK.getSound('escape').play();
}
}
};
self.pop = function () {
if (!self.isPopped) {
self.isPopped = true;
LK.setScore(LK.getScore() + self.points);
LK.getSound('pop').play();
// Pop animation
tween(bubbleGraphics, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
// Mark for removal
self.shouldRemove = true;
}
});
}
};
self.down = function (x, y, obj) {
self.pop();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var bubbles = [];
var escapedBubbles = 0;
var gameSpeed = 1;
var spawnTimer = 0;
var spawnDelay = 90; // frames between spawns
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var escapedTxt = new Text2('Escaped: 0/5', {
size: 60,
fill: 0xFFFF00
});
escapedTxt.anchor.set(1, 0);
escapedTxt.x = -50;
escapedTxt.y = 100;
LK.gui.topRight.addChild(escapedTxt);
// Spawn bubble function
function spawnBubble() {
var bubble = new Bubble();
// Random bubble type with weighted distribution
var rand = Math.random();
var bubbleType;
if (rand < 0.5) {
bubbleType = 'large';
} else if (rand < 0.8) {
bubbleType = 'medium';
} else {
bubbleType = 'small';
}
bubble.init(bubbleType);
// Random horizontal position
bubble.x = 100 + Math.random() * (2048 - 200);
bubble.y = 2732 + 100; // Start below screen
// Apply game speed modifier
bubble.speed *= gameSpeed;
bubbles.push(bubble);
game.addChild(bubble);
}
game.update = function () {
// Update score display
scoreTxt.setText('Score: ' + LK.getScore());
escapedTxt.setText('Escaped: ' + escapedBubbles + '/5');
// Check game over condition
if (escapedBubbles >= 5) {
LK.showGameOver();
return;
}
// Increase game difficulty over time
if (LK.ticks % 1800 === 0) {
// Every 30 seconds
gameSpeed += 0.2;
spawnDelay = Math.max(30, spawnDelay - 5); // Faster spawning, minimum 30 frames
}
// Spawn new bubbles
spawnTimer++;
if (spawnTimer >= spawnDelay) {
spawnBubble();
spawnTimer = 0;
}
// Update and cleanup bubbles
for (var i = bubbles.length - 1; i >= 0; i--) {
var bubble = bubbles[i];
// Remove bubbles that are off screen or marked for removal
if (bubble.shouldRemove || bubble.y < -200) {
bubble.destroy();
bubbles.splice(i, 1);
}
}
};
// Initial spawn
spawnBubble();
spawnBubble();