/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bush = Container.expand(function () { var self = Container.call(this); var bushGraphics = self.attachAsset('bush', { anchorX: 0.5, anchorY: 1 }); self.hasBeenTapped = false; self.down = function (x, y, obj) { if (!self.hasBeenTapped) { self.hasBeenTapped = true; tween(bushGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); tween(bushGraphics, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); LK.getSound('surprise').play(); // Create a small surprise effect var surpriseText = new Text2('Surprise!', { size: 40, fill: '#FF69B4' }); surpriseText.anchor.set(0.5, 0.5); surpriseText.x = self.x; surpriseText.y = self.y - 100; game.addChild(surpriseText); tween(surpriseText, { alpha: 0, y: surpriseText.y - 50 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { surpriseText.destroy(); } }); } }; return self; }); var Candle = Container.expand(function () { var self = Container.call(this); var candleBody = self.attachAsset('candle', { anchorX: 0.5, anchorY: 1 }); var flame = self.attachAsset('flame', { anchorX: 0.5, anchorY: 1, y: -60 }); self.isLit = false; flame.visible = false; self.light = function () { if (!self.isLit) { self.isLit = true; flame.visible = true; tween(flame, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, easing: tween.easeOut }); tween(flame, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); LK.getSound('lightCandle').play(); } }; self.extinguish = function () { if (self.isLit) { self.isLit = false; flame.visible = false; } }; self.down = function (x, y, obj) { if (!self.isLit) { self.light(); } }; return self; }); var Character = Container.expand(function (characterId) { var self = Container.call(this); var characterGraphics = self.attachAsset(characterId, { anchorX: 0.5, anchorY: 1 }); self.characterId = characterId; self.down = function (x, y, obj) { if (self.characterId === 'bubbles') { blowOutCandles(); } else if (self.characterId === 'bliss') { playHappyBirthday(); } }; return self; }); var Confetti = Container.expand(function () { var self = Container.call(this); var colors = [0xFF69B4, 0x00CED1, 0xFFD700, 0xFF6347, 0x98FB98]; var randomColor = colors[Math.floor(Math.random() * colors.length)]; var confettiGraphics = self.attachAsset('confetti', { anchorX: 0.5, anchorY: 0.5 }); confettiGraphics.tint = randomColor; self.speed = Math.random() * 3 + 2; self.rotation = Math.random() * 0.1 - 0.05; self.update = function () { self.y += self.speed; self.rotation += self.rotation; if (self.y > 2732 + 50) { self.destroy(); for (var i = confettiPieces.length - 1; i >= 0; i--) { if (confettiPieces[i] === self) { confettiPieces.splice(i, 1); break; } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game state variables var candles = []; var confettiPieces = []; var candlesBlownCount = 0; var gameComplete = false; // Create cake var cake = game.addChild(LK.getAsset('cake', { anchorX: 0.5, anchorY: 0.5 })); cake.x = 1024; cake.y = 1400; // Create candles around the cake var candlePositions = [{ x: 1024 - 120, y: 1320 }, { x: 1024 - 60, y: 1300 }, { x: 1024, y: 1290 }, { x: 1024 + 60, y: 1300 }, { x: 1024 + 120, y: 1320 }]; for (var i = 0; i < candlePositions.length; i++) { var candle = game.addChild(new Candle()); candle.x = candlePositions[i].x; candle.y = candlePositions[i].y; candles.push(candle); } // Create characters var bubbles = game.addChild(new Character('bubbles')); bubbles.x = 1024; bubbles.y = 1800; var blossom = game.addChild(new Character('blossom')); blossom.x = 400; blossom.y = 1700; var buttercup = game.addChild(new Character('buttercup')); buttercup.x = 1648; buttercup.y = 1700; var bliss = game.addChild(new Character('bliss')); bliss.x = 1024; bliss.y = 800; // Create music note above Bliss var musicNote = game.addChild(LK.getAsset('musicNote', { anchorX: 0.5, anchorY: 0.5 })); musicNote.x = bliss.x + 70; musicNote.y = bliss.y - 150; // Create bushes var bushPositions = [{ x: 200, y: 2000 }, { x: 1848, y: 2000 }, { x: 100, y: 1200 }, { x: 1948, y: 1200 }]; for (var i = 0; i < bushPositions.length; i++) { var bush = game.addChild(new Bush()); bush.x = bushPositions[i].x; bush.y = bushPositions[i].y; } // Create instruction text var instructionText = new Text2('Tap candles to light them!', { size: 50, fill: '#FFFFFF' }); instructionText.anchor.set(0.5, 0); LK.gui.top.addChild(instructionText); function areAllCandlesLit() { for (var i = 0; i < candles.length; i++) { if (!candles[i].isLit) { return false; } } return true; } function blowOutCandles() { if (areAllCandlesLit() && !gameComplete) { for (var i = 0; i < candles.length; i++) { candles[i].extinguish(); } candlesBlownCount++; LK.getSound('blowCandle').play(); // Animate Bubbles blowing tween(bubbles, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); tween(bubbles, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); if (candlesBlownCount === 1) { instructionText.setText('Great! Light them again and blow once more!'); } else if (candlesBlownCount === 2) { triggerCakeExplosion(); } } } function playHappyBirthday() { LK.getSound('happyBirthday').play(); // Animate music note tween(musicNote, { scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeOut }); tween(musicNote, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); // Show singing text var singingText = new Text2('♪ Happy Birthday! ♪', { size: 60, fill: '#FF69B4' }); singingText.anchor.set(0.5, 0.5); singingText.x = bliss.x; singingText.y = bliss.y - 200; game.addChild(singingText); tween(singingText, { alpha: 0, y: singingText.y - 100 }, { duration: 3000, easing: tween.easeOut, onFinish: function onFinish() { singingText.destroy(); } }); } function triggerCakeExplosion() { gameComplete = true; instructionText.setText('Happy Birthday Bubbles!'); // Create explosion effect var explosion = game.addChild(LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5 })); explosion.x = cake.x; explosion.y = cake.y; explosion.alpha = 0.7; tween(explosion, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { explosion.destroy(); } }); LK.getSound('explosion').play(); // Create confetti for (var i = 0; i < 50; i++) { var confetti = new Confetti(); confetti.x = Math.random() * 2048; confetti.y = -50; game.addChild(confetti); confettiPieces.push(confetti); } // Animate cake tween(cake, { scaleX: 1.3, scaleY: 1.3 }, { duration: 500, easing: tween.easeOut }); tween(cake, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeIn }); } game.update = function () { // Update instruction text based on game state if (!gameComplete) { if (areAllCandlesLit()) { if (candlesBlownCount === 0) { instructionText.setText('Tap Bubbles to blow out the candles!'); } else if (candlesBlownCount === 1) { instructionText.setText('Light the candles again!'); } } else if (candlesBlownCount === 1) { instructionText.setText('Tap candles to light them again!'); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bush = Container.expand(function () {
var self = Container.call(this);
var bushGraphics = self.attachAsset('bush', {
anchorX: 0.5,
anchorY: 1
});
self.hasBeenTapped = false;
self.down = function (x, y, obj) {
if (!self.hasBeenTapped) {
self.hasBeenTapped = true;
tween(bushGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut
});
tween(bushGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
LK.getSound('surprise').play();
// Create a small surprise effect
var surpriseText = new Text2('Surprise!', {
size: 40,
fill: '#FF69B4'
});
surpriseText.anchor.set(0.5, 0.5);
surpriseText.x = self.x;
surpriseText.y = self.y - 100;
game.addChild(surpriseText);
tween(surpriseText, {
alpha: 0,
y: surpriseText.y - 50
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
surpriseText.destroy();
}
});
}
};
return self;
});
var Candle = Container.expand(function () {
var self = Container.call(this);
var candleBody = self.attachAsset('candle', {
anchorX: 0.5,
anchorY: 1
});
var flame = self.attachAsset('flame', {
anchorX: 0.5,
anchorY: 1,
y: -60
});
self.isLit = false;
flame.visible = false;
self.light = function () {
if (!self.isLit) {
self.isLit = true;
flame.visible = true;
tween(flame, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(flame, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn
});
LK.getSound('lightCandle').play();
}
};
self.extinguish = function () {
if (self.isLit) {
self.isLit = false;
flame.visible = false;
}
};
self.down = function (x, y, obj) {
if (!self.isLit) {
self.light();
}
};
return self;
});
var Character = Container.expand(function (characterId) {
var self = Container.call(this);
var characterGraphics = self.attachAsset(characterId, {
anchorX: 0.5,
anchorY: 1
});
self.characterId = characterId;
self.down = function (x, y, obj) {
if (self.characterId === 'bubbles') {
blowOutCandles();
} else if (self.characterId === 'bliss') {
playHappyBirthday();
}
};
return self;
});
var Confetti = Container.expand(function () {
var self = Container.call(this);
var colors = [0xFF69B4, 0x00CED1, 0xFFD700, 0xFF6347, 0x98FB98];
var randomColor = colors[Math.floor(Math.random() * colors.length)];
var confettiGraphics = self.attachAsset('confetti', {
anchorX: 0.5,
anchorY: 0.5
});
confettiGraphics.tint = randomColor;
self.speed = Math.random() * 3 + 2;
self.rotation = Math.random() * 0.1 - 0.05;
self.update = function () {
self.y += self.speed;
self.rotation += self.rotation;
if (self.y > 2732 + 50) {
self.destroy();
for (var i = confettiPieces.length - 1; i >= 0; i--) {
if (confettiPieces[i] === self) {
confettiPieces.splice(i, 1);
break;
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state variables
var candles = [];
var confettiPieces = [];
var candlesBlownCount = 0;
var gameComplete = false;
// Create cake
var cake = game.addChild(LK.getAsset('cake', {
anchorX: 0.5,
anchorY: 0.5
}));
cake.x = 1024;
cake.y = 1400;
// Create candles around the cake
var candlePositions = [{
x: 1024 - 120,
y: 1320
}, {
x: 1024 - 60,
y: 1300
}, {
x: 1024,
y: 1290
}, {
x: 1024 + 60,
y: 1300
}, {
x: 1024 + 120,
y: 1320
}];
for (var i = 0; i < candlePositions.length; i++) {
var candle = game.addChild(new Candle());
candle.x = candlePositions[i].x;
candle.y = candlePositions[i].y;
candles.push(candle);
}
// Create characters
var bubbles = game.addChild(new Character('bubbles'));
bubbles.x = 1024;
bubbles.y = 1800;
var blossom = game.addChild(new Character('blossom'));
blossom.x = 400;
blossom.y = 1700;
var buttercup = game.addChild(new Character('buttercup'));
buttercup.x = 1648;
buttercup.y = 1700;
var bliss = game.addChild(new Character('bliss'));
bliss.x = 1024;
bliss.y = 800;
// Create music note above Bliss
var musicNote = game.addChild(LK.getAsset('musicNote', {
anchorX: 0.5,
anchorY: 0.5
}));
musicNote.x = bliss.x + 70;
musicNote.y = bliss.y - 150;
// Create bushes
var bushPositions = [{
x: 200,
y: 2000
}, {
x: 1848,
y: 2000
}, {
x: 100,
y: 1200
}, {
x: 1948,
y: 1200
}];
for (var i = 0; i < bushPositions.length; i++) {
var bush = game.addChild(new Bush());
bush.x = bushPositions[i].x;
bush.y = bushPositions[i].y;
}
// Create instruction text
var instructionText = new Text2('Tap candles to light them!', {
size: 50,
fill: '#FFFFFF'
});
instructionText.anchor.set(0.5, 0);
LK.gui.top.addChild(instructionText);
function areAllCandlesLit() {
for (var i = 0; i < candles.length; i++) {
if (!candles[i].isLit) {
return false;
}
}
return true;
}
function blowOutCandles() {
if (areAllCandlesLit() && !gameComplete) {
for (var i = 0; i < candles.length; i++) {
candles[i].extinguish();
}
candlesBlownCount++;
LK.getSound('blowCandle').play();
// Animate Bubbles blowing
tween(bubbles, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut
});
tween(bubbles, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
if (candlesBlownCount === 1) {
instructionText.setText('Great! Light them again and blow once more!');
} else if (candlesBlownCount === 2) {
triggerCakeExplosion();
}
}
}
function playHappyBirthday() {
LK.getSound('happyBirthday').play();
// Animate music note
tween(musicNote, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
easing: tween.easeOut
});
tween(musicNote, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn
});
// Show singing text
var singingText = new Text2('♪ Happy Birthday! ♪', {
size: 60,
fill: '#FF69B4'
});
singingText.anchor.set(0.5, 0.5);
singingText.x = bliss.x;
singingText.y = bliss.y - 200;
game.addChild(singingText);
tween(singingText, {
alpha: 0,
y: singingText.y - 100
}, {
duration: 3000,
easing: tween.easeOut,
onFinish: function onFinish() {
singingText.destroy();
}
});
}
function triggerCakeExplosion() {
gameComplete = true;
instructionText.setText('Happy Birthday Bubbles!');
// Create explosion effect
var explosion = game.addChild(LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
}));
explosion.x = cake.x;
explosion.y = cake.y;
explosion.alpha = 0.7;
tween(explosion, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
LK.getSound('explosion').play();
// Create confetti
for (var i = 0; i < 50; i++) {
var confetti = new Confetti();
confetti.x = Math.random() * 2048;
confetti.y = -50;
game.addChild(confetti);
confettiPieces.push(confetti);
}
// Animate cake
tween(cake, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 500,
easing: tween.easeOut
});
tween(cake, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeIn
});
}
game.update = function () {
// Update instruction text based on game state
if (!gameComplete) {
if (areAllCandlesLit()) {
if (candlesBlownCount === 0) {
instructionText.setText('Tap Bubbles to blow out the candles!');
} else if (candlesBlownCount === 1) {
instructionText.setText('Light the candles again!');
}
} else if (candlesBlownCount === 1) {
instructionText.setText('Tap candles to light them again!');
}
}
};