#include "game/entities/item.h" #include // for rand #include "core/rendering/animatedsprite.h" // for AnimatedSprite #include "game/defaults.hpp" // for PLAY_AREA_LEFT, PLAY_AREA_RIGHT, PLAY_AR... class Texture; // Constructor Item::Item(Id id, float x, float y, Texture *texture, const std::vector *animation, SDL_Renderer *renderer) { sprite_ = new AnimatedSprite(texture, renderer, "", animation); this->id_ = id; enabled_ = true; time_to_live_ = 600; accel_x_ = 0.0F; floor_collision_ = false; if (id == Item::Id::COFFEE_MACHINE) { width_ = 23; height_ = 29; pos_x_ = (((int)x + (PLAY_AREA_WIDTH / 2)) % (PLAY_AREA_WIDTH - width_ - 5)) + 2; pos_y_ = PLAY_AREA_TOP - height_; vel_x_ = 0.0F; vel_y_ = -0.1F; accel_y_ = 0.1F; collider_.r = 10; } else { width_ = 16; height_ = 16; pos_x_ = x; pos_y_ = y; vel_x_ = -1.0F + ((rand() % 5) * 0.5F); vel_y_ = -4.0F; accel_y_ = 0.2F; collider_.r = width_ / 2; } sprite_->setPosX(pos_x_); sprite_->setPosY(pos_y_); shiftColliders(); } // Destructor Item::~Item() { delete sprite_; } // Centra el objeto en la posición X void Item::allignTo(int x) { pos_x_ = float(x - (width_ / 2)); if (pos_x_ < PLAY_AREA_LEFT) { pos_x_ = PLAY_AREA_LEFT + 1; } else if ((pos_x_ + width_) > PLAY_AREA_RIGHT) { pos_x_ = float(PLAY_AREA_RIGHT - width_ - 1); } // Posición X,Y del sprite sprite_->setPosX(int(pos_x_)); sprite_->setPosY(int(pos_y_)); // Alinea el circulo de colisión con el objeto shiftColliders(); } // Pinta el objeto en la pantalla void Item::render() { // Mentre quede temps de sobra (>200) es renderitza sempre; quan està a // punt d'expirar, parpalleja alternant 10 frames visibles i 10 invisibles. if (enabled_ && (time_to_live_ > 200 || time_to_live_ % 20 > 10)) { sprite_->render(); } } // Actualiza la posición y estados del objeto void Item::move() { floor_collision_ = false; // Calcula la nueva posición pos_x_ += vel_x_; pos_y_ += vel_y_; // Aplica las aceleraciones a la velocidad vel_x_ += accel_x_; vel_y_ += accel_y_; // Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido if ((pos_x_ < PLAY_AREA_LEFT) || (pos_x_ + width_ > PLAY_AREA_RIGHT)) { // Corregir posición pos_x_ -= vel_x_; // Invertir sentido vel_x_ = -vel_x_; } // Si se sale por arriba rebota (excepto la maquina de café) if ((pos_y_ < PLAY_AREA_TOP) && !(id_ == Item::Id::COFFEE_MACHINE)) { // Corrige pos_y_ -= vel_y_; // Invierte el sentido vel_y_ = -vel_y_; } // Si el objeto se sale por la parte inferior if (pos_y_ + height_ > PLAY_AREA_BOTTOM) { // Detiene el objeto vel_y_ = 0; vel_x_ = 0; accel_x_ = 0; accel_y_ = 0; pos_y_ = PLAY_AREA_BOTTOM - height_; if (id_ == Item::Id::COFFEE_MACHINE) { floor_collision_ = true; } } // Actualiza la posición del sprite sprite_->setPosX(int(pos_x_)); sprite_->setPosY(int(pos_y_)); shiftColliders(); } // Pone a cero todos los valores del objeto void Item::disable() { enabled_ = false; } // Actualiza el objeto a su posicion, animación y controla los contadores void Item::update() { move(); sprite_->animate(); updateTimeToLive(); checkTimeToLive(); } // Actualiza el contador void Item::updateTimeToLive() { if (time_to_live_ > 0) { time_to_live_--; } } // Comprueba si el objeto sigue vivo void Item::checkTimeToLive() { if (time_to_live_ == 0) { disable(); } } // Obtiene del valor de la variable auto Item::getPosX() const -> float { return pos_x_; } // Obtiene del valor de la variable auto Item::getPosY() const -> float { return pos_y_; } // Obtiene del valor de la variable auto Item::getWidth() const -> int { return width_; } // Obtiene del valor de la variable auto Item::getHeight() const -> int { return height_; } // Obtiene del valor de la variable auto Item::getId() const -> Id { return id_; } // Obtiene el valor de la variable auto Item::isEnabled() const -> bool { return enabled_; } // Obtiene el circulo de colisión auto Item::getCollider() -> Circle & { return collider_; } // Alinea el circulo de colisión con la posición del objeto void Item::shiftColliders() { collider_.x = int(pos_x_ + (width_ / 2)); collider_.y = int(pos_y_ + (height_ / 2)); } // Informa si el objeto ha colisionado con el suelo auto Item::isOnFloor() const -> bool { return floor_collision_; }