/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bubble = Container.expand(function () { var self = Container.call(this); var bubbleGraphic = self.attachAsset('bubble', { anchorX: 0.5, anchorY: 0.5 }); self.isPopped = false; self.initialScale = 1; self.pop = function () { if (self.isPopped) { return; } self.isPopped = true; LK.getSound('pop').play(); // First shrink slightly tween(bubbleGraphic, { scaleX: 0.85, scaleY: 0.85, alpha: 0.8 }, { duration: 60, easing: tween.easeOut, onFinish: function onFinish() { // Then expand and fade out tween(bubbleGraphic, { scaleX: 0.1, scaleY: 0.1, alpha: 0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { if (self.onPopped) { self.onPopped(); } } }); } }); }; self.reset = function () { self.isPopped = false; bubbleGraphic.scaleX = self.initialScale; bubbleGraphic.scaleY = self.initialScale; bubbleGraphic.alpha = 1; }; self.down = function (x, y, obj) { self.pop(); }; return self; }); var RestartButton = Container.expand(function () { var self = Container.call(this); var buttonGraphic = self.attachAsset('restartButton', { anchorX: 0.5, anchorY: 0.5 }); self.down = function (x, y, obj) { resetGame(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x48d1cc // Cyan color for background }); /**** * Game Code ****/ var paperTexture = game.attachAsset('crumpledPaper', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(paperTexture); // Configuration var bubbleSize = 150; var bubblePadding = 30; var bubbleCount = 0; var totalBubbles = 0; var bubbles = []; var columns = 0; var rows = 0; // Text for remaining bubbles var remainingBubblesTxt = new Text2('Bubbles: 0', { size: 80, fill: 0x000000 }); remainingBubblesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(remainingBubblesTxt); // Initialize the game layout function initializeGame() { // Calculate grid layout based on screen dimensions var gameWidth = 2048; var gameHeight = 2732; // Calculate how many bubbles we can fit columns = Math.floor((gameWidth - bubblePadding) / (bubbleSize + bubblePadding)); rows = Math.floor((gameHeight - 200 - bubblePadding) / (bubbleSize + bubblePadding)); // Save space for UI // Center grid horizontally var startX = (gameWidth - (columns * (bubbleSize + bubblePadding) - bubblePadding)) / 2 + bubbleSize / 2; var startY = 200 + bubbleSize / 2; // Start below UI area // Clear existing bubbles if any for (var i = 0; i < bubbles.length; i++) { if (bubbles[i] && bubbles[i].parent) { bubbles[i].parent.removeChild(bubbles[i]); } } bubbles = []; bubbleCount = 0; totalBubbles = columns * rows; // Create bubbles grid for (var row = 0; row < rows; row++) { for (var col = 0; col < columns; col++) { var bubble = new Bubble(); bubble.x = startX + col * (bubbleSize + bubblePadding); bubble.y = startY + row * (bubbleSize + bubblePadding); // Random size variation for more natural look var scale = 0.85 + Math.random() * 0.3; bubble.initialScale = scale; bubble.getChildAt(0).scale.set(scale, scale); // Callback when bubble is popped bubble.onPopped = function () { bubbleCount++; updateUI(); // Check win condition if (bubbleCount >= totalBubbles) { LK.setTimeout(resetGame, 1500); } }; game.addChild(bubble); bubbles.push(bubble); } } updateUI(); } // Update UI elements function updateUI() { remainingBubblesTxt.setText('Bubbles: ' + bubbleCount + ' / ' + totalBubbles); } // Reset the game function resetGame() { initializeGame(); LK.getSound('girlVoice').play(); } // Initialize game on start LK.setTimeout(function () { initializeGame(); // Play background music LK.playMusic('relaxMusic', { fade: { start: 0, end: 0.4, duration: 1000 } }); LK.getSound('girlVoice').play(); // Initialize restart button var restartButton = new RestartButton(); restartButton.x = 2048 - 100; // Position the button 100 pixels from the right edge restartButton.y = 100; // Position the button 100 pixels from the top edge game.addChild(restartButton); }, 500); // Mouse/touch handlers for game area game.down = function (x, y, obj) { // This is handled by individual bubbles }; // Drag-to-pop: pop bubbles when dragging over them game.move = function (x, y, obj) { // For each bubble, check if the pointer is inside and not already popped for (var i = 0; i < bubbles.length; i++) { var bubble = bubbles[i]; if (!bubble.isPopped) { // Calculate distance from pointer to bubble center var dx = x - bubble.x; var dy = y - bubble.y; var radius = bubble.getChildAt(0).width * bubble.getChildAt(0).scaleX / 2; if (dx * dx + dy * dy <= radius * radius) { bubble.pop(); } } } }; // Update function called every frame game.update = function () { // No additional per-frame logic needed as bubbles handle their own popping };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Bubble = Container.expand(function () {
var self = Container.call(this);
var bubbleGraphic = self.attachAsset('bubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.isPopped = false;
self.initialScale = 1;
self.pop = function () {
if (self.isPopped) {
return;
}
self.isPopped = true;
LK.getSound('pop').play();
// First shrink slightly
tween(bubbleGraphic, {
scaleX: 0.85,
scaleY: 0.85,
alpha: 0.8
}, {
duration: 60,
easing: tween.easeOut,
onFinish: function onFinish() {
// Then expand and fade out
tween(bubbleGraphic, {
scaleX: 0.1,
scaleY: 0.1,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
if (self.onPopped) {
self.onPopped();
}
}
});
}
});
};
self.reset = function () {
self.isPopped = false;
bubbleGraphic.scaleX = self.initialScale;
bubbleGraphic.scaleY = self.initialScale;
bubbleGraphic.alpha = 1;
};
self.down = function (x, y, obj) {
self.pop();
};
return self;
});
var RestartButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphic = self.attachAsset('restartButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
resetGame();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x48d1cc // Cyan color for background
});
/****
* Game Code
****/
var paperTexture = game.attachAsset('crumpledPaper', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(paperTexture);
// Configuration
var bubbleSize = 150;
var bubblePadding = 30;
var bubbleCount = 0;
var totalBubbles = 0;
var bubbles = [];
var columns = 0;
var rows = 0;
// Text for remaining bubbles
var remainingBubblesTxt = new Text2('Bubbles: 0', {
size: 80,
fill: 0x000000
});
remainingBubblesTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(remainingBubblesTxt);
// Initialize the game layout
function initializeGame() {
// Calculate grid layout based on screen dimensions
var gameWidth = 2048;
var gameHeight = 2732;
// Calculate how many bubbles we can fit
columns = Math.floor((gameWidth - bubblePadding) / (bubbleSize + bubblePadding));
rows = Math.floor((gameHeight - 200 - bubblePadding) / (bubbleSize + bubblePadding)); // Save space for UI
// Center grid horizontally
var startX = (gameWidth - (columns * (bubbleSize + bubblePadding) - bubblePadding)) / 2 + bubbleSize / 2;
var startY = 200 + bubbleSize / 2; // Start below UI area
// Clear existing bubbles if any
for (var i = 0; i < bubbles.length; i++) {
if (bubbles[i] && bubbles[i].parent) {
bubbles[i].parent.removeChild(bubbles[i]);
}
}
bubbles = [];
bubbleCount = 0;
totalBubbles = columns * rows;
// Create bubbles grid
for (var row = 0; row < rows; row++) {
for (var col = 0; col < columns; col++) {
var bubble = new Bubble();
bubble.x = startX + col * (bubbleSize + bubblePadding);
bubble.y = startY + row * (bubbleSize + bubblePadding);
// Random size variation for more natural look
var scale = 0.85 + Math.random() * 0.3;
bubble.initialScale = scale;
bubble.getChildAt(0).scale.set(scale, scale);
// Callback when bubble is popped
bubble.onPopped = function () {
bubbleCount++;
updateUI();
// Check win condition
if (bubbleCount >= totalBubbles) {
LK.setTimeout(resetGame, 1500);
}
};
game.addChild(bubble);
bubbles.push(bubble);
}
}
updateUI();
}
// Update UI elements
function updateUI() {
remainingBubblesTxt.setText('Bubbles: ' + bubbleCount + ' / ' + totalBubbles);
}
// Reset the game
function resetGame() {
initializeGame();
LK.getSound('girlVoice').play();
}
// Initialize game on start
LK.setTimeout(function () {
initializeGame();
// Play background music
LK.playMusic('relaxMusic', {
fade: {
start: 0,
end: 0.4,
duration: 1000
}
});
LK.getSound('girlVoice').play();
// Initialize restart button
var restartButton = new RestartButton();
restartButton.x = 2048 - 100; // Position the button 100 pixels from the right edge
restartButton.y = 100; // Position the button 100 pixels from the top edge
game.addChild(restartButton);
}, 500);
// Mouse/touch handlers for game area
game.down = function (x, y, obj) {
// This is handled by individual bubbles
};
// Drag-to-pop: pop bubbles when dragging over them
game.move = function (x, y, obj) {
// For each bubble, check if the pointer is inside and not already popped
for (var i = 0; i < bubbles.length; i++) {
var bubble = bubbles[i];
if (!bubble.isPopped) {
// Calculate distance from pointer to bubble center
var dx = x - bubble.x;
var dy = y - bubble.y;
var radius = bubble.getChildAt(0).width * bubble.getChildAt(0).scaleX / 2;
if (dx * dx + dy * dy <= radius * radius) {
bubble.pop();
}
}
}
};
// Update function called every frame
game.update = function () {
// No additional per-frame logic needed as bubbles handle their own popping
};