/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Airplane = Container.expand(function () { var self = Container.call(this); var airplaneGraphics = self.attachAsset('airplane', { anchorX: 0.5, anchorY: 0.5 }); self.velocityY = 0; self.gravity = 0.5; self.jumpPower = -35; self.speed = 4; self.lastY = 0; self.lastColliding = false; self.jump = function () { if (!isPressed) { self.velocityY = self.jumpPower; LK.getSound('engine').play(); } isPressed = true; }; self.update = function () { self.lastY = self.y; // Apply gravity only when not continuously pressed if (!isPressed) { self.velocityY += self.gravity; } else { // Fly straight when continuously pressed self.velocityY = 0; } self.y += self.velocityY; // Keep airplane level at all times airplaneGraphics.rotation = 0; // Keep airplane within bounds - only lower bound if (self.y > 2600) { self.y = 2600; self.velocityY = 0; } }; return self; }); var SecondAirplane = Container.expand(function () { var self = Container.call(this); var airplaneGraphics = self.attachAsset('airplane', { anchorX: 0.5, anchorY: 0.5 }); self.velocityY = 0; self.gravity = 0.5; self.jumpPower = -35; self.speed = 4; self.lastY = 0; self.lastColliding = false; self.jump = function () { if (!isPressed) { self.velocityY = self.jumpPower; LK.getSound('engine').play(); } isPressed = true; }; self.update = function () { self.lastY = self.y; // Apply gravity only when not continuously pressed if (!isPressed) { self.velocityY += self.gravity; } else { // Fly straight when continuously pressed self.velocityY = 0; } self.y += self.velocityY; // Keep airplane level at all times airplaneGraphics.rotation = 0; // Keep airplane within bounds - only lower bound if (self.y > 2600) { self.y = 2600; self.velocityY = 0; } }; return self; }); var Tower = Container.expand(function () { var self = Container.call(this); var towerGraphics = self.attachAsset('tower', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Create a simple blue background game.setBackgroundColor(0x4169E1); // Add ground var ground = game.addChild(LK.getAsset('ground', { anchorX: 0.5, anchorY: 1.0 })); ground.x = 1024; ground.y = 2732; // Add sun var sun = game.addChild(LK.getAsset('sun', { anchorX: 0.5, anchorY: 0.5 })); sun.x = 1800; sun.y = 200; var scoreTxt = new Text2('Score: 0', { size: 60, fill: 0x000000 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var livesTxt = new Text2('Lives: 2', { size: 60, fill: 0x000000 }); livesTxt.anchor.set(0.5, 0); livesTxt.y = 80; // Position below score LK.gui.top.addChild(livesTxt); var airplane = game.addChild(new Airplane()); airplane.x = 200; airplane.y = 1366; var secondAirplane = game.addChild(new SecondAirplane()); secondAirplane.x = -200; // Start behind the first airplane secondAirplane.y = 1366; var firstAirplaneCrashed = false; var secondAirplaneCrashed = false; var activeAirplane = airplane; // Track which airplane is currently controlled var towers = []; var score = 0; var lives = 2; var gameSpeed = 100; var isPressed = false; var touchX = 0; var touchY = 0; var isTouching = false; var clouds = []; // Create clouds in the sky for (var i = 0; i < 4; i++) { var cloud = game.addChild(LK.getAsset('cloud', { anchorX: 0.5, anchorY: 0.5 })); cloud.x = Math.random() * 3000 + 500; cloud.y = Math.random() * 800 + 200; cloud.alpha = 0.7; cloud.speed = 100; clouds.push(cloud); } var joystickCenter = { x: 300, y: 2400 }; // Add joystick visual elements var joystickBase = game.addChild(LK.getAsset('joystick_base', { anchorX: 0.5, anchorY: 0.5 })); joystickBase.x = joystickCenter.x; joystickBase.y = joystickCenter.y; joystickBase.alpha = 0.6; var joystickKnob = game.addChild(LK.getAsset('joystick_knob', { anchorX: 0.5, anchorY: 0.5 })); joystickKnob.x = joystickCenter.x; joystickKnob.y = joystickCenter.y; joystickKnob.alpha = 0.8; function updateScore() { scoreTxt.setText('Score: ' + score); livesTxt.setText('Lives: ' + lives); } function checkCollisions() { // Check collision for first airplane (if not crashed) if (!firstAirplaneCrashed) { var airplaneNoseX = airplane.x + 200; // Airplane nose is about 200px from center var airplaneLeftWing = airplane.x - 200; // Left wing edge var airplaneRightWing = airplane.x + 200; // Right wing edge var airplaneTop = airplane.y - 125; // Top of airplane var airplaneBottom = airplane.y + 125; // Bottom of airplane var isColliding = false; // Check collision with all towers for (var i = 0; i < towers.length; i++) { var tower = towers[i]; var towerLeft = tower.x - 50; // Tower width consideration var towerRight = tower.x + 50; var towerTop = tower.y - 750; // Half tower height from center var towerBottom = tower.y + 750; // Half tower height from center var currentIntersecting = airplaneNoseX >= towerLeft && airplaneLeftWing <= towerRight && airplaneBottom >= towerTop && airplaneTop <= towerBottom; if (currentIntersecting) { isColliding = true; break; } } if (!airplane.lastColliding && isColliding) { // First airplane hit a tower - create bomb explosion effect LK.getSound('crash').play(); // Flash the airplane red for explosion effect LK.effects.flashObject(airplane, 0xff0000, 500); // Create multiple explosion circles for bomb effect at airplane position var explosionCircles = []; for (var i = 0; i < 12; i++) { var circle = game.addChild(LK.getAsset('explosion_circle', { anchorX: 0.5, anchorY: 0.5 })); circle.x = airplane.x + (Math.random() - 0.5) * 300; circle.y = airplane.y + (Math.random() - 0.5) * 300; circle.alpha = 0.8; circle.tint = i % 2 === 0 ? 0xff4500 : 0xffa500; // Alternate between orange and yellow explosionCircles.push(circle); // Animate each circle expanding and fading tween(circle, { scaleX: 8 + Math.random() * 4, scaleY: 8 + Math.random() * 4, alpha: 0 }, { duration: 400 + Math.random() * 200, easing: tween.easeOut, onFinish: function onFinish() { circle.destroy(); } }); } // First airplane crashed, lose 1 life lives--; updateScore(); firstAirplaneCrashed = true; activeAirplane = secondAirplane; // Hide the first airplane airplane.alpha = 0; // Screen shake effect using tween tween(game, { x: 10 }, { duration: 50, onFinish: function onFinish() { tween(game, { x: -10 }, { duration: 50, onFinish: function onFinish() { tween(game, { x: 5 }, { duration: 50, onFinish: function onFinish() { tween(game, { x: 0 }, { duration: 50 }); } }); } }); } }); } airplane.lastColliding = isColliding; } // Check collision for second airplane (if not crashed) if (!secondAirplaneCrashed) { var airplaneNoseX = secondAirplane.x + 200; // Airplane nose is about 200px from center var airplaneLeftWing = secondAirplane.x - 200; // Left wing edge var airplaneRightWing = secondAirplane.x + 200; // Right wing edge var airplaneTop = secondAirplane.y - 125; // Top of airplane var airplaneBottom = secondAirplane.y + 125; // Bottom of airplane var isColliding = false; // Check collision with all towers for (var i = 0; i < towers.length; i++) { var tower = towers[i]; var towerLeft = tower.x - 50; // Tower width consideration var towerRight = tower.x + 50; var towerTop = tower.y - 750; // Half tower height from center var towerBottom = tower.y + 750; // Half tower height from center var currentIntersecting = airplaneNoseX >= towerLeft && airplaneLeftWing <= towerRight && airplaneBottom >= towerTop && airplaneTop <= towerBottom; if (currentIntersecting) { isColliding = true; break; } } if (!secondAirplane.lastColliding && isColliding) { // Second airplane hit a tower - create bomb explosion effect LK.getSound('crash').play(); // Flash the airplane red for explosion effect LK.effects.flashObject(secondAirplane, 0xff0000, 500); // Create multiple explosion circles for bomb effect at airplane position var explosionCircles = []; for (var i = 0; i < 12; i++) { var circle = game.addChild(LK.getAsset('explosion_circle', { anchorX: 0.5, anchorY: 0.5 })); circle.x = secondAirplane.x + (Math.random() - 0.5) * 300; circle.y = secondAirplane.y + (Math.random() - 0.5) * 300; circle.alpha = 0.8; circle.tint = i % 2 === 0 ? 0xff4500 : 0xffa500; // Alternate between orange and yellow explosionCircles.push(circle); // Animate each circle expanding and fading tween(circle, { scaleX: 8 + Math.random() * 4, scaleY: 8 + Math.random() * 4, alpha: 0 }, { duration: 400 + Math.random() * 200, easing: tween.easeOut, onFinish: function onFinish() { circle.destroy(); } }); } // Second airplane crashed, lose last life and game over lives--; updateScore(); secondAirplaneCrashed = true; // Screen shake effect using tween tween(game, { x: 10 }, { duration: 50, onFinish: function onFinish() { tween(game, { x: -10 }, { duration: 50, onFinish: function onFinish() { tween(game, { x: 5 }, { duration: 50, onFinish: function onFinish() { tween(game, { x: 0 }, { duration: 50, onFinish: function onFinish() { // Show game over after explosion effects complete LK.showGameOver(); } }); } }); } }); } }); } secondAirplane.lastColliding = isColliding; } // Check if airplane passed towers for scoring - only count active airplane var currentAirplane = firstAirplaneCrashed ? secondAirplane : airplane; for (var i = 0; i < towers.length; i++) { var tower = towers[i]; if (!tower.scored && currentAirplane.x > tower.x) { score += 10; tower.scored = true; updateScore(); } } } game.down = function (x, y, obj) { // Only respond to touches in the joystick area var distanceFromJoystick = Math.sqrt((x - joystickCenter.x) * (x - joystickCenter.x) + (y - joystickCenter.y) * (y - joystickCenter.y)); if (distanceFromJoystick <= 150) { touchX = x; touchY = y; isTouching = true; activeAirplane.jump(); } }; game.move = function (x, y, obj) { if (isTouching) { touchX = x; touchY = y; } }; game.up = function (x, y, obj) { isPressed = false; isTouching = false; }; game.update = function () { airplane.lastX = airplane.x; secondAirplane.lastX = secondAirplane.x; // Move towers left for side-scrolling effect for (var i = 0; i < towers.length; i++) { towers[i].x -= gameSpeed; } // Add new towers when needed - but only after game has started (score > 0 or some delay) if (LK.ticks > 180 && (towers.length === 0 || towers[towers.length - 1].x < 2048 + 50000)) { var newTower = game.addChild(new Tower()); newTower.x = towers.length > 0 ? towers[towers.length - 1].x + 50000 : 2200; // Reduced spacing by 1/3 newTower.y = 2732 - 750; // Adjust Y position so tower touches ground (2732 - half tower height) towers.push(newTower); } // Remove towers that are off-screen for (var i = towers.length - 1; i >= 0; i--) { if (towers[i].x < -200) { towers[i].destroy(); towers.splice(i, 1); } } checkCollisions(); // Move clouds quickly across the sky for (var i = 0; i < clouds.length; i++) { clouds[i].x -= clouds[i].speed; // Reset cloud position when it goes off-screen if (clouds[i].x < -200) { clouds[i].x = 2300; clouds[i].y = Math.random() * 800 + 200; } } // Joystick control - move airplane vertically only if (isTouching) { var deltaY = touchY - joystickCenter.y; // Limit joystick knob movement vertically only var maxRange = 100; if (deltaY > maxRange) { deltaY = maxRange; } else if (deltaY < -maxRange) { deltaY = -maxRange; } // Update joystick knob position - vertical movement only joystickKnob.x = joystickCenter.x; joystickKnob.y = joystickCenter.y + deltaY; // Move airplane vertically based on joystick input var moveScale = 4; var targetY = 1366 - deltaY * moveScale; // Inverted Y-axis // Keep airplane within screen bounds vertically activeAirplane.y = Math.max(-500, Math.min(2632, targetY)); } else { // Reset joystick knob to center when not touching joystickKnob.x = joystickCenter.x; joystickKnob.y = joystickCenter.y; } // Keep airplane centered horizontally at all times if (!firstAirplaneCrashed) { airplane.x = 1024; // Second airplane follows behind the first airplane secondAirplane.x = airplane.x - 2000; // 2000px behind - much further back secondAirplane.y = airplane.y - 400; // 400px higher than first airplane } else { // After crash, control the second airplane secondAirplane.x = 1024; } // Win condition if (score >= 100) { LK.showYouWin(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Airplane = Container.expand(function () {
var self = Container.call(this);
var airplaneGraphics = self.attachAsset('airplane', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityY = 0;
self.gravity = 0.5;
self.jumpPower = -35;
self.speed = 4;
self.lastY = 0;
self.lastColliding = false;
self.jump = function () {
if (!isPressed) {
self.velocityY = self.jumpPower;
LK.getSound('engine').play();
}
isPressed = true;
};
self.update = function () {
self.lastY = self.y;
// Apply gravity only when not continuously pressed
if (!isPressed) {
self.velocityY += self.gravity;
} else {
// Fly straight when continuously pressed
self.velocityY = 0;
}
self.y += self.velocityY;
// Keep airplane level at all times
airplaneGraphics.rotation = 0;
// Keep airplane within bounds - only lower bound
if (self.y > 2600) {
self.y = 2600;
self.velocityY = 0;
}
};
return self;
});
var SecondAirplane = Container.expand(function () {
var self = Container.call(this);
var airplaneGraphics = self.attachAsset('airplane', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityY = 0;
self.gravity = 0.5;
self.jumpPower = -35;
self.speed = 4;
self.lastY = 0;
self.lastColliding = false;
self.jump = function () {
if (!isPressed) {
self.velocityY = self.jumpPower;
LK.getSound('engine').play();
}
isPressed = true;
};
self.update = function () {
self.lastY = self.y;
// Apply gravity only when not continuously pressed
if (!isPressed) {
self.velocityY += self.gravity;
} else {
// Fly straight when continuously pressed
self.velocityY = 0;
}
self.y += self.velocityY;
// Keep airplane level at all times
airplaneGraphics.rotation = 0;
// Keep airplane within bounds - only lower bound
if (self.y > 2600) {
self.y = 2600;
self.velocityY = 0;
}
};
return self;
});
var Tower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('tower', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Create a simple blue background
game.setBackgroundColor(0x4169E1);
// Add ground
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0.5,
anchorY: 1.0
}));
ground.x = 1024;
ground.y = 2732;
// Add sun
var sun = game.addChild(LK.getAsset('sun', {
anchorX: 0.5,
anchorY: 0.5
}));
sun.x = 1800;
sun.y = 200;
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0x000000
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var livesTxt = new Text2('Lives: 2', {
size: 60,
fill: 0x000000
});
livesTxt.anchor.set(0.5, 0);
livesTxt.y = 80; // Position below score
LK.gui.top.addChild(livesTxt);
var airplane = game.addChild(new Airplane());
airplane.x = 200;
airplane.y = 1366;
var secondAirplane = game.addChild(new SecondAirplane());
secondAirplane.x = -200; // Start behind the first airplane
secondAirplane.y = 1366;
var firstAirplaneCrashed = false;
var secondAirplaneCrashed = false;
var activeAirplane = airplane; // Track which airplane is currently controlled
var towers = [];
var score = 0;
var lives = 2;
var gameSpeed = 100;
var isPressed = false;
var touchX = 0;
var touchY = 0;
var isTouching = false;
var clouds = [];
// Create clouds in the sky
for (var i = 0; i < 4; i++) {
var cloud = game.addChild(LK.getAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5
}));
cloud.x = Math.random() * 3000 + 500;
cloud.y = Math.random() * 800 + 200;
cloud.alpha = 0.7;
cloud.speed = 100;
clouds.push(cloud);
}
var joystickCenter = {
x: 300,
y: 2400
};
// Add joystick visual elements
var joystickBase = game.addChild(LK.getAsset('joystick_base', {
anchorX: 0.5,
anchorY: 0.5
}));
joystickBase.x = joystickCenter.x;
joystickBase.y = joystickCenter.y;
joystickBase.alpha = 0.6;
var joystickKnob = game.addChild(LK.getAsset('joystick_knob', {
anchorX: 0.5,
anchorY: 0.5
}));
joystickKnob.x = joystickCenter.x;
joystickKnob.y = joystickCenter.y;
joystickKnob.alpha = 0.8;
function updateScore() {
scoreTxt.setText('Score: ' + score);
livesTxt.setText('Lives: ' + lives);
}
function checkCollisions() {
// Check collision for first airplane (if not crashed)
if (!firstAirplaneCrashed) {
var airplaneNoseX = airplane.x + 200; // Airplane nose is about 200px from center
var airplaneLeftWing = airplane.x - 200; // Left wing edge
var airplaneRightWing = airplane.x + 200; // Right wing edge
var airplaneTop = airplane.y - 125; // Top of airplane
var airplaneBottom = airplane.y + 125; // Bottom of airplane
var isColliding = false;
// Check collision with all towers
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
var towerLeft = tower.x - 50; // Tower width consideration
var towerRight = tower.x + 50;
var towerTop = tower.y - 750; // Half tower height from center
var towerBottom = tower.y + 750; // Half tower height from center
var currentIntersecting = airplaneNoseX >= towerLeft && airplaneLeftWing <= towerRight && airplaneBottom >= towerTop && airplaneTop <= towerBottom;
if (currentIntersecting) {
isColliding = true;
break;
}
}
if (!airplane.lastColliding && isColliding) {
// First airplane hit a tower - create bomb explosion effect
LK.getSound('crash').play();
// Flash the airplane red for explosion effect
LK.effects.flashObject(airplane, 0xff0000, 500);
// Create multiple explosion circles for bomb effect at airplane position
var explosionCircles = [];
for (var i = 0; i < 12; i++) {
var circle = game.addChild(LK.getAsset('explosion_circle', {
anchorX: 0.5,
anchorY: 0.5
}));
circle.x = airplane.x + (Math.random() - 0.5) * 300;
circle.y = airplane.y + (Math.random() - 0.5) * 300;
circle.alpha = 0.8;
circle.tint = i % 2 === 0 ? 0xff4500 : 0xffa500; // Alternate between orange and yellow
explosionCircles.push(circle);
// Animate each circle expanding and fading
tween(circle, {
scaleX: 8 + Math.random() * 4,
scaleY: 8 + Math.random() * 4,
alpha: 0
}, {
duration: 400 + Math.random() * 200,
easing: tween.easeOut,
onFinish: function onFinish() {
circle.destroy();
}
});
}
// First airplane crashed, lose 1 life
lives--;
updateScore();
firstAirplaneCrashed = true;
activeAirplane = secondAirplane;
// Hide the first airplane
airplane.alpha = 0;
// Screen shake effect using tween
tween(game, {
x: 10
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: -10
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: 5
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: 0
}, {
duration: 50
});
}
});
}
});
}
});
}
airplane.lastColliding = isColliding;
}
// Check collision for second airplane (if not crashed)
if (!secondAirplaneCrashed) {
var airplaneNoseX = secondAirplane.x + 200; // Airplane nose is about 200px from center
var airplaneLeftWing = secondAirplane.x - 200; // Left wing edge
var airplaneRightWing = secondAirplane.x + 200; // Right wing edge
var airplaneTop = secondAirplane.y - 125; // Top of airplane
var airplaneBottom = secondAirplane.y + 125; // Bottom of airplane
var isColliding = false;
// Check collision with all towers
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
var towerLeft = tower.x - 50; // Tower width consideration
var towerRight = tower.x + 50;
var towerTop = tower.y - 750; // Half tower height from center
var towerBottom = tower.y + 750; // Half tower height from center
var currentIntersecting = airplaneNoseX >= towerLeft && airplaneLeftWing <= towerRight && airplaneBottom >= towerTop && airplaneTop <= towerBottom;
if (currentIntersecting) {
isColliding = true;
break;
}
}
if (!secondAirplane.lastColliding && isColliding) {
// Second airplane hit a tower - create bomb explosion effect
LK.getSound('crash').play();
// Flash the airplane red for explosion effect
LK.effects.flashObject(secondAirplane, 0xff0000, 500);
// Create multiple explosion circles for bomb effect at airplane position
var explosionCircles = [];
for (var i = 0; i < 12; i++) {
var circle = game.addChild(LK.getAsset('explosion_circle', {
anchorX: 0.5,
anchorY: 0.5
}));
circle.x = secondAirplane.x + (Math.random() - 0.5) * 300;
circle.y = secondAirplane.y + (Math.random() - 0.5) * 300;
circle.alpha = 0.8;
circle.tint = i % 2 === 0 ? 0xff4500 : 0xffa500; // Alternate between orange and yellow
explosionCircles.push(circle);
// Animate each circle expanding and fading
tween(circle, {
scaleX: 8 + Math.random() * 4,
scaleY: 8 + Math.random() * 4,
alpha: 0
}, {
duration: 400 + Math.random() * 200,
easing: tween.easeOut,
onFinish: function onFinish() {
circle.destroy();
}
});
}
// Second airplane crashed, lose last life and game over
lives--;
updateScore();
secondAirplaneCrashed = true;
// Screen shake effect using tween
tween(game, {
x: 10
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: -10
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: 5
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: 0
}, {
duration: 50,
onFinish: function onFinish() {
// Show game over after explosion effects complete
LK.showGameOver();
}
});
}
});
}
});
}
});
}
secondAirplane.lastColliding = isColliding;
}
// Check if airplane passed towers for scoring - only count active airplane
var currentAirplane = firstAirplaneCrashed ? secondAirplane : airplane;
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
if (!tower.scored && currentAirplane.x > tower.x) {
score += 10;
tower.scored = true;
updateScore();
}
}
}
game.down = function (x, y, obj) {
// Only respond to touches in the joystick area
var distanceFromJoystick = Math.sqrt((x - joystickCenter.x) * (x - joystickCenter.x) + (y - joystickCenter.y) * (y - joystickCenter.y));
if (distanceFromJoystick <= 150) {
touchX = x;
touchY = y;
isTouching = true;
activeAirplane.jump();
}
};
game.move = function (x, y, obj) {
if (isTouching) {
touchX = x;
touchY = y;
}
};
game.up = function (x, y, obj) {
isPressed = false;
isTouching = false;
};
game.update = function () {
airplane.lastX = airplane.x;
secondAirplane.lastX = secondAirplane.x;
// Move towers left for side-scrolling effect
for (var i = 0; i < towers.length; i++) {
towers[i].x -= gameSpeed;
}
// Add new towers when needed - but only after game has started (score > 0 or some delay)
if (LK.ticks > 180 && (towers.length === 0 || towers[towers.length - 1].x < 2048 + 50000)) {
var newTower = game.addChild(new Tower());
newTower.x = towers.length > 0 ? towers[towers.length - 1].x + 50000 : 2200; // Reduced spacing by 1/3
newTower.y = 2732 - 750; // Adjust Y position so tower touches ground (2732 - half tower height)
towers.push(newTower);
}
// Remove towers that are off-screen
for (var i = towers.length - 1; i >= 0; i--) {
if (towers[i].x < -200) {
towers[i].destroy();
towers.splice(i, 1);
}
}
checkCollisions();
// Move clouds quickly across the sky
for (var i = 0; i < clouds.length; i++) {
clouds[i].x -= clouds[i].speed;
// Reset cloud position when it goes off-screen
if (clouds[i].x < -200) {
clouds[i].x = 2300;
clouds[i].y = Math.random() * 800 + 200;
}
}
// Joystick control - move airplane vertically only
if (isTouching) {
var deltaY = touchY - joystickCenter.y;
// Limit joystick knob movement vertically only
var maxRange = 100;
if (deltaY > maxRange) {
deltaY = maxRange;
} else if (deltaY < -maxRange) {
deltaY = -maxRange;
}
// Update joystick knob position - vertical movement only
joystickKnob.x = joystickCenter.x;
joystickKnob.y = joystickCenter.y + deltaY;
// Move airplane vertically based on joystick input
var moveScale = 4;
var targetY = 1366 - deltaY * moveScale; // Inverted Y-axis
// Keep airplane within screen bounds vertically
activeAirplane.y = Math.max(-500, Math.min(2632, targetY));
} else {
// Reset joystick knob to center when not touching
joystickKnob.x = joystickCenter.x;
joystickKnob.y = joystickCenter.y;
}
// Keep airplane centered horizontally at all times
if (!firstAirplaneCrashed) {
airplane.x = 1024;
// Second airplane follows behind the first airplane
secondAirplane.x = airplane.x - 2000; // 2000px behind - much further back
secondAirplane.y = airplane.y - 400; // 400px higher than first airplane
} else {
// After crash, control the second airplane
secondAirplane.x = 1024;
}
// Win condition
if (score >= 100) {
LK.showYouWin();
}
};
Plane. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
İkiz kule . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
yuvarlak ve gerçekçi güneş
gerçekçi patlama biraz ateş biraz duman. In-Game asset. 2d. High contrast. No shadows
bulut. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat