/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Aircraft = Container.expand(function () { var self = Container.call(this); var aircraftGraphics = self.attachAsset('aircraft', { anchorX: 0.5, anchorY: 0.5 }); var hitboxGraphics = self.attachAsset('hitboxAircraft', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.targetX = 0; self.targetY = 0; self.velocityX = 0; self.velocityY = 0; self.banking = 0; self.maxSpeed = 8; self.acceleration = 0.3; self.friction = 0.85; self.update = function () { // Calculate movement towards target var deltaX = self.targetX - self.x; var deltaY = self.targetY - self.y; // Apply acceleration towards target self.velocityX += deltaX * self.acceleration * 0.01; self.velocityY += deltaY * self.acceleration * 0.01; // Apply friction self.velocityX *= self.friction; self.velocityY *= self.friction; // Limit max speed var speed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY); if (speed > self.maxSpeed) { self.velocityX = self.velocityX / speed * self.maxSpeed; self.velocityY = self.velocityY / speed * self.maxSpeed; } // Update position self.x += self.velocityX; self.y += self.velocityY; // Banking animation based on horizontal movement var targetBanking = self.velocityX * 0.1; self.banking += (targetBanking - self.banking) * 0.1; aircraftGraphics.rotation = self.banking; // Keep aircraft within screen bounds if (self.x < 60) self.x = 60; if (self.x > 1988) self.x = 1988; if (self.y < 100) self.y = 100; if (self.y > 2632) self.y = 2632; // Create engine smoke trail if (LK.ticks % 3 == 0) { var smoke = new Smoke(); // Position smoke at aircraft engine (behind aircraft) smoke.x = self.x + Math.sin(self.banking) * 30 - Math.cos(self.banking) * 50; smoke.y = self.y - Math.sin(self.banking) * 50 + Math.cos(self.banking) * 30; game.addChild(smoke); smokes.push(smoke); } }; return self; }); var Bonus = Container.expand(function () { var self = Container.call(this); var bonusGraphics = self.attachAsset('bonus', { anchorX: 0.5, anchorY: 0.5 }); var hitboxGraphics = self.attachAsset('hitboxBonus', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.speed = 2.5; self.rotationSpeed = 0.1; self.update = function () { self.y += self.speed; bonusGraphics.rotation += self.rotationSpeed; }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); var hitboxGraphics = self.attachAsset('hitboxBullet', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.speed = -8; self.update = function () { self.y += self.speed; }; return self; }); var FastObstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('fastObstacle', { anchorX: 0.5, anchorY: 0.5 }); var hitboxGraphics = self.attachAsset('hitboxFastObstacle', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.speed = 5; self.zigzagSpeed = 3; self.zigzagOffset = 0; self.initialX = 0; self.update = function () { self.y += self.speed; self.zigzagOffset += 0.15; self.x = self.initialX + Math.sin(self.zigzagOffset) * 150; obstacleGraphics.rotation += 0.1; }; return self; }); var Fuel = Container.expand(function () { var self = Container.call(this); var fuelGraphics = self.attachAsset('fuel', { anchorX: 0.5, anchorY: 0.5 }); var hitboxGraphics = self.attachAsset('hitboxFuel', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.speed = 2; self.bobOffset = 0; self.update = function () { self.y += self.speed; self.bobOffset += 0.2; fuelGraphics.y = Math.sin(self.bobOffset) * 5; }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); var hitboxGraphics = self.attachAsset('hitboxObstacle', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.speed = 3; self.update = function () { self.y += self.speed; }; return self; }); var Smoke = Container.expand(function () { var self = Container.call(this); var smokeGraphics = self.attachAsset('smoke', { anchorX: 0.5, anchorY: 0.5 }); self.life = 60; self.maxLife = 60; self.velocityX = (Math.random() - 0.5) * 2; self.velocityY = Math.random() * 2 + 1; self.rotationSpeed = (Math.random() - 0.5) * 0.1; self.initialScale = 0.3 + Math.random() * 0.4; self.scaleX = self.initialScale; self.scaleY = self.initialScale; self.update = function () { self.life--; self.alpha = self.life / self.maxLife; // Smoke expands as it ages var ageRatio = 1 - self.life / self.maxLife; var scale = self.initialScale + ageRatio * 1.5; self.scaleX = scale; self.scaleY = scale; // Smoke drifts and rises self.x += self.velocityX; self.y += self.velocityY; self.velocityY += 0.1; // Slight upward acceleration smokeGraphics.rotation += self.rotationSpeed; // Fade to lighter gray as it ages var grayValue = Math.floor(0x88 + ageRatio * 0x44); smokeGraphics.tint = grayValue << 16 | grayValue << 8 | grayValue; }; return self; }); var Trail = Container.expand(function () { var self = Container.call(this); var trailGraphics = self.attachAsset('trail', { anchorX: 0.5, anchorY: 0.5 }); self.life = 30; self.maxLife = 30; self.update = function () { self.life--; self.alpha = self.life / self.maxLife; self.scaleX = self.alpha; self.scaleY = self.alpha; self.y += 1; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var aircraft = game.addChild(new Aircraft()); aircraft.x = 1024; aircraft.y = 2000; aircraft.targetX = aircraft.x; aircraft.targetY = aircraft.y; var obstacles = []; var fastObstacles = []; var fuels = []; var bonuses = []; var trails = []; var smokes = []; var bullets = []; var isShootingMode = false; var shootingEndTime = 0; var lastBulletSpawn = 0; var fuelLevel = 100; var maxFuel = 100; var gameSpeed = 1; var distance = 0; var lastObstacleSpawn = 0; var lastFastObstacleSpawn = 0; var lastFuelSpawn = 0; var lastBonusSpawn = 0; var isDragging = false; // UI Elements var scoreText = new Text2('Distance: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var fuelText = new Text2('Fuel: 100%', { size: 50, fill: 0xFFFFFF }); fuelText.anchor.set(1, 0); LK.gui.topRight.addChild(fuelText); // Event handlers game.down = function (x, y, obj) { isDragging = true; aircraft.targetX = x; aircraft.targetY = y; }; game.move = function (x, y, obj) { if (isDragging) { aircraft.targetX = x; aircraft.targetY = y; } }; game.up = function (x, y, obj) { isDragging = false; }; game.update = function () { // Update distance and speed distance += gameSpeed; gameSpeed += 0.001; // Fuel consumption fuelLevel -= 0.075; if (fuelLevel <= 0) { LK.showGameOver(); return; } // Spawn obstacles if (LK.ticks - lastObstacleSpawn > 60 - gameSpeed * 5) { var obstacle = new Obstacle(); obstacle.x = Math.random() * 1800 + 100; obstacle.y = -50; obstacle.speed = 2 + gameSpeed; obstacles.push(obstacle); game.addChild(obstacle); lastObstacleSpawn = LK.ticks; } // Spawn fast obstacles if (LK.ticks - lastFastObstacleSpawn > 120 - gameSpeed * 8) { var fastObstacle = new FastObstacle(); fastObstacle.x = Math.random() * 1400 + 300; fastObstacle.initialX = fastObstacle.x; fastObstacle.y = -50; fastObstacle.speed = 4 + gameSpeed * 1.5; fastObstacles.push(fastObstacle); game.addChild(fastObstacle); lastFastObstacleSpawn = LK.ticks; } // Spawn fuel if (LK.ticks - lastFuelSpawn > 180) { var fuel = new Fuel(); fuel.x = Math.random() * 1800 + 100; fuel.y = -50; fuel.speed = 2 + gameSpeed * 0.5; fuels.push(fuel); game.addChild(fuel); lastFuelSpawn = LK.ticks; } // Spawn bonus if (LK.ticks - lastBonusSpawn > 300) { var bonus = new Bonus(); bonus.x = Math.random() * 1800 + 100; bonus.y = -50; bonus.speed = 2 + gameSpeed * 0.5; bonuses.push(bonus); game.addChild(bonus); lastBonusSpawn = LK.ticks; } // Update and check obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; if (obstacle.lastY === undefined) obstacle.lastY = obstacle.y; if (obstacle.lastIntersecting === undefined) obstacle.lastIntersecting = false; // Remove off-screen obstacles if (obstacle.lastY < 2800 && obstacle.y >= 2800) { obstacle.destroy(); obstacles.splice(i, 1); continue; } // Check pixel-perfect collision with aircraft var deltaX = Math.abs(aircraft.x - obstacle.x); var deltaY = Math.abs(aircraft.y - obstacle.y); var currentIntersecting = deltaX < 75 && deltaY < 40; // Tight pixel collision bounds if (!obstacle.lastIntersecting && currentIntersecting) { LK.getSound('explosion').play(); LK.effects.flashScreen(0xff0000, 1000); // Aircraft explosion animation tween(aircraft, { scaleX: 2, scaleY: 2, alpha: 0, rotation: Math.PI * 2 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { LK.showGameOver(); } }); return; } obstacle.lastY = obstacle.y; obstacle.lastIntersecting = currentIntersecting; } // Update and check fast obstacles for (var i = fastObstacles.length - 1; i >= 0; i--) { var fastObstacle = fastObstacles[i]; if (fastObstacle.lastY === undefined) fastObstacle.lastY = fastObstacle.y; if (fastObstacle.lastIntersecting === undefined) fastObstacle.lastIntersecting = false; // Remove off-screen fast obstacles if (fastObstacle.lastY < 2800 && fastObstacle.y >= 2800) { fastObstacle.destroy(); fastObstacles.splice(i, 1); continue; } // Check pixel-perfect collision with aircraft var deltaX = Math.abs(aircraft.x - fastObstacle.x); var deltaY = Math.abs(aircraft.y - fastObstacle.y); var currentIntersecting = deltaX < 65 && deltaY < 60; // Tight pixel collision bounds for fast obstacle if (!fastObstacle.lastIntersecting && currentIntersecting) { LK.getSound('explosion').play(); LK.effects.flashScreen(0xff0000, 1000); // Aircraft explosion animation tween(aircraft, { scaleX: 2, scaleY: 2, alpha: 0, rotation: Math.PI * 2 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { LK.showGameOver(); } }); return; } fastObstacle.lastY = fastObstacle.y; fastObstacle.lastIntersecting = currentIntersecting; } // Update and check fuel pickups for (var i = fuels.length - 1; i >= 0; i--) { var fuel = fuels[i]; if (fuel.lastY === undefined) fuel.lastY = fuel.y; if (fuel.lastIntersecting === undefined) fuel.lastIntersecting = false; // Remove off-screen fuel if (fuel.lastY < 2800 && fuel.y >= 2800) { fuel.destroy(); fuels.splice(i, 1); continue; } // Check collection var currentIntersecting = fuel.intersects(aircraft); if (!fuel.lastIntersecting && currentIntersecting) { LK.getSound('collect').play(); fuelLevel = Math.min(fuelLevel + 25, maxFuel); LK.setScore(LK.getScore() + 10); fuel.destroy(); fuels.splice(i, 1); continue; } fuel.lastY = fuel.y; fuel.lastIntersecting = currentIntersecting; } // Update and check bonus items for (var i = bonuses.length - 1; i >= 0; i--) { var bonus = bonuses[i]; if (bonus.lastY === undefined) bonus.lastY = bonus.y; if (bonus.lastIntersecting === undefined) bonus.lastIntersecting = false; // Remove off-screen bonus if (bonus.lastY < 2800 && bonus.y >= 2800) { bonus.destroy(); bonuses.splice(i, 1); continue; } // Check collection var currentIntersecting = bonus.intersects(aircraft); if (!bonus.lastIntersecting && currentIntersecting) { LK.getSound('collect').play(); LK.setScore(LK.getScore() + 50); // Activate shooting mode for 3 seconds isShootingMode = true; shootingEndTime = LK.ticks + 180; // 3 seconds at 60 FPS // Flash aircraft to indicate power-up tween(aircraft, { tint: 0xff0000 }, { duration: 200, onFinish: function onFinish() { tween(aircraft, { tint: 0xffffff }, { duration: 200 }); } }); bonus.destroy(); bonuses.splice(i, 1); continue; } bonus.lastY = bonus.y; bonus.lastIntersecting = currentIntersecting; } // Handle shooting mode if (isShootingMode) { if (LK.ticks >= shootingEndTime) { isShootingMode = false; } // Spawn bullets if (LK.ticks - lastBulletSpawn > 10) { // Shoot every 10 ticks var bullet = new Bullet(); bullet.x = aircraft.x; bullet.y = aircraft.y - 50; bullets.push(bullet); game.addChild(bullet); lastBulletSpawn = LK.ticks; } } // Update and check bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.lastY === undefined) bullet.lastY = bullet.y; // Remove off-screen bullets if (bullet.lastY >= -50 && bullet.y < -50) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check bullet collision with obstacles for (var j = obstacles.length - 1; j >= 0; j--) { var obstacle = obstacles[j]; if (bullet.intersects(obstacle)) { // Destroy both bullet and obstacle LK.getSound('explosion').play(); LK.setScore(LK.getScore() + 20); bullet.destroy(); bullets.splice(i, 1); obstacle.destroy(); obstacles.splice(j, 1); break; } } // Check bullet collision with fast obstacles for (var j = fastObstacles.length - 1; j >= 0; j--) { var fastObstacle = fastObstacles[j]; if (bullet.intersects(fastObstacle)) { // Destroy both bullet and fast obstacle (worth more points) LK.getSound('explosion').play(); LK.setScore(LK.getScore() + 30); bullet.destroy(); bullets.splice(i, 1); fastObstacle.destroy(); fastObstacles.splice(j, 1); break; } } bullet.lastY = bullet.y; } // Update and clean up trails for (var i = trails.length - 1; i >= 0; i--) { var trail = trails[i]; if (trail.life <= 0) { trail.destroy(); trails.splice(i, 1); } } // Update and clean up smoke particles for (var i = smokes.length - 1; i >= 0; i--) { var smoke = smokes[i]; if (smoke.life <= 0) { smoke.destroy(); smokes.splice(i, 1); } } // Update UI scoreText.setText('Distance: ' + Math.floor(distance)); fuelText.setText('Fuel: ' + Math.floor(fuelLevel) + '%'); // Update score based on distance LK.setScore(Math.floor(distance / 10)); }; // Start background music LK.playMusic('bgmusic');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Aircraft = Container.expand(function () {
var self = Container.call(this);
var aircraftGraphics = self.attachAsset('aircraft', {
anchorX: 0.5,
anchorY: 0.5
});
var hitboxGraphics = self.attachAsset('hitboxAircraft', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.targetX = 0;
self.targetY = 0;
self.velocityX = 0;
self.velocityY = 0;
self.banking = 0;
self.maxSpeed = 8;
self.acceleration = 0.3;
self.friction = 0.85;
self.update = function () {
// Calculate movement towards target
var deltaX = self.targetX - self.x;
var deltaY = self.targetY - self.y;
// Apply acceleration towards target
self.velocityX += deltaX * self.acceleration * 0.01;
self.velocityY += deltaY * self.acceleration * 0.01;
// Apply friction
self.velocityX *= self.friction;
self.velocityY *= self.friction;
// Limit max speed
var speed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
if (speed > self.maxSpeed) {
self.velocityX = self.velocityX / speed * self.maxSpeed;
self.velocityY = self.velocityY / speed * self.maxSpeed;
}
// Update position
self.x += self.velocityX;
self.y += self.velocityY;
// Banking animation based on horizontal movement
var targetBanking = self.velocityX * 0.1;
self.banking += (targetBanking - self.banking) * 0.1;
aircraftGraphics.rotation = self.banking;
// Keep aircraft within screen bounds
if (self.x < 60) self.x = 60;
if (self.x > 1988) self.x = 1988;
if (self.y < 100) self.y = 100;
if (self.y > 2632) self.y = 2632;
// Create engine smoke trail
if (LK.ticks % 3 == 0) {
var smoke = new Smoke();
// Position smoke at aircraft engine (behind aircraft)
smoke.x = self.x + Math.sin(self.banking) * 30 - Math.cos(self.banking) * 50;
smoke.y = self.y - Math.sin(self.banking) * 50 + Math.cos(self.banking) * 30;
game.addChild(smoke);
smokes.push(smoke);
}
};
return self;
});
var Bonus = Container.expand(function () {
var self = Container.call(this);
var bonusGraphics = self.attachAsset('bonus', {
anchorX: 0.5,
anchorY: 0.5
});
var hitboxGraphics = self.attachAsset('hitboxBonus', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.speed = 2.5;
self.rotationSpeed = 0.1;
self.update = function () {
self.y += self.speed;
bonusGraphics.rotation += self.rotationSpeed;
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
var hitboxGraphics = self.attachAsset('hitboxBullet', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.speed = -8;
self.update = function () {
self.y += self.speed;
};
return self;
});
var FastObstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('fastObstacle', {
anchorX: 0.5,
anchorY: 0.5
});
var hitboxGraphics = self.attachAsset('hitboxFastObstacle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.speed = 5;
self.zigzagSpeed = 3;
self.zigzagOffset = 0;
self.initialX = 0;
self.update = function () {
self.y += self.speed;
self.zigzagOffset += 0.15;
self.x = self.initialX + Math.sin(self.zigzagOffset) * 150;
obstacleGraphics.rotation += 0.1;
};
return self;
});
var Fuel = Container.expand(function () {
var self = Container.call(this);
var fuelGraphics = self.attachAsset('fuel', {
anchorX: 0.5,
anchorY: 0.5
});
var hitboxGraphics = self.attachAsset('hitboxFuel', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.speed = 2;
self.bobOffset = 0;
self.update = function () {
self.y += self.speed;
self.bobOffset += 0.2;
fuelGraphics.y = Math.sin(self.bobOffset) * 5;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
var hitboxGraphics = self.attachAsset('hitboxObstacle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.speed = 3;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Smoke = Container.expand(function () {
var self = Container.call(this);
var smokeGraphics = self.attachAsset('smoke', {
anchorX: 0.5,
anchorY: 0.5
});
self.life = 60;
self.maxLife = 60;
self.velocityX = (Math.random() - 0.5) * 2;
self.velocityY = Math.random() * 2 + 1;
self.rotationSpeed = (Math.random() - 0.5) * 0.1;
self.initialScale = 0.3 + Math.random() * 0.4;
self.scaleX = self.initialScale;
self.scaleY = self.initialScale;
self.update = function () {
self.life--;
self.alpha = self.life / self.maxLife;
// Smoke expands as it ages
var ageRatio = 1 - self.life / self.maxLife;
var scale = self.initialScale + ageRatio * 1.5;
self.scaleX = scale;
self.scaleY = scale;
// Smoke drifts and rises
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += 0.1; // Slight upward acceleration
smokeGraphics.rotation += self.rotationSpeed;
// Fade to lighter gray as it ages
var grayValue = Math.floor(0x88 + ageRatio * 0x44);
smokeGraphics.tint = grayValue << 16 | grayValue << 8 | grayValue;
};
return self;
});
var Trail = Container.expand(function () {
var self = Container.call(this);
var trailGraphics = self.attachAsset('trail', {
anchorX: 0.5,
anchorY: 0.5
});
self.life = 30;
self.maxLife = 30;
self.update = function () {
self.life--;
self.alpha = self.life / self.maxLife;
self.scaleX = self.alpha;
self.scaleY = self.alpha;
self.y += 1;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var aircraft = game.addChild(new Aircraft());
aircraft.x = 1024;
aircraft.y = 2000;
aircraft.targetX = aircraft.x;
aircraft.targetY = aircraft.y;
var obstacles = [];
var fastObstacles = [];
var fuels = [];
var bonuses = [];
var trails = [];
var smokes = [];
var bullets = [];
var isShootingMode = false;
var shootingEndTime = 0;
var lastBulletSpawn = 0;
var fuelLevel = 100;
var maxFuel = 100;
var gameSpeed = 1;
var distance = 0;
var lastObstacleSpawn = 0;
var lastFastObstacleSpawn = 0;
var lastFuelSpawn = 0;
var lastBonusSpawn = 0;
var isDragging = false;
// UI Elements
var scoreText = new Text2('Distance: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var fuelText = new Text2('Fuel: 100%', {
size: 50,
fill: 0xFFFFFF
});
fuelText.anchor.set(1, 0);
LK.gui.topRight.addChild(fuelText);
// Event handlers
game.down = function (x, y, obj) {
isDragging = true;
aircraft.targetX = x;
aircraft.targetY = y;
};
game.move = function (x, y, obj) {
if (isDragging) {
aircraft.targetX = x;
aircraft.targetY = y;
}
};
game.up = function (x, y, obj) {
isDragging = false;
};
game.update = function () {
// Update distance and speed
distance += gameSpeed;
gameSpeed += 0.001;
// Fuel consumption
fuelLevel -= 0.075;
if (fuelLevel <= 0) {
LK.showGameOver();
return;
}
// Spawn obstacles
if (LK.ticks - lastObstacleSpawn > 60 - gameSpeed * 5) {
var obstacle = new Obstacle();
obstacle.x = Math.random() * 1800 + 100;
obstacle.y = -50;
obstacle.speed = 2 + gameSpeed;
obstacles.push(obstacle);
game.addChild(obstacle);
lastObstacleSpawn = LK.ticks;
}
// Spawn fast obstacles
if (LK.ticks - lastFastObstacleSpawn > 120 - gameSpeed * 8) {
var fastObstacle = new FastObstacle();
fastObstacle.x = Math.random() * 1400 + 300;
fastObstacle.initialX = fastObstacle.x;
fastObstacle.y = -50;
fastObstacle.speed = 4 + gameSpeed * 1.5;
fastObstacles.push(fastObstacle);
game.addChild(fastObstacle);
lastFastObstacleSpawn = LK.ticks;
}
// Spawn fuel
if (LK.ticks - lastFuelSpawn > 180) {
var fuel = new Fuel();
fuel.x = Math.random() * 1800 + 100;
fuel.y = -50;
fuel.speed = 2 + gameSpeed * 0.5;
fuels.push(fuel);
game.addChild(fuel);
lastFuelSpawn = LK.ticks;
}
// Spawn bonus
if (LK.ticks - lastBonusSpawn > 300) {
var bonus = new Bonus();
bonus.x = Math.random() * 1800 + 100;
bonus.y = -50;
bonus.speed = 2 + gameSpeed * 0.5;
bonuses.push(bonus);
game.addChild(bonus);
lastBonusSpawn = LK.ticks;
}
// Update and check obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.lastY === undefined) obstacle.lastY = obstacle.y;
if (obstacle.lastIntersecting === undefined) obstacle.lastIntersecting = false;
// Remove off-screen obstacles
if (obstacle.lastY < 2800 && obstacle.y >= 2800) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Check pixel-perfect collision with aircraft
var deltaX = Math.abs(aircraft.x - obstacle.x);
var deltaY = Math.abs(aircraft.y - obstacle.y);
var currentIntersecting = deltaX < 75 && deltaY < 40; // Tight pixel collision bounds
if (!obstacle.lastIntersecting && currentIntersecting) {
LK.getSound('explosion').play();
LK.effects.flashScreen(0xff0000, 1000);
// Aircraft explosion animation
tween(aircraft, {
scaleX: 2,
scaleY: 2,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
LK.showGameOver();
}
});
return;
}
obstacle.lastY = obstacle.y;
obstacle.lastIntersecting = currentIntersecting;
}
// Update and check fast obstacles
for (var i = fastObstacles.length - 1; i >= 0; i--) {
var fastObstacle = fastObstacles[i];
if (fastObstacle.lastY === undefined) fastObstacle.lastY = fastObstacle.y;
if (fastObstacle.lastIntersecting === undefined) fastObstacle.lastIntersecting = false;
// Remove off-screen fast obstacles
if (fastObstacle.lastY < 2800 && fastObstacle.y >= 2800) {
fastObstacle.destroy();
fastObstacles.splice(i, 1);
continue;
}
// Check pixel-perfect collision with aircraft
var deltaX = Math.abs(aircraft.x - fastObstacle.x);
var deltaY = Math.abs(aircraft.y - fastObstacle.y);
var currentIntersecting = deltaX < 65 && deltaY < 60; // Tight pixel collision bounds for fast obstacle
if (!fastObstacle.lastIntersecting && currentIntersecting) {
LK.getSound('explosion').play();
LK.effects.flashScreen(0xff0000, 1000);
// Aircraft explosion animation
tween(aircraft, {
scaleX: 2,
scaleY: 2,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
LK.showGameOver();
}
});
return;
}
fastObstacle.lastY = fastObstacle.y;
fastObstacle.lastIntersecting = currentIntersecting;
}
// Update and check fuel pickups
for (var i = fuels.length - 1; i >= 0; i--) {
var fuel = fuels[i];
if (fuel.lastY === undefined) fuel.lastY = fuel.y;
if (fuel.lastIntersecting === undefined) fuel.lastIntersecting = false;
// Remove off-screen fuel
if (fuel.lastY < 2800 && fuel.y >= 2800) {
fuel.destroy();
fuels.splice(i, 1);
continue;
}
// Check collection
var currentIntersecting = fuel.intersects(aircraft);
if (!fuel.lastIntersecting && currentIntersecting) {
LK.getSound('collect').play();
fuelLevel = Math.min(fuelLevel + 25, maxFuel);
LK.setScore(LK.getScore() + 10);
fuel.destroy();
fuels.splice(i, 1);
continue;
}
fuel.lastY = fuel.y;
fuel.lastIntersecting = currentIntersecting;
}
// Update and check bonus items
for (var i = bonuses.length - 1; i >= 0; i--) {
var bonus = bonuses[i];
if (bonus.lastY === undefined) bonus.lastY = bonus.y;
if (bonus.lastIntersecting === undefined) bonus.lastIntersecting = false;
// Remove off-screen bonus
if (bonus.lastY < 2800 && bonus.y >= 2800) {
bonus.destroy();
bonuses.splice(i, 1);
continue;
}
// Check collection
var currentIntersecting = bonus.intersects(aircraft);
if (!bonus.lastIntersecting && currentIntersecting) {
LK.getSound('collect').play();
LK.setScore(LK.getScore() + 50);
// Activate shooting mode for 3 seconds
isShootingMode = true;
shootingEndTime = LK.ticks + 180; // 3 seconds at 60 FPS
// Flash aircraft to indicate power-up
tween(aircraft, {
tint: 0xff0000
}, {
duration: 200,
onFinish: function onFinish() {
tween(aircraft, {
tint: 0xffffff
}, {
duration: 200
});
}
});
bonus.destroy();
bonuses.splice(i, 1);
continue;
}
bonus.lastY = bonus.y;
bonus.lastIntersecting = currentIntersecting;
}
// Handle shooting mode
if (isShootingMode) {
if (LK.ticks >= shootingEndTime) {
isShootingMode = false;
}
// Spawn bullets
if (LK.ticks - lastBulletSpawn > 10) {
// Shoot every 10 ticks
var bullet = new Bullet();
bullet.x = aircraft.x;
bullet.y = aircraft.y - 50;
bullets.push(bullet);
game.addChild(bullet);
lastBulletSpawn = LK.ticks;
}
}
// Update and check bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.lastY === undefined) bullet.lastY = bullet.y;
// Remove off-screen bullets
if (bullet.lastY >= -50 && bullet.y < -50) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet collision with obstacles
for (var j = obstacles.length - 1; j >= 0; j--) {
var obstacle = obstacles[j];
if (bullet.intersects(obstacle)) {
// Destroy both bullet and obstacle
LK.getSound('explosion').play();
LK.setScore(LK.getScore() + 20);
bullet.destroy();
bullets.splice(i, 1);
obstacle.destroy();
obstacles.splice(j, 1);
break;
}
}
// Check bullet collision with fast obstacles
for (var j = fastObstacles.length - 1; j >= 0; j--) {
var fastObstacle = fastObstacles[j];
if (bullet.intersects(fastObstacle)) {
// Destroy both bullet and fast obstacle (worth more points)
LK.getSound('explosion').play();
LK.setScore(LK.getScore() + 30);
bullet.destroy();
bullets.splice(i, 1);
fastObstacle.destroy();
fastObstacles.splice(j, 1);
break;
}
}
bullet.lastY = bullet.y;
}
// Update and clean up trails
for (var i = trails.length - 1; i >= 0; i--) {
var trail = trails[i];
if (trail.life <= 0) {
trail.destroy();
trails.splice(i, 1);
}
}
// Update and clean up smoke particles
for (var i = smokes.length - 1; i >= 0; i--) {
var smoke = smokes[i];
if (smoke.life <= 0) {
smoke.destroy();
smokes.splice(i, 1);
}
}
// Update UI
scoreText.setText('Distance: ' + Math.floor(distance));
fuelText.setText('Fuel: ' + Math.floor(fuelLevel) + '%');
// Update score based on distance
LK.setScore(Math.floor(distance / 10));
};
// Start background music
LK.playMusic('bgmusic');
benzin bidonu. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
kuş bakışı bird. In-Game asset. High contrast. No shadows
askeri kuşbakışı uçak. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
bullet. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
smoke. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
arkasından alev çıkan nükleer enerji füzesi. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat