/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Apple class var Apple = Container.expand(function () { var self = Container.call(this); var appleAsset = self.attachAsset('apple', { anchorX: 0.5, anchorY: 1 }); self.isSalty = false; return self; }); // Bird class var Bird = Container.expand(function () { var self = Container.call(this); // Attach asset based on self.birdType var birdAsset = null; if (self.birdType === 1) { birdAsset = self.attachAsset('bird1', { anchorX: 0.5, anchorY: 1 }); } else if (self.birdType === 2) { birdAsset = self.attachAsset('bird2', { anchorX: 0.5, anchorY: 1 }); } else { birdAsset = self.attachAsset('bird3', { anchorX: 0.5, anchorY: 1 }); } // Speech bubble self.bubble = self.addChild(LK.getAsset('bubble', { anchorX: 0.5, anchorY: 1, y: -160, x: 0, scaleX: 1, scaleY: 1 })); self.bubble.visible = false; self.bubbleText = new Text2('', { size: 48, fill: '#222222' }); self.bubbleText.anchor.set(0.5, 1); self.bubbleText.x = 0; self.bubbleText.y = -30; self.bubble.addChild(self.bubbleText); // Show speech self.say = function (text, duration) { self.bubble.visible = true; self.bubbleText.setText(text); if (duration) { LK.setTimeout(function () { self.bubble.visible = false; }, duration); } }; // Hide speech self.hideSpeech = function () { self.bubble.visible = false; }; // Animate jump self.jump = function (cb) { tween(self, { y: self.y - 120 }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { tween(self, { y: self.y + 120 }, { duration: 220, easing: tween.cubicIn, onFinish: cb }); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf7e9b0 }); /**** * Game Code ****/ // Speech bubble // Desert ground // Apple asset // Bird assets: 3 birds, each a different color and shape // Game state var birds = []; var apple = null; var ground = null; var currentTurn = 0; // 0,1,2 for birds var phase = 0; // 0: intro, 1: arguing, 2: action, 3: reveal, 4: end var choices = [["I saw it first!", "I'm the hungriest!", "I can sing for it!"], ["Let's share!", "No way, it's mine!", "Rock-paper-scissors?"], ["Fine, you take it.", "I'm not giving up!", "Let's race for it!"]]; var selectedChoices = [null, null, null]; var winner = null; var saltyRevealDone = false; // Add desert ground ground = LK.getAsset('ground', { anchorX: 0, anchorY: 1, x: 0, y: 2732 }); game.addChild(ground); // Add birds var birdPositions = [600, 1024, 1448]; for (var i = 0; i < 3; i++) { var b = new Bird(); b.birdType = i + 1; b.x = birdPositions[i]; b.y = 2732 - 300; birds.push(b); game.addChild(b); } // Add apple in the center, slightly above ground apple = new Apple(); apple.x = 1024; apple.y = 2732 - 300 - 40; game.addChild(apple); // Title text var titleText = new Text2("The Last Apple", { size: 120, fill: '#c0392b' }); titleText.anchor.set(0.5, 0); titleText.x = 1024; titleText.y = 80; LK.gui.top.addChild(titleText); // Instruction text var instrText = new Text2("Help the birds decide who gets the apple!", { size: 64, fill: '#333333' }); instrText.anchor.set(0.5, 0); instrText.x = 1024; instrText.y = 220; LK.gui.top.addChild(instrText); // Choice buttons var choiceButtons = []; function showChoices(birdIdx) { // Remove old buttons for (var i = 0; i < choiceButtons.length; i++) { if (choiceButtons[i].parent) { LK.gui.bottom.removeChild(choiceButtons[i]); } } choiceButtons = []; // Show 3 choices for this bird for (var j = 0; j < 3; j++) { var btn = new Text2(choices[birdIdx][j], { size: 60, fill: '#222222' }); btn.anchor.set(0.5, 0.5); btn.x = 512 + j * 512; btn.y = 100; btn.bg = LK.getAsset('bubble', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, scaleX: 1.2, scaleY: 0.7 }); btn.addChild(btn.bg); btn.bg.zIndex = -1; btn.zIndex = 1; // Touch/click handler (function (idx, choiceIdx) { btn.down = function (x, y, obj) { selectChoice(idx, choiceIdx); }; })(birdIdx, j); LK.gui.bottom.addChild(btn); choiceButtons.push(btn); } } // Select a choice for a bird function selectChoice(birdIdx, choiceIdx) { selectedChoices[birdIdx] = choiceIdx; birds[birdIdx].say(choices[birdIdx][choiceIdx], 1200); // Animate bird birds[birdIdx].jump(function () { // Next turn or next phase if (birdIdx < 2) { currentTurn++; showChoices(currentTurn); } else { // All birds have chosen, move to action phase phase = 2; LK.setTimeout(startActionPhase, 900); } }); // Remove buttons for (var i = 0; i < choiceButtons.length; i++) { if (choiceButtons[i].parent) { LK.gui.bottom.removeChild(choiceButtons[i]); } } choiceButtons = []; } // Start the action phase: birds act out their choices function startActionPhase() { // Each bird acts in turn var actIdx = 0; function nextAct() { if (actIdx >= 3) { // All acted, pick winner phase = 3; LK.setTimeout(revealSaltyApple, 900); return; } var b = birds[actIdx]; var c = selectedChoices[actIdx]; // Animate based on choice if (c === 0) { // First option: move toward apple tween(b, { x: apple.x }, { duration: 400, easing: tween.cubicInOut, onFinish: function onFinish() { b.say("Mine!", 900); LK.setTimeout(function () { actIdx++; nextAct(); }, 900); } }); } else if (c === 1) { // Second option: jump b.say("No way!", 900); b.jump(function () { LK.setTimeout(function () { actIdx++; nextAct(); }, 900); }); } else { // Third option: shake b.say("Let's go!", 900); tween(b, { rotation: 0.2 }, { duration: 120, onFinish: function onFinish() { tween(b, { rotation: -0.2 }, { duration: 120, onFinish: function onFinish() { tween(b, { rotation: 0 }, { duration: 80, onFinish: function onFinish() { LK.setTimeout(function () { actIdx++; nextAct(); }, 900); } }); } }); } }); } } nextAct(); } // Reveal the apple is salty! function revealSaltyApple() { if (saltyRevealDone) return; saltyRevealDone = true; // Pick a winner: random among birds who chose option 0 (move toward apple), else random var candidates = []; for (var i = 0; i < 3; i++) { if (selectedChoices[i] === 0) candidates.push(i); } if (candidates.length === 0) { candidates = [0, 1, 2]; } winner = candidates[Math.floor(Math.random() * candidates.length)]; // Animate winner to apple var b = birds[winner]; tween(b, { x: apple.x }, { duration: 500, easing: tween.cubicInOut, onFinish: function onFinish() { b.say("I got it!", 1000); // Animate apple "bite" LK.setTimeout(function () { apple.isSalty = true; // Show salty face b.say("Yuck! It's salty!", 1800); // Animate apple color to blue tween(apple.children[0], { tint: 0x5dade2 }, { duration: 600 }); // Show other birds laughing for (var i = 0; i < 3; i++) { if (i !== winner) { birds[i].say("Haha!", 1200); } } // End LK.setTimeout(showEnd, 2000); }, 1000); } }); } // Show end screen function showEnd() { phase = 4; // Remove all speech for (var i = 0; i < 3; i++) birds[i].hideSpeech(); // Show final message var endText = new Text2("The real prize was laughter!\nPlay again for a new story.", { size: 80, fill: '#2d3436' }); endText.anchor.set(0.5, 0.5); endText.x = 1024; endText.y = 900; LK.gui.center.addChild(endText); // Show "You Win" after a moment LK.setTimeout(function () { LK.showYouWin(); }, 2200); } // Start game: intro phase function startGame() { phase = 1; currentTurn = 0; selectedChoices = [null, null, null]; winner = null; saltyRevealDone = false; // Remove any end text if (LK.gui.center.children.length > 0) { for (var i = LK.gui.center.children.length - 1; i >= 0; i--) { LK.gui.center.removeChild(LK.gui.center.children[i]); } } // Reset birds and apple for (var i = 0; i < 3; i++) { birds[i].x = birdPositions[i]; birds[i].y = 2732 - 300; birds[i].rotation = 0; birds[i].hideSpeech(); } apple.x = 1024; apple.y = 2732 - 300 - 40; apple.children[0].tint = 0xc0392b; // Show first choices showChoices(0); } // Restart on game reset game.on('reset', function () { startGame(); }); // Start game on load startGame(); // No update loop needed, all is event-driven.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Apple class
var Apple = Container.expand(function () {
var self = Container.call(this);
var appleAsset = self.attachAsset('apple', {
anchorX: 0.5,
anchorY: 1
});
self.isSalty = false;
return self;
});
// Bird class
var Bird = Container.expand(function () {
var self = Container.call(this);
// Attach asset based on self.birdType
var birdAsset = null;
if (self.birdType === 1) {
birdAsset = self.attachAsset('bird1', {
anchorX: 0.5,
anchorY: 1
});
} else if (self.birdType === 2) {
birdAsset = self.attachAsset('bird2', {
anchorX: 0.5,
anchorY: 1
});
} else {
birdAsset = self.attachAsset('bird3', {
anchorX: 0.5,
anchorY: 1
});
}
// Speech bubble
self.bubble = self.addChild(LK.getAsset('bubble', {
anchorX: 0.5,
anchorY: 1,
y: -160,
x: 0,
scaleX: 1,
scaleY: 1
}));
self.bubble.visible = false;
self.bubbleText = new Text2('', {
size: 48,
fill: '#222222'
});
self.bubbleText.anchor.set(0.5, 1);
self.bubbleText.x = 0;
self.bubbleText.y = -30;
self.bubble.addChild(self.bubbleText);
// Show speech
self.say = function (text, duration) {
self.bubble.visible = true;
self.bubbleText.setText(text);
if (duration) {
LK.setTimeout(function () {
self.bubble.visible = false;
}, duration);
}
};
// Hide speech
self.hideSpeech = function () {
self.bubble.visible = false;
};
// Animate jump
self.jump = function (cb) {
tween(self, {
y: self.y - 120
}, {
duration: 180,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(self, {
y: self.y + 120
}, {
duration: 220,
easing: tween.cubicIn,
onFinish: cb
});
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf7e9b0
});
/****
* Game Code
****/
// Speech bubble
// Desert ground
// Apple asset
// Bird assets: 3 birds, each a different color and shape
// Game state
var birds = [];
var apple = null;
var ground = null;
var currentTurn = 0; // 0,1,2 for birds
var phase = 0; // 0: intro, 1: arguing, 2: action, 3: reveal, 4: end
var choices = [["I saw it first!", "I'm the hungriest!", "I can sing for it!"], ["Let's share!", "No way, it's mine!", "Rock-paper-scissors?"], ["Fine, you take it.", "I'm not giving up!", "Let's race for it!"]];
var selectedChoices = [null, null, null];
var winner = null;
var saltyRevealDone = false;
// Add desert ground
ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 1,
x: 0,
y: 2732
});
game.addChild(ground);
// Add birds
var birdPositions = [600, 1024, 1448];
for (var i = 0; i < 3; i++) {
var b = new Bird();
b.birdType = i + 1;
b.x = birdPositions[i];
b.y = 2732 - 300;
birds.push(b);
game.addChild(b);
}
// Add apple in the center, slightly above ground
apple = new Apple();
apple.x = 1024;
apple.y = 2732 - 300 - 40;
game.addChild(apple);
// Title text
var titleText = new Text2("The Last Apple", {
size: 120,
fill: '#c0392b'
});
titleText.anchor.set(0.5, 0);
titleText.x = 1024;
titleText.y = 80;
LK.gui.top.addChild(titleText);
// Instruction text
var instrText = new Text2("Help the birds decide who gets the apple!", {
size: 64,
fill: '#333333'
});
instrText.anchor.set(0.5, 0);
instrText.x = 1024;
instrText.y = 220;
LK.gui.top.addChild(instrText);
// Choice buttons
var choiceButtons = [];
function showChoices(birdIdx) {
// Remove old buttons
for (var i = 0; i < choiceButtons.length; i++) {
if (choiceButtons[i].parent) {
LK.gui.bottom.removeChild(choiceButtons[i]);
}
}
choiceButtons = [];
// Show 3 choices for this bird
for (var j = 0; j < 3; j++) {
var btn = new Text2(choices[birdIdx][j], {
size: 60,
fill: '#222222'
});
btn.anchor.set(0.5, 0.5);
btn.x = 512 + j * 512;
btn.y = 100;
btn.bg = LK.getAsset('bubble', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0,
scaleX: 1.2,
scaleY: 0.7
});
btn.addChild(btn.bg);
btn.bg.zIndex = -1;
btn.zIndex = 1;
// Touch/click handler
(function (idx, choiceIdx) {
btn.down = function (x, y, obj) {
selectChoice(idx, choiceIdx);
};
})(birdIdx, j);
LK.gui.bottom.addChild(btn);
choiceButtons.push(btn);
}
}
// Select a choice for a bird
function selectChoice(birdIdx, choiceIdx) {
selectedChoices[birdIdx] = choiceIdx;
birds[birdIdx].say(choices[birdIdx][choiceIdx], 1200);
// Animate bird
birds[birdIdx].jump(function () {
// Next turn or next phase
if (birdIdx < 2) {
currentTurn++;
showChoices(currentTurn);
} else {
// All birds have chosen, move to action phase
phase = 2;
LK.setTimeout(startActionPhase, 900);
}
});
// Remove buttons
for (var i = 0; i < choiceButtons.length; i++) {
if (choiceButtons[i].parent) {
LK.gui.bottom.removeChild(choiceButtons[i]);
}
}
choiceButtons = [];
}
// Start the action phase: birds act out their choices
function startActionPhase() {
// Each bird acts in turn
var actIdx = 0;
function nextAct() {
if (actIdx >= 3) {
// All acted, pick winner
phase = 3;
LK.setTimeout(revealSaltyApple, 900);
return;
}
var b = birds[actIdx];
var c = selectedChoices[actIdx];
// Animate based on choice
if (c === 0) {
// First option: move toward apple
tween(b, {
x: apple.x
}, {
duration: 400,
easing: tween.cubicInOut,
onFinish: function onFinish() {
b.say("Mine!", 900);
LK.setTimeout(function () {
actIdx++;
nextAct();
}, 900);
}
});
} else if (c === 1) {
// Second option: jump
b.say("No way!", 900);
b.jump(function () {
LK.setTimeout(function () {
actIdx++;
nextAct();
}, 900);
});
} else {
// Third option: shake
b.say("Let's go!", 900);
tween(b, {
rotation: 0.2
}, {
duration: 120,
onFinish: function onFinish() {
tween(b, {
rotation: -0.2
}, {
duration: 120,
onFinish: function onFinish() {
tween(b, {
rotation: 0
}, {
duration: 80,
onFinish: function onFinish() {
LK.setTimeout(function () {
actIdx++;
nextAct();
}, 900);
}
});
}
});
}
});
}
}
nextAct();
}
// Reveal the apple is salty!
function revealSaltyApple() {
if (saltyRevealDone) return;
saltyRevealDone = true;
// Pick a winner: random among birds who chose option 0 (move toward apple), else random
var candidates = [];
for (var i = 0; i < 3; i++) {
if (selectedChoices[i] === 0) candidates.push(i);
}
if (candidates.length === 0) {
candidates = [0, 1, 2];
}
winner = candidates[Math.floor(Math.random() * candidates.length)];
// Animate winner to apple
var b = birds[winner];
tween(b, {
x: apple.x
}, {
duration: 500,
easing: tween.cubicInOut,
onFinish: function onFinish() {
b.say("I got it!", 1000);
// Animate apple "bite"
LK.setTimeout(function () {
apple.isSalty = true;
// Show salty face
b.say("Yuck! It's salty!", 1800);
// Animate apple color to blue
tween(apple.children[0], {
tint: 0x5dade2
}, {
duration: 600
});
// Show other birds laughing
for (var i = 0; i < 3; i++) {
if (i !== winner) {
birds[i].say("Haha!", 1200);
}
}
// End
LK.setTimeout(showEnd, 2000);
}, 1000);
}
});
}
// Show end screen
function showEnd() {
phase = 4;
// Remove all speech
for (var i = 0; i < 3; i++) birds[i].hideSpeech();
// Show final message
var endText = new Text2("The real prize was laughter!\nPlay again for a new story.", {
size: 80,
fill: '#2d3436'
});
endText.anchor.set(0.5, 0.5);
endText.x = 1024;
endText.y = 900;
LK.gui.center.addChild(endText);
// Show "You Win" after a moment
LK.setTimeout(function () {
LK.showYouWin();
}, 2200);
}
// Start game: intro phase
function startGame() {
phase = 1;
currentTurn = 0;
selectedChoices = [null, null, null];
winner = null;
saltyRevealDone = false;
// Remove any end text
if (LK.gui.center.children.length > 0) {
for (var i = LK.gui.center.children.length - 1; i >= 0; i--) {
LK.gui.center.removeChild(LK.gui.center.children[i]);
}
}
// Reset birds and apple
for (var i = 0; i < 3; i++) {
birds[i].x = birdPositions[i];
birds[i].y = 2732 - 300;
birds[i].rotation = 0;
birds[i].hideSpeech();
}
apple.x = 1024;
apple.y = 2732 - 300 - 40;
apple.children[0].tint = 0xc0392b;
// Show first choices
showChoices(0);
}
// Restart on game reset
game.on('reset', function () {
startGame();
});
// Start game on load
startGame();
// No update loop needed, all is event-driven.