nous sons

This commit is contained in:
2025-12-17 17:05:42 +01:00
parent ec333efe66
commit 8bc259b25a
12 changed files with 105 additions and 96 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -168,16 +168,26 @@ constexpr bool INFINITE_CONTINUES = false; // If true, unlimited continue
namespace ContinueScreen { namespace ContinueScreen {
// "CONTINUE" text // "CONTINUE" text
constexpr float CONTINUE_TEXT_SCALE = 2.0f; // Text size constexpr float CONTINUE_TEXT_SCALE = 2.0f; // Text size
constexpr float CONTINUE_TEXT_Y_RATIO = 0.35f; // 35% from top of PLAYAREA constexpr float CONTINUE_TEXT_Y_RATIO = 0.30f; // 35% from top of PLAYAREA
// Countdown number (9, 8, 7...) // Countdown number (9, 8, 7...)
constexpr float COUNTER_TEXT_SCALE = 4.0f; // Text size (large) constexpr float COUNTER_TEXT_SCALE = 4.0f; // Text size (large)
constexpr float COUNTER_TEXT_Y_RATIO = 0.50f; // 50% from top of PLAYAREA constexpr float COUNTER_TEXT_Y_RATIO = 0.50f; // 50% from top of PLAYAREA
// "CONTINUES LEFT: X" text // "CONTINUES LEFT: X" text
constexpr float INFO_TEXT_SCALE = 1.0f; // Text size (small) constexpr float INFO_TEXT_SCALE = 0.7f; // Text size (small)
constexpr float INFO_TEXT_Y_RATIO = 0.65f; // 65% from top of PLAYAREA constexpr float INFO_TEXT_Y_RATIO = 0.75f; // 65% from top of PLAYAREA
} // namespace ContinueScreen } // namespace ContinueScreen
// Game Over screen visual configuration
namespace GameOverScreen {
constexpr float TEXT_SCALE = 2.0f; // "GAME OVER" text size
constexpr float TEXT_SPACING = 4.0f; // Character spacing
} // namespace GameOverScreen
// Stage message configuration (LEVEL_START, LEVEL_COMPLETED)
constexpr float STAGE_MESSAGE_Y_RATIO = 0.25f; // 25% from top of PLAYAREA
constexpr float STAGE_MESSAGE_MAX_WIDTH_RATIO = 0.9f; // 90% of PLAYAREA width
} // namespace Game } // namespace Game
// Física (valores actuales del juego, sincronizados con joc_asteroides.cpp) // Física (valores actuales del juego, sincronizados con joc_asteroides.cpp)
@@ -272,6 +282,7 @@ namespace Music {
constexpr float VOLUME = 0.8F; // Volumen música constexpr float VOLUME = 0.8F; // Volumen música
constexpr bool ENABLED = true; // Música habilitada constexpr bool ENABLED = true; // Música habilitada
constexpr const char* GAME_TRACK = "game.ogg"; // Pista de juego constexpr const char* GAME_TRACK = "game.ogg"; // Pista de juego
constexpr const char* TITLE_TRACK = "title.ogg"; // Pista de titulo
constexpr int FADE_DURATION_MS = 1000; // Fade out duration constexpr int FADE_DURATION_MS = 1000; // Fade out duration
} // namespace Music } // namespace Music
@@ -279,9 +290,13 @@ constexpr int FADE_DURATION_MS = 1000; // Fade out duration
namespace Sound { namespace Sound {
constexpr float VOLUME = 1.0F; // Volumen efectos constexpr float VOLUME = 1.0F; // Volumen efectos
constexpr bool ENABLED = true; // Sonidos habilitados constexpr bool ENABLED = true; // Sonidos habilitados
constexpr const char* CONTINUE = "effects/continue.wav"; // Cuenta atras
constexpr const char* EXPLOSION = "effects/explosion.wav"; // Explosión constexpr const char* EXPLOSION = "effects/explosion.wav"; // Explosión
constexpr const char* EXPLOSION2 = "effects/explosion2.wav"; // Explosión alternativa
constexpr const char* INIT_HUD = "effects/init_hud.wav"; // Para la animación del HUD
constexpr const char* LASER = "effects/laser_shoot.wav"; // Disparo constexpr const char* LASER = "effects/laser_shoot.wav"; // Disparo
constexpr const char* LOGO = "effects/logo.wav"; // Logo constexpr const char* LOGO = "effects/logo.wav"; // Logo
constexpr const char* START = "effects/start.wav"; // El jugador pulsa START
constexpr const char* GOOD_JOB_COMMANDER = "voices/good_job_commander.wav"; // Voz: "Good job, commander" constexpr const char* GOOD_JOB_COMMANDER = "voices/good_job_commander.wav"; // Voz: "Good job, commander"
} // namespace Sound } // namespace Sound
@@ -473,8 +488,8 @@ constexpr float P2_FREQUENCY_MULTIPLIER = 1.12f; // 12% més ràpida
namespace Layout { namespace Layout {
// Posicions verticals (anclatges des del TOP de pantalla lògica, 0.0-1.0) // Posicions verticals (anclatges des del TOP de pantalla lògica, 0.0-1.0)
constexpr float LOGO_POS = 0.20f; // Logo "ORNI" constexpr float LOGO_POS = 0.20f; // Logo "ORNI"
constexpr float PRESS_START_POS = 0.73f; // "PRESS START TO PLAY" constexpr float PRESS_START_POS = 0.75f; // "PRESS START TO PLAY"
constexpr float COPYRIGHT1_POS = 0.87f; // Primera línia copyright constexpr float COPYRIGHT1_POS = 0.90f; // Primera línia copyright
// Separacions relatives (proporció respecte Game::HEIGHT = 480px) // Separacions relatives (proporció respecte Game::HEIGHT = 480px)
constexpr float LOGO_LINE_SPACING = 0.02f; // Entre "ORNI" i "ATTACK!" (10px) constexpr float LOGO_LINE_SPACING = 0.02f; // Entre "ORNI" i "ATTACK!" (10px)

View File

@@ -236,6 +236,22 @@ void VectorText::render(const std::string& text, const Punt& posicio, float esca
} }
} }
void VectorText::render_centered(const std::string& text, const Punt& centre_punt, float escala, float spacing, float brightness) {
// Calcular dimensions del text
float text_width = get_text_width(text, escala, spacing);
float text_height = get_text_height(escala);
// Calcular posició de l'esquina superior esquerra
// restant la meitat de les dimensions del punt central
Punt posicio_esquerra = {
centre_punt.x - (text_width / 2.0f),
centre_punt.y - (text_height / 2.0f)
};
// Delegar al mètode render() existent
render(text, posicio_esquerra, escala, spacing, brightness);
}
float VectorText::get_text_width(const std::string& text, float escala, float spacing) const { float VectorText::get_text_width(const std::string& text, float escala, float spacing) const {
if (text.empty()) { if (text.empty()) {
return 0.0f; return 0.0f;

View File

@@ -27,6 +27,14 @@ class VectorText {
// - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor) // - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor)
void render(const std::string& text, const Punt& posicio, float escala = 1.0f, float spacing = 2.0f, float brightness = 1.0f); void render(const std::string& text, const Punt& posicio, float escala = 1.0f, float spacing = 2.0f, float brightness = 1.0f);
// Renderizar string centrado en un punto
// - text: cadena a renderizar
// - centre_punt: punto central del texto (no esquina superior izquierda)
// - escala: factor de escala (1.0 = 20×40 px por carácter)
// - spacing: espacio entre caracteres en píxeles (a escala 1.0)
// - brightness: factor de brillantor (0.0-1.0, default 1.0 = màxima brillantor)
void render_centered(const std::string& text, const Punt& centre_punt, float escala = 1.0f, float spacing = 2.0f, float brightness = 1.0f);
// Calcular ancho total de un string (útil para centrado) // Calcular ancho total de un string (útil para centrado)
float get_text_width(const std::string& text, float escala = 1.0f, float spacing = 2.0f) const; float get_text_width(const std::string& text, float escala = 1.0f, float spacing = 2.0f) const;

View File

@@ -51,13 +51,14 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
float brightness, float brightness,
const Punt& velocitat_objecte, const Punt& velocitat_objecte,
float velocitat_angular, float velocitat_angular,
float factor_herencia_visual) { float factor_herencia_visual,
const std::string& sound) {
if (!shape || !shape->es_valida()) { if (!shape || !shape->es_valida()) {
return; return;
} }
// Reproducir sonido de explosión // Reproducir sonido de explosión
Audio::get()->playSound(Defaults::Sound::EXPLOSION, Audio::Group::GAME); Audio::get()->playSound(sound, Audio::Group::GAME);
// Obtenir centre de la forma per a transformacions // Obtenir centre de la forma per a transformacions
const Punt& shape_centre = shape->get_centre(); const Punt& shape_centre = shape->get_centre();

View File

@@ -37,7 +37,8 @@ class DebrisManager {
float brightness = 1.0f, float brightness = 1.0f,
const Punt& velocitat_objecte = {0.0f, 0.0f}, const Punt& velocitat_objecte = {0.0f, 0.0f},
float velocitat_angular = 0.0f, float velocitat_angular = 0.0f,
float factor_herencia_visual = 0.0f); float factor_herencia_visual = 0.0f,
const std::string& sound = Defaults::Sound::EXPLOSION);
// Actualitzar tots els fragments actius // Actualitzar tots els fragments actius
void actualitzar(float delta_time); void actualitzar(float delta_time);

View File

@@ -61,16 +61,11 @@ void GestorPuntuacioFlotant::dibuixar() {
if (!pf.actiu) if (!pf.actiu)
continue; continue;
// 1. Calcular dimensions del text per centrar-lo // Renderitzar centrat amb brightness (fade)
constexpr float escala = Defaults::FloatingScore::SCALE; constexpr float escala = Defaults::FloatingScore::SCALE;
constexpr float spacing = Defaults::FloatingScore::SPACING; constexpr float spacing = Defaults::FloatingScore::SPACING;
float text_width = text_.get_text_width(pf.text, escala, spacing);
// 2. Centrar text sobre la posició text_.render_centered(pf.text, pf.posicio, escala, spacing, pf.brightness);
Punt render_pos = {pf.posicio.x - text_width / 2.0f, pf.posicio.y};
// 3. Renderitzar amb brightness (fade)
text_.render(pf.text, render_pos, escala, spacing, pf.brightness);
} }
} }

View File

@@ -526,17 +526,15 @@ void EscenaJoc::dibuixar() {
// Draw centered "GAME OVER" text // Draw centered "GAME OVER" text
const std::string game_over_text = "GAME OVER"; const std::string game_over_text = "GAME OVER";
constexpr float escala = 2.0f; constexpr float escala = Defaults::Game::GameOverScreen::TEXT_SCALE;
constexpr float spacing = 4.0f; constexpr float spacing = Defaults::Game::GameOverScreen::TEXT_SPACING;
float text_width = text_.get_text_width(game_over_text, escala, spacing);
float text_height = text_.get_text_height(escala);
// Calcular centre de l'àrea de joc usant constants
const SDL_FRect& play_area = Defaults::Zones::PLAYAREA; const SDL_FRect& play_area = Defaults::Zones::PLAYAREA;
float x = play_area.x + (play_area.w - text_width) / 2.0f; float centre_x = play_area.x + play_area.w / 2.0f;
float y = play_area.y + (play_area.h - text_height) / 2.0f; float centre_y = play_area.y + play_area.h / 2.0f;
text_.render(game_over_text, {x, y}, escala, spacing); text_.render_centered(game_over_text, {centre_x, centre_y}, escala, spacing);
dibuixar_marcador(); dibuixar_marcador();
return; return;
@@ -577,7 +575,7 @@ void EscenaJoc::dibuixar() {
if (rect_progress > 0.0f) { if (rect_progress > 0.0f) {
// [NOU] Reproduir so quan comença l'animació del rectangle // [NOU] Reproduir so quan comença l'animació del rectangle
if (!init_hud_rect_sound_played_) { if (!init_hud_rect_sound_played_) {
Audio::get()->playSound(Defaults::Sound::LOGO, Audio::Group::GAME); Audio::get()->playSound(Defaults::Sound::INIT_HUD, Audio::Group::GAME);
init_hud_rect_sound_played_ = true; init_hud_rect_sound_played_ = true;
} }
@@ -702,11 +700,10 @@ void EscenaJoc::tocado(uint8_t player_id) {
naus_[player_id].get_brightness(), // Heredar brightness naus_[player_id].get_brightness(), // Heredar brightness
vel_nau_80, // Heredar 80% velocitat vel_nau_80, // Heredar 80% velocitat
0.0f, // Nave: trayectorias rectas (sin drotacio) 0.0f, // Nave: trayectorias rectas (sin drotacio)
0.0f // Sin herencia visual (rotación aleatoria) 0.0f, // Sin herencia visual (rotación aleatoria)
Defaults::Sound::EXPLOSION2 // Sonido alternativo para la explosión
); );
Audio::get()->playSound(Defaults::Sound::EXPLOSION, Audio::Group::GAME);
// Start death timer (non-zero to avoid re-triggering) // Start death timer (non-zero to avoid re-triggering)
itocado_per_jugador_[player_id] = 0.001f; itocado_per_jugador_[player_id] = 0.001f;
} }
@@ -739,19 +736,13 @@ void EscenaJoc::dibuixar_marcador() {
const float escala = 0.85f; const float escala = 0.85f;
const float spacing = 0.0f; const float spacing = 0.0f;
// Calcular dimensions del text // Calcular centre de la zona del marcador
float text_width = text_.get_text_width(text, escala, spacing); const SDL_FRect& scoreboard = Defaults::Zones::SCOREBOARD;
float text_height = text_.get_text_height(escala); float centre_x = scoreboard.w / 2.0f;
float centre_y = scoreboard.y + scoreboard.h / 2.0f;
// Centrat horitzontal dins de la zona del marcador // Renderitzar centrat
float x = (Defaults::Zones::SCOREBOARD.w - text_width) / 2.0f; text_.render_centered(text, {centre_x, centre_y}, escala, spacing);
// Centrat vertical dins de la zona del marcador
float y = Defaults::Zones::SCOREBOARD.y +
(Defaults::Zones::SCOREBOARD.h - text_height) / 2.0f;
// Renderitzar
text_.render(text, {x, y}, escala, spacing);
} }
void EscenaJoc::dibuixar_marges_animat(float progress) const { void EscenaJoc::dibuixar_marges_animat(float progress) const {
@@ -826,25 +817,19 @@ void EscenaJoc::dibuixar_marcador_animat(float progress) {
const float escala = 0.85f; const float escala = 0.85f;
const float spacing = 0.0f; const float spacing = 0.0f;
// Calcular dimensions // Calcular centre de la zona del marcador
float text_width = text_.get_text_width(text, escala, spacing); const SDL_FRect& scoreboard = Defaults::Zones::SCOREBOARD;
float text_height = text_.get_text_height(escala); float centre_x = scoreboard.w / 2.0f;
float centre_y_final = scoreboard.y + scoreboard.h / 2.0f;
// Posició X final (centrada horitzontalment)
float x_final = (Defaults::Zones::SCOREBOARD.w - text_width) / 2.0f;
// Posició Y final (centrada verticalment en la zona de scoreboard)
float y_final = Defaults::Zones::SCOREBOARD.y +
(Defaults::Zones::SCOREBOARD.h - text_height) / 2.0f;
// Posició Y inicial (offscreen, sota de la pantalla) // Posició Y inicial (offscreen, sota de la pantalla)
float y_inicial = static_cast<float>(Defaults::Game::HEIGHT) + text_height; float centre_y_inicial = static_cast<float>(Defaults::Game::HEIGHT);
// Interpolació amb easing // Interpolació amb easing
float y_animada = y_inicial + (y_final - y_inicial) * eased_progress; float centre_y_animada = centre_y_inicial + (centre_y_final - centre_y_inicial) * eased_progress;
// Renderitzar en posició animada // Renderitzar centrat en posició animada
text_.render(text, {x_final, y_animada}, escala, spacing); text_.render_centered(text, {centre_x, centre_y_animada}, escala, spacing);
} }
Punt EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const { Punt EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const {
@@ -1067,10 +1052,9 @@ void EscenaJoc::detectar_col·lisio_naus_enemics() {
void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) { void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) {
constexpr float escala_base = 1.0f; constexpr float escala_base = 1.0f;
constexpr float spacing = 2.0f; constexpr float spacing = 2.0f;
constexpr float max_width_ratio = 0.9f; // 90% del ancho disponible
const SDL_FRect& play_area = Defaults::Zones::PLAYAREA; const SDL_FRect& play_area = Defaults::Zones::PLAYAREA;
const float max_width = play_area.w * max_width_ratio; // 558px const float max_width = play_area.w * Defaults::Game::STAGE_MESSAGE_MAX_WIDTH_RATIO;
// ========== TYPEWRITER EFFECT (PARAMETRIZED) ========== // ========== TYPEWRITER EFFECT (PARAMETRIZED) ==========
// Get state-specific timing configuration // Get state-specific timing configuration
@@ -1123,7 +1107,7 @@ void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) {
// Calculate position as if FULL text was there (for fixed position typewriter) // Calculate position as if FULL text was there (for fixed position typewriter)
float x = play_area.x + (play_area.w - full_text_width) / 2.0f; float x = play_area.x + (play_area.w - full_text_width) / 2.0f;
float y = play_area.y + (play_area.h * 0.25f) - (text_height / 2.0f); float y = play_area.y + (play_area.h * Defaults::Game::STAGE_MESSAGE_Y_RATIO) - (text_height / 2.0f);
// Render only the partial message (typewriter effect) // Render only the partial message (typewriter effect)
Punt pos = {x, y}; Punt pos = {x, y};
@@ -1190,7 +1174,7 @@ void EscenaJoc::actualitzar_continue(float delta_time) {
continue_tick_timer_ = Defaults::Game::CONTINUE_TICK_DURATION; continue_tick_timer_ = Defaults::Game::CONTINUE_TICK_DURATION;
// Play tick sound // Play tick sound
Audio::get()->playSound("continue_tick"); Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME);
if (continue_counter_ <= 0) { if (continue_counter_ <= 0) {
// Timeout → final game over // Timeout → final game over
@@ -1257,7 +1241,7 @@ void EscenaJoc::processar_input_continue() {
continue_tick_timer_ = 0.0f; continue_tick_timer_ = 0.0f;
// Play continue confirmation sound // Play continue confirmation sound
Audio::get()->playSound("continue_confirm"); Audio::get()->playSound(Defaults::Sound::START, Audio::Group::GAME);
return; return;
} }
@@ -1272,7 +1256,7 @@ void EscenaJoc::processar_input_continue() {
continue_counter_--; continue_counter_--;
// Play tick sound on manual decrement // Play tick sound on manual decrement
Audio::get()->playSound("continue_tick"); Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME);
if (continue_counter_ <= 0) { if (continue_counter_ <= 0) {
estat_game_over_ = EstatGameOver::GAME_OVER; estat_game_over_ = EstatGameOver::GAME_OVER;
@@ -1293,22 +1277,19 @@ void EscenaJoc::dibuixar_continue() {
float escala_continue = Defaults::Game::ContinueScreen::CONTINUE_TEXT_SCALE; float escala_continue = Defaults::Game::ContinueScreen::CONTINUE_TEXT_SCALE;
float y_ratio_continue = Defaults::Game::ContinueScreen::CONTINUE_TEXT_Y_RATIO; float y_ratio_continue = Defaults::Game::ContinueScreen::CONTINUE_TEXT_Y_RATIO;
float text_width_continue = text_.get_text_width(continue_text, escala_continue, spacing); float centre_x = play_area.x + play_area.w / 2.0f;
float x_continue = play_area.x + (play_area.w - text_width_continue) / 2.0f; float centre_y_continue = play_area.y + play_area.h * y_ratio_continue;
float y_continue = play_area.y + play_area.h * y_ratio_continue;
text_.render(continue_text, {x_continue, y_continue}, escala_continue, spacing); text_.render_centered(continue_text, {centre_x, centre_y_continue}, escala_continue, spacing);
// Countdown number (using constants) // Countdown number (using constants)
const std::string counter_str = std::to_string(continue_counter_); const std::string counter_str = std::to_string(continue_counter_);
float escala_counter = Defaults::Game::ContinueScreen::COUNTER_TEXT_SCALE; float escala_counter = Defaults::Game::ContinueScreen::COUNTER_TEXT_SCALE;
float y_ratio_counter = Defaults::Game::ContinueScreen::COUNTER_TEXT_Y_RATIO; float y_ratio_counter = Defaults::Game::ContinueScreen::COUNTER_TEXT_Y_RATIO;
float text_width_counter = text_.get_text_width(counter_str, escala_counter, spacing); float centre_y_counter = play_area.y + play_area.h * y_ratio_counter;
float x_counter = play_area.x + (play_area.w - text_width_counter) / 2.0f;
float y_counter = play_area.y + play_area.h * y_ratio_counter;
text_.render(counter_str, {x_counter, y_counter}, escala_counter, spacing); text_.render_centered(counter_str, {centre_x, centre_y_counter}, escala_counter, spacing);
// "CONTINUES LEFT" (conditional + using constants) // "CONTINUES LEFT" (conditional + using constants)
if (!Defaults::Game::INFINITE_CONTINUES) { if (!Defaults::Game::INFINITE_CONTINUES) {
@@ -1316,11 +1297,9 @@ void EscenaJoc::dibuixar_continue() {
float escala_info = Defaults::Game::ContinueScreen::INFO_TEXT_SCALE; float escala_info = Defaults::Game::ContinueScreen::INFO_TEXT_SCALE;
float y_ratio_info = Defaults::Game::ContinueScreen::INFO_TEXT_Y_RATIO; float y_ratio_info = Defaults::Game::ContinueScreen::INFO_TEXT_Y_RATIO;
float text_width_info = text_.get_text_width(continues_text, escala_info, spacing); float centre_y_info = play_area.y + play_area.h * y_ratio_info;
float x_info = play_area.x + (play_area.w - text_width_info) / 2.0f;
float y_info = play_area.y + play_area.h * y_ratio_info;
text_.render(continues_text, {x_info, y_info}, escala_info, spacing); text_.render_centered(continues_text, {centre_x, centre_y_info}, escala_info, spacing);
} }
} }

View File

@@ -420,8 +420,8 @@ void EscenaTitol::actualitzar(float delta_time) {
} }
} }
// Reproducir so de LASER quan el segon jugador s'uneix // Reproducir so de START quan el segon jugador s'uneix
Audio::get()->playSound(Defaults::Sound::LASER, Audio::Group::GAME); Audio::get()->playSound(Defaults::Sound::START, Audio::Group::GAME);
// Reiniciar el timer per allargar el temps de transició // Reiniciar el timer per allargar el temps de transició
temps_acumulat_ = 0.0f; temps_acumulat_ = 0.0f;
@@ -496,7 +496,7 @@ void EscenaTitol::actualitzar(float delta_time) {
} }
Audio::get()->fadeOutMusic(MUSIC_FADE); Audio::get()->fadeOutMusic(MUSIC_FADE);
Audio::get()->playSound(Defaults::Sound::LASER, Audio::Group::GAME); Audio::get()->playSound(Defaults::Sound::START, Audio::Group::GAME);
} }
} }
} }
@@ -652,12 +652,10 @@ void EscenaTitol::dibuixar() {
const std::string main_text = "PRESS START TO PLAY"; const std::string main_text = "PRESS START TO PLAY";
const float escala_main = Defaults::Title::Layout::PRESS_START_SCALE; const float escala_main = Defaults::Title::Layout::PRESS_START_SCALE;
float text_width = text_.get_text_width(main_text, escala_main, spacing); float centre_x = Defaults::Game::WIDTH / 2.0f;
float centre_y = Defaults::Game::HEIGHT * Defaults::Title::Layout::PRESS_START_POS;
float x_center = (Defaults::Game::WIDTH - text_width) / 2.0f; text_.render_centered(main_text, {centre_x, centre_y}, escala_main, spacing);
float y_center = Defaults::Game::HEIGHT * Defaults::Title::Layout::PRESS_START_POS;
text_.render(main_text, Punt{x_center, y_center}, escala_main, spacing);
} }
// === Copyright a la part inferior (centrat horitzontalment, dues línies) === // === Copyright a la part inferior (centrat horitzontalment, dues línies) ===
@@ -681,15 +679,11 @@ void EscenaTitol::dibuixar() {
float y_line1 = Defaults::Game::HEIGHT * Defaults::Title::Layout::COPYRIGHT1_POS; float y_line1 = Defaults::Game::HEIGHT * Defaults::Title::Layout::COPYRIGHT1_POS;
float y_line2 = y_line1 + copy_height + line_spacing; // Línea 2 debajo de línea 1 float y_line2 = y_line1 + copy_height + line_spacing; // Línea 2 debajo de línea 1
// Renderitzar línea 1 (original) // Renderitzar línees centrades
float width_line1 = text_.get_text_width(copyright_original, escala_copy, spacing); float centre_x = Defaults::Game::WIDTH / 2.0f;
float x_line1 = (Defaults::Game::WIDTH - width_line1) / 2.0f;
text_.render(copyright_original, Punt{x_line1, y_line1}, escala_copy, spacing);
// Renderitzar línea 2 (port) text_.render_centered(copyright_original, {centre_x, y_line1}, escala_copy, spacing);
float width_line2 = text_.get_text_width(copyright_port, escala_copy, spacing); text_.render_centered(copyright_port, {centre_x, y_line2}, escala_copy, spacing);
float x_line2 = (Defaults::Game::WIDTH - width_line2) / 2.0f;
text_.render(copyright_port, Punt{x_line2, y_line2}, escala_copy, spacing);
} }
} }