User prompt
Please fix the bug: 'ReferenceError: Crystal is not defined' in or related to this line: 'var crystal = new Crystal();' Line Number: 317
User prompt
Please fix the bug: 'ReferenceError: Laser is not defined' in or related to this line: 'var laser = new Laser();' Line Number: 437
User prompt
Please fix the bug: 'ReferenceError: Alien is not defined' in or related to this line: 'var alien = new Alien();' Line Number: 425
User prompt
Please fix the bug: 'Player is not defined' in or related to this line: 'player = new Player();' Line Number: 112
User prompt
her dalga sonrası büyük bir boss gelsin
User prompt
enemies come from top to bottom and after each wave there will be 5 more enemies for the next wave
User prompt
Let the boxes falling from the enemy come towards us
User prompt
Let there be 3 roads in front of us and these enemies will come at us randomly from these roads.
User prompt
Sets the enemies to come from the opposite side of the character
Code edit (1 edits merged)
Please save this source code
User prompt
Crystal Defense: Alien Waves
Initial prompt
You are a man You can move left and right on the screen. You move with your finger or A/D keys. Aliens are coming Aliens are walking in waves from the right of the screen. They are trying to reach you. You fire automatically When the enemy approaches, your character shoots lasers at himself. Just get in a good position. When you shoot the enemies, the crystal falls You cannot pass over them. You can increase the limits with the crystal once. A new wave starts every 10 enemies The characteristics of the waves, the enemies are faster, stronger. A bonus box drops every 3 waves Go to the box → opens → gives you a random power. Objective: Stay alive as long as you can! The more waves you pass, the better.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Alien class var Alien = Container.expand(function () { var self = Container.call(this); var alienSprite = self.attachAsset('alien', { anchorX: 0.5, anchorY: 0.5 }); self.width = alienSprite.width; self.height = alienSprite.height; self.speed = 2.5; self.hp = 1; self.wave = 1; self.lastX = self.x; self.lastY = self.y; self.lastIntersecting = false; self.isDead = false; self.update = function () { self.x -= self.speed; }; return self; }); // Bonus box class var BonusBox = Container.expand(function () { var self = Container.call(this); var bonusSprite = self.attachAsset('bonus', { anchorX: 0.5, anchorY: 0.5 }); self.width = bonusSprite.width; self.height = bonusSprite.height; self.lastY = self.y; self.lastIntersecting = false; self.type = null; // Set on spawn return self; }); // Crystal class var Crystal = Container.expand(function () { var self = Container.call(this); var crystalSprite = self.attachAsset('crystal', { anchorX: 0.5, anchorY: 0.5 }); self.width = crystalSprite.width; self.height = crystalSprite.height; self.lastY = self.y; self.lastIntersecting = false; return self; }); // Laser class var Laser = Container.expand(function () { var self = Container.call(this); var laserSprite = self.attachAsset('laser', { anchorX: 0.5, anchorY: 1 }); self.width = laserSprite.width; self.height = laserSprite.height; self.speed = 32; self.pierce = false; self.lastY = self.y; self.lastIntersecting = false; self.update = function () { self.y -= self.speed; }; return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); var playerSprite = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.width = playerSprite.width; self.height = playerSprite.height; self.shootCooldown = 0; self.moveSpeed = 32; // px per tick when dragged self.leftLimit = 0 + self.width / 2 + 40; self.rightLimit = 2048 - self.width / 2 - 40; self.powered = false; self.powerTimer = 0; self.powerType = null; // For powerup visuals self.setPower = function (type, duration) { self.powered = true; self.powerType = type; self.powerTimer = duration; if (type === 'rapid') { playerSprite.tint = 0xffe100; } else if (type === 'pierce') { playerSprite.tint = 0x00ffb0; } else if (type === 'shield') { playerSprite.tint = 0x00eaff; } }; self.clearPower = function () { self.powered = false; self.powerType = null; self.powerTimer = 0; playerSprite.tint = 0xffffff; }; self.update = function () { if (self.powered) { self.powerTimer--; if (self.powerTimer <= 0) { self.clearPower(); } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0a0a1a }); /**** * Game Code ****/ // Music // Sound effects // Bonus box // Crystal (collectible) // Player bullet (laser) // Alien (enemy) // Player // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var GROUND_Y = GAME_HEIGHT - 220; var PLAYER_START_X = GAME_WIDTH / 2; var PLAYER_START_Y = GROUND_Y; var PLAYER_MIN_X = 160 + 40; var PLAYER_MAX_X = GAME_WIDTH - 160 - 40; var ENEMY_START_Y_MIN = 220; var ENEMY_START_Y_MAX = GROUND_Y - 200; var ENEMY_START_X = GAME_WIDTH + 120; var LASER_COOLDOWN = 18; // ticks var LASER_COOLDOWN_RAPID = 6; var CRYSTAL_COLLECT_DIST = 120; var BONUS_COLLECT_DIST = 120; var CRYSTAL_MOVE_STEP = 180; // How much movement area expands per crystal var MAX_CRYSTALS = 8; var WAVE_ENEMY_BASE = 10; var WAVE_ENEMY_INC = 4; var WAVE_SPEED_INC = 0.4; var WAVE_HP_INC = 1; var BONUS_WAVE_INTERVAL = 3; var POWERUP_DURATION = 360; // 6 seconds at 60fps // Game state var player = null; var aliens = []; var lasers = []; var crystals = []; var bonuses = []; var dragNode = null; var dragOffsetX = 0; var dragOffsetY = 0; var lastMoveX = 0; var lastMoveY = 0; var lastAlienSpawnTick = 0; var wave = 1; var enemiesLeft = 0; var enemiesToSpawn = 0; var enemiesKilled = 0; var crystalsCollected = 0; var leftLimit = PLAYER_MIN_X; var rightLimit = PLAYER_MAX_X; var bonusActive = false; var bonusType = null; var score = 0; var scoreTxt = null; var waveTxt = null; var powerupTxt = null; var gameOver = false; var youWin = false; // GUI scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); waveTxt = new Text2('Wave 1', { size: 80, fill: 0xAAFFFF }); waveTxt.anchor.set(0.5, 0); LK.gui.top.addChild(waveTxt); waveTxt.y = 120; powerupTxt = new Text2('', { size: 70, fill: 0xFFE100 }); powerupTxt.anchor.set(0.5, 0); LK.gui.top.addChild(powerupTxt); powerupTxt.y = 220; // Start music LK.playMusic('bgmusic'); // Spawn player player = new Player(); player.x = PLAYER_START_X; player.y = PLAYER_START_Y; game.addChild(player); // Set initial movement limits leftLimit = player.leftLimit; rightLimit = player.rightLimit; // Start first wave function startWave(waveNum) { wave = waveNum; waveTxt.setText('Wave ' + wave); enemiesToSpawn = WAVE_ENEMY_BASE + (wave - 1) * WAVE_ENEMY_INC; enemiesLeft = enemiesToSpawn; lastAlienSpawnTick = LK.ticks; } startWave(1); // Utility: clamp function clamp(val, min, max) { if (val < min) return min; if (val > max) return max; return val; } // Utility: random int function randInt(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); } // Utility: random powerup function randomPowerup() { var arr = ['rapid', 'pierce', 'shield']; return arr[randInt(0, arr.length - 1)]; } // Handle movement (dragging) function handleMove(x, y, obj) { if (dragNode === player) { // Clamp to current movement limits var newX = clamp(x, leftLimit, rightLimit); player.x = newX; lastMoveX = newX; lastMoveY = player.y; } } game.move = handleMove; game.down = function (x, y, obj) { // Only allow drag if touch/click is on player or below if (y > GROUND_Y - 200) { dragNode = player; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; // Main game update game.update = function () { if (gameOver || youWin) return; // Player update (powerup timer) player.update(); // Aliens update for (var i = aliens.length - 1; i >= 0; i--) { var alien = aliens[i]; alien.update(); // Check if alien reached left edge (player dies) if (alien.x < 0 - alien.width / 2) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); gameOver = true; return; } // Check collision with player (if shielded, destroy alien) if (player.powered && player.powerType === 'shield' && alien.intersects(player)) { LK.getSound('alien_die').play(); LK.effects.flashObject(alien, 0x00eaff, 400); alien.isDead = true; aliens.splice(i, 1); alien.destroy(); continue; } } // Lasers update for (var i = lasers.length - 1; i >= 0; i--) { var laser = lasers[i]; laser.update(); // Remove if off screen if (laser.y < -100) { lasers.splice(i, 1); laser.destroy(); continue; } // Check collision with aliens var hit = false; for (var j = aliens.length - 1; j >= 0; j--) { var alien = aliens[j]; if (!alien.isDead && laser.intersects(alien)) { alien.hp -= player.powered && player.powerType === 'pierce' ? 2 : 1; if (alien.hp <= 0) { // Alien dies LK.getSound('alien_die').play(); LK.effects.flashObject(alien, 0xff0000, 400); alien.isDead = true; // Drop crystal var crystal = new Crystal(); crystal.x = alien.x; crystal.y = alien.y; crystals.push(crystal); game.addChild(crystal); // Remove alien aliens.splice(j, 1); alien.destroy(); enemiesLeft--; enemiesKilled++; score += 10; scoreTxt.setText(score); // New wave? if (enemiesLeft <= 0) { // Bonus box every BONUS_WAVE_INTERVAL if (wave % BONUS_WAVE_INTERVAL === 0) { var bonus = new BonusBox(); bonus.x = randInt(leftLimit + 100, rightLimit - 100); bonus.y = randInt(ENEMY_START_Y_MIN + 100, ENEMY_START_Y_MAX - 100); bonus.type = randomPowerup(); bonuses.push(bonus); game.addChild(bonus); } startWave(wave + 1); } } hit = true; if (!(player.powered && player.powerType === 'pierce')) break; } } if (hit && !(player.powered && player.powerType === 'pierce')) { lasers.splice(i, 1); laser.destroy(); } } // Crystals update for (var i = crystals.length - 1; i >= 0; i--) { var crystal = crystals[i]; // If player close enough, collect var dx = player.x - crystal.x; var dy = player.y - crystal.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < CRYSTAL_COLLECT_DIST) { LK.getSound('crystal_get').play(); LK.effects.flashObject(crystal, 0x00eaff, 400); crystals.splice(i, 1); crystal.destroy(); // Expand movement area if (crystalsCollected < MAX_CRYSTALS) { leftLimit = Math.max(PLAYER_MIN_X - (crystalsCollected + 1) * CRYSTAL_MOVE_STEP, 80 + player.width / 2); rightLimit = Math.min(PLAYER_MAX_X + (crystalsCollected + 1) * CRYSTAL_MOVE_STEP, GAME_WIDTH - 80 - player.width / 2); crystalsCollected++; } } } // Bonus boxes update for (var i = bonuses.length - 1; i >= 0; i--) { var bonus = bonuses[i]; var dx = player.x - bonus.x; var dy = player.y - bonus.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < BONUS_COLLECT_DIST) { LK.getSound('bonus_get').play(); LK.effects.flashObject(bonus, 0xffe100, 400); bonuses.splice(i, 1); bonus.destroy(); // Grant powerup player.setPower(bonus.type, POWERUP_DURATION); if (bonus.type === 'rapid') { powerupTxt.setText('Rapid Fire!'); } else if (bonus.type === 'pierce') { powerupTxt.setText('Piercing Shots!'); } else if (bonus.type === 'shield') { powerupTxt.setText('Shield!'); } } } // Powerup text timer if (player.powered) { powerupTxt.alpha = 1; } else { if (powerupTxt.alpha > 0) { powerupTxt.alpha -= 0.04; if (powerupTxt.alpha < 0) powerupTxt.alpha = 0; } powerupTxt.setText(''); } // Player auto-fire var cooldown = player.powered && player.powerType === 'rapid' ? LASER_COOLDOWN_RAPID : LASER_COOLDOWN; if (player.shootCooldown > 0) player.shootCooldown--; // Find nearest alien in range var nearestAlien = null; var minDist = 99999; for (var i = 0; i < aliens.length; i++) { var alien = aliens[i]; var dx = alien.x - player.x; var dy = alien.y - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dx < 0) continue; // Only shoot aliens to the right if (dist < minDist) { minDist = dist; nearestAlien = alien; } } if (nearestAlien && player.shootCooldown <= 0) { // Fire laser var laser = new Laser(); laser.x = player.x; laser.y = player.y - player.height / 2 + 10; if (player.powered && player.powerType === 'pierce') { laser.pierce = true; } lasers.push(laser); game.addChild(laser); player.shootCooldown = cooldown; LK.getSound('laser_shoot').play(); } // Spawn aliens for current wave if (enemiesToSpawn > 0 && LK.ticks - lastAlienSpawnTick > 24) { var alien = new Alien(); alien.x = ENEMY_START_X; alien.y = randInt(ENEMY_START_Y_MIN, ENEMY_START_Y_MAX); alien.wave = wave; alien.speed = 2.5 + (wave - 1) * WAVE_SPEED_INC; alien.hp = 1 + Math.floor((wave - 1) * WAVE_HP_INC / 2); aliens.push(alien); game.addChild(alien); enemiesToSpawn--; lastAlienSpawnTick = LK.ticks; } };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,442 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Alien class
+var Alien = Container.expand(function () {
+ var self = Container.call(this);
+ var alienSprite = self.attachAsset('alien', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = alienSprite.width;
+ self.height = alienSprite.height;
+ self.speed = 2.5;
+ self.hp = 1;
+ self.wave = 1;
+ self.lastX = self.x;
+ self.lastY = self.y;
+ self.lastIntersecting = false;
+ self.isDead = false;
+ self.update = function () {
+ self.x -= self.speed;
+ };
+ return self;
+});
+// Bonus box class
+var BonusBox = Container.expand(function () {
+ var self = Container.call(this);
+ var bonusSprite = self.attachAsset('bonus', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = bonusSprite.width;
+ self.height = bonusSprite.height;
+ self.lastY = self.y;
+ self.lastIntersecting = false;
+ self.type = null; // Set on spawn
+ return self;
+});
+// Crystal class
+var Crystal = Container.expand(function () {
+ var self = Container.call(this);
+ var crystalSprite = self.attachAsset('crystal', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = crystalSprite.width;
+ self.height = crystalSprite.height;
+ self.lastY = self.y;
+ self.lastIntersecting = false;
+ return self;
+});
+// Laser class
+var Laser = Container.expand(function () {
+ var self = Container.call(this);
+ var laserSprite = self.attachAsset('laser', {
+ anchorX: 0.5,
+ anchorY: 1
+ });
+ self.width = laserSprite.width;
+ self.height = laserSprite.height;
+ self.speed = 32;
+ self.pierce = false;
+ self.lastY = self.y;
+ self.lastIntersecting = false;
+ self.update = function () {
+ self.y -= self.speed;
+ };
+ return self;
+});
+// Player class
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var playerSprite = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.width = playerSprite.width;
+ self.height = playerSprite.height;
+ self.shootCooldown = 0;
+ self.moveSpeed = 32; // px per tick when dragged
+ self.leftLimit = 0 + self.width / 2 + 40;
+ self.rightLimit = 2048 - self.width / 2 - 40;
+ self.powered = false;
+ self.powerTimer = 0;
+ self.powerType = null;
+ // For powerup visuals
+ self.setPower = function (type, duration) {
+ self.powered = true;
+ self.powerType = type;
+ self.powerTimer = duration;
+ if (type === 'rapid') {
+ playerSprite.tint = 0xffe100;
+ } else if (type === 'pierce') {
+ playerSprite.tint = 0x00ffb0;
+ } else if (type === 'shield') {
+ playerSprite.tint = 0x00eaff;
+ }
+ };
+ self.clearPower = function () {
+ self.powered = false;
+ self.powerType = null;
+ self.powerTimer = 0;
+ playerSprite.tint = 0xffffff;
+ };
+ self.update = function () {
+ if (self.powered) {
+ self.powerTimer--;
+ if (self.powerTimer <= 0) {
+ self.clearPower();
+ }
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x0a0a1a
+});
+
+/****
+* Game Code
+****/
+// Music
+// Sound effects
+// Bonus box
+// Crystal (collectible)
+// Player bullet (laser)
+// Alien (enemy)
+// Player
+// Game constants
+var GAME_WIDTH = 2048;
+var GAME_HEIGHT = 2732;
+var GROUND_Y = GAME_HEIGHT - 220;
+var PLAYER_START_X = GAME_WIDTH / 2;
+var PLAYER_START_Y = GROUND_Y;
+var PLAYER_MIN_X = 160 + 40;
+var PLAYER_MAX_X = GAME_WIDTH - 160 - 40;
+var ENEMY_START_Y_MIN = 220;
+var ENEMY_START_Y_MAX = GROUND_Y - 200;
+var ENEMY_START_X = GAME_WIDTH + 120;
+var LASER_COOLDOWN = 18; // ticks
+var LASER_COOLDOWN_RAPID = 6;
+var CRYSTAL_COLLECT_DIST = 120;
+var BONUS_COLLECT_DIST = 120;
+var CRYSTAL_MOVE_STEP = 180; // How much movement area expands per crystal
+var MAX_CRYSTALS = 8;
+var WAVE_ENEMY_BASE = 10;
+var WAVE_ENEMY_INC = 4;
+var WAVE_SPEED_INC = 0.4;
+var WAVE_HP_INC = 1;
+var BONUS_WAVE_INTERVAL = 3;
+var POWERUP_DURATION = 360; // 6 seconds at 60fps
+// Game state
+var player = null;
+var aliens = [];
+var lasers = [];
+var crystals = [];
+var bonuses = [];
+var dragNode = null;
+var dragOffsetX = 0;
+var dragOffsetY = 0;
+var lastMoveX = 0;
+var lastMoveY = 0;
+var lastAlienSpawnTick = 0;
+var wave = 1;
+var enemiesLeft = 0;
+var enemiesToSpawn = 0;
+var enemiesKilled = 0;
+var crystalsCollected = 0;
+var leftLimit = PLAYER_MIN_X;
+var rightLimit = PLAYER_MAX_X;
+var bonusActive = false;
+var bonusType = null;
+var score = 0;
+var scoreTxt = null;
+var waveTxt = null;
+var powerupTxt = null;
+var gameOver = false;
+var youWin = false;
+// GUI
+scoreTxt = new Text2('0', {
+ size: 120,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+waveTxt = new Text2('Wave 1', {
+ size: 80,
+ fill: 0xAAFFFF
+});
+waveTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(waveTxt);
+waveTxt.y = 120;
+powerupTxt = new Text2('', {
+ size: 70,
+ fill: 0xFFE100
+});
+powerupTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(powerupTxt);
+powerupTxt.y = 220;
+// Start music
+LK.playMusic('bgmusic');
+// Spawn player
+player = new Player();
+player.x = PLAYER_START_X;
+player.y = PLAYER_START_Y;
+game.addChild(player);
+// Set initial movement limits
+leftLimit = player.leftLimit;
+rightLimit = player.rightLimit;
+// Start first wave
+function startWave(waveNum) {
+ wave = waveNum;
+ waveTxt.setText('Wave ' + wave);
+ enemiesToSpawn = WAVE_ENEMY_BASE + (wave - 1) * WAVE_ENEMY_INC;
+ enemiesLeft = enemiesToSpawn;
+ lastAlienSpawnTick = LK.ticks;
+}
+startWave(1);
+// Utility: clamp
+function clamp(val, min, max) {
+ if (val < min) return min;
+ if (val > max) return max;
+ return val;
+}
+// Utility: random int
+function randInt(min, max) {
+ return min + Math.floor(Math.random() * (max - min + 1));
+}
+// Utility: random powerup
+function randomPowerup() {
+ var arr = ['rapid', 'pierce', 'shield'];
+ return arr[randInt(0, arr.length - 1)];
+}
+// Handle movement (dragging)
+function handleMove(x, y, obj) {
+ if (dragNode === player) {
+ // Clamp to current movement limits
+ var newX = clamp(x, leftLimit, rightLimit);
+ player.x = newX;
+ lastMoveX = newX;
+ lastMoveY = player.y;
+ }
+}
+game.move = handleMove;
+game.down = function (x, y, obj) {
+ // Only allow drag if touch/click is on player or below
+ if (y > GROUND_Y - 200) {
+ dragNode = player;
+ handleMove(x, y, obj);
+ }
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+// Main game update
+game.update = function () {
+ if (gameOver || youWin) return;
+ // Player update (powerup timer)
+ player.update();
+ // Aliens update
+ for (var i = aliens.length - 1; i >= 0; i--) {
+ var alien = aliens[i];
+ alien.update();
+ // Check if alien reached left edge (player dies)
+ if (alien.x < 0 - alien.width / 2) {
+ LK.effects.flashScreen(0xff0000, 1000);
+ LK.showGameOver();
+ gameOver = true;
+ return;
+ }
+ // Check collision with player (if shielded, destroy alien)
+ if (player.powered && player.powerType === 'shield' && alien.intersects(player)) {
+ LK.getSound('alien_die').play();
+ LK.effects.flashObject(alien, 0x00eaff, 400);
+ alien.isDead = true;
+ aliens.splice(i, 1);
+ alien.destroy();
+ continue;
+ }
+ }
+ // Lasers update
+ for (var i = lasers.length - 1; i >= 0; i--) {
+ var laser = lasers[i];
+ laser.update();
+ // Remove if off screen
+ if (laser.y < -100) {
+ lasers.splice(i, 1);
+ laser.destroy();
+ continue;
+ }
+ // Check collision with aliens
+ var hit = false;
+ for (var j = aliens.length - 1; j >= 0; j--) {
+ var alien = aliens[j];
+ if (!alien.isDead && laser.intersects(alien)) {
+ alien.hp -= player.powered && player.powerType === 'pierce' ? 2 : 1;
+ if (alien.hp <= 0) {
+ // Alien dies
+ LK.getSound('alien_die').play();
+ LK.effects.flashObject(alien, 0xff0000, 400);
+ alien.isDead = true;
+ // Drop crystal
+ var crystal = new Crystal();
+ crystal.x = alien.x;
+ crystal.y = alien.y;
+ crystals.push(crystal);
+ game.addChild(crystal);
+ // Remove alien
+ aliens.splice(j, 1);
+ alien.destroy();
+ enemiesLeft--;
+ enemiesKilled++;
+ score += 10;
+ scoreTxt.setText(score);
+ // New wave?
+ if (enemiesLeft <= 0) {
+ // Bonus box every BONUS_WAVE_INTERVAL
+ if (wave % BONUS_WAVE_INTERVAL === 0) {
+ var bonus = new BonusBox();
+ bonus.x = randInt(leftLimit + 100, rightLimit - 100);
+ bonus.y = randInt(ENEMY_START_Y_MIN + 100, ENEMY_START_Y_MAX - 100);
+ bonus.type = randomPowerup();
+ bonuses.push(bonus);
+ game.addChild(bonus);
+ }
+ startWave(wave + 1);
+ }
+ }
+ hit = true;
+ if (!(player.powered && player.powerType === 'pierce')) break;
+ }
+ }
+ if (hit && !(player.powered && player.powerType === 'pierce')) {
+ lasers.splice(i, 1);
+ laser.destroy();
+ }
+ }
+ // Crystals update
+ for (var i = crystals.length - 1; i >= 0; i--) {
+ var crystal = crystals[i];
+ // If player close enough, collect
+ var dx = player.x - crystal.x;
+ var dy = player.y - crystal.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < CRYSTAL_COLLECT_DIST) {
+ LK.getSound('crystal_get').play();
+ LK.effects.flashObject(crystal, 0x00eaff, 400);
+ crystals.splice(i, 1);
+ crystal.destroy();
+ // Expand movement area
+ if (crystalsCollected < MAX_CRYSTALS) {
+ leftLimit = Math.max(PLAYER_MIN_X - (crystalsCollected + 1) * CRYSTAL_MOVE_STEP, 80 + player.width / 2);
+ rightLimit = Math.min(PLAYER_MAX_X + (crystalsCollected + 1) * CRYSTAL_MOVE_STEP, GAME_WIDTH - 80 - player.width / 2);
+ crystalsCollected++;
+ }
+ }
+ }
+ // Bonus boxes update
+ for (var i = bonuses.length - 1; i >= 0; i--) {
+ var bonus = bonuses[i];
+ var dx = player.x - bonus.x;
+ var dy = player.y - bonus.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < BONUS_COLLECT_DIST) {
+ LK.getSound('bonus_get').play();
+ LK.effects.flashObject(bonus, 0xffe100, 400);
+ bonuses.splice(i, 1);
+ bonus.destroy();
+ // Grant powerup
+ player.setPower(bonus.type, POWERUP_DURATION);
+ if (bonus.type === 'rapid') {
+ powerupTxt.setText('Rapid Fire!');
+ } else if (bonus.type === 'pierce') {
+ powerupTxt.setText('Piercing Shots!');
+ } else if (bonus.type === 'shield') {
+ powerupTxt.setText('Shield!');
+ }
+ }
+ }
+ // Powerup text timer
+ if (player.powered) {
+ powerupTxt.alpha = 1;
+ } else {
+ if (powerupTxt.alpha > 0) {
+ powerupTxt.alpha -= 0.04;
+ if (powerupTxt.alpha < 0) powerupTxt.alpha = 0;
+ }
+ powerupTxt.setText('');
+ }
+ // Player auto-fire
+ var cooldown = player.powered && player.powerType === 'rapid' ? LASER_COOLDOWN_RAPID : LASER_COOLDOWN;
+ if (player.shootCooldown > 0) player.shootCooldown--;
+ // Find nearest alien in range
+ var nearestAlien = null;
+ var minDist = 99999;
+ for (var i = 0; i < aliens.length; i++) {
+ var alien = aliens[i];
+ var dx = alien.x - player.x;
+ var dy = alien.y - player.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dx < 0) continue; // Only shoot aliens to the right
+ if (dist < minDist) {
+ minDist = dist;
+ nearestAlien = alien;
+ }
+ }
+ if (nearestAlien && player.shootCooldown <= 0) {
+ // Fire laser
+ var laser = new Laser();
+ laser.x = player.x;
+ laser.y = player.y - player.height / 2 + 10;
+ if (player.powered && player.powerType === 'pierce') {
+ laser.pierce = true;
+ }
+ lasers.push(laser);
+ game.addChild(laser);
+ player.shootCooldown = cooldown;
+ LK.getSound('laser_shoot').play();
+ }
+ // Spawn aliens for current wave
+ if (enemiesToSpawn > 0 && LK.ticks - lastAlienSpawnTick > 24) {
+ var alien = new Alien();
+ alien.x = ENEMY_START_X;
+ alien.y = randInt(ENEMY_START_Y_MIN, ENEMY_START_Y_MAX);
+ alien.wave = wave;
+ alien.speed = 2.5 + (wave - 1) * WAVE_SPEED_INC;
+ alien.hp = 1 + Math.floor((wave - 1) * WAVE_HP_INC / 2);
+ aliens.push(alien);
+ game.addChild(alien);
+ enemiesToSpawn--;
+ lastAlienSpawnTick = LK.ticks;
+ }
+};
\ No newline at end of file
A triangular spaceship. In-Game asset. 2d. High contrast. No shadows
alien creature drawing. In-Game asset. 2d. High contrast. No shadows
alien creature drawing. In-Game asset. 2d. High contrast. No shadows
alien creature drawing. In-Game asset. 2d. High contrast. No shadows
alien creature drawing. In-Game asset. 2d. High contrast. No shadows
blue crystal. In-Game asset. 2d. High contrast. No shadows
draw thick long laser bullet. In-Game asset. 2d. High contrast. No shadows
remove bonus text
spaceship. In-Game asset. 2d. High contrast. No shadows