diff --git a/assets/enemy-sprite.png b/assets/enemy-sprite.png index cdca7ac..01713e8 100644 Binary files a/assets/enemy-sprite.png and b/assets/enemy-sprite.png differ diff --git a/assets/sounds/missle.mp3 b/assets/sounds/missle.mp3 new file mode 100644 index 0000000..deb629c Binary files /dev/null and b/assets/sounds/missle.mp3 differ diff --git a/raw/enemies.psd b/raw/enemies.psd index 4f71e68..ec449a6 100644 Binary files a/raw/enemies.psd and b/raw/enemies.psd differ diff --git a/src/scenes/GameScene.js b/src/scenes/GameScene.js index 84cb80a..d6a994b 100644 --- a/src/scenes/GameScene.js +++ b/src/scenes/GameScene.js @@ -11,6 +11,7 @@ export class GameScene extends Phaser.Scene { // Enemy bullets group this.enemyBullets = null; + this.enemyMissles = null; // Game state this.score = 0; @@ -39,6 +40,11 @@ export class GameScene extends Phaser.Scene { waveNumber: 2, time: 40000, enemyTypes: [2] // Special enemies in wave 3 + }, + { + waveNumber: 3, + time: 60000, + enemyTypes: [3] // Special enemies in wave 3 } ]; } @@ -75,6 +81,7 @@ export class GameScene extends Phaser.Scene { this.load.audio('enemy-shoot', 'assets/sounds/enemy-shoot.mp3'); this.load.audio('next-wave', 'assets/sounds/next-wave.mp3'); this.load.audio('thruster', 'assets/sounds/thruster.mp3'); + this.load.audio('missle', 'assets/sounds/missle.mp3'); // Load Fonts this.load.font('Space', 'assets/space-age.otf'); @@ -98,11 +105,13 @@ export class GameScene extends Phaser.Scene { this.bullets = this.physics.add.group(); this.enemyBullets = this.physics.add.group(); this.enemies = this.physics.add.group(); + this.enemyMissles = this.physics.add.group(); // Setup collision detection this.physics.add.overlap(this.bullets, this.enemies, this.hitEnemy, null, this); this.physics.add.overlap(this.player.sprite, this.enemies, this.hitPlayer, null, this); this.physics.add.overlap(this.player.sprite, this.enemyBullets, this.hitPlayer, null, this); + this.physics.add.overlap(this.player.sprite, this.enemyMissles, this.hitPlayer, null, this); // Start enemy spawning this.time.addEvent({ @@ -287,14 +296,6 @@ export class GameScene extends Phaser.Scene { fontFamily: 'Space, Arial' }); - // Create game title - // this.titleText = this.add.text(300, 50, 'Zenith Vector', { - // fontSize: '40px', - // fill: '#00ffcc', - // fontFamily: 'Arial', - // align: 'center' - // }); - // this.titleText.setOrigin(0.5); this.titleText = this.add.image(500, 50, 'logo').setScale(.3).setOrigin(0.5).postFX.addGlow(); } @@ -339,9 +340,6 @@ export class GameScene extends Phaser.Scene { const speed = Phaser.Math.Between(50, 150); enemy.setVelocityY(speed); - // Add some rotation for visual effect - //enemy.setRotation(Phaser.Math.FloatBetween(-0.2, 0.2)); - // Apply wave-specific properties this.applyWaveProperties(enemy, texture); } @@ -353,14 +351,16 @@ export class GameScene extends Phaser.Scene { // Wave 1: Basic enemies (no shooting) if (this.currentWave === 0) { enemy.canShoot = false; + enemy.canMissle = false; if (enemy.shootTimer) { enemy.shootTimer.remove(); enemy.shootTimer = null; } } // Wave 2: Enemies that can shoot - else if (this.currentWave >= 1 && texture > 0) { + else if (this.currentWave >= 1 && texture > 0 && texture <= 2) { enemy.canShoot = true; + enemy.canMissle = false; // Only set up shooting timer if it doesn't exist yet if (!enemy.shootTimer) { enemy.shootTimer = this.time.addEvent({ @@ -371,6 +371,19 @@ export class GameScene extends Phaser.Scene { }); } } + // Wave 3: Enemies with missles + else if (this.currentWave >= 3 && texture === 3) { + enemy.canMissle = true; + // Only set up shooting timer if it doesn't exist yet + if (!enemy.missleTimer) { + enemy.missleTimer = this.time.addEvent({ + delay: Phaser.Math.Between(1000, 3000), + callback: () => this.enemyMissle(enemy, texture), + callbackScope: this, + loop: true + }); + } + } } hitEnemy(bullet, enemy) { @@ -483,10 +496,9 @@ export class GameScene extends Phaser.Scene { enemyShoot(enemy, texture) { // Only shoot if enemy can shoot and isn't destroyed if (!enemy.canShoot || !enemy.active) return; - - console.log(texture); + // Check if this is wave 3 and enemy has texture 2 (special shooting) - if (this.currentWave >= 2 && enemy.waveNumber >= 2 && texture >= 2) { + if (this.currentWave >= 2 && enemy.waveNumber >= 2 && texture === 2) { // Shoot toward player const angle = Phaser.Math.Angle.Between( enemy.x, @@ -500,7 +512,7 @@ export class GameScene extends Phaser.Scene { bullet.setVelocityX(Math.cos(angle) * speed); bullet.setVelocityY(Math.sin(angle) * speed); bullet.setScale(1.5); - } else { + } else if (texture === 1) { // Regular straight-down shooting const bullet = this.enemyBullets.create(enemy.x, enemy.y, 'enemyBullet'); bullet.setVelocityY(300); // Move straight down at 200px/s @@ -511,6 +523,55 @@ export class GameScene extends Phaser.Scene { this.sound.play('enemy-shoot'); } + enemyMissle(enemy, texture) { + // Only shoot if enemy can shoot and isn't destroyed + if (!enemy.canMissle || !enemy.active) return; + + // Check if this is wave 3 and enemy has texture 2 (special shooting) + if (this.currentWave >= 3 && enemy.waveNumber >= 3 && texture >= 3) { + const missle1 = this.enemyMissles.create(enemy.x, enemy.y, 'enemy-sprite', 30); + const missle2 = this.enemyMissles.create(enemy.x, enemy.y, 'enemy-sprite', 30); + + // Initial velocity + missle1.setVelocityX(-100).setVelocityY(200).setAngle(45).setScale(.5); + missle2.setVelocityX(100).setVelocityY(200).setAngle(-45).setScale(.5); + + // After 500ms, change direction towards player and increase speed + this.time.delayedCall(500, () => { + if (missle1 && missle1.active) { + const angle = Phaser.Math.Angle.Between( + missle1.x, + missle1.y, + this.player.sprite.x, + this.player.sprite.y + ); + + // Increase velocity to 300 and change direction + missle1.setVelocityX(Math.cos(angle) * 300); + missle1.setVelocityY(Math.sin(angle) * 300); + missle1.setAngle(Phaser.Math.RadToDeg(angle)-90); + } + + if (missle2 && missle2.active) { + const angle = Phaser.Math.Angle.Between( + missle2.x, + missle2.y, + this.player.sprite.x, + this.player.sprite.y + ); + + // Increase velocity to 300 and change direction + missle2.setVelocityX(Math.cos(angle) * 300); + missle2.setVelocityY(Math.sin(angle) * 300); + missle2.setAngle(Phaser.Math.RadToDeg(angle)-90); + } + }); + } + + // Sound effect for enemy shooting + this.sound.play('missle'); + } + checkEnemiesOffScreen() { // Destroy enemies that have gone below the screen this.enemies.children.iterate((enemy) => {