155 lines
5.9 KiB
C++
155 lines
5.9 KiB
C++
#include "game/gameplay/scoreboard.hpp"
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include <utility>
|
|
|
|
#include "core/rendering/screen.hpp" // Para Screen
|
|
#include "core/rendering/surface.hpp" // Para Surface
|
|
#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite
|
|
#include "core/rendering/text.hpp" // Para Text
|
|
#include "core/resources/resource_cache.hpp" // Para Resource
|
|
#include "game/options.hpp" // Para Options, options, Cheat, OptionsGame
|
|
#include "utils/defines.hpp" // Para BLOCK
|
|
#include "utils/utils.hpp" // Para stringToColor
|
|
|
|
// Constructor
|
|
Scoreboard::Scoreboard(std::shared_ptr<Data> data)
|
|
: item_surface_(Resource::Cache::get()->getSurface("items.gif")),
|
|
data_(std::move(std::move(data))) {
|
|
constexpr float SURFACE_WIDTH = ScoreboardArea::WIDTH;
|
|
constexpr float SURFACE_HEIGHT = ScoreboardArea::HEIGHT;
|
|
|
|
// Reserva memoria para los objetos
|
|
const auto& player_animation_data = Resource::Cache::get()->getAnimationData(Options::cheats.alternate_skin == Options::Cheat::State::ENABLED ? "player2.yaml" : "player.yaml");
|
|
player_sprite_ = std::make_shared<SurfaceAnimatedSprite>(player_animation_data);
|
|
player_sprite_->setCurrentAnimation("walk_menu");
|
|
|
|
surface_ = std::make_shared<Surface>(SURFACE_WIDTH, SURFACE_HEIGHT);
|
|
surface_dest_ = {.x = ScoreboardArea::X, .y = ScoreboardArea::Y, .w = SURFACE_WIDTH, .h = SURFACE_HEIGHT};
|
|
|
|
// Inicializa el color de items
|
|
items_color_ = stringToColor("white");
|
|
|
|
// Inicializa el vector de colores
|
|
const std::vector<std::string> COLORS = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
|
|
for (const auto& color : COLORS) {
|
|
color_.push_back(stringToColor(color));
|
|
}
|
|
}
|
|
|
|
// Pinta el objeto en pantalla
|
|
void Scoreboard::render() {
|
|
surface_->render(nullptr, &surface_dest_);
|
|
}
|
|
|
|
// Actualiza las variables del objeto
|
|
void Scoreboard::update(float delta_time) {
|
|
// Acumular tiempo para animaciones
|
|
time_accumulator_ += delta_time;
|
|
|
|
// Actualizar sprite con delta time
|
|
player_sprite_->update(delta_time);
|
|
|
|
// Actualiza el color de la cantidad de items recogidos
|
|
updateItemsColor(delta_time);
|
|
|
|
// Dibuja la textura
|
|
fillTexture();
|
|
|
|
if (!is_paused_) {
|
|
// Si está en pausa no se actualiza el reloj
|
|
clock_ = getTime();
|
|
}
|
|
}
|
|
|
|
// Obtiene el tiempo transcurrido de partida
|
|
auto Scoreboard::getTime() -> Scoreboard::ClockData {
|
|
const Uint32 TIME_ELAPSED = SDL_GetTicks() - data_->ini_clock - paused_time_elapsed_;
|
|
|
|
ClockData time;
|
|
time.hours = TIME_ELAPSED / 3600000;
|
|
time.minutes = TIME_ELAPSED / 60000;
|
|
time.seconds = TIME_ELAPSED / 1000;
|
|
time.separator = (TIME_ELAPSED % 1000 <= 500) ? ":" : " ";
|
|
|
|
return time;
|
|
}
|
|
|
|
// Pone el marcador en modo pausa
|
|
void Scoreboard::setPaused(bool value) {
|
|
if (is_paused_ == value) {
|
|
// Evita ejecutar lógica si el estado no cambia
|
|
return;
|
|
}
|
|
|
|
is_paused_ = value;
|
|
|
|
if (is_paused_) {
|
|
// Guarda el tiempo actual al pausar
|
|
paused_time_ = SDL_GetTicks();
|
|
} else {
|
|
// Calcula el tiempo pausado acumulado al reanudar
|
|
paused_time_elapsed_ += SDL_GetTicks() - paused_time_;
|
|
}
|
|
}
|
|
|
|
// Actualiza el color de la cantidad de items recogidos
|
|
void Scoreboard::updateItemsColor(float delta_time) {
|
|
// No hay animación de color de items en este juego
|
|
items_color_ = stringToColor("white");
|
|
}
|
|
|
|
// Devuelve la cantidad de minutos de juego transcurridos
|
|
auto Scoreboard::getMinutes() -> int {
|
|
return getTime().minutes;
|
|
}
|
|
|
|
// Dibuja los elementos del marcador en la textura
|
|
void Scoreboard::fillTexture() {
|
|
// Empieza a dibujar en la textura
|
|
auto previuos_renderer = Screen::get()->getRendererSurface();
|
|
Screen::get()->setRendererSurface(surface_);
|
|
|
|
// Limpia la textura
|
|
surface_->clear(stringToColor("black"));
|
|
|
|
// Anclas
|
|
constexpr int LINE1 = Tile::SIZE;
|
|
constexpr int LINE2 = 3 * Tile::SIZE;
|
|
|
|
// Dibuja las vidas
|
|
// Calcular desplazamiento basado en tiempo
|
|
const int DESP = static_cast<int>(time_accumulator_ / SPRITE_WALK_CYCLE_DURATION) % 8;
|
|
const int FRAME = DESP % SPRITE_WALK_FRAMES;
|
|
player_sprite_->setCurrentAnimationFrame(FRAME);
|
|
player_sprite_->setPosY(LINE2);
|
|
for (int i = 0; i < data_->lives; ++i) {
|
|
player_sprite_->setPosX(8 + (16 * i) + DESP);
|
|
const int INDEX = i % color_.size();
|
|
player_sprite_->render(4, color_.at(INDEX));
|
|
}
|
|
|
|
// Muestra si suena la música
|
|
if (data_->music) {
|
|
const Uint8 C = data_->color;
|
|
SDL_FRect clip = {0, 8, 8, 8};
|
|
item_surface_->renderWithColorReplace(20 * Tile::SIZE, LINE2, 1, C, &clip);
|
|
}
|
|
|
|
// Escribe los textos
|
|
auto text = Resource::Cache::get()->getText("smb2");
|
|
const std::string TIME_TEXT = std::to_string((clock_.minutes % 100) / 10) + std::to_string(clock_.minutes % 10) + clock_.separator + std::to_string((clock_.seconds % 60) / 10) + std::to_string(clock_.seconds % 10);
|
|
const std::string ITEMS_TEXT = std::to_string(data_->items / 100) + std::to_string((data_->items % 100) / 10) + std::to_string(data_->items % 10);
|
|
text->writeColored(Tile::SIZE, LINE1, "Items collected ", data_->color);
|
|
text->writeColored(17 * Tile::SIZE, LINE1, ITEMS_TEXT, items_color_);
|
|
text->writeColored(20 * Tile::SIZE, LINE1, " Time ", data_->color);
|
|
text->writeColored(26 * Tile::SIZE, LINE1, TIME_TEXT, stringToColor("white"));
|
|
|
|
const std::string ROOMS_TEXT = std::to_string(data_->rooms / 100) + std::to_string((data_->rooms % 100) / 10) + std::to_string(data_->rooms % 10);
|
|
text->writeColored(22 * Tile::SIZE, LINE2, "Rooms", stringToColor("white"));
|
|
text->writeColored(28 * Tile::SIZE, LINE2, ROOMS_TEXT, stringToColor("white"));
|
|
|
|
// Deja el renderizador como estaba
|
|
Screen::get()->setRendererSurface(previuos_renderer);
|
|
} |