#include "hiscore_table.h" #include // para SDL_BLENDMODE_BLEND #include // para SDL_PollEvent, SDL_Event, SDL_QUIT #include // para SDL_PIXELFORMAT_RGBA8888 #include // para SDL_GetTicks #include // para SDL_WINDOWEVENT_SIZE_CHANGED #include // para max #include // para vector #include "asset.h" // para Asset #include "background.h" // para Background #include "fade.h" // para Fade, FadeMode, FadeType #include "global_inputs.h" // para check #include "input.h" // para Input #include "jail_audio.h" // para JA_GetMusicState, JA_Music_state #include "lang.h" // para getText #include "options.h" // para options #include "param.h" // para param #include "resource.h" // para Resource #include "screen.h" // para Screen #include "section.h" // para Name, name, Options, options #include "text.h" // para Text, TEXT_CENTER, TEXT_SHADOW, TEXT... #include "utils.h" // para Param, ParamGame, Color, HiScoreEntry // Constructor HiScoreTable::HiScoreTable() : renderer_(Screen::get()->getRenderer()), backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), fade_(std::make_unique()), background_(std::make_unique()), text_(std::make_unique(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"))), counter_(0), ticks_(0), view_area_({0, 0, param.game.width, param.game.height}), fade_mode_(FadeMode::IN) { // Inicializa el resto de variables section::name = section::Name::HI_SCORE_TABLE; // Inicializa objetos SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND); background_->setPos(param.game.game_area.rect); background_->setCloudsSpeed(-0.1f); background_->setGradientNumber(1); background_->setTransition(0.8f); fade_->setColor(fade_color.r, fade_color.g, fade_color.b); fade_->setType(FadeType::RANDOM_SQUARE); fade_->setPost(param.fade.post_duration); fade_->setMode(fade_mode_); fade_->activate(); // Crea el contenido de la textura con la lista de puntuaciones fillTexture(); } // Destructor HiScoreTable::~HiScoreTable() { SDL_DestroyTexture(backbuffer_); } // Actualiza las variables void HiScoreTable::update() { constexpr int TICKS_SPEED = 15; if (SDL_GetTicks() - ticks_ > TICKS_SPEED) { // Actualiza el contador de ticks ticks_ = SDL_GetTicks(); // Mantiene la música sonando if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED)) { JA_PlayMusic(Resource::get()->getMusic("title.ogg")); } // Actualiza el objeto screen Screen::get()->update(); // Actualiza el fondo background_->update(); // Gestiona el fade updateFade(); // Gestiona el contador y sus eventos counter_++; if (counter_ == 150) { background_->setColor(Color(0, 0, 0)); background_->setAlpha(96); } if (counter_ == COUNTER_END_) { fade_->activate(); } } } // Crea el contenido de la textura con la lista de puntuaciones void HiScoreTable::fillTexture() { // hay 27 letras - 7 de puntos quedan 20 caracteres 20 - name_lenght 0 num_dots constexpr auto max_names = 10; constexpr auto space_between_header = 32; const auto space_between_lines = text_->getCharacterSize() * 2.0f; const auto size = space_between_header + space_between_lines * (max_names - 1) + text_->getCharacterSize(); const auto first_line = (param.game.height - size) / 2; // Pinta en el backbuffer el texto y los sprites auto temp = SDL_GetRenderTarget(renderer_); SDL_SetRenderTarget(renderer_, backbuffer_); SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0); SDL_RenderClear(renderer_); // Escribe el texto: Mejores puntuaciones text_->writeDX(TEXT_CENTER | TEXT_COLOR | TEXT_SHADOW, param.game.game_area.center_x, first_line, lang::getText(42), 1, orange_color, 1, shdw_txt_color); // Escribe los nombres de la tabla de puntuaciones for (int i = 0; i < max_names; ++i) { const auto name_lenght = options.game.hi_score_table[i].name.length(); const auto score = format(options.game.hi_score_table[i].score); const auto score_lenght = score.size(); const auto num_dots = 25 - name_lenght - score_lenght; std::string dots; for (int j = 0; j < (int)num_dots; ++j) { dots = dots + "."; } const auto line = options.game.hi_score_table[i].name + dots + score; text_->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, (i * space_between_lines) + first_line + space_between_header, line, 1, orange_color, 1, shdw_txt_color); } // Cambia el destino de renderizado SDL_SetRenderTarget(renderer_, temp); } // Pinta en pantalla void HiScoreTable::render() { // Prepara para empezar a dibujar en la textura de juego Screen::get()->start(); // Limpia la pantalla Screen::get()->clean(bg_color); // Pinta el fondo background_->render(); // Establece la ventana del backbuffer view_area_.y = std::max(0, param.game.height - counter_ + 100); // Copia el backbuffer al renderizador SDL_RenderCopy(renderer_, backbuffer_, nullptr, &view_area_); // Renderiza el fade fade_->render(); // Vuelca el contenido del renderizador en pantalla Screen::get()->blit(); } // Recarga todas las texturas void HiScoreTable::reloadTextures() { text_->reLoadTexture(); fillTexture(); } // Comprueba los eventos void HiScoreTable::checkEvents() { // Comprueba los eventos que hay en la cola SDL_Event event; while (SDL_PollEvent(&event)) { // Evento de salida de la aplicación if (event.type == SDL_QUIT) { section::name = section::Name::QUIT; section::options = section::Options::QUIT_FROM_EVENT; break; } // Comprueba si se ha cambiado el tamaño de la ventana else if (event.type == SDL_WINDOWEVENT) { if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { reloadTextures(); } } } } // Comprueba las entradas void HiScoreTable::checkInput() { // Comprueba si se ha pulsado cualquier botón (de los usados para jugar) if (Input::get()->checkAnyButtonPressed()) { JA_StopMusic(); section::name = section::Name::TITLE; section::options = section::Options::TITLE_1; return; } // Comprueba el input para el resto de objetos Screen::get()->checkInput(); // Comprueba los inputs que se pueden introducir en cualquier sección del juego globalInputs::check(); } // Bucle para la pantalla de instrucciones void HiScoreTable::run() { while (section::name == section::Name::HI_SCORE_TABLE) { checkInput(); update(); checkEvents(); // Tiene que ir antes del render render(); } } // Gestiona el fade void HiScoreTable::updateFade() { fade_->update(); if (fade_->hasEnded() && fade_mode_ == FadeMode::IN) { fade_->reset(); fade_mode_ = FadeMode::OUT; fade_->setMode(fade_mode_); } if (fade_->hasEnded() && fade_mode_ == FadeMode::OUT) { section::name = section::Name::INSTRUCTIONS; } } // Convierte un entero a un string con separadores de miles std::string HiScoreTable::format(int number) { const std::string separator = "."; const std::string score = std::to_string(number); auto index = (int)score.size() - 1; std::string result; auto i = 0; while (index >= 0) { result = score.at(index) + result; index--; i++; if (i == 3) { i = 0; result = separator + result; } } return result; }