Title screen: copyright único + logo JAILGAMES encima

Sustituye las dos líneas de copyright (Pascal original 1999 + port 2025)
por una sola línea "© 2026 JAILDESIGNER" centrada en la posición de la
antigua primera línea. Encima, en el espacio liberado, se muestra el
logo vectorial JAILGAMES en pequeño (escala 0.25, las mismas letras
que usa LogoScene).

Cambios:
- CMakeLists.txt: PROJECT_COPYRIGHT pasa a "© 2026 JailDesigner".
  Eliminadas las variables intermedias PROJECT_COPYRIGHT_ORIGINAL y
  PROJECT_COPYRIGHT_PORT (ya no se referenciaban en otro sitio).
- project.h.in: fuera Project::COPYRIGHT_ORIGINAL y Project::COPYRIGHT_PORT.
- Defaults::Title::Layout: nuevas constantes JAILGAMES_SCALE (0.25) y
  JAILGAMES_COPYRIGHT_GAP (1.5% de la altura lógica) para el espaciado.
- TitleScene: nuevo helper inicialitzarJailgames() que carga las 9
  letras y las posiciona centradas justo encima de la línea de copyright.
  El bloque del pie del título sale del draw() a un dibuixarPeuTitol()
  para mantener la complejidad cognitiva por debajo del umbral del linter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 09:46:38 +02:00
parent 89a9f06324
commit 8c251d2246
5 changed files with 108 additions and 36 deletions
+97 -30
View File
@@ -91,6 +91,9 @@ TitleScene::TitleScene(SDLManager& sdl, SceneContext& context)
// Inicialitzar lletres del título "ORNI ATTACK!"
inicialitzar_titol();
// Logo JAILGAMES pequeño sobre el copyright inferior.
inicialitzarJailgames();
// Iniciar música de título si no está sonant
if (Audio::getMusicState() != Audio::MusicState::PLAYING) {
Audio::get()->playMusic("title.ogg");
@@ -254,6 +257,99 @@ void TitleScene::inicialitzar_titol() {
std::cout << "[TitleScene] Animación: Posicions originals guardades\n";
}
void TitleScene::inicialitzarJailgames() {
using namespace Graphics;
// Mismas letras que la LogoScene, mismo orden (J-A-I-L-G-A-M-E-S).
const std::vector<std::string> FITXERS = {
"logo/letra_j.shp",
"logo/letra_a.shp",
"logo/letra_i.shp",
"logo/letra_l.shp",
"logo/letra_g.shp",
"logo/letra_a.shp",
"logo/letra_m.shp",
"logo/letra_e.shp",
"logo/letra_s.shp"};
constexpr float SCALE = Defaults::Title::Layout::JAILGAMES_SCALE;
// Pas 1: carregar formes i calcular amplada/altura escalades.
float ancho_total = 0.0F;
float altura_max = 0.0F;
for (const auto& file : FITXERS) {
auto shape = ShapeLoader::load(file);
if (!shape || !shape->isValid()) {
std::cerr << "[TitleScene] Error carregant " << file << '\n';
continue;
}
float min_x = FLT_MAX;
float max_x = -FLT_MAX;
float min_y = FLT_MAX;
float max_y = -FLT_MAX;
for (const auto& prim : shape->get_primitives()) {
for (const auto& point : prim.points) {
min_x = std::min(min_x, point.x);
max_x = std::max(max_x, point.x);
min_y = std::min(min_y, point.y);
max_y = std::max(max_y, point.y);
}
}
const float ANCHO = (max_x - min_x) * SCALE;
const float ALTURA = (max_y - min_y) * SCALE;
const float OFFSET_CENTRE = (shape->getCenter().x - min_x) * SCALE;
lletres_jailgames_.push_back({shape, {.x = 0.0F, .y = 0.0F},
ANCHO, ALTURA, OFFSET_CENTRE});
ancho_total += ANCHO;
altura_max = std::max(altura_max, ALTURA);
}
// Espaiat entre lletres (proporcional a la escala, para que no quede pegado).
constexpr float ESPAI_JAILGAMES = ESPAI_ENTRE_LLETRES * SCALE;
if (!lletres_jailgames_.empty()) {
ancho_total += ESPAI_JAILGAMES * static_cast<float>(lletres_jailgames_.size() - 1);
}
// Pas 2: centrar horizontalmente y colocar JUST encima de la línea de copyright.
const float Y_COPYRIGHT = Defaults::Game::HEIGHT * Defaults::Title::Layout::COPYRIGHT1_POS;
const float GAP = Defaults::Game::HEIGHT * Defaults::Title::Layout::JAILGAMES_COPYRIGHT_GAP;
const float Y_CENTRE = Y_COPYRIGHT - GAP - (altura_max / 2.0F);
const float X_INICIAL = (Defaults::Game::WIDTH - ancho_total) / 2.0F;
float x_actual = X_INICIAL;
for (auto& lletra : lletres_jailgames_) {
lletra.position.x = x_actual + lletra.offset_centre;
lletra.position.y = Y_CENTRE;
x_actual += lletra.ancho + ESPAI_JAILGAMES;
}
}
void TitleScene::dibuixarPeuTitol(float spacing) const {
// Logo JAILGAMES pequeño sobre el copyright.
for (const auto& lletra : lletres_jailgames_) {
Rendering::render_shape(sdl_.getRenderer(), lletra.shape,
lletra.position, 0.0F,
Defaults::Title::Layout::JAILGAMES_SCALE,
1.0F);
}
// Copyright en una sola línea, centrado, en mayúsculas.
std::string copyright = Project::COPYRIGHT;
for (char& c : copyright) {
if (c >= 'a' && c <= 'z') {
c = static_cast<char>(c - 32);
}
}
const float Y_COPY = Defaults::Game::HEIGHT * Defaults::Title::Layout::COPYRIGHT1_POS;
const float CENTRE_X = Defaults::Game::WIDTH / 2.0F;
text_.renderCentered(copyright, {.x = CENTRE_X, .y = Y_COPY},
Defaults::Title::Layout::COPYRIGHT_SCALE, spacing);
}
auto TitleScene::isFinished() const -> bool {
return context_.nextScene() != SceneType::TITLE;
}
@@ -604,36 +700,7 @@ void TitleScene::draw() {
text_.renderCentered(main_text, {.x = centre_x, .y = centre_y}, escala_main, spacing);
}
// === Copyright a la part inferior (centrat horitzontalment, dues línies) ===
const float escala_copy = Defaults::Title::Layout::COPYRIGHT_SCALE;
const float copy_height = text_.get_text_height(escala_copy);
const float line_spacing = Defaults::Game::HEIGHT * Defaults::Title::Layout::COPYRIGHT_LINE_SPACING;
// Línea 1: Original (© 1999 Visente i Sergi)
std::string copyright_original = Project::COPYRIGHT_ORIGINAL;
for (char& c : copyright_original) {
if (c >= 'a' && c <= 'z') {
c = c - 32; // Uppercase
}
}
// Línea 2: Port (© 2025 jaildesigner)
std::string copyright_port = Project::COPYRIGHT_PORT;
for (char& c : copyright_port) {
if (c >= 'a' && c <= 'z') {
c = c - 32; // Uppercase
}
}
// Calcular posicions (anclatge des del top + separació)
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
// Renderizar línees centrades
float centre_x = Defaults::Game::WIDTH / 2.0F;
text_.renderCentered(copyright_original, {.x = centre_x, .y = y_line1}, escala_copy, spacing);
text_.renderCentered(copyright_port, {.x = centre_x, .y = y_line2}, escala_copy, spacing);
dibuixarPeuTitol(spacing);
}
}