LegendsOfCoyoteGulch/src/characters/proEdge.js

396 lines
13 KiB
JavaScript

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();
});
}
}
}
}
}