#include "scoreboard.h" #include // Constructor Scoreboard::Scoreboard(SDL_Renderer *renderer, Asset *asset, Lang *lang, options_t *options) { // Copia los punteros this->renderer = renderer; this->asset = asset; this->lang = lang; this->options = options; // Inicializa punteros gamePowerMeterTexture = nullptr; powerMeterSprite = nullptr; textScoreBoard = nullptr; // Inicializa variables stage = 1; for (int i = 0; i< SCOREBOARD_MAX_PANELS; ++i) { name[i] = ""; score[i] = 0; mult[i] = 0; continueCounter[i] = 0; } hiScore = 0; power = 0; hiScoreName = ""; color = {0, 0, 0}; rect = {0, 0, 320, 40}; panel[SCOREBOARD_LEFT_PANEL].mode = SCOREBOARD_MODE_SCORE; panel[SCOREBOARD_RIGHT_PANEL].mode = SCOREBOARD_MODE_SCORE; panel[SCOREBOARD_CENTER_PANEL].mode = SCOREBOARD_MODE_STAGE_INFO; ticks = SDL_GetTicks(); counter = 0; // Recalcula las anclas de los elementos recalculateAnchors(); // Crea objetos gamePowerMeterTexture = new Texture(renderer, asset->get("game_power_meter.png")); powerMeterSprite = new Sprite(slot4_2.x - 20, slot4_2.y, 40, 7, gamePowerMeterTexture); textScoreBoard = new Text(asset->get("8bithud.png"), asset->get("8bithud.txt"), renderer); // Crea la textura de fondo background = nullptr; createBackgroundTexture(); // Crea las texturas de los paneles createPanelTextures(); // Rellena la textura de fondo fillBackgroundTexture(); } Scoreboard::~Scoreboard() { gamePowerMeterTexture->unload(); delete gamePowerMeterTexture; delete powerMeterSprite; delete textScoreBoard; if (background) { SDL_DestroyTexture(background); } for (auto texture : panelTexture) { if (texture) { SDL_DestroyTexture(texture); } } } // Transforma un valor numérico en una cadena de 6 cifras std::string Scoreboard::updateScoreText(Uint32 num) { if ((num >= 0) && (num <= 9)) { return ("000000" + std::to_string(num)); } if ((num >= 10) && (num <= 99)) { return ("00000" + std::to_string(num)); } if ((num >= 100) && (num <= 999)) { return ("0000" + std::to_string(num)); } if ((num >= 1000) && (num <= 9999)) { return ("000" + std::to_string(num)); } if ((num >= 010000) && (num <= 99999)) { return ("00" + std::to_string(num)); } if ((num >= 100000) && (num <= 999999)) { return ("0" + std::to_string(num)); } if ((num >= 1000000) && (num <= 9999999)) { return (std::to_string(num)); } return (std::to_string(num)); } // Actualiza el contador void Scoreboard::updateCounter() { if (SDL_GetTicks() - ticks > SCOREBOARD_TICK_SPEED) { ticks = SDL_GetTicks(); counter++; } } // Actualiza la lógica del marcador void Scoreboard::update() { fillBackgroundTexture(); updateCounter(); } // Pinta el marcador void Scoreboard::render() { SDL_RenderCopy(renderer, background, nullptr, &rect); } // Establece el valor de la variable void Scoreboard::setName(int panel, std::string name) { this->name[panel] = name; } // Establece el valor de la variable void Scoreboard::setScore(int panel, int score) { this->score[panel] = score; } // Establece el valor de la variable void Scoreboard::setMult(int panel, float mult) { this->mult[panel] = mult; } // Establece el valor de la variable void Scoreboard::setContinue(int panel, int value) { continueCounter[panel] = value; } // Establece el valor de la variable void Scoreboard::setStage(int stage) { this->stage = stage; } // Establece el valor de la variable void Scoreboard::setHiScore(int hiScore) { this->hiScore = hiScore; } // Establece el valor de la variable void Scoreboard::setPower(float power) { this->power = power; } // Establece el valor de la variable void Scoreboard::setHiScoreName(std::string name) { hiScoreName = name; } // Establece el valor de la variable void Scoreboard::setColor(color_t color) { this->color = color; fillBackgroundTexture(); } // Establece el valor de la variable void Scoreboard::setPos(SDL_Rect rect) { this->rect = rect; // Recalcula las anclas de los elementos recalculateAnchors(); // Crea la textura de fondo createBackgroundTexture(); // Crea las texturas de los paneles createPanelTextures(); // Rellena la textura de fondo fillBackgroundTexture(); } // Rellena los diferentes paneles del marcador void Scoreboard::fillPanelTextures() { // Guarda a donde apunta actualmente el renderizador SDL_Texture *temp = SDL_GetRenderTarget(renderer); // Genera el contenidoi de cada panel for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i) { // Cambia el destino del renderizador SDL_SetRenderTarget(renderer, panelTexture[i]); // Dibuja el fondo de la textura SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); switch (panel[i].mode) { case SCOREBOARD_MODE_SCORE: // SCORE textScoreBoard->writeCentered(slot4_1.x, slot4_1.y, name[i]); textScoreBoard->writeCentered(slot4_2.x, slot4_2.y, updateScoreText(score[i])); // MULT textScoreBoard->writeCentered(slot4_3.x, slot4_3.y, lang->getText(55)); textScoreBoard->writeCentered(slot4_4.x, slot4_4.y, std::to_string(mult[i]).substr(0, 3)); break; case SCOREBOARD_MODE_DEMO: textScoreBoard->writeCentered(slot4_1.x, slot4_1.y + 4, "Mode demostracio"); if (counter % 10 < 8) { textScoreBoard->writeCentered(slot4_3.x, slot4_3.y - 2, "Pulsa START"); textScoreBoard->writeCentered(slot4_4.x, slot4_4.y - 2, "per jugar"); } break; case SCOREBOARD_MODE_GAME_OVER: textScoreBoard->writeCentered(slot4_1.x, slot4_1.y + 4, "Game Over"); if (counter % 10 < 8) { textScoreBoard->writeCentered(slot4_3.x, slot4_3.y - 2, "Pulsa START"); textScoreBoard->writeCentered(slot4_4.x, slot4_4.y - 2, "per jugar"); } break; case SCOREBOARD_MODE_STAGE_INFO: // STAGE textScoreBoard->writeCentered(slot4_1.x, slot4_1.y, lang->getText(57) + std::to_string(stage)); // POWERMETER powerMeterSprite->setSpriteClip(0, 0, 40, 7); powerMeterSprite->render(); powerMeterSprite->setSpriteClip(40, 0, int(power * 40.0f), 7); powerMeterSprite->render(); // HI-SCORE textScoreBoard->writeCentered(slot4_3.x, slot4_3.y, lang->getText(56)); textScoreBoard->writeCentered(slot4_4.x, slot4_4.y, hiScoreName + " - " +updateScoreText(hiScore)); break; case SCOREBOARD_MODE_CONTINUE: // SCORE textScoreBoard->writeCentered(slot4_1.x, slot4_1.y, name[i]); textScoreBoard->writeCentered(slot4_2.x, slot4_2.y, updateScoreText(score[i])); // CONTINUE textScoreBoard->writeCentered(slot4_3.x, slot4_3.y, "Continuar?"); textScoreBoard->writeCentered(slot4_4.x, slot4_4.y, std::to_string(continueCounter[i])); break; default: break; } } // Deja el renderizador apuntando donde estaba SDL_SetRenderTarget(renderer, temp); } // Rellena la textura de fondo void Scoreboard::fillBackgroundTexture() { // Rellena los diferentes paneles del marcador fillPanelTextures(); // Cambia el destino del renderizador SDL_Texture *temp = SDL_GetRenderTarget(renderer); SDL_SetRenderTarget(renderer, background); // Dibuja el fondo del marcador SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 255); SDL_RenderClear(renderer); // Copia las texturas de los paneles for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i) { SDL_RenderCopy(renderer, panelTexture[i], nullptr, &panel[i].pos); } // Deja el renderizador apuntando donde estaba SDL_SetRenderTarget(renderer, temp); } // Recalcula las anclas de los elementos void Scoreboard::recalculateAnchors() { // Recalcula la posición y el tamaño de los paneles const float panelWidth = (float)rect.w / (float)SCOREBOARD_MAX_PANELS; for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i) { panel[i].pos.x = roundf(panelWidth * i); panel[i].pos.y = 0; panel[i].pos.w = roundf(panelWidth * (i + 1)) - panel[i].pos.x; panel[i].pos.h = rect.h; } // Constantes para definir las zonas del panel: 4 filas y 1 columna const int rowSize = rect.h / 4; const int textHeight = 7; // Filas const int row1 = (rowSize * 0) + (textHeight / 2); const int row2 = (rowSize * 1) + (textHeight / 2) - 1; const int row3 = (rowSize * 2) + (textHeight / 2) - 2; const int row4 = (rowSize * 3) + (textHeight / 2) - 3; // Columna const int col = panelWidth / 2; // Slots de 4 slot4_1 = {col, row1}; slot4_2 = {col, row2}; slot4_3 = {col, row3}; slot4_4 = {col, row4}; // Recoloca los sprites if (powerMeterSprite) { powerMeterSprite->setPosX(slot4_2.x - 20); powerMeterSprite->setPosY(slot4_2.y); } } // Establece el modo del marcador void Scoreboard::setMode(int index, scoreboard_modes_e mode) { panel[index].mode = mode; } // Crea la textura de fondo void Scoreboard::createBackgroundTexture() { // Elimina la textura en caso de existir if (background) { SDL_DestroyTexture(background); } // Recrea la textura de fondo background = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect.w, rect.h); SDL_SetTextureBlendMode(background, SDL_BLENDMODE_BLEND); } // Crea las texturas de los paneles void Scoreboard::createPanelTextures() { // Elimina las texturas en caso de existir for (auto texture : panelTexture) { if (texture != nullptr) { SDL_DestroyTexture(texture); } } panelTexture.clear(); // Crea las texturas para cada panel for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i) { SDL_Texture *tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, panel[i].pos.w, panel[i].pos.h); SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND); panelTexture.push_back(tex); } }