Code edit (1 edits merged)
Please save this source code
User prompt
add sound for each event.
User prompt
write a small orange “Glaud” in a logical place on the screen. write it as text.
User prompt
write a small orange “Glaud” in a logical place on the screen.
User prompt
add a small orange “Glaud” in a logical place on the screen.
User prompt
add a small orange “Glaud” in a logical place on the screen.
User prompt
Make the text visible on the screen. The design should be good.
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'width')' in or related to this line: 'if (self.x > LK.game.width + padding) {' Line Number: 49
User prompt
Identify and solve some basic logic errors in the game.
User prompt
Identify the features that will make it better and implement them in an optimized way, don't make any mistakes, it's clean and playable. Make it a user-friendly game. ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Cosmic Cargo Commander
Initial prompt
game
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Asteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5 }); self.speedX = 0; self.speedY = 0; self.rotationSpeed = (Math.random() - 0.5) * 0.04; self.update = function () { self.x += self.speedX; self.y += self.speedY; asteroidGraphics.rotation += self.rotationSpeed; // Wrap around screen var padding = asteroidGraphics.width / 2; // Use asset size for padding if (self.x < -padding) { self.x = 2048 + padding; // Use fixed width } if (self.x > 2048 + padding) { // Use fixed width self.x = -padding; } if (self.y < -padding) { self.y = 2732 + padding; // Use fixed height } if (self.y > 2732 + padding) { // Use fixed height self.y = -padding; } }; return self; }); var CargoContainer = Container.expand(function () { var self = Container.call(this); var cargoGraphics = self.attachAsset('cargoContainer', { anchorX: 0.5, anchorY: 0.5 }); self.bobSpeed = 0.02; self.bobAmount = 5; self.bobPhase = Math.random() * Math.PI * 2; self.originalY = 0; self.update = function () { self.bobPhase += self.bobSpeed; if (self.originalY) { self.y = self.originalY + Math.sin(self.bobPhase) * self.bobAmount; } }; return self; }); var CargoShip = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('cargoShip', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.fuel = 100; self.maxFuel = 100; self.fuelConsumption = 0.05; self.cargoCapacity = 3; self.cargo = 0; self.shieldActive = false; self.magnetActive = false; self.magnetRange = 300; // Create visual shield effect var shield = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, alpha: 0.4 }); shield.visible = false; // Create visual magnet effect var magnetIndicator = self.attachAsset('magnet', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, scaleX: 0.5, scaleY: 0.5 }); magnetIndicator.visible = false; self.activateShield = function (duration) { if (!self.shieldActive) { LK.getSound('shieldActivate').play(); // Play activation sound self.shieldActive = true; shield.visible = true; shield.alpha = 0.1; // Animate shield appearance tween(shield, { alpha: 0.6 }, { duration: 500, easing: tween.elasticOut }); LK.setTimeout(function () { // Fade out shield when expiring tween(shield, { alpha: 0 }, { duration: 800, onFinish: function onFinish() { self.shieldActive = false; shield.visible = false; shield.alpha = 0.4; } }); }, duration || 5000); } }; self.activateMagnet = function (duration) { if (!self.magnetActive) { var _pulseMagnet = function pulseMagnet() { if (self.magnetActive) { tween(magnetIndicator, { alpha: 0.2 }, { duration: 800, onFinish: function onFinish() { if (self.magnetActive) { tween(magnetIndicator, { alpha: 0.5 }, { duration: 800, onFinish: _pulseMagnet }); } } }); } }; LK.getSound('magnetActivate').play(); // Play activation sound self.magnetActive = true; magnetIndicator.visible = true; magnetIndicator.alpha = 0.2; magnetIndicator.scale.set(0.5, 0.5); // Animate magnet field appearance tween(magnetIndicator, { alpha: 0.5, scaleX: 6, scaleY: 6 }, { duration: 800, easing: tween.elasticOut }); // Pulse the magnet field _pulseMagnet(); LK.setTimeout(function () { // Fade out magnet field when expiring tween(magnetIndicator, { alpha: 0, scaleX: 10, scaleY: 10 }, { duration: 1000, onFinish: function onFinish() { self.magnetActive = false; magnetIndicator.visible = false; magnetIndicator.scale.set(0.5, 0.5); } }); }, duration || 5000); } }; self.consumeFuel = function () { self.fuel -= self.fuelConsumption; if (self.fuel <= 0) { self.fuel = 0; } if (self.fuel <= 20 && self.fuel > 19.95) { LK.getSound('lowFuel').play(); } }; self.refuel = function (amount) { self.fuel = Math.min(self.fuel + amount, self.maxFuel); }; self.pickupCargo = function () { if (self.cargo < self.cargoCapacity) { self.cargo++; return true; } return false; }; self.deliverCargo = function () { var delivered = self.cargo; self.cargo = 0; return delivered; }; return self; }); var EnemyDrone = Container.expand(function () { var self = Container.call(this); var droneGraphics = self.attachAsset('enemyDrone', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.target = null; self.patrolRadius = 300; self.patrolCenter = { x: 0, y: 0 }; self.patrolAngle = Math.random() * Math.PI * 2; self.patrolSpeed = 0.01; self.setPatrolCenter = function (x, y, radius) { self.patrolCenter.x = x; self.patrolCenter.y = y; if (radius) { self.patrolRadius = radius; } }; self.setTarget = function (target) { self.target = target; }; self.update = function () { if (self.target) { // Move toward target var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 5) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } } else { // Patrol in a circle self.patrolAngle += self.patrolSpeed; self.x = self.patrolCenter.x + Math.cos(self.patrolAngle) * self.patrolRadius; self.y = self.patrolCenter.y + Math.sin(self.patrolAngle) * self.patrolRadius; } }; return self; }); var Powerup = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'fuel'; var assetType; switch (self.type) { case 'fuel': assetType = 'fuelPowerup'; break; case 'shield': assetType = 'shieldPowerup'; break; case 'magnet': assetType = 'magnet'; break; default: assetType = 'fuelPowerup'; } var powerupGraphics = self.attachAsset(assetType, { anchorX: 0.5, anchorY: 0.5 }); self.bobSpeed = 0.03; self.bobAmount = 5; self.bobPhase = Math.random() * Math.PI * 2; self.originalY = 0; self.rotationSpeed = 0.02; self.update = function () { self.bobPhase += self.bobSpeed; powerupGraphics.rotation += self.rotationSpeed; if (self.originalY) { self.y = self.originalY + Math.sin(self.bobPhase) * self.bobAmount; } }; return self; }); var SpaceStation = Container.expand(function () { var self = Container.call(this); var stationGraphics = self.attachAsset('spaceStation', { anchorX: 0.5, anchorY: 0.5 }); self.rotationSpeed = 0.002; self.isFlashing = false; self.pulseTime = 0; self.pulseFrequency = 0.05; // Function to make the station flash to indicate it's ready for delivery self.startFlashing = function () { if (!self.isFlashing) { var _flashCycle = function flashCycle() { if (self.isFlashing) { tween(stationGraphics, { tint: 0xf1c40f }, { duration: 800, onFinish: function onFinish() { if (self.isFlashing) { tween(stationGraphics, { tint: 0x9b59b6 }, { duration: 800, onFinish: _flashCycle }); } } }); } }; self.isFlashing = true; // Flash between colors _flashCycle(); } }; // Function to stop flashing self.stopFlashing = function () { self.isFlashing = false; tween(stationGraphics, { tint: 0x9b59b6 }, { duration: 400 }); }; self.update = function () { stationGraphics.rotation += self.rotationSpeed; // Pulse effect self.pulseTime += self.pulseFrequency; var pulseFactor = 1 + Math.sin(self.pulseTime) * 0.1; stationGraphics.scale.set(pulseFactor, pulseFactor); }; // Start flashing by default self.startFlashing(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000033 }); /**** * Game Code ****/ // Game state var ship; var asteroids = []; var cargoContainers = []; var spaceStations = []; var enemyDrones = []; var powerups = []; var fuelBarBg; var fuelBarFront; var cargoText; var scoreText; var levelText; var highScoreText; var gameActive = true; var level = 1; var score = 0; var highScore = storage.highScore || 0; var destX = 0; var destY = 0; var dragNode = null; var rotationTween = null; // Added to track ship rotation tween var lastSpawnTime = 0; var difficultyTimer; // Initialize UI elements function initUI() { // Score text scoreText = new Text2('Score: 0', { size: 70, // Increased size fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); scoreText.y = 10; // Position adjusted slightly if needed, but 10 seems okay LK.gui.top.addChild(scoreText); // High score text highScoreText = new Text2('Best: ' + highScore, { size: 50, // Increased size fill: 0xFFFFFF }); highScoreText.anchor.set(0.5, 0); highScoreText.y = 90; // Adjusted y position to account for larger scoreText above LK.gui.top.addChild(highScoreText); // Level text levelText = new Text2('Level: 1', { size: 70, // Increased size fill: 0xFFFFFF }); levelText.anchor.set(1, 0); levelText.x = -50; levelText.y = 10; LK.gui.topRight.addChild(levelText); // Cargo text cargoText = new Text2('Cargo: 0/3', { size: 70, // Increased size fill: 0xFFFFFF }); cargoText.anchor.set(0, 0); cargoText.x = 120; // Moved further right to avoid menu icon cargoText.y = 10; LK.gui.topLeft.addChild(cargoText); // Fuel bar background fuelBarBg = LK.getAsset('fuelBarBackground', { anchorX: 0.5, anchorY: 0.5 }); fuelBarBg.x = 0; fuelBarBg.y = 40; LK.gui.bottom.addChild(fuelBarBg); // Fuel bar fuelBarFront = LK.getAsset('fuelBar', { anchorX: 0, anchorY: 0.5 }); fuelBarFront.x = -fuelBarBg.width / 2; fuelBarFront.y = 40; LK.gui.bottom.addChild(fuelBarFront); // Add visual labels var fuelLabel = new Text2('FUEL', { size: 45, // Increased size fill: 0xFFFFFF }); fuelLabel.anchor.set(0.5, 0.5); fuelLabel.y = 40; // Position remains centered on the bar LK.gui.bottom.addChild(fuelLabel); } // Create cargo ship function createShip() { ship = new CargoShip(); ship.x = 2048 / 2; ship.y = 2732 / 2; game.addChild(ship); } // Create random asteroid function createAsteroid() { var asteroid = new Asteroid(); // Random position on the edge of the screen var side = Math.floor(Math.random() * 4); switch (side) { case 0: // Top asteroid.x = Math.random() * 2048; asteroid.y = -100; break; case 1: // Right asteroid.x = 2148; asteroid.y = Math.random() * 2732; break; case 2: // Bottom asteroid.x = Math.random() * 2048; asteroid.y = 2832; break; case 3: // Left asteroid.x = -100; asteroid.y = Math.random() * 2732; break; } // Random speed (higher in higher levels) var baseSpeed = 2 + level * 0.5; var speed = baseSpeed * (0.5 + Math.random() * 0.5); // Direction toward center with some randomness var targetX = 2048 / 2 + (Math.random() - 0.5) * 1000; var targetY = 2732 / 2 + (Math.random() - 0.5) * 1000; var dx = targetX - asteroid.x; var dy = targetY - asteroid.y; var dist = Math.sqrt(dx * dx + dy * dy); asteroid.speedX = dx / dist * speed; asteroid.speedY = dy / dist * speed; // Scale randomly var scale = 0.8 + Math.random() * 0.8; asteroid.scale.set(scale, scale); asteroids.push(asteroid); game.addChild(asteroid); } // Create cargo container function createCargoContainer() { var container = new CargoContainer(); // Random position (not too close to the edge) container.x = 200 + Math.random() * (2048 - 400); container.y = 200 + Math.random() * (2732 - 400); container.originalY = container.y; cargoContainers.push(container); game.addChild(container); } // Create space station function createSpaceStation() { var station = new SpaceStation(); // Position near an edge but not too close var side = Math.floor(Math.random() * 4); switch (side) { case 0: // Top station.x = 400 + Math.random() * (2048 - 800); station.y = 300; break; case 1: // Right station.x = 2048 - 300; station.y = 400 + Math.random() * (2732 - 800); break; case 2: // Bottom station.x = 400 + Math.random() * (2048 - 800); station.y = 2732 - 300; break; case 3: // Left station.x = 300; station.y = 400 + Math.random() * (2732 - 800); break; } spaceStations.push(station); game.addChild(station); } // Create enemy drone function createEnemyDrone() { var drone = new EnemyDrone(); // Random position drone.x = Math.random() * 2048; drone.y = Math.random() * 2732; // Set patrol area drone.setPatrolCenter(drone.x, drone.y, 200 + Math.random() * 200); // Set speed based on level drone.speed = 1 + level * 0.3; enemyDrones.push(drone); game.addChild(drone); } // Create powerup function createPowerup(type) { if (!type) { var types = ['fuel', 'shield', 'magnet']; type = types[Math.floor(Math.random() * types.length)]; } var powerup = new Powerup(type); // Random position (not too close to the edge) powerup.x = 300 + Math.random() * (2048 - 600); powerup.y = 300 + Math.random() * (2732 - 600); powerup.originalY = powerup.y; powerups.push(powerup); game.addChild(powerup); } // Spawn game objects based on level function spawnObjects() { var currentTime = Date.now(); // Only spawn new objects every 1-3 seconds depending on level var spawnRate = Math.max(3000 - level * 200, 1000); if (currentTime - lastSpawnTime > spawnRate) { // Spawn asteroid if (asteroids.length < 5 + level * 2) { createAsteroid(); } // Spawn cargo if (cargoContainers.length < 3 + Math.floor(level / 2)) { createCargoContainer(); } // Spawn enemy drones in higher levels if (level >= 2 && enemyDrones.length < level - 1) { createEnemyDrone(); } // Spawn powerup (less frequently) if (Math.random() < 0.2) { createPowerup(); } lastSpawnTime = currentTime; } } // Update ship movement based on destination function updateShipMovement() { if (destX && destY) { var dx = destX - ship.x; var dy = destY - ship.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 5) { // Calculate rotation angle to face destination var angle = Math.atan2(dy, dx); // Rotate ship to face direction of travel // Stop existing rotation tween if it exists and is running if (rotationTween && rotationTween.playing) { rotationTween.stop(); } rotationTween = tween(ship, { rotation: angle }, { duration: 150 // Slightly faster rotation }); // Move toward destination ship.x += dx / dist * ship.speed; ship.y += dy / dist * ship.speed; // Consume fuel while moving ship.consumeFuel(); } } } // Update enemy drones function updateEnemyDrones() { for (var i = 0; i < enemyDrones.length; i++) { var drone = enemyDrones[i]; // Set ship as target if it's close var dx = ship.x - drone.x; var dy = ship.y - drone.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 500) { drone.setTarget(ship); } else { drone.setTarget(null); } } } // Update UI elements function updateUI() { // Update fuel bar var fuelPercentage = ship.fuel / ship.maxFuel; fuelBarFront.width = fuelBarBg.width * fuelPercentage; // Change fuel bar color based on level if (fuelPercentage <= 0.2) { fuelBarFront.tint = 0xe74c3c; // Red } else if (fuelPercentage <= 0.5) { fuelBarFront.tint = 0xf39c12; // Orange } else { fuelBarFront.tint = 0x27ae60; // Green } // Update text displays cargoText.setText('Cargo: ' + ship.cargo + '/' + ship.cargoCapacity); scoreText.setText('Score: ' + score); levelText.setText('Level: ' + level); } // Check for ship collisions with game objects function checkCollisions() { // Check asteroid collisions for (var i = asteroids.length - 1; i >= 0; i--) { var asteroid = asteroids[i]; if (ship.intersects(asteroid)) { if (ship.shieldActive) { // Destroy asteroid if shield is active asteroid.destroy(); asteroids.splice(i, 1); // Play collision sound LK.getSound('collision').play(); // Add points score += 5; } else { // Game over if no shield gameOver(); return; } } } // Check enemy drone collisions for (var i = enemyDrones.length - 1; i >= 0; i--) { var drone = enemyDrones[i]; if (ship.intersects(drone)) { if (ship.shieldActive) { // Destroy drone if shield is active drone.destroy(); enemyDrones.splice(i, 1); // Play collision sound LK.getSound('collision').play(); // Add points score += 10; } else { // Game over if no shield gameOver(); return; } } } // Check cargo container pickups for (var i = cargoContainers.length - 1; i >= 0; i--) { var container = cargoContainers[i]; // Check direct collision if (ship.intersects(container)) { if (ship.pickupCargo()) { // Remove container and add points container.destroy(); cargoContainers.splice(i, 1); // Play pickup sound LK.getSound('pickup').play(); // Add points score += 10; } } // Check magnet range else if (ship.magnetActive) { var dx = ship.x - container.x; var dy = ship.y - container.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < ship.magnetRange) { // Move container toward ship container.x += dx / dist * 5; container.y += dy / dist * 5; container.originalY = container.y; } } } // Check space station delivery for (var i = 0; i < spaceStations.length; i++) { var station = spaceStations[i]; // Update flashing based on cargo status // Only call startFlashing if cargo exists AND the station isn't already flashing if (ship.cargo > 0 && !station.isFlashing) { station.startFlashing(); } // Only call stopFlashing if cargo is zero AND the station is currently flashing else if (ship.cargo <= 0 && station.isFlashing) { station.stopFlashing(); } if (ship.intersects(station) && ship.cargo > 0) { // Deliver cargo var deliveredCargo = ship.deliverCargo(); // Add points var deliveryPoints = deliveredCargo * 25; score += deliveryPoints; // Play delivery sound LK.getSound('delivery').play(); // Flash screen green LK.effects.flashScreen(0x27ae60, 300); // Visual success feedback tween(station, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, onFinish: function onFinish() { tween(station, { scaleX: 1, scaleY: 1 }, { duration: 300 }); } }); // Check for level up if (score >= level * 100) { levelUp(); } } } // Check powerup pickups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; if (ship.intersects(powerup)) { // Apply powerup effect switch (powerup.type) { case 'fuel': ship.refuel(50); break; case 'shield': ship.activateShield(8000); break; case 'magnet': ship.activateMagnet(10000); break; } // Play powerup sound LK.getSound('powerup').play(); // Add points score += 5; // Remove powerup powerup.destroy(); powerups.splice(i, 1); } } // Check if out of fuel if (ship.fuel <= 0 && gameActive) { gameOver(); } } // Level up function function levelUp() { LK.getSound('levelUp').play(); // Play level up sound level++; // Update level text levelText.setText('Level: ' + level); // Flash screen LK.effects.flashScreen(0xf1c40f, 500); // Show level up message var levelUpText = new Text2('LEVEL UP!', { size: 120, fill: 0xf1c40f }); levelUpText.anchor.set(0.5, 0.5); levelUpText.alpha = 0; LK.gui.center.addChild(levelUpText); tween(levelUpText, { alpha: 1, scaleX: 1.5, scaleY: 1.5 }, { duration: 700, easing: tween.elasticOut, onFinish: function onFinish() { tween(levelUpText, { alpha: 0 }, { duration: 700, onFinish: function onFinish() { levelUpText.destroy(); } }); } }); // Create new space station if needed if (spaceStations.length < Math.min(3, Math.floor(level / 2) + 1)) { createSpaceStation(); } // Increase ship speed slightly ship.speed = 6 + level * 0.3; // Add visual effects to ship to indicate power increase tween(ship, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, onFinish: function onFinish() { tween(ship, { scaleX: 1, scaleY: 1 }, { duration: 300 }); } }); } // Game over function function gameOver() { LK.getSound('gameOver').play(); // Play game over sound gameActive = false; // Flash screen red LK.effects.flashScreen(0xe74c3c, 1000); // Update high score if needed if (score > highScore) { highScore = score; storage.highScore = highScore; // Visual feedback for new high score var newHighScoreText = new Text2('NEW HIGH SCORE!', { size: 80, fill: 0xf1c40f }); newHighScoreText.anchor.set(0.5, 0.5); newHighScoreText.alpha = 0; LK.gui.center.addChild(newHighScoreText); tween(newHighScoreText, { alpha: 1, scaleX: 1.2, scaleY: 1.2 }, { duration: 800, easing: tween.elasticOut }); LK.setTimeout(function () { tween(newHighScoreText, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { newHighScoreText.destroy(); } }); }, 2000); } // Set final score LK.setScore(score); // Show game over LK.showGameOver(); } // Tutorial system var tutorialSteps = ["Tap to guide your ship to that location", "Collect floating cargo containers", "Deliver cargo to the flashing space station", "Watch your fuel level at the bottom", "Avoid asteroids - collect shields for protection", "Deliver more cargo to level up!"]; var currentTutorialStep = 0; var tutorialText; var tutorialShown = storage.tutorialShown || false; function showTutorialStep() { if (!tutorialText) { tutorialText = new Text2(tutorialSteps[0], { size: 70, fill: 0xFFFFFF }); tutorialText.anchor.set(0.5, 0.5); LK.gui.center.addChild(tutorialText); } if (currentTutorialStep < tutorialSteps.length) { tutorialText.setText(tutorialSteps[currentTutorialStep]); tutorialText.alpha = 0; tween(tutorialText, { alpha: 1 }, { duration: 500 }); LK.setTimeout(function () { // Check if tutorialText still exists before tweening if (tutorialText && tutorialText.parent) { tween(tutorialText, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { // Check if tutorialText still exists before proceeding if (tutorialText && tutorialText.parent) { currentTutorialStep++; if (currentTutorialStep < tutorialSteps.length) { LK.setTimeout(showTutorialStep, 1000); } else { tutorialText.destroy(); tutorialText = null; storage.tutorialShown = true; } } else { // If text was destroyed elsewhere, ensure flag is set storage.tutorialShown = true; tutorialText = null; // Clear reference } } }); } else { // If text was destroyed elsewhere, ensure flag is set storage.tutorialShown = true; tutorialText = null; // Clear reference } }, 4000); } } // Initialize game function initGame() { // Initialize UI initUI(); // Create ship createShip(); // Create initial objects for (var i = 0; i < 5; i++) { createAsteroid(); } for (var i = 0; i < 3; i++) { createCargoContainer(); } // Create initial space station createSpaceStation(); // Create initial powerup createPowerup('fuel'); // Start background music LK.playMusic('gameMusic'); // Show tutorial for new players if (!tutorialShown) { LK.setTimeout(showTutorialStep, 1000); } // Add Glaud text element var glaudText = new Text2('Glaud', { size: 60, fill: 0xffa500 // Orange color }); glaudText.anchor.set(0, 1); // Anchor bottom-left // Position Glaud in the bottom-left corner (away from the fuel bar and top-left menu) glaudText.x = 50; // Padding from left edge, ensuring it's not in the top-left 100x100 area glaudText.y = 2732 - 120; // Padding from bottom edge, positioned above the fuel bar GUI elements game.addChild(glaudText); // Add text to the main game stage } function handleDown(x, y, obj) { destX = x; destY = y; dragNode = ship; // Set dragNode to enable dragging in handleMove } // Handle game moves function handleMove(x, y, obj) { if (dragNode) { destX = x; destY = y; } } // Handle game releases function handleUp(x, y, obj) { dragNode = null; } // Set event handlers game.down = handleDown; game.move = handleMove; game.up = handleUp; // Initialize the game initGame(); // Game update loop game.update = function () { if (gameActive) { // Spawn new objects based on level spawnObjects(); // Update ship movement updateShipMovement(); // Update enemy drones updateEnemyDrones(); // Check collisions checkCollisions(); // Update UI updateUI(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Asteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.rotationSpeed = (Math.random() - 0.5) * 0.04;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
asteroidGraphics.rotation += self.rotationSpeed;
// Wrap around screen
var padding = asteroidGraphics.width / 2; // Use asset size for padding
if (self.x < -padding) {
self.x = 2048 + padding; // Use fixed width
}
if (self.x > 2048 + padding) {
// Use fixed width
self.x = -padding;
}
if (self.y < -padding) {
self.y = 2732 + padding; // Use fixed height
}
if (self.y > 2732 + padding) {
// Use fixed height
self.y = -padding;
}
};
return self;
});
var CargoContainer = Container.expand(function () {
var self = Container.call(this);
var cargoGraphics = self.attachAsset('cargoContainer', {
anchorX: 0.5,
anchorY: 0.5
});
self.bobSpeed = 0.02;
self.bobAmount = 5;
self.bobPhase = Math.random() * Math.PI * 2;
self.originalY = 0;
self.update = function () {
self.bobPhase += self.bobSpeed;
if (self.originalY) {
self.y = self.originalY + Math.sin(self.bobPhase) * self.bobAmount;
}
};
return self;
});
var CargoShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('cargoShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.fuel = 100;
self.maxFuel = 100;
self.fuelConsumption = 0.05;
self.cargoCapacity = 3;
self.cargo = 0;
self.shieldActive = false;
self.magnetActive = false;
self.magnetRange = 300;
// Create visual shield effect
var shield = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.4
});
shield.visible = false;
// Create visual magnet effect
var magnetIndicator = self.attachAsset('magnet', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
magnetIndicator.visible = false;
self.activateShield = function (duration) {
if (!self.shieldActive) {
LK.getSound('shieldActivate').play(); // Play activation sound
self.shieldActive = true;
shield.visible = true;
shield.alpha = 0.1;
// Animate shield appearance
tween(shield, {
alpha: 0.6
}, {
duration: 500,
easing: tween.elasticOut
});
LK.setTimeout(function () {
// Fade out shield when expiring
tween(shield, {
alpha: 0
}, {
duration: 800,
onFinish: function onFinish() {
self.shieldActive = false;
shield.visible = false;
shield.alpha = 0.4;
}
});
}, duration || 5000);
}
};
self.activateMagnet = function (duration) {
if (!self.magnetActive) {
var _pulseMagnet = function pulseMagnet() {
if (self.magnetActive) {
tween(magnetIndicator, {
alpha: 0.2
}, {
duration: 800,
onFinish: function onFinish() {
if (self.magnetActive) {
tween(magnetIndicator, {
alpha: 0.5
}, {
duration: 800,
onFinish: _pulseMagnet
});
}
}
});
}
};
LK.getSound('magnetActivate').play(); // Play activation sound
self.magnetActive = true;
magnetIndicator.visible = true;
magnetIndicator.alpha = 0.2;
magnetIndicator.scale.set(0.5, 0.5);
// Animate magnet field appearance
tween(magnetIndicator, {
alpha: 0.5,
scaleX: 6,
scaleY: 6
}, {
duration: 800,
easing: tween.elasticOut
});
// Pulse the magnet field
_pulseMagnet();
LK.setTimeout(function () {
// Fade out magnet field when expiring
tween(magnetIndicator, {
alpha: 0,
scaleX: 10,
scaleY: 10
}, {
duration: 1000,
onFinish: function onFinish() {
self.magnetActive = false;
magnetIndicator.visible = false;
magnetIndicator.scale.set(0.5, 0.5);
}
});
}, duration || 5000);
}
};
self.consumeFuel = function () {
self.fuel -= self.fuelConsumption;
if (self.fuel <= 0) {
self.fuel = 0;
}
if (self.fuel <= 20 && self.fuel > 19.95) {
LK.getSound('lowFuel').play();
}
};
self.refuel = function (amount) {
self.fuel = Math.min(self.fuel + amount, self.maxFuel);
};
self.pickupCargo = function () {
if (self.cargo < self.cargoCapacity) {
self.cargo++;
return true;
}
return false;
};
self.deliverCargo = function () {
var delivered = self.cargo;
self.cargo = 0;
return delivered;
};
return self;
});
var EnemyDrone = Container.expand(function () {
var self = Container.call(this);
var droneGraphics = self.attachAsset('enemyDrone', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.target = null;
self.patrolRadius = 300;
self.patrolCenter = {
x: 0,
y: 0
};
self.patrolAngle = Math.random() * Math.PI * 2;
self.patrolSpeed = 0.01;
self.setPatrolCenter = function (x, y, radius) {
self.patrolCenter.x = x;
self.patrolCenter.y = y;
if (radius) {
self.patrolRadius = radius;
}
};
self.setTarget = function (target) {
self.target = target;
};
self.update = function () {
if (self.target) {
// Move toward target
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 5) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
} else {
// Patrol in a circle
self.patrolAngle += self.patrolSpeed;
self.x = self.patrolCenter.x + Math.cos(self.patrolAngle) * self.patrolRadius;
self.y = self.patrolCenter.y + Math.sin(self.patrolAngle) * self.patrolRadius;
}
};
return self;
});
var Powerup = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'fuel';
var assetType;
switch (self.type) {
case 'fuel':
assetType = 'fuelPowerup';
break;
case 'shield':
assetType = 'shieldPowerup';
break;
case 'magnet':
assetType = 'magnet';
break;
default:
assetType = 'fuelPowerup';
}
var powerupGraphics = self.attachAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
});
self.bobSpeed = 0.03;
self.bobAmount = 5;
self.bobPhase = Math.random() * Math.PI * 2;
self.originalY = 0;
self.rotationSpeed = 0.02;
self.update = function () {
self.bobPhase += self.bobSpeed;
powerupGraphics.rotation += self.rotationSpeed;
if (self.originalY) {
self.y = self.originalY + Math.sin(self.bobPhase) * self.bobAmount;
}
};
return self;
});
var SpaceStation = Container.expand(function () {
var self = Container.call(this);
var stationGraphics = self.attachAsset('spaceStation', {
anchorX: 0.5,
anchorY: 0.5
});
self.rotationSpeed = 0.002;
self.isFlashing = false;
self.pulseTime = 0;
self.pulseFrequency = 0.05;
// Function to make the station flash to indicate it's ready for delivery
self.startFlashing = function () {
if (!self.isFlashing) {
var _flashCycle = function flashCycle() {
if (self.isFlashing) {
tween(stationGraphics, {
tint: 0xf1c40f
}, {
duration: 800,
onFinish: function onFinish() {
if (self.isFlashing) {
tween(stationGraphics, {
tint: 0x9b59b6
}, {
duration: 800,
onFinish: _flashCycle
});
}
}
});
}
};
self.isFlashing = true;
// Flash between colors
_flashCycle();
}
};
// Function to stop flashing
self.stopFlashing = function () {
self.isFlashing = false;
tween(stationGraphics, {
tint: 0x9b59b6
}, {
duration: 400
});
};
self.update = function () {
stationGraphics.rotation += self.rotationSpeed;
// Pulse effect
self.pulseTime += self.pulseFrequency;
var pulseFactor = 1 + Math.sin(self.pulseTime) * 0.1;
stationGraphics.scale.set(pulseFactor, pulseFactor);
};
// Start flashing by default
self.startFlashing();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
// Game state
var ship;
var asteroids = [];
var cargoContainers = [];
var spaceStations = [];
var enemyDrones = [];
var powerups = [];
var fuelBarBg;
var fuelBarFront;
var cargoText;
var scoreText;
var levelText;
var highScoreText;
var gameActive = true;
var level = 1;
var score = 0;
var highScore = storage.highScore || 0;
var destX = 0;
var destY = 0;
var dragNode = null;
var rotationTween = null; // Added to track ship rotation tween
var lastSpawnTime = 0;
var difficultyTimer;
// Initialize UI elements
function initUI() {
// Score text
scoreText = new Text2('Score: 0', {
size: 70,
// Increased size
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.y = 10; // Position adjusted slightly if needed, but 10 seems okay
LK.gui.top.addChild(scoreText);
// High score text
highScoreText = new Text2('Best: ' + highScore, {
size: 50,
// Increased size
fill: 0xFFFFFF
});
highScoreText.anchor.set(0.5, 0);
highScoreText.y = 90; // Adjusted y position to account for larger scoreText above
LK.gui.top.addChild(highScoreText);
// Level text
levelText = new Text2('Level: 1', {
size: 70,
// Increased size
fill: 0xFFFFFF
});
levelText.anchor.set(1, 0);
levelText.x = -50;
levelText.y = 10;
LK.gui.topRight.addChild(levelText);
// Cargo text
cargoText = new Text2('Cargo: 0/3', {
size: 70,
// Increased size
fill: 0xFFFFFF
});
cargoText.anchor.set(0, 0);
cargoText.x = 120; // Moved further right to avoid menu icon
cargoText.y = 10;
LK.gui.topLeft.addChild(cargoText);
// Fuel bar background
fuelBarBg = LK.getAsset('fuelBarBackground', {
anchorX: 0.5,
anchorY: 0.5
});
fuelBarBg.x = 0;
fuelBarBg.y = 40;
LK.gui.bottom.addChild(fuelBarBg);
// Fuel bar
fuelBarFront = LK.getAsset('fuelBar', {
anchorX: 0,
anchorY: 0.5
});
fuelBarFront.x = -fuelBarBg.width / 2;
fuelBarFront.y = 40;
LK.gui.bottom.addChild(fuelBarFront);
// Add visual labels
var fuelLabel = new Text2('FUEL', {
size: 45,
// Increased size
fill: 0xFFFFFF
});
fuelLabel.anchor.set(0.5, 0.5);
fuelLabel.y = 40; // Position remains centered on the bar
LK.gui.bottom.addChild(fuelLabel);
}
// Create cargo ship
function createShip() {
ship = new CargoShip();
ship.x = 2048 / 2;
ship.y = 2732 / 2;
game.addChild(ship);
}
// Create random asteroid
function createAsteroid() {
var asteroid = new Asteroid();
// Random position on the edge of the screen
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
asteroid.x = Math.random() * 2048;
asteroid.y = -100;
break;
case 1:
// Right
asteroid.x = 2148;
asteroid.y = Math.random() * 2732;
break;
case 2:
// Bottom
asteroid.x = Math.random() * 2048;
asteroid.y = 2832;
break;
case 3:
// Left
asteroid.x = -100;
asteroid.y = Math.random() * 2732;
break;
}
// Random speed (higher in higher levels)
var baseSpeed = 2 + level * 0.5;
var speed = baseSpeed * (0.5 + Math.random() * 0.5);
// Direction toward center with some randomness
var targetX = 2048 / 2 + (Math.random() - 0.5) * 1000;
var targetY = 2732 / 2 + (Math.random() - 0.5) * 1000;
var dx = targetX - asteroid.x;
var dy = targetY - asteroid.y;
var dist = Math.sqrt(dx * dx + dy * dy);
asteroid.speedX = dx / dist * speed;
asteroid.speedY = dy / dist * speed;
// Scale randomly
var scale = 0.8 + Math.random() * 0.8;
asteroid.scale.set(scale, scale);
asteroids.push(asteroid);
game.addChild(asteroid);
}
// Create cargo container
function createCargoContainer() {
var container = new CargoContainer();
// Random position (not too close to the edge)
container.x = 200 + Math.random() * (2048 - 400);
container.y = 200 + Math.random() * (2732 - 400);
container.originalY = container.y;
cargoContainers.push(container);
game.addChild(container);
}
// Create space station
function createSpaceStation() {
var station = new SpaceStation();
// Position near an edge but not too close
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
station.x = 400 + Math.random() * (2048 - 800);
station.y = 300;
break;
case 1:
// Right
station.x = 2048 - 300;
station.y = 400 + Math.random() * (2732 - 800);
break;
case 2:
// Bottom
station.x = 400 + Math.random() * (2048 - 800);
station.y = 2732 - 300;
break;
case 3:
// Left
station.x = 300;
station.y = 400 + Math.random() * (2732 - 800);
break;
}
spaceStations.push(station);
game.addChild(station);
}
// Create enemy drone
function createEnemyDrone() {
var drone = new EnemyDrone();
// Random position
drone.x = Math.random() * 2048;
drone.y = Math.random() * 2732;
// Set patrol area
drone.setPatrolCenter(drone.x, drone.y, 200 + Math.random() * 200);
// Set speed based on level
drone.speed = 1 + level * 0.3;
enemyDrones.push(drone);
game.addChild(drone);
}
// Create powerup
function createPowerup(type) {
if (!type) {
var types = ['fuel', 'shield', 'magnet'];
type = types[Math.floor(Math.random() * types.length)];
}
var powerup = new Powerup(type);
// Random position (not too close to the edge)
powerup.x = 300 + Math.random() * (2048 - 600);
powerup.y = 300 + Math.random() * (2732 - 600);
powerup.originalY = powerup.y;
powerups.push(powerup);
game.addChild(powerup);
}
// Spawn game objects based on level
function spawnObjects() {
var currentTime = Date.now();
// Only spawn new objects every 1-3 seconds depending on level
var spawnRate = Math.max(3000 - level * 200, 1000);
if (currentTime - lastSpawnTime > spawnRate) {
// Spawn asteroid
if (asteroids.length < 5 + level * 2) {
createAsteroid();
}
// Spawn cargo
if (cargoContainers.length < 3 + Math.floor(level / 2)) {
createCargoContainer();
}
// Spawn enemy drones in higher levels
if (level >= 2 && enemyDrones.length < level - 1) {
createEnemyDrone();
}
// Spawn powerup (less frequently)
if (Math.random() < 0.2) {
createPowerup();
}
lastSpawnTime = currentTime;
}
}
// Update ship movement based on destination
function updateShipMovement() {
if (destX && destY) {
var dx = destX - ship.x;
var dy = destY - ship.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 5) {
// Calculate rotation angle to face destination
var angle = Math.atan2(dy, dx);
// Rotate ship to face direction of travel
// Stop existing rotation tween if it exists and is running
if (rotationTween && rotationTween.playing) {
rotationTween.stop();
}
rotationTween = tween(ship, {
rotation: angle
}, {
duration: 150 // Slightly faster rotation
});
// Move toward destination
ship.x += dx / dist * ship.speed;
ship.y += dy / dist * ship.speed;
// Consume fuel while moving
ship.consumeFuel();
}
}
}
// Update enemy drones
function updateEnemyDrones() {
for (var i = 0; i < enemyDrones.length; i++) {
var drone = enemyDrones[i];
// Set ship as target if it's close
var dx = ship.x - drone.x;
var dy = ship.y - drone.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 500) {
drone.setTarget(ship);
} else {
drone.setTarget(null);
}
}
}
// Update UI elements
function updateUI() {
// Update fuel bar
var fuelPercentage = ship.fuel / ship.maxFuel;
fuelBarFront.width = fuelBarBg.width * fuelPercentage;
// Change fuel bar color based on level
if (fuelPercentage <= 0.2) {
fuelBarFront.tint = 0xe74c3c; // Red
} else if (fuelPercentage <= 0.5) {
fuelBarFront.tint = 0xf39c12; // Orange
} else {
fuelBarFront.tint = 0x27ae60; // Green
}
// Update text displays
cargoText.setText('Cargo: ' + ship.cargo + '/' + ship.cargoCapacity);
scoreText.setText('Score: ' + score);
levelText.setText('Level: ' + level);
}
// Check for ship collisions with game objects
function checkCollisions() {
// Check asteroid collisions
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
if (ship.intersects(asteroid)) {
if (ship.shieldActive) {
// Destroy asteroid if shield is active
asteroid.destroy();
asteroids.splice(i, 1);
// Play collision sound
LK.getSound('collision').play();
// Add points
score += 5;
} else {
// Game over if no shield
gameOver();
return;
}
}
}
// Check enemy drone collisions
for (var i = enemyDrones.length - 1; i >= 0; i--) {
var drone = enemyDrones[i];
if (ship.intersects(drone)) {
if (ship.shieldActive) {
// Destroy drone if shield is active
drone.destroy();
enemyDrones.splice(i, 1);
// Play collision sound
LK.getSound('collision').play();
// Add points
score += 10;
} else {
// Game over if no shield
gameOver();
return;
}
}
}
// Check cargo container pickups
for (var i = cargoContainers.length - 1; i >= 0; i--) {
var container = cargoContainers[i];
// Check direct collision
if (ship.intersects(container)) {
if (ship.pickupCargo()) {
// Remove container and add points
container.destroy();
cargoContainers.splice(i, 1);
// Play pickup sound
LK.getSound('pickup').play();
// Add points
score += 10;
}
}
// Check magnet range
else if (ship.magnetActive) {
var dx = ship.x - container.x;
var dy = ship.y - container.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < ship.magnetRange) {
// Move container toward ship
container.x += dx / dist * 5;
container.y += dy / dist * 5;
container.originalY = container.y;
}
}
}
// Check space station delivery
for (var i = 0; i < spaceStations.length; i++) {
var station = spaceStations[i];
// Update flashing based on cargo status
// Only call startFlashing if cargo exists AND the station isn't already flashing
if (ship.cargo > 0 && !station.isFlashing) {
station.startFlashing();
}
// Only call stopFlashing if cargo is zero AND the station is currently flashing
else if (ship.cargo <= 0 && station.isFlashing) {
station.stopFlashing();
}
if (ship.intersects(station) && ship.cargo > 0) {
// Deliver cargo
var deliveredCargo = ship.deliverCargo();
// Add points
var deliveryPoints = deliveredCargo * 25;
score += deliveryPoints;
// Play delivery sound
LK.getSound('delivery').play();
// Flash screen green
LK.effects.flashScreen(0x27ae60, 300);
// Visual success feedback
tween(station, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
tween(station, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
// Check for level up
if (score >= level * 100) {
levelUp();
}
}
}
// Check powerup pickups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
if (ship.intersects(powerup)) {
// Apply powerup effect
switch (powerup.type) {
case 'fuel':
ship.refuel(50);
break;
case 'shield':
ship.activateShield(8000);
break;
case 'magnet':
ship.activateMagnet(10000);
break;
}
// Play powerup sound
LK.getSound('powerup').play();
// Add points
score += 5;
// Remove powerup
powerup.destroy();
powerups.splice(i, 1);
}
}
// Check if out of fuel
if (ship.fuel <= 0 && gameActive) {
gameOver();
}
}
// Level up function
function levelUp() {
LK.getSound('levelUp').play(); // Play level up sound
level++;
// Update level text
levelText.setText('Level: ' + level);
// Flash screen
LK.effects.flashScreen(0xf1c40f, 500);
// Show level up message
var levelUpText = new Text2('LEVEL UP!', {
size: 120,
fill: 0xf1c40f
});
levelUpText.anchor.set(0.5, 0.5);
levelUpText.alpha = 0;
LK.gui.center.addChild(levelUpText);
tween(levelUpText, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 700,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(levelUpText, {
alpha: 0
}, {
duration: 700,
onFinish: function onFinish() {
levelUpText.destroy();
}
});
}
});
// Create new space station if needed
if (spaceStations.length < Math.min(3, Math.floor(level / 2) + 1)) {
createSpaceStation();
}
// Increase ship speed slightly
ship.speed = 6 + level * 0.3;
// Add visual effects to ship to indicate power increase
tween(ship, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
onFinish: function onFinish() {
tween(ship, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
}
// Game over function
function gameOver() {
LK.getSound('gameOver').play(); // Play game over sound
gameActive = false;
// Flash screen red
LK.effects.flashScreen(0xe74c3c, 1000);
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
// Visual feedback for new high score
var newHighScoreText = new Text2('NEW HIGH SCORE!', {
size: 80,
fill: 0xf1c40f
});
newHighScoreText.anchor.set(0.5, 0.5);
newHighScoreText.alpha = 0;
LK.gui.center.addChild(newHighScoreText);
tween(newHighScoreText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.elasticOut
});
LK.setTimeout(function () {
tween(newHighScoreText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
newHighScoreText.destroy();
}
});
}, 2000);
}
// Set final score
LK.setScore(score);
// Show game over
LK.showGameOver();
}
// Tutorial system
var tutorialSteps = ["Tap to guide your ship to that location", "Collect floating cargo containers", "Deliver cargo to the flashing space station", "Watch your fuel level at the bottom", "Avoid asteroids - collect shields for protection", "Deliver more cargo to level up!"];
var currentTutorialStep = 0;
var tutorialText;
var tutorialShown = storage.tutorialShown || false;
function showTutorialStep() {
if (!tutorialText) {
tutorialText = new Text2(tutorialSteps[0], {
size: 70,
fill: 0xFFFFFF
});
tutorialText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(tutorialText);
}
if (currentTutorialStep < tutorialSteps.length) {
tutorialText.setText(tutorialSteps[currentTutorialStep]);
tutorialText.alpha = 0;
tween(tutorialText, {
alpha: 1
}, {
duration: 500
});
LK.setTimeout(function () {
// Check if tutorialText still exists before tweening
if (tutorialText && tutorialText.parent) {
tween(tutorialText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
// Check if tutorialText still exists before proceeding
if (tutorialText && tutorialText.parent) {
currentTutorialStep++;
if (currentTutorialStep < tutorialSteps.length) {
LK.setTimeout(showTutorialStep, 1000);
} else {
tutorialText.destroy();
tutorialText = null;
storage.tutorialShown = true;
}
} else {
// If text was destroyed elsewhere, ensure flag is set
storage.tutorialShown = true;
tutorialText = null; // Clear reference
}
}
});
} else {
// If text was destroyed elsewhere, ensure flag is set
storage.tutorialShown = true;
tutorialText = null; // Clear reference
}
}, 4000);
}
}
// Initialize game
function initGame() {
// Initialize UI
initUI();
// Create ship
createShip();
// Create initial objects
for (var i = 0; i < 5; i++) {
createAsteroid();
}
for (var i = 0; i < 3; i++) {
createCargoContainer();
}
// Create initial space station
createSpaceStation();
// Create initial powerup
createPowerup('fuel');
// Start background music
LK.playMusic('gameMusic');
// Show tutorial for new players
if (!tutorialShown) {
LK.setTimeout(showTutorialStep, 1000);
}
// Add Glaud text element
var glaudText = new Text2('Glaud', {
size: 60,
fill: 0xffa500 // Orange color
});
glaudText.anchor.set(0, 1); // Anchor bottom-left
// Position Glaud in the bottom-left corner (away from the fuel bar and top-left menu)
glaudText.x = 50; // Padding from left edge, ensuring it's not in the top-left 100x100 area
glaudText.y = 2732 - 120; // Padding from bottom edge, positioned above the fuel bar GUI elements
game.addChild(glaudText); // Add text to the main game stage
}
function handleDown(x, y, obj) {
destX = x;
destY = y;
dragNode = ship; // Set dragNode to enable dragging in handleMove
}
// Handle game moves
function handleMove(x, y, obj) {
if (dragNode) {
destX = x;
destY = y;
}
}
// Handle game releases
function handleUp(x, y, obj) {
dragNode = null;
}
// Set event handlers
game.down = handleDown;
game.move = handleMove;
game.up = handleUp;
// Initialize the game
initGame();
// Game update loop
game.update = function () {
if (gameActive) {
// Spawn new objects based on level
spawnObjects();
// Update ship movement
updateShipMovement();
// Update enemy drones
updateEnemyDrones();
// Check collisions
checkCollisions();
// Update UI
updateUI();
}
};
asteroid. In-Game asset. 2d. High contrast. No shadows
cargoContainer. In-Game asset. 2d. High contrast. No shadows
cargo spaceShip. In-Game asset. 2d. High contrast. No shadows
enemy space ship. In-Game asset. 2d. High contrast. No shadows
fuelPowerup. In-Game asset. 2d. High contrast. No shadows
spaceStation. In-Game asset. 2d. High contrast. No shadows
magnet. In-Game asset. 2d. High contrast. No shadows
shieldPowerup. In-Game asset. 2d. High contrast. No shadows
shield. In-Game asset. 2d. High contrast. No shadows