afegit titol al TITOL
This commit is contained in:
@@ -3,11 +3,14 @@
|
||||
|
||||
#include "escena_titol.hpp"
|
||||
|
||||
#include <cfloat>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "core/audio/audio.hpp"
|
||||
#include "core/graphics/shape_loader.hpp"
|
||||
#include "core/input/mouse.hpp"
|
||||
#include "core/rendering/shape_renderer.hpp"
|
||||
#include "core/system/gestor_escenes.hpp"
|
||||
#include "core/system/global_events.hpp"
|
||||
#include "project.h"
|
||||
@@ -25,7 +28,8 @@ EscenaTitol::EscenaTitol(SDLManager& sdl)
|
||||
Defaults::Game::HEIGHT / 2.0f};
|
||||
|
||||
SDL_FRect area_completa{
|
||||
0, 0,
|
||||
0,
|
||||
0,
|
||||
static_cast<float>(Defaults::Game::WIDTH),
|
||||
static_cast<float>(Defaults::Game::HEIGHT)};
|
||||
|
||||
@@ -35,6 +39,146 @@ EscenaTitol::EscenaTitol(SDLManager& sdl)
|
||||
area_completa,
|
||||
150 // densitat: 150 estrelles (50 per capa)
|
||||
);
|
||||
|
||||
// Inicialitzar lletres del títol "ORNI ATTACK!"
|
||||
inicialitzar_titol();
|
||||
}
|
||||
|
||||
void EscenaTitol::inicialitzar_titol() {
|
||||
using namespace Graphics;
|
||||
|
||||
// === LÍNIA 1: "ORNI" ===
|
||||
std::vector<std::string> fitxers_orni = {
|
||||
"title/letra_o.shp",
|
||||
"title/letra_r.shp",
|
||||
"title/letra_n.shp",
|
||||
"title/letra_i.shp"};
|
||||
|
||||
// Pas 1: Carregar formes i calcular amplades per "ORNI"
|
||||
float ancho_total_orni = 0.0f;
|
||||
|
||||
for (const auto& fitxer : fitxers_orni) {
|
||||
auto forma = ShapeLoader::load(fitxer);
|
||||
if (!forma || !forma->es_valida()) {
|
||||
std::cerr << "[EscenaTitol] Error carregant " << fitxer << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calcular bounding box de la forma (trobar ancho i altura)
|
||||
float min_x = FLT_MAX;
|
||||
float max_x = -FLT_MAX;
|
||||
float min_y = FLT_MAX;
|
||||
float max_y = -FLT_MAX;
|
||||
|
||||
for (const auto& prim : forma->get_primitives()) {
|
||||
for (const auto& punt : prim.points) {
|
||||
min_x = std::min(min_x, punt.x);
|
||||
max_x = std::max(max_x, punt.x);
|
||||
min_y = std::min(min_y, punt.y);
|
||||
max_y = std::max(max_y, punt.y);
|
||||
}
|
||||
}
|
||||
|
||||
float ancho_sin_escalar = max_x - min_x;
|
||||
float altura_sin_escalar = max_y - min_y;
|
||||
|
||||
// Escalar ancho, altura i offset amb ESCALA_TITULO
|
||||
float ancho = ancho_sin_escalar * ESCALA_TITULO;
|
||||
float altura = altura_sin_escalar * ESCALA_TITULO;
|
||||
float offset_centre = (forma->get_centre().x - min_x) * ESCALA_TITULO;
|
||||
|
||||
lletres_orni_.push_back({forma, {0.0f, 0.0f}, ancho, altura, offset_centre});
|
||||
|
||||
ancho_total_orni += ancho;
|
||||
}
|
||||
|
||||
// Afegir espaiat entre lletres
|
||||
ancho_total_orni += ESPAI_ENTRE_LLETRES * (lletres_orni_.size() - 1);
|
||||
|
||||
// Calcular posició inicial (centrat horitzontal) per "ORNI"
|
||||
float x_inicial_orni = (Defaults::Game::WIDTH - ancho_total_orni) / 2.0f;
|
||||
float x_actual = x_inicial_orni;
|
||||
|
||||
for (auto& lletra : lletres_orni_) {
|
||||
lletra.posicio.x = x_actual + lletra.offset_centre;
|
||||
lletra.posicio.y = Y_ORNI;
|
||||
x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES;
|
||||
}
|
||||
|
||||
std::cout << "[EscenaTitol] Línia 1 (ORNI): " << lletres_orni_.size()
|
||||
<< " lletres, ancho total: " << ancho_total_orni << " px\n";
|
||||
|
||||
// === Calcular posició Y dinàmica per "ATTACK!" ===
|
||||
// Totes les lletres ORNI tenen la mateixa altura, utilitzem la primera
|
||||
float altura_orni = lletres_orni_.empty() ? 50.0f : lletres_orni_[0].altura;
|
||||
y_attack_dinamica_ = Y_ORNI + altura_orni + SEPARACION_LINEAS;
|
||||
|
||||
std::cout << "[EscenaTitol] Altura ORNI: " << altura_orni
|
||||
<< " px, Y_ATTACK dinàmica: " << y_attack_dinamica_ << " px\n";
|
||||
|
||||
// === LÍNIA 2: "ATTACK!" ===
|
||||
std::vector<std::string> fitxers_attack = {
|
||||
"title/letra_a.shp",
|
||||
"title/letra_t.shp",
|
||||
"title/letra_t.shp", // T repetida
|
||||
"title/letra_a.shp", // A repetida
|
||||
"title/letra_c.shp",
|
||||
"title/letra_k.shp",
|
||||
"title/letra_exclamacion.shp"};
|
||||
|
||||
// Pas 1: Carregar formes i calcular amplades per "ATTACK!"
|
||||
float ancho_total_attack = 0.0f;
|
||||
|
||||
for (const auto& fitxer : fitxers_attack) {
|
||||
auto forma = ShapeLoader::load(fitxer);
|
||||
if (!forma || !forma->es_valida()) {
|
||||
std::cerr << "[EscenaTitol] Error carregant " << fitxer << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calcular bounding box de la forma (trobar ancho i altura)
|
||||
float min_x = FLT_MAX;
|
||||
float max_x = -FLT_MAX;
|
||||
float min_y = FLT_MAX;
|
||||
float max_y = -FLT_MAX;
|
||||
|
||||
for (const auto& prim : forma->get_primitives()) {
|
||||
for (const auto& punt : prim.points) {
|
||||
min_x = std::min(min_x, punt.x);
|
||||
max_x = std::max(max_x, punt.x);
|
||||
min_y = std::min(min_y, punt.y);
|
||||
max_y = std::max(max_y, punt.y);
|
||||
}
|
||||
}
|
||||
|
||||
float ancho_sin_escalar = max_x - min_x;
|
||||
float altura_sin_escalar = max_y - min_y;
|
||||
|
||||
// Escalar ancho, altura i offset amb ESCALA_TITULO
|
||||
float ancho = ancho_sin_escalar * ESCALA_TITULO;
|
||||
float altura = altura_sin_escalar * ESCALA_TITULO;
|
||||
float offset_centre = (forma->get_centre().x - min_x) * ESCALA_TITULO;
|
||||
|
||||
lletres_attack_.push_back({forma, {0.0f, 0.0f}, ancho, altura, offset_centre});
|
||||
|
||||
ancho_total_attack += ancho;
|
||||
}
|
||||
|
||||
// Afegir espaiat entre lletres
|
||||
ancho_total_attack += ESPAI_ENTRE_LLETRES * (lletres_attack_.size() - 1);
|
||||
|
||||
// Calcular posició inicial (centrat horitzontal) per "ATTACK!"
|
||||
float x_inicial_attack = (Defaults::Game::WIDTH - ancho_total_attack) / 2.0f;
|
||||
x_actual = x_inicial_attack;
|
||||
|
||||
for (auto& lletra : lletres_attack_) {
|
||||
lletra.posicio.x = x_actual + lletra.offset_centre;
|
||||
lletra.posicio.y = y_attack_dinamica_; // Usar posició dinàmica
|
||||
x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES;
|
||||
}
|
||||
|
||||
std::cout << "[EscenaTitol] Línia 2 (ATTACK!): " << lletres_attack_.size()
|
||||
<< " lletres, ancho total: " << ancho_total_attack << " px\n";
|
||||
}
|
||||
|
||||
void EscenaTitol::executar() {
|
||||
@@ -129,22 +273,51 @@ void EscenaTitol::dibuixar() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Estat MAIN: Dibuixar text de títol i copyright (sobre el starfield)
|
||||
// Estat MAIN: Dibuixar títol i text (sobre el starfield)
|
||||
if (estat_actual_ == EstatTitol::MAIN) {
|
||||
// Text principal centrat (vertical i horitzontalment)
|
||||
// === Dibuixar lletres del títol "ORNI ATTACK!" ===
|
||||
|
||||
// Dibuixar "ORNI" (línia 1)
|
||||
for (const auto& lletra : lletres_orni_) {
|
||||
Rendering::render_shape(
|
||||
sdl_.obte_renderer(),
|
||||
lletra.forma,
|
||||
lletra.posicio,
|
||||
0.0f, // sense rotació
|
||||
ESCALA_TITULO, // escala 80%
|
||||
true, // dibuixar
|
||||
1.0f // progrés complet (totalment visible)
|
||||
);
|
||||
}
|
||||
|
||||
// Dibuixar "ATTACK!" (línia 2)
|
||||
for (const auto& lletra : lletres_attack_) {
|
||||
Rendering::render_shape(
|
||||
sdl_.obte_renderer(),
|
||||
lletra.forma,
|
||||
lletra.posicio,
|
||||
0.0f, // sense rotació
|
||||
ESCALA_TITULO, // escala 80%
|
||||
true, // dibuixar
|
||||
1.0f // progrés complet (totalment visible)
|
||||
);
|
||||
}
|
||||
|
||||
// === Text "PRESS BUTTON TO PLAY" (a sota del títol) ===
|
||||
const std::string main_text = "PRESS BUTTON TO PLAY";
|
||||
const float escala_main = 1.0f;
|
||||
const float spacing = 2.0f;
|
||||
|
||||
float text_width = text_.get_text_width(main_text, escala_main, spacing);
|
||||
float text_height = text_.get_text_height(escala_main);
|
||||
|
||||
float x_center = (Defaults::Game::WIDTH - text_width) / 2.0f;
|
||||
float y_center = (Defaults::Game::HEIGHT - text_height) / 2.0f;
|
||||
// Usar posició dinàmica: ATTACK + altura lletres + separació
|
||||
float altura_attack = lletres_attack_.empty() ? 50.0f : lletres_attack_[0].altura;
|
||||
float y_center = y_attack_dinamica_ + altura_attack + 70.0f; // 70px sota "ATTACK!"
|
||||
|
||||
text_.render(main_text, Punt{x_center, y_center}, escala_main, spacing);
|
||||
|
||||
// Copyright a la part inferior (centrat horitzontalment)
|
||||
// === Copyright a la part inferior (centrat horitzontalment) ===
|
||||
// Convert to uppercase since VectorText only supports A-Z
|
||||
std::string copyright = Project::COPYRIGHT;
|
||||
for (char& c : copyright) {
|
||||
@@ -168,7 +341,6 @@ void EscenaTitol::processar_events(const SDL_Event& event) {
|
||||
// Qualsevol tecla o clic de ratolí
|
||||
if (event.type == SDL_EVENT_KEY_DOWN ||
|
||||
event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
|
||||
|
||||
switch (estat_actual_) {
|
||||
case EstatTitol::INIT:
|
||||
// Saltar a MAIN
|
||||
|
||||
Reference in New Issue
Block a user