/****
* 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