diff --git a/source/director.cpp b/source/director.cpp index d335afe..9bcaf13 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -30,6 +30,7 @@ #include "lang.h" // for Code, loadFromFile #include "logo.h" // for Logo #include "manage_hiscore_table.h" // for ManageHiScoreTable +#include "notifier.h" // for Notifier #include "on_screen_help.h" // for OnScreenHelp #include "options.h" // for options, loadOptionsFile, saveO... #include "param.h" // for param, loadParamsFromFile @@ -102,6 +103,8 @@ Director::Director(int argc, const char *argv[]) Screen::init(window_, renderer_); + Notifier::init(renderer_, std::string(), Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), Asset::get()->get("notify.wav")); + OnScreenHelp::init(); // Carga los sonidos del juego @@ -120,6 +123,7 @@ Director::~Director() Asset::destroy(); Input::destroy(); Screen::destroy(); + Notifier::destroy(); OnScreenHelp::destroy(); sounds_.clear(); diff --git a/source/game.cpp b/source/game.cpp index 59aeeba..48a73e1 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -25,6 +25,7 @@ #include "jail_audio.h" // for JA_PlaySound, JA_DeleteSound, JA_L... #include "lang.h" // for getText #include "manage_hiscore_table.h" // for ManageHiScoreTable +#include "notifier.h" // for Notifier #include "options.h" // for options #include "param.h" // for param #include "player.h" // for Player, PlayerStatus @@ -2404,7 +2405,7 @@ void Game::checkEvents() case SDLK_3: { auto_pop_balloons_ = !auto_pop_balloons_; - screen_->showNotification("auto_pop_balloons_ " + boolToString(auto_pop_balloons_)); + Notifier::get()->showText("auto_pop_balloons_ " + boolToString(auto_pop_balloons_)); break; } diff --git a/source/global_inputs.cpp b/source/global_inputs.cpp index 403867f..100891d 100644 --- a/source/global_inputs.cpp +++ b/source/global_inputs.cpp @@ -3,6 +3,7 @@ #include "input.h" // for Input, inputs_e, INPUT_DO_NOT_ALLOW_REPEAT #include "jail_audio.h" // for JA_EnableMusic, JA_EnableSound #include "lang.h" // for getText +#include "notifier.h" // for Notifier #include "options.h" // for options #include "on_screen_help.h" #include "screen.h" // for Screen @@ -28,14 +29,14 @@ namespace globalInputs // Termina void quit(section::Options code) { - if (Screen::get()->notificationsAreActive()) + if (Notifier::get()->isActive()) { section::name = section::Name::QUIT; section::options = code; } else { - Screen::get()->showNotification(lang::getText(94)); + Notifier::get()->showText(lang::getText(94)); } } @@ -43,7 +44,7 @@ namespace globalInputs void reset() { section::name = section::Name::INIT; - Screen::get()->showNotification("Reset"); + Notifier::get()->showText("Reset"); } // Activa o desactiva el audio @@ -52,7 +53,7 @@ namespace globalInputs options.audio.sound.enabled = options.audio.music.enabled = !options.audio.music.enabled; JA_EnableMusic(options.audio.music.enabled); JA_EnableSound(options.audio.sound.enabled); - Screen::get()->showNotification("Audio " + boolToOnOff(options.audio.music.enabled)); + Notifier::get()->showText("Audio " + boolToOnOff(options.audio.music.enabled)); } // Comprueba los inputs que se pueden introducir en cualquier sección del juego diff --git a/source/notifier.cpp b/source/notifier.cpp new file mode 100644 index 0000000..b94f4a2 --- /dev/null +++ b/source/notifier.cpp @@ -0,0 +1,341 @@ +#include "notifier.h" +#include // for SDL_BLENDMODE_BLEND +#include // for SDL_PIXELFORMAT_RGBA8888 +#include // for string +#include "jail_audio.h" // for JA_DeleteSound, JA_LoadSound, JA_Pla... +#include "param.h" // for param +#include "sprite.h" // for Sprite +#include "text.h" // for Text +#include "texture.h" // for Texture + +// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado +Notifier *Notifier::notifier_ = nullptr; + +// [SINGLETON] Crearemos el objeto screen con esta función estática +void Notifier::init(SDL_Renderer *renderer, std::string icon_file, std::string bitmap_file, std::string text_file, const std::string &sound_file) +{ + Notifier::notifier_ = new Notifier(renderer, icon_file, bitmap_file, text_file, sound_file); +} + +// [SINGLETON] Destruiremos el objeto screen con esta función estática +void Notifier::destroy() +{ + delete Notifier::notifier_; +} + +// [SINGLETON] Con este método obtenemos el objeto screen y podemos trabajar con él +Notifier *Notifier::get() +{ + return Notifier::notifier_; +} + +// Constructor +Notifier::Notifier(SDL_Renderer *renderer, std::string icon_file, std::string bitmap_file, std::string text_file, const std::string &sound_file) + : renderer_(renderer), + text_(std::make_unique(bitmap_file, text_file, renderer)), + bg_color_(param.notification.color), + wait_time_(150), + stack_(false), + sound_(JA_LoadSound(sound_file.c_str())) +{ + // Inicializa variables + has_icons_ = !icon_file.empty(); + + // Crea objetos + icon_texture_ = has_icons_ ? std::make_unique(renderer, icon_file) : nullptr; +} + +// Destructor +Notifier::~Notifier() +{ + // Libera la memoria de los objetos + JA_DeleteSound(sound_); + + notifications_.clear(); +} + +// Dibuja las notificaciones por pantalla +void Notifier::render() +{ + for (int i = (int)notifications_.size() - 1; i >= 0; --i) + { + notifications_[i].sprite->render(); + } +} + +// Actualiza el estado de las notificaiones +void Notifier::update() +{ + for (int i = 0; i < (int)notifications_.size(); ++i) + { + // Si la notificación anterior está "saliendo", no hagas nada + if (i > 0) + { + if (notifications_[i - 1].status == NotificationStatus::RISING) + { + break; + } + } + + notifications_[i].counter++; + + // Hace sonar la notificación en el primer frame + if (notifications_[i].counter == 1) + { + if (param.notification.sound) + { + if (notifications_[i].status == NotificationStatus::RISING) + { // Reproduce el sonido de la notificación + JA_PlaySound(sound_); + } + } + } + + // Comprueba los estados + if (notifications_[i].status == NotificationStatus::RISING) + { + const float step = ((float)notifications_[i].counter / notifications_[i].travel_dist); + const int alpha = 255 * step; + + if (param.notification.pos_v == NotifyPosition::TOP) + { + notifications_[i].rect.y++; + } + else + { + notifications_[i].rect.y--; + } + notifications_[i].texture->setAlpha(alpha); + + if (notifications_[i].rect.y == notifications_[i].y) + { + notifications_[i].status = NotificationStatus::STAY; + notifications_[i].texture->setAlpha(255); + notifications_[i].counter = 0; + } + } + + else if (notifications_[i].status == NotificationStatus::STAY) + { + if (notifications_[i].counter == wait_time_) + { + notifications_[i].status = NotificationStatus::VANISHING; + notifications_[i].counter = 0; + } + } + else if (notifications_[i].status == NotificationStatus::VANISHING) + { + + const float step = (notifications_[i].counter / (float)notifications_[i].travel_dist); + const int alpha = 255 * (1 - step); + + if (param.notification.pos_v == NotifyPosition::TOP) + { + notifications_[i].rect.y--; + } + else + { + notifications_[i].rect.y++; + } + notifications_[i].texture->setAlpha(alpha); + + if (notifications_[i].rect.y == notifications_[i].y - notifications_[i].travel_dist) + { + notifications_[i].status = NotificationStatus::FINISHED; + } + } + + notifications_[i].sprite->setPos(notifications_[i].rect); + } + + clearFinishedNotifications(); +} + +// Elimina las notificaciones finalizadas +void Notifier::clearFinishedNotifications() +{ + for (int i = (int)notifications_.size() - 1; i >= 0; --i) + { + if (notifications_[i].status == NotificationStatus::FINISHED) + { + notifications_.erase(notifications_.begin() + i); + } + } +} + +void Notifier::showText(std::string text1, std::string text2, int icon, std::string code) +{ + // Cuenta el número de textos a mostrar + const int num_texts = !text1.empty() + !text2.empty(); + + // Si no hay texto, acaba + if (num_texts == 0) + { + return; + } + + // Si solo hay un texto, lo coloca en la primera variable + if (num_texts == 1) + { + text1 += text2; + text2.clear(); + } + + // Si las notificaciones no se apilan, elimina las anteriores + if (!stack_) + { + clearNotifications(); + } + + // Inicializa variables + constexpr auto icon_size = 16; + constexpr auto padding_out = 1; + const auto padding_in = text_->getCharacterSize() / 2; + const auto icon_space = icon >= 0 ? icon_size + padding_in : 0; + const std::string txt = text1.length() > text2.length() ? text1 : text2; + const auto width = text_->lenght(txt) + (padding_in * 2) + icon_space; + const auto height = (text_->getCharacterSize() * num_texts) + (padding_in * 2); + const auto shape = NotificationShape::SQUARED; + + // Posición horizontal + auto desp_h = 0; + if (param.notification.pos_h == NotifyPosition::LEFT) + { + desp_h = padding_out; + } + else if (param.notification.pos_h == NotifyPosition::MIDDLE) + { + desp_h = ((param.game.width / 2) - (width / 2)); + } + else + { + desp_h = param.game.width - width - padding_out; + } + + // Posición vertical + const int desp_v = (param.notification.pos_v == NotifyPosition::TOP) ? padding_out : (param.game.height - height - padding_out); + + // Offset + const auto travel_dist = height + padding_out; + auto offset = 0; + if (param.notification.pos_v == NotifyPosition::TOP) + { + offset = (int)notifications_.size() > 0 ? notifications_.back().y + travel_dist : desp_v; + } + else + { + offset = (int)notifications_.size() > 0 ? notifications_.back().y - travel_dist : desp_v; + } + + // Crea la notificacion + Notification n; + + // Inicializa variables + n.code = code; + n.y = offset; + n.travel_dist = travel_dist; + n.counter = 0; + n.status = NotificationStatus::RISING; + n.text1 = text1; + n.text2 = text2; + n.shape = shape; + auto y_pos = offset + (param.notification.pos_v == NotifyPosition::TOP ? -travel_dist : travel_dist); + n.rect = {desp_h, y_pos, width, height}; + + // Crea la textura + n.texture = std::make_shared(renderer_); + n.texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET); + n.texture->setBlendMode(SDL_BLENDMODE_BLEND); + + // Prepara para dibujar en la textura + n.texture->setAsRenderTarget(renderer_); + + // Dibuja el fondo de la notificación + SDL_SetRenderDrawColor(renderer_, bg_color_.r, bg_color_.g, bg_color_.b, 255); + SDL_Rect rect; + if (shape == NotificationShape::ROUNDED) + { + rect = {4, 0, width - (4 * 2), height}; + SDL_RenderFillRect(renderer_, &rect); + + rect = {4 / 2, 1, width - 4, height - 2}; + SDL_RenderFillRect(renderer_, &rect); + + rect = {1, 4 / 2, width - 2, height - 4}; + SDL_RenderFillRect(renderer_, &rect); + + rect = {0, 4, width, height - (4 * 2)}; + SDL_RenderFillRect(renderer_, &rect); + } + + else if (shape == NotificationShape::SQUARED) + { + SDL_RenderClear(renderer_); + } + + // Dibuja el icono de la notificación + if (has_icons_ && icon >= 0 && num_texts == 2) + { + auto sp = std::make_unique((SDL_Rect){0, 0, icon_size, icon_size}, icon_texture_); + sp->setPos({padding_in, padding_in, icon_size, icon_size}); + sp->setSpriteClip({icon_size * (icon % 10), icon_size * (icon / 10), icon_size, icon_size}); + sp->render(); + } + + // Escribe el texto de la notificación + Color color = {255, 255, 255}; + if (num_texts == 2) + { // Dos lineas de texto + text_->writeColored(padding_in + icon_space, padding_in, text1, color); + text_->writeColored(padding_in + icon_space, padding_in + text_->getCharacterSize() + 1, text2, color); + } + else + { // Una linea de texto + text_->writeColored(padding_in + icon_space, padding_in, text1, color); + } + + // Deja de dibujar en la textura + SDL_SetRenderTarget(renderer_, nullptr); + + // Crea el sprite de la notificación + n.sprite = std::make_shared(n.rect, n.texture); + + // Deja la notificación invisible + n.texture->setAlpha(0); + + // Añade la notificación a la lista + notifications_.push_back(n); +} + +// Indica si hay notificaciones activas +bool Notifier::isActive() +{ + if ((int)notifications_.size() > 0) + { + return true; + } + + return false; +} + +// Finaliza y elimnina todas las notificaciones activas +void Notifier::clearNotifications() +{ + for (int i = 0; i < (int)notifications_.size(); ++i) + { + notifications_[i].status = NotificationStatus::FINISHED; + } + + clearFinishedNotifications(); +} + +// Obtiene los códigos de las notificaciones +std::vector Notifier::getCodes() +{ + std::vector codes; + for (int i = 0; i < (int)notifications_.size(); ++i) + { + codes.push_back(notifications_[i].code); + } + return codes; +} \ No newline at end of file diff --git a/source/notifier.h b/source/notifier.h new file mode 100644 index 0000000..de6216c --- /dev/null +++ b/source/notifier.h @@ -0,0 +1,121 @@ +#pragma once + +#include // for SDL_Rect +#include // for SDL_Renderer +#include // for shared_ptr, unique_ptr +#include // for string, basic_string +#include // for vector +#include "utils.h" // for Color +class Sprite; +class Text; +class Texture; +struct JA_Sound_t; // lines 12-12 + +class Notifier +{ +private: + // [SINGLETON] Objeto notifier privado para Don Melitón + static Notifier *notifier_; + + enum class NotificationStatus + { + RISING, + STAY, + VANISHING, + FINISHED, + }; + + enum class NotificationPosition + { + UPPER_LEFT, + UPPER_CENTER, + UPPER_RIGHT, + MIDDLE_LEFT, + MIDDLE_RIGHT, + BOTTOM_LEFT, + BOTTOM_CENTER, + BOTTOM_RIGHT, + }; + + enum class NotificationShape + { + ROUNDED, + SQUARED, + }; + + struct Notification + { + std::shared_ptr texture; + std::shared_ptr sprite; + std::string text1; + std::string text2; + int counter; + NotificationStatus status; + NotificationPosition position; + NotificationShape shape; + SDL_Rect rect; + int y; + int travel_dist; + std::string code; // Permite asignar un código a la notificación + }; + + // Objetos y punteros + SDL_Renderer *renderer_; // El renderizador de la ventana + + std::shared_ptr icon_texture_; // Textura para los iconos de las notificaciones + std::unique_ptr text_; // Objeto para dibujar texto + + // Variables + Color bg_color_; // Color de fondo de las notificaciones + int wait_time_; // Tiempo que se ve la notificación + std::vector notifications_; // La lista de notificaciones activas + bool stack_; // Indica si las notificaciones se apilan + bool has_icons_; // Indica si el notificador tiene textura para iconos + JA_Sound_t *sound_; // Sonido a reproducir cuando suena la notificación + + // Elimina las notificaciones finalizadas + void clearFinishedNotifications(); + + // Finaliza y elimnina todas las notificaciones activas + void clearNotifications(); + + // [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos notifier desde fuera + + // Constructor + Notifier(SDL_Renderer *renderer, std::string icon_file, std::string bitmap_file, std::string text_file, const std::string &sound_file); + + // Destructor + ~Notifier(); + +public: + // [SINGLETON] Crearemos el objeto notifier con esta función estática + static void init(SDL_Renderer *renderer, std::string icon_file, std::string bitmap_file, std::string text_file, const std::string &sound_file); + + // [SINGLETON] Destruiremos el objeto notifier con esta función estática + static void destroy(); + + // [SINGLETON] Con este método obtenemos el objeto notifier y podemos trabajar con él + static Notifier *get(); + + // Dibuja las notificaciones por pantalla + void render(); + + // Actualiza el estado de las notificaiones + void update(); + + /** + * @brief Muestra una notificación de texto por pantalla. + * + * @param text1 Primer texto opcional para mostrar (valor predeterminado: cadena vacía). + * @param text2 Segundo texto opcional para mostrar (valor predeterminado: cadena vacía). + * @param icon Icono opcional para mostrar (valor predeterminado: -1). + * @param code Permite asignar un código a la notificación (valor predeterminado: cadena vacía). + */ + void showText(std::string text1 = std::string(), std::string text2 = std::string(), int icon = -1, std::string code = std::string()); + + // Indica si hay notificaciones activas + bool isActive(); + + // Obtiene los códigos de las notificaciones + std::vector getCodes(); +}; diff --git a/source/notify.cpp b/source/notify.cpp deleted file mode 100644 index ccb5322..0000000 --- a/source/notify.cpp +++ /dev/null @@ -1,309 +0,0 @@ -#include "notify.h" -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for string -#include "jail_audio.h" // for JA_DeleteSound, JA_LoadSound, JA_Pla... -#include "param.h" // for param -#include "sprite.h" // for Sprite -#include "text.h" // for Text -#include "texture.h" // for Texture - -// Constructor -Notify::Notify(SDL_Renderer *renderer, std::string iconFile, std::string bitmapFile, std::string textFile, const std::string &soundFile) - : renderer(renderer), - text(std::make_unique(bitmapFile, textFile, renderer)), - bgColor(param.notification.color), - waitTime(150), - stack(false), - sound(JA_LoadSound(soundFile.c_str())) -{ - // Inicializa variables - hasIcons = !iconFile.empty(); - - // Crea objetos - iconTexture = hasIcons ? std::make_unique(renderer, iconFile) : nullptr; -} - -// Destructor -Notify::~Notify() -{ - // Libera la memoria de los objetos - JA_DeleteSound(sound); - - notifications.clear(); -} - -// Dibuja las notificaciones por pantalla -void Notify::render() -{ - for (int i = (int)notifications.size() - 1; i >= 0; --i) - { - notifications[i].sprite->render(); - } -} - -// Actualiza el estado de las notificaiones -void Notify::update() -{ - for (int i = 0; i < (int)notifications.size(); ++i) - { - // Si la notificación anterior está "saliendo", no hagas nada - if (i > 0) - { - if (notifications[i - 1].status == NotificationStatus::RISING) - { - break; - } - } - - notifications[i].counter++; - - // Hace sonar la notificación en el primer frame - if (notifications[i].counter == 1) - { - if (param.notification.sound) - { - if (notifications[i].status == NotificationStatus::RISING) - { // Reproduce el sonido de la notificación - JA_PlaySound(sound); - } - } - } - - // Comprueba los estados - if (notifications[i].status == NotificationStatus::RISING) - { - const float step = ((float)notifications[i].counter / notifications[i].travelDist); - const int alpha = 255 * step; - - if (param.notification.pos_v == NotifyPosition::TOP) - { - notifications[i].rect.y++; - } - else - { - notifications[i].rect.y--; - } - notifications[i].texture->setAlpha(alpha); - - if (notifications[i].rect.y == notifications[i].y) - { - notifications[i].status = NotificationStatus::STAY; - notifications[i].texture->setAlpha(255); - notifications[i].counter = 0; - } - } - - else if (notifications[i].status == NotificationStatus::STAY) - { - if (notifications[i].counter == waitTime) - { - notifications[i].status = NotificationStatus::VANISHING; - notifications[i].counter = 0; - } - } - else if (notifications[i].status == NotificationStatus::VANISHING) - { - - const float step = (notifications[i].counter / (float)notifications[i].travelDist); - const int alpha = 255 * (1 - step); - - if (param.notification.pos_v == NotifyPosition::TOP) - { - notifications[i].rect.y--; - } - else - { - notifications[i].rect.y++; - } - notifications[i].texture->setAlpha(alpha); - - if (notifications[i].rect.y == notifications[i].y - notifications[i].travelDist) - { - notifications[i].status = NotificationStatus::FINISHED; - } - } - - notifications[i].sprite->setPos(notifications[i].rect); - } - - clearFinishedNotifications(); -} - -// Elimina las notificaciones finalizadas -void Notify::clearFinishedNotifications() -{ - for (int i = (int)notifications.size() - 1; i >= 0; --i) - { - if (notifications[i].status == NotificationStatus::FINISHED) - { - notifications.erase(notifications.begin() + i); - } - } -} - -// Muestra una notificación de texto por pantalla; -void Notify::showText(std::string text1, std::string text2, int icon) -{ - // Cuenta el número de textos a mostrar - const int numTexts = !text1.empty() + !text2.empty(); - - // Si no hay texto, acaba - if (numTexts == 0) - { - return; - } - - // Si solo hay un texto, lo coloca en la primera variable - if (numTexts == 1) - { - text1 += text2; - text2.clear(); - } - - // Si las notificaciones no se apilan, elimina las anteriores - if (!stack) - { - clearNotifications(); - } - - // Inicializa variables - constexpr auto iconSize = 16; - constexpr auto paddingOut = 1; - const auto paddingIn = text->getCharacterSize() / 2; - const auto iconSpace = icon >= 0 ? iconSize + paddingIn : 0; - const std::string txt = text1.length() > text2.length() ? text1 : text2; - const auto width = text->lenght(txt) + (paddingIn * 2) + iconSpace; - const auto height = (text->getCharacterSize() * numTexts) + (paddingIn * 2); - const auto shape = NotificationShape::SQUARED; - - // Posición horizontal - auto despH = 0; - if (param.notification.pos_h == NotifyPosition::LEFT) - { - despH = paddingOut; - } - else if (param.notification.pos_h == NotifyPosition::MIDDLE) - { - despH = ((param.game.width / 2) - (width / 2)); - } - else - { - despH = param.game.width - width - paddingOut; - } - - // Posición vertical - const int despV = (param.notification.pos_v == NotifyPosition::TOP) ? paddingOut : (param.game.height - height - paddingOut); - - // Offset - const auto travelDist = height + paddingOut; - auto offset = 0; - if (param.notification.pos_v == NotifyPosition::TOP) - { - offset = (int)notifications.size() > 0 ? notifications.back().y + travelDist : despV; - } - else - { - offset = (int)notifications.size() > 0 ? notifications.back().y - travelDist : despV; - } - - // Crea la notificacion - Notification n; - - // Inicializa variables - n.y = offset; - n.travelDist = travelDist; - n.counter = 0; - n.status = NotificationStatus::RISING; - n.text1 = text1; - n.text2 = text2; - n.shape = shape; - auto yPos = offset + (param.notification.pos_v == NotifyPosition::TOP ? -travelDist : travelDist); - n.rect = {despH, yPos, width, height}; - - // Crea la textura - n.texture = std::make_shared(renderer); - n.texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET); - n.texture->setBlendMode(SDL_BLENDMODE_BLEND); - - // Prepara para dibujar en la textura - n.texture->setAsRenderTarget(renderer); - - // Dibuja el fondo de la notificación - SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255); - SDL_Rect rect; - if (shape == NotificationShape::ROUNDED) - { - rect = {4, 0, width - (4 * 2), height}; - SDL_RenderFillRect(renderer, &rect); - - rect = {4 / 2, 1, width - 4, height - 2}; - SDL_RenderFillRect(renderer, &rect); - - rect = {1, 4 / 2, width - 2, height - 4}; - SDL_RenderFillRect(renderer, &rect); - - rect = {0, 4, width, height - (4 * 2)}; - SDL_RenderFillRect(renderer, &rect); - } - - else if (shape == NotificationShape::SQUARED) - { - SDL_RenderClear(renderer); - } - - // Dibuja el icono de la notificación - if (hasIcons && icon >= 0 && numTexts == 2) - { - auto sp = std::make_unique((SDL_Rect){0, 0, iconSize, iconSize}, iconTexture); - sp->setPos({paddingIn, paddingIn, iconSize, iconSize}); - sp->setSpriteClip({iconSize * (icon % 10), iconSize * (icon / 10), iconSize, iconSize}); - sp->render(); - } - - // Escribe el texto de la notificación - Color color = {255, 255, 255}; - if (numTexts == 2) - { // Dos lineas de texto - text->writeColored(paddingIn + iconSpace, paddingIn, text1, color); - text->writeColored(paddingIn + iconSpace, paddingIn + text->getCharacterSize() + 1, text2, color); - } - else - { // Una linea de texto - text->writeColored(paddingIn + iconSpace, paddingIn, text1, color); - } - - // Deja de dibujar en la textura - SDL_SetRenderTarget(renderer, nullptr); - - // Crea el sprite de la notificación - n.sprite = std::make_shared(n.rect, n.texture); - - // Deja la notificación invisible - n.texture->setAlpha(0); - - // Añade la notificación a la lista - notifications.push_back(n); -} - -// Indica si hay notificaciones activas -bool Notify::active() -{ - if ((int)notifications.size() > 0) - { - return true; - } - - return false; -} - -// Finaliza y elimnina todas las notificaciones activas -void Notify::clearNotifications() -{ - for (int i = 0; i < (int)notifications.size(); ++i) - { - notifications[i].status = NotificationStatus::FINISHED; - } - - clearFinishedNotifications(); -} \ No newline at end of file diff --git a/source/notify.h b/source/notify.h deleted file mode 100644 index f56e2b1..0000000 --- a/source/notify.h +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#include // for SDL_Rect -#include // for SDL_Renderer -#include // for shared_ptr, unique_ptr -#include // for string, basic_string -#include // for vector -#include "utils.h" // for Color -class Sprite; -class Text; -class Texture; -struct JA_Sound_t; // lines 12-12 - -class Notify -{ -private: - enum class NotificationStatus - { - RISING, - STAY, - VANISHING, - FINISHED, - }; - - enum class NotificationPosition - { - UPPER_LEFT, - UPPER_CENTER, - UPPER_RIGHT, - MIDDLE_LEFT, - MIDDLE_RIGHT, - BOTTOM_LEFT, - BOTTOM_CENTER, - BOTTOM_RIGHT, - }; - - enum class NotificationShape - { - ROUNDED, - SQUARED, - }; - - struct Notification - { - std::shared_ptr texture; - std::shared_ptr sprite; - std::string text1; - std::string text2; - int counter; - NotificationStatus status; - NotificationPosition position; - NotificationShape shape; - SDL_Rect rect; - int y; - int travelDist; - }; - - // Objetos y punteros - SDL_Renderer *renderer; // El renderizador de la ventana - - std::shared_ptr iconTexture; // Textura para los iconos de las notificaciones - std::unique_ptr text; // Objeto para dibujar texto - - // Variables - Color bgColor; // Color de fondo de las notificaciones - int waitTime; // Tiempo que se ve la notificación - std::vector notifications; // La lista de notificaciones activas - bool stack; // Indica si las notificaciones se apilan - bool hasIcons; // Indica si el notificador tiene textura para iconos - JA_Sound_t *sound; // Sonido a reproducir cuando suena la notificación - - // Elimina las notificaciones finalizadas - void clearFinishedNotifications(); - - // Finaliza y elimnina todas las notificaciones activas - void clearNotifications(); - -public: - // Constructor - Notify(SDL_Renderer *renderer, std::string iconFile, std::string bitmapFile, std::string textFile, const std::string &soundFile); - - // Destructor - ~Notify(); - - // Dibuja las notificaciones por pantalla - void render(); - - // Actualiza el estado de las notificaiones - void update(); - - // Muestra una notificación de texto por pantalla; - void showText(std::string text1 = std::string(), std::string text2 = std::string(), int icon = -1); - - // Indica si hay notificaciones activas - bool active(); -}; diff --git a/source/screen.cpp b/source/screen.cpp index d374568..d1e5dc2 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -12,7 +12,7 @@ #include "dbgtxt.h" // for dbg_print #include "global_inputs.h" // for servicePressedCounter #include "input.h" // for Input, inputs_e, INPUT_DO_NOT_ALLOW_REPEAT -#include "notify.h" // for Notify +#include "notifier.h" // for Notify #include "on_screen_help.h" // for OnScreenHelp #include "options.h" // for options #include "param.h" // for param @@ -47,7 +47,6 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) : window_(window), renderer_(renderer), - notify_(std::make_unique(renderer_, std::string(), Asset::get()->get("8bithud.png"), Asset::get()->get("8bithud.txt"), Asset::get()->get("notify.wav"))), game_canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), shader_canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), @@ -127,7 +126,7 @@ void Screen::blit() displayInfo(); // Muestra las notificaciones - notify_->render(); + Notifier::get()->render(); #ifdef NO_SHADERS // Vuelve a dejar el renderizador en modo normal @@ -281,7 +280,7 @@ void Screen::setBlendMode(SDL_BlendMode blendMode) void Screen::update() { updateShakeEffect(); - notify_->update(); + Notifier::get()->update(); updateFPS(); OnScreenHelp::get()->update(); } @@ -295,7 +294,7 @@ void Screen::checkInput() { switchVideoMode(); const std::string mode = options.video.mode == ScreenVideoMode::WINDOW ? "Window" : "Fullscreen"; - showNotification(mode + " mode"); + Notifier::get()->showText(mode + " mode"); return; } @@ -304,7 +303,7 @@ void Screen::checkInput() { decWindowSize(); const std::string size = std::to_string(options.video.window.size); - showNotification("Window size x" + size); + Notifier::get()->showText("Window size x" + size); return; } @@ -313,7 +312,7 @@ void Screen::checkInput() { incWindowSize(); const std::string size = std::to_string(options.video.window.size); - showNotification("Window size x" + size); + Notifier::get()->showText("Window size x" + size); return; } #endif @@ -443,7 +442,7 @@ void Screen::switchShaders() options.video.shaders = !options.video.shaders; setVideoMode(options.video.mode); const std::string value = options.video.shaders ? "on" : "off"; - showNotification("Shaders " + value); + Notifier::get()->showText("Shaders " + value); } // Atenua la pantalla @@ -452,12 +451,6 @@ void Screen::attenuate(bool value) attenuate_effect_ = value; } -// Muestra una notificación de texto por pantalla; -void Screen::showNotification(const std::string &text1, const std::string &text2, int icon) -{ - notify_->showText(text1, text2, icon); -} - // Obtiene el puntero al renderizador SDL_Renderer *Screen::getRenderer() { @@ -491,12 +484,6 @@ void Screen::displayInfo() } } -// Indica si hay alguna notificación activa en pantalla -bool Screen::notificationsAreActive() const -{ - return notify_->active(); -} - // Calcula la nueva posición de la ventana a partir de la antigua al cambiarla de tamaño SDL_Point Screen::getNewPosition() { diff --git a/source/screen.h b/source/screen.h index 3450e97..7a21884 100644 --- a/source/screen.h +++ b/source/screen.h @@ -8,7 +8,6 @@ #include // for basic_string, string #include "utils.h" // for Color #include -class Notify; enum class ScreenFilter : int { @@ -29,11 +28,10 @@ private: static Screen *screen_; // Objetos y punteros - SDL_Window *window_; // Ventana de la aplicación - SDL_Renderer *renderer_; // El renderizador de la ventana - std::unique_ptr notify_; // Pinta notificaciones en pantalla - SDL_Texture *game_canvas_; // Textura donde se dibuja todo antes de volcarse al renderizador - SDL_Texture *shader_canvas_; // Textura para pasarle al shader desde gameCanvas + SDL_Window *window_; // Ventana de la aplicación + SDL_Renderer *renderer_; // El renderizador de la ventana + SDL_Texture *game_canvas_; // Textura donde se dibuja todo antes de volcarse al renderizador + SDL_Texture *shader_canvas_; // Textura para pasarle al shader desde gameCanvas // Variables SDL_Rect src_rect_; // Coordenadas de donde va a pillar la textura del juego para dibujarla @@ -154,12 +152,6 @@ public: // Atenua la pantalla void attenuate(bool value); - // Muestra una notificación de texto por pantalla; - void showNotification(const std::string &text1 = std::string(), const std::string &text2 = std::string(), int icon = -1); - - // Indica si hay alguna notificación activa en pantalla - bool notificationsAreActive() const; - // Obtiene el puntero al renderizador SDL_Renderer *getRenderer(); }; \ No newline at end of file diff --git a/source/title.cpp b/source/title.cpp index 2d33553..f068889 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -1,24 +1,25 @@ #include "title.h" -#include // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN -#include // for SDLK_1, SDLK_2, SDLK_3 -#include // for SDL_Rect -#include // for SDL_Renderer -#include // for SDL_GetTicks -#include // for char_traits, operator+, to_string, bas... -#include // for move -#include // for vector -#include "asset.h" // for Asset -#include "global_inputs.h" // for check -#include "input.h" // for Input, InputType, INPUT_DO_NOT_ALLOW_R... -#include "jail_audio.h" // for JA_GetMusicState, JA_Music_state, JA_P... -#include "lang.h" // for getText -#include "options.h" // for options -#include "param.h" // for param -#include "screen.h" // for Screen -#include "section.h" // for Options, options, Name, name -#include "texture.h" // for Texture -#include "utils.h" // for Param, OptionsController, Color, Param... -struct JA_Music_t; // lines 17-17 +#include // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN +#include // for SDLK_1, SDLK_2, SDLK_3 +#include // for SDL_Rect +#include // for SDL_Renderer +#include // for SDL_GetTicks +#include // for char_traits, operator+, to_string, bas... +#include // for move +#include // for vector +#include "asset.h" // for Asset +#include "global_inputs.h" // for check +#include "input.h" // for Input, InputType, INPUT_DO_NOT_ALLOW_R... +#include "jail_audio.h" // for JA_GetMusicState, JA_Music_state, JA_P... +#include "lang.h" // for getText +#include "notifier.h" // for Notifier +#include "options.h" // for options +#include "param.h" // for param +#include "screen.h" // for Screen +#include "section.h" // for Options, options, Name, name +#include "texture.h" // for Texture +#include "utils.h" // for Param, OptionsController, Color, Param... +struct JA_Music_t; // lines 17-17 // Constructor Title::Title(JA_Music_t *music) @@ -354,7 +355,7 @@ void Title::swapControllers() } } - screen_->showNotification(text[0], text[1]); + Notifier::get()->showText(text[0], text[1]); resetCounter(); } \ No newline at end of file