export class ProEdgeEnemy extends Phaser.GameObjects.Sprite { constructor(scene, x, y, texture, frame) { super(scene, x, y, texture, frame); // Add the enemy to the scene scene.add.existing(this); // Enable physics for the enemy (if using Arcade Physics) scene.physics.world.enable(this); this.speed = 100; this.isFollowing = false; this.onPatrol = false; this.leftBoundary = 0; this.rightBoundary = 0; this.topBoundary = 0; this.bottomBoundary = 0; this.shoots = false; this.shootTimer = 0; this.scytheSpeed = 550; this.fireballSpeed = 300; this.exploding = false; this.reloadVariance = 4000; this.reloadCalc = 1000; this.reload = 0; this.bulletsGroup = scene.add.group(); this.dropHeartOneIn = 3; this.garbage = false; this.onPause = false; this.health = 1; this.takingDamage = false; this.boss = false; this.follows = false; // Create animations this.anims.create({ key: 'walk99', frames: this.anims.generateFrameNumbers(texture, { start: frame, end: frame+1 }), frameRate: 5, repeat: -1 }); } setPatrolX(leftBoundary, rightBoundary) { this.onPatrol = true; this.leftBoundary = leftBoundary; this.rightBoundary = rightBoundary; } setPatrolY(topBoundary, bottomBoundary) { this.onPatrol = true; this.topBoundary = topBoundary; this.bottomBoundary = bottomBoundary; } setSpeed(spd) { this.speed = spd; } // Example: Basic patrolling movement patrol() { if (this.onPause === true) { return; } // Horizontal boundaries if (this.leftBoundary !== 0) { if (this.body.blocked.left || this.body.x <= this.leftBoundary) { this.flipX = true; this.body.setVelocityX(this.speed); } else if (this.body.blocked.right || this.body.x >= this.rightBoundary) { this.flipX = false; this.body.setVelocityX(-this.speed); } } // Vertical boundaries if (this.topBoundary !== 0) { if (this.body.touching.up || this.body.y <= this.topBoundary) { this.body.setVelocityY(this.speed); } else if (this.body.touching.down || this.body.y >= this.bottomBoundary) { this.body.setVelocityY(-this.speed); } } // Prevent falling off the platform if (this.body.velocity.x === 0 && this.leftBoundary!== 0) { this.body.setVelocityX(this.speed); this.flipX = true; } if (this.body.velocity.y === 0 && this.bottomBoundary!== 0) { this.body.setVelocityY(this.speed); } } // Example: Following the player follow() { const camera = this.scene.cameras.main; // Only follow if enemy is visible on screen if (camera.worldView.contains(this.x, this.y)) { this.isFollowing = true; this.scene.physics.moveToObject(this, player, this.speed); } else { this.isFollowing = false; this.body.setVelocity(0); } } // Example: Enemy taking damage takeDamage() { if (this.takingDamage === true) { return; } this.takingDamage = true; // Set takingDamage back to false after 2000ms this.scene.time.delayedCall(500, () => { this.takingDamage = false; }); if (this.health === 1) { if (this.boss === true) { //BOSS DEFEAT this.scene.game.globalState.addScore(100); this.scene.interface.showScore(); this.shoots = false; this.garbage = false; this.onPatrol = false; this.anims.stop('walk99'); this.onPause = true; this.setTexture('boss-tiles', 2); this.scene.tweens.add({ targets: this, scale: 1.5, ease: 'Power1', yoyo: true, repeat: 2, duration: 200, onComplete: () => { this.setTexture('boss-tiles', 3); this.scene.tweens.add({ targets: this, ease: 'Power1', scale: 1.1, duration: 200, onComplete: () => { this.setTexture('boss-tiles', 4); this.scene.tweens.add({ targets: this, ease: 'Power1', scale: 0, duration: 2000, delay: 2000, onComplete: () => { this.destroy(); } }); } }); } }); } else { this.scene.game.globalState.addScore(25); this.scene.interface.showScore(); //REGULAR ENEMY DEFEAT let dropHeart = Math.floor(Math.random() * this.dropHeartOneIn); if (dropHeart === 1) { let heart = this.scene.physics.add.image(this.x, this.y, 'heart-full').setScale(.5); this.scene.hearts.add(heart); this.scene.tweens.add({ targets: heart, scale: 0.8, duration: 1000, ease: 'Power1', yoyo: true, repeat: -1 }); } // Create a tween that scales the enemy's body on Y-axis to 10 let variance = Math.floor(Math.random() * 2); this.scene.tweens.add({ targets: this, scaleY: .2, duration: 200, // Duration of the animation in milliseconds ease: 'Power1', onComplete: () => { // Destroy the enemy after the animation completes this.destroy(); } }); } } else { this.body.setVelocity(0, 0); this.health --; if (this.health === 2) { this.shoots = true; this.bottleReload = 1200; this.speed += 200; } if (this.health === 1) { this.bottleReload = 800; this.speed += 200; this.bottleReloadVariance = 1000; } if (this.boss === true) { this.anims.stop('walk99'); this.setTexture('boss-tiles', 2); } } } fireBullet() { // Fire the bottle let variance = Math.floor(Math.random() * 2); if (variance === 0) { this.fireScythe(); } else { this.fireBalls(); } } fireScythe() { const player = this.scene.player; const scythe = this.scene.physics.add.sprite(this.x, this.y, 'proedge-enemies', 3); scythe.setSize(75, 75); this.scene.attacks.add(scythe); const angle = Phaser.Math.Angle.Between(this.x, this.y, player.x, player.y); scythe.setVelocity(Math.cos(angle) * this.scytheSpeed, Math.sin(angle) * this.scytheSpeed); this.scene.physics.world.enable(scythe); this.scene.sound.play('swoosh'); this.scene.tweens.add({ targets: scythe, angle: 1080, duration: 1500, ease: 'Power1', onComplete: () => { scythe.destroy(); } }); } fireBalls() { // Get the player from the scene const player = this.scene.player; // Fire three garbage projectiles with different angles const baseAngle = Phaser.Math.Angle.Between(this.x, this.y, player.x, player.y); // Create and fire garbage at 0.5 radians less than the base angle this.createFireballProjectile(baseAngle - 0.8); // Create and fire garbage at 0.5 radians more than the base angle this.createFireballProjectile(baseAngle + 0.8); this.scene.sound.play('fireball-1'); this.scene.time.delayedCall(800, () => { if (this.scene) { this.scene.sound.play('fireball-2'); } }); } createFireballProjectile(angle) { const player = this.scene.player; const fireball = this.scene.physics.add.sprite(this.x, this.y, 'proedge-enemies', 2); fireball.setSize(50, 50).setScale(.75); this.scene.attacks.add(fireball); fireball.setVelocity(Math.cos(angle) * this.scytheSpeed, Math.sin(angle) * this.scytheSpeed); this.scene.physics.world.enable(fireball); this.scene.tweens.add({ targets: fireball, angle: 720, duration: 800, ease: 'Power1', onComplete: () => { const baseAngle = Phaser.Math.Angle.Between(fireball.x, fireball.y, player.x, player.y); fireball.setVelocity(Math.cos(baseAngle) * this.fireballSpeed, Math.sin(baseAngle) * this.fireballSpeed); if (this.scene) { this.scene.tweens.add({ targets: fireball, angle: -720, duration: 1500, ease: 'Power1', onComplete: () => { fireball.destroy(); } }); } } }); } explode() { const player = this.scene.player; this.prepShot(); this.scene.time.delayedCall(1000, () => { if (this.scene) { const explosion = this.scene.physics.add.image(this.x, this.y, 'explosion'); this.scene.explosions.add(explosion); this.scene.physics.world.enable(explosion); this.scene.sound.play('explosion'); this.scene.tweens.add({ targets: explosion, angle: 120, duration: 500, ease: 'Power1', alpha: .3, scale: 3, onComplete: () => { explosion.destroy(); } }); } this.destroy(); }); } prepShot() { this.scene.time.delayedCall(500, () => { if(!this.body) { return; } this.onPause = true; const originalVelocity = this.body.velocity.clone(); this.body.setVelocity(0, 0); this.scene.time.delayedCall(500, () => { if(!this.body) { return; } this.body.setVelocity(originalVelocity.x, originalVelocity.y); this.onPause = false; }); }); this.scene.tweens.add({ targets: this, tint: 0xaaaaff, duration: 1000, repeat: 0, yoyo: true, ease: 'Power1' }); } // update(time, delta) { if (this.takingDamage === true) { this.body.setVelocity(0, 0); return; } if (this.follows === true) { const camera = this.scene.cameras.main; if (camera.worldView.contains(this.x, this.y)) { this.isFollowing = true; if (Phaser.Math.Distance.Between(this.x, this.y, this.scene.player.x, this.scene.player.y) < 200 && this.exploding === false) { this.exploding = true; this.explode(); } else { this.scene.physics.moveToObject(this, this.scene.player, this.speed); this.anims.play('walk99', true); } } else { this.isFollowing = false; this.body.setVelocity(0); } } if (this.onPatrol === true) { this.patrol(); this.anims.play('walk99', true); } const camera = this.scene.cameras.main; if (this.shoots) { if (camera.worldView.contains(this.x, this.y)) { this.shootTimer += delta; if (this.shootTimer >= this.reloadCalc) { this.shootTimer = 0; let variance = Math.floor(Math.random() * this.reloadVariance); this.reloadCalc = this.reload + variance; this.prepShot(); this.scene.time.delayedCall(1000, () => { if(!this.body) { return; } this.fireBullet(); }); } } } } }