/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Laser Cannon Class var Cannon = Container.expand(function () { var self = Container.call(this); // Base var base = self.attachAsset('cannonBase', { anchorX: 0.5, anchorY: 0.5, y: 0 }); // Barrel var barrel = self.attachAsset('cannonBarrel', { anchorX: 0.5, anchorY: 1, y: -80 }); // Glow (for charging) var glow = self.attachAsset('cannonGlow', { anchorX: 0.5, anchorY: 0.5, y: -80, alpha: 0 }); self.barrel = barrel; self.glow = glow; // Add a hitbox for the cannon body (for enemy collision) var bodyHitbox = LK.getAsset('cannonBase', { anchorX: 0.5, anchorY: 0.5, y: 0, alpha: 0 // invisible, just for collision }); self.addChild(bodyHitbox); self.bodyHitbox = bodyHitbox; // Cannon rotation (radians) self.angle = 0; // Charging state self.isCharging = false; self.chargeTime = 0; // ms // Set cannon angle (radians) self.setAngle = function (r) { self.angle = r; barrel.rotation = r - Math.PI / 2; glow.rotation = r - Math.PI / 2; }; // Start charging self.startCharge = function () { self.isCharging = true; self.chargeTime = 0; glow.alpha = 0.5; glow.scaleX = 1; glow.scaleY = 1; }; // Stop charging self.stopCharge = function () { self.isCharging = false; glow.alpha = 0; glow.scaleX = 1; glow.scaleY = 1; }; // Update charging visuals self.updateCharge = function (dt) { if (self.isCharging) { self.chargeTime += dt; var scale = 1 + Math.min(self.chargeTime / 800, 1.5); glow.scaleX = scale; glow.scaleY = scale; glow.alpha = 0.5 + 0.3 * Math.sin(LK.ticks / 6); } }; return self; }); // Enemy Drone Class var Drone = Container.expand(function () { var self = Container.call(this); // Body var body = self.attachAsset('droneBody', { anchorX: 0.5, anchorY: 0.5 }); // Eye var eye = self.attachAsset('droneEye', { anchorX: 0.5, anchorY: 0.5, y: 0 }); // Movement self.speed = 3 + Math.random() * 2; // Will be increased by wave self.waveOffset = Math.random() * Math.PI * 2; self.waveAmp = 60 + Math.random() * 40; // For collision self.radius = 60; // Update self.update = function () { // Sway left/right self.x += Math.sin(self.y / 180 + self.waveOffset) * 2; self.y += self.speed; }; return self; }); // Explosion Effect var Explosion = Container.expand(function () { var self = Container.call(this); var exp = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); // Animate and destroy tween(exp, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); return self; }); // Laser Beam Class var LaserBeam = Container.expand(function () { var self = Container.call(this); // Beam var beam = self.attachAsset('laserBeam', { anchorX: 0.5, anchorY: 1, y: 0 }); self.beam = beam; // Direction (radians) self.angle = 0; // Power (1 = normal, >1 = charged) self.power = 1; // Speed (pixels per frame) self.speed = 60; // Set angle self.setAngle = function (r) { self.angle = r; self.rotation = r - Math.PI / 2; }; // Set power (affects width/length) self.setPower = function (p) { self.power = p; beam.width = 24 * p; beam.height = 900 + 300 * (p - 1); }; // Update self.update = function () { self.x += Math.cos(self.angle) * self.speed; self.y += Math.sin(self.angle) * self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181c2a }); /**** * Game Code ****/ // Background shape asset // Sound effects // Explosion effect // Enemy Drone // Laser Beam // Laser Cannon (player) // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var CANNON_Y = GAME_HEIGHT - 180; var CANNON_X = GAME_WIDTH / 2; // State var cannon; var laserBeams = []; var drones = []; var canFire = true; var fireCooldown = 0; var lastTouch = { x: CANNON_X, y: CANNON_Y - 400 }; var wave = 1; var spawnTimer = 0; var spawnInterval = 140; // frames (increased to reduce enemy quantity) var scoreTxt; // Add background shape var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: GAME_WIDTH, height: GAME_HEIGHT, color: 0x222244 }); game.addChild(background); // Add cannon cannon = new Cannon(); game.addChild(cannon); cannon.x = CANNON_X; cannon.y = CANNON_Y; cannon.setAngle(-Math.PI / 2); // Score display scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Helper: clamp angle to upper half of screen function clampAngle(r) { // Only allow aiming between -160deg and -20deg (in radians) var min = -Math.PI * 0.89; // ~-160deg var max = -Math.PI * 0.11; // ~-20deg if (r < min) r = min; if (r > max) r = max; return r; } // Touch/drag aiming and charging var isTouching = false; game.down = function (x, y, obj) { // Don't allow touch in top 100px (menu) if (y < 100 && x < 100) return; isTouching = true; lastTouch.x = x; lastTouch.y = y; // Calculate angle var dx = x - cannon.x; var dy = y - cannon.y; var angle = Math.atan2(dy, dx); angle = clampAngle(angle); cannon.setAngle(angle); cannon.startCharge(); }; game.move = function (x, y, obj) { if (!isTouching) return; lastTouch.x = x; lastTouch.y = y; var dx = x - cannon.x; var dy = y - cannon.y; var angle = Math.atan2(dy, dx); angle = clampAngle(angle); cannon.setAngle(angle); }; game.up = function (x, y, obj) { if (!isTouching) return; isTouching = false; // Fire laser if (canFire) { var power = 1 + Math.min(cannon.chargeTime / 800, 1.5); // up to 2.5x fireLaser(cannon.angle, power); canFire = false; fireCooldown = 24; // frames } cannon.stopCharge(); }; // Fire laser function fireLaser(angle, power) { var laser = new LaserBeam(); laser.x = cannon.x + Math.cos(angle) * 0; laser.y = cannon.y + Math.sin(angle) * 0; laser.setAngle(angle); laser.setPower(power); laserBeams.push(laser); game.addChild(laser); LK.getSound('laserFire').play(); } // Spawn a drone function spawnDrone() { var drone = new Drone(); // Random x, but not too close to edge var margin = 120; drone.x = margin + Math.random() * (GAME_WIDTH - margin * 2); drone.y = -80; // Increase speed with wave drone.speed += (wave - 1) * 0.5; drones.push(drone); game.addChild(drone); } // Destroy drone with explosion function destroyDrone(drone) { var exp = new Explosion(); exp.x = drone.x; exp.y = drone.y; game.addChild(exp); LK.getSound('droneExplode').play(); drone.destroy(); } // Main update loop game.update = function () { // Update cannon charging visuals cannon.updateCharge(16.7); // Fire cooldown if (!canFire) { fireCooldown--; if (fireCooldown <= 0) canFire = true; } // Laser beams update for (var i = laserBeams.length - 1; i >= 0; i--) { var l = laserBeams[i]; l.update(); // Remove if off screen if (l.x < -100 || l.x > GAME_WIDTH + 100 || l.y < -100 || l.y > GAME_HEIGHT + 100) { l.destroy(); laserBeams.splice(i, 1); continue; } } // Drones update for (var j = drones.length - 1; j >= 0; j--) { var d = drones[j]; d.update(); // Check if reached cannon (game over) // Check collision with cannon body hitbox if (d.bodyLastWasIntersecting === undefined) d.bodyLastWasIntersecting = false; var isIntersecting = d.intersects(cannon.bodyHitbox); if (!d.bodyLastWasIntersecting && isIntersecting) { // Game over LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } d.bodyLastWasIntersecting = isIntersecting; // Remove if off screen if (d.y > GAME_HEIGHT + 100) { d.destroy(); drones.splice(j, 1); continue; } } // Laser-drone collision for (var i = laserBeams.length - 1; i >= 0; i--) { var l = laserBeams[i]; var lx = l.x + Math.cos(l.angle) * l.beam.height / 2; var ly = l.y + Math.sin(l.angle) * l.beam.height / 2; for (var j = drones.length - 1; j >= 0; j--) { var d = drones[j]; // Approximate collision: check if laser line passes through drone circle var dx = d.x - l.x; var dy = d.y - l.y; var proj = dx * Math.cos(l.angle) + dy * Math.sin(l.angle); if (proj > 0 && proj < l.beam.height) { // Closest point on beam var px = l.x + Math.cos(l.angle) * proj; var py = l.y + Math.sin(l.angle) * proj; var dist = Math.sqrt((d.x - px) * (d.x - px) + (d.y - py) * (d.y - py)); if (dist < d.radius * (0.7 + 0.2 * l.power)) { // Hit! destroyDrone(d); drones.splice(j, 1); // Score var addScore = Math.floor(10 * l.power); LK.setScore(LK.getScore() + addScore); scoreTxt.setText(LK.getScore()); // Remove laser l.destroy(); laserBeams.splice(i, 1); break; } } } } // Spawn drones spawnTimer++; var interval = Math.max(60, spawnInterval - (wave - 1) * 3); if (spawnTimer >= interval) { spawnDrone(); spawnTimer = 0; } // Increase wave every 20 drones destroyed var currentScore = LK.getScore(); var newWave = 1 + Math.floor(currentScore / 200); if (newWave > wave) { wave = newWave; // Flash for new wave LK.effects.flashScreen(0x44ff44, 400); } }; // Play background music at game start LK.playMusic('1alarmofwar');
===================================================================
--- original.js
+++ change.js
@@ -171,15 +171,15 @@
/****
* Game Code
****/
-// Game constants
-// Laser Cannon (player)
-// Laser Beam
-// Enemy Drone
-// Explosion effect
-// Sound effects
// Background shape asset
+// Sound effects
+// Explosion effect
+// Enemy Drone
+// Laser Beam
+// Laser Cannon (player)
+// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var CANNON_Y = GAME_HEIGHT - 180;
var CANNON_X = GAME_WIDTH / 2;
@@ -389,6 +389,6 @@
// Flash for new wave
LK.effects.flashScreen(0x44ff44, 400);
}
};
-// Play music (if you want to add music, uncomment and set up an asset)
-// LK.playMusic('bgmusic');
\ No newline at end of file
+// Play background music at game start
+LK.playMusic('1alarmofwar');
\ No newline at end of file