/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphic = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -15; self.active = true; self.update = function () { if (!self.active) { return; } self.y += self.speed; if (self.y < -50) { self.active = false; } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphic = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.active = true; self.movementPattern = "straight"; self.movementPhase = 0; self.speed = Math.random() * 2 + 1; self.fireRate = 180; // Frames between shots self.fireCooldown = Math.floor(Math.random() * 180); self.health = 1; self.initialize = function (pattern, speed, health) { self.movementPattern = pattern || "straight"; self.speed = speed || Math.random() * 2 + 1; self.health = health || 1; return self; }; self.update = function () { if (!self.active) { return; } self.movementPhase += 0.02; // Different movement patterns switch (self.movementPattern) { case "straight": self.y += self.speed; break; case "sine": self.y += self.speed; self.x += Math.sin(self.movementPhase) * 3; break; case "zigzag": self.y += self.speed; self.x += Math.sin(self.movementPhase * 2) > 0 ? 2 : -2; break; } // Check if off screen if (self.y > 2732 + 50) { self.active = false; } // Handle shooting if (self.fireCooldown > 0) { self.fireCooldown--; } else { self.shoot(); self.fireCooldown = self.fireRate; } }; self.shoot = function () { if (player && Math.random() < 0.3) { // 30% chance to shoot var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y + 25; enemyBullets.push(bullet); game.addChild(bullet); } }; self.hit = function () { self.health--; if (self.health <= 0) { LK.getSound('enemyExplode').play(); LK.effects.flashObject(self, 0xffffff, 300); // Chance to spawn powerup if (Math.random() < 0.1) { // 10% chance spawnPowerup(self.x, self.y); } self.active = false; return true; } return false; }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphic = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.active = true; self.update = function () { if (!self.active) { return; } self.y += self.speed; if (self.y > 2732 + 50) { self.active = false; } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphic = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.fireRate = 15; // Frames between shots self.fireCooldown = 0; self.lives = 3; self.invulnerable = false; self.invulnerableTime = 0; self.powerupTime = 0; self.hasPowerup = false; self.update = function () { if (self.fireCooldown > 0) { self.fireCooldown--; } if (self.invulnerable) { self.invulnerableTime--; // Flash effect when invulnerable self.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5; if (self.invulnerableTime <= 0) { self.invulnerable = false; self.alpha = 1; } } if (self.hasPowerup) { self.powerupTime--; if (self.powerupTime <= 0) { self.hasPowerup = false; // Reset fire rate when powerup ends self.fireRate = 15; } } }; self.shoot = function () { if (self.fireCooldown <= 0) { LK.getSound('playerShoot').play(); var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y - 30; bullet.lastY = bullet.y; bullets.push(bullet); game.addChild(bullet); // If player has powerup, create side bullets if (self.hasPowerup) { var bulletLeft = new Bullet(); bulletLeft.x = self.x - 30; bulletLeft.y = self.y - 20; bulletLeft.lastY = bulletLeft.y; var bulletRight = new Bullet(); bulletRight.x = self.x + 30; bulletRight.y = self.y - 20; bulletRight.lastY = bulletRight.y; bullets.push(bulletLeft, bulletRight); game.addChild(bulletLeft, bulletRight); } self.fireCooldown = self.fireRate; } }; self.hit = function () { if (self.invulnerable) { return; } LK.getSound('playerHit').play(); self.lives--; LK.effects.flashObject(self, 0xff0000, 500); if (self.lives <= 0) { // Game over handled by the game class return true; } else { // Make player invulnerable for a short time self.invulnerable = true; self.invulnerableTime = 120; // 2 seconds at 60fps return false; } }; self.activatePowerup = function () { self.hasPowerup = true; self.powerupTime = 600; // 10 seconds at 60fps self.fireRate = 8; // Faster firing with powerup }; return self; }); var Powerup = Container.expand(function () { var self = Container.call(this); var powerupGraphic = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.active = true; self.speed = 3; self.update = function () { if (!self.active) { return; } self.y += self.speed; // Gentle oscillation effect self.x += Math.sin(LK.ticks * 0.05) * 0.5; // Check if off screen if (self.y > 2732 + 50) { self.active = false; } }; return self; }); var Star = Container.expand(function () { var self = Container.call(this); var starGraphic = self.attachAsset('star', { anchorX: 0.5, anchorY: 0.5 }); self.speed = Math.random() * 3 + 1; self.update = function () { self.y += self.speed; if (self.y > 2732) { self.y = -10; self.x = Math.random() * 2048; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000022 }); /**** * Game Code ****/ // Game variables var player; var bullets = []; var enemies = []; var enemyBullets = []; var powerups = []; var stars = []; var gameState = "playing"; var score = 0; var level = 1; var enemySpawnTimer = 0; var levelTimer = 0; var dragTarget = null; // Game UI elements var scoreTxt; var livesText; var levelText; // Initialize game function function initGame() { // Reset game state bullets = []; enemies = []; enemyBullets = []; powerups = []; score = 0; level = 1; gameState = "playing"; // Create player player = new Player(); player.x = 2048 / 2; player.y = 2732 - 200; game.addChild(player); // Create background stars createStars(); // Initialize UI initUI(); // Start game music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.7, duration: 1000 } }); } function createStars() { // Clear existing stars for (var i = 0; i < stars.length; i++) { if (stars[i].parent) { stars[i].parent.removeChild(stars[i]); } } stars = []; // Create new stars for (var i = 0; i < 100; i++) { var star = new Star(); star.x = Math.random() * 2048; star.y = Math.random() * 2732; stars.push(star); game.addChild(star); } } function initUI() { // Score text scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -300; // Offset from right edge // Lives text livesText = new Text2('Lives: 3', { size: 60, fill: 0xFFFFFF }); livesText.anchor.set(0, 0); LK.gui.top.addChild(livesText); livesText.x = -200; // Offset from center // Level text levelText = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); LK.gui.top.addChild(levelText); levelText.x = 200; // Offset from center } function updateUI() { scoreTxt.setText('Score: ' + score); livesText.setText('Lives: ' + player.lives); levelText.setText('Level: ' + level); } function spawnEnemy() { var enemy = new Enemy(); // Set initial position enemy.x = Math.random() * (2048 - 200) + 100; enemy.y = -50; // Set properties based on level var pattern = "straight"; var health = 1; var spd = 1 + level * 0.2; // Higher levels get more complex enemies if (level > 1) { if (Math.random() < 0.3) { pattern = "sine"; } } if (level > 3) { if (Math.random() < 0.3) { pattern = "zigzag"; } if (Math.random() < 0.2) { health = 2; } } if (level > 5) { spd += 1; if (Math.random() < 0.3) { health = 3; } } enemy.initialize(pattern, spd, health); enemies.push(enemy); game.addChild(enemy); } function spawnPowerup(x, y) { var powerup = new Powerup(); powerup.x = x; powerup.y = y; powerups.push(powerup); game.addChild(powerup); } function handleCollisions() { // Player bullets vs enemies for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (!bullet.active) { continue; } for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (!enemy.active) { continue; } if (bullet.intersects(enemy)) { bullet.active = false; if (bullet.parent) { bullet.parent.removeChild(bullet); } bullets.splice(i, 1); if (enemy.hit()) { score += 10 * level; if (enemy.parent) { enemy.parent.removeChild(enemy); } enemies.splice(j, 1); } break; } } } // Enemy bullets vs player for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; if (!bullet.active) { continue; } if (player && bullet.intersects(player)) { bullet.active = false; if (bullet.parent) { bullet.parent.removeChild(bullet); } enemyBullets.splice(i, 1); if (player.hit()) { // Game over gameOver(); } } } // Enemies vs player for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (!enemy.active) { continue; } if (player && enemy.intersects(player)) { enemy.active = false; if (enemy.parent) { enemy.parent.removeChild(enemy); } enemies.splice(i, 1); if (player.hit()) { // Game over gameOver(); } } } // Powerups vs player for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; if (!powerup.active) { continue; } if (player && powerup.intersects(player)) { powerup.active = false; if (powerup.parent) { powerup.parent.removeChild(powerup); } powerups.splice(i, 1); // Activate powerup effect player.activatePowerup(); LK.getSound('powerupCollect').play(); score += 50; } } } function clearInactiveObjects() { // Clear inactive bullets for (var i = bullets.length - 1; i >= 0; i--) { if (!bullets[i].active) { if (bullets[i].parent) { bullets[i].parent.removeChild(bullets[i]); } bullets.splice(i, 1); } } // Clear inactive enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { if (!enemyBullets[i].active) { if (enemyBullets[i].parent) { enemyBullets[i].parent.removeChild(enemyBullets[i]); } enemyBullets.splice(i, 1); } } // Clear inactive enemies for (var i = enemies.length - 1; i >= 0; i--) { if (!enemies[i].active) { if (enemies[i].parent) { enemies[i].parent.removeChild(enemies[i]); } enemies.splice(i, 1); } } // Clear inactive powerups for (var i = powerups.length - 1; i >= 0; i--) { if (!powerups[i].active) { if (powerups[i].parent) { powerups[i].parent.removeChild(powerups[i]); } powerups.splice(i, 1); } } } function gameOver() { gameState = "over"; // Update high score if needed if (score > storage.highScore) { storage.highScore = score; console.log("New high score: " + score); } // Fade out music LK.playMusic('gameMusic', { fade: { start: 0.7, end: 0, duration: 1000 } }); // Show game over LK.effects.flashScreen(0xff0000, 800); // Let the engine handle game over LK.setScore(score); LK.showGameOver(); } function handleInput(x, y) { if (player && gameState === "playing") { player.x = x; // Keep player in bounds if (player.x < 50) { player.x = 50; } if (player.x > 2048 - 50) { player.x = 2048 - 50; } // Always shoot when moving player.shoot(); } } // Event handlers game.down = function (x, y, obj) { dragTarget = player; handleInput(x, y); }; game.up = function (x, y, obj) { dragTarget = null; }; game.move = function (x, y, obj) { if (dragTarget) { handleInput(x, y); } }; // Main game update function game.update = function () { if (gameState !== "playing") { return; } // Update player if (player) { player.update(); } // Update all game objects for (var i = 0; i < bullets.length; i++) { bullets[i].update(); } for (var i = 0; i < enemies.length; i++) { enemies[i].update(); } for (var i = 0; i < enemyBullets.length; i++) { enemyBullets[i].update(); } for (var i = 0; i < powerups.length; i++) { powerups[i].update(); } for (var i = 0; i < stars.length; i++) { stars[i].update(); } // Check for collisions handleCollisions(); // Clean up inactive objects clearInactiveObjects(); // Spawn enemies based on level enemySpawnTimer--; if (enemySpawnTimer <= 0) { spawnEnemy(); // Spawn rate decreases (gets faster) with level enemySpawnTimer = Math.max(20, 100 - level * 10); } // Level progression levelTimer++; if (levelTimer >= 1800) { // 30 seconds at 60fps level++; levelTimer = 0; // Spawn a powerup when leveling up spawnPowerup(Math.random() * 2048, 100); } // Update UI updateUI(); }; // Initialize the game initGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,612 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0
+});
+
+/****
+* Classes
+****/
+var Bullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphic = self.attachAsset('bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -15;
+ self.active = true;
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ self.y += self.speed;
+ if (self.y < -50) {
+ self.active = false;
+ }
+ };
+ return self;
+});
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ var enemyGraphic = self.attachAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.active = true;
+ self.movementPattern = "straight";
+ self.movementPhase = 0;
+ self.speed = Math.random() * 2 + 1;
+ self.fireRate = 180; // Frames between shots
+ self.fireCooldown = Math.floor(Math.random() * 180);
+ self.health = 1;
+ self.initialize = function (pattern, speed, health) {
+ self.movementPattern = pattern || "straight";
+ self.speed = speed || Math.random() * 2 + 1;
+ self.health = health || 1;
+ return self;
+ };
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ self.movementPhase += 0.02;
+ // Different movement patterns
+ switch (self.movementPattern) {
+ case "straight":
+ self.y += self.speed;
+ break;
+ case "sine":
+ self.y += self.speed;
+ self.x += Math.sin(self.movementPhase) * 3;
+ break;
+ case "zigzag":
+ self.y += self.speed;
+ self.x += Math.sin(self.movementPhase * 2) > 0 ? 2 : -2;
+ break;
+ }
+ // Check if off screen
+ if (self.y > 2732 + 50) {
+ self.active = false;
+ }
+ // Handle shooting
+ if (self.fireCooldown > 0) {
+ self.fireCooldown--;
+ } else {
+ self.shoot();
+ self.fireCooldown = self.fireRate;
+ }
+ };
+ self.shoot = function () {
+ if (player && Math.random() < 0.3) {
+ // 30% chance to shoot
+ var bullet = new EnemyBullet();
+ bullet.x = self.x;
+ bullet.y = self.y + 25;
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+ }
+ };
+ self.hit = function () {
+ self.health--;
+ if (self.health <= 0) {
+ LK.getSound('enemyExplode').play();
+ LK.effects.flashObject(self, 0xffffff, 300);
+ // Chance to spawn powerup
+ if (Math.random() < 0.1) {
+ // 10% chance
+ spawnPowerup(self.x, self.y);
+ }
+ self.active = false;
+ return true;
+ }
+ return false;
+ };
+ return self;
+});
+var EnemyBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphic = self.attachAsset('enemyBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 8;
+ self.active = true;
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ self.y += self.speed;
+ if (self.y > 2732 + 50) {
+ self.active = false;
+ }
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var playerGraphic = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.fireRate = 15; // Frames between shots
+ self.fireCooldown = 0;
+ self.lives = 3;
+ self.invulnerable = false;
+ self.invulnerableTime = 0;
+ self.powerupTime = 0;
+ self.hasPowerup = false;
+ self.update = function () {
+ if (self.fireCooldown > 0) {
+ self.fireCooldown--;
+ }
+ if (self.invulnerable) {
+ self.invulnerableTime--;
+ // Flash effect when invulnerable
+ self.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5;
+ if (self.invulnerableTime <= 0) {
+ self.invulnerable = false;
+ self.alpha = 1;
+ }
+ }
+ if (self.hasPowerup) {
+ self.powerupTime--;
+ if (self.powerupTime <= 0) {
+ self.hasPowerup = false;
+ // Reset fire rate when powerup ends
+ self.fireRate = 15;
+ }
+ }
+ };
+ self.shoot = function () {
+ if (self.fireCooldown <= 0) {
+ LK.getSound('playerShoot').play();
+ var bullet = new Bullet();
+ bullet.x = self.x;
+ bullet.y = self.y - 30;
+ bullet.lastY = bullet.y;
+ bullets.push(bullet);
+ game.addChild(bullet);
+ // If player has powerup, create side bullets
+ if (self.hasPowerup) {
+ var bulletLeft = new Bullet();
+ bulletLeft.x = self.x - 30;
+ bulletLeft.y = self.y - 20;
+ bulletLeft.lastY = bulletLeft.y;
+ var bulletRight = new Bullet();
+ bulletRight.x = self.x + 30;
+ bulletRight.y = self.y - 20;
+ bulletRight.lastY = bulletRight.y;
+ bullets.push(bulletLeft, bulletRight);
+ game.addChild(bulletLeft, bulletRight);
+ }
+ self.fireCooldown = self.fireRate;
+ }
+ };
+ self.hit = function () {
+ if (self.invulnerable) {
+ return;
+ }
+ LK.getSound('playerHit').play();
+ self.lives--;
+ LK.effects.flashObject(self, 0xff0000, 500);
+ if (self.lives <= 0) {
+ // Game over handled by the game class
+ return true;
+ } else {
+ // Make player invulnerable for a short time
+ self.invulnerable = true;
+ self.invulnerableTime = 120; // 2 seconds at 60fps
+ return false;
+ }
+ };
+ self.activatePowerup = function () {
+ self.hasPowerup = true;
+ self.powerupTime = 600; // 10 seconds at 60fps
+ self.fireRate = 8; // Faster firing with powerup
+ };
+ return self;
+});
+var Powerup = Container.expand(function () {
+ var self = Container.call(this);
+ var powerupGraphic = self.attachAsset('powerup', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.active = true;
+ self.speed = 3;
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ self.y += self.speed;
+ // Gentle oscillation effect
+ self.x += Math.sin(LK.ticks * 0.05) * 0.5;
+ // Check if off screen
+ if (self.y > 2732 + 50) {
+ self.active = false;
+ }
+ };
+ return self;
+});
+var Star = Container.expand(function () {
+ var self = Container.call(this);
+ var starGraphic = self.attachAsset('star', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = Math.random() * 3 + 1;
+ self.update = function () {
+ self.y += self.speed;
+ if (self.y > 2732) {
+ self.y = -10;
+ self.x = Math.random() * 2048;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x000022
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var player;
+var bullets = [];
+var enemies = [];
+var enemyBullets = [];
+var powerups = [];
+var stars = [];
+var gameState = "playing";
+var score = 0;
+var level = 1;
+var enemySpawnTimer = 0;
+var levelTimer = 0;
+var dragTarget = null;
+// Game UI elements
+var scoreTxt;
+var livesText;
+var levelText;
+// Initialize game function
+function initGame() {
+ // Reset game state
+ bullets = [];
+ enemies = [];
+ enemyBullets = [];
+ powerups = [];
+ score = 0;
+ level = 1;
+ gameState = "playing";
+ // Create player
+ player = new Player();
+ player.x = 2048 / 2;
+ player.y = 2732 - 200;
+ game.addChild(player);
+ // Create background stars
+ createStars();
+ // Initialize UI
+ initUI();
+ // Start game music
+ LK.playMusic('gameMusic', {
+ fade: {
+ start: 0,
+ end: 0.7,
+ duration: 1000
+ }
+ });
+}
+function createStars() {
+ // Clear existing stars
+ for (var i = 0; i < stars.length; i++) {
+ if (stars[i].parent) {
+ stars[i].parent.removeChild(stars[i]);
+ }
+ }
+ stars = [];
+ // Create new stars
+ for (var i = 0; i < 100; i++) {
+ var star = new Star();
+ star.x = Math.random() * 2048;
+ star.y = Math.random() * 2732;
+ stars.push(star);
+ game.addChild(star);
+ }
+}
+function initUI() {
+ // Score text
+ scoreTxt = new Text2('Score: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ scoreTxt.anchor.set(0, 0);
+ LK.gui.topRight.addChild(scoreTxt);
+ scoreTxt.x = -300; // Offset from right edge
+ // Lives text
+ livesText = new Text2('Lives: 3', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ livesText.anchor.set(0, 0);
+ LK.gui.top.addChild(livesText);
+ livesText.x = -200; // Offset from center
+ // Level text
+ levelText = new Text2('Level: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ levelText.anchor.set(0, 0);
+ LK.gui.top.addChild(levelText);
+ levelText.x = 200; // Offset from center
+}
+function updateUI() {
+ scoreTxt.setText('Score: ' + score);
+ livesText.setText('Lives: ' + player.lives);
+ levelText.setText('Level: ' + level);
+}
+function spawnEnemy() {
+ var enemy = new Enemy();
+ // Set initial position
+ enemy.x = Math.random() * (2048 - 200) + 100;
+ enemy.y = -50;
+ // Set properties based on level
+ var pattern = "straight";
+ var health = 1;
+ var spd = 1 + level * 0.2;
+ // Higher levels get more complex enemies
+ if (level > 1) {
+ if (Math.random() < 0.3) {
+ pattern = "sine";
+ }
+ }
+ if (level > 3) {
+ if (Math.random() < 0.3) {
+ pattern = "zigzag";
+ }
+ if (Math.random() < 0.2) {
+ health = 2;
+ }
+ }
+ if (level > 5) {
+ spd += 1;
+ if (Math.random() < 0.3) {
+ health = 3;
+ }
+ }
+ enemy.initialize(pattern, spd, health);
+ enemies.push(enemy);
+ game.addChild(enemy);
+}
+function spawnPowerup(x, y) {
+ var powerup = new Powerup();
+ powerup.x = x;
+ powerup.y = y;
+ powerups.push(powerup);
+ game.addChild(powerup);
+}
+function handleCollisions() {
+ // Player bullets vs enemies
+ for (var i = bullets.length - 1; i >= 0; i--) {
+ var bullet = bullets[i];
+ if (!bullet.active) {
+ continue;
+ }
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ var enemy = enemies[j];
+ if (!enemy.active) {
+ continue;
+ }
+ if (bullet.intersects(enemy)) {
+ bullet.active = false;
+ if (bullet.parent) {
+ bullet.parent.removeChild(bullet);
+ }
+ bullets.splice(i, 1);
+ if (enemy.hit()) {
+ score += 10 * level;
+ if (enemy.parent) {
+ enemy.parent.removeChild(enemy);
+ }
+ enemies.splice(j, 1);
+ }
+ break;
+ }
+ }
+ }
+ // Enemy bullets vs player
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ var bullet = enemyBullets[i];
+ if (!bullet.active) {
+ continue;
+ }
+ if (player && bullet.intersects(player)) {
+ bullet.active = false;
+ if (bullet.parent) {
+ bullet.parent.removeChild(bullet);
+ }
+ enemyBullets.splice(i, 1);
+ if (player.hit()) {
+ // Game over
+ gameOver();
+ }
+ }
+ }
+ // Enemies vs player
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ if (!enemy.active) {
+ continue;
+ }
+ if (player && enemy.intersects(player)) {
+ enemy.active = false;
+ if (enemy.parent) {
+ enemy.parent.removeChild(enemy);
+ }
+ enemies.splice(i, 1);
+ if (player.hit()) {
+ // Game over
+ gameOver();
+ }
+ }
+ }
+ // Powerups vs player
+ for (var i = powerups.length - 1; i >= 0; i--) {
+ var powerup = powerups[i];
+ if (!powerup.active) {
+ continue;
+ }
+ if (player && powerup.intersects(player)) {
+ powerup.active = false;
+ if (powerup.parent) {
+ powerup.parent.removeChild(powerup);
+ }
+ powerups.splice(i, 1);
+ // Activate powerup effect
+ player.activatePowerup();
+ LK.getSound('powerupCollect').play();
+ score += 50;
+ }
+ }
+}
+function clearInactiveObjects() {
+ // Clear inactive bullets
+ for (var i = bullets.length - 1; i >= 0; i--) {
+ if (!bullets[i].active) {
+ if (bullets[i].parent) {
+ bullets[i].parent.removeChild(bullets[i]);
+ }
+ bullets.splice(i, 1);
+ }
+ }
+ // Clear inactive enemy bullets
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ if (!enemyBullets[i].active) {
+ if (enemyBullets[i].parent) {
+ enemyBullets[i].parent.removeChild(enemyBullets[i]);
+ }
+ enemyBullets.splice(i, 1);
+ }
+ }
+ // Clear inactive enemies
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ if (!enemies[i].active) {
+ if (enemies[i].parent) {
+ enemies[i].parent.removeChild(enemies[i]);
+ }
+ enemies.splice(i, 1);
+ }
+ }
+ // Clear inactive powerups
+ for (var i = powerups.length - 1; i >= 0; i--) {
+ if (!powerups[i].active) {
+ if (powerups[i].parent) {
+ powerups[i].parent.removeChild(powerups[i]);
+ }
+ powerups.splice(i, 1);
+ }
+ }
+}
+function gameOver() {
+ gameState = "over";
+ // Update high score if needed
+ if (score > storage.highScore) {
+ storage.highScore = score;
+ console.log("New high score: " + score);
+ }
+ // Fade out music
+ LK.playMusic('gameMusic', {
+ fade: {
+ start: 0.7,
+ end: 0,
+ duration: 1000
+ }
+ });
+ // Show game over
+ LK.effects.flashScreen(0xff0000, 800);
+ // Let the engine handle game over
+ LK.setScore(score);
+ LK.showGameOver();
+}
+function handleInput(x, y) {
+ if (player && gameState === "playing") {
+ player.x = x;
+ // Keep player in bounds
+ if (player.x < 50) {
+ player.x = 50;
+ }
+ if (player.x > 2048 - 50) {
+ player.x = 2048 - 50;
+ }
+ // Always shoot when moving
+ player.shoot();
+ }
+}
+// Event handlers
+game.down = function (x, y, obj) {
+ dragTarget = player;
+ handleInput(x, y);
+};
+game.up = function (x, y, obj) {
+ dragTarget = null;
+};
+game.move = function (x, y, obj) {
+ if (dragTarget) {
+ handleInput(x, y);
+ }
+};
+// Main game update function
+game.update = function () {
+ if (gameState !== "playing") {
+ return;
+ }
+ // Update player
+ if (player) {
+ player.update();
+ }
+ // Update all game objects
+ for (var i = 0; i < bullets.length; i++) {
+ bullets[i].update();
+ }
+ for (var i = 0; i < enemies.length; i++) {
+ enemies[i].update();
+ }
+ for (var i = 0; i < enemyBullets.length; i++) {
+ enemyBullets[i].update();
+ }
+ for (var i = 0; i < powerups.length; i++) {
+ powerups[i].update();
+ }
+ for (var i = 0; i < stars.length; i++) {
+ stars[i].update();
+ }
+ // Check for collisions
+ handleCollisions();
+ // Clean up inactive objects
+ clearInactiveObjects();
+ // Spawn enemies based on level
+ enemySpawnTimer--;
+ if (enemySpawnTimer <= 0) {
+ spawnEnemy();
+ // Spawn rate decreases (gets faster) with level
+ enemySpawnTimer = Math.max(20, 100 - level * 10);
+ }
+ // Level progression
+ levelTimer++;
+ if (levelTimer >= 1800) {
+ // 30 seconds at 60fps
+ level++;
+ levelTimer = 0;
+ // Spawn a powerup when leveling up
+ spawnPowerup(Math.random() * 2048, 100);
+ }
+ // Update UI
+ updateUI();
+};
+// Initialize the game
+initGame();
\ No newline at end of file