treballant en el overlay, el text i les notificacions
This commit is contained in:
119
source/core/rendering/overlay.cpp
Normal file
119
source/core/rendering/overlay.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#include "core/rendering/overlay.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "core/rendering/text.hpp"
|
||||
|
||||
namespace Overlay {
|
||||
|
||||
static std::unique_ptr<Text> font_;
|
||||
|
||||
// --- Notificacions amb animació ---
|
||||
|
||||
enum class Status { RISING, STAY, VANISHING, FINISHED };
|
||||
|
||||
struct Notification {
|
||||
std::string message;
|
||||
Status status{Status::RISING};
|
||||
float y_offset{0.0F}; // 0 = fora de pantalla, 1 = posició final
|
||||
float timer{0.0F};
|
||||
float duration{2.0F};
|
||||
};
|
||||
|
||||
static std::vector<Notification> notifications_;
|
||||
static Uint32 last_ticks_ = 0;
|
||||
|
||||
static constexpr float SLIDE_SPEED = 4.0F; // velocitat d'animació (unitats/segon)
|
||||
static constexpr int BAR_HEIGHT = 12; // alçada de la barra
|
||||
static constexpr int TEXT_Y_OFFSET = 2; // offset del text dins la barra
|
||||
static constexpr Uint32 BG_COLOR = 0xFF1A1A2E; // fons blau fosc
|
||||
static constexpr Uint32 TEXT_COLOR = 0xFF00FFFF; // cyan
|
||||
static constexpr int SCREEN_W = 320;
|
||||
static constexpr int SCREEN_H = 200;
|
||||
|
||||
void init() {
|
||||
font_ = std::make_unique<Text>("fonts/8bithud.fnt", "fonts/8bithud.gif");
|
||||
last_ticks_ = SDL_GetTicks();
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
font_.reset();
|
||||
notifications_.clear();
|
||||
}
|
||||
|
||||
static void drawBar(Uint32* pixel_data, int y, int h, Uint32 color) {
|
||||
for (int row = y; row < y + h; row++) {
|
||||
if (row < 0 || row >= SCREEN_H) continue;
|
||||
for (int col = 0; col < SCREEN_W; col++) {
|
||||
pixel_data[col + row * SCREEN_W] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void render(Uint32* pixel_data) {
|
||||
if (!font_ || !pixel_data) return;
|
||||
|
||||
// Calcula delta time
|
||||
Uint32 now = SDL_GetTicks();
|
||||
float dt = static_cast<float>(now - last_ticks_) / 1000.0F;
|
||||
last_ticks_ = now;
|
||||
|
||||
// Actualitza i pinta cada notificació
|
||||
for (auto& notif : notifications_) {
|
||||
switch (notif.status) {
|
||||
case Status::RISING:
|
||||
notif.y_offset += SLIDE_SPEED * dt;
|
||||
if (notif.y_offset >= 1.0F) {
|
||||
notif.y_offset = 1.0F;
|
||||
notif.status = Status::STAY;
|
||||
notif.timer = 0.0F;
|
||||
}
|
||||
break;
|
||||
|
||||
case Status::STAY:
|
||||
notif.timer += dt;
|
||||
if (notif.timer >= notif.duration) {
|
||||
notif.status = Status::VANISHING;
|
||||
}
|
||||
break;
|
||||
|
||||
case Status::VANISHING:
|
||||
notif.y_offset -= SLIDE_SPEED * dt;
|
||||
if (notif.y_offset <= 0.0F) {
|
||||
notif.status = Status::FINISHED;
|
||||
}
|
||||
break;
|
||||
|
||||
case Status::FINISHED:
|
||||
break;
|
||||
}
|
||||
|
||||
if (notif.status == Status::FINISHED) continue;
|
||||
|
||||
// Posició: puja des de sota la pantalla
|
||||
int bar_y = SCREEN_H - static_cast<int>(notif.y_offset * BAR_HEIGHT);
|
||||
|
||||
// Pinta fons
|
||||
drawBar(pixel_data, bar_y, BAR_HEIGHT, BG_COLOR);
|
||||
|
||||
// Pinta text centrat
|
||||
font_->drawCentered(pixel_data, bar_y + TEXT_Y_OFFSET, notif.message.c_str(), TEXT_COLOR);
|
||||
}
|
||||
|
||||
// Elimina les acabades
|
||||
notifications_.erase(
|
||||
std::remove_if(notifications_.begin(), notifications_.end(),
|
||||
[](const Notification& n) { return n.status == Status::FINISHED; }),
|
||||
notifications_.end());
|
||||
}
|
||||
|
||||
void showNotification(const char* text, float duration_seconds) {
|
||||
// Si ja hi ha una notificació, la reemplaça (no apilem)
|
||||
notifications_.clear();
|
||||
notifications_.push_back({text, Status::RISING, 0.0F, 0.0F, duration_seconds});
|
||||
}
|
||||
|
||||
} // namespace Overlay
|
||||
Reference in New Issue
Block a user