Code edit (1 edits merged)
Please save this source code
User prompt
Richard the Falcon & Friends: Rescue Flight (1-9 Joystick)
Initial prompt
Richard The Falcon Save The Geoffrey The Eagle Quinn The Chough Nina The Robin Astrid The Stork Martin The Duck Ronald The Macaw Graham The Seagull Jones The Hummingbird And Swen The Swan The Game With 1-9 And Joysitck
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // BirdFriend class var BirdFriend = Container.expand(function () { var self = Container.call(this); // Attach asset (ellipse, color varies by number) var colors = [0xcccccc, // 0 (unused) 0xffe066, // 1 - Geoffrey the Eagle (yellow) 0x8ecae6, // 2 - Quinn the Chough (blue) 0xff595e, // 3 - Nina the Robin (red) 0x90be6d, // 4 - Astrid the Stork (green) 0x6d597a, // 5 - Martin the Duck (purple) 0xffca3a, // 6 - Ronald the Macaw (orange) 0x43aa8b, // 7 - Graham the Seagull (teal) 0x577590, // 8 - Jones the Hummingbird (navy) 0xffffff // 9 - Swen the Swan (white) ]; self.number = 1; // Will be set after creation var birdSprite = self.attachAsset('birdfriend', { anchorX: 0.5, anchorY: 0.5, color: colors[self.number], width: 120, height: 120, shape: 'ellipse' }); // Add number label var numberText = new Text2('1', { size: 70, fill: 0x222222 }); numberText.anchor.set(0.5, 0.5); self.addChild(numberText); // Set number and color self.setNumber = function (n) { self.number = n; birdSprite.color = colors[n]; numberText.setText('' + n); }; // Animate collection self.collect = function (_onFinish) { tween(self, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 400, easing: tween.easeIn, onFinish: function onFinish() { if (_onFinish) _onFinish(); } }); }; return self; }); // Falcon (Player) class var Falcon = Container.expand(function () { var self = Container.call(this); // Attach falcon asset (red box, will be replaced with image later) var falconSprite = self.attachAsset('falcon', { anchorX: 0.5, anchorY: 0.5 }); // Movement speed self.speed = 18; // Current velocity self.vx = 0; self.vy = 0; // Update method called every tick self.update = function () { self.x += self.vx; self.y += self.vy; // Clamp to game area if (self.x < 100 + falconSprite.width / 2) self.x = 100 + falconSprite.width / 2; if (self.x > 2048 - falconSprite.width / 2) self.x = 2048 - falconSprite.width / 2; if (self.y < falconSprite.height / 2) self.y = falconSprite.height / 2; if (self.y > 2732 - falconSprite.height / 2) self.y = 2732 - falconSprite.height / 2; }; return self; }); // Joystick class (on-screen) var Joystick = Container.expand(function () { var self = Container.call(this); // Outer circle var base = self.attachAsset('joystickBase', { anchorX: 0.5, anchorY: 0.5, color: 0xaaaaaa, width: 260, height: 260, shape: 'ellipse' }); // Inner knob var knob = self.attachAsset('joystickKnob', { anchorX: 0.5, anchorY: 0.5, color: 0x333333, width: 120, height: 120, shape: 'ellipse' }); knob.x = 0; knob.y = 0; self.addChild(knob); // Joystick state self.active = false; self.startX = 0; self.startY = 0; self.deltaX = 0; self.deltaY = 0; // Get normalized direction (-1 to 1) self.getDirection = function () { var dx = self.deltaX / 100; var dy = self.deltaY / 100; // Clamp if (dx < -1) dx = -1; if (dx > 1) dx = 1; if (dy < -1) dy = -1; if (dy > 1) dy = 1; return { x: dx, y: dy }; }; // Reset knob self.reset = function () { self.deltaX = 0; self.deltaY = 0; knob.x = 0; knob.y = 0; }; // Touch/mouse events self.down = function (x, y, obj) { self.active = true; self.startX = x; self.startY = y; self.deltaX = 0; self.deltaY = 0; }; self.move = function (x, y, obj) { if (!self.active) return; self.deltaX = x - self.startX; self.deltaY = y - self.startY; // Clamp to radius 100 var dist = Math.sqrt(self.deltaX * self.deltaX + self.deltaY * self.deltaY); if (dist > 100) { var scale = 100 / dist; self.deltaX *= scale; self.deltaY *= scale; } knob.x = self.deltaX; knob.y = self.deltaY; }; self.up = function (x, y, obj) { self.active = false; self.reset(); }; return self; }); // Obstacle class var Obstacle = Container.expand(function () { var self = Container.call(this); // Attach asset (gray box) var obsSprite = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5, color: 0x444444, width: 180, height: 60, shape: 'box' }); // Movement speed self.speed = 10 + Math.random() * 8; // Direction: 1 = right, -1 = left self.dir = Math.random() < 0.5 ? 1 : -1; // Update method self.update = function () { self.x += self.speed * self.dir; // Bounce off edges if (self.x < 100 + obsSprite.width / 2) { self.x = 100 + obsSprite.width / 2; self.dir = 1; } if (self.x > 2048 - obsSprite.width / 2) { self.x = 2048 - obsSprite.width / 2; self.dir = -1; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x7ec8e3 // Light blue sky }); /**** * Game Code ****/ // --- Game variables --- var falcon; var joystick; var birdFriends = []; var obstacles = []; var nextBird = 1; var scoreTxt; var timerTxt; var timeElapsed = 0; var timerInterval; var gameActive = true; var lastFalconX = 0, lastFalconY = 0; var lastIntersectingBird = false; var lastIntersectingObstacle = false; // --- Setup --- // Set background color game.setBackgroundColor(0x7ec8e3); // Add Falcon (player) falcon = new Falcon(); falcon.x = 2048 / 2; falcon.y = 2732 - 400; game.addChild(falcon); // Add BirdFriends (1-9) at random positions, not overlapping function randomBirdPos() { var margin = 200; var x = margin + Math.random() * (2048 - 2 * margin); var y = margin + Math.random() * (2732 - 2 * margin - 600); return { x: x, y: y }; } for (var i = 1; i <= 9; i++) { var bird = new BirdFriend(); bird.setNumber(i); var pos; var tries = 0; do { pos = randomBirdPos(); var overlap = false; for (var j = 0; j < birdFriends.length; j++) { var dx = pos.x - birdFriends[j].x; var dy = pos.y - birdFriends[j].y; if (Math.sqrt(dx * dx + dy * dy) < 220) { overlap = true; break; } } tries++; } while (overlap && tries < 20); bird.x = pos.x; bird.y = pos.y + 200; // leave top margin for timer bird.scaleX = 1; bird.scaleY = 1; bird.alpha = 1; birdFriends.push(bird); game.addChild(bird); } // Add obstacles (4 obstacles) for (var o = 0; o < 4; o++) { var obs = new Obstacle(); obs.x = 300 + Math.random() * (2048 - 600); obs.y = 600 + Math.random() * (2732 - 1200); obstacles.push(obs); game.addChild(obs); } // Add joystick (bottom left, outside 100x100 menu area) joystick = new Joystick(); joystick.x = 220; joystick.y = 2732 - 220; game.addChild(joystick); // Add score text (top center) scoreTxt = new Text2('Next: 1', { size: 120, fill: 0x222222 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Add timer text (top right) timerTxt = new Text2('0.0s', { size: 90, fill: 0x222222 }); timerTxt.anchor.set(1, 0); LK.gui.topRight.addChild(timerTxt); // --- Timer --- function updateTimer() { if (!gameActive) return; timeElapsed += 0.1; timerTxt.setText(timeElapsed.toFixed(1) + 's'); } timerInterval = LK.setInterval(updateTimer, 100); // --- Joystick events --- joystick.down = function (x, y, obj) { joystick.active = true; joystick.startX = x; joystick.startY = y; joystick.deltaX = 0; joystick.deltaY = 0; }; joystick.move = function (x, y, obj) { if (!joystick.active) return; joystick.deltaX = x - joystick.startX; joystick.deltaY = y - joystick.startY; var dist = Math.sqrt(joystick.deltaX * joystick.deltaX + joystick.deltaY * joystick.deltaY); if (dist > 100) { var scale = 100 / dist; joystick.deltaX *= scale; joystick.deltaY *= scale; } joystick.children[1].x = joystick.deltaX; joystick.children[1].y = joystick.deltaY; }; joystick.up = function (x, y, obj) { joystick.active = false; joystick.reset(); }; // --- Game move/up/down events (for joystick) --- game.down = function (x, y, obj) { // If touch is inside joystick area, activate joystick var dx = x - joystick.x; var dy = y - joystick.y; if (dx * dx + dy * dy < 130 * 130) { joystick.down(x, y, obj); } }; game.move = function (x, y, obj) { if (joystick.active) { joystick.move(x, y, obj); } }; game.up = function (x, y, obj) { if (joystick.active) { joystick.up(x, y, obj); } }; // --- Main game update --- game.update = function () { if (!gameActive) return; // Joystick controls Falcon var dir = joystick.getDirection(); falcon.vx = dir.x * falcon.speed; falcon.vy = dir.y * falcon.speed; // Update Falcon falcon.update(); // Update obstacles for (var i = 0; i < obstacles.length; i++) { obstacles[i].update(); } // Check collision with next bird var nextBirdObj = null; for (var i = 0; i < birdFriends.length; i++) { if (birdFriends[i].number === nextBird) { nextBirdObj = birdFriends[i]; break; } } if (nextBirdObj) { var intersecting = falcon.intersects(nextBirdObj); if (!lastIntersectingBird && intersecting) { // Collect bird nextBirdObj.collect(function () { nextBirdObj.destroy(); }); nextBird++; if (nextBird > 9) { // Win! gameActive = false; LK.clearInterval(timerInterval); LK.setScore(Math.max(0, Math.round(10000 - timeElapsed * 100))); LK.showYouWin(); return; } scoreTxt.setText('Next: ' + nextBird); } lastIntersectingBird = intersecting; } // Check collision with obstacles var hitObstacle = false; for (var i = 0; i < obstacles.length; i++) { if (falcon.intersects(obstacles[i])) { hitObstacle = true; break; } } if (!lastIntersectingObstacle && hitObstacle) { // Game over gameActive = false; LK.clearInterval(timerInterval); LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } lastIntersectingObstacle = hitObstacle; }; // --- Clean up on game end --- function cleanup() { LK.clearInterval(timerInterval); }
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// BirdFriend class
var BirdFriend = Container.expand(function () {
var self = Container.call(this);
// Attach asset (ellipse, color varies by number)
var colors = [0xcccccc,
// 0 (unused)
0xffe066,
// 1 - Geoffrey the Eagle (yellow)
0x8ecae6,
// 2 - Quinn the Chough (blue)
0xff595e,
// 3 - Nina the Robin (red)
0x90be6d,
// 4 - Astrid the Stork (green)
0x6d597a,
// 5 - Martin the Duck (purple)
0xffca3a,
// 6 - Ronald the Macaw (orange)
0x43aa8b,
// 7 - Graham the Seagull (teal)
0x577590,
// 8 - Jones the Hummingbird (navy)
0xffffff // 9 - Swen the Swan (white)
];
self.number = 1; // Will be set after creation
var birdSprite = self.attachAsset('birdfriend', {
anchorX: 0.5,
anchorY: 0.5,
color: colors[self.number],
width: 120,
height: 120,
shape: 'ellipse'
});
// Add number label
var numberText = new Text2('1', {
size: 70,
fill: 0x222222
});
numberText.anchor.set(0.5, 0.5);
self.addChild(numberText);
// Set number and color
self.setNumber = function (n) {
self.number = n;
birdSprite.color = colors[n];
numberText.setText('' + n);
};
// Animate collection
self.collect = function (_onFinish) {
tween(self, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
if (_onFinish) _onFinish();
}
});
};
return self;
});
// Falcon (Player) class
var Falcon = Container.expand(function () {
var self = Container.call(this);
// Attach falcon asset (red box, will be replaced with image later)
var falconSprite = self.attachAsset('falcon', {
anchorX: 0.5,
anchorY: 0.5
});
// Movement speed
self.speed = 18;
// Current velocity
self.vx = 0;
self.vy = 0;
// Update method called every tick
self.update = function () {
self.x += self.vx;
self.y += self.vy;
// Clamp to game area
if (self.x < 100 + falconSprite.width / 2) self.x = 100 + falconSprite.width / 2;
if (self.x > 2048 - falconSprite.width / 2) self.x = 2048 - falconSprite.width / 2;
if (self.y < falconSprite.height / 2) self.y = falconSprite.height / 2;
if (self.y > 2732 - falconSprite.height / 2) self.y = 2732 - falconSprite.height / 2;
};
return self;
});
// Joystick class (on-screen)
var Joystick = Container.expand(function () {
var self = Container.call(this);
// Outer circle
var base = self.attachAsset('joystickBase', {
anchorX: 0.5,
anchorY: 0.5,
color: 0xaaaaaa,
width: 260,
height: 260,
shape: 'ellipse'
});
// Inner knob
var knob = self.attachAsset('joystickKnob', {
anchorX: 0.5,
anchorY: 0.5,
color: 0x333333,
width: 120,
height: 120,
shape: 'ellipse'
});
knob.x = 0;
knob.y = 0;
self.addChild(knob);
// Joystick state
self.active = false;
self.startX = 0;
self.startY = 0;
self.deltaX = 0;
self.deltaY = 0;
// Get normalized direction (-1 to 1)
self.getDirection = function () {
var dx = self.deltaX / 100;
var dy = self.deltaY / 100;
// Clamp
if (dx < -1) dx = -1;
if (dx > 1) dx = 1;
if (dy < -1) dy = -1;
if (dy > 1) dy = 1;
return {
x: dx,
y: dy
};
};
// Reset knob
self.reset = function () {
self.deltaX = 0;
self.deltaY = 0;
knob.x = 0;
knob.y = 0;
};
// Touch/mouse events
self.down = function (x, y, obj) {
self.active = true;
self.startX = x;
self.startY = y;
self.deltaX = 0;
self.deltaY = 0;
};
self.move = function (x, y, obj) {
if (!self.active) return;
self.deltaX = x - self.startX;
self.deltaY = y - self.startY;
// Clamp to radius 100
var dist = Math.sqrt(self.deltaX * self.deltaX + self.deltaY * self.deltaY);
if (dist > 100) {
var scale = 100 / dist;
self.deltaX *= scale;
self.deltaY *= scale;
}
knob.x = self.deltaX;
knob.y = self.deltaY;
};
self.up = function (x, y, obj) {
self.active = false;
self.reset();
};
return self;
});
// Obstacle class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
// Attach asset (gray box)
var obsSprite = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
color: 0x444444,
width: 180,
height: 60,
shape: 'box'
});
// Movement speed
self.speed = 10 + Math.random() * 8;
// Direction: 1 = right, -1 = left
self.dir = Math.random() < 0.5 ? 1 : -1;
// Update method
self.update = function () {
self.x += self.speed * self.dir;
// Bounce off edges
if (self.x < 100 + obsSprite.width / 2) {
self.x = 100 + obsSprite.width / 2;
self.dir = 1;
}
if (self.x > 2048 - obsSprite.width / 2) {
self.x = 2048 - obsSprite.width / 2;
self.dir = -1;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x7ec8e3 // Light blue sky
});
/****
* Game Code
****/
// --- Game variables ---
var falcon;
var joystick;
var birdFriends = [];
var obstacles = [];
var nextBird = 1;
var scoreTxt;
var timerTxt;
var timeElapsed = 0;
var timerInterval;
var gameActive = true;
var lastFalconX = 0,
lastFalconY = 0;
var lastIntersectingBird = false;
var lastIntersectingObstacle = false;
// --- Setup ---
// Set background color
game.setBackgroundColor(0x7ec8e3);
// Add Falcon (player)
falcon = new Falcon();
falcon.x = 2048 / 2;
falcon.y = 2732 - 400;
game.addChild(falcon);
// Add BirdFriends (1-9) at random positions, not overlapping
function randomBirdPos() {
var margin = 200;
var x = margin + Math.random() * (2048 - 2 * margin);
var y = margin + Math.random() * (2732 - 2 * margin - 600);
return {
x: x,
y: y
};
}
for (var i = 1; i <= 9; i++) {
var bird = new BirdFriend();
bird.setNumber(i);
var pos;
var tries = 0;
do {
pos = randomBirdPos();
var overlap = false;
for (var j = 0; j < birdFriends.length; j++) {
var dx = pos.x - birdFriends[j].x;
var dy = pos.y - birdFriends[j].y;
if (Math.sqrt(dx * dx + dy * dy) < 220) {
overlap = true;
break;
}
}
tries++;
} while (overlap && tries < 20);
bird.x = pos.x;
bird.y = pos.y + 200; // leave top margin for timer
bird.scaleX = 1;
bird.scaleY = 1;
bird.alpha = 1;
birdFriends.push(bird);
game.addChild(bird);
}
// Add obstacles (4 obstacles)
for (var o = 0; o < 4; o++) {
var obs = new Obstacle();
obs.x = 300 + Math.random() * (2048 - 600);
obs.y = 600 + Math.random() * (2732 - 1200);
obstacles.push(obs);
game.addChild(obs);
}
// Add joystick (bottom left, outside 100x100 menu area)
joystick = new Joystick();
joystick.x = 220;
joystick.y = 2732 - 220;
game.addChild(joystick);
// Add score text (top center)
scoreTxt = new Text2('Next: 1', {
size: 120,
fill: 0x222222
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Add timer text (top right)
timerTxt = new Text2('0.0s', {
size: 90,
fill: 0x222222
});
timerTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(timerTxt);
// --- Timer ---
function updateTimer() {
if (!gameActive) return;
timeElapsed += 0.1;
timerTxt.setText(timeElapsed.toFixed(1) + 's');
}
timerInterval = LK.setInterval(updateTimer, 100);
// --- Joystick events ---
joystick.down = function (x, y, obj) {
joystick.active = true;
joystick.startX = x;
joystick.startY = y;
joystick.deltaX = 0;
joystick.deltaY = 0;
};
joystick.move = function (x, y, obj) {
if (!joystick.active) return;
joystick.deltaX = x - joystick.startX;
joystick.deltaY = y - joystick.startY;
var dist = Math.sqrt(joystick.deltaX * joystick.deltaX + joystick.deltaY * joystick.deltaY);
if (dist > 100) {
var scale = 100 / dist;
joystick.deltaX *= scale;
joystick.deltaY *= scale;
}
joystick.children[1].x = joystick.deltaX;
joystick.children[1].y = joystick.deltaY;
};
joystick.up = function (x, y, obj) {
joystick.active = false;
joystick.reset();
};
// --- Game move/up/down events (for joystick) ---
game.down = function (x, y, obj) {
// If touch is inside joystick area, activate joystick
var dx = x - joystick.x;
var dy = y - joystick.y;
if (dx * dx + dy * dy < 130 * 130) {
joystick.down(x, y, obj);
}
};
game.move = function (x, y, obj) {
if (joystick.active) {
joystick.move(x, y, obj);
}
};
game.up = function (x, y, obj) {
if (joystick.active) {
joystick.up(x, y, obj);
}
};
// --- Main game update ---
game.update = function () {
if (!gameActive) return;
// Joystick controls Falcon
var dir = joystick.getDirection();
falcon.vx = dir.x * falcon.speed;
falcon.vy = dir.y * falcon.speed;
// Update Falcon
falcon.update();
// Update obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].update();
}
// Check collision with next bird
var nextBirdObj = null;
for (var i = 0; i < birdFriends.length; i++) {
if (birdFriends[i].number === nextBird) {
nextBirdObj = birdFriends[i];
break;
}
}
if (nextBirdObj) {
var intersecting = falcon.intersects(nextBirdObj);
if (!lastIntersectingBird && intersecting) {
// Collect bird
nextBirdObj.collect(function () {
nextBirdObj.destroy();
});
nextBird++;
if (nextBird > 9) {
// Win!
gameActive = false;
LK.clearInterval(timerInterval);
LK.setScore(Math.max(0, Math.round(10000 - timeElapsed * 100)));
LK.showYouWin();
return;
}
scoreTxt.setText('Next: ' + nextBird);
}
lastIntersectingBird = intersecting;
}
// Check collision with obstacles
var hitObstacle = false;
for (var i = 0; i < obstacles.length; i++) {
if (falcon.intersects(obstacles[i])) {
hitObstacle = true;
break;
}
}
if (!lastIntersectingObstacle && hitObstacle) {
// Game over
gameActive = false;
LK.clearInterval(timerInterval);
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
lastIntersectingObstacle = hitObstacle;
};
// --- Clean up on game end ---
function cleanup() {
LK.clearInterval(timerInterval);
}