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