Code edit (1 edits merged)
Please save this source code
User prompt
move the glaud sign down a little bit.
User prompt
move the glaud sign down a little bit.
User prompt
Add a small “Glaud” inscription in the upper right corner, orange color
User prompt
we must be able to hit enemies.
Code edit (1 edits merged)
Please save this source code
User prompt
Rocket Blast Defense
User prompt
Please continue polishing my design document.
Initial prompt
Idea 3: Melody of Shadows (Stealth / Puzzle Platformer) Concept: The player controls an agile character who can manipulate light and shadow. Shadows can become both hiding places and physical platforms. Mechanics: The player can move, block or destroy light sources. Created shadows can be walked on, climbed or hidden in. Different types of light (e.g. moonlight, firelight, magic light) can create shadows with different properties (e.g. slippery, sticky, damaging). Sound mechanics can also be added: Enemies become sensitive to sound, the player can make noises as a distraction. Maybe some puzzles are based on rhythm or melody. Stealth-oriented; avoiding enemies and reaching objectives undetected is essential. Story Potential: A noir story set in a city plunged into darkness could be the story of a character who wants to become a shadow master in a magical world. Why It's Great: High potential to be atmospheric and visually appealing. Allows for creative puzzle designs. Encourages the player to think cleverly.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, level: 1 }); /**** * Classes ****/ var CounterRocket = Container.expand(function () { var self = Container.call(this); var rocketGraphic = self.attachAsset('counter_rocket', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 12; self.active = true; self.blastRadius = 100; self.init = function (startX, startY, targetX, targetY) { self.x = startX; self.y = startY; self.targetX = targetX; self.targetY = targetY; // Calculate direction vector var dx = targetX - startX; var dy = targetY - startY; var dist = Math.sqrt(dx * dx + dy * dy); self.vx = dx / dist * self.speed; self.vy = dy / dist * self.speed; // Set rotation self.rotation = Math.atan2(dx, -dy); }; self.update = function () { if (!self.active) { return; } // Move along trajectory self.x += self.vx; self.y += self.vy; // Check if reached target area var distToTarget = Math.sqrt(Math.pow(self.x - self.targetX, 2) + Math.pow(self.y - self.targetY, 2)); if (distToTarget < 10) { self.explode(); } // Check if off screen if (self.y < -100 || self.y > 2832 || self.x < -100 || self.x > 2148) { self.destroy(); // Remove from counter rockets array var index = counterRockets.indexOf(self); if (index !== -1) { counterRockets.splice(index, 1); } } }; self.explode = function () { self.active = false; // Create explosion var explosion = new Explosion(); explosion.x = self.x; explosion.y = self.y; explosion.init(self.blastRadius); game.addChild(explosion); // Check for missile hits game.checkMissileHits(self.x, self.y, self.blastRadius); // Play sound LK.getSound('explosion_sound').play(); // Remove rocket self.destroy(); // Remove from counter rockets array var index = counterRockets.indexOf(self); if (index !== -1) { counterRockets.splice(index, 1); } }; return self; }); var DefenseStation = Container.expand(function () { var self = Container.call(this); var stationGraphic = self.attachAsset('defense_station', { anchorX: 0.5, anchorY: 0.5 }); var aimLine = self.attachAsset('aim_line', { anchorX: 0.5, anchorY: 1, alpha: 0.7 }); self.init = function () { self.x = 2048 / 2; self.y = 2732 - 60 - 100; // Just above ground aimLine.visible = false; aimLine.rotation = -Math.PI / 2; // Pointing upward }; self.startAiming = function (x, y) { aimLine.visible = true; self.updateAimLine(x, y); }; self.updateAimLine = function (x, y) { if (!aimLine.visible) { return; } // Calculate angle for aim line var dx = x - self.x; var dy = y - self.y; var angle = Math.atan2(dx, -dy); // Negative dy because y is inverted // Restrict angle (can't aim below horizon) if (angle > Math.PI / 2) { angle = Math.PI / 2; } if (angle < -Math.PI / 2) { angle = -Math.PI / 2; } aimLine.rotation = angle; }; self.stopAiming = function () { aimLine.visible = false; }; self.fire = function (x, y) { // Calculate direction and target position var dx = x - self.x; var dy = y - self.y; var angle = Math.atan2(dx, -dy); // Restrict angle (can't fire below horizon) if (angle > Math.PI / 2) { angle = Math.PI / 2; } if (angle < -Math.PI / 2) { angle = -Math.PI / 2; } // Calculate target point var reach = 2000; var targetX = self.x + Math.sin(angle) * reach; var targetY = self.y - Math.cos(angle) * reach; // Fire main rocket var rocket = new CounterRocket(); rocket.init(self.x, self.y, targetX, targetY); counterRockets.push(rocket); game.addChild(rocket); // Fire additional rockets if multishot is active if (game.multishotActive) { var spread = Math.PI / 12; // 15 degrees // Left rocket var leftRocket = new CounterRocket(); var leftAngle = angle - spread; var leftTargetX = self.x + Math.sin(leftAngle) * reach; var leftTargetY = self.y - Math.cos(leftAngle) * reach; leftRocket.init(self.x, self.y, leftTargetX, leftTargetY); counterRockets.push(leftRocket); game.addChild(leftRocket); // Right rocket var rightRocket = new CounterRocket(); var rightAngle = angle + spread; var rightTargetX = self.x + Math.sin(rightAngle) * reach; var rightTargetY = self.y - Math.cos(rightAngle) * reach; rightRocket.init(self.x, self.y, rightTargetX, rightTargetY); counterRockets.push(rightRocket); game.addChild(rightRocket); } // Play sound LK.getSound('rocket_launch').play(); }; 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.init = function (radius) { self.radius = radius || 75; explosionGraphic.width = self.radius * 2; explosionGraphic.height = self.radius * 2; // Start animation explosionGraphic.alpha = 0.9; tween(explosionGraphic, { alpha: 0, width: self.radius * 3, height: self.radius * 3 }, { duration: 600, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var Missile = Container.expand(function () { var self = Container.call(this); var missileGraphic = self.attachAsset('missile', { anchorX: 0.5, anchorY: 0.5 }); // Default properties self.speed = 3; self.targetX = 0; self.active = true; self.init = function (startX, speed, targetX) { self.x = startX; self.y = -100; self.speed = speed || 3; self.targetX = targetX || self.x; // Calculate angle based on trajectory var dx = self.targetX - self.x; var dy = 2732 - self.y; self.rotation = Math.atan2(dx, dy); }; self.update = function () { if (!self.active) { return; } // Move towards target var dx = self.targetX - self.x; var groundY = 2732 - 60; // Ground level var percentComplete = self.y / groundY; self.x += dx * 0.005; self.y += self.speed; // Check if hit ground if (self.y >= groundY - 40) { self.explode(); game.missileHitGround(self.x); } }; self.explode = function () { self.active = false; // Create explosion var explosion = new Explosion(); explosion.x = self.x; explosion.y = self.y; explosion.init(75); game.addChild(explosion); // Play sound LK.getSound('explosion_sound').play(); // Remove missile self.destroy(); // Remove from missiles array var index = missiles.indexOf(self); if (index !== -1) { missiles.splice(index, 1); } }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphic = self.attachAsset('power_up', { anchorX: 0.5, anchorY: 0.5 }); self.type = "multishot"; self.fallSpeed = 2; self.active = true; self.init = function (type) { self.type = type || (Math.random() < 0.5 ? "multishot" : "nuke"); // Set color based on type if (self.type === "multishot") { powerUpGraphic.tint = 0x9b59b6; // Purple } else { powerUpGraphic.tint = 0xe74c3c; // Red } // Position self.x = 100 + Math.random() * (2048 - 200); self.y = -100; // Animation tween(self, { rotation: Math.PI * 2 }, { duration: 3000, onFinish: function onFinish() { if (self.active) { self.rotation = 0; tween(self, { rotation: Math.PI * 2 }, { duration: 3000 }); } } }); }; self.update = function () { if (!self.active) { return; } // Fall down self.y += self.fallSpeed; // Check if hit ground if (self.y >= 2732 - 60 - 40) { self.destroy(); var index = powerUps.indexOf(self); if (index !== -1) { powerUps.splice(index, 1); } } // Check if near defense station var distToStation = Math.sqrt(Math.pow(self.x - defenseStation.x, 2) + Math.pow(self.y - defenseStation.y, 2)); if (distToStation < 150) { self.collect(); } }; self.collect = function () { self.active = false; // Apply power up effect if (self.type === "multishot") { game.activateMultishot(); } else { game.activateNuke(); } // Play sound LK.getSound('power_up_collect').play(); // Remove power up self.destroy(); // Remove from powerUps array var index = powerUps.indexOf(self); if (index !== -1) { powerUps.splice(index, 1); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x121f2a }); /**** * Game Code ****/ // Game variables var score = 0; var level = 1; var lives = 3; var isAiming = false; var aimStartX = 0; var aimStartY = 0; var missiles = []; var counterRockets = []; var powerUps = []; var defenseStation; var ground; var gameActive = true; var missileSpawnRate = 3000; // Time in ms between missile spawns var missileSpawnTimer = null; var powerUpSpawnTimer = null; var multishotTimeoutId = null; var comboCount = 0; var comboTimer = null; // UI elements var scoreTxt; var livesTxt; var levelTxt; var comboTxt; // Initialize game objects function initGame() { // Set background game.setBackgroundColor(0x121f2a); // Play background music LK.playMusic('game_music'); // Create ground ground = LK.getAsset('ground', { anchorX: 0.5, anchorY: 0.5 }); ground.x = 2048 / 2; ground.y = 2732 - 30; // Bottom of screen game.addChild(ground); // Create defense station defenseStation = new DefenseStation(); defenseStation.init(); game.addChild(defenseStation); // Setup UI setupUI(); // Start missile spawning startMissileSpawner(); // Start power-up spawning startPowerUpSpawner(); // Reset game state score = 0; level = storage.level || 1; lives = 3; gameActive = true; game.multishotActive = false; comboCount = 0; // Update UI updateUI(); } function setupUI() { // Score text scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -280; scoreTxt.y = 20; // Lives text livesTxt = new Text2('Lives: 3', { size: 60, fill: 0xFFFFFF }); livesTxt.anchor.set(0, 0); LK.gui.top.addChild(livesTxt); livesTxt.y = 20; // Level text levelTxt = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(levelTxt); levelTxt.x = 120; // Avoid the top-left 100x100 reserved area levelTxt.y = 20; // Combo text comboTxt = new Text2('', { size: 80, fill: 0xF1C40F }); comboTxt.anchor.set(0.5, 0.5); LK.gui.center.addChild(comboTxt); comboTxt.visible = false; } function updateUI() { scoreTxt.setText('Score: ' + score); livesTxt.setText('Lives: ' + lives); levelTxt.setText('Level: ' + level); if (comboCount > 1) { comboTxt.setText('COMBO x' + comboCount + '!'); comboTxt.visible = true; // Reset combo timer if (comboTimer) { LK.clearTimeout(comboTimer); } comboTimer = LK.setTimeout(function () { comboTxt.visible = false; comboCount = 0; }, 2000); } } function startMissileSpawner() { // Clear any existing timer if (missileSpawnTimer) { LK.clearInterval(missileSpawnTimer); } // Calculate spawn rate based on level var rate = Math.max(3000 - level * 200, 500); missileSpawnTimer = LK.setInterval(function () { if (!gameActive) { return; } spawnMissile(); }, rate); } function spawnMissile() { // Create a new missile var missile = new Missile(); // Randomize starting position var startX = Math.random() * 2048; // Randomize target position var targetX = Math.random() * 2048; // Calculate speed based on level var speed = 3 + level * 0.5; // Initialize missile missile.init(startX, speed, targetX); // Add to game missiles.push(missile); game.addChild(missile); } function startPowerUpSpawner() { // Clear any existing timer if (powerUpSpawnTimer) { LK.clearInterval(powerUpSpawnTimer); } powerUpSpawnTimer = LK.setInterval(function () { if (!gameActive) { return; } // 10% chance to spawn a power-up if (Math.random() < 0.1) { spawnPowerUp(); } }, 5000); } function spawnPowerUp() { // Create a new power-up var powerUp = new PowerUp(); // Initialize power-up powerUp.init(); // Add to game powerUps.push(powerUp); game.addChild(powerUp); } // Game mechanics game.checkMissileHits = function (x, y, radius) { var hitCount = 0; // Check all missiles for (var i = missiles.length - 1; i >= 0; i--) { var missile = missiles[i]; if (!missile.active) { continue; } // Calculate distance var dist = Math.sqrt(Math.pow(missile.x - x, 2) + Math.pow(missile.y - y, 2)); // If missile is within blast radius if (dist <= radius) { missile.explode(); hitCount++; // Award points score += 10 * (1 + level * 0.1); // Increment combo comboCount++; if (comboCount > 1) { // Bonus points for combos score += 5 * comboCount; } } } // Check if level should advance if (score >= level * 1000) { advanceLevel(); } // Update UI updateUI(); return hitCount; }; game.missileHitGround = function (x) { // Visual effect var groundExplosion = new Explosion(); groundExplosion.x = x; groundExplosion.y = 2732 - 60; groundExplosion.init(100); game.addChild(groundExplosion); // Reduce lives lives--; // Reset combo comboCount = 0; if (comboTimer) { LK.clearTimeout(comboTimer); } comboTxt.visible = false; // Update UI updateUI(); // Check for game over if (lives <= 0) { gameOver(); } }; function gameOver() { gameActive = false; // Stop spawners if (missileSpawnTimer) { LK.clearInterval(missileSpawnTimer); } if (powerUpSpawnTimer) { LK.clearInterval(powerUpSpawnTimer); } // Update high score if (score > storage.highScore) { storage.highScore = score; } // Set final score LK.setScore(score); // Show game over screen LK.showGameOver(); } function advanceLevel() { level++; storage.level = level; // Update UI updateUI(); // Flash level indicator tween(levelTxt, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { tween(levelTxt, { alpha: 1 }, { duration: 200 }); } }); // Restart missile spawner with new rate startMissileSpawner(); } game.activateMultishot = function () { game.multishotActive = true; // Create visual indicator defenseStation.attachAsset('power_up', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -50, tint: 0x9b59b6, alpha: 0.7, scale: 0.5 }); // Clear previous timeout if exists if (multishotTimeoutId) { LK.clearTimeout(multishotTimeoutId); } // Set timeout to disable multishot multishotTimeoutId = LK.setTimeout(function () { game.multishotActive = false; // Remove all power-up indicators from defense station for (var i = 0; i < defenseStation.children.length; i++) { var child = defenseStation.children[i]; if (child.color && child.color === 0x9b59b6) { defenseStation.removeChild(child); child.destroy(); } } }, 10000); // 10 seconds }; game.activateNuke = function () { // Create large explosion at center var nukeExplosion = new Explosion(); nukeExplosion.x = 2048 / 2; nukeExplosion.y = 2732 / 2; nukeExplosion.init(1500); // Large radius game.addChild(nukeExplosion); // Destroy all missiles var destroyedCount = 0; for (var i = missiles.length - 1; i >= 0; i--) { var missile = missiles[i]; if (missile.active) { missile.explode(); destroyedCount++; } } // Award points if (destroyedCount > 0) { score += destroyedCount * 15; updateUI(); } }; // Input handling game.down = function (x, y, obj) { if (!gameActive) { return; } isAiming = true; aimStartX = x; aimStartY = y; // Start aiming defenseStation.startAiming(x, y); }; game.move = function (x, y, obj) { if (!isAiming || !gameActive) { return; } // Update aim line defenseStation.updateAimLine(x, y); }; game.up = function (x, y, obj) { if (!isAiming || !gameActive) { return; } // Fire rocket defenseStation.fire(x, y); // Reset aiming isAiming = false; defenseStation.stopAiming(); }; // Game loop game.update = function () { if (!gameActive) { return; } // Update missiles for (var i = missiles.length - 1; i >= 0; i--) { missiles[i].update(); } // Update counter rockets for (var i = counterRockets.length - 1; i >= 0; i--) { counterRockets[i].update(); } // Update power-ups for (var i = powerUps.length - 1; i >= 0; i--) { powerUps[i].update(); } }; // Initialize the game initGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,693 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0,
+ level: 1
+});
+
+/****
+* Classes
+****/
+var CounterRocket = Container.expand(function () {
+ var self = Container.call(this);
+ var rocketGraphic = self.attachAsset('counter_rocket', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 12;
+ self.active = true;
+ self.blastRadius = 100;
+ self.init = function (startX, startY, targetX, targetY) {
+ self.x = startX;
+ self.y = startY;
+ self.targetX = targetX;
+ self.targetY = targetY;
+ // Calculate direction vector
+ var dx = targetX - startX;
+ var dy = targetY - startY;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ self.vx = dx / dist * self.speed;
+ self.vy = dy / dist * self.speed;
+ // Set rotation
+ self.rotation = Math.atan2(dx, -dy);
+ };
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ // Move along trajectory
+ self.x += self.vx;
+ self.y += self.vy;
+ // Check if reached target area
+ var distToTarget = Math.sqrt(Math.pow(self.x - self.targetX, 2) + Math.pow(self.y - self.targetY, 2));
+ if (distToTarget < 10) {
+ self.explode();
+ }
+ // Check if off screen
+ if (self.y < -100 || self.y > 2832 || self.x < -100 || self.x > 2148) {
+ self.destroy();
+ // Remove from counter rockets array
+ var index = counterRockets.indexOf(self);
+ if (index !== -1) {
+ counterRockets.splice(index, 1);
+ }
+ }
+ };
+ self.explode = function () {
+ self.active = false;
+ // Create explosion
+ var explosion = new Explosion();
+ explosion.x = self.x;
+ explosion.y = self.y;
+ explosion.init(self.blastRadius);
+ game.addChild(explosion);
+ // Check for missile hits
+ game.checkMissileHits(self.x, self.y, self.blastRadius);
+ // Play sound
+ LK.getSound('explosion_sound').play();
+ // Remove rocket
+ self.destroy();
+ // Remove from counter rockets array
+ var index = counterRockets.indexOf(self);
+ if (index !== -1) {
+ counterRockets.splice(index, 1);
+ }
+ };
+ return self;
+});
+var DefenseStation = Container.expand(function () {
+ var self = Container.call(this);
+ var stationGraphic = self.attachAsset('defense_station', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var aimLine = self.attachAsset('aim_line', {
+ anchorX: 0.5,
+ anchorY: 1,
+ alpha: 0.7
+ });
+ self.init = function () {
+ self.x = 2048 / 2;
+ self.y = 2732 - 60 - 100; // Just above ground
+ aimLine.visible = false;
+ aimLine.rotation = -Math.PI / 2; // Pointing upward
+ };
+ self.startAiming = function (x, y) {
+ aimLine.visible = true;
+ self.updateAimLine(x, y);
+ };
+ self.updateAimLine = function (x, y) {
+ if (!aimLine.visible) {
+ return;
+ }
+ // Calculate angle for aim line
+ var dx = x - self.x;
+ var dy = y - self.y;
+ var angle = Math.atan2(dx, -dy); // Negative dy because y is inverted
+ // Restrict angle (can't aim below horizon)
+ if (angle > Math.PI / 2) {
+ angle = Math.PI / 2;
+ }
+ if (angle < -Math.PI / 2) {
+ angle = -Math.PI / 2;
+ }
+ aimLine.rotation = angle;
+ };
+ self.stopAiming = function () {
+ aimLine.visible = false;
+ };
+ self.fire = function (x, y) {
+ // Calculate direction and target position
+ var dx = x - self.x;
+ var dy = y - self.y;
+ var angle = Math.atan2(dx, -dy);
+ // Restrict angle (can't fire below horizon)
+ if (angle > Math.PI / 2) {
+ angle = Math.PI / 2;
+ }
+ if (angle < -Math.PI / 2) {
+ angle = -Math.PI / 2;
+ }
+ // Calculate target point
+ var reach = 2000;
+ var targetX = self.x + Math.sin(angle) * reach;
+ var targetY = self.y - Math.cos(angle) * reach;
+ // Fire main rocket
+ var rocket = new CounterRocket();
+ rocket.init(self.x, self.y, targetX, targetY);
+ counterRockets.push(rocket);
+ game.addChild(rocket);
+ // Fire additional rockets if multishot is active
+ if (game.multishotActive) {
+ var spread = Math.PI / 12; // 15 degrees
+ // Left rocket
+ var leftRocket = new CounterRocket();
+ var leftAngle = angle - spread;
+ var leftTargetX = self.x + Math.sin(leftAngle) * reach;
+ var leftTargetY = self.y - Math.cos(leftAngle) * reach;
+ leftRocket.init(self.x, self.y, leftTargetX, leftTargetY);
+ counterRockets.push(leftRocket);
+ game.addChild(leftRocket);
+ // Right rocket
+ var rightRocket = new CounterRocket();
+ var rightAngle = angle + spread;
+ var rightTargetX = self.x + Math.sin(rightAngle) * reach;
+ var rightTargetY = self.y - Math.cos(rightAngle) * reach;
+ rightRocket.init(self.x, self.y, rightTargetX, rightTargetY);
+ counterRockets.push(rightRocket);
+ game.addChild(rightRocket);
+ }
+ // Play sound
+ LK.getSound('rocket_launch').play();
+ };
+ 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.init = function (radius) {
+ self.radius = radius || 75;
+ explosionGraphic.width = self.radius * 2;
+ explosionGraphic.height = self.radius * 2;
+ // Start animation
+ explosionGraphic.alpha = 0.9;
+ tween(explosionGraphic, {
+ alpha: 0,
+ width: self.radius * 3,
+ height: self.radius * 3
+ }, {
+ duration: 600,
+ onFinish: function onFinish() {
+ self.destroy();
+ }
+ });
+ };
+ return self;
+});
+var Missile = Container.expand(function () {
+ var self = Container.call(this);
+ var missileGraphic = self.attachAsset('missile', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Default properties
+ self.speed = 3;
+ self.targetX = 0;
+ self.active = true;
+ self.init = function (startX, speed, targetX) {
+ self.x = startX;
+ self.y = -100;
+ self.speed = speed || 3;
+ self.targetX = targetX || self.x;
+ // Calculate angle based on trajectory
+ var dx = self.targetX - self.x;
+ var dy = 2732 - self.y;
+ self.rotation = Math.atan2(dx, dy);
+ };
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ // Move towards target
+ var dx = self.targetX - self.x;
+ var groundY = 2732 - 60; // Ground level
+ var percentComplete = self.y / groundY;
+ self.x += dx * 0.005;
+ self.y += self.speed;
+ // Check if hit ground
+ if (self.y >= groundY - 40) {
+ self.explode();
+ game.missileHitGround(self.x);
+ }
+ };
+ self.explode = function () {
+ self.active = false;
+ // Create explosion
+ var explosion = new Explosion();
+ explosion.x = self.x;
+ explosion.y = self.y;
+ explosion.init(75);
+ game.addChild(explosion);
+ // Play sound
+ LK.getSound('explosion_sound').play();
+ // Remove missile
+ self.destroy();
+ // Remove from missiles array
+ var index = missiles.indexOf(self);
+ if (index !== -1) {
+ missiles.splice(index, 1);
+ }
+ };
+ return self;
+});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ var powerUpGraphic = self.attachAsset('power_up', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.type = "multishot";
+ self.fallSpeed = 2;
+ self.active = true;
+ self.init = function (type) {
+ self.type = type || (Math.random() < 0.5 ? "multishot" : "nuke");
+ // Set color based on type
+ if (self.type === "multishot") {
+ powerUpGraphic.tint = 0x9b59b6; // Purple
+ } else {
+ powerUpGraphic.tint = 0xe74c3c; // Red
+ }
+ // Position
+ self.x = 100 + Math.random() * (2048 - 200);
+ self.y = -100;
+ // Animation
+ tween(self, {
+ rotation: Math.PI * 2
+ }, {
+ duration: 3000,
+ onFinish: function onFinish() {
+ if (self.active) {
+ self.rotation = 0;
+ tween(self, {
+ rotation: Math.PI * 2
+ }, {
+ duration: 3000
+ });
+ }
+ }
+ });
+ };
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ // Fall down
+ self.y += self.fallSpeed;
+ // Check if hit ground
+ if (self.y >= 2732 - 60 - 40) {
+ self.destroy();
+ var index = powerUps.indexOf(self);
+ if (index !== -1) {
+ powerUps.splice(index, 1);
+ }
+ }
+ // Check if near defense station
+ var distToStation = Math.sqrt(Math.pow(self.x - defenseStation.x, 2) + Math.pow(self.y - defenseStation.y, 2));
+ if (distToStation < 150) {
+ self.collect();
+ }
+ };
+ self.collect = function () {
+ self.active = false;
+ // Apply power up effect
+ if (self.type === "multishot") {
+ game.activateMultishot();
+ } else {
+ game.activateNuke();
+ }
+ // Play sound
+ LK.getSound('power_up_collect').play();
+ // Remove power up
+ self.destroy();
+ // Remove from powerUps array
+ var index = powerUps.indexOf(self);
+ if (index !== -1) {
+ powerUps.splice(index, 1);
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x121f2a
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var score = 0;
+var level = 1;
+var lives = 3;
+var isAiming = false;
+var aimStartX = 0;
+var aimStartY = 0;
+var missiles = [];
+var counterRockets = [];
+var powerUps = [];
+var defenseStation;
+var ground;
+var gameActive = true;
+var missileSpawnRate = 3000; // Time in ms between missile spawns
+var missileSpawnTimer = null;
+var powerUpSpawnTimer = null;
+var multishotTimeoutId = null;
+var comboCount = 0;
+var comboTimer = null;
+// UI elements
+var scoreTxt;
+var livesTxt;
+var levelTxt;
+var comboTxt;
+// Initialize game objects
+function initGame() {
+ // Set background
+ game.setBackgroundColor(0x121f2a);
+ // Play background music
+ LK.playMusic('game_music');
+ // Create ground
+ ground = LK.getAsset('ground', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ ground.x = 2048 / 2;
+ ground.y = 2732 - 30; // Bottom of screen
+ game.addChild(ground);
+ // Create defense station
+ defenseStation = new DefenseStation();
+ defenseStation.init();
+ game.addChild(defenseStation);
+ // Setup UI
+ setupUI();
+ // Start missile spawning
+ startMissileSpawner();
+ // Start power-up spawning
+ startPowerUpSpawner();
+ // Reset game state
+ score = 0;
+ level = storage.level || 1;
+ lives = 3;
+ gameActive = true;
+ game.multishotActive = false;
+ comboCount = 0;
+ // Update UI
+ updateUI();
+}
+function setupUI() {
+ // Score text
+ scoreTxt = new Text2('Score: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ scoreTxt.anchor.set(0, 0);
+ LK.gui.topRight.addChild(scoreTxt);
+ scoreTxt.x = -280;
+ scoreTxt.y = 20;
+ // Lives text
+ livesTxt = new Text2('Lives: 3', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ livesTxt.anchor.set(0, 0);
+ LK.gui.top.addChild(livesTxt);
+ livesTxt.y = 20;
+ // Level text
+ levelTxt = new Text2('Level: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ levelTxt.anchor.set(0, 0);
+ LK.gui.topLeft.addChild(levelTxt);
+ levelTxt.x = 120; // Avoid the top-left 100x100 reserved area
+ levelTxt.y = 20;
+ // Combo text
+ comboTxt = new Text2('', {
+ size: 80,
+ fill: 0xF1C40F
+ });
+ comboTxt.anchor.set(0.5, 0.5);
+ LK.gui.center.addChild(comboTxt);
+ comboTxt.visible = false;
+}
+function updateUI() {
+ scoreTxt.setText('Score: ' + score);
+ livesTxt.setText('Lives: ' + lives);
+ levelTxt.setText('Level: ' + level);
+ if (comboCount > 1) {
+ comboTxt.setText('COMBO x' + comboCount + '!');
+ comboTxt.visible = true;
+ // Reset combo timer
+ if (comboTimer) {
+ LK.clearTimeout(comboTimer);
+ }
+ comboTimer = LK.setTimeout(function () {
+ comboTxt.visible = false;
+ comboCount = 0;
+ }, 2000);
+ }
+}
+function startMissileSpawner() {
+ // Clear any existing timer
+ if (missileSpawnTimer) {
+ LK.clearInterval(missileSpawnTimer);
+ }
+ // Calculate spawn rate based on level
+ var rate = Math.max(3000 - level * 200, 500);
+ missileSpawnTimer = LK.setInterval(function () {
+ if (!gameActive) {
+ return;
+ }
+ spawnMissile();
+ }, rate);
+}
+function spawnMissile() {
+ // Create a new missile
+ var missile = new Missile();
+ // Randomize starting position
+ var startX = Math.random() * 2048;
+ // Randomize target position
+ var targetX = Math.random() * 2048;
+ // Calculate speed based on level
+ var speed = 3 + level * 0.5;
+ // Initialize missile
+ missile.init(startX, speed, targetX);
+ // Add to game
+ missiles.push(missile);
+ game.addChild(missile);
+}
+function startPowerUpSpawner() {
+ // Clear any existing timer
+ if (powerUpSpawnTimer) {
+ LK.clearInterval(powerUpSpawnTimer);
+ }
+ powerUpSpawnTimer = LK.setInterval(function () {
+ if (!gameActive) {
+ return;
+ }
+ // 10% chance to spawn a power-up
+ if (Math.random() < 0.1) {
+ spawnPowerUp();
+ }
+ }, 5000);
+}
+function spawnPowerUp() {
+ // Create a new power-up
+ var powerUp = new PowerUp();
+ // Initialize power-up
+ powerUp.init();
+ // Add to game
+ powerUps.push(powerUp);
+ game.addChild(powerUp);
+}
+// Game mechanics
+game.checkMissileHits = function (x, y, radius) {
+ var hitCount = 0;
+ // Check all missiles
+ for (var i = missiles.length - 1; i >= 0; i--) {
+ var missile = missiles[i];
+ if (!missile.active) {
+ continue;
+ }
+ // Calculate distance
+ var dist = Math.sqrt(Math.pow(missile.x - x, 2) + Math.pow(missile.y - y, 2));
+ // If missile is within blast radius
+ if (dist <= radius) {
+ missile.explode();
+ hitCount++;
+ // Award points
+ score += 10 * (1 + level * 0.1);
+ // Increment combo
+ comboCount++;
+ if (comboCount > 1) {
+ // Bonus points for combos
+ score += 5 * comboCount;
+ }
+ }
+ }
+ // Check if level should advance
+ if (score >= level * 1000) {
+ advanceLevel();
+ }
+ // Update UI
+ updateUI();
+ return hitCount;
+};
+game.missileHitGround = function (x) {
+ // Visual effect
+ var groundExplosion = new Explosion();
+ groundExplosion.x = x;
+ groundExplosion.y = 2732 - 60;
+ groundExplosion.init(100);
+ game.addChild(groundExplosion);
+ // Reduce lives
+ lives--;
+ // Reset combo
+ comboCount = 0;
+ if (comboTimer) {
+ LK.clearTimeout(comboTimer);
+ }
+ comboTxt.visible = false;
+ // Update UI
+ updateUI();
+ // Check for game over
+ if (lives <= 0) {
+ gameOver();
+ }
+};
+function gameOver() {
+ gameActive = false;
+ // Stop spawners
+ if (missileSpawnTimer) {
+ LK.clearInterval(missileSpawnTimer);
+ }
+ if (powerUpSpawnTimer) {
+ LK.clearInterval(powerUpSpawnTimer);
+ }
+ // Update high score
+ if (score > storage.highScore) {
+ storage.highScore = score;
+ }
+ // Set final score
+ LK.setScore(score);
+ // Show game over screen
+ LK.showGameOver();
+}
+function advanceLevel() {
+ level++;
+ storage.level = level;
+ // Update UI
+ updateUI();
+ // Flash level indicator
+ tween(levelTxt, {
+ alpha: 0
+ }, {
+ duration: 200,
+ onFinish: function onFinish() {
+ tween(levelTxt, {
+ alpha: 1
+ }, {
+ duration: 200
+ });
+ }
+ });
+ // Restart missile spawner with new rate
+ startMissileSpawner();
+}
+game.activateMultishot = function () {
+ game.multishotActive = true;
+ // Create visual indicator
+ defenseStation.attachAsset('power_up', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: -50,
+ tint: 0x9b59b6,
+ alpha: 0.7,
+ scale: 0.5
+ });
+ // Clear previous timeout if exists
+ if (multishotTimeoutId) {
+ LK.clearTimeout(multishotTimeoutId);
+ }
+ // Set timeout to disable multishot
+ multishotTimeoutId = LK.setTimeout(function () {
+ game.multishotActive = false;
+ // Remove all power-up indicators from defense station
+ for (var i = 0; i < defenseStation.children.length; i++) {
+ var child = defenseStation.children[i];
+ if (child.color && child.color === 0x9b59b6) {
+ defenseStation.removeChild(child);
+ child.destroy();
+ }
+ }
+ }, 10000); // 10 seconds
+};
+game.activateNuke = function () {
+ // Create large explosion at center
+ var nukeExplosion = new Explosion();
+ nukeExplosion.x = 2048 / 2;
+ nukeExplosion.y = 2732 / 2;
+ nukeExplosion.init(1500); // Large radius
+ game.addChild(nukeExplosion);
+ // Destroy all missiles
+ var destroyedCount = 0;
+ for (var i = missiles.length - 1; i >= 0; i--) {
+ var missile = missiles[i];
+ if (missile.active) {
+ missile.explode();
+ destroyedCount++;
+ }
+ }
+ // Award points
+ if (destroyedCount > 0) {
+ score += destroyedCount * 15;
+ updateUI();
+ }
+};
+// Input handling
+game.down = function (x, y, obj) {
+ if (!gameActive) {
+ return;
+ }
+ isAiming = true;
+ aimStartX = x;
+ aimStartY = y;
+ // Start aiming
+ defenseStation.startAiming(x, y);
+};
+game.move = function (x, y, obj) {
+ if (!isAiming || !gameActive) {
+ return;
+ }
+ // Update aim line
+ defenseStation.updateAimLine(x, y);
+};
+game.up = function (x, y, obj) {
+ if (!isAiming || !gameActive) {
+ return;
+ }
+ // Fire rocket
+ defenseStation.fire(x, y);
+ // Reset aiming
+ isAiming = false;
+ defenseStation.stopAiming();
+};
+// Game loop
+game.update = function () {
+ if (!gameActive) {
+ return;
+ }
+ // Update missiles
+ for (var i = missiles.length - 1; i >= 0; i--) {
+ missiles[i].update();
+ }
+ // Update counter rockets
+ for (var i = counterRockets.length - 1; i >= 0; i--) {
+ counterRockets[i].update();
+ }
+ // Update power-ups
+ for (var i = powerUps.length - 1; i >= 0; i--) {
+ powerUps[i].update();
+ }
+};
+// Initialize the game
+initGame();
\ No newline at end of file
defense_station. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
counter rocket. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
power up. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
explosion. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
missile. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
aim line. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
graund. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows