Source: models/enemies/endboss.class.js

/**
 * Represents the Endboss in the game, which extends from MovableObject.
 * This class controls the different states of the Endboss (walking, alerted,
 * attacking, hurt, and dead) as well as its movement and animation intervals.
 */
class Endboss extends MovableObject {
  height = 400;
  width = 200;
  speed = 1;
  itsMove = false;
  speedResetTimeout = null;

  /**
   * Indicates whether the Endboss is currently attacking.
   * @type {boolean}
   */
  isAttack = false;
  y = 55;
  energy = 100;
  movementInterval = null;

  /**
   * Reference to the setInterval used for animations.
   * @type {number|null}
   */
  animationInterval = null;

  /**
   * Reference to the setInterval used for movement while attacking.
   * @type {number|null}
   */
  moveInterval = null;
  /**
   * Array of image paths for the alert state.
   * @type {string[]}
   */
  IMAGES_ALERT = [
    "img/4_enemie_boss_chicken/2_alert/G5.png",
    "img/4_enemie_boss_chicken/2_alert/G6.png",
    "img/4_enemie_boss_chicken/2_alert/G7.png",
    "img/4_enemie_boss_chicken/2_alert/G8.png",
    "img/4_enemie_boss_chicken/2_alert/G9.png",
    "img/4_enemie_boss_chicken/2_alert/G10.png",
    "img/4_enemie_boss_chicken/2_alert/G11.png",
    "img/4_enemie_boss_chicken/2_alert/G12.png",
  ];

  /**
   * Array of image paths for the attack state.
   * @type {string[]}
   */
  IMAGES_ATTACK = [
    "img/4_enemie_boss_chicken/3_attack/G13.png",
    "img/4_enemie_boss_chicken/3_attack/G14.png",
    "img/4_enemie_boss_chicken/3_attack/G15.png",
    "img/4_enemie_boss_chicken/3_attack/G16.png",
    "img/4_enemie_boss_chicken/3_attack/G17.png",
    "img/4_enemie_boss_chicken/3_attack/G18.png",
    "img/4_enemie_boss_chicken/3_attack/G19.png",
    "img/4_enemie_boss_chicken/3_attack/G20.png",
  ];

  /**
   * Array of image paths for the walking state.
   * @type {string[]}
   */
  IMAGES_WALKING = [
    "img/4_enemie_boss_chicken/1_walk/G1.png",
    "img/4_enemie_boss_chicken/1_walk/G2.png",
    "img/4_enemie_boss_chicken/1_walk/G3.png",
    "img/4_enemie_boss_chicken/1_walk/G4.png",
  ];

  /**
   * Array of image paths for the hurt state.
   * @type {string[]}
   */
  IMAGES_HURT = [
    "img/4_enemie_boss_chicken/4_hurt/G21.png",
    "img/4_enemie_boss_chicken/4_hurt/G22.png",
    "img/4_enemie_boss_chicken/4_hurt/G23.png",
  ];

  /**
   * Array of image paths for the dead state.
   * @type {string[]}
   */
  IMAGES_DEAD = [
    "img/4_enemie_boss_chicken/5_dead/G24.png",
    "img/4_enemie_boss_chicken/5_dead/G25.png",
    "img/4_enemie_boss_chicken/5_dead/G26.png",
  ];

  /**
   * Creates an instance of Endboss.
   * Loads images, sets the initial position and offsets, and starts the animation.
   */
  constructor() {
    super();
    this.loadImage(this.IMAGES_ALERT[0]);
    this.loadImages(this.IMAGES_ALERT);
    this.loadImages(this.IMAGES_DEAD);
    this.loadImages(this.IMAGES_WALKING);
    this.loadImages(this.IMAGES_ATTACK);
    this.loadImages(this.IMAGES_HURT);
    this.offset.top = 60;
    this.offset.bottom = 10;
    this.x = 10150;
    this.movementInterval = null;
    this.animationInterval = null;
    this.moveInterval = null;
    this.frameIndexDead = 0;
    this.animate();
    this.hurtSpeedIncreased = false;
  }

  /**
   * Starts the movement and animation intervals.
   */
  animate() {
    this.clearIntervals();
    this.startMovementInterval();
    this.startAnimationInterval();
  }
  updatePrecent(){

  }

  /**
   * Clears any existing movement and animation intervals.
   */
  clearIntervals() {
    if (this.movementInterval) clearInterval(this.movementInterval);
    if (this.animationInterval) clearInterval(this.animationInterval);
  }

  /**
   * Starts the interval that controls the movement logic.
   */
  startMovementInterval() {
    this.movementInterval = setInterval(() => this.handleMovement(), 1000 / 60);
  }

  /**
   * Controls the movement logic:
   * - Moves the Endboss to the left if it is attacking.
   * - Stops the interval if the Endboss is dead.
   * - Moves left if not attacking and the itsMove flag is true.
   */
  handleMovement() {
    if (this.isAttack) {
      this.moveEnemie();
    }

    if (this.isDead()) {
      clearInterval(this.movementInterval);
      return;
    }

    if (!this.isAttack && this.itsMove) {
      this.moveLeft();
    }
  }

  /**
   * Starts the interval that controls the animation logic.
   */
  startAnimationInterval() {
    this.animationInterval = setInterval(() => this.handleAnimation(), 150);
  }

  /**
   * Determines the current state and plays the corresponding animation:
   * - Dead, Hurt, Attack, Walking, or Alert.
   */
  handleAnimation() {
    if (this.isDead()) {
      this.handleDeadAnimation();
    } else if (this.isHurt()) {
      this.handleHurtAnimation();
    } else {
      this.hurtSpeedIncreased = false;
      if (this.isAttack) {
        this.handleAttackAnimation();
      } else if (this.itsMove) {
        this.handleWalkingAnimation();
      } else {
        this.handleAlertAnimation();
      }
    }
  }

  /**
   * Plays the death animation and increments the frame index until the animation completes.
   */
  handleDeadAnimation() {
    this.playAnimation([this.IMAGES_DEAD[this.frameIndexDead]]);
    this.frameIndexDead++;
    if (this.frameIndexDead >= this.IMAGES_DEAD.length) {
      clearInterval(this.animationInterval);
    }
  }

  /**
   * Plays the hurt animation and slightly moves the Endboss to the right.
   * Increases the speed only once during the hurt state.
   */
  handleHurtAnimation() {
    if (!this.hurtSpeedIncreased) {
      this.speed += 2;
      this.speedResetTimeout = setTimeout(() => {
        this.resetSpeed();
      }, 5000);
      this.hurtSpeedIncreased = true;
    }
    this.playAnimation(this.IMAGES_HURT);
  }

  /**
   * Plays the attack animation.
   */
  handleAttackAnimation() {
    this.playAnimation(this.IMAGES_ATTACK);
    clearInterval(this.moveInterval);
  
  }

  /**
   * Plays the walking animation.
   */
  handleWalkingAnimation() {
    this.playAnimation(this.IMAGES_WALKING);
  }

  /**
   * Plays the alert animation.
   */
  handleAlertAnimation() {
    this.playAnimation(this.IMAGES_ALERT);
  }

  /**
   * Resets the Endboss's speed to its default value.
   */
  resetSpeed() {
    this.speed = 1;
  }

  /**
   * Resets the Endboss to its initial state and restarts movement and animation intervals.
   */
  resetEnemy() {
    if (this.movementInterval) clearInterval(this.movementInterval);
    if (this.animationInterval) clearInterval(this.animationInterval);
    if (this.moveInterval) clearInterval(this.moveInterval);
    this.itsMove = false;
    this.isAttack = false;
    this.y = 55;
    this.x = 10150;
    this.energy = 100;
    this.frameIndexDead = 0;
    this.hurtSpeedIncreased = false;
    this.animate();
  }

  /**
   * Moves the Endboss to the left during an attack.
   * Starts a movement interval if one is not already active.
   */
  moveEnemie() {
    if (!this.isDead() && this.isAttack && !this.moveInterval) {
      this.moveInterval = setInterval(() => {
        this.moveLeft();
      }, 1000 / 60);
    }
  }
}