202 lines
6.5 KiB
C++
202 lines
6.5 KiB
C++
#include "scoreboard.h"
|
|
#include <SDL2/SDL_rect.h> // for SDL_Rect
|
|
#include <SDL2/SDL_timer.h> // 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
|
|
#include <iostream>
|
|
|
|
// Constructor
|
|
Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
|
|
: renderer_(Screen::get()->getRenderer()),
|
|
resource_(Resource::get()),
|
|
asset_(Asset::get()),
|
|
data_(data),
|
|
clock_(ClockData())
|
|
{
|
|
const int TEXTURE_WIDTH_ = options.game.width;
|
|
constexpr int TEXTURE_HEIGHT_ = 6 * BLOCK;
|
|
|
|
// 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<AnimatedSprite>(player_texture, player_animations);
|
|
player_sprite_->setCurrentAnimation("walk_menu");
|
|
text_ = resource_->getText("smb2");
|
|
|
|
texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, TEXTURE_WIDTH_, TEXTURE_HEIGHT_);
|
|
if (texture_ == nullptr)
|
|
{
|
|
if (options.console)
|
|
{
|
|
std::cout << "Scorebard::texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
|
}
|
|
}
|
|
texture_dest_ = {0, options.game.height - TEXTURE_HEIGHT_, TEXTURE_WIDTH_, TEXTURE_HEIGHT_};
|
|
|
|
// 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<std::string> COLORS = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
|
|
for (const auto &color : COLORS)
|
|
{
|
|
color_.push_back(stringToColor(options.video.palette, color));
|
|
}
|
|
}
|
|
|
|
// Destructor
|
|
Scoreboard::~Scoreboard()
|
|
{
|
|
SDL_DestroyTexture(texture_);
|
|
}
|
|
|
|
// Pinta el objeto en pantalla
|
|
void Scoreboard::render()
|
|
{
|
|
SDL_RenderCopy(renderer_, texture_, nullptr, &texture_dest_);
|
|
}
|
|
|
|
// Actualiza las variables del objeto
|
|
void Scoreboard::update()
|
|
{
|
|
counter_++;
|
|
player_sprite_->update();
|
|
|
|
// Actualiza el color de la cantidad de items recogidos
|
|
updateItemsColor();
|
|
|
|
// Dibuja la textura
|
|
fillTexture();
|
|
|
|
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;
|
|
}
|
|
|
|
// Pone el marcador en modo pausa
|
|
void Scoreboard::setPaused(bool value)
|
|
{
|
|
if (is_paused_ == value)
|
|
{
|
|
// Evita ejecutar lógica si el estado no cambia
|
|
return;
|
|
}
|
|
|
|
is_paused_ = value;
|
|
|
|
if (is_paused_)
|
|
{
|
|
// Guarda el tiempo actual al pausar
|
|
paused_time_ = SDL_GetTicks();
|
|
}
|
|
else
|
|
{
|
|
// Calcula el tiempo pausado acumulado al reanudar
|
|
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;
|
|
}
|
|
|
|
// Dibuja los elementos del marcador en la textura
|
|
void Scoreboard::fillTexture()
|
|
{
|
|
// Empieza a dibujar en la textura
|
|
auto temp = SDL_GetRenderTarget(renderer_);
|
|
SDL_SetRenderTarget(renderer_, texture_);
|
|
|
|
// Limpia la textura
|
|
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255);
|
|
SDL_RenderFillRect(renderer_, nullptr);
|
|
|
|
// Anclas
|
|
constexpr int LINE1 = BLOCK;
|
|
constexpr int LINE2 = 3 * BLOCK;
|
|
|
|
// 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);
|
|
text_->writeColored(BLOCK, LINE1, "Items collected ", data_->color);
|
|
text_->writeColored(17 * BLOCK, LINE1, itemsTxt, items_color_);
|
|
text_->writeColored(20 * BLOCK, LINE1, " Time ", data_->color);
|
|
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);
|
|
text_->writeColored(22 * BLOCK, LINE2, "Rooms", stringToColor(options.video.palette, "white"));
|
|
text_->writeColored(28 * BLOCK, LINE2, roomsTxt, stringToColor(options.video.palette, "white"));
|
|
|
|
// Deja el renderizador como estaba
|
|
SDL_SetRenderTarget(renderer_, temp);
|
|
} |