/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var Cloud = Container.expand(function () { var self = Container.call(this); var cloudShape = self.attachAsset('cloud', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.speed = 0.5 + Math.random() * 0.5; self.update = function () { self.x -= self.speed; if (self.x < -cloudShape.width) { self.x = 2048 + cloudShape.width; self.y = 100 + Math.random() * 500; } }; return self; }); var FuelBar = Container.expand(function () { var self = Container.call(this); var frame = self.attachAsset('fuelBar', { anchorX: 1.0, anchorY: 0.0, tint: 0x000000 // Frame color }); var bar = self.attachAsset('fuelBar', { anchorX: 1.0, anchorY: 0.0, tint: 0x00ff00 // Glowing fill effect }); self.maxFuel = 100; self.currentFuel = self.maxFuel; self.depletionRate = 0.05; // Adjusted fuel depletion rate for fairness self.update = function () { if (self.currentFuel > 0) { // Adjust depletion rate based on score var dynamicDepletionRate = self.depletionRate + Math.min(0.05, score * 0.001); self.currentFuel -= dynamicDepletionRate; bar.scaleX = self.currentFuel / self.maxFuel; if (self.currentFuel < 25) { // Low fuel warning tween(bar, { tint: 0xff0000 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(bar, { tint: 0x00ff00 }, { duration: 500, easing: tween.easeInOut }); } }); if (!self.lowFuelSoundPlaying) { LK.getSound('lowFuelWarning').play(); self.lowFuelSoundPlaying = true; } } else { self.lowFuelSoundPlaying = false; } } else { bird.die(); // Trigger game over if fuel is empty } }; self.refill = function (amount) { self.currentFuel = Math.min(self.currentFuel + amount, self.maxFuel); }; var fuelIcon = self.attachAsset('fuelCollectible', { anchorX: 0.5, anchorY: 0.5, x: -frame.width - 20, // Position next to the fuel bar y: frame.height / 2 }); return self; }); var FuelCollectible = Container.expand(function (type) { var self = Container.call(this); self.type = type; var collectible = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x -= baseObstacleSpeed; // Move fuel tanks from right to left collectible.rotation -= 0.05; // Reverse slow spin collectible.alpha = 0.8 + 0.2 * Math.sin(LK.ticks * 0.1); // Light glow effect if (self.x < -collectible.width) { self.destroy(); } }; self.speed = baseFuelSpeed; // Set fuel tank speed to match obstacles return self; }); var Helicopter = Container.expand(function () { var self = Container.call(this); // Bird body var body = self.attachAsset('helicopter', { anchorX: 0.5, anchorY: 0.5 }); // Bird properties self.velocity = 0; self.gravity = 0.5; self.flapPower = -12; self.rotation = 0; self.alive = true; self.flap = function () { if (!self.alive) { return; } self.velocity = self.flapPower; LK.getSound('flap').play(); // Wing flap animation tween(self, { scaleY: 0.7 }, { duration: 100, onFinish: function onFinish() { tween(self, { scaleY: 1 }, { duration: 200 }); } }); }; self.update = function () { if (!self.alive) { return; } // Apply gravity or hold-to-fly mechanic if (self.holdFlying) { self.velocity = Math.max(self.velocity - 0.2, -5); // Slow rise when holding } else { self.velocity += self.gravity; } self.y += self.velocity; // Rotate based on velocity var targetRotation = self.velocity * 0.03; targetRotation = Math.max(Math.min(targetRotation, Math.PI / 4), -Math.PI / 4); self.rotation += (targetRotation - self.rotation) * 0.1; // Boundaries if (self.y < 0) { self.die(); // Trigger game over when the player goes off-screen at the top } if (self.y > 2732 - 250) { self.die(); } }; self.die = function () { if (!self.alive) { return; } self.alive = false; LK.getSound('hit').play(); LK.effects.flashObject(self, 0xff0000, 500); // Death spin animation tween(self, { rotation: Math.PI, alpha: 0.7 }, { duration: 1000, onFinish: function onFinish() { LK.showGameOver(); } }); }; // Rotor blade animation var rotor = self.attachAsset('helicopterRotor', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -body.height / 2 }); // Function to continuously rotate the rotor function rotateRotor() { tween(rotor, { rotation: rotor.rotation + Math.PI * 2 }, { duration: 500, onFinish: rotateRotor }); } // Start the rotor animation rotateRotor(); return self; }); var Obstacle = Container.expand(function (topType, bottomType) { var self = Container.call(this); // Gap between top and bottom obstacles // Top obstacle var topObstacle = self.attachAsset(topType, { anchorX: 0.5, anchorY: 1.0, y: 0 }); var bottomObstacle = self.attachAsset(bottomType, { anchorX: 0.5, anchorY: 0, y: 0 }); self.speed = 3; self.passed = false; self.width = topObstacle.width; self.setGapSize = function (size) { bottomObstacle.y = topObstacle.y + size; }; self.update = function () { self.x -= self.speed; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerUpAsset = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x -= baseObstacleSpeed; if (self.x < -powerUpAsset.width) { self.destroy(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB, title: 'Fly High: Fuel or Fall' }); /**** * Game Code ****/ // Game variables var bird; var obstacles = []; var clouds = []; var water; var score = 0; var highScore = storage.highScore || 0; var baseObstacleSpeed = 3; var baseFuelSpeed = baseObstacleSpeed; // Initialize fuel tank speed to match obstacles var spawnInterval = 150; var minGapSize = 400; var gameStarted = false; var scoreTxt; var highScoreTxt; var instructionsTxt; // Initialize water (always at bottom of screen) water = LK.getAsset('water', { anchorX: 0, anchorY: 0, x: 0, y: 2732 - 500 }); game.addChild(water); // Initialize clouds for (var i = 0; i < 5; i++) { var cloud = new Cloud(); cloud.x = Math.random() * 2048; cloud.y = 100 + Math.random() * 500; clouds.push(cloud); game.addChild(cloud); } // Initialize bird bird = new Helicopter(); bird.x = 400; bird.y = 2732 / 2; game.addChild(bird); // Initialize fuel bar var fuelBar = new FuelBar(); fuelBar.x = 2048 - 20; // Position at top-right corner fuelBar.y = 20; // Score text scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.y = 50; // Move the score text slightly down LK.gui.top.addChild(scoreTxt); // Initialize fuel bar var fuelBar = new FuelBar(); fuelBar.x = scoreTxt.x + scoreTxt.width / 2 + 60; // Increase space between the fuel bar and fuel tank fuelBar.y = 20; LK.gui.top.addChild(fuelBar); // High score text highScoreTxt = new Text2('Best: ' + highScore, { size: 60, fill: 0xFFFFFF }); highScoreTxt.anchor.set(0.5, 0); highScoreTxt.y = 180; LK.gui.top.addChild(highScoreTxt); // Instructions text instructionsTxt = new Text2('Tap to flap!', { size: 80, fill: 0xFFFFFF }); instructionsTxt.anchor.set(0.5, 0.5); LK.gui.center.addChild(instructionsTxt); // Tap to flap function function handleTap() { if (!gameStarted) { gameStarted = true; instructionsTxt.visible = false; LK.playMusic('bgMusic'); } bird.flap(); } // Obstacle spawning function function spawnObstacle() { var obstacleTypes = ['lollipop', 'birdNest', 'ufo', 'satellite', 'tree', 'balloon', 'bird', 'smily']; var chosenType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)]; var topObstacleType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)]; var bottomObstacleType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)]; var obstacle = new Obstacle(topObstacleType, bottomObstacleType); // Set position obstacle.x = 2048 + obstacle.width; // Random vertical position for the gap, keeping it away from the very top and bottom var minY = 100; // Ensure taller obstacles are fully visible var maxY = 2732 - 500 - minGapSize - obstacle.children[0].height; // Adjust maxY to account for obstacle height obstacle.y = minY + Math.random() * (maxY - minY); // Adjust gap size based on score (gets narrower as score increases) var gapSize = minGapSize + 300 - Math.min(200, score * 5); obstacle.setGapSize(gapSize); // Adjust speed based on score (gets faster as score increases) obstacle.speed = baseObstacleSpeed + Math.min(5, score * 0.1); obstacles.push(obstacle); game.addChild(obstacle); } // Handle tap or click game.down = function (x, y, obj) { handleTap(); bird.holdFlying = true; }; // Handle release of mouse or touch game.up = function (x, y, obj) { bird.holdFlying = false; }; // Game update loop game.update = function () { // Update clouds for (var i = 0; i < clouds.length; i++) { clouds[i].update(); } if (!gameStarted) { return; } // Spawn obstacles if (LK.ticks % spawnInterval === 0) { spawnObstacle(); } // Spawn fuel collectible occasionally if (LK.ticks % (spawnInterval * Math.max(3, 5 - Math.floor(score / 10))) === 0) { if (Math.random() < 0.1) { // 10% chance to spawn a power-up var powerUp = new PowerUp(); powerUp.x = 2048 + 50; powerUp.y = 150 + Math.random() * (2732 - 900 - minGapSize); game.addChild(powerUp); } var fuelType = Math.random() < 0.8 ? 'smallFuelCollectible' : 'bigFuelCollectible'; // 80% chance for small, 20% for big var fuelCollectible = new FuelCollectible(fuelType); fuelCollectible.x = 2048 + 50; fuelCollectible.y = 150 + Math.random() * (2732 - 900 - minGapSize); game.addChild(fuelCollectible); } // Update obstacles for (var j = obstacles.length - 1; j >= 0; j--) { var obstacle = obstacles[j]; obstacle.update(); // Check if bird passed obstacle if (!obstacle.passed && bird.x > obstacle.x + obstacle.width / 2) { obstacle.passed = true; score++; LK.setScore(score); scoreTxt.setText(score.toString()); LK.getSound('score').play(); // Update high score if needed if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('Best: ' + highScore); } } // Check for collision with bird if (bird.alive) { var topObstacleBounds = new Rectangle(obstacle.x - obstacle.width / 2, obstacle.y - obstacle.children[0].height, obstacle.width, obstacle.children[0].height); var bottomObstacleBounds = new Rectangle(obstacle.x - obstacle.width / 2, obstacle.y + obstacle.children[1].y, obstacle.width, obstacle.children[1].height); var birdBounds = new Rectangle(bird.x - 60, bird.y - 40, 120, 80); // Check collision with top obstacle if (birdBounds.x + birdBounds.width > topObstacleBounds.x && birdBounds.x < topObstacleBounds.x + topObstacleBounds.width && birdBounds.y + birdBounds.height > topObstacleBounds.y && birdBounds.y < topObstacleBounds.y + topObstacleBounds.height) { bird.die(); } // Check collision with bottom obstacle if (birdBounds.x + birdBounds.width > bottomObstacleBounds.x && birdBounds.x < bottomObstacleBounds.x + bottomObstacleBounds.width && birdBounds.y < bottomObstacleBounds.y + bottomObstacleBounds.height && birdBounds.y + birdBounds.height > bottomObstacleBounds.y) { bird.die(); } } // Remove obstacles that are off-screen if (obstacle.x < -obstacle.width) { obstacle.destroy(); obstacles.splice(j, 1); } } // Update fuel bar fuelBar.update(); // Check for fuel collection var fuelCollectibles = game.children.filter(function (child) { return child instanceof FuelCollectible; }); for (var k = fuelCollectibles.length - 1; k >= 0; k--) { var fuel = fuelCollectibles[k]; if (bird.intersects(fuel)) { if (fuel.type === 'smallFuelCollectible') { var smallFuelValue = 20 + Math.min(5, score * 0.1); // Scale with score fuelBar.refill(smallFuelValue); // Refill fuel bar LK.getSound('collectSmallFuel').play(); } else if (fuel.type === 'bigFuelCollectible') { fuelBar.refill(fuelBar.maxFuel); // Instantly refill to 100% LK.getSound('collectBigFuel').play(); // Add a satisfying animation for full refill tween(fuelBar, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(fuelBar, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); } }); } fuel.destroy(); } } // Check for power-up collection var powerUps = game.children.filter(function (child) { return child instanceof PowerUp; }); for (var l = powerUps.length - 1; l >= 0; l--) { var powerUp = powerUps[l]; if (bird.intersects(powerUp)) { baseObstacleSpeed += 2; // Increase speed LK.setTimeout(function () { baseObstacleSpeed -= 2; // Revert speed after 10 seconds }, 10000); powerUp.destroy(); } } // Update bird bird.update(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Cloud = Container.expand(function () {
var self = Container.call(this);
var cloudShape = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
self.speed = 0.5 + Math.random() * 0.5;
self.update = function () {
self.x -= self.speed;
if (self.x < -cloudShape.width) {
self.x = 2048 + cloudShape.width;
self.y = 100 + Math.random() * 500;
}
};
return self;
});
var FuelBar = Container.expand(function () {
var self = Container.call(this);
var frame = self.attachAsset('fuelBar', {
anchorX: 1.0,
anchorY: 0.0,
tint: 0x000000 // Frame color
});
var bar = self.attachAsset('fuelBar', {
anchorX: 1.0,
anchorY: 0.0,
tint: 0x00ff00 // Glowing fill effect
});
self.maxFuel = 100;
self.currentFuel = self.maxFuel;
self.depletionRate = 0.05; // Adjusted fuel depletion rate for fairness
self.update = function () {
if (self.currentFuel > 0) {
// Adjust depletion rate based on score
var dynamicDepletionRate = self.depletionRate + Math.min(0.05, score * 0.001);
self.currentFuel -= dynamicDepletionRate;
bar.scaleX = self.currentFuel / self.maxFuel;
if (self.currentFuel < 25) {
// Low fuel warning
tween(bar, {
tint: 0xff0000
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(bar, {
tint: 0x00ff00
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
if (!self.lowFuelSoundPlaying) {
LK.getSound('lowFuelWarning').play();
self.lowFuelSoundPlaying = true;
}
} else {
self.lowFuelSoundPlaying = false;
}
} else {
bird.die(); // Trigger game over if fuel is empty
}
};
self.refill = function (amount) {
self.currentFuel = Math.min(self.currentFuel + amount, self.maxFuel);
};
var fuelIcon = self.attachAsset('fuelCollectible', {
anchorX: 0.5,
anchorY: 0.5,
x: -frame.width - 20,
// Position next to the fuel bar
y: frame.height / 2
});
return self;
});
var FuelCollectible = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
var collectible = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.x -= baseObstacleSpeed; // Move fuel tanks from right to left
collectible.rotation -= 0.05; // Reverse slow spin
collectible.alpha = 0.8 + 0.2 * Math.sin(LK.ticks * 0.1); // Light glow effect
if (self.x < -collectible.width) {
self.destroy();
}
};
self.speed = baseFuelSpeed; // Set fuel tank speed to match obstacles
return self;
});
var Helicopter = Container.expand(function () {
var self = Container.call(this);
// Bird body
var body = self.attachAsset('helicopter', {
anchorX: 0.5,
anchorY: 0.5
});
// Bird properties
self.velocity = 0;
self.gravity = 0.5;
self.flapPower = -12;
self.rotation = 0;
self.alive = true;
self.flap = function () {
if (!self.alive) {
return;
}
self.velocity = self.flapPower;
LK.getSound('flap').play();
// Wing flap animation
tween(self, {
scaleY: 0.7
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
scaleY: 1
}, {
duration: 200
});
}
});
};
self.update = function () {
if (!self.alive) {
return;
}
// Apply gravity or hold-to-fly mechanic
if (self.holdFlying) {
self.velocity = Math.max(self.velocity - 0.2, -5); // Slow rise when holding
} else {
self.velocity += self.gravity;
}
self.y += self.velocity;
// Rotate based on velocity
var targetRotation = self.velocity * 0.03;
targetRotation = Math.max(Math.min(targetRotation, Math.PI / 4), -Math.PI / 4);
self.rotation += (targetRotation - self.rotation) * 0.1;
// Boundaries
if (self.y < 0) {
self.die(); // Trigger game over when the player goes off-screen at the top
}
if (self.y > 2732 - 250) {
self.die();
}
};
self.die = function () {
if (!self.alive) {
return;
}
self.alive = false;
LK.getSound('hit').play();
LK.effects.flashObject(self, 0xff0000, 500);
// Death spin animation
tween(self, {
rotation: Math.PI,
alpha: 0.7
}, {
duration: 1000,
onFinish: function onFinish() {
LK.showGameOver();
}
});
};
// Rotor blade animation
var rotor = self.attachAsset('helicopterRotor', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -body.height / 2
});
// Function to continuously rotate the rotor
function rotateRotor() {
tween(rotor, {
rotation: rotor.rotation + Math.PI * 2
}, {
duration: 500,
onFinish: rotateRotor
});
}
// Start the rotor animation
rotateRotor();
return self;
});
var Obstacle = Container.expand(function (topType, bottomType) {
var self = Container.call(this);
// Gap between top and bottom obstacles
// Top obstacle
var topObstacle = self.attachAsset(topType, {
anchorX: 0.5,
anchorY: 1.0,
y: 0
});
var bottomObstacle = self.attachAsset(bottomType, {
anchorX: 0.5,
anchorY: 0,
y: 0
});
self.speed = 3;
self.passed = false;
self.width = topObstacle.width;
self.setGapSize = function (size) {
bottomObstacle.y = topObstacle.y + size;
};
self.update = function () {
self.x -= self.speed;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpAsset = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.x -= baseObstacleSpeed;
if (self.x < -powerUpAsset.width) {
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB,
title: 'Fly High: Fuel or Fall'
});
/****
* Game Code
****/
// Game variables
var bird;
var obstacles = [];
var clouds = [];
var water;
var score = 0;
var highScore = storage.highScore || 0;
var baseObstacleSpeed = 3;
var baseFuelSpeed = baseObstacleSpeed; // Initialize fuel tank speed to match obstacles
var spawnInterval = 150;
var minGapSize = 400;
var gameStarted = false;
var scoreTxt;
var highScoreTxt;
var instructionsTxt;
// Initialize water (always at bottom of screen)
water = LK.getAsset('water', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2732 - 500
});
game.addChild(water);
// Initialize clouds
for (var i = 0; i < 5; i++) {
var cloud = new Cloud();
cloud.x = Math.random() * 2048;
cloud.y = 100 + Math.random() * 500;
clouds.push(cloud);
game.addChild(cloud);
}
// Initialize bird
bird = new Helicopter();
bird.x = 400;
bird.y = 2732 / 2;
game.addChild(bird);
// Initialize fuel bar
var fuelBar = new FuelBar();
fuelBar.x = 2048 - 20; // Position at top-right corner
fuelBar.y = 20;
// Score text
scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.y = 50; // Move the score text slightly down
LK.gui.top.addChild(scoreTxt);
// Initialize fuel bar
var fuelBar = new FuelBar();
fuelBar.x = scoreTxt.x + scoreTxt.width / 2 + 60; // Increase space between the fuel bar and fuel tank
fuelBar.y = 20;
LK.gui.top.addChild(fuelBar);
// High score text
highScoreTxt = new Text2('Best: ' + highScore, {
size: 60,
fill: 0xFFFFFF
});
highScoreTxt.anchor.set(0.5, 0);
highScoreTxt.y = 180;
LK.gui.top.addChild(highScoreTxt);
// Instructions text
instructionsTxt = new Text2('Tap to flap!', {
size: 80,
fill: 0xFFFFFF
});
instructionsTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionsTxt);
// Tap to flap function
function handleTap() {
if (!gameStarted) {
gameStarted = true;
instructionsTxt.visible = false;
LK.playMusic('bgMusic');
}
bird.flap();
}
// Obstacle spawning function
function spawnObstacle() {
var obstacleTypes = ['lollipop', 'birdNest', 'ufo', 'satellite', 'tree', 'balloon', 'bird', 'smily'];
var chosenType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];
var topObstacleType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];
var bottomObstacleType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];
var obstacle = new Obstacle(topObstacleType, bottomObstacleType);
// Set position
obstacle.x = 2048 + obstacle.width;
// Random vertical position for the gap, keeping it away from the very top and bottom
var minY = 100; // Ensure taller obstacles are fully visible
var maxY = 2732 - 500 - minGapSize - obstacle.children[0].height; // Adjust maxY to account for obstacle height
obstacle.y = minY + Math.random() * (maxY - minY);
// Adjust gap size based on score (gets narrower as score increases)
var gapSize = minGapSize + 300 - Math.min(200, score * 5);
obstacle.setGapSize(gapSize);
// Adjust speed based on score (gets faster as score increases)
obstacle.speed = baseObstacleSpeed + Math.min(5, score * 0.1);
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Handle tap or click
game.down = function (x, y, obj) {
handleTap();
bird.holdFlying = true;
};
// Handle release of mouse or touch
game.up = function (x, y, obj) {
bird.holdFlying = false;
};
// Game update loop
game.update = function () {
// Update clouds
for (var i = 0; i < clouds.length; i++) {
clouds[i].update();
}
if (!gameStarted) {
return;
}
// Spawn obstacles
if (LK.ticks % spawnInterval === 0) {
spawnObstacle();
}
// Spawn fuel collectible occasionally
if (LK.ticks % (spawnInterval * Math.max(3, 5 - Math.floor(score / 10))) === 0) {
if (Math.random() < 0.1) {
// 10% chance to spawn a power-up
var powerUp = new PowerUp();
powerUp.x = 2048 + 50;
powerUp.y = 150 + Math.random() * (2732 - 900 - minGapSize);
game.addChild(powerUp);
}
var fuelType = Math.random() < 0.8 ? 'smallFuelCollectible' : 'bigFuelCollectible'; // 80% chance for small, 20% for big
var fuelCollectible = new FuelCollectible(fuelType);
fuelCollectible.x = 2048 + 50;
fuelCollectible.y = 150 + Math.random() * (2732 - 900 - minGapSize);
game.addChild(fuelCollectible);
}
// Update obstacles
for (var j = obstacles.length - 1; j >= 0; j--) {
var obstacle = obstacles[j];
obstacle.update();
// Check if bird passed obstacle
if (!obstacle.passed && bird.x > obstacle.x + obstacle.width / 2) {
obstacle.passed = true;
score++;
LK.setScore(score);
scoreTxt.setText(score.toString());
LK.getSound('score').play();
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('Best: ' + highScore);
}
}
// Check for collision with bird
if (bird.alive) {
var topObstacleBounds = new Rectangle(obstacle.x - obstacle.width / 2, obstacle.y - obstacle.children[0].height, obstacle.width, obstacle.children[0].height);
var bottomObstacleBounds = new Rectangle(obstacle.x - obstacle.width / 2, obstacle.y + obstacle.children[1].y, obstacle.width, obstacle.children[1].height);
var birdBounds = new Rectangle(bird.x - 60, bird.y - 40, 120, 80);
// Check collision with top obstacle
if (birdBounds.x + birdBounds.width > topObstacleBounds.x && birdBounds.x < topObstacleBounds.x + topObstacleBounds.width && birdBounds.y + birdBounds.height > topObstacleBounds.y && birdBounds.y < topObstacleBounds.y + topObstacleBounds.height) {
bird.die();
}
// Check collision with bottom obstacle
if (birdBounds.x + birdBounds.width > bottomObstacleBounds.x && birdBounds.x < bottomObstacleBounds.x + bottomObstacleBounds.width && birdBounds.y < bottomObstacleBounds.y + bottomObstacleBounds.height && birdBounds.y + birdBounds.height > bottomObstacleBounds.y) {
bird.die();
}
}
// Remove obstacles that are off-screen
if (obstacle.x < -obstacle.width) {
obstacle.destroy();
obstacles.splice(j, 1);
}
}
// Update fuel bar
fuelBar.update();
// Check for fuel collection
var fuelCollectibles = game.children.filter(function (child) {
return child instanceof FuelCollectible;
});
for (var k = fuelCollectibles.length - 1; k >= 0; k--) {
var fuel = fuelCollectibles[k];
if (bird.intersects(fuel)) {
if (fuel.type === 'smallFuelCollectible') {
var smallFuelValue = 20 + Math.min(5, score * 0.1); // Scale with score
fuelBar.refill(smallFuelValue); // Refill fuel bar
LK.getSound('collectSmallFuel').play();
} else if (fuel.type === 'bigFuelCollectible') {
fuelBar.refill(fuelBar.maxFuel); // Instantly refill to 100%
LK.getSound('collectBigFuel').play();
// Add a satisfying animation for full refill
tween(fuelBar, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(fuelBar, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn
});
}
});
}
fuel.destroy();
}
}
// Check for power-up collection
var powerUps = game.children.filter(function (child) {
return child instanceof PowerUp;
});
for (var l = powerUps.length - 1; l >= 0; l--) {
var powerUp = powerUps[l];
if (bird.intersects(powerUp)) {
baseObstacleSpeed += 2; // Increase speed
LK.setTimeout(function () {
baseObstacleSpeed -= 2; // Revert speed after 10 seconds
}, 10000);
powerUp.destroy();
}
}
// Update bird
bird.update();
};
passing cloud images with single round shape with white color. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Create a cartoon-style lollipop tower as an obstacle in a helicopter game. The tower should look like a giant stacked swirl lollipop with a stick base, colorful stripes, and a playful vibe. Use bold outlines and a candy theme.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Make a cartoon-style birdhouse obstacle for a helicopter game. The birdhouse should have a wood texture, a circular hole, a tiny roof, and bright colors. Optionally add a little cartoon bird peeking out.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Design a cartoon-style bird flying sideways with big eyes and colorful feathers. The bird should look friendly, cute, and match a fun sky-themed game.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Generate a cartoon-style giant mushroom obstacle for a helicopter game. It should be colorful, exaggerated in size, and fun in appearance, with a thick stem and a big cap. Use soft shadows and vibrant tones.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A cute cartoon-style small fuel tank with rounded edges red color, glossy metal finish, and a little red cap. Add a glowing yellow outline to make it pop. It should look lightweight and collectible, floating gently in the air.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Powerup magnetic asset. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows