/**
* Represents a throwable salsa bottle in the game, extending the MovableObject class.
* It can be thrown in a chosen direction, rotates while in the air, and splashes upon hitting the ground.
*
* @class Throwableobject
* @extends MovableObject
*/
class Throwableobject extends MovableObject {
/**
* Indicates whether the bottle has broken (splash animation completed).
* @type {boolean}
*/
bottleIsBroken = false;
/**
* Reference to the game world.
* @type {object}
*/
world;
/**
* An array of image paths for the bottle's rotation animation.
* @type {string[]}
*/
IMAGES_ROTATION = [
"img/6_salsa_bottle/bottle_rotation/1_bottle_rotation.png",
"img/6_salsa_bottle/bottle_rotation/2_bottle_rotation.png",
"img/6_salsa_bottle/bottle_rotation/3_bottle_rotation.png",
"img/6_salsa_bottle/bottle_rotation/4_bottle_rotation.png",
];
/**
* An array of image paths for the bottle's splash animation upon impact.
* @type {string[]}
*/
IMAGES_SPLASH = [
"img/6_salsa_bottle/bottle_rotation/bottle_splash/1_bottle_splash.png",
"img/6_salsa_bottle/bottle_rotation/bottle_splash/2_bottle_splash.png",
"img/6_salsa_bottle/bottle_rotation/bottle_splash/3_bottle_splash.png",
"img/6_salsa_bottle/bottle_rotation/bottle_splash/4_bottle_splash.png",
"img/6_salsa_bottle/bottle_rotation/bottle_splash/5_bottle_splash.png",
"img/6_salsa_bottle/bottle_rotation/bottle_splash/6_bottle_splash.png",
];
/**
* Constructs a new Throwableobject, loads rotation and splash images, and initiates its throwing and animation behavior.
*
* @constructor
* @param {number} x - The initial x position of the bottle.
* @param {number} y - The initial y position of the bottle.
* @param {boolean} otherDirektion - If true, the bottle is thrown to the left; otherwise, to the right.
*/
constructor(x, y, otherDirektion) {
super().loadImage("img/6_salsa_bottle/salsa_bottle.png");
this.loadImages(this.IMAGES_ROTATION);
this.loadImages(this.IMAGES_SPLASH);
this.x = x;
this.y = y;
this.height = 60;
this.width = 50;
this.trow(otherDirektion);
this.animate();
}
/**
* Initiates the throwing behavior by setting vertical speed and applying gravity,
* then continuously updates the bottle's movement until it hits the ground.
*
* @param {boolean} otherDirektion - Determines the horizontal direction of the throw.
*/
trow(otherDirektion) {
this.speedY = 30;
this.applyGravity();
this.throwInterval = setInterval(() => {
this.updateThrowMovement(otherDirektion);
}, 25);
}
/**
* Updates the bottle's horizontal movement based on the throw direction.
* Stops the throwing interval and restarts animation when the bottle hits the ground.
*
* @param {boolean} otherDirektion - Determines the horizontal direction of the throw.
*/
updateThrowMovement(otherDirektion) {
if (this.y < 370) {
if (otherDirektion) {
this.x -= 5;
} else {
this.x += 5;
}
} else {
clearInterval(this.throwInterval);
this.animate();
}
}
/**
* Handles the rotation animation while the bottle is in the air.
* Once the bottle lands, triggers the splash animation.
*/
animate() {
if (this.animateInterval) {
return;
}
this.animateInterval = setInterval(() => {
if (this.y >= 370) {
clearInterval(this.animateInterval);
this.animateInterval = null;
this.animateSplash();
} else {
this.playAnimation(this.IMAGES_ROTATION);
}
}, 50);
}
/**
* Plays the splash animation after the bottle hits the ground.
* Once the final frame is reached, marks the bottle as broken.
*/
animateSplash() {
let frameIndex = 0;
let splashInterval = setInterval(() => {
this.playAnimation(this.IMAGES_SPLASH);
frameIndex++;
if (frameIndex >= this.IMAGES_SPLASH.length) {
clearInterval(splashInterval);
this.bottleIsBroken = true;
}
}, 50);
}
/**
* Removes this throwable object from the world's array of throwable objects (if present).
*/
remove() {
const index = this.world.throwableObjects.indexOf(this);
if (index !== -1) {
this.world.throwableObjects.splice(index, 1);
}
}
}