#include "scoreboard.h" #include // for SDL_Rect #include // for SDL_GetTicks #include "animated_sprite.h" // for AnimatedSprite #include "asset.h" // for Asset #include "defines.h" // for BLOCK, GAMECANVAS_HEIGHT, PLAY_AREA_HEIGHT #include "options.h" // for Options, options, OptionsVideo, Cheat #include "resource.h" // for Resource #include "screen.h" // for Screen #include "text.h" // for Text #include "texture.h" // for Texture // Constructor Scoreboard::Scoreboard(std::shared_ptr data) : renderer_(Screen::get()->getRenderer()), resource_(Resource::get()), asset_(Asset::get()), data_(data) { // Reserva memoria para los objetos item_texture_ = resource_->getTexture("items.png"); auto player_texture = resource_->getTexture(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png"); auto player_animations = resource_->getAnimations(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani"); player_sprite_ = std::make_shared(player_texture, player_animations); player_sprite_->setCurrentAnimation("walk_menu"); text_ = resource_->getText("smb2"); // Inicializa las variables counter_ = 0; change_color_speed_ = 4; is_paused_ = false; paused_time_ = 0; paused_time_elapsed_ = 0; items_color_ = stringToColor(options.video.palette, "white"); // Inicializa el vector de colores const std::vector vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"}; for (auto v : vColors) { color_.push_back(stringToColor(options.video.palette, v)); } } // Pinta el objeto en pantalla void Scoreboard::render() { // Anclas const int line1 = 19 * BLOCK; const int line2 = line1 + (2 * BLOCK); // Dibuja el fondo del marcador const SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT}; SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255); SDL_RenderFillRect(renderer_, &rect); // Dibuja las vidas const int desp = (counter_ / 40) % 8; const int frame = desp % 4; 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_->getTexture()->setColor(color_[index].r, color_[index].g, color_[index].b); player_sprite_->render(); } // Muestra si suena la música if (data_->music) { const Color c = data_->color; SDL_Rect clip = {0, 8, 8, 8}; item_texture_->setColor(c.r, c.g, c.b); item_texture_->render(20 * BLOCK, line2, &clip); } // Escribe los textos const std::string timeTxt = 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 itemsTxt = std::to_string(data_->items / 100) + std::to_string((data_->items % 100) / 10) + std::to_string(data_->items % 10); this->text_->writeColored(BLOCK, line1, "Items collected ", data_->color); this->text_->writeColored(17 * BLOCK, line1, itemsTxt, items_color_); this->text_->writeColored(20 * BLOCK, line1, " Time ", data_->color); this->text_->writeColored(26 * BLOCK, line1, timeTxt, stringToColor(options.video.palette, "white")); const std::string roomsTxt = std::to_string(data_->rooms / 100) + std::to_string((data_->rooms % 100) / 10) + std::to_string(data_->rooms % 10); this->text_->writeColored(22 * BLOCK, line2, "Rooms", stringToColor(options.video.palette, "white")); this->text_->writeColored(28 * BLOCK, line2, roomsTxt, stringToColor(options.video.palette, "white")); } // Actualiza las variables del objeto void Scoreboard::update() { counter_++; player_sprite_->update(); // Actualiza el color de la cantidad de items recogidos updateItemsColor(); if (!is_paused_) { // Si está en pausa no se actualiza el reloj clock_ = getTime(); } } // Obtiene el tiempo transcurrido de partida Scoreboard::ClockData Scoreboard::getTime() { const Uint32 timeElapsed = SDL_GetTicks() - data_->ini_clock - paused_time_elapsed_; ClockData time; time.hours = timeElapsed / 3600000; time.minutes = timeElapsed / 60000; time.seconds = timeElapsed / 1000; time.separator = (timeElapsed % 1000 <= 500) ? ":" : " "; return time; } // Recarga la textura void Scoreboard::reLoadTexture() { player_sprite_->getTexture()->reLoad(); // playerTexture->reLoad(); item_texture_->reLoad(); text_->reLoadTexture(); } // Recarga la paleta void Scoreboard::reLoadPalette() { // Reinicia el vector de colores const std::vector vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"}; color_.clear(); for (auto v : vColors) { color_.push_back(stringToColor(options.video.palette, v)); } } // Pone el marcador en modo pausa void Scoreboard::pause() { is_paused_ = true; paused_time_ = SDL_GetTicks(); } // Quita el modo pausa del marcador void Scoreboard::resume() { is_paused_ = false; paused_time_elapsed_ += SDL_GetTicks() - paused_time_; } // Actualiza el color de la cantidad de items recogidos void Scoreboard::updateItemsColor() { if (!data_->jail_is_open) { return; } if (counter_ % 20 < 10) { items_color_ = stringToColor(options.video.palette, "white"); } else { items_color_ = stringToColor(options.video.palette, "magenta"); } } // Devuelve la cantidad de minutos de juego transcurridos int Scoreboard::getMinutes() { return getTime().minutes; }