User prompt
שיהיה ברקע של המשחק, רק במהלך המשחק בלי המסך הראשי, כל הזמן המון נקודות קטנות כאלה. ביום הם יהיו בצבע ירוק כהה, בלילה הם יהיו בצבע לבן. קטנים ובהירים, חלק מהרקע, זזים כל הזמן ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
תשתמש באפקטים הזוהרים של הלילה, כל שנייה וחצי במהלך הזמן של הלילה. תגביר את הזוהר באפקט ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
תוריד ל9 שניות את הזמן חיים המקסימלי של טיל באוויר
User prompt
כאשר הרקע הופך להיות כהה, תשתמש באפקטים ושהכל יהיה זוהר כאשר נפגעים מטיל ויורד חיים, שכל המסך יהבהב לרגע בצבע אדום ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
כאשר המשחק במצב לילה, תעשה שכל הטילים וכל האלמנטים במשחק זוהרים ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
אחרי שהמשחק נטען, תהפוך את הרקע לחום מדברי. אחרי 20 שניות של משחק הרקע הופך למדברי אבל מאוד כהה ודומה ללילה, ואחרי עוד 10 שניות חוזר להיות מדברי. ואז שוב, 20 שניות והופך ללילה, 10 שניות ולמדברי ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Raise up the B-2 Mission raise up and make bigger the start button The legend and instructions: make much bigger, the text and the symbols
User prompt
Add the flare symbol near the flare instruction
User prompt
Delete the Click mouse to fire Move mouse forward ti drop bomb Shake mouse ti use flares and add under cannon: Flares - Shake the mouse left and right to use
User prompt
Remove the explain that write with the white colour at the start page
User prompt
תסיר את ההסבר על ההזזות של העכבר תגביה את כפתור הstart תגביה את כל ההסברים. בהסבר על הפצצה תכתוב שצריך להזיז את העכבר קדימה, בהסבר על התותח תכתוב ללחוץ על הכבר
User prompt
במסך הראשי, שכל הרקע יהיה שחור. הכל הכל, לא רק מאחורי הStart
User prompt
אל תכתוב במילים. תראה את הבניינים ואת הסוללה, ותכתוב באמצעות פצצות ותראה את הפצצה תראה את הרכבים ותכתוב עם תותח רגיל ותראה אותו תעשה מקרא של כל המבנים והרכבים, כמה כל אחד נותן בניקוד
User prompt
The title should be "B-2 Mission". At the bottom of the screen, display the following instructions along with an illustration of a mouse showing the actions: Move the mouse to control the bomber Click the mouse to fire Drag the mouse forward to drop bombs Shake the mouse to use flares explain that: Buildings and S-300 can be destroyd using bombs only Cars with the main cannon
User prompt
Please fix the bug: 'ReferenceError: updateFlareDisplay is not defined' in or related to this line: 'updateFlareDisplay();' Line Number: 138
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'x')' in or related to this line: 'missile.targetX = fighterJet.x;' Line Number: 237
User prompt
Please fix the bug: 'ReferenceError: missiles is not defined' in or related to this line: 'for (var i = 0; i < missiles.length; i++) {' Line Number: 156
User prompt
Please fix the bug: 'ReferenceError: scrollSpeed is not defined' in or related to this line: 'self.y += scrollSpeed;' Line Number: 200
User prompt
Please fix the bug: 'ReferenceError: scrollSpeed is not defined' in or related to this line: 'self.y += scrollSpeed;' Line Number: 200
User prompt
Please fix the bug: 'Uncaught ReferenceError: getPointsForTarget is not defined' in or related to this line: 'self.points = getPointsForTarget(targetType);' Line Number: 190
User prompt
Please fix the bug: 'Uncaught ReferenceError: getPointsForTarget is not defined' in or related to this line: 'self.points = getPointsForTarget(targetType);' Line Number: 190
User prompt
Please fix the bug: 'Uncaught ReferenceError: getPointsForTarget is not defined' in or related to this line: 'self.points = getPointsForTarget(targetType);' Line Number: 190
User prompt
Please fix the bug: 'Uncaught ReferenceError: fighterJet is not defined' in or related to this line: 'fighterJet.x = 1024;' Line Number: 375
User prompt
תוסיף מסך לפני שהמשחק נטען. בהתחלה יש רק את המסך, כשמתחילים לשחק, המסך הזה נסגר ומתחיל המשחק. 2 מסכים שונים. במסך הזה יהיה כפתור start
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'bullet.x = fighterJet.x;' Line Number: 930
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bomb = Container.expand(function () { var self = Container.call(this); var bombGraphics = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.targetX = 0; self.targetY = 0; self.update = function () { // Basic fallback movement if no tween is active if (!self.targetX && !self.targetY) { self.y += self.speed; } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -12; self.lastX = 0; self.lastY = 0; self.stuckTimer = 0; self.update = function () { self.y += self.speed; // Track last position to detect if bullet is stuck var moveThreshold = 2; // Minimum movement required var dx = Math.abs(self.x - self.lastX); var dy = Math.abs(self.y - self.lastY); var totalMovement = dx + dy; // If bullet hasn't moved enough, increment stuck timer if (totalMovement < moveThreshold) { self.stuckTimer++; } else { self.stuckTimer = 0; // Reset timer if bullet is moving } // If stuck for more than 3 seconds (180 frames at 60fps), mark for destruction if (self.stuckTimer >= 180) { self.destroy(); return; } // Store current position for next frame comparison self.lastX = self.x; self.lastY = self.y; }; return self; }); var DestructionMark = Container.expand(function () { var self = Container.call(this); var markGraphics = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5 }); markGraphics.tint = 0x000000; // Black color markGraphics.alpha = 0.8; self.update = function () { self.y += scrollSpeed; // Move with ground scroll }; return self; }); var Explosion = Container.expand(function () { var self = Container.call(this); var explosionGraphics = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5 }); self.lifespan = 30; self.update = function () { self.lifespan--; self.alpha = self.lifespan / 30; if (self.lifespan <= 0) { self.destroy(); } }; return self; }); var FighterJet = Container.expand(function () { var self = Container.call(this); var jetGraphics = self.attachAsset('fighterJet', { anchorX: 0.5, anchorY: 0.5 }); var bombTargetCircle = self.attachAsset('bombTarget', { anchorX: 0.5, anchorY: 0.5 }); bombTargetCircle.y = -400; // Position much further in front of the jet bombTargetCircle.alpha = 0.6; bombTargetCircle.visible = false; self.bombTargetCircle = bombTargetCircle; self.lives = 3; self.flareCount = 3; self.maxFlares = 3; self.flareRechargeTimer = 0; self.aaSystemsDestroyed = 0; self.update = function () { // Recharge flares over time if (self.flareCount < self.maxFlares) { self.flareRechargeTimer++; if (self.flareRechargeTimer >= 150) { // 2.5 seconds at 60fps self.flareCount++; self.flareRechargeTimer = 0; updateFlareDisplay(); } } }; return self; }); var Flare = Container.expand(function () { var self = Container.call(this); var flareGraphics = self.attachAsset('flare', { anchorX: 0.5, anchorY: 0.5 }); self.lifespan = 240; // 4 seconds at 60fps self.update = function () { self.lifespan--; // Track nearest missile var nearestMissile = null; var nearestDistance = Infinity; for (var i = 0; i < missiles.length; i++) { var missile = missiles[i]; var dx = missile.x - self.x; var dy = missile.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestMissile = missile; } } // Move towards nearest missile if within tracking range if (nearestMissile && nearestDistance < 300) { var dx = nearestMissile.x - self.x; var dy = nearestMissile.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * 8; self.y += dy / distance * 8; } } // Destroy flare after 4 seconds no matter what if (self.lifespan <= 0) { self.destroy(); } }; return self; }); var GroundTarget = Container.expand(function (targetType) { var self = Container.call(this); var targetGraphics = self.attachAsset(targetType, { anchorX: 0.5, anchorY: 0.5 }); self.targetType = targetType; self.points = getPointsForTarget(targetType); self.canShootMissiles = targetType === 's300System'; self.missileTimer = 0; // Set random movement direction for vehicles (only once at creation) if (targetType === 'car' || targetType === 'armyVan') { self.moveDirection = Math.random() < 0.5 ? -4 : 4; // Either -4 (left) or 4 (right) } else { self.moveDirection = 0; } self.update = function () { self.y += scrollSpeed; // Movement for cars and army vans in one consistent direction if (self.targetType === 'car' || self.targetType === 'armyVan') { // Move consistently in the chosen direction self.x += self.moveDirection; // Mirror vehicle to face movement direction if (self.moveDirection > 0) { // Moving right - no flip needed (default orientation) targetGraphics.scale.x = Math.abs(targetGraphics.scale.x); } else { // Moving left - flip horizontally targetGraphics.scale.x = -Math.abs(targetGraphics.scale.x); } // Keep vehicles within screen bounds and reverse direction if hitting edges if (self.x < 50) { self.x = 50; self.moveDirection = Math.abs(self.moveDirection); // Force positive direction } if (self.x > 1998) { self.x = 1998; self.moveDirection = -Math.abs(self.moveDirection); // Force negative direction } } // S-300 systems shoot missiles at the player if (self.canShootMissiles && self.y > 200 && self.y < 2000) { self.missileTimer++; if (self.missileTimer >= 180) { // Every 3 seconds self.fireMissile(); self.missileTimer = 0; } } }; self.fireMissile = function () { var missile = new Missile(); missile.x = self.x; missile.y = self.y; missile.targetX = fighterJet.x; missile.targetY = fighterJet.y; missiles.push(missile); game.addChild(missile); LK.getSound('missile').play(); }; return self; }); var Missile = Container.expand(function () { var self = Container.call(this); var missileGraphics = self.attachAsset('missile', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.targetX = 0; self.targetY = 0; self.lastX = 0; self.lastY = 0; self.stuckTimer = 0; self.bottomTimer = 0; // Track time spent in bottom area self.lifeTimer = 600; // 10 seconds at 60fps self.update = function () { // Decrease lifespan timer self.lifeTimer--; if (self.lifeTimer <= 0) { self.destroy(); return; } // Track last position to detect if missile is stuck var moveThreshold = 2; // Minimum movement required var dx = Math.abs(self.x - self.lastX); var dy = Math.abs(self.y - self.lastY); var totalMovement = dx + dy; // If missile hasn't moved enough, increment stuck timer if (totalMovement < moveThreshold) { self.stuckTimer++; } else { self.stuckTimer = 0; // Reset timer if missile is moving } // If stuck for more than 3 seconds (180 frames at 60fps), mark for destruction if (self.stuckTimer >= 180) { self.destroy(); return; } // Check if missile is in bottom 20% of screen (2732 * 0.8 = 2185.6) if (self.y > 2185) { self.bottomTimer++; } else { self.bottomTimer = 0; // Reset timer if missile leaves bottom area } // If missile has been in bottom area for more than 3 seconds (180 frames at 60fps), mark for destruction if (self.bottomTimer >= 180) { self.destroy(); return; } // Store current position for next frame comparison self.lastX = self.x; self.lastY = self.y; // Move towards target (fighter jet) var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xc19a6b }); /**** * Game Code ****/ var gameStarted = false; var startScreen = null; var startButton = null; // Create start screen startScreen = new Container(); game.addChild(startScreen); // Add background for start screen var startBackground = LK.getAsset('road', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 10 }); startBackground.x = 1024; startBackground.y = 1366; startBackground.tint = 0x2c3e50; startScreen.addChild(startBackground); // Add title text var titleText = new Text2('Fighter Jet Simulator', { size: 120, fill: '#ffffff' }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 800; startScreen.addChild(titleText); // Create start button startButton = LK.getAsset('road', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.8 }); startButton.x = 1024; startButton.y = 1400; startButton.tint = 0x27ae60; startScreen.addChild(startButton); // Add button text var buttonText = new Text2('START', { size: 80, fill: '#ffffff' }); buttonText.anchor.set(0.5, 0.5); buttonText.x = 1024; buttonText.y = 1400; startScreen.addChild(buttonText); // Handle start button click startButton.down = function (x, y, obj) { if (gameStarted) return; gameStarted = true; startScreen.destroy(); // Initialize game after start button is clicked initializeGame(); }; function initializeGame() { fighterJet.x = 1024; fighterJet.y = 2200; var bullets = []; var bombs = []; var flares = []; var missiles = []; var groundTargets = []; var explosions = []; var destructionMarks = []; var scrollSpeed = 3; var spawnTimer = 0; var gameSpeed = 1; var roadSystem = { roads: [], // Array to track active roads roadGraphics: [], // Array to track road graphics for movement nextRoadTime: 0, // Time for next road generation roadHeight: 80, // Height of road area generateNewRoad: true // Flag to generate road immediately at start }; var bombKeyPressed = false; var flareKeyPressed = false; var keyStates = {}; var fKeyPressed = false; var bKeyPressed = false; var lastMouseX = 0; var lastMouseY = 0; // Store bomb target position when bomb is released var bombTargetX = 0; var bombTargetY = 0; var bombCooldown = 0; var bombingActive = true; var bombTargetMarked = false; // UI Elements var scoreText = new Text2('Score: 0', { size: 60, fill: '#ffffff' }); scoreText.anchor.set(0, 0); scoreText.x = 150; scoreText.y = 50; LK.gui.topLeft.addChild(scoreText); var livesText = new Text2('Lives: 3', { size: 60, fill: '#ffffff' }); livesText.anchor.set(1, 0); LK.gui.topRight.addChild(livesText); var flareText = new Text2('Flares: 3', { size: 60, fill: '#ffffff' }); flareText.anchor.set(0.5, 0); LK.gui.top.addChild(flareText); var bombingText = new Text2('Bombing: Active', { size: 60, fill: '#ffffff' }); bombingText.anchor.set(0.5, 0); bombingText.y = 70; LK.gui.top.addChild(bombingText); function updateScore() { scoreText.setText('Score: ' + LK.getScore()); } function updateLivesDisplay() { livesText.setText('Lives: ' + fighterJet.lives); } function updateFlareDisplay() { flareText.setText('Flares: ' + fighterJet.flareCount); } function updateBombingDisplay() { bombingText.setText('Bombing: ' + (bombingActive ? 'Active' : 'Disabled')); } function getPointsForTarget(targetType) { switch (targetType) { case 'building': return -10; // Civilian building penalty case 'targetBuilding': return 10; // Military building points case 'car': return -5; // Regular truck penalty case 'armyVan': return 5; // Military truck points case 's300System': return 15; // S-300 system points default: return 10; } } function generateRoadStructure() { // Check if we need to create a new road based on time if (roadSystem.generateNewRoad || LK.ticks >= roadSystem.nextRoadTime) { // Create new road at top of screen (y = 0) var roadY = 0; var road = { y: roadY, hasVehicles: true, // Always have vehicles (minimum 1) hasBuildings: true, // Always have buildings (minimum 1) vehicleCount: Math.floor(Math.random() * 4) + 1, // 1-4 vehicles buildingCount: Math.floor(Math.random() * 3) + 1 // 1-3 buildings }; roadSystem.roads.push(road); // Draw the actual road var roadGraphics = LK.getAsset('road', { anchorX: 0.5, anchorY: 0.5 }); roadGraphics.x = 1024; // Center of screen roadGraphics.y = roadY; roadSystem.roadGraphics.push(roadGraphics); game.addChild(roadGraphics); // Spawn vehicles on road (always at least 1) for (var v = 0; v < road.vehicleCount; v++) { var vehicleType = Math.random() < 0.6 ? 'car' : 'armyVan'; var vehicle = new GroundTarget(vehicleType); vehicle.x = Math.random() * 1700 + 174; // Increased travel distance vehicle.y = roadY; groundTargets.push(vehicle); game.addChild(vehicle); } // Spawn buildings adjacent to road (above it) - always at least 1 var placedBuildings = []; // Track placed building positions for (var b = 0; b < road.buildingCount; b++) { var buildingType; var rand = Math.random(); if (rand < 0.4) { buildingType = 'building'; } else if (rand < 0.8) { buildingType = 'targetBuilding'; } else if (rand < 0.82) { buildingType = 's300System'; } else { buildingType = 's300System'; } // Find valid position with minimum spacing var attempts = 0; var validPosition = false; var buildingX, buildingY; while (!validPosition && attempts < 20) { buildingX = Math.random() * 1400 + 324; // Slightly more constrained buildingY = roadY - 150; // Position above road validPosition = true; // Check distance from other buildings for (var pb = 0; pb < placedBuildings.length; pb++) { var placedBuilding = placedBuildings[pb]; var dx = buildingX - placedBuilding.x; var dy = buildingY - placedBuilding.y; var distance = Math.sqrt(dx * dx + dy * dy); // Minimum distance of 250 pixels between buildings if (distance < 250) { validPosition = false; break; } } attempts++; } // Only place building if valid position found if (validPosition) { var building = new GroundTarget(buildingType); building.x = buildingX; // Raise regular buildings by 25 pixels (original 5 + additional 20) if (buildingType === 'building') { building.y = buildingY - 25; } else if (buildingType === 's300System') { building.y = buildingY + 5; // Lower military buildings by 5 pixels } else { building.y = buildingY; } placedBuildings.push({ x: buildingX, y: buildingY }); groundTargets.push(building); game.addChild(building); } } // Calculate next road time: 5.5 seconds average ± 1.5 seconds (330 ± 90 ticks at 60fps) var baseTime = 330; // 5.5 seconds at 60fps var variance = 180; // ±3 seconds total range (1.5 second variance) var nextRoadDelay = baseTime + (Math.random() * variance - variance / 2); roadSystem.nextRoadTime = LK.ticks + nextRoadDelay; roadSystem.generateNewRoad = false; } } function spawnAntiAircraftSystems() { // Spawn S-300 systems in dead zones between roads if (Math.random() < 0.13) { // 13% chance per spawn cycle var s300 = new GroundTarget('s300System'); s300.x = Math.random() * 1600 + 224; s300.y = -100 - Math.random() * 200; // In dead zone area groundTargets.push(s300); game.addChild(s300); } } function spawnGroundTarget() { // This function is now called less frequently and handles structured generation generateRoadStructure(); spawnAntiAircraftSystems(); } function createExplosion(x, y) { var explosion = new Explosion(); explosion.x = x; explosion.y = y; explosions.push(explosion); game.addChild(explosion); LK.getSound('explosion').play(); } function checkMissileFlareCollision(missile) { for (var f = flares.length - 1; f >= 0; f--) { var flare = flares[f]; if (missile.intersects(flare)) { // Flare explodes and destroys missiles in radius createExplosion(flare.x, flare.y); // Destroy all missiles within explosion radius for (var m = missiles.length - 1; m >= 0; m--) { var targetMissile = missiles[m]; var dx = targetMissile.x - flare.x; var dy = targetMissile.y - flare.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) { // Explosion radius createExplosion(targetMissile.x, targetMissile.y); LK.setScore(LK.getScore() + 1); // +1 point for missile destruction by flare updateScore(); targetMissile.destroy(); missiles.splice(m, 1); } } flare.destroy(); flares.splice(f, 1); return true; } } return false; } // Generate first road at game start generateRoadStructure(); // Event handlers game.move = function (x, y, obj) { fighterJet.x = x; fighterJet.y = y; // Improved keyboard input simulation with better detection var deltaX = Math.abs(x - lastMouseX); var deltaY = Math.abs(y - lastMouseY); // F key simulation: horizontal movement with more sensitive detection if (deltaX > 30 && deltaY < 30) { fKeyPressed = true; } else { fKeyPressed = false; } // B key simulation: vertical movement with more sensitive detection if (deltaY > 30 && deltaX < 30) { bKeyPressed = true; } else { bKeyPressed = false; } lastMouseX = x; lastMouseY = y; }; game.down = function (x, y, obj) { // Check for special input zones for keyboard simulation if (y < 200 && x < 300) { // Top-left corner click - fire flare (F key simulation) if (fighterJet.flareCount > 0) { var flare = new Flare(); flare.x = fighterJet.x + (Math.random() - 0.5) * 100; flare.y = fighterJet.y + (Math.random() - 0.5) * 100; flares.push(flare); game.addChild(flare); fighterJet.flareCount--; updateFlareDisplay(); LK.getSound('flare').play(); } return; } else if (y < 200 && x > 1748) { // Top-right corner click - drop bomb (B key simulation) var bomb = new Bomb(); bomb.x = fighterJet.x; bomb.y = fighterJet.y + 50; bombs.push(bomb); game.addChild(bomb); LK.getSound('bomb').play(); return; } if (obj.event && obj.event.button === 0) { // Left click - fire bullet var bullet = new Bullet(); bullet.x = fighterJet.x; bullet.y = fighterJet.y - 50; bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); } else if (obj.event && obj.event.button === 2) { // Right click - drop bomb var bomb = new Bomb(); bomb.x = fighterJet.x; bomb.y = fighterJet.y + 50; bombs.push(bomb); game.addChild(bomb); LK.getSound('bomb').play(); } else if (!obj.event) { // Default action for touch/tap (no event object) - fire bullet var bullet = new Bullet(); bullet.x = fighterJet.x; bullet.y = fighterJet.y - 50; bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); } }; game.update = function () { // Handle keyboard input - using LK tick-based simulation // Since document is not available, we'll use mouse position changes to detect special actions var currentFlareKeyPressed = false; // Will be triggered by specific mouse positions var currentBombKeyPressed = false; // Will be triggered by specific mouse positions // Fire flare on F key press (only once per press) if (fKeyPressed && !flareKeyPressed && fighterJet.flareCount > 0) { var flare = new Flare(); flare.x = fighterJet.x + (Math.random() - 0.5) * 100; flare.y = fighterJet.y + (Math.random() - 0.5) * 100; flares.push(flare); game.addChild(flare); fighterJet.flareCount--; updateFlareDisplay(); LK.getSound('flare').play(); } flareKeyPressed = fKeyPressed; // Handle bomb cooldown if (bombCooldown > 0) { bombCooldown--; if (bombCooldown === 0) { bombingActive = true; updateBombingDisplay(); } } // Drop bomb on B key press (only once per press) if (bKeyPressed && !bombKeyPressed && bombingActive) { if (!bombTargetMarked) { // Calculate exact target position based on circle's current position, 55 pixels behind bombTargetX = fighterJet.x + fighterJet.bombTargetCircle.x; bombTargetY = fighterJet.y + fighterJet.bombTargetCircle.y + 60; bombTargetMarked = true; // Create and drop the bomb var bomb = new Bomb(); bomb.x = fighterJet.x; bomb.y = fighterJet.y + 50; bomb.targetX = bombTargetX; bomb.targetY = bombTargetY; // Animate bomb falling to target position tween(bomb, { x: bombTargetX, y: bombTargetY }, { duration: 2000, easing: tween.easeIn, onFinish: function onFinish() { // Create big explosion at exact target createExplosion(bombTargetX, bombTargetY); // Create persistent destruction mark var destructionMark = new DestructionMark(); destructionMark.x = bombTargetX; destructionMark.y = bombTargetY; destructionMarks.push(destructionMark); game.addChild(destructionMark); // Destroy ground targets in explosion radius for (var gt = groundTargets.length - 1; gt >= 0; gt--) { var target = groundTargets[gt]; var dx = target.x - bombTargetX; var dy = target.y - bombTargetY; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Big explosion radius createExplosion(target.x, target.y); LK.setScore(LK.getScore() + target.points); updateScore(); if (target.targetType === 's300System') { fighterJet.aaSystemsDestroyed++; if (fighterJet.aaSystemsDestroyed >= 5 && fighterJet.lives < 3) { fighterJet.lives++; fighterJet.aaSystemsDestroyed = 0; updateLivesDisplay(); } } target.destroy(); groundTargets.splice(gt, 1); } } // Remove and destroy the bomb after explosion bomb.destroy(); for (var i = bombs.length - 1; i >= 0; i--) { if (bombs[i] === bomb) { bombs.splice(i, 1); break; } } // Start cooldown bombCooldown = 60; // 1 second at 60fps bombingActive = false; bombTargetMarked = false; updateBombingDisplay(); } }); bombs.push(bomb); game.addChild(bomb); LK.getSound('bomb').play(); } } bombKeyPressed = bKeyPressed; spawnTimer++; // Generate road structures and spawn targets if (spawnTimer >= 30) { // Every 0.5 seconds for more frequent spawning spawnGroundTarget(); spawnTimer = 0; } // Update road system - move roads with scroll speed and clean up for (var r = roadSystem.roads.length - 1; r >= 0; r--) { var road = roadSystem.roads[r]; // Move road down with scroll speed road.y += scrollSpeed; // Move corresponding road graphics if (roadSystem.roadGraphics[r]) { roadSystem.roadGraphics[r].y += scrollSpeed; } // Remove roads that are off screen if (road.y > 2800) { // Destroy road graphics if (roadSystem.roadGraphics[r]) { roadSystem.roadGraphics[r].destroy(); roadSystem.roadGraphics.splice(r, 1); } roadSystem.roads.splice(r, 1); } } // Show bomb target circle when mouse is in bombing position if (fighterJet.y < 2500) { fighterJet.bombTargetCircle.visible = true; } else { fighterJet.bombTargetCircle.visible = false; } // Update bullets for (var b = bullets.length - 1; b >= 0; b--) { var bullet = bullets[b]; if (bullet.y < -50) { bullet.destroy(); bullets.splice(b, 1); continue; } // Check bullet vs ground targets for (var gt = groundTargets.length - 1; gt >= 0; gt--) { var target = groundTargets[gt]; if (bullet.intersects(target)) { // Only allow bullets to destroy certain targets - not S-300, missile buildings, or regular buildings if (target.targetType === 's300System' || target.targetType === 'targetBuilding' || target.targetType === 'building') { // Bullets cannot destroy S-300 systems, missile buildings, or regular buildings bullet.destroy(); bullets.splice(b, 1); break; } createExplosion(target.x, target.y); // Apply scoring based on target type LK.setScore(LK.getScore() + target.points); updateScore(); bullet.destroy(); bullets.splice(b, 1); target.destroy(); groundTargets.splice(gt, 1); break; } } } // Update bombs - cleanup only for (var bo = bombs.length - 1; bo >= 0; bo--) { var bomb = bombs[bo]; if (bomb.destroyed) { bombs.splice(bo, 1); } } // Update missiles for (var m = missiles.length - 1; m >= 0; m--) { var missile = missiles[m]; // Skip if missile doesn't exist (already removed) if (!missile) { continue; } // Update missile target to current fighter jet position missile.targetX = fighterJet.x; missile.targetY = fighterJet.y; // Check if missile was intercepted by flare if (checkMissileFlareCollision(missile)) { missiles.splice(m, 1); continue; } // Check missile vs fighter jet (only the jet graphics, not the targeting circle) // Calculate distance to jet center for more precise collision var dx = missile.x - fighterJet.x; var dy = missile.y - fighterJet.y; var distance = Math.sqrt(dx * dx + dy * dy); // Only consider collision if missile is close to the actual jet (not the targeting circle) if (distance < 60) { // Jet is 120x80, so radius of ~60 should cover the jet body createExplosion(fighterJet.x, fighterJet.y); fighterJet.lives--; updateLivesDisplay(); if (fighterJet.lives <= 0) { LK.showGameOver(); return; } missile.destroy(); missiles.splice(m, 1); continue; } // Remove missiles that go off screen if (missile.y > 2800 || missile.y < -50 || missile.x < -50 || missile.x > 2100) { missile.destroy(); missiles.splice(m, 1); } } // Update ground targets for (var gt = groundTargets.length - 1; gt >= 0; gt--) { var target = groundTargets[gt]; if (target.y > 2800) { target.destroy(); groundTargets.splice(gt, 1); } } // Update flares for (var f = flares.length - 1; f >= 0; f--) { var flare = flares[f]; if (flare.destroyed) { flares.splice(f, 1); } } // Update explosions for (var e = explosions.length - 1; e >= 0; e--) { var explosion = explosions[e]; if (explosion.destroyed) { explosions.splice(e, 1); } } // Update destruction marks for (var dm = destructionMarks.length - 1; dm >= 0; dm--) { var destructionMark = destructionMarks[dm]; if (destructionMark.y > 2800) { destructionMark.destroy(); destructionMarks.splice(dm, 1); } } }; }
===================================================================
--- original.js
+++ change.js
@@ -1,9 +1,8 @@
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
-var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
@@ -220,104 +219,8 @@
LK.getSound('missile').play();
};
return self;
});
-var LeaderboardScreen = Container.expand(function () {
- var self = Container.call(this);
- // Background overlay
- var background = LK.getAsset('road', {
- anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 1.2,
- scaleY: 20
- });
- background.x = 1024;
- background.y = 1366;
- background.tint = 0x000000;
- background.alpha = 0.9;
- self.addChild(background);
- // Title
- var titleText = new Text2('LEADERBOARD', {
- size: 80,
- fill: '#ffffff'
- });
- titleText.anchor.set(0.5, 0.5);
- titleText.x = 1024;
- titleText.y = 300;
- self.addChild(titleText);
- // Leaderboard entries container
- self.entriesContainer = new Container();
- self.addChild(self.entriesContainer);
- // Back button
- var backButton = LK.getAsset('targetBuilding', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- backButton.x = 1024;
- backButton.y = 2200;
- backButton.tint = 0xff4444;
- self.addChild(backButton);
- var backText = new Text2('BACK', {
- size: 60,
- fill: '#ffffff'
- });
- backText.anchor.set(0.5, 0.5);
- backText.x = 1024;
- backText.y = 2200;
- self.addChild(backText);
- self.backButton = backButton;
- self.updateLeaderboard = function () {
- // Clear existing entries
- for (var i = self.entriesContainer.children.length - 1; i >= 0; i--) {
- self.entriesContainer.children[i].destroy();
- }
- // Get leaderboard data
- var leaderboard = storage.leaderboard || {};
- var sortedEntries = [];
- // Convert to array and sort
- for (var pilotName in leaderboard) {
- sortedEntries.push({
- name: pilotName,
- score: leaderboard[pilotName]
- });
- }
- sortedEntries.sort(function (a, b) {
- return b.score - a.score;
- });
- // Display top 10
- var maxEntries = Math.min(10, sortedEntries.length);
- if (maxEntries === 0) {
- var noDataText = new Text2('No scores yet!', {
- size: 60,
- fill: '#cccccc'
- });
- noDataText.anchor.set(0.5, 0.5);
- noDataText.x = 1024;
- noDataText.y = 800;
- self.entriesContainer.addChild(noDataText);
- } else {
- for (var i = 0; i < maxEntries; i++) {
- var entry = sortedEntries[i];
- var rank = i + 1;
- var entryText = new Text2(rank + '. ' + entry.name + ': ' + entry.score, {
- size: 50,
- fill: rank <= 3 ? '#ffdd00' : '#ffffff'
- });
- entryText.anchor.set(0.5, 0.5);
- entryText.x = 1024;
- entryText.y = 450 + i * 80;
- self.entriesContainer.addChild(entryText);
- }
- }
- };
- self.down = function (x, y, obj) {
- // Check if clicking back button
- if (y > 2120 && y < 2280 && x > 900 && x < 1150) {
- self.visible = false;
- }
- };
- return self;
-});
var Missile = Container.expand(function () {
var self = Container.call(this);
var missileGraphics = self.attachAsset('missile', {
anchorX: 0.5,
@@ -378,133 +281,8 @@
}
};
return self;
});
-var StartScreen = Container.expand(function () {
- var self = Container.call(this);
- // Background overlay
- var background = LK.getAsset('road', {
- anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 1.2,
- scaleY: 20
- });
- background.x = 1024;
- background.y = 1366;
- background.tint = 0x000000;
- background.alpha = 0.8;
- self.addChild(background);
- // Title
- var titleText = new Text2('Fighter Jet Simulator', {
- size: 100,
- fill: '#ffffff'
- });
- titleText.anchor.set(0.5, 0.5);
- titleText.x = 1024;
- titleText.y = 400;
- self.addChild(titleText);
- // Name input label
- var nameLabel = new Text2('Enter Your Name:', {
- size: 60,
- fill: '#ffffff'
- });
- nameLabel.anchor.set(0.5, 0.5);
- nameLabel.x = 1024;
- nameLabel.y = 600;
- self.addChild(nameLabel);
- // Name display (simulated input)
- self.playerName = storage.playerName || 'Pilot';
- var nameDisplay = new Text2(self.playerName, {
- size: 80,
- fill: '#ffff00'
- });
- nameDisplay.anchor.set(0.5, 0.5);
- nameDisplay.x = 1024;
- nameDisplay.y = 700;
- self.addChild(nameDisplay);
- self.nameDisplay = nameDisplay;
- // Name input instructions
- var nameInstructions = new Text2('Tap to change name', {
- size: 40,
- fill: '#cccccc'
- });
- nameInstructions.anchor.set(0.5, 0.5);
- nameInstructions.x = 1024;
- nameInstructions.y = 780;
- self.addChild(nameInstructions);
- // Start game button
- var startButton = LK.getAsset('targetBuilding', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- startButton.x = 1024;
- startButton.y = 900;
- startButton.tint = 0x00ff00;
- self.addChild(startButton);
- var startText = new Text2('START GAME', {
- size: 60,
- fill: '#ffffff'
- });
- startText.anchor.set(0.5, 0.5);
- startText.x = 1024;
- startText.y = 900;
- self.addChild(startText);
- self.startButton = startButton;
- // Leaderboard button
- var leaderboardButton = LK.getAsset('targetBuilding', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- leaderboardButton.x = 1024;
- leaderboardButton.y = 1050;
- leaderboardButton.tint = 0x0088ff;
- self.addChild(leaderboardButton);
- var leaderboardText = new Text2('LEADERBOARD', {
- size: 60,
- fill: '#ffffff'
- });
- leaderboardText.anchor.set(0.5, 0.5);
- leaderboardText.x = 1024;
- leaderboardText.y = 1050;
- self.addChild(leaderboardText);
- self.leaderboardButton = leaderboardButton;
- // Predefined names for cycling
- self.nameList = ['Ace', 'Pilot', 'Maverick', 'Ghost', 'Eagle', 'Falcon', 'Storm', 'Thunder', 'Lightning', 'Phoenix'];
- self.currentNameIndex = 0;
- // Find current name index
- for (var i = 0; i < self.nameList.length; i++) {
- if (self.nameList[i] === self.playerName) {
- self.currentNameIndex = i;
- break;
- }
- }
- self.cycleName = function () {
- self.currentNameIndex = (self.currentNameIndex + 1) % self.nameList.length;
- self.playerName = self.nameList[self.currentNameIndex];
- self.nameDisplay.setText(self.playerName);
- storage.playerName = self.playerName;
- };
- self.down = function (x, y, obj) {
- // Check if clicking on name area
- if (y > 600 && y < 800 && x > 500 && x < 1500) {
- self.cycleName();
- }
- // Check if clicking start button
- else if (y > 820 && y < 980 && x > 900 && x < 1150) {
- gameState = 'playing';
- self.visible = false;
- initializeGame();
- }
- // Check if clicking leaderboard button
- else if (y > 970 && y < 1130 && x > 900 && x < 1150) {
- if (leaderboardScreen) {
- leaderboardScreen.visible = true;
- leaderboardScreen.updateLeaderboard();
- }
- }
- };
- return self;
-});
/****
* Initialize Game
****/
@@ -514,654 +292,621 @@
/****
* Game Code
****/
-// Game state management
-var gameState = 'menu'; // 'menu', 'playing', 'gameOver'
-var startScreen;
-var leaderboardScreen;
-// Initialize screens
-function initializeScreens() {
- startScreen = game.addChild(new StartScreen());
- leaderboardScreen = game.addChild(new LeaderboardScreen());
- leaderboardScreen.visible = false;
-}
-// Initialize game components
+var gameStarted = false;
+var startScreen = null;
+var startButton = null;
+// Create start screen
+startScreen = new Container();
+game.addChild(startScreen);
+// Add background for start screen
+var startBackground = LK.getAsset('road', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1,
+ scaleY: 10
+});
+startBackground.x = 1024;
+startBackground.y = 1366;
+startBackground.tint = 0x2c3e50;
+startScreen.addChild(startBackground);
+// Add title text
+var titleText = new Text2('Fighter Jet Simulator', {
+ size: 120,
+ fill: '#ffffff'
+});
+titleText.anchor.set(0.5, 0.5);
+titleText.x = 1024;
+titleText.y = 800;
+startScreen.addChild(titleText);
+// Create start button
+startButton = LK.getAsset('road', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.3,
+ scaleY: 0.8
+});
+startButton.x = 1024;
+startButton.y = 1400;
+startButton.tint = 0x27ae60;
+startScreen.addChild(startButton);
+// Add button text
+var buttonText = new Text2('START', {
+ size: 80,
+ fill: '#ffffff'
+});
+buttonText.anchor.set(0.5, 0.5);
+buttonText.x = 1024;
+buttonText.y = 1400;
+startScreen.addChild(buttonText);
+// Handle start button click
+startButton.down = function (x, y, obj) {
+ if (gameStarted) return;
+ gameStarted = true;
+ startScreen.destroy();
+ // Initialize game after start button is clicked
+ initializeGame();
+};
function initializeGame() {
- // Reset all game variables
- bullets = [];
- bombs = [];
- flares = [];
- missiles = [];
- groundTargets = [];
- explosions = [];
- destructionMarks = [];
- scrollSpeed = 3;
- spawnTimer = 0;
- gameSpeed = 1;
- bombKeyPressed = false;
- flareKeyPressed = false;
- keyStates = {};
- fKeyPressed = false;
- bKeyPressed = false;
- lastMouseX = 0;
- lastMouseY = 0;
- bombTargetX = 0;
- bombTargetY = 0;
- bombCooldown = 0;
- bombingActive = true;
- bombTargetMarked = false;
- // Reset road system
- roadSystem = {
+ fighterJet.x = 1024;
+ fighterJet.y = 2200;
+ var bullets = [];
+ var bombs = [];
+ var flares = [];
+ var missiles = [];
+ var groundTargets = [];
+ var explosions = [];
+ var destructionMarks = [];
+ var scrollSpeed = 3;
+ var spawnTimer = 0;
+ var gameSpeed = 1;
+ var roadSystem = {
roads: [],
+ // Array to track active roads
roadGraphics: [],
+ // Array to track road graphics for movement
nextRoadTime: 0,
+ // Time for next road generation
roadHeight: 80,
- generateNewRoad: true
+ // Height of road area
+ generateNewRoad: true // Flag to generate road immediately at start
};
- // Clear existing game objects
- for (var i = game.children.length - 1; i >= 0; i--) {
- var child = game.children[i];
- if (child !== startScreen && child !== leaderboardScreen) {
- child.destroy();
- }
+ var bombKeyPressed = false;
+ var flareKeyPressed = false;
+ var keyStates = {};
+ var fKeyPressed = false;
+ var bKeyPressed = false;
+ var lastMouseX = 0;
+ var lastMouseY = 0;
+ // Store bomb target position when bomb is released
+ var bombTargetX = 0;
+ var bombTargetY = 0;
+ var bombCooldown = 0;
+ var bombingActive = true;
+ var bombTargetMarked = false;
+ // UI Elements
+ var scoreText = new Text2('Score: 0', {
+ size: 60,
+ fill: '#ffffff'
+ });
+ scoreText.anchor.set(0, 0);
+ scoreText.x = 150;
+ scoreText.y = 50;
+ LK.gui.topLeft.addChild(scoreText);
+ var livesText = new Text2('Lives: 3', {
+ size: 60,
+ fill: '#ffffff'
+ });
+ livesText.anchor.set(1, 0);
+ LK.gui.topRight.addChild(livesText);
+ var flareText = new Text2('Flares: 3', {
+ size: 60,
+ fill: '#ffffff'
+ });
+ flareText.anchor.set(0.5, 0);
+ LK.gui.top.addChild(flareText);
+ var bombingText = new Text2('Bombing: Active', {
+ size: 60,
+ fill: '#ffffff'
+ });
+ bombingText.anchor.set(0.5, 0);
+ bombingText.y = 70;
+ LK.gui.top.addChild(bombingText);
+ function updateScore() {
+ scoreText.setText('Score: ' + LK.getScore());
}
- // Reset score
- LK.setScore(0);
- updateScore();
- // Create fighter jet
- fighterJet = game.addChild(new FighterJet());
- fighterJet.x = 1024;
- fighterJet.y = 2200;
- // Generate first road
- generateRoadStructure();
-}
-// Save score to leaderboard
-function saveScore() {
- var playerName = storage.playerName || 'Pilot';
- var currentScore = LK.getScore();
- var leaderboard = storage.leaderboard || {};
- // Only save if it's a better score for this player
- if (!leaderboard[playerName] || currentScore > leaderboard[playerName]) {
- leaderboard[playerName] = currentScore;
- storage.leaderboard = leaderboard;
+ function updateLivesDisplay() {
+ livesText.setText('Lives: ' + fighterJet.lives);
}
-}
-var fighterJet;
-// Initialize screens first
-initializeScreens();
-var bullets = [];
-var bombs = [];
-var flares = [];
-var missiles = [];
-var groundTargets = [];
-var explosions = [];
-var destructionMarks = [];
-var scrollSpeed = 3;
-var spawnTimer = 0;
-var gameSpeed = 1;
-var roadSystem = {
- roads: [],
- // Array to track active roads
- roadGraphics: [],
- // Array to track road graphics for movement
- nextRoadTime: 0,
- // Time for next road generation
- roadHeight: 80,
- // Height of road area
- generateNewRoad: true // Flag to generate road immediately at start
-};
-var bombKeyPressed = false;
-var flareKeyPressed = false;
-var keyStates = {};
-var fKeyPressed = false;
-var bKeyPressed = false;
-var lastMouseX = 0;
-var lastMouseY = 0;
-// Store bomb target position when bomb is released
-var bombTargetX = 0;
-var bombTargetY = 0;
-var bombCooldown = 0;
-var bombingActive = true;
-var bombTargetMarked = false;
-// UI Elements
-var scoreText = new Text2('Score: 0', {
- size: 60,
- fill: '#ffffff'
-});
-scoreText.anchor.set(0, 0);
-scoreText.x = 150;
-scoreText.y = 50;
-LK.gui.topLeft.addChild(scoreText);
-var livesText = new Text2('Lives: 3', {
- size: 60,
- fill: '#ffffff'
-});
-livesText.anchor.set(1, 0);
-LK.gui.topRight.addChild(livesText);
-var flareText = new Text2('Flares: 3', {
- size: 60,
- fill: '#ffffff'
-});
-flareText.anchor.set(0.5, 0);
-LK.gui.top.addChild(flareText);
-var bombingText = new Text2('Bombing: Active', {
- size: 60,
- fill: '#ffffff'
-});
-bombingText.anchor.set(0.5, 0);
-bombingText.y = 70;
-LK.gui.top.addChild(bombingText);
-function updateScore() {
- scoreText.setText('Score: ' + LK.getScore());
-}
-function updateLivesDisplay() {
- livesText.setText('Lives: ' + fighterJet.lives);
-}
-function updateFlareDisplay() {
- flareText.setText('Flares: ' + fighterJet.flareCount);
-}
-function updateBombingDisplay() {
- bombingText.setText('Bombing: ' + (bombingActive ? 'Active' : 'Disabled'));
-}
-function getPointsForTarget(targetType) {
- switch (targetType) {
- case 'building':
- return -10;
- // Civilian building penalty
- case 'targetBuilding':
- return 10;
- // Military building points
- case 'car':
- return -5;
- // Regular truck penalty
- case 'armyVan':
- return 5;
- // Military truck points
- case 's300System':
- return 15;
- // S-300 system points
- default:
- return 10;
+ function updateFlareDisplay() {
+ flareText.setText('Flares: ' + fighterJet.flareCount);
}
-}
-function generateRoadStructure() {
- // Check if we need to create a new road based on time
- if (roadSystem.generateNewRoad || LK.ticks >= roadSystem.nextRoadTime) {
- // Create new road at top of screen (y = 0)
- var roadY = 0;
- var road = {
- y: roadY,
- hasVehicles: true,
- // Always have vehicles (minimum 1)
- hasBuildings: true,
- // Always have buildings (minimum 1)
- vehicleCount: Math.floor(Math.random() * 4) + 1,
- // 1-4 vehicles
- buildingCount: Math.floor(Math.random() * 3) + 1 // 1-3 buildings
- };
- roadSystem.roads.push(road);
- // Draw the actual road
- var roadGraphics = LK.getAsset('road', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- roadGraphics.x = 1024; // Center of screen
- roadGraphics.y = roadY;
- roadSystem.roadGraphics.push(roadGraphics);
- game.addChild(roadGraphics);
- // Spawn vehicles on road (always at least 1)
- for (var v = 0; v < road.vehicleCount; v++) {
- var vehicleType = Math.random() < 0.6 ? 'car' : 'armyVan';
- var vehicle = new GroundTarget(vehicleType);
- vehicle.x = Math.random() * 1700 + 174; // Increased travel distance
- vehicle.y = roadY;
- groundTargets.push(vehicle);
- game.addChild(vehicle);
+ function updateBombingDisplay() {
+ bombingText.setText('Bombing: ' + (bombingActive ? 'Active' : 'Disabled'));
+ }
+ function getPointsForTarget(targetType) {
+ switch (targetType) {
+ case 'building':
+ return -10;
+ // Civilian building penalty
+ case 'targetBuilding':
+ return 10;
+ // Military building points
+ case 'car':
+ return -5;
+ // Regular truck penalty
+ case 'armyVan':
+ return 5;
+ // Military truck points
+ case 's300System':
+ return 15;
+ // S-300 system points
+ default:
+ return 10;
}
- // Spawn buildings adjacent to road (above it) - always at least 1
- var placedBuildings = []; // Track placed building positions
- for (var b = 0; b < road.buildingCount; b++) {
- var buildingType;
- var rand = Math.random();
- if (rand < 0.4) {
- buildingType = 'building';
- } else if (rand < 0.8) {
- buildingType = 'targetBuilding';
- } else if (rand < 0.82) {
- buildingType = 's300System';
- } else {
- buildingType = 's300System';
+ }
+ function generateRoadStructure() {
+ // Check if we need to create a new road based on time
+ if (roadSystem.generateNewRoad || LK.ticks >= roadSystem.nextRoadTime) {
+ // Create new road at top of screen (y = 0)
+ var roadY = 0;
+ var road = {
+ y: roadY,
+ hasVehicles: true,
+ // Always have vehicles (minimum 1)
+ hasBuildings: true,
+ // Always have buildings (minimum 1)
+ vehicleCount: Math.floor(Math.random() * 4) + 1,
+ // 1-4 vehicles
+ buildingCount: Math.floor(Math.random() * 3) + 1 // 1-3 buildings
+ };
+ roadSystem.roads.push(road);
+ // Draw the actual road
+ var roadGraphics = LK.getAsset('road', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ roadGraphics.x = 1024; // Center of screen
+ roadGraphics.y = roadY;
+ roadSystem.roadGraphics.push(roadGraphics);
+ game.addChild(roadGraphics);
+ // Spawn vehicles on road (always at least 1)
+ for (var v = 0; v < road.vehicleCount; v++) {
+ var vehicleType = Math.random() < 0.6 ? 'car' : 'armyVan';
+ var vehicle = new GroundTarget(vehicleType);
+ vehicle.x = Math.random() * 1700 + 174; // Increased travel distance
+ vehicle.y = roadY;
+ groundTargets.push(vehicle);
+ game.addChild(vehicle);
}
- // Find valid position with minimum spacing
- var attempts = 0;
- var validPosition = false;
- var buildingX, buildingY;
- while (!validPosition && attempts < 20) {
- buildingX = Math.random() * 1400 + 324; // Slightly more constrained
- buildingY = roadY - 150; // Position above road
- validPosition = true;
- // Check distance from other buildings
- for (var pb = 0; pb < placedBuildings.length; pb++) {
- var placedBuilding = placedBuildings[pb];
- var dx = buildingX - placedBuilding.x;
- var dy = buildingY - placedBuilding.y;
- var distance = Math.sqrt(dx * dx + dy * dy);
- // Minimum distance of 250 pixels between buildings
- if (distance < 250) {
- validPosition = false;
- break;
+ // Spawn buildings adjacent to road (above it) - always at least 1
+ var placedBuildings = []; // Track placed building positions
+ for (var b = 0; b < road.buildingCount; b++) {
+ var buildingType;
+ var rand = Math.random();
+ if (rand < 0.4) {
+ buildingType = 'building';
+ } else if (rand < 0.8) {
+ buildingType = 'targetBuilding';
+ } else if (rand < 0.82) {
+ buildingType = 's300System';
+ } else {
+ buildingType = 's300System';
+ }
+ // Find valid position with minimum spacing
+ var attempts = 0;
+ var validPosition = false;
+ var buildingX, buildingY;
+ while (!validPosition && attempts < 20) {
+ buildingX = Math.random() * 1400 + 324; // Slightly more constrained
+ buildingY = roadY - 150; // Position above road
+ validPosition = true;
+ // Check distance from other buildings
+ for (var pb = 0; pb < placedBuildings.length; pb++) {
+ var placedBuilding = placedBuildings[pb];
+ var dx = buildingX - placedBuilding.x;
+ var dy = buildingY - placedBuilding.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ // Minimum distance of 250 pixels between buildings
+ if (distance < 250) {
+ validPosition = false;
+ break;
+ }
}
+ attempts++;
}
- attempts++;
- }
- // Only place building if valid position found
- if (validPosition) {
- var building = new GroundTarget(buildingType);
- building.x = buildingX;
- // Raise regular buildings by 25 pixels (original 5 + additional 20)
- if (buildingType === 'building') {
- building.y = buildingY - 25;
- } else if (buildingType === 's300System') {
- building.y = buildingY + 5; // Lower military buildings by 5 pixels
- } else {
- building.y = buildingY;
+ // Only place building if valid position found
+ if (validPosition) {
+ var building = new GroundTarget(buildingType);
+ building.x = buildingX;
+ // Raise regular buildings by 25 pixels (original 5 + additional 20)
+ if (buildingType === 'building') {
+ building.y = buildingY - 25;
+ } else if (buildingType === 's300System') {
+ building.y = buildingY + 5; // Lower military buildings by 5 pixels
+ } else {
+ building.y = buildingY;
+ }
+ placedBuildings.push({
+ x: buildingX,
+ y: buildingY
+ });
+ groundTargets.push(building);
+ game.addChild(building);
}
- placedBuildings.push({
- x: buildingX,
- y: buildingY
- });
- groundTargets.push(building);
- game.addChild(building);
}
+ // Calculate next road time: 5.5 seconds average ± 1.5 seconds (330 ± 90 ticks at 60fps)
+ var baseTime = 330; // 5.5 seconds at 60fps
+ var variance = 180; // ±3 seconds total range (1.5 second variance)
+ var nextRoadDelay = baseTime + (Math.random() * variance - variance / 2);
+ roadSystem.nextRoadTime = LK.ticks + nextRoadDelay;
+ roadSystem.generateNewRoad = false;
}
- // Calculate next road time: 5.5 seconds average ± 1.5 seconds (330 ± 90 ticks at 60fps)
- var baseTime = 330; // 5.5 seconds at 60fps
- var variance = 180; // ±3 seconds total range (1.5 second variance)
- var nextRoadDelay = baseTime + (Math.random() * variance - variance / 2);
- roadSystem.nextRoadTime = LK.ticks + nextRoadDelay;
- roadSystem.generateNewRoad = false;
}
-}
-function spawnAntiAircraftSystems() {
- // Spawn S-300 systems in dead zones between roads
- if (Math.random() < 0.13) {
- // 13% chance per spawn cycle
- var s300 = new GroundTarget('s300System');
- s300.x = Math.random() * 1600 + 224;
- s300.y = -100 - Math.random() * 200; // In dead zone area
- groundTargets.push(s300);
- game.addChild(s300);
+ function spawnAntiAircraftSystems() {
+ // Spawn S-300 systems in dead zones between roads
+ if (Math.random() < 0.13) {
+ // 13% chance per spawn cycle
+ var s300 = new GroundTarget('s300System');
+ s300.x = Math.random() * 1600 + 224;
+ s300.y = -100 - Math.random() * 200; // In dead zone area
+ groundTargets.push(s300);
+ game.addChild(s300);
+ }
}
-}
-function spawnGroundTarget() {
- // This function is now called less frequently and handles structured generation
- generateRoadStructure();
- spawnAntiAircraftSystems();
-}
-function createExplosion(x, y) {
- var explosion = new Explosion();
- explosion.x = x;
- explosion.y = y;
- explosions.push(explosion);
- game.addChild(explosion);
- LK.getSound('explosion').play();
-}
-function checkMissileFlareCollision(missile) {
- for (var f = flares.length - 1; f >= 0; f--) {
- var flare = flares[f];
- if (missile.intersects(flare)) {
- // Flare explodes and destroys missiles in radius
- createExplosion(flare.x, flare.y);
- // Destroy all missiles within explosion radius
- for (var m = missiles.length - 1; m >= 0; m--) {
- var targetMissile = missiles[m];
- var dx = targetMissile.x - flare.x;
- var dy = targetMissile.y - flare.y;
- var distance = Math.sqrt(dx * dx + dy * dy);
- if (distance < 150) {
- // Explosion radius
- createExplosion(targetMissile.x, targetMissile.y);
- LK.setScore(LK.getScore() + 1); // +1 point for missile destruction by flare
- updateScore();
- targetMissile.destroy();
- missiles.splice(m, 1);
+ function spawnGroundTarget() {
+ // This function is now called less frequently and handles structured generation
+ generateRoadStructure();
+ spawnAntiAircraftSystems();
+ }
+ function createExplosion(x, y) {
+ var explosion = new Explosion();
+ explosion.x = x;
+ explosion.y = y;
+ explosions.push(explosion);
+ game.addChild(explosion);
+ LK.getSound('explosion').play();
+ }
+ function checkMissileFlareCollision(missile) {
+ for (var f = flares.length - 1; f >= 0; f--) {
+ var flare = flares[f];
+ if (missile.intersects(flare)) {
+ // Flare explodes and destroys missiles in radius
+ createExplosion(flare.x, flare.y);
+ // Destroy all missiles within explosion radius
+ for (var m = missiles.length - 1; m >= 0; m--) {
+ var targetMissile = missiles[m];
+ var dx = targetMissile.x - flare.x;
+ var dy = targetMissile.y - flare.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < 150) {
+ // Explosion radius
+ createExplosion(targetMissile.x, targetMissile.y);
+ LK.setScore(LK.getScore() + 1); // +1 point for missile destruction by flare
+ updateScore();
+ targetMissile.destroy();
+ missiles.splice(m, 1);
+ }
}
+ flare.destroy();
+ flares.splice(f, 1);
+ return true;
}
- flare.destroy();
- flares.splice(f, 1);
- return true;
}
+ return false;
}
- return false;
-}
-// Generate first road at game start
-generateRoadStructure();
-// Event handlers
-game.move = function (x, y, obj) {
- // Only update fighter jet if it exists and game is playing
- if (fighterJet && gameState === 'playing') {
+ // Generate first road at game start
+ generateRoadStructure();
+ // Event handlers
+ game.move = function (x, y, obj) {
fighterJet.x = x;
fighterJet.y = y;
- }
- // Improved keyboard input simulation with better detection
- var deltaX = Math.abs(x - lastMouseX);
- var deltaY = Math.abs(y - lastMouseY);
- // F key simulation: horizontal movement with more sensitive detection
- if (deltaX > 30 && deltaY < 30) {
- fKeyPressed = true;
- } else {
- fKeyPressed = false;
- }
- // B key simulation: vertical movement with more sensitive detection
- if (deltaY > 30 && deltaX < 30) {
- bKeyPressed = true;
- } else {
- bKeyPressed = false;
- }
- lastMouseX = x;
- lastMouseY = y;
-};
-game.down = function (x, y, obj) {
- // Check for special input zones for keyboard simulation
- if (y < 200 && x < 300) {
- // Top-left corner click - fire flare (F key simulation)
- if (fighterJet && fighterJet.flareCount > 0) {
- var flare = new Flare();
- flare.x = fighterJet.x + (Math.random() - 0.5) * 100;
- flare.y = fighterJet.y + (Math.random() - 0.5) * 100;
- flares.push(flare);
- game.addChild(flare);
- fighterJet.flareCount--;
- updateFlareDisplay();
- LK.getSound('flare').play();
+ // Improved keyboard input simulation with better detection
+ var deltaX = Math.abs(x - lastMouseX);
+ var deltaY = Math.abs(y - lastMouseY);
+ // F key simulation: horizontal movement with more sensitive detection
+ if (deltaX > 30 && deltaY < 30) {
+ fKeyPressed = true;
+ } else {
+ fKeyPressed = false;
}
- return;
- } else if (y < 200 && x > 1748) {
- // Top-right corner click - drop bomb (B key simulation)
- if (fighterJet) {
+ // B key simulation: vertical movement with more sensitive detection
+ if (deltaY > 30 && deltaX < 30) {
+ bKeyPressed = true;
+ } else {
+ bKeyPressed = false;
+ }
+ lastMouseX = x;
+ lastMouseY = y;
+ };
+ game.down = function (x, y, obj) {
+ // Check for special input zones for keyboard simulation
+ if (y < 200 && x < 300) {
+ // Top-left corner click - fire flare (F key simulation)
+ if (fighterJet.flareCount > 0) {
+ var flare = new Flare();
+ flare.x = fighterJet.x + (Math.random() - 0.5) * 100;
+ flare.y = fighterJet.y + (Math.random() - 0.5) * 100;
+ flares.push(flare);
+ game.addChild(flare);
+ fighterJet.flareCount--;
+ updateFlareDisplay();
+ LK.getSound('flare').play();
+ }
+ return;
+ } else if (y < 200 && x > 1748) {
+ // Top-right corner click - drop bomb (B key simulation)
var bomb = new Bomb();
bomb.x = fighterJet.x;
bomb.y = fighterJet.y + 50;
bombs.push(bomb);
game.addChild(bomb);
LK.getSound('bomb').play();
+ return;
}
- return;
- }
- if (obj.event && obj.event.button === 0) {
- // Left click - fire bullet
- if (fighterJet) {
+ if (obj.event && obj.event.button === 0) {
+ // Left click - fire bullet
var bullet = new Bullet();
bullet.x = fighterJet.x;
bullet.y = fighterJet.y - 50;
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
- }
- } else if (obj.event && obj.event.button === 2) {
- // Right click - drop bomb
- if (fighterJet) {
+ } else if (obj.event && obj.event.button === 2) {
+ // Right click - drop bomb
var bomb = new Bomb();
bomb.x = fighterJet.x;
bomb.y = fighterJet.y + 50;
bombs.push(bomb);
game.addChild(bomb);
LK.getSound('bomb').play();
- }
- } else if (!obj.event) {
- // Default action for touch/tap (no event object) - fire bullet
- if (fighterJet) {
+ } else if (!obj.event) {
+ // Default action for touch/tap (no event object) - fire bullet
var bullet = new Bullet();
bullet.x = fighterJet.x;
bullet.y = fighterJet.y - 50;
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
}
- }
-};
-game.update = function () {
- // Only update game logic when playing
- if (gameState !== 'playing') {
- return;
- }
- // Handle keyboard input - using LK tick-based simulation
- // Since document is not available, we'll use mouse position changes to detect special actions
- var currentFlareKeyPressed = false; // Will be triggered by specific mouse positions
- var currentBombKeyPressed = false; // Will be triggered by specific mouse positions
- // Fire flare on F key press (only once per press)
- if (fKeyPressed && !flareKeyPressed && fighterJet.flareCount > 0) {
- var flare = new Flare();
- flare.x = fighterJet.x + (Math.random() - 0.5) * 100;
- flare.y = fighterJet.y + (Math.random() - 0.5) * 100;
- flares.push(flare);
- game.addChild(flare);
- fighterJet.flareCount--;
- updateFlareDisplay();
- LK.getSound('flare').play();
- }
- flareKeyPressed = fKeyPressed;
- // Handle bomb cooldown
- if (bombCooldown > 0) {
- bombCooldown--;
- if (bombCooldown === 0) {
- bombingActive = true;
- updateBombingDisplay();
+ };
+ game.update = function () {
+ // Handle keyboard input - using LK tick-based simulation
+ // Since document is not available, we'll use mouse position changes to detect special actions
+ var currentFlareKeyPressed = false; // Will be triggered by specific mouse positions
+ var currentBombKeyPressed = false; // Will be triggered by specific mouse positions
+ // Fire flare on F key press (only once per press)
+ if (fKeyPressed && !flareKeyPressed && fighterJet.flareCount > 0) {
+ var flare = new Flare();
+ flare.x = fighterJet.x + (Math.random() - 0.5) * 100;
+ flare.y = fighterJet.y + (Math.random() - 0.5) * 100;
+ flares.push(flare);
+ game.addChild(flare);
+ fighterJet.flareCount--;
+ updateFlareDisplay();
+ LK.getSound('flare').play();
}
- }
- // Drop bomb on B key press (only once per press)
- if (bKeyPressed && !bombKeyPressed && bombingActive) {
- if (!bombTargetMarked) {
- // Calculate exact target position based on circle's current position, 55 pixels behind
- bombTargetX = fighterJet.x + fighterJet.bombTargetCircle.x;
- bombTargetY = fighterJet.y + fighterJet.bombTargetCircle.y + 60;
- bombTargetMarked = true;
- // Create and drop the bomb
- var bomb = new Bomb();
- bomb.x = fighterJet.x;
- bomb.y = fighterJet.y + 50;
- bomb.targetX = bombTargetX;
- bomb.targetY = bombTargetY;
- // Animate bomb falling to target position
- tween(bomb, {
- x: bombTargetX,
- y: bombTargetY
- }, {
- duration: 2000,
- easing: tween.easeIn,
- onFinish: function onFinish() {
- // Create big explosion at exact target
- createExplosion(bombTargetX, bombTargetY);
- // Create persistent destruction mark
- var destructionMark = new DestructionMark();
- destructionMark.x = bombTargetX;
- destructionMark.y = bombTargetY;
- destructionMarks.push(destructionMark);
- game.addChild(destructionMark);
- // Destroy ground targets in explosion radius
- for (var gt = groundTargets.length - 1; gt >= 0; gt--) {
- var target = groundTargets[gt];
- var dx = target.x - bombTargetX;
- var dy = target.y - bombTargetY;
- var distance = Math.sqrt(dx * dx + dy * dy);
- if (distance < 200) {
- // Big explosion radius
- createExplosion(target.x, target.y);
- LK.setScore(LK.getScore() + target.points);
- updateScore();
- if (target.targetType === 's300System') {
- fighterJet.aaSystemsDestroyed++;
- if (fighterJet.aaSystemsDestroyed >= 5 && fighterJet.lives < 3) {
- fighterJet.lives++;
- fighterJet.aaSystemsDestroyed = 0;
- updateLivesDisplay();
+ flareKeyPressed = fKeyPressed;
+ // Handle bomb cooldown
+ if (bombCooldown > 0) {
+ bombCooldown--;
+ if (bombCooldown === 0) {
+ bombingActive = true;
+ updateBombingDisplay();
+ }
+ }
+ // Drop bomb on B key press (only once per press)
+ if (bKeyPressed && !bombKeyPressed && bombingActive) {
+ if (!bombTargetMarked) {
+ // Calculate exact target position based on circle's current position, 55 pixels behind
+ bombTargetX = fighterJet.x + fighterJet.bombTargetCircle.x;
+ bombTargetY = fighterJet.y + fighterJet.bombTargetCircle.y + 60;
+ bombTargetMarked = true;
+ // Create and drop the bomb
+ var bomb = new Bomb();
+ bomb.x = fighterJet.x;
+ bomb.y = fighterJet.y + 50;
+ bomb.targetX = bombTargetX;
+ bomb.targetY = bombTargetY;
+ // Animate bomb falling to target position
+ tween(bomb, {
+ x: bombTargetX,
+ y: bombTargetY
+ }, {
+ duration: 2000,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ // Create big explosion at exact target
+ createExplosion(bombTargetX, bombTargetY);
+ // Create persistent destruction mark
+ var destructionMark = new DestructionMark();
+ destructionMark.x = bombTargetX;
+ destructionMark.y = bombTargetY;
+ destructionMarks.push(destructionMark);
+ game.addChild(destructionMark);
+ // Destroy ground targets in explosion radius
+ for (var gt = groundTargets.length - 1; gt >= 0; gt--) {
+ var target = groundTargets[gt];
+ var dx = target.x - bombTargetX;
+ var dy = target.y - bombTargetY;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < 200) {
+ // Big explosion radius
+ createExplosion(target.x, target.y);
+ LK.setScore(LK.getScore() + target.points);
+ updateScore();
+ if (target.targetType === 's300System') {
+ fighterJet.aaSystemsDestroyed++;
+ if (fighterJet.aaSystemsDestroyed >= 5 && fighterJet.lives < 3) {
+ fighterJet.lives++;
+ fighterJet.aaSystemsDestroyed = 0;
+ updateLivesDisplay();
+ }
}
+ target.destroy();
+ groundTargets.splice(gt, 1);
}
- target.destroy();
- groundTargets.splice(gt, 1);
}
- }
- // Remove and destroy the bomb after explosion
- bomb.destroy();
- for (var i = bombs.length - 1; i >= 0; i--) {
- if (bombs[i] === bomb) {
- bombs.splice(i, 1);
- break;
+ // Remove and destroy the bomb after explosion
+ bomb.destroy();
+ for (var i = bombs.length - 1; i >= 0; i--) {
+ if (bombs[i] === bomb) {
+ bombs.splice(i, 1);
+ break;
+ }
}
+ // Start cooldown
+ bombCooldown = 60; // 1 second at 60fps
+ bombingActive = false;
+ bombTargetMarked = false;
+ updateBombingDisplay();
}
- // Start cooldown
- bombCooldown = 60; // 1 second at 60fps
- bombingActive = false;
- bombTargetMarked = false;
- updateBombingDisplay();
- }
- });
- bombs.push(bomb);
- game.addChild(bomb);
- LK.getSound('bomb').play();
+ });
+ bombs.push(bomb);
+ game.addChild(bomb);
+ LK.getSound('bomb').play();
+ }
}
- }
- bombKeyPressed = bKeyPressed;
- spawnTimer++;
- // Generate road structures and spawn targets
- if (spawnTimer >= 30) {
- // Every 0.5 seconds for more frequent spawning
- spawnGroundTarget();
- spawnTimer = 0;
- }
- // Update road system - move roads with scroll speed and clean up
- for (var r = roadSystem.roads.length - 1; r >= 0; r--) {
- var road = roadSystem.roads[r];
- // Move road down with scroll speed
- road.y += scrollSpeed;
- // Move corresponding road graphics
- if (roadSystem.roadGraphics[r]) {
- roadSystem.roadGraphics[r].y += scrollSpeed;
+ bombKeyPressed = bKeyPressed;
+ spawnTimer++;
+ // Generate road structures and spawn targets
+ if (spawnTimer >= 30) {
+ // Every 0.5 seconds for more frequent spawning
+ spawnGroundTarget();
+ spawnTimer = 0;
}
- // Remove roads that are off screen
- if (road.y > 2800) {
- // Destroy road graphics
+ // Update road system - move roads with scroll speed and clean up
+ for (var r = roadSystem.roads.length - 1; r >= 0; r--) {
+ var road = roadSystem.roads[r];
+ // Move road down with scroll speed
+ road.y += scrollSpeed;
+ // Move corresponding road graphics
if (roadSystem.roadGraphics[r]) {
- roadSystem.roadGraphics[r].destroy();
- roadSystem.roadGraphics.splice(r, 1);
+ roadSystem.roadGraphics[r].y += scrollSpeed;
}
- roadSystem.roads.splice(r, 1);
+ // Remove roads that are off screen
+ if (road.y > 2800) {
+ // Destroy road graphics
+ if (roadSystem.roadGraphics[r]) {
+ roadSystem.roadGraphics[r].destroy();
+ roadSystem.roadGraphics.splice(r, 1);
+ }
+ roadSystem.roads.splice(r, 1);
+ }
}
- }
- // Show bomb target circle when mouse is in bombing position
- if (fighterJet.y < 2500) {
- fighterJet.bombTargetCircle.visible = true;
- } else {
- fighterJet.bombTargetCircle.visible = false;
- }
- // Update bullets
- for (var b = bullets.length - 1; b >= 0; b--) {
- var bullet = bullets[b];
- if (bullet.y < -50) {
- bullet.destroy();
- bullets.splice(b, 1);
- continue;
+ // Show bomb target circle when mouse is in bombing position
+ if (fighterJet.y < 2500) {
+ fighterJet.bombTargetCircle.visible = true;
+ } else {
+ fighterJet.bombTargetCircle.visible = false;
}
- // Check bullet vs ground targets
- for (var gt = groundTargets.length - 1; gt >= 0; gt--) {
- var target = groundTargets[gt];
- if (bullet.intersects(target)) {
- // Only allow bullets to destroy certain targets - not S-300, missile buildings, or regular buildings
- if (target.targetType === 's300System' || target.targetType === 'targetBuilding' || target.targetType === 'building') {
- // Bullets cannot destroy S-300 systems, missile buildings, or regular buildings
+ // Update bullets
+ for (var b = bullets.length - 1; b >= 0; b--) {
+ var bullet = bullets[b];
+ if (bullet.y < -50) {
+ bullet.destroy();
+ bullets.splice(b, 1);
+ continue;
+ }
+ // Check bullet vs ground targets
+ for (var gt = groundTargets.length - 1; gt >= 0; gt--) {
+ var target = groundTargets[gt];
+ if (bullet.intersects(target)) {
+ // Only allow bullets to destroy certain targets - not S-300, missile buildings, or regular buildings
+ if (target.targetType === 's300System' || target.targetType === 'targetBuilding' || target.targetType === 'building') {
+ // Bullets cannot destroy S-300 systems, missile buildings, or regular buildings
+ bullet.destroy();
+ bullets.splice(b, 1);
+ break;
+ }
+ createExplosion(target.x, target.y);
+ // Apply scoring based on target type
+ LK.setScore(LK.getScore() + target.points);
+ updateScore();
bullet.destroy();
bullets.splice(b, 1);
+ target.destroy();
+ groundTargets.splice(gt, 1);
break;
}
- createExplosion(target.x, target.y);
- // Apply scoring based on target type
- LK.setScore(LK.getScore() + target.points);
- updateScore();
- bullet.destroy();
- bullets.splice(b, 1);
- target.destroy();
- groundTargets.splice(gt, 1);
- break;
}
}
- }
- // Update bombs - cleanup only
- for (var bo = bombs.length - 1; bo >= 0; bo--) {
- var bomb = bombs[bo];
- if (bomb.destroyed) {
- bombs.splice(bo, 1);
+ // Update bombs - cleanup only
+ for (var bo = bombs.length - 1; bo >= 0; bo--) {
+ var bomb = bombs[bo];
+ if (bomb.destroyed) {
+ bombs.splice(bo, 1);
+ }
}
- }
- // Update missiles
- for (var m = missiles.length - 1; m >= 0; m--) {
- var missile = missiles[m];
- // Skip if missile doesn't exist (already removed)
- if (!missile) {
- continue;
+ // Update missiles
+ for (var m = missiles.length - 1; m >= 0; m--) {
+ var missile = missiles[m];
+ // Skip if missile doesn't exist (already removed)
+ if (!missile) {
+ continue;
+ }
+ // Update missile target to current fighter jet position
+ missile.targetX = fighterJet.x;
+ missile.targetY = fighterJet.y;
+ // Check if missile was intercepted by flare
+ if (checkMissileFlareCollision(missile)) {
+ missiles.splice(m, 1);
+ continue;
+ }
+ // Check missile vs fighter jet (only the jet graphics, not the targeting circle)
+ // Calculate distance to jet center for more precise collision
+ var dx = missile.x - fighterJet.x;
+ var dy = missile.y - fighterJet.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ // Only consider collision if missile is close to the actual jet (not the targeting circle)
+ if (distance < 60) {
+ // Jet is 120x80, so radius of ~60 should cover the jet body
+ createExplosion(fighterJet.x, fighterJet.y);
+ fighterJet.lives--;
+ updateLivesDisplay();
+ if (fighterJet.lives <= 0) {
+ LK.showGameOver();
+ return;
+ }
+ missile.destroy();
+ missiles.splice(m, 1);
+ continue;
+ }
+ // Remove missiles that go off screen
+ if (missile.y > 2800 || missile.y < -50 || missile.x < -50 || missile.x > 2100) {
+ missile.destroy();
+ missiles.splice(m, 1);
+ }
}
- // Update missile target to current fighter jet position
- missile.targetX = fighterJet.x;
- missile.targetY = fighterJet.y;
- // Check if missile was intercepted by flare
- if (checkMissileFlareCollision(missile)) {
- missiles.splice(m, 1);
- continue;
+ // Update ground targets
+ for (var gt = groundTargets.length - 1; gt >= 0; gt--) {
+ var target = groundTargets[gt];
+ if (target.y > 2800) {
+ target.destroy();
+ groundTargets.splice(gt, 1);
+ }
}
- // Check missile vs fighter jet (only the jet graphics, not the targeting circle)
- // Calculate distance to jet center for more precise collision
- var dx = missile.x - fighterJet.x;
- var dy = missile.y - fighterJet.y;
- var distance = Math.sqrt(dx * dx + dy * dy);
- // Only consider collision if missile is close to the actual jet (not the targeting circle)
- if (distance < 60) {
- // Jet is 120x80, so radius of ~60 should cover the jet body
- createExplosion(fighterJet.x, fighterJet.y);
- fighterJet.lives--;
- updateLivesDisplay();
- if (fighterJet.lives <= 0) {
- saveScore();
- gameState = 'menu';
- startScreen.visible = true;
- return;
+ // Update flares
+ for (var f = flares.length - 1; f >= 0; f--) {
+ var flare = flares[f];
+ if (flare.destroyed) {
+ flares.splice(f, 1);
}
- missile.destroy();
- missiles.splice(m, 1);
- continue;
}
- // Remove missiles that go off screen
- if (missile.y > 2800 || missile.y < -50 || missile.x < -50 || missile.x > 2100) {
- missile.destroy();
- missiles.splice(m, 1);
+ // Update explosions
+ for (var e = explosions.length - 1; e >= 0; e--) {
+ var explosion = explosions[e];
+ if (explosion.destroyed) {
+ explosions.splice(e, 1);
+ }
}
- }
- // Update ground targets
- for (var gt = groundTargets.length - 1; gt >= 0; gt--) {
- var target = groundTargets[gt];
- if (target.y > 2800) {
- target.destroy();
- groundTargets.splice(gt, 1);
+ // Update destruction marks
+ for (var dm = destructionMarks.length - 1; dm >= 0; dm--) {
+ var destructionMark = destructionMarks[dm];
+ if (destructionMark.y > 2800) {
+ destructionMark.destroy();
+ destructionMarks.splice(dm, 1);
+ }
}
- }
- // Update flares
- for (var f = flares.length - 1; f >= 0; f--) {
- var flare = flares[f];
- if (flare.destroyed) {
- flares.splice(f, 1);
- }
- }
- // Update explosions
- for (var e = explosions.length - 1; e >= 0; e--) {
- var explosion = explosions[e];
- if (explosion.destroyed) {
- explosions.splice(e, 1);
- }
- }
- // Update destruction marks
- for (var dm = destructionMarks.length - 1; dm >= 0; dm--) {
- var destructionMark = destructionMarks[dm];
- if (destructionMark.y > 2800) {
- destructionMark.destroy();
- destructionMarks.splice(dm, 1);
- }
- }
-};
\ No newline at end of file
+ };
+}
\ No newline at end of file
B-2 bombing jet. In-Game asset. 2d. High contrast. No shadows
S-300 Anti Air system from the bird view. In-Game asset. 2d. High contrast. No shadows
Hi-Teck buikding. In-Game asset. 2d. High contrast. No shadows
Tiny missile pointing up. In-Game asset. 2d. High contrast. No shadows
Strait anti air missile. In-Game asset. 2d. High contrast. No shadows
strait flare missile. In-Game asset. 2d. High contrast. No shadows
WW2 bomb. In-Game asset. 2d. High contrast. No shadows
Army building. In-Game asset. 2d. High contrast. No shadows
רכב צבאי ארוך וגדול, כמו תובלתית, מכוסה בברזנט, מבט מהפרופיל.
Missiles storage. In-Game asset. 2d. High contrast. No shadows
מתקן ענק לשיגור טיל שעליו מוכן טיל גרעיני. In-Game asset. 2d. High contrast. No shadows