/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Enemy var Enemy = Container.expand(function () { var self = Container.call(this); // type: 1,2,3 self.type = 1; self.row = 0; self.col = 0; self.isDiving = false; self.diveTargetX = 0; self.diveTargetY = 0; self.diveStep = 0; self.diveSpeed = 0; self.baseX = 0; self.baseY = 0; self.direction = 1; // 1: right, -1: left self.bulletCooldown = 0; self.alive = true; self.asset = null; self.init = function (type) { self.type = type; var assetId = 'enemy' + type; self.asset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.width = self.asset.width; self.height = self.asset.height; }; self.startDive = function (targetX, targetY, speed) { self.isDiving = true; self.diveTargetX = targetX; self.diveTargetY = targetY; self.diveStep = 0; self.diveSpeed = speed; }; self.update = function () { if (!self.alive) return; if (self.isDiving) { // Dive movement: curve towards player, then return var dx = self.diveTargetX - self.x; var dy = self.diveTargetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 40) { // Dive finished, return to base self.isDiving = false; tween(self, { x: self.baseX, y: self.baseY }, { duration: 600, easing: tween.cubicOut }); } else { var step = self.diveSpeed; self.x += dx / dist * step; self.y += dy / dist * step; } } // Bullet cooldown if (self.bulletCooldown > 0) self.bulletCooldown--; }; return self; }); // Enemy Bullet var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bullet = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 22; self.update = function () { self.y += self.speed; }; return self; }); // Player Bullet var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bullet = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -38; self.update = function () { self.y += self.speed; }; return self; }); // Player Ship var PlayerShip = Container.expand(function () { var self = Container.call(this); var ship = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); self.width = ship.width; self.height = ship.height; self.speed = 22; self.canShoot = true; self.shootCooldown = 0; self.update = function () { // Cooldown for shooting if (self.shootCooldown > 0) { self.shootCooldown--; if (self.shootCooldown === 0) self.canShoot = true; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000010 }); /**** * Game Code ****/ // Sounds // Bullets // Enemy types // Spaceship (player) // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var ENEMY_ROWS = 5; var ENEMY_COLS = 8; var ENEMY_SPACING_X = 180; var ENEMY_SPACING_Y = 160; var ENEMY_START_Y = 320; var ENEMY_START_X = (GAME_WIDTH - (ENEMY_COLS - 1) * ENEMY_SPACING_X) / 2 + ENEMY_SPACING_X / 2; var ENEMY_MOVE_STEP = 32; var ENEMY_MOVE_DOWN = 60; var ENEMY_MOVE_INTERVAL = 32; // ticks var ENEMY_DIVE_INTERVAL = 120; // ticks var ENEMY_BULLET_CHANCE = 0.012; // per update per enemy var PLAYER_Y = GAME_HEIGHT - 220; var PLAYER_SHOOT_COOLDOWN = 18; // ticks // Game state var playerShip = null; var playerBullets = []; var enemyBullets = []; var enemies = []; var enemyDirection = 1; // 1: right, -1: left var enemyMoveTick = 0; var enemyDiveTick = 0; var dragNode = null; var scoreTxt = null; var lastIntersecting = false; var gameOver = false; var wave = 1; // Score display scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Wave display var waveTxt = new Text2('Wave 1', { size: 80, fill: "#fff" }); waveTxt.anchor.set(0.5, 0); LK.gui.top.addChild(waveTxt); waveTxt.y = 120; // Initialize player playerShip = new PlayerShip(); game.addChild(playerShip); playerShip.x = GAME_WIDTH / 2; playerShip.y = PLAYER_Y; // Initialize enemies function spawnEnemies() { for (var row = 0; row < ENEMY_ROWS; row++) { for (var col = 0; col < ENEMY_COLS; col++) { var type = row === 0 ? 3 : row < 3 ? 2 : 1; var enemy = new Enemy(); enemy.init(type); enemy.row = row; enemy.col = col; enemy.baseX = ENEMY_START_X + col * ENEMY_SPACING_X; enemy.baseY = ENEMY_START_Y + row * ENEMY_SPACING_Y; enemy.x = enemy.baseX; enemy.y = enemy.baseY; enemy.direction = 1; enemy.isDiving = false; enemy.alive = true; enemies.push(enemy); game.addChild(enemy); } } } spawnEnemies(); // Handle player movement (dragging) function handleMove(x, y, obj) { if (gameOver) return; if (dragNode === playerShip) { // Clamp to game area, avoid left 100px for menu var minX = Math.max(playerShip.width / 2 + 100, 100 + playerShip.width / 2); var maxX = GAME_WIDTH - playerShip.width / 2; var newX = Math.max(minX, Math.min(maxX, x)); playerShip.x = newX; } } game.move = handleMove; game.down = function (x, y, obj) { if (gameOver) return; // Only allow drag if touch is on player ship var local = playerShip.toLocal(game.toGlobal({ x: x, y: y })); if (local.x >= -playerShip.width / 2 && local.x <= playerShip.width / 2 && local.y >= -playerShip.height / 2 && local.y <= playerShip.height / 2) { dragNode = playerShip; } }; game.up = function (x, y, obj) { dragNode = null; }; // Handle shooting (tap anywhere) game.tap = function (x, y, obj) { if (gameOver) return; shootPlayerBullet(); }; // For mobile, also allow shooting on down if not dragging game.down = function (x, y, obj) { if (gameOver) return; var local = playerShip.toLocal(game.toGlobal({ x: x, y: y })); if (local.x >= -playerShip.width / 2 && local.x <= playerShip.width / 2 && local.y >= -playerShip.height / 2 && local.y <= playerShip.height / 2) { dragNode = playerShip; } else { shootPlayerBullet(); } }; // Player shooting function shootPlayerBullet() { if (!playerShip.canShoot || gameOver) return; var bullet = new PlayerBullet(); bullet.x = playerShip.x; bullet.y = playerShip.y - playerShip.height / 2 - 20; playerBullets.push(bullet); game.addChild(bullet); playerShip.canShoot = false; playerShip.shootCooldown = PLAYER_SHOOT_COOLDOWN; LK.getSound('shoot').play(); } // Enemy shooting function shootEnemyBullet(enemy) { var bullet = new EnemyBullet(); bullet.x = enemy.x; bullet.y = enemy.y + enemy.height / 2 + 20; enemyBullets.push(bullet); game.addChild(bullet); LK.getSound('enemyShoot').play(); } // Enemy movement and dive logic function updateEnemies() { // Move formation if (enemyMoveTick <= 0) { // Find leftmost and rightmost alive enemy var minX = GAME_WIDTH, maxX = 0; for (var i = 0; i < enemies.length; i++) { var e = enemies[i]; if (!e.alive || e.isDiving) continue; if (e.x < minX) minX = e.x; if (e.x > maxX) maxX = e.x; } var moveEdge = false; if (enemyDirection === 1 && maxX + ENEMY_MOVE_STEP > GAME_WIDTH - 40) moveEdge = true; if (enemyDirection === -1 && minX - ENEMY_MOVE_STEP < 140) moveEdge = true; for (var i = 0; i < enemies.length; i++) { var e = enemies[i]; if (!e.alive || e.isDiving) continue; if (moveEdge) { e.y += ENEMY_MOVE_DOWN; } else { e.x += ENEMY_MOVE_STEP * enemyDirection; e.baseX = e.x; } } if (moveEdge) enemyDirection *= -1; enemyMoveTick = Math.max(ENEMY_MOVE_INTERVAL - wave * 2, 10); } else { enemyMoveTick--; } // Dive logic if (enemyDiveTick <= 0) { // Pick a random front-row enemy to dive var frontEnemies = []; for (var col = 0; col < ENEMY_COLS; col++) { for (var row = ENEMY_ROWS - 1; row >= 0; row--) { var idx = row * ENEMY_COLS + col; if (enemies[idx] && enemies[idx].alive && !enemies[idx].isDiving) { frontEnemies.push(enemies[idx]); break; } } } if (frontEnemies.length > 0) { var diveEnemy = frontEnemies[Math.floor(Math.random() * frontEnemies.length)]; if (diveEnemy && !diveEnemy.isDiving) { var targetX = playerShip.x + (Math.random() - 0.5) * 200; var targetY = playerShip.y - 100; diveEnemy.startDive(targetX, targetY, 32 + wave * 2); } } enemyDiveTick = Math.max(ENEMY_DIVE_INTERVAL - wave * 8, 40); } else { enemyDiveTick--; } // Enemy shooting for (var i = 0; i < enemies.length; i++) { var e = enemies[i]; if (!e.alive) continue; if (e.isDiving && e.bulletCooldown <= 0 && Math.random() < 0.18) { shootEnemyBullet(e); e.bulletCooldown = 32 + Math.floor(Math.random() * 32); } else if (!e.isDiving && e.bulletCooldown <= 0 && Math.random() < ENEMY_BULLET_CHANCE) { shootEnemyBullet(e); e.bulletCooldown = 64 + Math.floor(Math.random() * 32); } } } // Collision detection function checkCollision(a, b) { // Simple AABB return a.x - a.width / 2 < b.x + b.width / 2 && a.x + a.width / 2 > b.x - b.width / 2 && a.y - a.height / 2 < b.y + b.height / 2 && a.y + a.height / 2 > b.y - b.height / 2; } // Game update game.update = function () { if (gameOver) return; // Player update playerShip.update(); // Enemies update for (var i = 0; i < enemies.length; i++) { enemies[i].update(); } updateEnemies(); // Player bullets update for (var i = playerBullets.length - 1; i >= 0; i--) { var b = playerBullets[i]; b.update(); // Remove if off screen if (b.y < -80) { b.destroy(); playerBullets.splice(i, 1); continue; } // Check collision with enemies for (var j = 0; j < enemies.length; j++) { var e = enemies[j]; if (!e.alive) continue; if (checkCollision(b, e)) { // Enemy hit e.alive = false; e.visible = false; b.destroy(); playerBullets.splice(i, 1); LK.setScore(LK.getScore() + 10 * e.type); scoreTxt.setText(LK.getScore()); LK.getSound('explosion').play(); break; } } } // Enemy bullets update for (var i = enemyBullets.length - 1; i >= 0; i--) { var b = enemyBullets[i]; b.update(); if (b.y > GAME_HEIGHT + 80) { b.destroy(); enemyBullets.splice(i, 1); continue; } // Check collision with player if (checkCollision(b, playerShip)) { // Player hit b.destroy(); enemyBullets.splice(i, 1); playerDeath(); return; } } // Enemy dive collision with player for (var i = 0; i < enemies.length; i++) { var e = enemies[i]; if (!e.alive) continue; if (checkCollision(e, playerShip)) { playerDeath(); return; } } // Check win condition var anyAlive = false; for (var i = 0; i < enemies.length; i++) { if (enemies[i].alive) { anyAlive = true; break; } } if (!anyAlive) { // Next wave wave++; waveTxt.setText('Wave ' + wave); // Remove old enemies for (var i = 0; i < enemies.length; i++) { enemies[i].destroy(); } enemies = []; enemyMoveTick = 0; enemyDiveTick = 0; spawnEnemies(); } }; // Player death function playerDeath() { if (gameOver) return; gameOver = true; LK.effects.flashScreen(0xff0000, 1000); tween(playerShip, { alpha: 0 }, { duration: 600, easing: tween.cubicOut }); LK.setTimeout(function () { LK.showGameOver(); }, 900); } // Score LK.setScore(0); scoreTxt.setText(LK.getScore()); /* End of file */
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,448 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Enemy
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ // type: 1,2,3
+ self.type = 1;
+ self.row = 0;
+ self.col = 0;
+ self.isDiving = false;
+ self.diveTargetX = 0;
+ self.diveTargetY = 0;
+ self.diveStep = 0;
+ self.diveSpeed = 0;
+ self.baseX = 0;
+ self.baseY = 0;
+ self.direction = 1; // 1: right, -1: left
+ self.bulletCooldown = 0;
+ self.alive = true;
+ self.asset = null;
+ self.init = function (type) {
+ self.type = type;
+ var assetId = 'enemy' + type;
+ self.asset = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = self.asset.width;
+ self.height = self.asset.height;
+ };
+ self.startDive = function (targetX, targetY, speed) {
+ self.isDiving = true;
+ self.diveTargetX = targetX;
+ self.diveTargetY = targetY;
+ self.diveStep = 0;
+ self.diveSpeed = speed;
+ };
+ self.update = function () {
+ if (!self.alive) return;
+ if (self.isDiving) {
+ // Dive movement: curve towards player, then return
+ var dx = self.diveTargetX - self.x;
+ var dy = self.diveTargetY - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 40) {
+ // Dive finished, return to base
+ self.isDiving = false;
+ tween(self, {
+ x: self.baseX,
+ y: self.baseY
+ }, {
+ duration: 600,
+ easing: tween.cubicOut
+ });
+ } else {
+ var step = self.diveSpeed;
+ self.x += dx / dist * step;
+ self.y += dy / dist * step;
+ }
+ }
+ // Bullet cooldown
+ if (self.bulletCooldown > 0) self.bulletCooldown--;
+ };
+ return self;
+});
+// Enemy Bullet
+var EnemyBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bullet = self.attachAsset('enemyBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 22;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Player Bullet
+var PlayerBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bullet = self.attachAsset('playerBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -38;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+// Player Ship
+var PlayerShip = Container.expand(function () {
+ var self = Container.call(this);
+ var ship = self.attachAsset('playerShip', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = ship.width;
+ self.height = ship.height;
+ self.speed = 22;
+ self.canShoot = true;
+ self.shootCooldown = 0;
+ self.update = function () {
+ // Cooldown for shooting
+ if (self.shootCooldown > 0) {
+ self.shootCooldown--;
+ if (self.shootCooldown === 0) self.canShoot = true;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x000010
+});
+
+/****
+* Game Code
+****/
+// Sounds
+// Bullets
+// Enemy types
+// Spaceship (player)
+// Game constants
+var GAME_WIDTH = 2048;
+var GAME_HEIGHT = 2732;
+var ENEMY_ROWS = 5;
+var ENEMY_COLS = 8;
+var ENEMY_SPACING_X = 180;
+var ENEMY_SPACING_Y = 160;
+var ENEMY_START_Y = 320;
+var ENEMY_START_X = (GAME_WIDTH - (ENEMY_COLS - 1) * ENEMY_SPACING_X) / 2 + ENEMY_SPACING_X / 2;
+var ENEMY_MOVE_STEP = 32;
+var ENEMY_MOVE_DOWN = 60;
+var ENEMY_MOVE_INTERVAL = 32; // ticks
+var ENEMY_DIVE_INTERVAL = 120; // ticks
+var ENEMY_BULLET_CHANCE = 0.012; // per update per enemy
+var PLAYER_Y = GAME_HEIGHT - 220;
+var PLAYER_SHOOT_COOLDOWN = 18; // ticks
+// Game state
+var playerShip = null;
+var playerBullets = [];
+var enemyBullets = [];
+var enemies = [];
+var enemyDirection = 1; // 1: right, -1: left
+var enemyMoveTick = 0;
+var enemyDiveTick = 0;
+var dragNode = null;
+var scoreTxt = null;
+var lastIntersecting = false;
+var gameOver = false;
+var wave = 1;
+// Score display
+scoreTxt = new Text2('0', {
+ size: 120,
+ fill: "#fff"
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Wave display
+var waveTxt = new Text2('Wave 1', {
+ size: 80,
+ fill: "#fff"
+});
+waveTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(waveTxt);
+waveTxt.y = 120;
+// Initialize player
+playerShip = new PlayerShip();
+game.addChild(playerShip);
+playerShip.x = GAME_WIDTH / 2;
+playerShip.y = PLAYER_Y;
+// Initialize enemies
+function spawnEnemies() {
+ for (var row = 0; row < ENEMY_ROWS; row++) {
+ for (var col = 0; col < ENEMY_COLS; col++) {
+ var type = row === 0 ? 3 : row < 3 ? 2 : 1;
+ var enemy = new Enemy();
+ enemy.init(type);
+ enemy.row = row;
+ enemy.col = col;
+ enemy.baseX = ENEMY_START_X + col * ENEMY_SPACING_X;
+ enemy.baseY = ENEMY_START_Y + row * ENEMY_SPACING_Y;
+ enemy.x = enemy.baseX;
+ enemy.y = enemy.baseY;
+ enemy.direction = 1;
+ enemy.isDiving = false;
+ enemy.alive = true;
+ enemies.push(enemy);
+ game.addChild(enemy);
+ }
+ }
+}
+spawnEnemies();
+// Handle player movement (dragging)
+function handleMove(x, y, obj) {
+ if (gameOver) return;
+ if (dragNode === playerShip) {
+ // Clamp to game area, avoid left 100px for menu
+ var minX = Math.max(playerShip.width / 2 + 100, 100 + playerShip.width / 2);
+ var maxX = GAME_WIDTH - playerShip.width / 2;
+ var newX = Math.max(minX, Math.min(maxX, x));
+ playerShip.x = newX;
+ }
+}
+game.move = handleMove;
+game.down = function (x, y, obj) {
+ if (gameOver) return;
+ // Only allow drag if touch is on player ship
+ var local = playerShip.toLocal(game.toGlobal({
+ x: x,
+ y: y
+ }));
+ if (local.x >= -playerShip.width / 2 && local.x <= playerShip.width / 2 && local.y >= -playerShip.height / 2 && local.y <= playerShip.height / 2) {
+ dragNode = playerShip;
+ }
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+// Handle shooting (tap anywhere)
+game.tap = function (x, y, obj) {
+ if (gameOver) return;
+ shootPlayerBullet();
+};
+// For mobile, also allow shooting on down if not dragging
+game.down = function (x, y, obj) {
+ if (gameOver) return;
+ var local = playerShip.toLocal(game.toGlobal({
+ x: x,
+ y: y
+ }));
+ if (local.x >= -playerShip.width / 2 && local.x <= playerShip.width / 2 && local.y >= -playerShip.height / 2 && local.y <= playerShip.height / 2) {
+ dragNode = playerShip;
+ } else {
+ shootPlayerBullet();
+ }
+};
+// Player shooting
+function shootPlayerBullet() {
+ if (!playerShip.canShoot || gameOver) return;
+ var bullet = new PlayerBullet();
+ bullet.x = playerShip.x;
+ bullet.y = playerShip.y - playerShip.height / 2 - 20;
+ playerBullets.push(bullet);
+ game.addChild(bullet);
+ playerShip.canShoot = false;
+ playerShip.shootCooldown = PLAYER_SHOOT_COOLDOWN;
+ LK.getSound('shoot').play();
+}
+// Enemy shooting
+function shootEnemyBullet(enemy) {
+ var bullet = new EnemyBullet();
+ bullet.x = enemy.x;
+ bullet.y = enemy.y + enemy.height / 2 + 20;
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+ LK.getSound('enemyShoot').play();
+}
+// Enemy movement and dive logic
+function updateEnemies() {
+ // Move formation
+ if (enemyMoveTick <= 0) {
+ // Find leftmost and rightmost alive enemy
+ var minX = GAME_WIDTH,
+ maxX = 0;
+ for (var i = 0; i < enemies.length; i++) {
+ var e = enemies[i];
+ if (!e.alive || e.isDiving) continue;
+ if (e.x < minX) minX = e.x;
+ if (e.x > maxX) maxX = e.x;
+ }
+ var moveEdge = false;
+ if (enemyDirection === 1 && maxX + ENEMY_MOVE_STEP > GAME_WIDTH - 40) moveEdge = true;
+ if (enemyDirection === -1 && minX - ENEMY_MOVE_STEP < 140) moveEdge = true;
+ for (var i = 0; i < enemies.length; i++) {
+ var e = enemies[i];
+ if (!e.alive || e.isDiving) continue;
+ if (moveEdge) {
+ e.y += ENEMY_MOVE_DOWN;
+ } else {
+ e.x += ENEMY_MOVE_STEP * enemyDirection;
+ e.baseX = e.x;
+ }
+ }
+ if (moveEdge) enemyDirection *= -1;
+ enemyMoveTick = Math.max(ENEMY_MOVE_INTERVAL - wave * 2, 10);
+ } else {
+ enemyMoveTick--;
+ }
+ // Dive logic
+ if (enemyDiveTick <= 0) {
+ // Pick a random front-row enemy to dive
+ var frontEnemies = [];
+ for (var col = 0; col < ENEMY_COLS; col++) {
+ for (var row = ENEMY_ROWS - 1; row >= 0; row--) {
+ var idx = row * ENEMY_COLS + col;
+ if (enemies[idx] && enemies[idx].alive && !enemies[idx].isDiving) {
+ frontEnemies.push(enemies[idx]);
+ break;
+ }
+ }
+ }
+ if (frontEnemies.length > 0) {
+ var diveEnemy = frontEnemies[Math.floor(Math.random() * frontEnemies.length)];
+ if (diveEnemy && !diveEnemy.isDiving) {
+ var targetX = playerShip.x + (Math.random() - 0.5) * 200;
+ var targetY = playerShip.y - 100;
+ diveEnemy.startDive(targetX, targetY, 32 + wave * 2);
+ }
+ }
+ enemyDiveTick = Math.max(ENEMY_DIVE_INTERVAL - wave * 8, 40);
+ } else {
+ enemyDiveTick--;
+ }
+ // Enemy shooting
+ for (var i = 0; i < enemies.length; i++) {
+ var e = enemies[i];
+ if (!e.alive) continue;
+ if (e.isDiving && e.bulletCooldown <= 0 && Math.random() < 0.18) {
+ shootEnemyBullet(e);
+ e.bulletCooldown = 32 + Math.floor(Math.random() * 32);
+ } else if (!e.isDiving && e.bulletCooldown <= 0 && Math.random() < ENEMY_BULLET_CHANCE) {
+ shootEnemyBullet(e);
+ e.bulletCooldown = 64 + Math.floor(Math.random() * 32);
+ }
+ }
+}
+// Collision detection
+function checkCollision(a, b) {
+ // Simple AABB
+ return a.x - a.width / 2 < b.x + b.width / 2 && a.x + a.width / 2 > b.x - b.width / 2 && a.y - a.height / 2 < b.y + b.height / 2 && a.y + a.height / 2 > b.y - b.height / 2;
+}
+// Game update
+game.update = function () {
+ if (gameOver) return;
+ // Player update
+ playerShip.update();
+ // Enemies update
+ for (var i = 0; i < enemies.length; i++) {
+ enemies[i].update();
+ }
+ updateEnemies();
+ // Player bullets update
+ for (var i = playerBullets.length - 1; i >= 0; i--) {
+ var b = playerBullets[i];
+ b.update();
+ // Remove if off screen
+ if (b.y < -80) {
+ b.destroy();
+ playerBullets.splice(i, 1);
+ continue;
+ }
+ // Check collision with enemies
+ for (var j = 0; j < enemies.length; j++) {
+ var e = enemies[j];
+ if (!e.alive) continue;
+ if (checkCollision(b, e)) {
+ // Enemy hit
+ e.alive = false;
+ e.visible = false;
+ b.destroy();
+ playerBullets.splice(i, 1);
+ LK.setScore(LK.getScore() + 10 * e.type);
+ scoreTxt.setText(LK.getScore());
+ LK.getSound('explosion').play();
+ break;
+ }
+ }
+ }
+ // Enemy bullets update
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ var b = enemyBullets[i];
+ b.update();
+ if (b.y > GAME_HEIGHT + 80) {
+ b.destroy();
+ enemyBullets.splice(i, 1);
+ continue;
+ }
+ // Check collision with player
+ if (checkCollision(b, playerShip)) {
+ // Player hit
+ b.destroy();
+ enemyBullets.splice(i, 1);
+ playerDeath();
+ return;
+ }
+ }
+ // Enemy dive collision with player
+ for (var i = 0; i < enemies.length; i++) {
+ var e = enemies[i];
+ if (!e.alive) continue;
+ if (checkCollision(e, playerShip)) {
+ playerDeath();
+ return;
+ }
+ }
+ // Check win condition
+ var anyAlive = false;
+ for (var i = 0; i < enemies.length; i++) {
+ if (enemies[i].alive) {
+ anyAlive = true;
+ break;
+ }
+ }
+ if (!anyAlive) {
+ // Next wave
+ wave++;
+ waveTxt.setText('Wave ' + wave);
+ // Remove old enemies
+ for (var i = 0; i < enemies.length; i++) {
+ enemies[i].destroy();
+ }
+ enemies = [];
+ enemyMoveTick = 0;
+ enemyDiveTick = 0;
+ spawnEnemies();
+ }
+};
+// Player death
+function playerDeath() {
+ if (gameOver) return;
+ gameOver = true;
+ LK.effects.flashScreen(0xff0000, 1000);
+ tween(playerShip, {
+ alpha: 0
+ }, {
+ duration: 600,
+ easing: tween.cubicOut
+ });
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 900);
+}
+// Score
+LK.setScore(0);
+scoreTxt.setText(LK.getScore());
+/* End of file */
\ No newline at end of file