LegendsOfCoyoteGulch/src/characters/proEdge.js

546 lines
18 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.stars = false;
this.sword = false;
this.lightningCast = false;
this.caster = false;
this.shootTimer = 0;
this.scytheSpeed = 550;
this.starSpeed = 700;
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.stars = false;
this.sword = false;
this.onPatrol = false;
this.lightningCast = false;
this.anims.stop('walk99');
this.onPause = true;
this.setTexture('boss-tiles', 8);
this.scene.tweens.add({
targets: this,
scale: 1.5,
ease: 'Power1',
yoyo: true,
repeat: 2,
duration: 200,
onComplete: () => {
this.scene.tweens.add({
targets: this,
ease: 'Power1',
scale: 1.1,
duration: 200,
onComplete: () => {
this.scene.bossDefeated = true;
this.setTexture('boss-tiles', 9);
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 === 3) {
this.speed += 100;
this.sword = true;
}
if (this.health === 2) {
this.stars = true;
this.bottleReload = 1200;
this.speed += 100;
}
if (this.health === 1) {
this.shoots = true;
this.bottleReload = 800;
this.speed += 200;
this.bottleReloadVariance = 1000;
}
if (this.boss === true) {
this.anims.stop('walk99');
this.setTexture('boss-tiles', 8);
}
}
}
fireStars() {
this.fireStar();
this.scene.time.delayedCall(200, () => {
this.fireStar();
});
this.scene.time.delayedCall(400, () => {
this.fireStar();
});
}
fireStar() {
if (this.scene) {
const player = this.scene.player;
const star = this.scene.physics.add.sprite(this.x, this.y, 'proedge-enemies', 14);
star.setSize(75, 75);
this.scene.attacks.add(star);
const angle = Phaser.Math.Angle.Between(this.x, this.y, player.x, player.y);
star.setVelocity(Math.cos(angle) * this.starSpeed, Math.sin(angle) * this.starSpeed);
this.scene.physics.world.enable(star);
this.scene.sound.play('swoosh');
this.scene.tweens.add({
targets: star,
angle: 1080,
duration: 1500,
ease: 'Linear',
onComplete: () => {
star.destroy();
}
});
}
}
fireSword() {
const player = this.scene.player;
const sword = this.scene.physics.add.sprite(this.x, this.y, 'proedge-enemies', 13);
sword.setSize(75, 75);
this.scene.attacks.add(sword);
const angle = Phaser.Math.Angle.Between(this.x, this.y, player.x, player.y);
sword.setVelocity(Math.cos(angle) * this.scytheSpeed, Math.sin(angle) * this.scytheSpeed);
this.scene.physics.world.enable(sword);
this.scene.sound.play('swoosh');
this.scene.tweens.add({
targets: sword,
angle: 360,
duration: 1500,
ease: 'Linear',
onComplete: () => {
sword.destroy();
}
});
}
cast() {
let vari = Phaser.Math.Between(1, 3)
if (vari === 1) {
this.fireBalls();
} else {
this.fireFloor();
}
}
fireFloor() {
const player = this.scene.player;
const fire = this.scene.physics.add.sprite(this.x, this.y, 'proedge-enemies', 12);
fire.setSize(150, 150).setScale(0.2);
this.scene.attacks.add(fire);
const angle = Phaser.Math.Angle.Between(this.x, this.y, player.x, player.y);
// Position the fire sprite 150 units away from player along the angle
fire.x = player.x + Math.cos(angle) * -150;
fire.y = player.y + Math.sin(angle) * -150;
this.scene.sound.play('fireSpell');
this.scene.physics.world.enable(fire);
this.scene.tweens.add({
targets: fire,
angle: -1080,
duration: 10000,
scale: 2.5,
ease: 'Linear',
onComplete: () => {
fire.destroy();
}
});
}
lightningFloor() {
const player = this.scene.player;
const lightning = this.scene.physics.add.sprite(this.x, this.y, 'proedge-enemies', 15);
const fire = this.scene.physics.add.sprite(this.x, this.y, 'proedge-enemies', 16);
fire.setSize(150, 150).setScale(0.2);
this.scene.attacks.add(fire);
const angle = Phaser.Math.Angle.Between(this.x, this.y, player.x, player.y);
// Position the fire sprite 150 units away from player along the angle
fire.x = player.x + Math.cos(angle) * -150;
fire.y = player.y + Math.sin(angle) * -150;
lightning.x = (player.x + Math.cos(angle) * -150) + 10;
lightning.y = (player.y + Math.sin(angle) * -150) - 40;
// Add flashing animation to lightning sprite
this.scene.tweens.add({
targets: lightning,
alpha: 0,
duration: 100,
repeat: 3,
yoyo: true,
ease: 'Linear',
onComplete: () => {
lightning.destroy();
}
});
this.scene.sound.play('lightningVortex');
this.scene.physics.world.enable(fire);
this.scene.tweens.add({
targets: fire,
angle: -1080,
duration: 6000,
scale: 2,
ease: 'Linear',
onComplete: () => {
fire.destroy();
}
});
}
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);
if (this.body.velocity.x < 0) {
this.flipX = false;
} else {
this.flipX = 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 || this.stars || this.sword || this.caster || this.boss) {
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;
}
if (this.shoots) {
this.fireBullet();
} else if (this.stars) {
this.fireStars();
} else if (this.sword) {
this.fireSword();
} else if (this.caster) {
this.cast();
}
if (this.lightningCast) {
this.lightningFloor();
}
});
}
}
}
}
}