/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Island = Container.expand(function () {
var self = Container.call(this);
var islandGraphics = self.attachAsset('island', {
anchorX: 0.5,
anchorY: 0.5
});
var mailboxGraphics = self.attachAsset('mailbox', {
anchorX: 0.5,
anchorY: 0.5
});
mailboxGraphics.y = -80;
self.hasDelivery = false;
self.deliveryValue = 10;
self.setDeliveryTarget = function () {
self.hasDelivery = true;
mailboxGraphics.tint = 0xFF0000;
};
self.clearDelivery = function () {
self.hasDelivery = false;
mailboxGraphics.tint = 0xFF6B35;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
};
return self;
});
var Plane = Container.expand(function () {
var self = Container.call(this);
var planeGraphics = self.attachAsset('plane', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.isDiving = false;
self.diveMultiplier = 1;
self.rotation = 0;
self.windFuel = 100;
self.maxWindFuel = 100;
self.update = function () {
// Apply gravity
self.velocityY += 0.15;
// Limit falling speed
if (self.velocityY > 8) {
self.velocityY = 8;
}
// Apply velocity
self.x += self.velocityX;
self.y += self.velocityY;
// Update rotation based on velocity
self.rotation = Math.atan2(self.velocityY, self.velocityX);
// Reset dive if no longer diving
if (!self.isDiving) {
self.diveMultiplier = 1;
}
};
self.useWind = function (amount) {
self.windFuel = Math.max(0, self.windFuel - amount);
if (self.windFuel > 0) {
LK.getSound('windUse').play();
}
};
self.dive = function () {
if (self.velocityY > -3) {
self.isDiving = true;
self.diveMultiplier = 1.5;
self.velocityY -= 2;
LK.getSound('dive').play();
}
};
self.applyWind = function (windForce) {
if (self.windFuel > 0) {
self.velocityX += windForce;
self.useWind(0.5);
}
};
self.refuelWind = function (amount) {
self.windFuel = Math.min(self.maxWindFuel, self.windFuel + amount);
};
return self;
});
var WindParticleEffect = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('windParticle', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.lifetime = 30;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.lifetime -= 1;
self.alpha = self.lifetime / 30;
if (self.lifetime <= 0) {
self.markForDestroy = true;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state
var plane = null;
var islands = [];
var obstacles = [];
var particles = [];
var currentDeliveryIsland = null;
var deliveriesCompleted = 0;
var gameTime = 0;
var dragStartX = 0;
var dragStartY = 0;
var isDragging = false;
// UI elements
var scoreText = new Text2('Score: 0', {
size: 80,
fill: '#ffffff'
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var windText = new Text2('Wind: 100%', {
size: 70,
fill: '#4A90E2'
});
windText.anchor.set(0.5, 0);
windText.y = 100;
LK.gui.top.addChild(windText);
var deliveryText = new Text2('Deliver to: Island 1', {
size: 70,
fill: '#FF6B35'
});
deliveryText.anchor.set(0.5, 0);
deliveryText.y = 200;
LK.gui.top.addChild(deliveryText);
// Initialize islands
function initializeIslands() {
islands = [];
var islandPositions = [{
x: 400,
y: 400
}, {
x: 1200,
y: 600
}, {
x: 1800,
y: 400
}, {
x: 600,
y: 1400
}, {
x: 1400,
y: 1800
}, {
x: 2000,
y: 2200
}];
for (var i = 0; i < islandPositions.length; i++) {
var island = game.addChild(new Island());
island.x = islandPositions[i].x;
island.y = islandPositions[i].y;
islands.push(island);
}
// Set first island as delivery target
currentDeliveryIsland = islands[0];
currentDeliveryIsland.setDeliveryTarget();
}
// Initialize obstacles
function initializeObstacles() {
obstacles = [];
var obstaclePositions = [{
x: 800,
y: 800
}, {
x: 1500,
y: 1200
}, {
x: 600,
y: 2000
}, {
x: 1800,
y: 1600
}];
for (var i = 0; i < obstaclePositions.length; i++) {
var obstacle = game.addChild(new Obstacle());
obstacle.x = obstaclePositions[i].x;
obstacle.y = obstaclePositions[i].y;
obstacles.push(obstacle);
}
}
// Initialize plane
function initializePlane() {
plane = game.addChild(new Plane());
plane.x = 300;
plane.y = 500;
plane.windFuel = 100;
}
// Create wind particle effect
function createWindParticle(x, y, vx, vy) {
var particle = game.addChild(new WindParticleEffect());
particle.x = x;
particle.y = y;
particle.velocityX = vx;
particle.velocityY = vy;
particles.push(particle);
}
// Get next delivery island
function getNextDeliveryIsland() {
if (currentDeliveryIsland) {
var currentIndex = islands.indexOf(currentDeliveryIsland);
var nextIndex = (currentIndex + 1) % islands.length;
return islands[nextIndex];
}
return islands[0];
}
// Update UI
function updateUI() {
scoreText.setText('Score: ' + deliveriesCompleted);
var windPercent = Math.ceil(plane.windFuel / plane.maxWindFuel * 100);
windText.setText('Wind: ' + windPercent + '%');
if (currentDeliveryIsland) {
var islandIndex = islands.indexOf(currentDeliveryIsland) + 1;
deliveryText.setText('Deliver to: Island ' + islandIndex);
}
}
// Game initialization
initializeIslands();
initializeObstacles();
initializePlane();
updateUI();
// Play background music
LK.playMusic('bgmusic');
// Game event handlers
game.down = function (x, y, obj) {
isDragging = true;
dragStartX = x;
dragStartY = y;
};
game.up = function (x, y, obj) {
isDragging = false;
};
game.move = function (x, y, obj) {
if (isDragging && plane.windFuel > 0) {
var deltaX = x - dragStartX;
var deltaY = y - dragStartY;
var windForce = deltaX * 0.01;
plane.applyWind(windForce);
// Create wind particle effects
for (var i = 0; i < 2; i++) {
createWindParticle(plane.x - deltaX * 0.3, plane.y - deltaY * 0.3, -deltaX * 0.05, -deltaY * 0.05);
}
dragStartX = x;
dragStartY = y;
}
};
// Main game loop
game.update = function () {
gameTime++;
// Update plane
if (plane.windFuel <= 0) {
plane.velocityX *= 0.99;
}
// Check if plane is out of bounds (too low)
if (plane.y > 2800) {
LK.showGameOver();
return;
}
// Check if plane is out of bounds horizontally
if (plane.x < -200 || plane.x > 2248) {
LK.showGameOver();
return;
}
// Update particles
for (var p = particles.length - 1; p >= 0; p--) {
var particle = particles[p];
if (particle.markForDestroy) {
particle.destroy();
particles.splice(p, 1);
}
}
// Update obstacles
for (var o = 0; o < obstacles.length; o++) {
obstacles[o].update();
}
// Check plane collision with obstacles
for (var o = 0; o < obstacles.length; o++) {
if (plane.intersects(obstacles[o])) {
LK.effects.flashScreen(0xFF0000, 500);
LK.showGameOver();
return;
}
}
// Check plane collision with islands
for (var i = 0; i < islands.length; i++) {
if (plane.intersects(islands[i])) {
if (currentDeliveryIsland === islands[i] && plane.velocityY > 0) {
// Successful delivery
LK.getSound('deliver').play();
deliveriesCompleted++;
LK.setScore(deliveriesCompleted);
currentDeliveryIsland.clearDelivery();
currentDeliveryIsland = getNextDeliveryIsland();
currentDeliveryIsland.setDeliveryTarget();
// Refuel wind on delivery
plane.refuelWind(30);
// Check win condition
if (deliveriesCompleted >= 5) {
LK.showYouWin();
return;
}
} else if (currentDeliveryIsland !== islands[i]) {
// Wrong island collision
LK.effects.flashScreen(0xFFFF00, 300);
plane.velocityY = -3;
}
}
}
// Diving mechanic - auto dive if going too slow horizontally
if (gameTime % 20 === 0 && plane.velocityY > -1 && plane.windFuel > 10) {
if (Math.abs(plane.velocityX) < 2) {
plane.dive();
}
}
// Apply wind boost for forward momentum
if (plane.windFuel > 0 && gameTime % 40 === 0) {
plane.applyWind(0.3);
}
updateUI();
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Island = Container.expand(function () {
var self = Container.call(this);
var islandGraphics = self.attachAsset('island', {
anchorX: 0.5,
anchorY: 0.5
});
var mailboxGraphics = self.attachAsset('mailbox', {
anchorX: 0.5,
anchorY: 0.5
});
mailboxGraphics.y = -80;
self.hasDelivery = false;
self.deliveryValue = 10;
self.setDeliveryTarget = function () {
self.hasDelivery = true;
mailboxGraphics.tint = 0xFF0000;
};
self.clearDelivery = function () {
self.hasDelivery = false;
mailboxGraphics.tint = 0xFF6B35;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
};
return self;
});
var Plane = Container.expand(function () {
var self = Container.call(this);
var planeGraphics = self.attachAsset('plane', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.isDiving = false;
self.diveMultiplier = 1;
self.rotation = 0;
self.windFuel = 100;
self.maxWindFuel = 100;
self.update = function () {
// Apply gravity
self.velocityY += 0.15;
// Limit falling speed
if (self.velocityY > 8) {
self.velocityY = 8;
}
// Apply velocity
self.x += self.velocityX;
self.y += self.velocityY;
// Update rotation based on velocity
self.rotation = Math.atan2(self.velocityY, self.velocityX);
// Reset dive if no longer diving
if (!self.isDiving) {
self.diveMultiplier = 1;
}
};
self.useWind = function (amount) {
self.windFuel = Math.max(0, self.windFuel - amount);
if (self.windFuel > 0) {
LK.getSound('windUse').play();
}
};
self.dive = function () {
if (self.velocityY > -3) {
self.isDiving = true;
self.diveMultiplier = 1.5;
self.velocityY -= 2;
LK.getSound('dive').play();
}
};
self.applyWind = function (windForce) {
if (self.windFuel > 0) {
self.velocityX += windForce;
self.useWind(0.5);
}
};
self.refuelWind = function (amount) {
self.windFuel = Math.min(self.maxWindFuel, self.windFuel + amount);
};
return self;
});
var WindParticleEffect = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('windParticle', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.lifetime = 30;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.lifetime -= 1;
self.alpha = self.lifetime / 30;
if (self.lifetime <= 0) {
self.markForDestroy = true;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state
var plane = null;
var islands = [];
var obstacles = [];
var particles = [];
var currentDeliveryIsland = null;
var deliveriesCompleted = 0;
var gameTime = 0;
var dragStartX = 0;
var dragStartY = 0;
var isDragging = false;
// UI elements
var scoreText = new Text2('Score: 0', {
size: 80,
fill: '#ffffff'
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var windText = new Text2('Wind: 100%', {
size: 70,
fill: '#4A90E2'
});
windText.anchor.set(0.5, 0);
windText.y = 100;
LK.gui.top.addChild(windText);
var deliveryText = new Text2('Deliver to: Island 1', {
size: 70,
fill: '#FF6B35'
});
deliveryText.anchor.set(0.5, 0);
deliveryText.y = 200;
LK.gui.top.addChild(deliveryText);
// Initialize islands
function initializeIslands() {
islands = [];
var islandPositions = [{
x: 400,
y: 400
}, {
x: 1200,
y: 600
}, {
x: 1800,
y: 400
}, {
x: 600,
y: 1400
}, {
x: 1400,
y: 1800
}, {
x: 2000,
y: 2200
}];
for (var i = 0; i < islandPositions.length; i++) {
var island = game.addChild(new Island());
island.x = islandPositions[i].x;
island.y = islandPositions[i].y;
islands.push(island);
}
// Set first island as delivery target
currentDeliveryIsland = islands[0];
currentDeliveryIsland.setDeliveryTarget();
}
// Initialize obstacles
function initializeObstacles() {
obstacles = [];
var obstaclePositions = [{
x: 800,
y: 800
}, {
x: 1500,
y: 1200
}, {
x: 600,
y: 2000
}, {
x: 1800,
y: 1600
}];
for (var i = 0; i < obstaclePositions.length; i++) {
var obstacle = game.addChild(new Obstacle());
obstacle.x = obstaclePositions[i].x;
obstacle.y = obstaclePositions[i].y;
obstacles.push(obstacle);
}
}
// Initialize plane
function initializePlane() {
plane = game.addChild(new Plane());
plane.x = 300;
plane.y = 500;
plane.windFuel = 100;
}
// Create wind particle effect
function createWindParticle(x, y, vx, vy) {
var particle = game.addChild(new WindParticleEffect());
particle.x = x;
particle.y = y;
particle.velocityX = vx;
particle.velocityY = vy;
particles.push(particle);
}
// Get next delivery island
function getNextDeliveryIsland() {
if (currentDeliveryIsland) {
var currentIndex = islands.indexOf(currentDeliveryIsland);
var nextIndex = (currentIndex + 1) % islands.length;
return islands[nextIndex];
}
return islands[0];
}
// Update UI
function updateUI() {
scoreText.setText('Score: ' + deliveriesCompleted);
var windPercent = Math.ceil(plane.windFuel / plane.maxWindFuel * 100);
windText.setText('Wind: ' + windPercent + '%');
if (currentDeliveryIsland) {
var islandIndex = islands.indexOf(currentDeliveryIsland) + 1;
deliveryText.setText('Deliver to: Island ' + islandIndex);
}
}
// Game initialization
initializeIslands();
initializeObstacles();
initializePlane();
updateUI();
// Play background music
LK.playMusic('bgmusic');
// Game event handlers
game.down = function (x, y, obj) {
isDragging = true;
dragStartX = x;
dragStartY = y;
};
game.up = function (x, y, obj) {
isDragging = false;
};
game.move = function (x, y, obj) {
if (isDragging && plane.windFuel > 0) {
var deltaX = x - dragStartX;
var deltaY = y - dragStartY;
var windForce = deltaX * 0.01;
plane.applyWind(windForce);
// Create wind particle effects
for (var i = 0; i < 2; i++) {
createWindParticle(plane.x - deltaX * 0.3, plane.y - deltaY * 0.3, -deltaX * 0.05, -deltaY * 0.05);
}
dragStartX = x;
dragStartY = y;
}
};
// Main game loop
game.update = function () {
gameTime++;
// Update plane
if (plane.windFuel <= 0) {
plane.velocityX *= 0.99;
}
// Check if plane is out of bounds (too low)
if (plane.y > 2800) {
LK.showGameOver();
return;
}
// Check if plane is out of bounds horizontally
if (plane.x < -200 || plane.x > 2248) {
LK.showGameOver();
return;
}
// Update particles
for (var p = particles.length - 1; p >= 0; p--) {
var particle = particles[p];
if (particle.markForDestroy) {
particle.destroy();
particles.splice(p, 1);
}
}
// Update obstacles
for (var o = 0; o < obstacles.length; o++) {
obstacles[o].update();
}
// Check plane collision with obstacles
for (var o = 0; o < obstacles.length; o++) {
if (plane.intersects(obstacles[o])) {
LK.effects.flashScreen(0xFF0000, 500);
LK.showGameOver();
return;
}
}
// Check plane collision with islands
for (var i = 0; i < islands.length; i++) {
if (plane.intersects(islands[i])) {
if (currentDeliveryIsland === islands[i] && plane.velocityY > 0) {
// Successful delivery
LK.getSound('deliver').play();
deliveriesCompleted++;
LK.setScore(deliveriesCompleted);
currentDeliveryIsland.clearDelivery();
currentDeliveryIsland = getNextDeliveryIsland();
currentDeliveryIsland.setDeliveryTarget();
// Refuel wind on delivery
plane.refuelWind(30);
// Check win condition
if (deliveriesCompleted >= 5) {
LK.showYouWin();
return;
}
} else if (currentDeliveryIsland !== islands[i]) {
// Wrong island collision
LK.effects.flashScreen(0xFFFF00, 300);
plane.velocityY = -3;
}
}
}
// Diving mechanic - auto dive if going too slow horizontally
if (gameTime % 20 === 0 && plane.velocityY > -1 && plane.windFuel > 10) {
if (Math.abs(plane.velocityX) < 2) {
plane.dive();
}
}
// Apply wind boost for forward momentum
if (plane.windFuel > 0 && gameTime % 40 === 0) {
plane.applyWind(0.3);
}
updateUI();
};