/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, shieldLevel: 1, laserLevel: 1, thrusterLevel: 1 }); /**** * Classes ****/ var Asteroid = Container.expand(function () { var self = Container.call(this); // Initialize with random size self.size = Math.random() * 0.5 + 0.8; // Between 0.8 and 1.3 self.health = Math.ceil(self.size * 3); self.initialHealth = self.health; self.speedX = (Math.random() - 0.5) * 4; self.speedY = Math.random() * 3 + 2; self.rotationSpeed = (Math.random() - 0.5) * 0.05; self.value = Math.ceil(self.size * 10); // Points value self.resourceValue = Math.ceil(self.size * 2); // Resource value var asteroidGraphic = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: self.size, scaleY: self.size }); self.takeDamage = function (amount) { self.health -= amount; // Visual feedback LK.effects.flashObject(self, 0xffffff, 200); // Break apart if (self.health <= 0) { self["break"](); return true; } // Change appearance based on damage var healthPercent = self.health / self.initialHealth; asteroidGraphic.alpha = 0.5 + healthPercent * 0.5; return false; }; self["break"] = function () { // Create minerals var mineralCount = Math.ceil(self.size * 2); for (var i = 0; i < mineralCount; i++) { var mineral = new Mineral(); mineral.x = self.x + (Math.random() - 0.5) * 50; mineral.y = self.y + (Math.random() - 0.5) * 50; minerals.push(mineral); game.addChild(mineral); } // Add score addScore(self.value); // Mark for removal self.toBeRemoved = true; }; self.update = function () { // Move asteroid self.x += self.speedX; self.y += self.speedY; // Rotate asteroid asteroidGraphic.rotation += self.rotationSpeed; // Wrap around screen edges horizontally if (self.x < -100) { self.x = 2148; } if (self.x > 2148) { self.x = -100; } // Remove if off bottom of screen if (self.y > 2832) { self.toBeRemoved = true; } }; return self; }); var ExplosiveAsteroid = Asteroid.expand(function () { var self = Asteroid.call(this); // Override the asteroid graphic with an explosive one self.removeChildren(); var asteroidGraphic = self.attachAsset('explosiveAsteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: self.size, scaleY: self.size }); // Make it pulse function pulse() { tween(asteroidGraphic, { alpha: 0.6 }, { duration: 500, onFinish: function onFinish() { tween(asteroidGraphic, { alpha: 1 }, { duration: 500, onFinish: pulse }); } }); } pulse(); // Override break function to create explosion var originalBreak = self["break"]; self["break"] = function () { // Create explosion var explosion = new Explosion(); explosion.x = self.x; explosion.y = self.y; explosions.push(explosion); game.addChild(explosion); // Original break functionality originalBreak(); }; return self; }); var Explosion = Container.expand(function () { var self = Container.call(this); var explosionGraphic = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5, alpha: 0.9 }); self.radius = 50; self.damage = 40; self.lifetime = 500; // milliseconds self.born = Date.now(); // Play explosion sound LK.getSound('explosion').play(); // Animate explosion tween(explosionGraphic, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: self.lifetime, onFinish: function onFinish() { self.toBeRemoved = true; } }); self.update = function () { self.radius = 50 + (Date.now() - self.born) / self.lifetime * 100; }; return self; }); var Laser = Container.expand(function () { var self = Container.call(this); var laserGraphic = self.attachAsset('laser', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.power = 1; // Will be set by ship when fired self.update = function () { self.y -= self.speed; // Destroy when off screen if (self.y < -100) { self.toBeRemoved = true; } }; return self; }); var Mineral = Container.expand(function () { var self = Container.call(this); var mineralGraphic = self.attachAsset('mineral', { anchorX: 0.5, anchorY: 0.5 }); self.speedX = (Math.random() - 0.5) * 2; self.speedY = Math.random() * 2 + 1; self.value = Math.floor(Math.random() * 3) + 1; self.rotationSpeed = (Math.random() - 0.5) * 0.1; // Different colors based on value if (self.value === 1) { mineralGraphic.tint = 0x95a5a6; // Iron (gray) } else if (self.value === 2) { mineralGraphic.tint = 0xf1c40f; // Gold (yellow) } else { mineralGraphic.tint = 0x1abc9c; // Platinum (teal) } self.update = function () { // Move mineral self.x += self.speedX; self.y += self.speedY; // Rotate mineral mineralGraphic.rotation += self.rotationSpeed; // Wrap around screen edges horizontally if (self.x < -50) { self.x = 2098; } if (self.x > 2098) { self.x = -50; } // Remove if off bottom of screen if (self.y > 2832) { self.toBeRemoved = true; } }; return self; }); var Ship = Container.expand(function () { var self = Container.call(this); // Ship attributes self.maxShields = 100; self.shields = self.maxShields; self.speed = 5; self.lastFired = 0; self.fireRate = 500; // milliseconds between shots self.laserPower = 1; self.invulnerable = false; // Create ship body var shipBody = self.attachAsset('ship', { anchorX: 0.5, anchorY: 0.5 }); // Create shield indicator var shieldIndicator = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 }); // Method to update shield appearance self.updateShieldDisplay = function () { var shieldPercent = self.shields / self.maxShields; shieldIndicator.alpha = 0.1 + shieldPercent * 0.4; if (self.shields < 30) { shieldIndicator.tint = 0xff0000; // Red when low } else if (self.shields < 60) { shieldIndicator.tint = 0xffff00; // Yellow when medium } else { shieldIndicator.tint = 0x3498db; // Blue when high } }; // Method to take damage self.takeDamage = function (amount) { if (self.invulnerable) { return; } self.shields -= amount; LK.getSound('damage').play(); // Visual feedback LK.effects.flashObject(self, 0xff0000, 500); // Make invulnerable briefly self.invulnerable = true; LK.setTimeout(function () { self.invulnerable = false; }, 1000); self.updateShieldDisplay(); if (self.shields <= 0) { gameOver(); } }; // Method to fire laser self.fireLaser = function () { var now = Date.now(); if (now - self.lastFired < self.fireRate) { return; } self.lastFired = now; var laser = new Laser(); laser.x = self.x; laser.y = self.y - 50; laser.power = self.laserPower; lasers.push(laser); game.addChild(laser); LK.getSound('laser').play(); }; // Init shield display self.updateShieldDisplay(); return self; }); var UpgradeCrate = Container.expand(function () { var self = Container.call(this); var crateGraphic = self.attachAsset('upgradeCrate', { anchorX: 0.5, anchorY: 0.5 }); self.speedY = 3; self.pulseAmount = 0; // Pulse effect function pulse() { tween(crateGraphic, { scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.sinOut, onFinish: function onFinish() { tween(crateGraphic, { scaleX: 1, scaleY: 1 }, { duration: 800, easing: tween.sinIn, onFinish: pulse }); } }); } pulse(); self.update = function () { // Move crate self.y += self.speedY; // Remove if off bottom of screen if (self.y > 2832) { self.toBeRemoved = true; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game variables var score = 0; var resources = 0; var level = 1; var ship; var lasers = []; var asteroids = []; var explosiveAsteroids = []; var minerals = []; var explosions = []; var upgradeCrates = []; var lastAsteroidTime = 0; var asteroidSpawnRate = 1500; // milliseconds between asteroid spawns var nextUpgradeScore = 500; var gameActive = true; var dragOffset = { x: 0, y: 0 }; var dragActive = false; // Initialize background game.setBackgroundColor(0x000033); // Create UI elements var scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); LK.gui.topRight.addChild(scoreText); scoreText.x = -300; scoreText.y = 20; var resourceText = new Text2('Resources: 0', { size: 60, fill: 0xFFFFFF }); resourceText.anchor.set(0, 0); LK.gui.topRight.addChild(resourceText); resourceText.x = -300; resourceText.y = 90; var levelText = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); LK.gui.topRight.addChild(levelText); levelText.x = -300; levelText.y = 160; var shieldText = new Text2('Shield: 100%', { size: 60, fill: 0xFFFFFF }); shieldText.anchor.set(0, 0); LK.gui.bottom.addChild(shieldText); shieldText.x = -650; shieldText.y = -80; // Initialize ship ship = new Ship(); ship.x = 2048 / 2; ship.y = 2500; game.addChild(ship); // Load saved upgrades loadUpgrades(); // Start background music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.4, duration: 1000 } }); // Game functions function addScore(points) { score += points; scoreText.setText('Score: ' + score); // Check if player reached next upgrade threshold if (score >= nextUpgradeScore) { spawnUpgradeCrate(); nextUpgradeScore += 500; } // Check for level increase var newLevel = Math.floor(score / 1000) + 1; if (newLevel > level) { level = newLevel; levelText.setText('Level: ' + level); // Increase difficulty asteroidSpawnRate = Math.max(300, 1500 - level * 100); } } function addResource(amount) { resources += amount; resourceText.setText('Resources: ' + resources); // Save high score if better than previous if (score > storage.highScore) { storage.highScore = score; } } function spawnAsteroid() { // Decide whether to spawn regular or explosive asteroid var isExplosive = Math.random() < 0.2; var asteroid; if (isExplosive) { asteroid = new ExplosiveAsteroid(); explosiveAsteroids.push(asteroid); } else { asteroid = new Asteroid(); asteroids.push(asteroid); } // Position at random location at top of screen asteroid.x = Math.random() * 2048; asteroid.y = -100; // Add to game game.addChild(asteroid); } function spawnUpgradeCrate() { var crate = new UpgradeCrate(); crate.x = Math.random() * (2048 - 200) + 100; // Keep away from edges crate.y = -100; upgradeCrates.push(crate); game.addChild(crate); } function applyUpgrade() { // Show upgrade options in a future version // For now, just upgrade shields if (resources >= 10) { resources -= 10; resourceText.setText('Resources: ' + resources); // Upgrade a random system var system = Math.floor(Math.random() * 3); if (system === 0 && storage.shieldLevel < 5) { storage.shieldLevel++; ship.maxShields = 100 + (storage.shieldLevel - 1) * 25; ship.shields = ship.maxShields; shieldText.setText('Shield: ' + Math.floor(ship.shields) + '%'); ship.updateShieldDisplay(); } else if (system === 1 && storage.laserLevel < 5) { storage.laserLevel++; ship.laserPower = storage.laserLevel; ship.fireRate = 500 - (storage.laserLevel - 1) * 50; } else if (storage.thrusterLevel < 5) { storage.thrusterLevel++; ship.speed = 5 + (storage.thrusterLevel - 1); } LK.getSound('upgrade').play(); // Visual feedback LK.effects.flashObject(ship, 0x9b59b6, 1000); } } function loadUpgrades() { // Apply saved upgrade levels ship.maxShields = 100 + (storage.shieldLevel - 1) * 25; ship.shields = ship.maxShields; ship.laserPower = storage.laserLevel; ship.fireRate = 500 - (storage.laserLevel - 1) * 50; ship.speed = 5 + (storage.thrusterLevel - 1); shieldText.setText('Shield: ' + Math.floor(ship.shields) + '%'); ship.updateShieldDisplay(); } function gameOver() { gameActive = false; LK.effects.flashScreen(0xff0000, 1000); LK.setTimeout(function () { LK.showGameOver(); }, 1000); } // Input handlers game.down = function (x, y, obj) { if (!gameActive) { return; } // Start dragging the ship dragOffset.x = ship.x - x; dragOffset.y = ship.y - y; dragActive = true; // Fire laser on tap ship.fireLaser(); }; game.move = function (x, y, obj) { if (!gameActive || !dragActive) { return; } // Move ship with drag, keeping it on screen ship.x = Math.min(Math.max(x + dragOffset.x, 50), 2048 - 50); ship.y = Math.min(Math.max(y + dragOffset.y, 50), 2732 - 50); }; game.up = function (x, y, obj) { dragActive = false; }; // Game loop game.update = function () { if (!gameActive) { return; } // Spawn new asteroids var now = Date.now(); if (now - lastAsteroidTime > asteroidSpawnRate) { spawnAsteroid(); lastAsteroidTime = now; } // Update UI shieldText.setText('Shield: ' + Math.floor(ship.shields) + '%'); // Update and check lasers for (var i = lasers.length - 1; i >= 0; i--) { var laser = lasers[i]; if (laser.toBeRemoved) { game.removeChild(laser); lasers.splice(i, 1); continue; } // Check laser collisions with asteroids for (var j = asteroids.length - 1; j >= 0; j--) { var asteroid = asteroids[j]; if (laser.intersects(asteroid)) { if (asteroid.takeDamage(laser.power)) { // Asteroid was destroyed game.removeChild(asteroid); asteroids.splice(j, 1); } // Remove laser on hit laser.toBeRemoved = true; break; } } // Check laser collisions with explosive asteroids for (var j = explosiveAsteroids.length - 1; j >= 0; j--) { var expAsteroid = explosiveAsteroids[j]; if (laser.intersects(expAsteroid)) { if (expAsteroid.takeDamage(laser.power)) { // Asteroid was destroyed game.removeChild(expAsteroid); explosiveAsteroids.splice(j, 1); } // Remove laser on hit laser.toBeRemoved = true; break; } } } // Update and check minerals for (var i = minerals.length - 1; i >= 0; i--) { var mineral = minerals[i]; if (mineral.toBeRemoved) { game.removeChild(mineral); minerals.splice(i, 1); continue; } // Check if ship collects mineral if (ship.intersects(mineral)) { addResource(mineral.value); LK.getSound('collect').play(); mineral.toBeRemoved = true; // Visual feedback LK.effects.flashObject(ship, 0x2ecc71, 200); } } // Update and check asteroids for (var i = asteroids.length - 1; i >= 0; i--) { var asteroid = asteroids[i]; if (asteroid.toBeRemoved) { game.removeChild(asteroid); asteroids.splice(i, 1); continue; } // Check collision with ship if (ship.intersects(asteroid)) { ship.takeDamage(10 + level); asteroid["break"](); game.removeChild(asteroid); asteroids.splice(i, 1); } } // Update and check explosive asteroids for (var i = explosiveAsteroids.length - 1; i >= 0; i--) { var expAsteroid = explosiveAsteroids[i]; if (expAsteroid.toBeRemoved) { game.removeChild(expAsteroid); explosiveAsteroids.splice(i, 1); continue; } // Check collision with ship if (ship.intersects(expAsteroid)) { ship.takeDamage(20 + level * 2); expAsteroid["break"](); game.removeChild(expAsteroid); explosiveAsteroids.splice(i, 1); } } // Update and check explosions for (var i = explosions.length - 1; i >= 0; i--) { var explosion = explosions[i]; if (explosion.toBeRemoved) { game.removeChild(explosion); explosions.splice(i, 1); continue; } // Check if ship is caught in explosion var dx = ship.x - explosion.x; var dy = ship.y - explosion.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < explosion.radius + 50) { // Add ship radius // Damage diminishes with distance var damageMultiplier = 1 - distance / (explosion.radius + 50); ship.takeDamage(explosion.damage * damageMultiplier); } } // Update and check upgrade crates for (var i = upgradeCrates.length - 1; i >= 0; i--) { var crate = upgradeCrates[i]; if (crate.toBeRemoved) { game.removeChild(crate); upgradeCrates.splice(i, 1); continue; } // Check if ship collects upgrade if (ship.intersects(crate)) { applyUpgrade(); crate.toBeRemoved = true; } } };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,646 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0,
+ shieldLevel: 1,
+ laserLevel: 1,
+ thrusterLevel: 1
+});
+
+/****
+* Classes
+****/
+var Asteroid = Container.expand(function () {
+ var self = Container.call(this);
+ // Initialize with random size
+ self.size = Math.random() * 0.5 + 0.8; // Between 0.8 and 1.3
+ self.health = Math.ceil(self.size * 3);
+ self.initialHealth = self.health;
+ self.speedX = (Math.random() - 0.5) * 4;
+ self.speedY = Math.random() * 3 + 2;
+ self.rotationSpeed = (Math.random() - 0.5) * 0.05;
+ self.value = Math.ceil(self.size * 10); // Points value
+ self.resourceValue = Math.ceil(self.size * 2); // Resource value
+ var asteroidGraphic = self.attachAsset('asteroid', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: self.size,
+ scaleY: self.size
+ });
+ self.takeDamage = function (amount) {
+ self.health -= amount;
+ // Visual feedback
+ LK.effects.flashObject(self, 0xffffff, 200);
+ // Break apart
+ if (self.health <= 0) {
+ self["break"]();
+ return true;
+ }
+ // Change appearance based on damage
+ var healthPercent = self.health / self.initialHealth;
+ asteroidGraphic.alpha = 0.5 + healthPercent * 0.5;
+ return false;
+ };
+ self["break"] = function () {
+ // Create minerals
+ var mineralCount = Math.ceil(self.size * 2);
+ for (var i = 0; i < mineralCount; i++) {
+ var mineral = new Mineral();
+ mineral.x = self.x + (Math.random() - 0.5) * 50;
+ mineral.y = self.y + (Math.random() - 0.5) * 50;
+ minerals.push(mineral);
+ game.addChild(mineral);
+ }
+ // Add score
+ addScore(self.value);
+ // Mark for removal
+ self.toBeRemoved = true;
+ };
+ self.update = function () {
+ // Move asteroid
+ self.x += self.speedX;
+ self.y += self.speedY;
+ // Rotate asteroid
+ asteroidGraphic.rotation += self.rotationSpeed;
+ // Wrap around screen edges horizontally
+ if (self.x < -100) {
+ self.x = 2148;
+ }
+ if (self.x > 2148) {
+ self.x = -100;
+ }
+ // Remove if off bottom of screen
+ if (self.y > 2832) {
+ self.toBeRemoved = true;
+ }
+ };
+ return self;
+});
+var ExplosiveAsteroid = Asteroid.expand(function () {
+ var self = Asteroid.call(this);
+ // Override the asteroid graphic with an explosive one
+ self.removeChildren();
+ var asteroidGraphic = self.attachAsset('explosiveAsteroid', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: self.size,
+ scaleY: self.size
+ });
+ // Make it pulse
+ function pulse() {
+ tween(asteroidGraphic, {
+ alpha: 0.6
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ tween(asteroidGraphic, {
+ alpha: 1
+ }, {
+ duration: 500,
+ onFinish: pulse
+ });
+ }
+ });
+ }
+ pulse();
+ // Override break function to create explosion
+ var originalBreak = self["break"];
+ self["break"] = function () {
+ // Create explosion
+ var explosion = new Explosion();
+ explosion.x = self.x;
+ explosion.y = self.y;
+ explosions.push(explosion);
+ game.addChild(explosion);
+ // Original break functionality
+ originalBreak();
+ };
+ return self;
+});
+var Explosion = Container.expand(function () {
+ var self = Container.call(this);
+ var explosionGraphic = self.attachAsset('explosion', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.9
+ });
+ self.radius = 50;
+ self.damage = 40;
+ self.lifetime = 500; // milliseconds
+ self.born = Date.now();
+ // Play explosion sound
+ LK.getSound('explosion').play();
+ // Animate explosion
+ tween(explosionGraphic, {
+ scaleX: 2,
+ scaleY: 2,
+ alpha: 0
+ }, {
+ duration: self.lifetime,
+ onFinish: function onFinish() {
+ self.toBeRemoved = true;
+ }
+ });
+ self.update = function () {
+ self.radius = 50 + (Date.now() - self.born) / self.lifetime * 100;
+ };
+ return self;
+});
+var Laser = Container.expand(function () {
+ var self = Container.call(this);
+ var laserGraphic = self.attachAsset('laser', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 15;
+ self.power = 1; // Will be set by ship when fired
+ self.update = function () {
+ self.y -= self.speed;
+ // Destroy when off screen
+ if (self.y < -100) {
+ self.toBeRemoved = true;
+ }
+ };
+ return self;
+});
+var Mineral = Container.expand(function () {
+ var self = Container.call(this);
+ var mineralGraphic = self.attachAsset('mineral', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speedX = (Math.random() - 0.5) * 2;
+ self.speedY = Math.random() * 2 + 1;
+ self.value = Math.floor(Math.random() * 3) + 1;
+ self.rotationSpeed = (Math.random() - 0.5) * 0.1;
+ // Different colors based on value
+ if (self.value === 1) {
+ mineralGraphic.tint = 0x95a5a6; // Iron (gray)
+ } else if (self.value === 2) {
+ mineralGraphic.tint = 0xf1c40f; // Gold (yellow)
+ } else {
+ mineralGraphic.tint = 0x1abc9c; // Platinum (teal)
+ }
+ self.update = function () {
+ // Move mineral
+ self.x += self.speedX;
+ self.y += self.speedY;
+ // Rotate mineral
+ mineralGraphic.rotation += self.rotationSpeed;
+ // Wrap around screen edges horizontally
+ if (self.x < -50) {
+ self.x = 2098;
+ }
+ if (self.x > 2098) {
+ self.x = -50;
+ }
+ // Remove if off bottom of screen
+ if (self.y > 2832) {
+ self.toBeRemoved = true;
+ }
+ };
+ return self;
+});
+var Ship = Container.expand(function () {
+ var self = Container.call(this);
+ // Ship attributes
+ self.maxShields = 100;
+ self.shields = self.maxShields;
+ self.speed = 5;
+ self.lastFired = 0;
+ self.fireRate = 500; // milliseconds between shots
+ self.laserPower = 1;
+ self.invulnerable = false;
+ // Create ship body
+ var shipBody = self.attachAsset('ship', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Create shield indicator
+ var shieldIndicator = self.attachAsset('shield', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.3
+ });
+ // Method to update shield appearance
+ self.updateShieldDisplay = function () {
+ var shieldPercent = self.shields / self.maxShields;
+ shieldIndicator.alpha = 0.1 + shieldPercent * 0.4;
+ if (self.shields < 30) {
+ shieldIndicator.tint = 0xff0000; // Red when low
+ } else if (self.shields < 60) {
+ shieldIndicator.tint = 0xffff00; // Yellow when medium
+ } else {
+ shieldIndicator.tint = 0x3498db; // Blue when high
+ }
+ };
+ // Method to take damage
+ self.takeDamage = function (amount) {
+ if (self.invulnerable) {
+ return;
+ }
+ self.shields -= amount;
+ LK.getSound('damage').play();
+ // Visual feedback
+ LK.effects.flashObject(self, 0xff0000, 500);
+ // Make invulnerable briefly
+ self.invulnerable = true;
+ LK.setTimeout(function () {
+ self.invulnerable = false;
+ }, 1000);
+ self.updateShieldDisplay();
+ if (self.shields <= 0) {
+ gameOver();
+ }
+ };
+ // Method to fire laser
+ self.fireLaser = function () {
+ var now = Date.now();
+ if (now - self.lastFired < self.fireRate) {
+ return;
+ }
+ self.lastFired = now;
+ var laser = new Laser();
+ laser.x = self.x;
+ laser.y = self.y - 50;
+ laser.power = self.laserPower;
+ lasers.push(laser);
+ game.addChild(laser);
+ LK.getSound('laser').play();
+ };
+ // Init shield display
+ self.updateShieldDisplay();
+ return self;
+});
+var UpgradeCrate = Container.expand(function () {
+ var self = Container.call(this);
+ var crateGraphic = self.attachAsset('upgradeCrate', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speedY = 3;
+ self.pulseAmount = 0;
+ // Pulse effect
+ function pulse() {
+ tween(crateGraphic, {
+ scaleX: 1.1,
+ scaleY: 1.1
+ }, {
+ duration: 800,
+ easing: tween.sinOut,
+ onFinish: function onFinish() {
+ tween(crateGraphic, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 800,
+ easing: tween.sinIn,
+ onFinish: pulse
+ });
+ }
+ });
+ }
+ pulse();
+ self.update = function () {
+ // Move crate
+ self.y += self.speedY;
+ // Remove if off bottom of screen
+ if (self.y > 2832) {
+ self.toBeRemoved = true;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var score = 0;
+var resources = 0;
+var level = 1;
+var ship;
+var lasers = [];
+var asteroids = [];
+var explosiveAsteroids = [];
+var minerals = [];
+var explosions = [];
+var upgradeCrates = [];
+var lastAsteroidTime = 0;
+var asteroidSpawnRate = 1500; // milliseconds between asteroid spawns
+var nextUpgradeScore = 500;
+var gameActive = true;
+var dragOffset = {
+ x: 0,
+ y: 0
+};
+var dragActive = false;
+// Initialize background
+game.setBackgroundColor(0x000033);
+// Create UI elements
+var scoreText = new Text2('Score: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+scoreText.anchor.set(0, 0);
+LK.gui.topRight.addChild(scoreText);
+scoreText.x = -300;
+scoreText.y = 20;
+var resourceText = new Text2('Resources: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+resourceText.anchor.set(0, 0);
+LK.gui.topRight.addChild(resourceText);
+resourceText.x = -300;
+resourceText.y = 90;
+var levelText = new Text2('Level: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+levelText.anchor.set(0, 0);
+LK.gui.topRight.addChild(levelText);
+levelText.x = -300;
+levelText.y = 160;
+var shieldText = new Text2('Shield: 100%', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+shieldText.anchor.set(0, 0);
+LK.gui.bottom.addChild(shieldText);
+shieldText.x = -650;
+shieldText.y = -80;
+// Initialize ship
+ship = new Ship();
+ship.x = 2048 / 2;
+ship.y = 2500;
+game.addChild(ship);
+// Load saved upgrades
+loadUpgrades();
+// Start background music
+LK.playMusic('gameMusic', {
+ fade: {
+ start: 0,
+ end: 0.4,
+ duration: 1000
+ }
+});
+// Game functions
+function addScore(points) {
+ score += points;
+ scoreText.setText('Score: ' + score);
+ // Check if player reached next upgrade threshold
+ if (score >= nextUpgradeScore) {
+ spawnUpgradeCrate();
+ nextUpgradeScore += 500;
+ }
+ // Check for level increase
+ var newLevel = Math.floor(score / 1000) + 1;
+ if (newLevel > level) {
+ level = newLevel;
+ levelText.setText('Level: ' + level);
+ // Increase difficulty
+ asteroidSpawnRate = Math.max(300, 1500 - level * 100);
+ }
+}
+function addResource(amount) {
+ resources += amount;
+ resourceText.setText('Resources: ' + resources);
+ // Save high score if better than previous
+ if (score > storage.highScore) {
+ storage.highScore = score;
+ }
+}
+function spawnAsteroid() {
+ // Decide whether to spawn regular or explosive asteroid
+ var isExplosive = Math.random() < 0.2;
+ var asteroid;
+ if (isExplosive) {
+ asteroid = new ExplosiveAsteroid();
+ explosiveAsteroids.push(asteroid);
+ } else {
+ asteroid = new Asteroid();
+ asteroids.push(asteroid);
+ }
+ // Position at random location at top of screen
+ asteroid.x = Math.random() * 2048;
+ asteroid.y = -100;
+ // Add to game
+ game.addChild(asteroid);
+}
+function spawnUpgradeCrate() {
+ var crate = new UpgradeCrate();
+ crate.x = Math.random() * (2048 - 200) + 100; // Keep away from edges
+ crate.y = -100;
+ upgradeCrates.push(crate);
+ game.addChild(crate);
+}
+function applyUpgrade() {
+ // Show upgrade options in a future version
+ // For now, just upgrade shields
+ if (resources >= 10) {
+ resources -= 10;
+ resourceText.setText('Resources: ' + resources);
+ // Upgrade a random system
+ var system = Math.floor(Math.random() * 3);
+ if (system === 0 && storage.shieldLevel < 5) {
+ storage.shieldLevel++;
+ ship.maxShields = 100 + (storage.shieldLevel - 1) * 25;
+ ship.shields = ship.maxShields;
+ shieldText.setText('Shield: ' + Math.floor(ship.shields) + '%');
+ ship.updateShieldDisplay();
+ } else if (system === 1 && storage.laserLevel < 5) {
+ storage.laserLevel++;
+ ship.laserPower = storage.laserLevel;
+ ship.fireRate = 500 - (storage.laserLevel - 1) * 50;
+ } else if (storage.thrusterLevel < 5) {
+ storage.thrusterLevel++;
+ ship.speed = 5 + (storage.thrusterLevel - 1);
+ }
+ LK.getSound('upgrade').play();
+ // Visual feedback
+ LK.effects.flashObject(ship, 0x9b59b6, 1000);
+ }
+}
+function loadUpgrades() {
+ // Apply saved upgrade levels
+ ship.maxShields = 100 + (storage.shieldLevel - 1) * 25;
+ ship.shields = ship.maxShields;
+ ship.laserPower = storage.laserLevel;
+ ship.fireRate = 500 - (storage.laserLevel - 1) * 50;
+ ship.speed = 5 + (storage.thrusterLevel - 1);
+ shieldText.setText('Shield: ' + Math.floor(ship.shields) + '%');
+ ship.updateShieldDisplay();
+}
+function gameOver() {
+ gameActive = false;
+ LK.effects.flashScreen(0xff0000, 1000);
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 1000);
+}
+// Input handlers
+game.down = function (x, y, obj) {
+ if (!gameActive) {
+ return;
+ }
+ // Start dragging the ship
+ dragOffset.x = ship.x - x;
+ dragOffset.y = ship.y - y;
+ dragActive = true;
+ // Fire laser on tap
+ ship.fireLaser();
+};
+game.move = function (x, y, obj) {
+ if (!gameActive || !dragActive) {
+ return;
+ }
+ // Move ship with drag, keeping it on screen
+ ship.x = Math.min(Math.max(x + dragOffset.x, 50), 2048 - 50);
+ ship.y = Math.min(Math.max(y + dragOffset.y, 50), 2732 - 50);
+};
+game.up = function (x, y, obj) {
+ dragActive = false;
+};
+// Game loop
+game.update = function () {
+ if (!gameActive) {
+ return;
+ }
+ // Spawn new asteroids
+ var now = Date.now();
+ if (now - lastAsteroidTime > asteroidSpawnRate) {
+ spawnAsteroid();
+ lastAsteroidTime = now;
+ }
+ // Update UI
+ shieldText.setText('Shield: ' + Math.floor(ship.shields) + '%');
+ // Update and check lasers
+ for (var i = lasers.length - 1; i >= 0; i--) {
+ var laser = lasers[i];
+ if (laser.toBeRemoved) {
+ game.removeChild(laser);
+ lasers.splice(i, 1);
+ continue;
+ }
+ // Check laser collisions with asteroids
+ for (var j = asteroids.length - 1; j >= 0; j--) {
+ var asteroid = asteroids[j];
+ if (laser.intersects(asteroid)) {
+ if (asteroid.takeDamage(laser.power)) {
+ // Asteroid was destroyed
+ game.removeChild(asteroid);
+ asteroids.splice(j, 1);
+ }
+ // Remove laser on hit
+ laser.toBeRemoved = true;
+ break;
+ }
+ }
+ // Check laser collisions with explosive asteroids
+ for (var j = explosiveAsteroids.length - 1; j >= 0; j--) {
+ var expAsteroid = explosiveAsteroids[j];
+ if (laser.intersects(expAsteroid)) {
+ if (expAsteroid.takeDamage(laser.power)) {
+ // Asteroid was destroyed
+ game.removeChild(expAsteroid);
+ explosiveAsteroids.splice(j, 1);
+ }
+ // Remove laser on hit
+ laser.toBeRemoved = true;
+ break;
+ }
+ }
+ }
+ // Update and check minerals
+ for (var i = minerals.length - 1; i >= 0; i--) {
+ var mineral = minerals[i];
+ if (mineral.toBeRemoved) {
+ game.removeChild(mineral);
+ minerals.splice(i, 1);
+ continue;
+ }
+ // Check if ship collects mineral
+ if (ship.intersects(mineral)) {
+ addResource(mineral.value);
+ LK.getSound('collect').play();
+ mineral.toBeRemoved = true;
+ // Visual feedback
+ LK.effects.flashObject(ship, 0x2ecc71, 200);
+ }
+ }
+ // Update and check asteroids
+ for (var i = asteroids.length - 1; i >= 0; i--) {
+ var asteroid = asteroids[i];
+ if (asteroid.toBeRemoved) {
+ game.removeChild(asteroid);
+ asteroids.splice(i, 1);
+ continue;
+ }
+ // Check collision with ship
+ if (ship.intersects(asteroid)) {
+ ship.takeDamage(10 + level);
+ asteroid["break"]();
+ game.removeChild(asteroid);
+ asteroids.splice(i, 1);
+ }
+ }
+ // Update and check explosive asteroids
+ for (var i = explosiveAsteroids.length - 1; i >= 0; i--) {
+ var expAsteroid = explosiveAsteroids[i];
+ if (expAsteroid.toBeRemoved) {
+ game.removeChild(expAsteroid);
+ explosiveAsteroids.splice(i, 1);
+ continue;
+ }
+ // Check collision with ship
+ if (ship.intersects(expAsteroid)) {
+ ship.takeDamage(20 + level * 2);
+ expAsteroid["break"]();
+ game.removeChild(expAsteroid);
+ explosiveAsteroids.splice(i, 1);
+ }
+ }
+ // Update and check explosions
+ for (var i = explosions.length - 1; i >= 0; i--) {
+ var explosion = explosions[i];
+ if (explosion.toBeRemoved) {
+ game.removeChild(explosion);
+ explosions.splice(i, 1);
+ continue;
+ }
+ // Check if ship is caught in explosion
+ var dx = ship.x - explosion.x;
+ var dy = ship.y - explosion.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < explosion.radius + 50) {
+ // Add ship radius
+ // Damage diminishes with distance
+ var damageMultiplier = 1 - distance / (explosion.radius + 50);
+ ship.takeDamage(explosion.damage * damageMultiplier);
+ }
+ }
+ // Update and check upgrade crates
+ for (var i = upgradeCrates.length - 1; i >= 0; i--) {
+ var crate = upgradeCrates[i];
+ if (crate.toBeRemoved) {
+ game.removeChild(crate);
+ upgradeCrates.splice(i, 1);
+ continue;
+ }
+ // Check if ship collects upgrade
+ if (ship.intersects(crate)) {
+ applyUpgrade();
+ crate.toBeRemoved = true;
+ }
+ }
+};
\ No newline at end of file