/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Falcon (player) class var Falcon = Container.expand(function () { var self = Container.call(this); var falconSprite = self.attachAsset('falcon', { anchorX: 0.5, anchorY: 0.5 }); // For a little personality, add a slight tilt falconSprite.rotation = -0.1; // For hit feedback self.flash = function () { tween(falconSprite, { tint: 0xff8888 }, { duration: 150, onFinish: function onFinish() { tween(falconSprite, { tint: 0x8c6e3f }, { duration: 150 }); } }); }; return self; }); // Feather collectible var Feather = Container.expand(function () { var self = Container.call(this); var featherSprite = self.attachAsset('feather', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0; self.update = function () { self.y += self.speed; }; return self; }); // Obstacle base class var Obstacle = Container.expand(function () { var self = Container.call(this); self.speed = 0; self.type = ''; self.update = function () { self.y += self.speed; }; return self; }); // Sponge obstacle var Sponge = Obstacle.expand(function () { var self = Obstacle.call(this); var spongeSprite = self.attachAsset('sponge', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'sponge'; return self; }); // Splash obstacle var Splash = Obstacle.expand(function () { var self = Obstacle.call(this); var splashSprite = self.attachAsset('splash', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'splash'; return self; }); // Duck obstacle var Duck = Obstacle.expand(function () { var self = Obstacle.call(this); var duckSprite = self.attachAsset('duck', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'duck'; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xb3e6f7 // Light blue, like bath water }); /**** * Game Code ****/ // Feather (collectible) // Splash (obstacle) // Rubber ducky (obstacle) // Sponge (obstacle) // Falcon (player) // Game area dimensions var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; // Falcon/player var falcon = new Falcon(); game.addChild(falcon); // Start position: bottom center, above the bottom edge falcon.x = GAME_WIDTH / 2; falcon.y = GAME_HEIGHT - 350; // Score var score = 0; var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Feathers collected var feathersCollected = 0; var featherTxt = new Text2('0', { size: 80, fill: 0xFFFBE6 }); featherTxt.anchor.set(1, 0); LK.gui.topRight.addChild(featherTxt); // Arrays for obstacles and feathers var obstacles = []; var feathers = []; // Dragging logic var dragFalcon = false; // Difficulty progression var level = 1; var ticksSinceStart = 0; var nextLevelAt = 1200; // ~20 seconds per level // For collision state var lastFalconHit = false; // Move handler for dragging falcon function handleMove(x, y, obj) { if (dragFalcon) { // Clamp falcon within game area, avoid top 100px (menu) var minX = falcon.width / 2; var maxX = GAME_WIDTH - falcon.width / 2; var minY = 100 + falcon.height / 2; var maxY = GAME_HEIGHT - falcon.height / 2; falcon.x = Math.max(minX, Math.min(maxX, x)); falcon.y = Math.max(minY, Math.min(maxY, y)); } } game.move = handleMove; game.down = function (x, y, obj) { // Only start drag if touch is on falcon var local = falcon.toLocal(game.toGlobal({ x: x, y: y })); if (Math.abs(local.x) <= falcon.width / 2 && Math.abs(local.y) <= falcon.height / 2) { dragFalcon = true; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragFalcon = false; }; // Helper: spawn random obstacle function spawnObstacle() { var types = ['sponge', 'duck', 'splash']; // Increase chance of splash as level increases if (level > 2) types.push('splash'); var t = types[Math.floor(Math.random() * types.length)]; var obs; if (t === 'sponge') obs = new Sponge();else if (t === 'duck') obs = new Duck();else obs = new Splash(); // Random X, avoid left 100px (menu) var minX = 100 + obs.width / 2; var maxX = GAME_WIDTH - obs.width / 2; obs.x = minX + Math.random() * (maxX - minX); obs.y = -obs.height / 2; // Speed increases with level obs.speed = 8 + level * 2 + Math.random() * 2; obstacles.push(obs); game.addChild(obs); } // Helper: spawn feather function spawnFeather() { var feather = new Feather(); var minX = 100 + feather.width / 2; var maxX = GAME_WIDTH - feather.width / 2; feather.x = minX + Math.random() * (maxX - minX); feather.y = -feather.height / 2; feather.speed = 10 + level * 1.5 + Math.random() * 2; feathers.push(feather); game.addChild(feather); } // Main game update game.update = function () { ticksSinceStart++; // Level up if (ticksSinceStart > nextLevelAt) { level++; nextLevelAt += 1200; // Optionally, flash screen or show level up LK.effects.flashScreen(0x7fdfff, 400); } // Spawn obstacles at intervals, faster with level if (LK.ticks % Math.max(40 - level * 3, 12) === 0) { spawnObstacle(); } // Spawn feathers less often if (LK.ticks % Math.max(180 - level * 10, 60) === 0) { spawnFeather(); } // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.update(); // Remove if off screen if (obs.y - obs.height / 2 > GAME_HEIGHT + 50) { obs.destroy(); obstacles.splice(i, 1); continue; } // Collision with falcon var hit = obs.intersects(falcon); if (hit) { if (!lastFalconHit) { // Only trigger on transition falcon.flash(); LK.effects.flashScreen(0xff6666, 600); LK.showGameOver(); return; } } lastFalconHit = hit; } // Update feathers for (var j = feathers.length - 1; j >= 0; j--) { var f = feathers[j]; f.update(); // Remove if off screen if (f.y - f.height / 2 > GAME_HEIGHT + 50) { f.destroy(); feathers.splice(j, 1); continue; } // Collectible collision if (f.intersects(falcon)) { feathersCollected++; featherTxt.setText(feathersCollected); // Score bonus for feathers score += 5; scoreTxt.setText(score); // Feather collect effect LK.effects.flashObject(f, 0xffff99, 300); f.destroy(); feathers.splice(j, 1); continue; } } // Score increases over time if (LK.ticks % 30 === 0) { score++; scoreTxt.setText(score); } // Win condition: survive to level 5 and collect at least 10 feathers if (level >= 5 && feathersCollected >= 10) { LK.showYouWin(); return; } }; // Initial text scoreTxt.setText(score); featherTxt.setText(feathersCollected);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Falcon (player) class
var Falcon = Container.expand(function () {
var self = Container.call(this);
var falconSprite = self.attachAsset('falcon', {
anchorX: 0.5,
anchorY: 0.5
});
// For a little personality, add a slight tilt
falconSprite.rotation = -0.1;
// For hit feedback
self.flash = function () {
tween(falconSprite, {
tint: 0xff8888
}, {
duration: 150,
onFinish: function onFinish() {
tween(falconSprite, {
tint: 0x8c6e3f
}, {
duration: 150
});
}
});
};
return self;
});
// Feather collectible
var Feather = Container.expand(function () {
var self = Container.call(this);
var featherSprite = self.attachAsset('feather', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Obstacle base class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
self.speed = 0;
self.type = '';
self.update = function () {
self.y += self.speed;
};
return self;
});
// Sponge obstacle
var Sponge = Obstacle.expand(function () {
var self = Obstacle.call(this);
var spongeSprite = self.attachAsset('sponge', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'sponge';
return self;
});
// Splash obstacle
var Splash = Obstacle.expand(function () {
var self = Obstacle.call(this);
var splashSprite = self.attachAsset('splash', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'splash';
return self;
});
// Duck obstacle
var Duck = Obstacle.expand(function () {
var self = Obstacle.call(this);
var duckSprite = self.attachAsset('duck', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'duck';
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xb3e6f7 // Light blue, like bath water
});
/****
* Game Code
****/
// Feather (collectible)
// Splash (obstacle)
// Rubber ducky (obstacle)
// Sponge (obstacle)
// Falcon (player)
// Game area dimensions
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
// Falcon/player
var falcon = new Falcon();
game.addChild(falcon);
// Start position: bottom center, above the bottom edge
falcon.x = GAME_WIDTH / 2;
falcon.y = GAME_HEIGHT - 350;
// Score
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Feathers collected
var feathersCollected = 0;
var featherTxt = new Text2('0', {
size: 80,
fill: 0xFFFBE6
});
featherTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(featherTxt);
// Arrays for obstacles and feathers
var obstacles = [];
var feathers = [];
// Dragging logic
var dragFalcon = false;
// Difficulty progression
var level = 1;
var ticksSinceStart = 0;
var nextLevelAt = 1200; // ~20 seconds per level
// For collision state
var lastFalconHit = false;
// Move handler for dragging falcon
function handleMove(x, y, obj) {
if (dragFalcon) {
// Clamp falcon within game area, avoid top 100px (menu)
var minX = falcon.width / 2;
var maxX = GAME_WIDTH - falcon.width / 2;
var minY = 100 + falcon.height / 2;
var maxY = GAME_HEIGHT - falcon.height / 2;
falcon.x = Math.max(minX, Math.min(maxX, x));
falcon.y = Math.max(minY, Math.min(maxY, y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Only start drag if touch is on falcon
var local = falcon.toLocal(game.toGlobal({
x: x,
y: y
}));
if (Math.abs(local.x) <= falcon.width / 2 && Math.abs(local.y) <= falcon.height / 2) {
dragFalcon = true;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragFalcon = false;
};
// Helper: spawn random obstacle
function spawnObstacle() {
var types = ['sponge', 'duck', 'splash'];
// Increase chance of splash as level increases
if (level > 2) types.push('splash');
var t = types[Math.floor(Math.random() * types.length)];
var obs;
if (t === 'sponge') obs = new Sponge();else if (t === 'duck') obs = new Duck();else obs = new Splash();
// Random X, avoid left 100px (menu)
var minX = 100 + obs.width / 2;
var maxX = GAME_WIDTH - obs.width / 2;
obs.x = minX + Math.random() * (maxX - minX);
obs.y = -obs.height / 2;
// Speed increases with level
obs.speed = 8 + level * 2 + Math.random() * 2;
obstacles.push(obs);
game.addChild(obs);
}
// Helper: spawn feather
function spawnFeather() {
var feather = new Feather();
var minX = 100 + feather.width / 2;
var maxX = GAME_WIDTH - feather.width / 2;
feather.x = minX + Math.random() * (maxX - minX);
feather.y = -feather.height / 2;
feather.speed = 10 + level * 1.5 + Math.random() * 2;
feathers.push(feather);
game.addChild(feather);
}
// Main game update
game.update = function () {
ticksSinceStart++;
// Level up
if (ticksSinceStart > nextLevelAt) {
level++;
nextLevelAt += 1200;
// Optionally, flash screen or show level up
LK.effects.flashScreen(0x7fdfff, 400);
}
// Spawn obstacles at intervals, faster with level
if (LK.ticks % Math.max(40 - level * 3, 12) === 0) {
spawnObstacle();
}
// Spawn feathers less often
if (LK.ticks % Math.max(180 - level * 10, 60) === 0) {
spawnFeather();
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.update();
// Remove if off screen
if (obs.y - obs.height / 2 > GAME_HEIGHT + 50) {
obs.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision with falcon
var hit = obs.intersects(falcon);
if (hit) {
if (!lastFalconHit) {
// Only trigger on transition
falcon.flash();
LK.effects.flashScreen(0xff6666, 600);
LK.showGameOver();
return;
}
}
lastFalconHit = hit;
}
// Update feathers
for (var j = feathers.length - 1; j >= 0; j--) {
var f = feathers[j];
f.update();
// Remove if off screen
if (f.y - f.height / 2 > GAME_HEIGHT + 50) {
f.destroy();
feathers.splice(j, 1);
continue;
}
// Collectible collision
if (f.intersects(falcon)) {
feathersCollected++;
featherTxt.setText(feathersCollected);
// Score bonus for feathers
score += 5;
scoreTxt.setText(score);
// Feather collect effect
LK.effects.flashObject(f, 0xffff99, 300);
f.destroy();
feathers.splice(j, 1);
continue;
}
}
// Score increases over time
if (LK.ticks % 30 === 0) {
score++;
scoreTxt.setText(score);
}
// Win condition: survive to level 5 and collect at least 10 feathers
if (level >= 5 && feathersCollected >= 10) {
LK.showYouWin();
return;
}
};
// Initial text
scoreTxt.setText(score);
featherTxt.setText(feathersCollected);