/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Balloon class var Balloon = Container.expand(function () { var self = Container.call(this); // Balloon color options var colors = [0xff4d4d, 0x4db8ff, 0x4dff88, 0xffe14d, 0xff4df2, 0x9d4dff]; // Random color var color = colors[Math.floor(Math.random() * colors.length)]; // Random size var minSize = 120; var maxSize = 220; var size = minSize + Math.floor(Math.random() * (maxSize - minSize)); // Attach balloon shape (ellipse) var balloonShape = self.attachAsset('balloon', { width: size, height: size * 1.2, color: color, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5 }); // Is this a special balloon? self.isSpecial = false; self.specialType = null; // 10% chance to be a special balloon if (Math.random() < 0.1) { self.isSpecial = true; // Randomly choose special type: 'score' or 'slow' self.specialType = Math.random() < 0.5 ? 'score' : 'slow'; // Add a visual indicator (star or S) var specialTxt = new Text2(self.specialType === 'score' ? '★' : 'S', { size: size * 0.7, fill: self.specialType === 'score' ? "#fff700" : "#00eaff" }); specialTxt.anchor.set(0.5, 0.5); self.addChild(specialTxt); } // Set initial speed (pixels per frame) self.baseSpeed = 6 + Math.random() * 3; self.speed = self.baseSpeed; // For touch detection self.interactive = true; // For popping animation self.isPopping = false; // Pop balloon self.pop = function () { if (self.isPopping) return; self.isPopping = true; // Animate: scale up and fade out tween(self, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); }; // Update method called every tick self.update = function () { if (self.isPopping) return; self.y -= self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Sky blue }); /**** * Game Code ****/ // Game variables var balloons = []; var spawnInterval = 36; // frames between spawns (~0.6s at 60fps) var lastSpawnTick = 0; var gameDuration = 30 * 60; // 30 seconds * 60fps var timeLeft = gameDuration; var score = 0; var slowEffectTicks = 0; // Score text var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Timer text var timerTxt = new Text2('30', { size: 90, fill: 0xFFFFFF }); timerTxt.anchor.set(0.5, 0); LK.gui.top.addChild(timerTxt); timerTxt.y = 120; // Helper: spawn a balloon at random x function spawnBalloon() { var balloon = new Balloon(); // Random x, avoid leftmost 100px (menu) and rightmost 100px var margin = 140; var x = margin + Math.random() * (2048 - 2 * margin); balloon.x = x; // Start just below the bottom balloon.y = 2732 + balloon.height / 2; // Randomize z-order a bit game.addChild(balloon); balloons.push(balloon); } // Helper: handle popping a balloon function handlePop(balloon) { if (balloon.isPopping) return; // Score var addScore = 1; if (balloon.isSpecial) { if (balloon.specialType === 'score') { addScore = 5; LK.effects.flashObject(balloon, 0xfff700, 400); } else if (balloon.specialType === 'slow') { slowEffectTicks = 180; // 3 seconds slow LK.effects.flashScreen(0x00eaff, 300); } } score += addScore; LK.setScore(score); scoreTxt.setText(score); balloon.pop(); } // Touch/drag handling var dragBalloon = null; function getBalloonAt(x, y) { for (var i = balloons.length - 1; i >= 0; i--) { var b = balloons[i]; if (b.isPopping) continue; // Simple hit test: distance to center < radius var dx = x - b.x; var dy = y - b.y; var rx = b.width / 2; var ry = b.height / 2; if (dx * dx / (rx * rx) + dy * dy / (ry * ry) <= 1) { return b; } } return null; } // Touch down: pop balloon if touched game.down = function (x, y, obj) { var b = getBalloonAt(x, y); if (b) { handlePop(b); dragBalloon = b; } }; // Touch move: allow dragging finger to pop more balloons game.move = function (x, y, obj) { var b = getBalloonAt(x, y); if (b && b !== dragBalloon) { handlePop(b); dragBalloon = b; } }; // Touch up: reset drag game.up = function (x, y, obj) { dragBalloon = null; }; // Main update loop game.update = function () { // Spawn balloons if (LK.ticks - lastSpawnTick >= spawnInterval) { spawnBalloon(); lastSpawnTick = LK.ticks; } // Update slow effect var speedFactor = 1; if (slowEffectTicks > 0) { speedFactor = 0.4; slowEffectTicks--; } // Update balloons for (var i = balloons.length - 1; i >= 0; i--) { var b = balloons[i]; if (b.isPopping) continue; b.speed = b.baseSpeed * speedFactor; b.update(); // Remove if off top if (b.y + b.height / 2 < 0) { b.pop(); balloons.splice(i, 1); } } // Remove destroyed balloons from array for (var i = balloons.length - 1; i >= 0; i--) { if (balloons[i].destroyed) { balloons.splice(i, 1); } } // Update timer timeLeft--; var seconds = Math.ceil(timeLeft / 60); timerTxt.setText(seconds); // End game if time is up if (timeLeft <= 0) { LK.showGameOver(); } }; // Initialize score and timer score = 0; LK.setScore(score); scoreTxt.setText(score); timerTxt.setText(Math.ceil(gameDuration / 60));
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Balloon class
var Balloon = Container.expand(function () {
var self = Container.call(this);
// Balloon color options
var colors = [0xff4d4d, 0x4db8ff, 0x4dff88, 0xffe14d, 0xff4df2, 0x9d4dff];
// Random color
var color = colors[Math.floor(Math.random() * colors.length)];
// Random size
var minSize = 120;
var maxSize = 220;
var size = minSize + Math.floor(Math.random() * (maxSize - minSize));
// Attach balloon shape (ellipse)
var balloonShape = self.attachAsset('balloon', {
width: size,
height: size * 1.2,
color: color,
shape: 'ellipse',
anchorX: 0.5,
anchorY: 0.5
});
// Is this a special balloon?
self.isSpecial = false;
self.specialType = null;
// 10% chance to be a special balloon
if (Math.random() < 0.1) {
self.isSpecial = true;
// Randomly choose special type: 'score' or 'slow'
self.specialType = Math.random() < 0.5 ? 'score' : 'slow';
// Add a visual indicator (star or S)
var specialTxt = new Text2(self.specialType === 'score' ? '★' : 'S', {
size: size * 0.7,
fill: self.specialType === 'score' ? "#fff700" : "#00eaff"
});
specialTxt.anchor.set(0.5, 0.5);
self.addChild(specialTxt);
}
// Set initial speed (pixels per frame)
self.baseSpeed = 6 + Math.random() * 3;
self.speed = self.baseSpeed;
// For touch detection
self.interactive = true;
// For popping animation
self.isPopping = false;
// Pop balloon
self.pop = function () {
if (self.isPopping) return;
self.isPopping = true;
// Animate: scale up and fade out
tween(self, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
};
// Update method called every tick
self.update = function () {
if (self.isPopping) return;
self.y -= self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Sky blue
});
/****
* Game Code
****/
// Game variables
var balloons = [];
var spawnInterval = 36; // frames between spawns (~0.6s at 60fps)
var lastSpawnTick = 0;
var gameDuration = 30 * 60; // 30 seconds * 60fps
var timeLeft = gameDuration;
var score = 0;
var slowEffectTicks = 0;
// Score text
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Timer text
var timerTxt = new Text2('30', {
size: 90,
fill: 0xFFFFFF
});
timerTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(timerTxt);
timerTxt.y = 120;
// Helper: spawn a balloon at random x
function spawnBalloon() {
var balloon = new Balloon();
// Random x, avoid leftmost 100px (menu) and rightmost 100px
var margin = 140;
var x = margin + Math.random() * (2048 - 2 * margin);
balloon.x = x;
// Start just below the bottom
balloon.y = 2732 + balloon.height / 2;
// Randomize z-order a bit
game.addChild(balloon);
balloons.push(balloon);
}
// Helper: handle popping a balloon
function handlePop(balloon) {
if (balloon.isPopping) return;
// Score
var addScore = 1;
if (balloon.isSpecial) {
if (balloon.specialType === 'score') {
addScore = 5;
LK.effects.flashObject(balloon, 0xfff700, 400);
} else if (balloon.specialType === 'slow') {
slowEffectTicks = 180; // 3 seconds slow
LK.effects.flashScreen(0x00eaff, 300);
}
}
score += addScore;
LK.setScore(score);
scoreTxt.setText(score);
balloon.pop();
}
// Touch/drag handling
var dragBalloon = null;
function getBalloonAt(x, y) {
for (var i = balloons.length - 1; i >= 0; i--) {
var b = balloons[i];
if (b.isPopping) continue;
// Simple hit test: distance to center < radius
var dx = x - b.x;
var dy = y - b.y;
var rx = b.width / 2;
var ry = b.height / 2;
if (dx * dx / (rx * rx) + dy * dy / (ry * ry) <= 1) {
return b;
}
}
return null;
}
// Touch down: pop balloon if touched
game.down = function (x, y, obj) {
var b = getBalloonAt(x, y);
if (b) {
handlePop(b);
dragBalloon = b;
}
};
// Touch move: allow dragging finger to pop more balloons
game.move = function (x, y, obj) {
var b = getBalloonAt(x, y);
if (b && b !== dragBalloon) {
handlePop(b);
dragBalloon = b;
}
};
// Touch up: reset drag
game.up = function (x, y, obj) {
dragBalloon = null;
};
// Main update loop
game.update = function () {
// Spawn balloons
if (LK.ticks - lastSpawnTick >= spawnInterval) {
spawnBalloon();
lastSpawnTick = LK.ticks;
}
// Update slow effect
var speedFactor = 1;
if (slowEffectTicks > 0) {
speedFactor = 0.4;
slowEffectTicks--;
}
// Update balloons
for (var i = balloons.length - 1; i >= 0; i--) {
var b = balloons[i];
if (b.isPopping) continue;
b.speed = b.baseSpeed * speedFactor;
b.update();
// Remove if off top
if (b.y + b.height / 2 < 0) {
b.pop();
balloons.splice(i, 1);
}
}
// Remove destroyed balloons from array
for (var i = balloons.length - 1; i >= 0; i--) {
if (balloons[i].destroyed) {
balloons.splice(i, 1);
}
}
// Update timer
timeLeft--;
var seconds = Math.ceil(timeLeft / 60);
timerTxt.setText(seconds);
// End game if time is up
if (timeLeft <= 0) {
LK.showGameOver();
}
};
// Initialize score and timer
score = 0;
LK.setScore(score);
scoreTxt.setText(score);
timerTxt.setText(Math.ceil(gameDuration / 60));