User prompt
Kingfisher Dive
Initial prompt
Title: Kingfisher fly 1. Create a new FRVR game with a vertical scrolling screen. Add a background (e.g., blue sky with clouds). Set up the game loop where the player controls a character by tapping to make it jump. 2. Add a flying character (a bird) at the center of the screen. The character should be affected by gravity, pulling it downwards. Implement a tap-to-flap mechanic where tapping makes the character jump up. 3. Generate randomly spaced vertical obstacles (like pipes or buildings) that the player must avoid. The obstacles should scroll from right to left and disappear after going off-screen. 4. Detect collisions between the player and obstacles. If the character touches an obstacle or the ground, trigger a game-over screen showing the final score. 5. Add a scoring system where the player earns 1 point for each obstacle successfully passed. Display the score at the top of the screen and update it dynamically. 6. Gradually increase the game's speed and reduce the gap between obstacles as the score increases to make the game more challenging. 7. Apply smooth animations for the bird’s flapping motion. Add slight rotation when the bird moves up or down. Include a soft fade-in effect when restarting the game. 8. Add sound effects for flapping, scoring, and collisions. Include background music that loops during gameplay with an option to mute/unmute.
/**** * 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