el marcador fake ja es pinta correctament

This commit is contained in:
2025-12-01 23:47:42 +01:00
parent 5210448ac9
commit 67681e0f37
11 changed files with 128 additions and 120 deletions

View File

@@ -1,7 +1,7 @@
# CMakeLists.txt # CMakeLists.txt
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(orni VERSION 0.1.0) project(orni VERSION 0.2.0)
# Info del proyecto # Info del proyecto
set(PROJECT_LONG_NAME "Orni Attack") set(PROJECT_LONG_NAME "Orni Attack")

View File

@@ -4,9 +4,9 @@
#ifndef SDL_MANAGER_HPP #ifndef SDL_MANAGER_HPP
#define SDL_MANAGER_HPP #define SDL_MANAGER_HPP
#include "core/rendering/color_oscillator.hpp"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <cstdint> #include <cstdint>
#include "core/rendering/color_oscillator.hpp"
class SDLManager { class SDLManager {
public: public:

View File

@@ -7,10 +7,12 @@
namespace Constants { namespace Constants {
// Marges de l'àrea de joc (derivats de Defaults::Zones::GAME) // Marges de l'àrea de joc (derivats de Defaults::Zones::GAME)
constexpr int MARGE_ESQ = static_cast<int>(Defaults::Zones::GAME.x); constexpr int MARGE_ESQ = static_cast<int>(Defaults::Zones::PLAYAREA.x);
constexpr int MARGE_DRET = static_cast<int>(Defaults::Zones::GAME.x + Defaults::Zones::GAME.w); constexpr int MARGE_DRET =
constexpr int MARGE_DALT = static_cast<int>(Defaults::Zones::GAME.y); static_cast<int>(Defaults::Zones::PLAYAREA.x + Defaults::Zones::PLAYAREA.w);
constexpr int MARGE_BAIX = static_cast<int>(Defaults::Zones::GAME.y + Defaults::Zones::GAME.h); constexpr int MARGE_DALT = static_cast<int>(Defaults::Zones::PLAYAREA.y);
constexpr int MARGE_BAIX =
static_cast<int>(Defaults::Zones::PLAYAREA.y + Defaults::Zones::PLAYAREA.h);
// Límits de polígons i objectes // Límits de polígons i objectes
constexpr int MAX_IPUNTS = Defaults::Entities::MAX_IPUNTS; constexpr int MAX_IPUNTS = Defaults::Entities::MAX_IPUNTS;
@@ -27,11 +29,12 @@ constexpr float PI = Defaults::Math::PI;
// Helpers per comprovar límits de zona // Helpers per comprovar límits de zona
inline bool dins_zona_joc(float x, float y) { inline bool dins_zona_joc(float x, float y) {
const SDL_FPoint punt = {x, y}; const SDL_FPoint punt = {x, y};
return SDL_PointInRectFloat(&punt, &Defaults::Zones::GAME); return SDL_PointInRectFloat(&punt, &Defaults::Zones::PLAYAREA);
} }
inline void obtenir_limits_zona(float& min_x, float& max_x, float& min_y, float& max_y) { inline void obtenir_limits_zona(float &min_x, float &max_x, float &min_y,
const auto& zona = Defaults::Zones::GAME; float &max_y) {
const auto &zona = Defaults::Zones::PLAYAREA;
min_x = zona.x; min_x = zona.x;
max_x = zona.x + zona.w; max_x = zona.x + zona.w;
min_y = zona.y; min_y = zona.y;

View File

@@ -27,8 +27,8 @@ void Enemic::inicialitzar() {
// Inicialitzar enemic (pentàgon) // Inicialitzar enemic (pentàgon)
// Copiat de joc_asteroides.cpp línies 41-54 // Copiat de joc_asteroides.cpp línies 41-54
// [NUEVO] Ja no cal crear_poligon_regular - la geometria es carrega del fitxer // [NUEVO] Ja no cal crear_poligon_regular - la geometria es carrega del
// Només inicialitzem l'estat de la instància // fitxer Només inicialitzem l'estat de la instància
// Posició aleatòria dins de l'àrea de joc // Posició aleatòria dins de l'àrea de joc
centre_.x = static_cast<float>((std::rand() % 580) + 30); // 30-610 centre_.x = static_cast<float>((std::rand() % 580) + 30); // 30-610

View File

@@ -30,10 +30,10 @@ private:
// [NUEVO] Estat de la instància (separat de la geometria) // [NUEVO] Estat de la instància (separat de la geometria)
Punt centre_; Punt centre_;
float angle_; // Angle de moviment float angle_; // Angle de moviment
float velocitat_; float velocitat_;
float drotacio_; // Delta rotació visual (rad/s) float drotacio_; // Delta rotació visual (rad/s)
float rotacio_; // Rotació visual acumulada float rotacio_; // Rotació visual acumulada
bool esta_; bool esta_;
void mou(float delta_time); void mou(float delta_time);

View File

@@ -28,8 +28,8 @@ void Nau::inicialitzar() {
// Basat en el codi Pascal original: lines 380-384 // Basat en el codi Pascal original: lines 380-384
// Copiat de joc_asteroides.cpp línies 30-44 // Copiat de joc_asteroides.cpp línies 30-44
// [NUEVO] Ja no cal configurar punts polars - la geometria es carrega del fitxer // [NUEVO] Ja no cal configurar punts polars - la geometria es carrega del
// Només inicialitzem l'estat de la instància // fitxer Només inicialitzem l'estat de la instància
// Posició inicial al centre de la pantalla // Posició inicial al centre de la pantalla
centre_.x = 320.0f; centre_.x = 320.0f;

View File

@@ -29,13 +29,14 @@ public:
private: private:
SDL_Renderer *renderer_; SDL_Renderer *renderer_;
// [NUEVO] Forma vectorial (compartida, només 1 instància de Nau però preparat per reutilització) // [NUEVO] Forma vectorial (compartida, només 1 instància de Nau però preparat
// per reutilització)
std::shared_ptr<Graphics::Shape> forma_; std::shared_ptr<Graphics::Shape> forma_;
// [NUEVO] Estat de la instància (separat de la geometria) // [NUEVO] Estat de la instància (separat de la geometria)
Punt centre_; Punt centre_;
float angle_; // Angle d'orientació float angle_; // Angle d'orientació
float velocitat_; // Velocitat (px/s) float velocitat_; // Velocitat (px/s)
bool esta_tocada_; bool esta_tocada_;
void aplicar_fisica(float delta_time); void aplicar_fisica(float delta_time);

View File

@@ -11,8 +11,9 @@
#include <ctime> #include <ctime>
#include <iostream> #include <iostream>
EscenaJoc::EscenaJoc(SDLManager& sdl) EscenaJoc::EscenaJoc(SDLManager &sdl)
: sdl_(sdl), nau_(sdl.obte_renderer()), itocado_(0), text_(sdl.obte_renderer()) { : sdl_(sdl), nau_(sdl.obte_renderer()), itocado_(0),
text_(sdl.obte_renderer()) {
// Inicialitzar bales amb renderer // Inicialitzar bales amb renderer
for (auto &bala : bales_) { for (auto &bala : bales_) {
bala = Bala(sdl.obte_renderer()); bala = Bala(sdl.obte_renderer());
@@ -171,7 +172,7 @@ void EscenaJoc::tocado() {
void EscenaJoc::dibuixar_marges() const { void EscenaJoc::dibuixar_marges() const {
// Dibuixar rectangle de la zona de joc // Dibuixar rectangle de la zona de joc
const SDL_FRect& zona = Defaults::Zones::GAME; const SDL_FRect &zona = Defaults::Zones::PLAYAREA;
// Coordenades dels cantons // Coordenades dels cantons
int x1 = static_cast<int>(zona.x); int x1 = static_cast<int>(zona.x);
@@ -188,25 +189,22 @@ void EscenaJoc::dibuixar_marges() const {
void EscenaJoc::dibuixar_marcador() { void EscenaJoc::dibuixar_marcador() {
// Text estàtic (hardcoded) // Text estàtic (hardcoded)
const std::string text = "SCORE: 00000 LIFE: 3 LEVEL: 01"; const std::string text = "SCORE: 01000 LIFE: 3 LEVEL: 01";
// Escala ajustada per cabre en 640px d'amplada // Paràmetres de renderització
// Zona marcador: width = 640 px, height = 64 px const float escala = 0.85f;
// Text: 34 caràcters → necessitem ~487 px amb escala 1.2 const float spacing = 0.0f;
// Altura caràcter: 20 * 1.2 = 24 px (37.5% de 64px)
const float escala = 1.2f;
const float spacing = 2.0f;
// Calcular amplada total del text // Calcular dimensions del text
float text_width = text_.get_text_width(text, escala, spacing); float text_width = text_.get_text_width(text, escala, spacing);
float text_height = text_.get_text_height(escala);
// Centrat horitzontal // Centrat horitzontal dins de la zona del marcador
float x = (Defaults::Zones::SCOREBOARD.w - text_width) / 2.0f; float x = (Defaults::Zones::SCOREBOARD.w - text_width) / 2.0f;
// Centrat vertical // Centrat vertical dins de la zona del marcador
// Altura del caràcter escalat: 20 * 1.2 = 24 px float y = Defaults::Zones::SCOREBOARD.y +
// Marge superior: (64 - 24) / 2 = 20 px (Defaults::Zones::SCOREBOARD.h - text_height) / 2.0f;
float y = Defaults::Zones::SCOREBOARD.y + 20.0f;
// Renderitzar // Renderitzar
text_.render(text, {x, y}, escala, spacing); text_.render(text, {x, y}, escala, spacing);

View File

@@ -19,17 +19,17 @@
// Classe principal del joc (escena) // Classe principal del joc (escena)
class EscenaJoc { class EscenaJoc {
public: public:
explicit EscenaJoc(SDLManager& sdl); explicit EscenaJoc(SDLManager &sdl);
~EscenaJoc() = default; ~EscenaJoc() = default;
void executar(); // Bucle principal de l'escena void executar(); // Bucle principal de l'escena
void inicialitzar(); void inicialitzar();
void actualitzar(float delta_time); void actualitzar(float delta_time);
void dibuixar(); void dibuixar();
void processar_input(const SDL_Event &event); void processar_input(const SDL_Event &event);
private: private:
SDLManager& sdl_; SDLManager &sdl_;
// Estat del joc // Estat del joc
Nau nau_; Nau nau_;

View File

@@ -2,20 +2,18 @@
// © 2025 Port a C++20 // © 2025 Port a C++20
#include "escena_logo.hpp" #include "escena_logo.hpp"
#include "../../core/system/gestor_escenes.hpp"
#include "../../core/system/global_events.hpp"
#include "../../core/graphics/shape_loader.hpp" #include "../../core/graphics/shape_loader.hpp"
#include "../../core/rendering/shape_renderer.hpp" #include "../../core/rendering/shape_renderer.hpp"
#include <iostream> #include "../../core/system/gestor_escenes.hpp"
#include <cfloat> #include "../../core/system/global_events.hpp"
#include <algorithm> #include <algorithm>
#include <cfloat>
#include <iostream>
// Helper: calcular el progrés individual d'una lletra // Helper: calcular el progrés individual d'una lletra
// en funció del progrés global (efecte seqüencial) // en funció del progrés global (efecte seqüencial)
static float calcular_progress_letra(size_t letra_index, static float calcular_progress_letra(size_t letra_index, size_t num_letras,
size_t num_letras, float global_progress, float threshold) {
float global_progress,
float threshold) {
if (num_letras == 0) if (num_letras == 0)
return 1.0f; return 1.0f;
@@ -27,18 +25,17 @@ static float calcular_progress_letra(size_t letra_index,
// Interpolar progrés // Interpolar progrés
if (global_progress < start) { if (global_progress < start) {
return 0.0f; // Encara no ha començat return 0.0f; // Encara no ha començat
} else if (global_progress >= end) { } else if (global_progress >= end) {
return 1.0f; // Completament apareguda return 1.0f; // Completament apareguda
} else { } else {
return (global_progress - start) / (end - start); return (global_progress - start) / (end - start);
} }
} }
EscenaLogo::EscenaLogo(SDLManager& sdl) EscenaLogo::EscenaLogo(SDLManager &sdl)
: sdl_(sdl), : sdl_(sdl), estat_actual_(EstatAnimacio::PRE_ANIMATION),
estat_actual_(EstatAnimacio::PRE_ANIMATION), temps_estat_actual_(0.0f) {
temps_estat_actual_(0.0f) {
std::cout << "Escena Logo: Inicialitzant...\n"; std::cout << "Escena Logo: Inicialitzant...\n";
inicialitzar_lletres(); inicialitzar_lletres();
} }
@@ -92,14 +89,14 @@ void EscenaLogo::inicialitzar_lletres() {
// Llista de fitxers .shp (A repetida per a les dues A's) // Llista de fitxers .shp (A repetida per a les dues A's)
std::vector<std::string> fitxers = { std::vector<std::string> fitxers = {
"logo/letra_j.shp", "logo/letra_a.shp", "logo/letra_i.shp", "logo/letra_l.shp", "logo/letra_j.shp", "logo/letra_a.shp", "logo/letra_i.shp",
"logo/letra_g.shp", "logo/letra_a.shp", "logo/letra_m.shp", "logo/letra_e.shp", "logo/letra_s.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"};
// Pas 1: Carregar totes les formes i calcular amplades // Pas 1: Carregar totes les formes i calcular amplades
float ancho_total = 0.0f; float ancho_total = 0.0f;
for (const auto& fitxer : fitxers) { for (const auto &fitxer : fitxers) {
auto forma = ShapeLoader::load(fitxer); auto forma = ShapeLoader::load(fitxer);
if (!forma || !forma->es_valida()) { if (!forma || !forma->es_valida()) {
std::cerr << "[EscenaLogo] Error carregant " << fitxer << std::endl; std::cerr << "[EscenaLogo] Error carregant " << fitxer << std::endl;
@@ -110,8 +107,8 @@ void EscenaLogo::inicialitzar_lletres() {
float min_x = FLT_MAX; float min_x = FLT_MAX;
float max_x = -FLT_MAX; float max_x = -FLT_MAX;
for (const auto& prim : forma->get_primitives()) { for (const auto &prim : forma->get_primitives()) {
for (const auto& punt : prim.points) { for (const auto &punt : prim.points) {
min_x = std::min(min_x, punt.x); min_x = std::min(min_x, punt.x);
max_x = std::max(max_x, punt.x); max_x = std::max(max_x, punt.x);
} }
@@ -124,12 +121,10 @@ void EscenaLogo::inicialitzar_lletres() {
float ancho = ancho_sin_escalar * ESCALA_FINAL; float ancho = ancho_sin_escalar * ESCALA_FINAL;
float offset_centre = (forma->get_centre().x - min_x) * ESCALA_FINAL; float offset_centre = (forma->get_centre().x - min_x) * ESCALA_FINAL;
lletres_.push_back({ lletres_.push_back({forma,
forma, {0.0f, 0.0f}, // Posició es calcularà després
{0.0f, 0.0f}, // Posició es calcularà després ancho,
ancho, offset_centre});
offset_centre
});
ancho_total += ancho; ancho_total += ancho;
} }
@@ -147,7 +142,7 @@ void EscenaLogo::inicialitzar_lletres() {
// Pas 4: Assignar posicions a cada lletra // Pas 4: Assignar posicions a cada lletra
float x_actual = x_inicial; float x_actual = x_inicial;
for (auto& lletra : lletres_) { for (auto &lletra : lletres_) {
// Posicionar el centre de la forma (shape_centre) en pantalla // Posicionar el centre de la forma (shape_centre) en pantalla
// Usar offset_centre en lloc de ancho/2 perquè shape_centre // Usar offset_centre en lloc de ancho/2 perquè shape_centre
// pot no estar exactament al mig del bounding box // pot no estar exactament al mig del bounding box
@@ -164,8 +159,9 @@ void EscenaLogo::inicialitzar_lletres() {
void EscenaLogo::canviar_estat(EstatAnimacio nou_estat) { void EscenaLogo::canviar_estat(EstatAnimacio nou_estat) {
estat_actual_ = nou_estat; estat_actual_ = nou_estat;
temps_estat_actual_ = 0.0f; // Reset temps temps_estat_actual_ = 0.0f; // Reset temps
std::cout << "[EscenaLogo] Canvi a estat: " << static_cast<int>(nou_estat) << "\n"; std::cout << "[EscenaLogo] Canvi a estat: " << static_cast<int>(nou_estat)
<< "\n";
} }
bool EscenaLogo::totes_lletres_completes() const { bool EscenaLogo::totes_lletres_completes() const {
@@ -177,23 +173,23 @@ void EscenaLogo::actualitzar(float delta_time) {
temps_estat_actual_ += delta_time; temps_estat_actual_ += delta_time;
switch (estat_actual_) { switch (estat_actual_) {
case EstatAnimacio::PRE_ANIMATION: case EstatAnimacio::PRE_ANIMATION:
if (temps_estat_actual_ >= DURACIO_PRE) { if (temps_estat_actual_ >= DURACIO_PRE) {
canviar_estat(EstatAnimacio::ANIMATION); canviar_estat(EstatAnimacio::ANIMATION);
} }
break; break;
case EstatAnimacio::ANIMATION: case EstatAnimacio::ANIMATION:
if (totes_lletres_completes()) { if (totes_lletres_completes()) {
canviar_estat(EstatAnimacio::POST_ANIMATION); canviar_estat(EstatAnimacio::POST_ANIMATION);
} }
break; break;
case EstatAnimacio::POST_ANIMATION: case EstatAnimacio::POST_ANIMATION:
if (temps_estat_actual_ >= DURACIO_POST) { if (temps_estat_actual_ >= DURACIO_POST) {
GestorEscenes::actual = GestorEscenes::Escena::JOC; GestorEscenes::actual = GestorEscenes::Escena::JOC;
} }
break; break;
} }
} }
@@ -204,23 +200,25 @@ void EscenaLogo::dibuixar() {
// PRE_ANIMATION: Només pantalla negra // PRE_ANIMATION: Només pantalla negra
if (estat_actual_ == EstatAnimacio::PRE_ANIMATION) { if (estat_actual_ == EstatAnimacio::PRE_ANIMATION) {
sdl_.presenta(); sdl_.presenta();
return; // No renderitzar lletres return; // No renderitzar lletres
} }
// ANIMATION o POST_ANIMATION: Calcular progrés // ANIMATION o POST_ANIMATION: Calcular progrés
float global_progress = (estat_actual_ == EstatAnimacio::ANIMATION) float global_progress =
? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0f) (estat_actual_ == EstatAnimacio::ANIMATION)
: 1.0f; // POST: mantenir al 100% ? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0f)
: 1.0f; // POST: mantenir al 100%
// Punt inicial del zoom (configurable amb ORIGEN_ZOOM_X/Y) // Punt inicial del zoom (configurable amb ORIGEN_ZOOM_X/Y)
const Punt ORIGEN_ZOOM = {ORIGEN_ZOOM_X, ORIGEN_ZOOM_Y}; const Punt ORIGEN_ZOOM = {ORIGEN_ZOOM_X, ORIGEN_ZOOM_Y};
// Dibuixar cada lletra amb animació seqüencial // Dibuixar cada lletra amb animació seqüencial
for (size_t i = 0; i < lletres_.size(); i++) { for (size_t i = 0; i < lletres_.size(); i++) {
const auto& lletra = lletres_[i]; const auto &lletra = lletres_[i];
// Calcular progrés individual d'aquesta lletra (0.0 → 1.0) // Calcular progrés individual d'aquesta lletra (0.0 → 1.0)
float letra_progress = calcular_progress_letra(i, lletres_.size(), global_progress, THRESHOLD_LETRA); float letra_progress = calcular_progress_letra(
i, lletres_.size(), global_progress, THRESHOLD_LETRA);
// Si la lletra encara no ha començat, saltar-la // Si la lletra encara no ha començat, saltar-la
if (letra_progress <= 0.0f) { if (letra_progress <= 0.0f) {
@@ -229,32 +227,34 @@ void EscenaLogo::dibuixar() {
// Interpolar posició: des del origen zoom cap a posició final // Interpolar posició: des del origen zoom cap a posició final
Punt pos_actual; Punt pos_actual;
pos_actual.x = ORIGEN_ZOOM.x + (lletra.posicio.x - ORIGEN_ZOOM.x) * letra_progress; pos_actual.x =
pos_actual.y = ORIGEN_ZOOM.y + (lletra.posicio.y - ORIGEN_ZOOM.y) * letra_progress; ORIGEN_ZOOM.x + (lletra.posicio.x - ORIGEN_ZOOM.x) * letra_progress;
pos_actual.y =
ORIGEN_ZOOM.y + (lletra.posicio.y - ORIGEN_ZOOM.y) * letra_progress;
// Aplicar ease-out quadràtic per suavitat // Aplicar ease-out quadràtic per suavitat
float t = letra_progress; float t = letra_progress;
float ease_factor = 1.0f - (1.0f - t) * (1.0f - t); float ease_factor = 1.0f - (1.0f - t) * (1.0f - t);
// Interpolar escala amb ease-out: des de ESCALA_INICIAL cap a ESCALA_FINAL // Interpolar escala amb ease-out: des de ESCALA_INICIAL cap a ESCALA_FINAL
float escala_actual = ESCALA_INICIAL + (ESCALA_FINAL - ESCALA_INICIAL) * ease_factor; float escala_actual =
ESCALA_INICIAL + (ESCALA_FINAL - ESCALA_INICIAL) * ease_factor;
// Renderitzar la lletra // Renderitzar la lletra
Rendering::render_shape( Rendering::render_shape(
sdl_.obte_renderer(), sdl_.obte_renderer(), lletra.forma,
lletra.forma, pos_actual, // Posició interpolada
pos_actual, // Posició interpolada 0.0f, // Sense rotació
0.0f, // Sense rotació escala_actual, // Escala interpolada amb ease-out
escala_actual, // Escala interpolada amb ease-out true, // Dibuixar
true, // Dibuixar 1.0f // Progress = 1.0 (lletra completa, sense animació de primitives)
1.0f // Progress = 1.0 (lletra completa, sense animació de primitives)
); );
} }
sdl_.presenta(); sdl_.presenta();
} }
void EscenaLogo::processar_events(const SDL_Event& event) { void EscenaLogo::processar_events(const SDL_Event &event) {
// Qualsevol tecla o clic de ratolí salta al joc // Qualsevol tecla o clic de ratolí salta al joc
if (event.type == SDL_EVENT_KEY_DOWN || if (event.type == SDL_EVENT_KEY_DOWN ||
event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) { event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {

View File

@@ -4,29 +4,30 @@
#pragma once #pragma once
#include "../../core/rendering/sdl_manager.hpp"
#include "../../core/graphics/shape.hpp" #include "../../core/graphics/shape.hpp"
#include "../../core/rendering/sdl_manager.hpp"
#include "../../core/types.hpp" #include "../../core/types.hpp"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <vector>
#include <memory> #include <memory>
#include <vector>
class EscenaLogo { class EscenaLogo {
public: public:
explicit EscenaLogo(SDLManager& sdl); explicit EscenaLogo(SDLManager &sdl);
void executar(); // Bucle principal de l'escena void executar(); // Bucle principal de l'escena
private: private:
// Màquina d'estats per l'animació // Màquina d'estats per l'animació
enum class EstatAnimacio { enum class EstatAnimacio {
PRE_ANIMATION, // Pantalla negra inicial PRE_ANIMATION, // Pantalla negra inicial
ANIMATION, // Animació de zoom de lletres ANIMATION, // Animació de zoom de lletres
POST_ANIMATION // Logo complet visible POST_ANIMATION // Logo complet visible
}; };
SDLManager& sdl_; SDLManager &sdl_;
EstatAnimacio estat_actual_; // Estat actual de la màquina EstatAnimacio estat_actual_; // Estat actual de la màquina
float temps_estat_actual_; // Temps en l'estat actual (reset en cada transició) float
temps_estat_actual_; // Temps en l'estat actual (reset en cada transició)
// Estructura per a cada lletra del logo // Estructura per a cada lletra del logo
struct LetraLogo { struct LetraLogo {
@@ -36,26 +37,31 @@ private:
float offset_centre; // Distància de min_x a shape_centre.x float offset_centre; // Distància de min_x a shape_centre.x
}; };
std::vector<LetraLogo> lletres_; // 9 lletres: J-A-I-L-G-A-M-E-S std::vector<LetraLogo> lletres_; // 9 lletres: J-A-I-L-G-A-M-E-S
// Constants d'animació // Constants d'animació
static constexpr float DURACIO_PRE = 1.5f; // Duració PRE_ANIMATION (pantalla negra) static constexpr float DURACIO_PRE =
static constexpr float DURACIO_ZOOM = 4.0f; // Duració del zoom (segons) 1.5f; // Duració PRE_ANIMATION (pantalla negra)
static constexpr float DURACIO_POST = 4.0f; // Duració POST_ANIMATION (logo complet) static constexpr float DURACIO_ZOOM = 4.0f; // Duració del zoom (segons)
static constexpr float ESCALA_INICIAL = 0.1f; // Escala inicial (10%) static constexpr float DURACIO_POST =
static constexpr float ESCALA_FINAL = 0.8f; // Escala final (80%) 4.0f; // Duració POST_ANIMATION (logo complet)
static constexpr float ESPAI_ENTRE_LLETRES = 10.0f; // Espaiat entre lletres static constexpr float ESCALA_INICIAL = 0.1f; // Escala inicial (10%)
static constexpr float ESCALA_FINAL = 0.8f; // Escala final (80%)
static constexpr float ESPAI_ENTRE_LLETRES = 10.0f; // Espaiat entre lletres
// Constants d'animació seqüencial // Constants d'animació seqüencial
static constexpr float THRESHOLD_LETRA = 0.6f; // Umbral per activar següent lletra (0.0-1.0) static constexpr float THRESHOLD_LETRA =
static constexpr float ORIGEN_ZOOM_X = 640.0f / 2.0f; // Punt inicial X del zoom (320) 0.6f; // Umbral per activar següent lletra (0.0-1.0)
static constexpr float ORIGEN_ZOOM_Y = 480.0f * 0.4f; // Punt inicial Y del zoom (240) static constexpr float ORIGEN_ZOOM_X =
640.0f / 2.0f; // Punt inicial X del zoom (320)
static constexpr float ORIGEN_ZOOM_Y =
480.0f * 0.4f; // Punt inicial Y del zoom (240)
// Mètodes privats // Mètodes privats
void inicialitzar_lletres(); void inicialitzar_lletres();
void actualitzar(float delta_time); void actualitzar(float delta_time);
void dibuixar(); void dibuixar();
void processar_events(const SDL_Event& event); void processar_events(const SDL_Event &event);
// Mètodes de gestió d'estats // Mètodes de gestió d'estats
void canviar_estat(EstatAnimacio nou_estat); void canviar_estat(EstatAnimacio nou_estat);