99 lines
2.7 KiB
C++
99 lines
2.7 KiB
C++
#include "ui_message.hpp"
|
|
|
|
#include <cmath> // Para pow
|
|
#include <utility>
|
|
|
|
#include "text.hpp" // Para Text::CENTER, Text::COLOR, Text
|
|
|
|
// Constructor: inicializa el renderizador, el texto y el color del mensaje
|
|
UIMessage::UIMessage(std::shared_ptr<Text> 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;
|
|
} |