Add enemy missle projectiles for wave 3 with new sound effect and updated shooting logic
This commit implements enemy missle projectiles for wave 3 enemies, including: - Added new 'missle' audio file and loaded it in GameScene - Created enemyMissles physics group for tracking missle projectiles - Updated game waves configuration to include wave 3 with special enemies (texture 3) - Modified enemy spawning logic to handle missle capability for wave 3 enemies - Implemented enemyMissle() method that creates two directional missles that later home in on player - Adjusted enemy shooting logic to differentiate between regular bullets and missles based on texture - Added collision detection between player and missles - Updated wave-specific properties handling for new enemy types The changes enable a new challenging gameplay element in wave 3 where enemies can launch homing missle projectiles.
This commit is contained in:
parent
eb01c3d89c
commit
c93e599556
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 31 KiB |
Binary file not shown.
BIN
raw/enemies.psd
BIN
raw/enemies.psd
Binary file not shown.
|
|
@ -11,6 +11,7 @@ export class GameScene extends Phaser.Scene {
|
||||||
|
|
||||||
// Enemy bullets group
|
// Enemy bullets group
|
||||||
this.enemyBullets = null;
|
this.enemyBullets = null;
|
||||||
|
this.enemyMissles = null;
|
||||||
|
|
||||||
// Game state
|
// Game state
|
||||||
this.score = 0;
|
this.score = 0;
|
||||||
|
|
@ -39,6 +40,11 @@ export class GameScene extends Phaser.Scene {
|
||||||
waveNumber: 2,
|
waveNumber: 2,
|
||||||
time: 40000,
|
time: 40000,
|
||||||
enemyTypes: [2] // Special enemies in wave 3
|
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('enemy-shoot', 'assets/sounds/enemy-shoot.mp3');
|
||||||
this.load.audio('next-wave', 'assets/sounds/next-wave.mp3');
|
this.load.audio('next-wave', 'assets/sounds/next-wave.mp3');
|
||||||
this.load.audio('thruster', 'assets/sounds/thruster.mp3');
|
this.load.audio('thruster', 'assets/sounds/thruster.mp3');
|
||||||
|
this.load.audio('missle', 'assets/sounds/missle.mp3');
|
||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
this.load.font('Space', 'assets/space-age.otf');
|
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.bullets = this.physics.add.group();
|
||||||
this.enemyBullets = this.physics.add.group();
|
this.enemyBullets = this.physics.add.group();
|
||||||
this.enemies = this.physics.add.group();
|
this.enemies = this.physics.add.group();
|
||||||
|
this.enemyMissles = this.physics.add.group();
|
||||||
|
|
||||||
// Setup collision detection
|
// Setup collision detection
|
||||||
this.physics.add.overlap(this.bullets, this.enemies, this.hitEnemy, null, this);
|
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.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.enemyBullets, this.hitPlayer, null, this);
|
||||||
|
this.physics.add.overlap(this.player.sprite, this.enemyMissles, this.hitPlayer, null, this);
|
||||||
|
|
||||||
// Start enemy spawning
|
// Start enemy spawning
|
||||||
this.time.addEvent({
|
this.time.addEvent({
|
||||||
|
|
@ -287,14 +296,6 @@ export class GameScene extends Phaser.Scene {
|
||||||
fontFamily: 'Space, Arial'
|
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();
|
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);
|
const speed = Phaser.Math.Between(50, 150);
|
||||||
enemy.setVelocityY(speed);
|
enemy.setVelocityY(speed);
|
||||||
|
|
||||||
// Add some rotation for visual effect
|
|
||||||
//enemy.setRotation(Phaser.Math.FloatBetween(-0.2, 0.2));
|
|
||||||
|
|
||||||
// Apply wave-specific properties
|
// Apply wave-specific properties
|
||||||
this.applyWaveProperties(enemy, texture);
|
this.applyWaveProperties(enemy, texture);
|
||||||
}
|
}
|
||||||
|
|
@ -353,14 +351,16 @@ export class GameScene extends Phaser.Scene {
|
||||||
// Wave 1: Basic enemies (no shooting)
|
// Wave 1: Basic enemies (no shooting)
|
||||||
if (this.currentWave === 0) {
|
if (this.currentWave === 0) {
|
||||||
enemy.canShoot = false;
|
enemy.canShoot = false;
|
||||||
|
enemy.canMissle = false;
|
||||||
if (enemy.shootTimer) {
|
if (enemy.shootTimer) {
|
||||||
enemy.shootTimer.remove();
|
enemy.shootTimer.remove();
|
||||||
enemy.shootTimer = null;
|
enemy.shootTimer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Wave 2: Enemies that can shoot
|
// 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.canShoot = true;
|
||||||
|
enemy.canMissle = false;
|
||||||
// Only set up shooting timer if it doesn't exist yet
|
// Only set up shooting timer if it doesn't exist yet
|
||||||
if (!enemy.shootTimer) {
|
if (!enemy.shootTimer) {
|
||||||
enemy.shootTimer = this.time.addEvent({
|
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) {
|
hitEnemy(bullet, enemy) {
|
||||||
|
|
@ -484,9 +497,8 @@ export class GameScene extends Phaser.Scene {
|
||||||
// Only shoot if enemy can shoot and isn't destroyed
|
// Only shoot if enemy can shoot and isn't destroyed
|
||||||
if (!enemy.canShoot || !enemy.active) return;
|
if (!enemy.canShoot || !enemy.active) return;
|
||||||
|
|
||||||
console.log(texture);
|
|
||||||
// Check if this is wave 3 and enemy has texture 2 (special shooting)
|
// 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
|
// Shoot toward player
|
||||||
const angle = Phaser.Math.Angle.Between(
|
const angle = Phaser.Math.Angle.Between(
|
||||||
enemy.x,
|
enemy.x,
|
||||||
|
|
@ -500,7 +512,7 @@ export class GameScene extends Phaser.Scene {
|
||||||
bullet.setVelocityX(Math.cos(angle) * speed);
|
bullet.setVelocityX(Math.cos(angle) * speed);
|
||||||
bullet.setVelocityY(Math.sin(angle) * speed);
|
bullet.setVelocityY(Math.sin(angle) * speed);
|
||||||
bullet.setScale(1.5);
|
bullet.setScale(1.5);
|
||||||
} else {
|
} else if (texture === 1) {
|
||||||
// Regular straight-down shooting
|
// Regular straight-down shooting
|
||||||
const bullet = this.enemyBullets.create(enemy.x, enemy.y, 'enemyBullet');
|
const bullet = this.enemyBullets.create(enemy.x, enemy.y, 'enemyBullet');
|
||||||
bullet.setVelocityY(300); // Move straight down at 200px/s
|
bullet.setVelocityY(300); // Move straight down at 200px/s
|
||||||
|
|
@ -511,6 +523,55 @@ export class GameScene extends Phaser.Scene {
|
||||||
this.sound.play('enemy-shoot');
|
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() {
|
checkEnemiesOffScreen() {
|
||||||
// Destroy enemies that have gone below the screen
|
// Destroy enemies that have gone below the screen
|
||||||
this.enemies.children.iterate((enemy) => {
|
this.enemies.children.iterate((enemy) => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue