#include "item.h" #include // Para rand #include // Para clamp #include "animated_sprite.h" // Para AnimatedSprite #include "param.h" // Para Param, ParamGame, param class Texture; // lines 6-6 Item::Item(ItemType type, float x, float y, SDL_Rect &play_area, std::shared_ptr texture, const std::vector &animation) : sprite_(std::make_unique(texture, animation)), type_(type), play_area_(play_area) { switch (type) { case ItemType::COFFEE_MACHINE: { width_ = param.game.coffee_machine_w; height_ = param.game.coffee_machine_h; pos_x_ = ((static_cast(x) + (play_area.w / 2)) % (play_area.w - width_ - 5)) + 2; pos_y_ = y; vel_x_ = 0.0f; vel_y_ = -0.1f; accel_y_ = 0.1f; collider_.r = 10; break; } default: { width_ = param.game.item_size; height_ = param.game.item_size; 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; break; } } // Actualiza el sprite shiftSprite(); shiftColliders(); } void Item::alignTo(int x) { const float min_x = param.game.play_area.rect.x + 1; const float max_x = play_area_.w - width_ - 1; pos_x_ = x - (width_ / 2); // Ajusta para que no quede fuera de la zona de juego pos_x_ = std::clamp(pos_x_, min_x, max_x); // Actualiza el sprite shiftSprite(); shiftColliders(); } void Item::render() { if (enabled_) { if (time_to_live_ > 200) { sprite_->render(); } else if (time_to_live_ % 20 > 10) { sprite_->render(); } } } 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_; // Comprueba los laterales de la zona de juego const float min_x = param.game.play_area.rect.x; const float max_x = play_area_.w - width_; pos_x_ = std::clamp(pos_x_, min_x, max_x); // Si toca el borde lateral, invierte la velocidad horizontal if (pos_x_ == min_x || pos_x_ == max_x) { vel_x_ = -vel_x_; } // Si colisiona por arriba, rebota (excepto la máquina de café) if ((pos_y_ < param.game.play_area.rect.y) && !(type_ == ItemType::COFFEE_MACHINE)) { // Corrige pos_y_ = param.game.play_area.rect.y; // Invierte la velocidad vel_y_ = -vel_y_; } // Si colisiona con la parte inferior if (pos_y_ > play_area_.h - height_) { // Corrige la posición pos_y_ = play_area_.h - height_; if (type_ == ItemType::COFFEE_MACHINE) { // Si es una máquina de café, detiene el objeto vel_y_ = vel_x_ = accel_x_ = accel_y_ = 0; floor_collision_ = true; } else { // Si no es una máquina de café if (vel_y_ < 1.0f) { // Si la velocidad vertical es baja, detiene el objeto vel_y_ = vel_x_ = accel_x_ = accel_y_ = 0; } else { // Si la velocidad vertical es alta, el objeto rebota y pierde velocidad vel_y_ *= -0.5f; vel_x_ *= 0.75f; } } } // Actualiza la posición del sprite shiftSprite(); shiftColliders(); } void Item::disable() { enabled_ = false; } void Item::update() { move(); sprite_->update(); updateTimeToLive(); } void Item::updateTimeToLive() { if (time_to_live_ > 0) { time_to_live_--; } else { disable(); } } void Item::shiftColliders() { collider_.x = static_cast(pos_x_ + (width_ / 2)); collider_.y = static_cast(pos_y_ + (height_ / 2)); } void Item::shiftSprite() { sprite_->setPosX(pos_x_); sprite_->setPosY(pos_y_); }