User prompt
Enemy types
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(graphics, 0.5, {' Line Number: 181 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'PowerUpManager is not a constructor' in or related to this line: 'powerUpManager = new PowerUpManager();' Line Number: 305
User prompt
Powerups
User prompt
The game is laggy
User prompt
Please fix the bug: 'ReferenceError: enemy is not defined' in or related to this line: 'if (minX < enemy.width / 2 && enemiesDirection === -1 || maxX > GAME_WIDTH - enemy.width / 2 && enemiesDirection === 1) {' Line Number: 301
Code edit (1 edits merged)
Please save this source code
User prompt
Cosmic Defenders
Initial prompt
Make space invaders
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.active = true;
self.width = enemyGraphics.width;
self.height = enemyGraphics.height;
self.points = 10;
self.shotChance = 0.005; // Chance per frame to shoot
self.update = function () {
// Enemy logic will be controlled by the formation
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8; // Positive because it moves downward
self.active = true;
self.width = bulletGraphics.width;
self.height = bulletGraphics.height;
self.update = function () {
self.y += self.speed;
// Destroy when off screen
if (self.y > 2732 + self.height) {
self.active = false;
}
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -15; // Negative because it moves upward
self.active = true;
self.width = bulletGraphics.width;
self.height = bulletGraphics.height;
self.update = function () {
self.y += self.speed;
// Destroy when off screen
if (self.y < -self.height) {
self.active = false;
}
};
return self;
});
var PlayerShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.width = shipGraphics.width;
self.height = shipGraphics.height;
self.fireRate = 15; // frames between shots
self.lastShot = 0;
self.alive = true;
self.moveLeft = function () {
self.x -= self.speed;
if (self.x < self.width / 2) {
self.x = self.width / 2;
}
};
self.moveRight = function () {
self.x += self.speed;
if (self.x > 2048 - self.width / 2) {
self.x = 2048 - self.width / 2;
}
};
self.canShoot = function () {
return self.lastShot <= 0;
};
self.resetShotTimer = function () {
self.lastShot = self.fireRate;
};
self.update = function () {
if (self.lastShot > 0) {
self.lastShot--;
}
};
return self;
});
var Shield = Container.expand(function () {
var self = Container.call(this);
var shieldGraphics = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.width = shieldGraphics.width;
self.height = shieldGraphics.height;
self.damage = function () {
self.health--;
shieldGraphics.alpha = self.health / 3;
if (self.health <= 0) {
self.active = false;
self.visible = false;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var PLAYER_START_Y = GAME_HEIGHT - 200;
var SHIELD_Y = PLAYER_START_Y - 150;
var ENEMY_START_Y = 300;
var ENEMY_ROWS = 5;
var ENEMY_COLS = 10;
var ENEMY_PADDING = 20;
var ENEMIES_MOVE_DOWN_AMOUNT = 30;
var WAVE_SPEED_INCREASE = 0.2;
// Game state
var player;
var playerBullets = [];
var enemies = [];
var enemyBullets = [];
var shields = [];
var score = 0;
var lives = 3;
var wave = 1;
var enemiesDirection = 1; // 1 = right, -1 = left
var enemiesSpeed = 1;
var enemyMoveTimer = 0;
var enemyMoveInterval = 30; // Frames between enemy movement
var gameState = "playing"; // playing, gameover
var dragActive = false;
var dragStartX = 0;
// UI elements
var scoreTxt;
var livesTxt;
var waveTxt;
// Initialize player
player = new PlayerShip();
player.x = GAME_WIDTH / 2;
player.y = PLAYER_START_Y;
game.addChild(player);
// Initialize shields
for (var i = 0; i < 3; i++) {
var shield = new Shield();
shield.x = GAME_WIDTH / 4 + GAME_WIDTH / 2 * (i / 2);
shield.y = SHIELD_Y;
shield.active = true;
shields.push(shield);
game.addChild(shield);
}
// Create UI
scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
scoreTxt.x = 20;
scoreTxt.y = 20;
LK.gui.addChild(scoreTxt);
livesTxt = new Text2('Lives: 3', {
size: 60,
fill: 0xFFFFFF
});
livesTxt.anchor.set(1, 0);
livesTxt.x = GAME_WIDTH - 20;
livesTxt.y = 20;
LK.gui.addChild(livesTxt);
waveTxt = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveTxt.anchor.set(0.5, 0);
waveTxt.x = GAME_WIDTH / 2;
waveTxt.y = 20;
LK.gui.addChild(waveTxt);
// Create enemies
function createEnemies() {
// Calculate total width of enemy formation
var enemyWidth = new Enemy().width;
var formationWidth = ENEMY_COLS * (enemyWidth + ENEMY_PADDING) - ENEMY_PADDING;
var startX = (GAME_WIDTH - formationWidth) / 2 + enemyWidth / 2;
for (var row = 0; row < ENEMY_ROWS; row++) {
for (var col = 0; col < ENEMY_COLS; col++) {
var enemy = new Enemy();
enemy.x = startX + col * (enemy.width + ENEMY_PADDING);
enemy.y = ENEMY_START_Y + row * (enemy.height + ENEMY_PADDING);
enemy.row = row;
enemy.col = col;
enemy.points = (ENEMY_ROWS - row) * 10; // Higher rows worth more points
// Different enemy colors based on row
if (row === 0) {
enemy.children[0].tint = 0xff0000; // Top row red
} else if (row === 1 || row === 2) {
enemy.children[0].tint = 0xff6600; // Middle rows orange
}
enemies.push(enemy);
game.addChild(enemy);
}
}
}
createEnemies();
// Play background music
LK.playMusic('bgMusic', {
loop: true
});
// Game control event handlers
game.down = function (x, y, obj) {
dragActive = true;
dragStartX = x;
};
game.up = function (x, y, obj) {
dragActive = false;
};
game.move = function (x, y, obj) {
if (dragActive && gameState === "playing") {
// Move player based on drag
var deltaX = x - dragStartX;
if (Math.abs(deltaX) > 5) {
// Threshold to prevent jitter
if (deltaX > 0) {
player.moveRight();
} else {
player.moveLeft();
}
dragStartX = x;
}
}
};
// Create player bullet
function shootPlayerBullet() {
if (player.canShoot() && gameState === "playing") {
var bullet = new PlayerBullet();
bullet.x = player.x;
bullet.y = player.y - player.height / 2;
playerBullets.push(bullet);
game.addChild(bullet);
player.resetShotTimer();
// Play shoot sound
LK.getSound('playerShoot').play();
}
}
// Create enemy bullet
function shootEnemyBullet(enemy) {
var bullet = new EnemyBullet();
bullet.x = enemy.x;
bullet.y = enemy.y + enemy.height / 2;
enemyBullets.push(bullet);
game.addChild(bullet);
}
// Check if formation needs to move down and change direction
function checkFormationBounds() {
var moveDown = false;
var minX = GAME_WIDTH;
var maxX = 0;
enemies.forEach(function (enemy) {
if (enemy.x < minX) minX = enemy.x;
if (enemy.x > maxX) maxX = enemy.x;
});
if (minX < enemy.width / 2 && enemiesDirection === -1 || maxX > GAME_WIDTH - enemy.width / 2 && enemiesDirection === 1) {
moveDown = true;
enemiesDirection *= -1;
}
return moveDown;
}
// Move enemy formation
function moveEnemies() {
var moveDown = checkFormationBounds();
enemies.forEach(function (enemy) {
if (moveDown) {
enemy.y += ENEMIES_MOVE_DOWN_AMOUNT;
}
enemy.x += enemiesDirection * enemiesSpeed;
});
}
// Check for collisions
function checkCollisions() {
// Player bullets vs enemies
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
// Check if bullet hits any enemy
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.active && bullet.intersects(enemy)) {
// Enemy hit
score += enemy.points;
scoreTxt.setText("Score: " + score);
// Remove enemy
game.removeChild(enemy);
enemies.splice(j, 1);
// Remove bullet
bullet.active = false;
game.removeChild(bullet);
playerBullets.splice(i, 1);
// Play explosion sound
LK.getSound('enemyExplode').play();
// Flash screen effect
LK.effects.flashObject(enemy, 0xffffff, 300);
break; // Bullet can only hit one enemy
}
}
// Check if bullet hits any shield
if (bullet.active) {
for (var k = shields.length - 1; k >= 0; k--) {
var shield = shields[k];
if (shield.active && bullet.intersects(shield)) {
// Shield hit by player bullet
shield.damage();
// Remove bullet
bullet.active = false;
game.removeChild(bullet);
playerBullets.splice(i, 1);
if (!shield.active) {
game.removeChild(shield);
shields.splice(k, 1);
}
break;
}
}
}
}
// Enemy bullets vs player and shields
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
// Check player collision
if (bullet.active && bullet.intersects(player) && gameState === "playing") {
// Player hit
lives--;
livesTxt.setText("Lives: " + lives);
// Remove bullet
bullet.active = false;
game.removeChild(bullet);
enemyBullets.splice(i, 1);
// Play hit sound
LK.getSound('playerHit').play();
// Flash player effect
LK.effects.flashObject(player, 0xff0000, 500);
if (lives <= 0) {
gameState = "gameover";
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
continue;
}
// Check shield collision
for (var k = shields.length - 1; k >= 0; k--) {
var shield = shields[k];
if (shield.active && bullet.active && bullet.intersects(shield)) {
// Shield hit by enemy bullet
shield.damage();
// Remove bullet
bullet.active = false;
game.removeChild(bullet);
enemyBullets.splice(i, 1);
if (!shield.active) {
game.removeChild(shield);
shields.splice(k, 1);
}
break;
}
}
}
// Enemies vs bottom of screen
for (var i = 0; i < enemies.length; i++) {
if (enemies[i].y + enemies[i].height / 2 > player.y) {
// Enemies reached player level - game over
gameState = "gameover";
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
break;
}
}
}
// Start next wave
function startNextWave() {
wave++;
waveTxt.setText("Wave: " + wave);
// Increase enemy speed with each wave
enemiesSpeed += WAVE_SPEED_INCREASE;
// Clear any remaining enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
game.removeChild(enemyBullets[i]);
}
enemyBullets = [];
// Create new enemy formation
createEnemies();
}
// Clean up inactive objects
function cleanupInactiveObjects() {
// Clean up player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
if (!playerBullets[i].active) {
game.removeChild(playerBullets[i]);
playerBullets.splice(i, 1);
}
}
// Clean up enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (!enemyBullets[i].active) {
game.removeChild(enemyBullets[i]);
enemyBullets.splice(i, 1);
}
}
}
// Main game update loop
game.update = function () {
if (gameState === "playing") {
// Update player
player.update();
// Auto shoot
if (LK.ticks % 30 === 0) {
shootPlayerBullet();
}
// Move enemies
enemyMoveTimer++;
if (enemyMoveTimer >= enemyMoveInterval) {
moveEnemies();
enemyMoveTimer = 0;
}
// Enemy shooting
if (enemies.length > 0 && LK.ticks % 5 === 0) {
// Find all enemies in the bottom row of each column
var bottomEnemies = [];
var columnsWithEnemies = {};
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var column = enemy.col;
if (!columnsWithEnemies[column] || enemies[columnsWithEnemies[column]].row < enemy.row) {
columnsWithEnemies[column] = i;
}
}
// Get bottom enemies
for (var col in columnsWithEnemies) {
bottomEnemies.push(enemies[columnsWithEnemies[col]]);
}
// Random chance for enemies to shoot
if (bottomEnemies.length > 0) {
for (var i = 0; i < bottomEnemies.length; i++) {
if (Math.random() < bottomEnemies[i].shotChance) {
shootEnemyBullet(bottomEnemies[i]);
}
}
}
}
// Update bullets
for (var i = 0; i < playerBullets.length; i++) {
playerBullets[i].update();
}
for (var i = 0; i < enemyBullets.length; i++) {
enemyBullets[i].update();
}
// Check collisions
checkCollisions();
// Clean up inactive objects
cleanupInactiveObjects();
// Check if wave cleared
if (enemies.length === 0) {
startNextWave();
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,485 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ var enemyGraphics = self.attachAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.active = true;
+ self.width = enemyGraphics.width;
+ self.height = enemyGraphics.height;
+ self.points = 10;
+ self.shotChance = 0.005; // Chance per frame to shoot
+ self.update = function () {
+ // Enemy logic will be controlled by the formation
+ };
+ return self;
+});
+var EnemyBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphics = self.attachAsset('enemyBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 8; // Positive because it moves downward
+ self.active = true;
+ self.width = bulletGraphics.width;
+ self.height = bulletGraphics.height;
+ self.update = function () {
+ self.y += self.speed;
+ // Destroy when off screen
+ if (self.y > 2732 + self.height) {
+ self.active = false;
+ }
+ };
+ return self;
+});
+var PlayerBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphics = self.attachAsset('playerBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -15; // Negative because it moves upward
+ self.active = true;
+ self.width = bulletGraphics.width;
+ self.height = bulletGraphics.height;
+ self.update = function () {
+ self.y += self.speed;
+ // Destroy when off screen
+ if (self.y < -self.height) {
+ self.active = false;
+ }
+ };
+ return self;
+});
+var PlayerShip = Container.expand(function () {
+ var self = Container.call(this);
+ var shipGraphics = self.attachAsset('playerShip', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 12;
+ self.width = shipGraphics.width;
+ self.height = shipGraphics.height;
+ self.fireRate = 15; // frames between shots
+ self.lastShot = 0;
+ self.alive = true;
+ self.moveLeft = function () {
+ self.x -= self.speed;
+ if (self.x < self.width / 2) {
+ self.x = self.width / 2;
+ }
+ };
+ self.moveRight = function () {
+ self.x += self.speed;
+ if (self.x > 2048 - self.width / 2) {
+ self.x = 2048 - self.width / 2;
+ }
+ };
+ self.canShoot = function () {
+ return self.lastShot <= 0;
+ };
+ self.resetShotTimer = function () {
+ self.lastShot = self.fireRate;
+ };
+ self.update = function () {
+ if (self.lastShot > 0) {
+ self.lastShot--;
+ }
+ };
+ return self;
+});
+var Shield = Container.expand(function () {
+ var self = Container.call(this);
+ var shieldGraphics = self.attachAsset('shield', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.health = 3;
+ self.width = shieldGraphics.width;
+ self.height = shieldGraphics.height;
+ self.damage = function () {
+ self.health--;
+ shieldGraphics.alpha = self.health / 3;
+ if (self.health <= 0) {
+ self.active = false;
+ self.visible = false;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x000022
+});
+
+/****
+* Game Code
+****/
+// Game constants
+var GAME_WIDTH = 2048;
+var GAME_HEIGHT = 2732;
+var PLAYER_START_Y = GAME_HEIGHT - 200;
+var SHIELD_Y = PLAYER_START_Y - 150;
+var ENEMY_START_Y = 300;
+var ENEMY_ROWS = 5;
+var ENEMY_COLS = 10;
+var ENEMY_PADDING = 20;
+var ENEMIES_MOVE_DOWN_AMOUNT = 30;
+var WAVE_SPEED_INCREASE = 0.2;
+// Game state
+var player;
+var playerBullets = [];
+var enemies = [];
+var enemyBullets = [];
+var shields = [];
+var score = 0;
+var lives = 3;
+var wave = 1;
+var enemiesDirection = 1; // 1 = right, -1 = left
+var enemiesSpeed = 1;
+var enemyMoveTimer = 0;
+var enemyMoveInterval = 30; // Frames between enemy movement
+var gameState = "playing"; // playing, gameover
+var dragActive = false;
+var dragStartX = 0;
+// UI elements
+var scoreTxt;
+var livesTxt;
+var waveTxt;
+// Initialize player
+player = new PlayerShip();
+player.x = GAME_WIDTH / 2;
+player.y = PLAYER_START_Y;
+game.addChild(player);
+// Initialize shields
+for (var i = 0; i < 3; i++) {
+ var shield = new Shield();
+ shield.x = GAME_WIDTH / 4 + GAME_WIDTH / 2 * (i / 2);
+ shield.y = SHIELD_Y;
+ shield.active = true;
+ shields.push(shield);
+ game.addChild(shield);
+}
+// Create UI
+scoreTxt = new Text2('Score: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0, 0);
+scoreTxt.x = 20;
+scoreTxt.y = 20;
+LK.gui.addChild(scoreTxt);
+livesTxt = new Text2('Lives: 3', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+livesTxt.anchor.set(1, 0);
+livesTxt.x = GAME_WIDTH - 20;
+livesTxt.y = 20;
+LK.gui.addChild(livesTxt);
+waveTxt = new Text2('Wave: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+waveTxt.anchor.set(0.5, 0);
+waveTxt.x = GAME_WIDTH / 2;
+waveTxt.y = 20;
+LK.gui.addChild(waveTxt);
+// Create enemies
+function createEnemies() {
+ // Calculate total width of enemy formation
+ var enemyWidth = new Enemy().width;
+ var formationWidth = ENEMY_COLS * (enemyWidth + ENEMY_PADDING) - ENEMY_PADDING;
+ var startX = (GAME_WIDTH - formationWidth) / 2 + enemyWidth / 2;
+ for (var row = 0; row < ENEMY_ROWS; row++) {
+ for (var col = 0; col < ENEMY_COLS; col++) {
+ var enemy = new Enemy();
+ enemy.x = startX + col * (enemy.width + ENEMY_PADDING);
+ enemy.y = ENEMY_START_Y + row * (enemy.height + ENEMY_PADDING);
+ enemy.row = row;
+ enemy.col = col;
+ enemy.points = (ENEMY_ROWS - row) * 10; // Higher rows worth more points
+ // Different enemy colors based on row
+ if (row === 0) {
+ enemy.children[0].tint = 0xff0000; // Top row red
+ } else if (row === 1 || row === 2) {
+ enemy.children[0].tint = 0xff6600; // Middle rows orange
+ }
+ enemies.push(enemy);
+ game.addChild(enemy);
+ }
+ }
+}
+createEnemies();
+// Play background music
+LK.playMusic('bgMusic', {
+ loop: true
+});
+// Game control event handlers
+game.down = function (x, y, obj) {
+ dragActive = true;
+ dragStartX = x;
+};
+game.up = function (x, y, obj) {
+ dragActive = false;
+};
+game.move = function (x, y, obj) {
+ if (dragActive && gameState === "playing") {
+ // Move player based on drag
+ var deltaX = x - dragStartX;
+ if (Math.abs(deltaX) > 5) {
+ // Threshold to prevent jitter
+ if (deltaX > 0) {
+ player.moveRight();
+ } else {
+ player.moveLeft();
+ }
+ dragStartX = x;
+ }
+ }
+};
+// Create player bullet
+function shootPlayerBullet() {
+ if (player.canShoot() && gameState === "playing") {
+ var bullet = new PlayerBullet();
+ bullet.x = player.x;
+ bullet.y = player.y - player.height / 2;
+ playerBullets.push(bullet);
+ game.addChild(bullet);
+ player.resetShotTimer();
+ // Play shoot sound
+ LK.getSound('playerShoot').play();
+ }
+}
+// Create enemy bullet
+function shootEnemyBullet(enemy) {
+ var bullet = new EnemyBullet();
+ bullet.x = enemy.x;
+ bullet.y = enemy.y + enemy.height / 2;
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+}
+// Check if formation needs to move down and change direction
+function checkFormationBounds() {
+ var moveDown = false;
+ var minX = GAME_WIDTH;
+ var maxX = 0;
+ enemies.forEach(function (enemy) {
+ if (enemy.x < minX) minX = enemy.x;
+ if (enemy.x > maxX) maxX = enemy.x;
+ });
+ if (minX < enemy.width / 2 && enemiesDirection === -1 || maxX > GAME_WIDTH - enemy.width / 2 && enemiesDirection === 1) {
+ moveDown = true;
+ enemiesDirection *= -1;
+ }
+ return moveDown;
+}
+// Move enemy formation
+function moveEnemies() {
+ var moveDown = checkFormationBounds();
+ enemies.forEach(function (enemy) {
+ if (moveDown) {
+ enemy.y += ENEMIES_MOVE_DOWN_AMOUNT;
+ }
+ enemy.x += enemiesDirection * enemiesSpeed;
+ });
+}
+// Check for collisions
+function checkCollisions() {
+ // Player bullets vs enemies
+ for (var i = playerBullets.length - 1; i >= 0; i--) {
+ var bullet = playerBullets[i];
+ // Check if bullet hits any enemy
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ var enemy = enemies[j];
+ if (bullet.active && bullet.intersects(enemy)) {
+ // Enemy hit
+ score += enemy.points;
+ scoreTxt.setText("Score: " + score);
+ // Remove enemy
+ game.removeChild(enemy);
+ enemies.splice(j, 1);
+ // Remove bullet
+ bullet.active = false;
+ game.removeChild(bullet);
+ playerBullets.splice(i, 1);
+ // Play explosion sound
+ LK.getSound('enemyExplode').play();
+ // Flash screen effect
+ LK.effects.flashObject(enemy, 0xffffff, 300);
+ break; // Bullet can only hit one enemy
+ }
+ }
+ // Check if bullet hits any shield
+ if (bullet.active) {
+ for (var k = shields.length - 1; k >= 0; k--) {
+ var shield = shields[k];
+ if (shield.active && bullet.intersects(shield)) {
+ // Shield hit by player bullet
+ shield.damage();
+ // Remove bullet
+ bullet.active = false;
+ game.removeChild(bullet);
+ playerBullets.splice(i, 1);
+ if (!shield.active) {
+ game.removeChild(shield);
+ shields.splice(k, 1);
+ }
+ break;
+ }
+ }
+ }
+ }
+ // Enemy bullets vs player and shields
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ var bullet = enemyBullets[i];
+ // Check player collision
+ if (bullet.active && bullet.intersects(player) && gameState === "playing") {
+ // Player hit
+ lives--;
+ livesTxt.setText("Lives: " + lives);
+ // Remove bullet
+ bullet.active = false;
+ game.removeChild(bullet);
+ enemyBullets.splice(i, 1);
+ // Play hit sound
+ LK.getSound('playerHit').play();
+ // Flash player effect
+ LK.effects.flashObject(player, 0xff0000, 500);
+ if (lives <= 0) {
+ gameState = "gameover";
+ LK.effects.flashScreen(0xff0000, 1000);
+ LK.showGameOver();
+ }
+ continue;
+ }
+ // Check shield collision
+ for (var k = shields.length - 1; k >= 0; k--) {
+ var shield = shields[k];
+ if (shield.active && bullet.active && bullet.intersects(shield)) {
+ // Shield hit by enemy bullet
+ shield.damage();
+ // Remove bullet
+ bullet.active = false;
+ game.removeChild(bullet);
+ enemyBullets.splice(i, 1);
+ if (!shield.active) {
+ game.removeChild(shield);
+ shields.splice(k, 1);
+ }
+ break;
+ }
+ }
+ }
+ // Enemies vs bottom of screen
+ for (var i = 0; i < enemies.length; i++) {
+ if (enemies[i].y + enemies[i].height / 2 > player.y) {
+ // Enemies reached player level - game over
+ gameState = "gameover";
+ LK.effects.flashScreen(0xff0000, 1000);
+ LK.showGameOver();
+ break;
+ }
+ }
+}
+// Start next wave
+function startNextWave() {
+ wave++;
+ waveTxt.setText("Wave: " + wave);
+ // Increase enemy speed with each wave
+ enemiesSpeed += WAVE_SPEED_INCREASE;
+ // Clear any remaining enemy bullets
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ game.removeChild(enemyBullets[i]);
+ }
+ enemyBullets = [];
+ // Create new enemy formation
+ createEnemies();
+}
+// Clean up inactive objects
+function cleanupInactiveObjects() {
+ // Clean up player bullets
+ for (var i = playerBullets.length - 1; i >= 0; i--) {
+ if (!playerBullets[i].active) {
+ game.removeChild(playerBullets[i]);
+ playerBullets.splice(i, 1);
+ }
+ }
+ // Clean up enemy bullets
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ if (!enemyBullets[i].active) {
+ game.removeChild(enemyBullets[i]);
+ enemyBullets.splice(i, 1);
+ }
+ }
+}
+// Main game update loop
+game.update = function () {
+ if (gameState === "playing") {
+ // Update player
+ player.update();
+ // Auto shoot
+ if (LK.ticks % 30 === 0) {
+ shootPlayerBullet();
+ }
+ // Move enemies
+ enemyMoveTimer++;
+ if (enemyMoveTimer >= enemyMoveInterval) {
+ moveEnemies();
+ enemyMoveTimer = 0;
+ }
+ // Enemy shooting
+ if (enemies.length > 0 && LK.ticks % 5 === 0) {
+ // Find all enemies in the bottom row of each column
+ var bottomEnemies = [];
+ var columnsWithEnemies = {};
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ var column = enemy.col;
+ if (!columnsWithEnemies[column] || enemies[columnsWithEnemies[column]].row < enemy.row) {
+ columnsWithEnemies[column] = i;
+ }
+ }
+ // Get bottom enemies
+ for (var col in columnsWithEnemies) {
+ bottomEnemies.push(enemies[columnsWithEnemies[col]]);
+ }
+ // Random chance for enemies to shoot
+ if (bottomEnemies.length > 0) {
+ for (var i = 0; i < bottomEnemies.length; i++) {
+ if (Math.random() < bottomEnemies[i].shotChance) {
+ shootEnemyBullet(bottomEnemies[i]);
+ }
+ }
+ }
+ }
+ // Update bullets
+ for (var i = 0; i < playerBullets.length; i++) {
+ playerBullets[i].update();
+ }
+ for (var i = 0; i < enemyBullets.length; i++) {
+ enemyBullets[i].update();
+ }
+ // Check collisions
+ checkCollisions();
+ // Clean up inactive objects
+ cleanupInactiveObjects();
+ // Check if wave cleared
+ if (enemies.length === 0) {
+ startNextWave();
+ }
+ }
+};
\ No newline at end of file
Top down 2d pixilated spaceship. In-Game asset. 2d. High contrast. No shadows
Enemy spaceship top down 2d pixilated and looking downwards. In-Game asset. 2d. High contrast. No shadows
Bullet 2d top down pixilated. In-Game asset. 2d. High contrast. No shadows
Bullet facing down and top Down 2d pixilated. In-Game asset. 2d. High contrast. No shadows
Sheid top down 2d pixilated. In-Game asset. 2d. High contrast. No shadows