/****
* 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);