No canviava al marcador, ni el nom del que tenia la maxima puntuació en calent ni al posar nom retallat el nom de 8 a 6 caracters, i tots en majuscula pa que capia en el marcador ja actualitza be la cadena amb el nom al posar nom per segona vegada en la mateixa partida
405 lines
11 KiB
C++
405 lines
11 KiB
C++
#include "scoreboard.h"
|
|
#include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND
|
|
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
|
|
#include <SDL2/SDL_timer.h> // Para SDL_GetTicks
|
|
#include <math.h> // Para roundf
|
|
#include <iomanip> // Para operator<<, setfill, setw
|
|
#include <sstream> // Para basic_ostream, basic_ostringstream
|
|
#include "lang.h" // Para getText
|
|
#include "resource.h" // Para Resource
|
|
#include "screen.h" // Para Screen
|
|
#include "sprite.h" // Para Sprite
|
|
#include "text.h" // Para Text
|
|
#include "enter_name.h"
|
|
|
|
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
|
|
Scoreboard *Scoreboard::scoreboard_ = nullptr;
|
|
|
|
// [SINGLETON] Crearemos el objeto score_board con esta función estática
|
|
void Scoreboard::init()
|
|
{
|
|
Scoreboard::scoreboard_ = new Scoreboard();
|
|
}
|
|
|
|
// [SINGLETON] Destruiremos el objeto score_board con esta función estática
|
|
void Scoreboard::destroy()
|
|
{
|
|
delete Scoreboard::scoreboard_;
|
|
}
|
|
|
|
// [SINGLETON] Con este método obtenemos el objeto score_board y podemos trabajar con él
|
|
Scoreboard *Scoreboard::get()
|
|
{
|
|
return Scoreboard::scoreboard_;
|
|
}
|
|
|
|
// Constructor
|
|
Scoreboard::Scoreboard()
|
|
: renderer_(Screen::get()->getRenderer()),
|
|
game_power_meter_texture_(Resource::get()->getTexture("game_power_meter.png")),
|
|
power_meter_sprite_(std::make_unique<Sprite>(game_power_meter_texture_)),
|
|
text_scoreboard_(Resource::get()->getText("8bithud"))
|
|
{
|
|
// Inicializa variables
|
|
for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i)
|
|
{
|
|
name_[i].clear();
|
|
record_name_[i].clear();
|
|
selector_pos_[i] = 0;
|
|
score_[i] = 0;
|
|
mult_[i] = 0;
|
|
continue_counter_[i] = 0;
|
|
}
|
|
|
|
panel_[SCOREBOARD_LEFT_PANEL].mode = ScoreboardMode::SCORE;
|
|
panel_[SCOREBOARD_RIGHT_PANEL].mode = ScoreboardMode::SCORE;
|
|
panel_[SCOREBOARD_CENTER_PANEL].mode = ScoreboardMode::STAGE_INFO;
|
|
|
|
// Recalcula las anclas de los elementos
|
|
recalculateAnchors();
|
|
power_meter_sprite_->setPosition({slot4_2_.x - 20, slot4_2_.y, 40, 7});
|
|
|
|
// Crea la textura de fondo
|
|
background_ = nullptr;
|
|
createBackgroundTexture();
|
|
|
|
// Crea las texturas de los paneles
|
|
createPanelTextures();
|
|
|
|
// Rellena la textura de fondo
|
|
fillBackgroundTexture();
|
|
}
|
|
|
|
Scoreboard::~Scoreboard()
|
|
{
|
|
if (background_)
|
|
{
|
|
SDL_DestroyTexture(background_);
|
|
}
|
|
|
|
for (auto texture : panel_texture_)
|
|
{
|
|
if (texture)
|
|
{
|
|
SDL_DestroyTexture(texture);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Transforma un valor numérico en una cadena de 6 cifras
|
|
std::string Scoreboard::updateScoreText(int num)
|
|
{
|
|
std::ostringstream oss;
|
|
oss << std::setw(8) << std::setfill('0') << num;
|
|
return oss.str();
|
|
}
|
|
|
|
// Actualiza el contador
|
|
void Scoreboard::updateCounter()
|
|
{
|
|
constexpr int TICKS_SPEED = 100;
|
|
|
|
if (SDL_GetTicks() - ticks_ > TICKS_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::setColor(Color color)
|
|
{
|
|
color_ = color;
|
|
fillBackgroundTexture();
|
|
}
|
|
|
|
// Establece el valor de la variable
|
|
void Scoreboard::setPos(SDL_Rect rect)
|
|
{
|
|
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
|
|
auto temp = SDL_GetRenderTarget(renderer_);
|
|
|
|
// Genera el contenidoi de cada panel_
|
|
for (size_t i = 0; i < SCOREBOARD_MAX_PANELS; ++i)
|
|
{
|
|
// Cambia el destino del renderizador
|
|
SDL_SetRenderTarget(renderer_, panel_texture_[i]);
|
|
|
|
// Dibuja el fondo de la textura
|
|
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
|
SDL_RenderClear(renderer_);
|
|
|
|
switch (panel_[i].mode)
|
|
{
|
|
case ScoreboardMode::SCORE:
|
|
{
|
|
// SCORE
|
|
text_scoreboard_->writeCentered(slot4_1_.x, slot4_1_.y, name_[i]);
|
|
text_scoreboard_->writeCentered(slot4_2_.x, slot4_2_.y, updateScoreText(score_[i]));
|
|
|
|
// MULT
|
|
text_scoreboard_->writeCentered(slot4_3_.x, slot4_3_.y, lang::getText(55));
|
|
text_scoreboard_->writeCentered(slot4_4_.x, slot4_4_.y, "x" + std::to_string(mult_[i]).substr(0, 3));
|
|
break;
|
|
}
|
|
|
|
case ScoreboardMode::DEMO:
|
|
{
|
|
// DEMO MODE
|
|
text_scoreboard_->writeCentered(slot4_1_.x, slot4_1_.y + 4, lang::getText(101));
|
|
|
|
// PRESS START TO PLAY
|
|
if (counter_ % 10 < 8)
|
|
{
|
|
text_scoreboard_->writeCentered(slot4_3_.x, slot4_3_.y - 2, lang::getText(103));
|
|
text_scoreboard_->writeCentered(slot4_4_.x, slot4_4_.y - 2, lang::getText(104));
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ScoreboardMode::WAITING:
|
|
{
|
|
// GAME OVER
|
|
text_scoreboard_->writeCentered(slot4_1_.x, slot4_1_.y + 4, lang::getText(102));
|
|
|
|
// PRESS START TO PLAY
|
|
if (counter_ % 10 < 8)
|
|
{
|
|
text_scoreboard_->writeCentered(slot4_3_.x, slot4_3_.y - 2, lang::getText(103));
|
|
text_scoreboard_->writeCentered(slot4_4_.x, slot4_4_.y - 2, lang::getText(104));
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ScoreboardMode::GAME_OVER:
|
|
{
|
|
// GAME OVER
|
|
text_scoreboard_->writeCentered(slot4_1_.x, slot4_1_.y + 4, lang::getText(102));
|
|
|
|
// PLEASE WAIT
|
|
if (counter_ % 10 < 8)
|
|
{
|
|
text_scoreboard_->writeCentered(slot4_3_.x, slot4_3_.y - 2, lang::getText(114));
|
|
text_scoreboard_->writeCentered(slot4_4_.x, slot4_4_.y - 2, lang::getText(115));
|
|
}
|
|
break;
|
|
}
|
|
|
|
case ScoreboardMode::STAGE_INFO:
|
|
{
|
|
// STAGE
|
|
text_scoreboard_->writeCentered(slot4_1_.x, slot4_1_.y, lang::getText(57) + std::to_string(stage_));
|
|
|
|
// POWERMETER
|
|
power_meter_sprite_->setSpriteClip(0, 0, 40, 7);
|
|
power_meter_sprite_->render();
|
|
power_meter_sprite_->setSpriteClip(40, 0, int(power_ * 40.0f), 7);
|
|
power_meter_sprite_->render();
|
|
|
|
// HI-SCORE
|
|
text_scoreboard_->writeCentered(slot4_3_.x, slot4_3_.y, lang::getText(56));
|
|
const std::string name = hi_score_name_ == "" ? "" : hi_score_name_ + " - ";
|
|
text_scoreboard_->writeCentered(slot4_4_.x, slot4_4_.y, name + updateScoreText(hi_score_));
|
|
break;
|
|
}
|
|
|
|
case ScoreboardMode::CONTINUE:
|
|
{
|
|
// SCORE
|
|
text_scoreboard_->writeCentered(slot4_1_.x, slot4_1_.y, name_[i]);
|
|
text_scoreboard_->writeCentered(slot4_2_.x, slot4_2_.y, updateScoreText(score_[i]));
|
|
|
|
// CONTINUE
|
|
text_scoreboard_->writeCentered(slot4_3_.x, slot4_3_.y, lang::getText(105));
|
|
text_scoreboard_->writeCentered(slot4_4_.x, slot4_4_.y, std::to_string(continue_counter_[i]));
|
|
break;
|
|
}
|
|
|
|
case ScoreboardMode::ENTER_NAME:
|
|
{
|
|
// SCORE
|
|
text_scoreboard_->writeCentered(slot4_1_.x, slot4_1_.y, name_[i]);
|
|
text_scoreboard_->writeCentered(slot4_2_.x, slot4_2_.y, updateScoreText(score_[i]));
|
|
|
|
// ENTER NAME
|
|
text_scoreboard_->writeCentered(slot4_3_.x, slot4_3_.y, lang::getText(106));
|
|
SDL_Rect rect = {enter_name_pos_.x, enter_name_pos_.y, 5, 7};
|
|
SDL_SetRenderDrawColor(renderer_, 0xFF, 0xFF, 0xEB, 255);
|
|
for (size_t j = 0; j < record_name_[i].size(); ++j)
|
|
{
|
|
if (j != selector_pos_[i] || counter_ % 3 == 0)
|
|
{
|
|
SDL_RenderDrawLine(renderer_, rect.x, rect.y + rect.h, rect.x + rect.w, rect.y + rect.h);
|
|
text_scoreboard_->write(rect.x, rect.y, record_name_[i].substr(j, 1));
|
|
}
|
|
rect.x += 7;
|
|
}
|
|
break;
|
|
}
|
|
case ScoreboardMode::GAME_COMPLETED:
|
|
{
|
|
// GAME OVER
|
|
text_scoreboard_->writeCentered(slot4_1_.x, slot4_1_.y + 4, lang::getText(102));
|
|
|
|
// SCORE
|
|
if (counter_ % 10 < 8)
|
|
{
|
|
text_scoreboard_->writeCentered(slot4_3_.x, slot4_3_.y - 2, lang::getText(120));
|
|
text_scoreboard_->writeCentered(slot4_4_.x, slot4_4_.y - 2, updateScoreText(score_[i]));
|
|
}
|
|
}
|
|
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_, panel_texture_[i], nullptr, &panel_[i].pos);
|
|
}
|
|
|
|
// Dibuja la linea que separa la zona de juego del marcador
|
|
renderSeparator();
|
|
|
|
// 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};
|
|
|
|
// Primer cuadrado para poner el nombre de record
|
|
const int enterNameLenght = NAME_LENGHT * 7;
|
|
enter_name_pos_.x = (panelWidth - enterNameLenght) / 2;
|
|
enter_name_pos_.y = row4;
|
|
|
|
// Recoloca los sprites
|
|
if (power_meter_sprite_)
|
|
{
|
|
power_meter_sprite_->setX(slot4_2_.x - 20);
|
|
power_meter_sprite_->setY(slot4_2_.y);
|
|
}
|
|
}
|
|
|
|
// 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 : panel_texture_)
|
|
{
|
|
if (texture != nullptr)
|
|
{
|
|
SDL_DestroyTexture(texture);
|
|
}
|
|
}
|
|
panel_texture_.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);
|
|
panel_texture_.push_back(tex);
|
|
}
|
|
}
|
|
|
|
// Dibuja la linea que separa la zona de juego del marcador
|
|
void Scoreboard::renderSeparator()
|
|
{
|
|
// Dibuja la linea que separa el marcador de la zona de juego
|
|
SDL_SetRenderDrawColor(renderer_, separator_color.r, separator_color.g, separator_color.b, 255);
|
|
SDL_RenderDrawLine(renderer_, 0, 0, rect_.w, 0);
|
|
} |