/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Balloon = Container.expand(function () { var self = Container.call(this); self.initBalloon = function (type) { self.balloonType = type; var assetName = type + 'Balloon'; self.balloonGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); // Set falling speed based on type - use current gameSpeed var currentGameSpeed = 20 + Math.floor(score / 200) * 2; if (type === 'bomb' || type === 'chaos') { self.fallSpeed = currentGameSpeed * 0.8; // Special balloons fall slightly slower } else { self.fallSpeed = currentGameSpeed; } self.isPopped = false; // Add floating animation self.floatOffset = Math.random() * Math.PI * 2; // Random starting phase self.originalX = 0; self.floatTimer = 0; return self; }; self.update = function () { if (!self.isPopped) { self.y += self.fallSpeed; // Add floating side-to-side animation self.floatTimer += 0.05; if (self.originalX === 0) { self.originalX = self.x; } self.x = self.originalX + Math.sin(self.floatTimer + self.floatOffset) * 15; } }; self.down = function (x, y, obj) { if (!self.isPopped) { self.popBalloon(); } }; self.popBalloon = function () { if (self.isPopped) return; self.isPopped = true; // Handle special balloon effects if (self.balloonType === 'bomb') { self.explodeBomb(); LK.getSound('special').play(); } else if (self.balloonType === 'chaos') { self.activateChaos(); LK.getSound('special').play(); } else if (self.balloonType === 'trap') { self.activateTrap(); LK.getSound('special').play(); } else { // Regular balloon - just add base score score += 20; LK.setScore(score); // Update LK score system LK.getSound('pop').play(); } // Visual explosion effect - first expand then shrink tween(self.balloonGraphics, { scaleX: 1.5, scaleY: 1.5, alpha: 0.8 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { // Then shrink and fade out tween(self.balloonGraphics, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 150, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); } }); } }); }; self.explodeBomb = function () { var explosionRadius = 200; for (var i = balloons.length - 1; i >= 0; i--) { var otherBalloon = balloons[i]; if (otherBalloon !== self && !otherBalloon.isPopped) { var dx = otherBalloon.x - self.x; var dy = otherBalloon.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= explosionRadius) { otherBalloon.popBalloon(); } } } score += 30; // Bomb balloon points LK.setScore(score); // Update LK score system }; self.activateChaos = function () { // Shuffle all balloon colors on screen for (var i = 0; i < balloons.length; i++) { var balloon = balloons[i]; if (!balloon.isPopped && balloon.balloonType !== 'bomb' && balloon.balloonType !== 'chaos') { var newType = regularColors[Math.floor(Math.random() * regularColors.length)]; balloon.changeBalloonType(newType); } } score += 20; LK.setScore(score); // Update LK score system }; self.activateTrap = function () { score -= 100; if (score < 0) score = 0; // Don't let score go negative LK.setScore(score); // Update LK score system }; self.changeBalloonType = function (newType) { self.balloonType = newType; self.removeChild(self.balloonGraphics); var assetName = newType + 'Balloon'; self.balloonGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Create sky background var skyBackground = game.addChild(LK.getAsset('skyBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); // Game variables var balloons = []; var score = 0; var baseScore = 10; var gameSpeed = 20; var spawnTimer = 0; var spawnRate = 45; // frames between spawns var regularColors = ['red', 'blue', 'green', 'yellow']; var specialTypes = ['bomb', 'chaos']; var lastTrapScore = 0; // Track when last trap balloon was spawned var trapBalloonActive = false; // Track if trap balloon is currently on screen var trapBalloonsSpawned = 0; // Track how many trap balloons have been spawned in current cycle var trapBalloonsOnScreen = 0; // Track current number of trap balloons on screen var lastTrophyScore = 0; // Track when last trophy was awarded // UI Elements var scoreText = new Text2('Score: 0', { size: 60, fill: '#FFFFFF' }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Trophy counter UI var trophyCount = storage.trophyCount || 0; var trophyText = new Text2('๐ ' + trophyCount, { size: 50, fill: '#FFD700' }); trophyText.anchor.set(1, 0); LK.gui.topRight.addChild(trophyText); function spawnBalloon() { var balloon = new Balloon(); var balloonType; // Check if we should spawn trap balloons (2 every 150 points) if (score >= lastTrapScore + 150 && trapBalloonsSpawned < 2) { balloonType = 'trap'; trapBalloonsSpawned++; trapBalloonsOnScreen++; if (trapBalloonsSpawned === 1) { lastTrapScore = score; // Update lastTrapScore only on first trap balloon } } else { // 15% chance for special balloons if (Math.random() < 0.15) { balloonType = specialTypes[Math.floor(Math.random() * specialTypes.length)]; } else { balloonType = regularColors[Math.floor(Math.random() * regularColors.length)]; } } balloon.initBalloon(balloonType); balloon.x = Math.random() * (2048 - 300) + 150; // Keep balloons within screen bounds balloon.y = -100; balloons.push(balloon); game.addChild(balloon); } function updateUI() { LK.setScore(score); scoreText.setText('Score: ' + score); // Check for trophy awards (every 1000 points) if (score >= lastTrophyScore + 1000) { trophyCount++; storage.trophyCount = trophyCount; lastTrophyScore = Math.floor(score / 1000) * 1000; // Set to the trophy milestone trophyText.setText('๐ ' + trophyCount); // Flash trophy text to show award LK.effects.flashObject(trophyText, 0xFFD700, 1000); // Create particle effect for trophy award var particle = new Text2('โจ', { size: 80, fill: '#FFD700' }); particle.anchor.set(0.5, 0.5); particle.x = trophyText.x - 50; particle.y = trophyText.y + 25; LK.gui.topRight.addChild(particle); // Animate particle with tween tween(particle, { y: particle.y - 100, alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { particle.destroy(); } }); } } game.update = function () { // Update game speed based on score (20 + 2 for every 200 points) gameSpeed = 20 + Math.floor(score / 200) * 2; // Update spawn rate based on speed increases var speedIncreases = Math.floor(score / 200); spawnRate = Math.max(15, 45 - speedIncreases * 3); // Spawn new balloons spawnTimer++; if (spawnTimer >= spawnRate) { spawnBalloon(); spawnTimer = 0; } // Check for balloons that have fallen off screen for (var i = balloons.length - 1; i >= 0; i--) { var balloon = balloons[i]; if (balloon.y > 2732 + 100) { // Check if it was a trap balloon if (balloon.balloonType === 'trap') { trapBalloonsOnScreen--; } // Balloon missed - just remove it balloon.destroy(); balloons.splice(i, 1); } } // Check for popped trap balloons to reset tracking for (var i = 0; i < balloons.length; i++) { var balloon = balloons[i]; if (balloon.balloonType === 'trap' && balloon.isPopped) { trapBalloonsOnScreen--; } } // Reset trap balloon cycle when all 2 have been removed if (trapBalloonsSpawned >= 2 && trapBalloonsOnScreen <= 0) { trapBalloonsSpawned = 0; } // Update UI updateUI(); }; // Initialize first balloon spawn spawnBalloon();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Balloon = Container.expand(function () {
var self = Container.call(this);
self.initBalloon = function (type) {
self.balloonType = type;
var assetName = type + 'Balloon';
self.balloonGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Set falling speed based on type - use current gameSpeed
var currentGameSpeed = 20 + Math.floor(score / 200) * 2;
if (type === 'bomb' || type === 'chaos') {
self.fallSpeed = currentGameSpeed * 0.8; // Special balloons fall slightly slower
} else {
self.fallSpeed = currentGameSpeed;
}
self.isPopped = false;
// Add floating animation
self.floatOffset = Math.random() * Math.PI * 2; // Random starting phase
self.originalX = 0;
self.floatTimer = 0;
return self;
};
self.update = function () {
if (!self.isPopped) {
self.y += self.fallSpeed;
// Add floating side-to-side animation
self.floatTimer += 0.05;
if (self.originalX === 0) {
self.originalX = self.x;
}
self.x = self.originalX + Math.sin(self.floatTimer + self.floatOffset) * 15;
}
};
self.down = function (x, y, obj) {
if (!self.isPopped) {
self.popBalloon();
}
};
self.popBalloon = function () {
if (self.isPopped) return;
self.isPopped = true;
// Handle special balloon effects
if (self.balloonType === 'bomb') {
self.explodeBomb();
LK.getSound('special').play();
} else if (self.balloonType === 'chaos') {
self.activateChaos();
LK.getSound('special').play();
} else if (self.balloonType === 'trap') {
self.activateTrap();
LK.getSound('special').play();
} else {
// Regular balloon - just add base score
score += 20;
LK.setScore(score); // Update LK score system
LK.getSound('pop').play();
}
// Visual explosion effect - first expand then shrink
tween(self.balloonGraphics, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.8
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
// Then shrink and fade out
tween(self.balloonGraphics, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
}
});
}
});
};
self.explodeBomb = function () {
var explosionRadius = 200;
for (var i = balloons.length - 1; i >= 0; i--) {
var otherBalloon = balloons[i];
if (otherBalloon !== self && !otherBalloon.isPopped) {
var dx = otherBalloon.x - self.x;
var dy = otherBalloon.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= explosionRadius) {
otherBalloon.popBalloon();
}
}
}
score += 30; // Bomb balloon points
LK.setScore(score); // Update LK score system
};
self.activateChaos = function () {
// Shuffle all balloon colors on screen
for (var i = 0; i < balloons.length; i++) {
var balloon = balloons[i];
if (!balloon.isPopped && balloon.balloonType !== 'bomb' && balloon.balloonType !== 'chaos') {
var newType = regularColors[Math.floor(Math.random() * regularColors.length)];
balloon.changeBalloonType(newType);
}
}
score += 20;
LK.setScore(score); // Update LK score system
};
self.activateTrap = function () {
score -= 100;
if (score < 0) score = 0; // Don't let score go negative
LK.setScore(score); // Update LK score system
};
self.changeBalloonType = function (newType) {
self.balloonType = newType;
self.removeChild(self.balloonGraphics);
var assetName = newType + 'Balloon';
self.balloonGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Create sky background
var skyBackground = game.addChild(LK.getAsset('skyBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
// Game variables
var balloons = [];
var score = 0;
var baseScore = 10;
var gameSpeed = 20;
var spawnTimer = 0;
var spawnRate = 45; // frames between spawns
var regularColors = ['red', 'blue', 'green', 'yellow'];
var specialTypes = ['bomb', 'chaos'];
var lastTrapScore = 0; // Track when last trap balloon was spawned
var trapBalloonActive = false; // Track if trap balloon is currently on screen
var trapBalloonsSpawned = 0; // Track how many trap balloons have been spawned in current cycle
var trapBalloonsOnScreen = 0; // Track current number of trap balloons on screen
var lastTrophyScore = 0; // Track when last trophy was awarded
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: '#FFFFFF'
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Trophy counter UI
var trophyCount = storage.trophyCount || 0;
var trophyText = new Text2('๐ ' + trophyCount, {
size: 50,
fill: '#FFD700'
});
trophyText.anchor.set(1, 0);
LK.gui.topRight.addChild(trophyText);
function spawnBalloon() {
var balloon = new Balloon();
var balloonType;
// Check if we should spawn trap balloons (2 every 150 points)
if (score >= lastTrapScore + 150 && trapBalloonsSpawned < 2) {
balloonType = 'trap';
trapBalloonsSpawned++;
trapBalloonsOnScreen++;
if (trapBalloonsSpawned === 1) {
lastTrapScore = score; // Update lastTrapScore only on first trap balloon
}
} else {
// 15% chance for special balloons
if (Math.random() < 0.15) {
balloonType = specialTypes[Math.floor(Math.random() * specialTypes.length)];
} else {
balloonType = regularColors[Math.floor(Math.random() * regularColors.length)];
}
}
balloon.initBalloon(balloonType);
balloon.x = Math.random() * (2048 - 300) + 150; // Keep balloons within screen bounds
balloon.y = -100;
balloons.push(balloon);
game.addChild(balloon);
}
function updateUI() {
LK.setScore(score);
scoreText.setText('Score: ' + score);
// Check for trophy awards (every 1000 points)
if (score >= lastTrophyScore + 1000) {
trophyCount++;
storage.trophyCount = trophyCount;
lastTrophyScore = Math.floor(score / 1000) * 1000; // Set to the trophy milestone
trophyText.setText('๐ ' + trophyCount);
// Flash trophy text to show award
LK.effects.flashObject(trophyText, 0xFFD700, 1000);
// Create particle effect for trophy award
var particle = new Text2('โจ', {
size: 80,
fill: '#FFD700'
});
particle.anchor.set(0.5, 0.5);
particle.x = trophyText.x - 50;
particle.y = trophyText.y + 25;
LK.gui.topRight.addChild(particle);
// Animate particle with tween
tween(particle, {
y: particle.y - 100,
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
particle.destroy();
}
});
}
}
game.update = function () {
// Update game speed based on score (20 + 2 for every 200 points)
gameSpeed = 20 + Math.floor(score / 200) * 2;
// Update spawn rate based on speed increases
var speedIncreases = Math.floor(score / 200);
spawnRate = Math.max(15, 45 - speedIncreases * 3);
// Spawn new balloons
spawnTimer++;
if (spawnTimer >= spawnRate) {
spawnBalloon();
spawnTimer = 0;
}
// Check for balloons that have fallen off screen
for (var i = balloons.length - 1; i >= 0; i--) {
var balloon = balloons[i];
if (balloon.y > 2732 + 100) {
// Check if it was a trap balloon
if (balloon.balloonType === 'trap') {
trapBalloonsOnScreen--;
}
// Balloon missed - just remove it
balloon.destroy();
balloons.splice(i, 1);
}
}
// Check for popped trap balloons to reset tracking
for (var i = 0; i < balloons.length; i++) {
var balloon = balloons[i];
if (balloon.balloonType === 'trap' && balloon.isPopped) {
trapBalloonsOnScreen--;
}
}
// Reset trap balloon cycle when all 2 have been removed
if (trapBalloonsSpawned >= 2 && trapBalloonsOnScreen <= 0) {
trapBalloonsSpawned = 0;
}
// Update UI
updateUI();
};
// Initialize first balloon spawn
spawnBalloon();