#include "ui_message.h" #include // Para pow #include #include "text.h" // Para Text::CENTER, Text::COLOR, Text // Constructor: inicializa el renderizador, el texto y el color del mensaje UIMessage::UIMessage(std::shared_ptr text_renderer, std::string message_text, const Color &color) : text_renderer_(std::move(text_renderer)), text_(std::move(message_text)), color_(color) {} // Muestra el mensaje en la posición base_x, base_y con animación de entrada desde arriba void UIMessage::show() { if (visible_ && target_y_ == 0.0F) { return; // Ya está visible y quieto } start_y_ = DESP; // Empieza 8 píxeles arriba de la posición base target_y_ = 0.0F; // La posición final es la base y_offset_ = start_y_; animation_timer_ = 0.0f; animating_ = true; visible_ = true; } // Oculta el mensaje con animación de salida hacia arriba void UIMessage::hide() { if (!visible_) { return; } start_y_ = y_offset_; // Comienza desde la posición actual target_y_ = DESP; // Termina 8 píxeles arriba de la base animation_timer_ = 0.0f; animating_ = true; } // Actualiza el estado de la animación (debe llamarse cada frame) void UIMessage::update(float delta_time) { if (animating_) { updateAnimation(delta_time); } } // Interpola la posición vertical del mensaje usando ease out cubic void UIMessage::updateAnimation(float delta_time) { animation_timer_ += delta_time; float t = animation_timer_ / ANIMATION_DURATION_S; // Clamp t entre 0 y 1 if (t > 1.0f) { t = 1.0f; } if (target_y_ > start_y_) { // Animación de entrada (ease out cubic) t = 1 - pow(1 - t, 3); } else { // Animación de salida (ease in cubic) t = pow(t, 3); } y_offset_ = start_y_ + (target_y_ - start_y_) * t; if (animation_timer_ >= ANIMATION_DURATION_S) { y_offset_ = target_y_; animating_ = false; animation_timer_ = 0.0f; // Reset timer if (target_y_ < 0.0F) { visible_ = false; } } } // Dibuja el mensaje en pantalla si está visible void UIMessage::render() { if (visible_) { text_renderer_->writeDX( Text::COLOR | Text::CENTER, base_x_, base_y_ + y_offset_, text_, -2, color_); } } // Devuelve true si el mensaje está visible actualmente auto UIMessage::isVisible() const -> bool { return visible_; } // Permite actualizar la posición del mensaje (por ejemplo, si el menú se mueve) void UIMessage::setPosition(float new_base_x, float new_base_y) { base_x_ = new_base_x; base_y_ = new_base_y; }