/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Gumball = Container.expand(function () { var self = Container.call(this); var character = self.attachAsset('gumball', { anchorX: 0.5, anchorY: 0.5 }); self.isRescued = false; self.lastRescued = false; self.startFloating = function () { tween(self, { y: self.y - 10 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { y: self.y + 10 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (!self.isRescued) { self.startFloating(); } } }); } }); }; return self; }); var Phone = Container.expand(function () { var self = Container.call(this); var phoneBody = self.attachAsset('phone', { anchorX: 0.5, anchorY: 0.5 }); var callBtn = self.attachAsset('callButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -50 }); var uncallBtn = self.attachAsset('uncallButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 50 }); self.isActive = false; self.lastActive = false; self.activate = function () { if (!self.isActive) { self.isActive = true; tween(phoneBody, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); tween(callBtn, { tint: 0x2ecc71 }, { duration: 200 }); LK.getSound('phoneRing').play(); } }; self.deactivate = function () { if (self.isActive) { self.isActive = false; tween(phoneBody, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut }); tween(callBtn, { tint: 0xffffff }, { duration: 200 }); } }; self.down = function (x, y, obj) { var localPos = self.toLocal(obj.parent.toGlobal(obj.position)); // Check if call button was pressed if (Math.abs(localPos.x - 0) < 60 && Math.abs(localPos.y - -50) < 60) { self.activate(); } // Check if uncall button was pressed if (Math.abs(localPos.x - 0) < 60 && Math.abs(localPos.y - 50) < 60) { self.deactivate(); } }; return self; }); var PowerpuffGirl = Container.expand(function (color, name) { var self = Container.call(this); var hero = self.attachAsset(name, { anchorX: 0.5, anchorY: 0.5 }); self.isActive = false; self.targetX = 0; self.targetY = 0; self.speed = 3; self.rescueComplete = false; self.setTarget = function (targetX, targetY) { self.targetX = targetX; self.targetY = targetY; self.isActive = true; }; self.update = function () { if (self.isActive && !self.rescueComplete) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } else { self.isActive = false; } } }; self.down = function (x, y, obj) { if (phone.isActive && !gameWon) { self.setTarget(gumball.x, gumball.y - 100); LK.getSound('heroSound').play(); tween(hero, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, easing: tween.bounceOut, onFinish: function onFinish() { tween(hero, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); } }); } }; return self; }); var Tree = Container.expand(function () { var self = Container.call(this); var trunk = self.attachAsset('tree', { anchorX: 0.5, anchorY: 1.0 }); var leaves = self.attachAsset('treeTop', { anchorX: 0.5, anchorY: 1.0, y: -400 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb }); /**** * Game Code ****/ var gameWon = false; var lastGameWon = false; // Create game objects var tree = game.addChild(new Tree()); tree.x = 2048 / 2; tree.y = 2200; var gumball = game.addChild(new Gumball()); gumball.x = tree.x + 50; gumball.y = tree.y - 350; gumball.startFloating(); var phone = game.addChild(new Phone()); phone.x = 300; phone.y = 400; var blossom = game.addChild(new PowerpuffGirl(0xff69b4, 'blossom')); blossom.x = -100; blossom.y = 500; var bubbles = game.addChild(new PowerpuffGirl(0x87ceeb, 'bubbles')); bubbles.x = -100; bubbles.y = 700; var buttercup = game.addChild(new PowerpuffGirl(0x90ee90, 'buttercup')); buttercup.x = -100; buttercup.y = 900; var heroes = [blossom, bubbles, buttercup]; var heroesNearGumball = 0; var rescueTimer = 0; // Score display var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Instructions var instructionTxt = new Text2('Tap green button to call heroes!', { size: 60, fill: 0xFFFFFF }); instructionTxt.anchor.set(0.5, 0); instructionTxt.y = 100; LK.gui.top.addChild(instructionTxt); game.update = function () { // Update score display scoreTxt.setText('Score: ' + LK.getScore()); // Phone state transitions if (!phone.lastActive && phone.isActive) { // Phone just activated - move heroes on screen for (var i = 0; i < heroes.length; i++) { tween(heroes[i], { x: 200 + i * 150 }, { duration: 1000, easing: tween.easeOut }); } instructionTxt.setText('Tap the heroes to direct rescue!'); } if (phone.lastActive && !phone.isActive) { // Phone just deactivated - move heroes off screen for (var i = 0; i < heroes.length; i++) { tween(heroes[i], { x: -100 }, { duration: 800, easing: tween.easeIn }); heroes[i].isActive = false; } instructionTxt.setText('Tap green button to call heroes!'); } phone.lastActive = phone.isActive; // Check rescue progress heroesNearGumball = 0; for (var i = 0; i < heroes.length; i++) { var hero = heroes[i]; var distance = Math.sqrt(Math.pow(hero.x - gumball.x, 2) + Math.pow(hero.y - gumball.y, 2)); if (distance < 120) { heroesNearGumball++; } } // Rescue logic if (heroesNearGumball >= 2 && phone.isActive && !gameWon) { rescueTimer++; if (rescueTimer > 60) { // 1 second at 60fps gameWon = true; } } else { rescueTimer = 0; } // Game won transition if (!lastGameWon && gameWon) { LK.getSound('rescue').play(); LK.setScore(LK.getScore() + 100); // Animate Gumball being rescued tween(gumball, { y: gumball.y + 200, scaleX: 1.5, scaleY: 1.5 }, { duration: 1000, easing: tween.bounceOut }); // Celebrate heroes for (var i = 0; i < heroes.length; i++) { tween(heroes[i], { rotation: Math.PI * 2 }, { duration: 1000 }); } LK.effects.flashScreen(0x90ee90, 1000); LK.setTimeout(function () { LK.showYouWin(); }, 2000); } lastGameWon = gameWon; };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Gumball = Container.expand(function () {
var self = Container.call(this);
var character = self.attachAsset('gumball', {
anchorX: 0.5,
anchorY: 0.5
});
self.isRescued = false;
self.lastRescued = false;
self.startFloating = function () {
tween(self, {
y: self.y - 10
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
y: self.y + 10
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!self.isRescued) {
self.startFloating();
}
}
});
}
});
};
return self;
});
var Phone = Container.expand(function () {
var self = Container.call(this);
var phoneBody = self.attachAsset('phone', {
anchorX: 0.5,
anchorY: 0.5
});
var callBtn = self.attachAsset('callButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -50
});
var uncallBtn = self.attachAsset('uncallButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 50
});
self.isActive = false;
self.lastActive = false;
self.activate = function () {
if (!self.isActive) {
self.isActive = true;
tween(phoneBody, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut
});
tween(callBtn, {
tint: 0x2ecc71
}, {
duration: 200
});
LK.getSound('phoneRing').play();
}
};
self.deactivate = function () {
if (self.isActive) {
self.isActive = false;
tween(phoneBody, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
tween(callBtn, {
tint: 0xffffff
}, {
duration: 200
});
}
};
self.down = function (x, y, obj) {
var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
// Check if call button was pressed
if (Math.abs(localPos.x - 0) < 60 && Math.abs(localPos.y - -50) < 60) {
self.activate();
}
// Check if uncall button was pressed
if (Math.abs(localPos.x - 0) < 60 && Math.abs(localPos.y - 50) < 60) {
self.deactivate();
}
};
return self;
});
var PowerpuffGirl = Container.expand(function (color, name) {
var self = Container.call(this);
var hero = self.attachAsset(name, {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = false;
self.targetX = 0;
self.targetY = 0;
self.speed = 3;
self.rescueComplete = false;
self.setTarget = function (targetX, targetY) {
self.targetX = targetX;
self.targetY = targetY;
self.isActive = true;
};
self.update = function () {
if (self.isActive && !self.rescueComplete) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
self.isActive = false;
}
}
};
self.down = function (x, y, obj) {
if (phone.isActive && !gameWon) {
self.setTarget(gumball.x, gumball.y - 100);
LK.getSound('heroSound').play();
tween(hero, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(hero, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
}
});
}
};
return self;
});
var Tree = Container.expand(function () {
var self = Container.call(this);
var trunk = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 1.0
});
var leaves = self.attachAsset('treeTop', {
anchorX: 0.5,
anchorY: 1.0,
y: -400
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var gameWon = false;
var lastGameWon = false;
// Create game objects
var tree = game.addChild(new Tree());
tree.x = 2048 / 2;
tree.y = 2200;
var gumball = game.addChild(new Gumball());
gumball.x = tree.x + 50;
gumball.y = tree.y - 350;
gumball.startFloating();
var phone = game.addChild(new Phone());
phone.x = 300;
phone.y = 400;
var blossom = game.addChild(new PowerpuffGirl(0xff69b4, 'blossom'));
blossom.x = -100;
blossom.y = 500;
var bubbles = game.addChild(new PowerpuffGirl(0x87ceeb, 'bubbles'));
bubbles.x = -100;
bubbles.y = 700;
var buttercup = game.addChild(new PowerpuffGirl(0x90ee90, 'buttercup'));
buttercup.x = -100;
buttercup.y = 900;
var heroes = [blossom, bubbles, buttercup];
var heroesNearGumball = 0;
var rescueTimer = 0;
// Score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Instructions
var instructionTxt = new Text2('Tap green button to call heroes!', {
size: 60,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0);
instructionTxt.y = 100;
LK.gui.top.addChild(instructionTxt);
game.update = function () {
// Update score display
scoreTxt.setText('Score: ' + LK.getScore());
// Phone state transitions
if (!phone.lastActive && phone.isActive) {
// Phone just activated - move heroes on screen
for (var i = 0; i < heroes.length; i++) {
tween(heroes[i], {
x: 200 + i * 150
}, {
duration: 1000,
easing: tween.easeOut
});
}
instructionTxt.setText('Tap the heroes to direct rescue!');
}
if (phone.lastActive && !phone.isActive) {
// Phone just deactivated - move heroes off screen
for (var i = 0; i < heroes.length; i++) {
tween(heroes[i], {
x: -100
}, {
duration: 800,
easing: tween.easeIn
});
heroes[i].isActive = false;
}
instructionTxt.setText('Tap green button to call heroes!');
}
phone.lastActive = phone.isActive;
// Check rescue progress
heroesNearGumball = 0;
for (var i = 0; i < heroes.length; i++) {
var hero = heroes[i];
var distance = Math.sqrt(Math.pow(hero.x - gumball.x, 2) + Math.pow(hero.y - gumball.y, 2));
if (distance < 120) {
heroesNearGumball++;
}
}
// Rescue logic
if (heroesNearGumball >= 2 && phone.isActive && !gameWon) {
rescueTimer++;
if (rescueTimer > 60) {
// 1 second at 60fps
gameWon = true;
}
} else {
rescueTimer = 0;
}
// Game won transition
if (!lastGameWon && gameWon) {
LK.getSound('rescue').play();
LK.setScore(LK.getScore() + 100);
// Animate Gumball being rescued
tween(gumball, {
y: gumball.y + 200,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 1000,
easing: tween.bounceOut
});
// Celebrate heroes
for (var i = 0; i < heroes.length; i++) {
tween(heroes[i], {
rotation: Math.PI * 2
}, {
duration: 1000
});
}
LK.effects.flashScreen(0x90ee90, 1000);
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
}
lastGameWon = gameWon;
};