/**** * 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 GravitationalAnomaly = Container.expand(function () { var self = Container.call(this); var anomalyGraphic = self.attachAsset('anomaly', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.radius = 150; self.strength = 0.5; self.update = function () { // Visual effect or animation can be added here }; 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 gravitationalAnomalies = []; 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; } // Randomly spawn gravitational anomalies if (Math.random() < 0.001) { // Adjust probability as needed var anomaly = new GravitationalAnomaly(); anomaly.x = Math.random() * 2048; anomaly.y = Math.random() * 2732; gravitationalAnomalies.push(anomaly); game.addChild(anomaly); } // 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 gravitational anomalies for (var i = gravitationalAnomalies.length - 1; i >= 0; i--) { var anomaly = gravitationalAnomalies[i]; if (anomaly.toBeRemoved) { game.removeChild(anomaly); gravitationalAnomalies.splice(i, 1); continue; } // Check if ship is affected by anomaly var dx = ship.x - anomaly.x; var dy = ship.y - anomaly.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < anomaly.radius) { // Apply gravitational pull var pullStrength = anomaly.strength * (1 - distance / anomaly.radius); ship.x += dx * pullStrength; ship.y += dy * pullStrength; } } // 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
@@ -147,8 +147,22 @@
self.radius = 50 + (Date.now() - self.born) / self.lifetime * 100;
};
return self;
});
+var GravitationalAnomaly = Container.expand(function () {
+ var self = Container.call(this);
+ var anomalyGraphic = self.attachAsset('anomaly', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.7
+ });
+ self.radius = 150;
+ self.strength = 0.5;
+ self.update = function () {
+ // Visual effect or animation can be added here
+ };
+ return self;
+});
var Laser = Container.expand(function () {
var self = Container.call(this);
var laserGraphic = self.attachAsset('laser', {
anchorX: 0.5,
@@ -335,8 +349,9 @@
var minerals = [];
var explosions = [];
var upgradeCrates = [];
var lastAsteroidTime = 0;
+var gravitationalAnomalies = [];
var asteroidSpawnRate = 1500; // milliseconds between asteroid spawns
var nextUpgradeScore = 500;
var gameActive = true;
var dragOffset = {
@@ -521,8 +536,17 @@
if (now - lastAsteroidTime > asteroidSpawnRate) {
spawnAsteroid();
lastAsteroidTime = now;
}
+ // Randomly spawn gravitational anomalies
+ if (Math.random() < 0.001) {
+ // Adjust probability as needed
+ var anomaly = new GravitationalAnomaly();
+ anomaly.x = Math.random() * 2048;
+ anomaly.y = Math.random() * 2732;
+ gravitationalAnomalies.push(anomaly);
+ game.addChild(anomaly);
+ }
// Update UI
shieldText.setText('Shield: ' + Math.floor(ship.shields) + '%');
// Update and check lasers
for (var i = lasers.length - 1; i >= 0; i--) {
@@ -628,8 +652,27 @@
var damageMultiplier = 1 - distance / (explosion.radius + 50);
ship.takeDamage(explosion.damage * damageMultiplier);
}
}
+ // Update and check gravitational anomalies
+ for (var i = gravitationalAnomalies.length - 1; i >= 0; i--) {
+ var anomaly = gravitationalAnomalies[i];
+ if (anomaly.toBeRemoved) {
+ game.removeChild(anomaly);
+ gravitationalAnomalies.splice(i, 1);
+ continue;
+ }
+ // Check if ship is affected by anomaly
+ var dx = ship.x - anomaly.x;
+ var dy = ship.y - anomaly.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < anomaly.radius) {
+ // Apply gravitational pull
+ var pullStrength = anomaly.strength * (1 - distance / anomaly.radius);
+ ship.x += dx * pullStrength;
+ ship.y += dy * pullStrength;
+ }
+ }
// Update and check upgrade crates
for (var i = upgradeCrates.length - 1; i >= 0; i--) {
var crate = upgradeCrates[i];
if (crate.toBeRemoved) {