Fase 1d: rename del codi restant (effects, stage_system, locals)
Sweep final del naming a CamelCase/camelBack/lower_case:
Fitxers renombrats:
- effects/gestor_puntuacio_flotant.{hpp,cpp} -> floating_score_manager.{hpp,cpp}
- effects/puntuacio_flotant.hpp -> floating_score.hpp
Tipus (CamelCase):
- GestorPuntuacioFlotant -> FloatingScoreManager
- PuntuacioFlotant -> FloatingScore
- ConfigStage -> StageConfig
- ConfigSistemaStages -> StageSystemConfig
- NauTitol -> TitleShip
- EstatNau -> ShipState
Metodes publics (camelBack):
- obte_renderer -> getRenderer
- get_num_actius -> getActiveCount
- calcular_direccio_explosio -> computeExplosionDirection
- trobar_slot_lliure -> findFreeSlot
- explotar -> explode
- reiniciar -> reset
- es_valida -> isValid
- parsejar_fitxer -> parseFile
- carregar -> load
- crear_explosio -> createExplosion
- registrar_puntuacio -> registerScore
- construir_marcador -> buildScoreboard
- render_centered -> renderCentered
Camps struct publics (snake_case):
- actiu/actius -> active
- rotacio -> rotation, rotacio_visual -> visual_rotation
- acceleracio -> acceleration
- velocitat -> velocity
- escala/escala_inicial/objectiu/actual -> scale/initial_scale/...
- posicio/posicio_inicial/objectiu/actual -> position/initial_position/...
- fase_oscilacio -> oscillation_phase
- temps_estat -> state_time
- jugador_id -> player_id
- estat -> state
- brillantor -> brightness
- tipus -> type
Camps privats (sufix _):
- naus_ -> ships_, orni_ -> enemies_, bales_ -> bullets_
- gestor_puntuacio_ -> floating_score_manager_
- punt_mort_ -> death_position_, punt_spawn_ -> spawn_position_
- itocado_per_jugador_ -> hit_timer_per_player_
- vides_per_jugador_ -> lives_per_player_
- puntuacio_per_jugador_ -> score_per_player_
- estat_game_over_ -> game_over_state_
- continues_usados_ -> continues_used_
Constants:
- MARGE_ESQ/DRET/DALT/BAIX -> MARGIN_LEFT/RIGHT/TOP/BOTTOM
Variables locals i parametres comuns (snake_case):
- nau -> ship, enemic -> enemy, bala -> bullet
- forma -> shape, punt(s) -> point(s)
- jugador -> player, partida -> match
- temps -> time, missatge -> message
Diff: 59 fitxers, +1000/-1000 (simetric). Compila i enllaça.
Pendents per a futures fases (no bloquejants):
- Comentaris de capçalera en catala -> castella
- Variables locals/parametres minoritaris en catala
- Include guards (queden alguns #ifndef en lloc de #pragma once)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,15 +7,15 @@
|
||||
namespace Effects {
|
||||
|
||||
// Debris: un segment de línia que vola perpendicular a sí mateix
|
||||
// Representa un fragment d'una forma destruïda (nau, enemic, bala)
|
||||
// Representa un fragment d'una shape destruïda (ship, enemy, bullet)
|
||||
struct Debris {
|
||||
// Geometria del segment (2 punts en coordenades mundials)
|
||||
// Geometria del segment (2 points en coordenades mundials)
|
||||
Vec2 p1; // Vec2 inicial del segment
|
||||
Vec2 p2; // Vec2 final del segment
|
||||
|
||||
// Física
|
||||
Vec2 velocitat; // Velocitat en px/s (components x, y)
|
||||
float acceleracio; // Acceleració negativa (fricció) en px/s²
|
||||
Vec2 velocity; // Velocitat en px/s (components x, y)
|
||||
float acceleration; // Acceleració negativa (fricció) en px/s²
|
||||
|
||||
// Rotació
|
||||
float angle_rotacio; // Angle de rotació acumulat (radians)
|
||||
@@ -25,13 +25,13 @@ struct Debris {
|
||||
// Estat de vida
|
||||
float temps_vida; // Temps transcorregut (segons)
|
||||
float temps_max; // Temps de vida màxim (segons)
|
||||
bool actiu; // Està actiu?
|
||||
bool active; // Està active?
|
||||
|
||||
// Shrinking (reducció de distància entre punts)
|
||||
// Shrinking (reducció de distància entre points)
|
||||
float factor_shrink; // Factor de reducció per segon (0.0-1.0)
|
||||
|
||||
// Rendering
|
||||
float brightness; // Factor de brillantor (0.0-1.0, heretat de l'objecte original)
|
||||
float brightness; // Factor de brightness (0.0-1.0, heretat de l'objecte original)
|
||||
};
|
||||
|
||||
} // namespace Effects
|
||||
|
||||
@@ -14,16 +14,16 @@
|
||||
|
||||
namespace Effects {
|
||||
|
||||
// Helper: transformar punt amb rotació, escala i trasllació
|
||||
// Helper: transformar point amb rotació, scale i trasllació
|
||||
// (Copiat de shape_renderer.cpp:12-34)
|
||||
static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& posicio, float angle, float escala) {
|
||||
// 1. Centrar el punt respecte al centre de la forma
|
||||
static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const Vec2& position, float angle, float scale) {
|
||||
// 1. Centrar el point respecte al centre de la shape
|
||||
float centered_x = point.x - shape_centre.x;
|
||||
float centered_y = point.y - shape_centre.y;
|
||||
|
||||
// 2. Aplicar escala al punt centrat
|
||||
float scaled_x = centered_x * escala;
|
||||
float scaled_y = centered_y * escala;
|
||||
// 2. Aplicar scale al point centrat
|
||||
float scaled_x = centered_x * scale;
|
||||
float scaled_y = centered_y * scale;
|
||||
|
||||
// 3. Aplicar rotació
|
||||
float cos_a = std::cos(angle);
|
||||
@@ -33,38 +33,38 @@ static Vec2 transform_point(const Vec2& point, const Vec2& shape_centre, const V
|
||||
float rotated_y = (scaled_x * sin_a) + (scaled_y * cos_a);
|
||||
|
||||
// 4. Aplicar trasllació a posició mundial
|
||||
return {.x = rotated_x + posicio.x, .y = rotated_y + posicio.y};
|
||||
return {.x = rotated_x + position.x, .y = rotated_y + position.y};
|
||||
}
|
||||
|
||||
DebrisManager::DebrisManager(SDL_Renderer* renderer)
|
||||
: renderer_(renderer) {
|
||||
// Inicialitzar tots els debris com inactius
|
||||
for (auto& debris : debris_pool_) {
|
||||
debris.actiu = false;
|
||||
debris.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
||||
void DebrisManager::explode(const std::shared_ptr<Graphics::Shape>& shape,
|
||||
const Vec2& centre,
|
||||
float angle,
|
||||
float escala,
|
||||
float scale,
|
||||
float velocitat_base,
|
||||
float brightness,
|
||||
const Vec2& velocitat_objecte,
|
||||
float velocitat_angular,
|
||||
float factor_herencia_visual,
|
||||
const std::string& sound) {
|
||||
if (!shape || !shape->es_valida()) {
|
||||
if (!shape || !shape->isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reproducir sonido de explosión
|
||||
Audio::get()->playSound(sound, Audio::Group::GAME);
|
||||
|
||||
// Obtenir centre de la forma per a transformacions
|
||||
// Obtenir centre de la shape per a transformacions
|
||||
const Vec2& shape_centre = shape->getCenter();
|
||||
|
||||
// Iterar sobre totes les primitives de la forma
|
||||
// Iterar sobre totes les primitives de la shape
|
||||
for (const auto& primitive : shape->get_primitives()) {
|
||||
// Processar cada segment de línia
|
||||
std::vector<std::pair<Vec2, Vec2>> segments;
|
||||
@@ -83,14 +83,14 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
||||
|
||||
// Crear debris per a cada segment
|
||||
for (const auto& [local_p1, local_p2] : segments) {
|
||||
// 1. Transformar punts locals → coordenades mundials
|
||||
// 1. Transformar points locals → coordenades mundials
|
||||
Vec2 world_p1 =
|
||||
transform_point(local_p1, shape_centre, centre, angle, escala);
|
||||
transform_point(local_p1, shape_centre, centre, angle, scale);
|
||||
Vec2 world_p2 =
|
||||
transform_point(local_p2, shape_centre, centre, angle, escala);
|
||||
transform_point(local_p2, shape_centre, centre, angle, scale);
|
||||
|
||||
// 2. Trobar slot lliure
|
||||
Debris* debris = trobar_slot_lliure();
|
||||
Debris* debris = findFreeSlot();
|
||||
if (debris == nullptr) {
|
||||
std::cerr << "[DebrisManager] Warning: no debris slots disponibles\n";
|
||||
return; // Pool ple
|
||||
@@ -101,20 +101,20 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
||||
debris->p2 = world_p2;
|
||||
|
||||
// 4. Calcular direcció d'explosió (radial, des del centre cap a fora)
|
||||
Vec2 direccio = calcular_direccio_explosio(world_p1, world_p2, centre);
|
||||
Vec2 direccio = computeExplosionDirection(world_p1, world_p2, centre);
|
||||
|
||||
// 5. Velocitat inicial (base ± variació aleatòria + velocitat heretada)
|
||||
// 5. Velocitat inicial (base ± variació aleatòria + velocity heretada)
|
||||
float speed =
|
||||
velocitat_base +
|
||||
(((std::rand() / static_cast<float>(RAND_MAX)) * 2.0F - 1.0F) *
|
||||
Defaults::Physics::Debris::VARIACIO_VELOCITAT);
|
||||
|
||||
// Heredar velocitat de l'objecte original (suma vectorial)
|
||||
debris->velocitat.x = (direccio.x * speed) + velocitat_objecte.x;
|
||||
debris->velocitat.y = (direccio.y * speed) + velocitat_objecte.y;
|
||||
debris->acceleracio = Defaults::Physics::Debris::ACCELERACIO;
|
||||
// Heredar velocity de l'objecte original (suma vectorial)
|
||||
debris->velocity.x = (direccio.x * speed) + velocitat_objecte.x;
|
||||
debris->velocity.y = (direccio.y * speed) + velocitat_objecte.y;
|
||||
debris->acceleration = Defaults::Physics::Debris::ACCELERACIO;
|
||||
|
||||
// 6. Herència de velocitat angular amb cap + conversió d'excés
|
||||
// 6. Herència de velocity angular amb cap + conversió d'excés
|
||||
|
||||
// 6a. Rotació de TRAYECTORIA amb cap + conversió tangencial
|
||||
if (std::abs(velocitat_angular) > 0.01F) {
|
||||
@@ -137,10 +137,10 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
||||
float sign_ang = (velocitat_ang_heretada >= 0.0F) ? 1.0F : -1.0F;
|
||||
|
||||
if (abs_ang > CAP) {
|
||||
// Excés: convertir a velocitat tangencial
|
||||
// Excés: convertir a velocity tangencial
|
||||
float excess = abs_ang - CAP;
|
||||
|
||||
// Radi de la forma (enemics = 20 px)
|
||||
// Radi de la shape (enemics = 20 px)
|
||||
float radius = 20.0F;
|
||||
|
||||
// Velocitat tangencial = ω_excés × radi
|
||||
@@ -151,11 +151,11 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
||||
float tangent_x = -direccio.y;
|
||||
float tangent_y = direccio.x;
|
||||
|
||||
// Afegir velocitat tangencial (suma vectorial)
|
||||
debris->velocitat.x += tangent_x * v_tangential;
|
||||
debris->velocitat.y += tangent_y * v_tangential;
|
||||
// Afegir velocity tangencial (suma vectorial)
|
||||
debris->velocity.x += tangent_x * v_tangential;
|
||||
debris->velocity.y += tangent_y * v_tangential;
|
||||
|
||||
// Aplicar cap a velocitat angular (preservar signe)
|
||||
// Aplicar cap a velocity angular (preservar signe)
|
||||
debris->velocitat_rot = sign_ang * CAP;
|
||||
} else {
|
||||
// Per sota del cap: comportament normal
|
||||
@@ -199,62 +199,62 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
||||
debris->brightness = brightness;
|
||||
|
||||
// 9. Activar
|
||||
debris->actiu = true;
|
||||
debris->active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DebrisManager::update(float delta_time) {
|
||||
for (auto& debris : debris_pool_) {
|
||||
if (!debris.actiu) {
|
||||
if (!debris.active) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1. Actualitzar temps de vida
|
||||
// 1. Actualitzar time de vida
|
||||
debris.temps_vida += delta_time;
|
||||
|
||||
// Desactivar si ha superat temps màxim
|
||||
// Desactivar si ha superat time màxim
|
||||
if (debris.temps_vida >= debris.temps_max) {
|
||||
debris.actiu = false;
|
||||
debris.active = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2. Actualitzar velocitat (desacceleració)
|
||||
// 2. Actualitzar velocity (desacceleració)
|
||||
// Aplicar fricció en la direcció del moviment
|
||||
float speed = std::sqrt((debris.velocitat.x * debris.velocitat.x) +
|
||||
(debris.velocitat.y * debris.velocitat.y));
|
||||
float speed = std::sqrt((debris.velocity.x * debris.velocity.x) +
|
||||
(debris.velocity.y * debris.velocity.y));
|
||||
|
||||
if (speed > 1.0F) {
|
||||
// Calcular direcció normalitzada
|
||||
float dir_x = debris.velocitat.x / speed;
|
||||
float dir_y = debris.velocitat.y / speed;
|
||||
float dir_x = debris.velocity.x / speed;
|
||||
float dir_y = debris.velocity.y / speed;
|
||||
|
||||
// Aplicar acceleració negativa (fricció)
|
||||
float nova_speed = speed + (debris.acceleracio * delta_time);
|
||||
float nova_speed = speed + (debris.acceleration * delta_time);
|
||||
nova_speed = std::max(nova_speed, 0.0F);
|
||||
|
||||
debris.velocitat.x = dir_x * nova_speed;
|
||||
debris.velocitat.y = dir_y * nova_speed;
|
||||
debris.velocity.x = dir_x * nova_speed;
|
||||
debris.velocity.y = dir_y * nova_speed;
|
||||
} else {
|
||||
// Velocitat molt baixa, aturar
|
||||
debris.velocitat.x = 0.0F;
|
||||
debris.velocitat.y = 0.0F;
|
||||
debris.velocity.x = 0.0F;
|
||||
debris.velocity.y = 0.0F;
|
||||
}
|
||||
|
||||
// 2b. Rotar vector de velocitat (trayectoria curva)
|
||||
// 2b. Rotar vector de velocity (trayectoria curva)
|
||||
if (std::abs(debris.velocitat_rot) > 0.01F) {
|
||||
// Calcular angle de rotació aquest frame
|
||||
float dangle = debris.velocitat_rot * delta_time;
|
||||
|
||||
// Rotar vector de velocitat usant matriu de rotació 2D
|
||||
float vel_x_old = debris.velocitat.x;
|
||||
float vel_y_old = debris.velocitat.y;
|
||||
// Rotar vector de velocity usant matriu de rotació 2D
|
||||
float vel_x_old = debris.velocity.x;
|
||||
float vel_y_old = debris.velocity.y;
|
||||
|
||||
float cos_a = std::cos(dangle);
|
||||
float sin_a = std::sin(dangle);
|
||||
|
||||
debris.velocitat.x = (vel_x_old * cos_a) - (vel_y_old * sin_a);
|
||||
debris.velocitat.y = (vel_x_old * sin_a) + (vel_y_old * cos_a);
|
||||
debris.velocity.x = (vel_x_old * cos_a) - (vel_y_old * sin_a);
|
||||
debris.velocity.y = (vel_x_old * sin_a) + (vel_y_old * cos_a);
|
||||
}
|
||||
|
||||
// 2c. Aplicar fricció angular (desacceleració gradual)
|
||||
@@ -275,18 +275,18 @@ void DebrisManager::update(float delta_time) {
|
||||
.y = (debris.p1.y + debris.p2.y) / 2.0F};
|
||||
|
||||
// 4. Actualitzar posició del centre
|
||||
centre.x += debris.velocitat.x * delta_time;
|
||||
centre.y += debris.velocitat.y * delta_time;
|
||||
centre.x += debris.velocity.x * delta_time;
|
||||
centre.y += debris.velocity.y * delta_time;
|
||||
|
||||
// 5. Actualitzar rotació VISUAL
|
||||
debris.angle_rotacio += debris.velocitat_rot_visual * delta_time;
|
||||
|
||||
// 6. Aplicar shrinking (reducció de distància entre punts)
|
||||
// 6. Aplicar shrinking (reducció de distància entre points)
|
||||
float shrink_factor =
|
||||
1.0F - (debris.factor_shrink * debris.temps_vida / debris.temps_max);
|
||||
shrink_factor = std::max(0.0F, shrink_factor); // No negatiu
|
||||
|
||||
// Calcular distància original entre punts
|
||||
// Calcular distància original entre points
|
||||
float dx = debris.p2.x - debris.p1.x;
|
||||
float dy = debris.p2.y - debris.p1.y;
|
||||
|
||||
@@ -304,7 +304,7 @@ void DebrisManager::update(float delta_time) {
|
||||
|
||||
void DebrisManager::draw() const {
|
||||
for (const auto& debris : debris_pool_) {
|
||||
if (!debris.actiu) {
|
||||
if (!debris.active) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -318,16 +318,16 @@ void DebrisManager::draw() const {
|
||||
}
|
||||
}
|
||||
|
||||
Debris* DebrisManager::trobar_slot_lliure() {
|
||||
Debris* DebrisManager::findFreeSlot() {
|
||||
for (auto& debris : debris_pool_) {
|
||||
if (!debris.actiu) {
|
||||
if (!debris.active) {
|
||||
return &debris;
|
||||
}
|
||||
}
|
||||
return nullptr; // Pool ple
|
||||
}
|
||||
|
||||
Vec2 DebrisManager::calcular_direccio_explosio(const Vec2& p1,
|
||||
Vec2 DebrisManager::computeExplosionDirection(const Vec2& p1,
|
||||
const Vec2& p2,
|
||||
const Vec2& centre_objecte) const {
|
||||
// 1. Calcular centre del segment
|
||||
@@ -364,16 +364,16 @@ Vec2 DebrisManager::calcular_direccio_explosio(const Vec2& p1,
|
||||
return {.x = final_x, .y = final_y};
|
||||
}
|
||||
|
||||
void DebrisManager::reiniciar() {
|
||||
void DebrisManager::reset() {
|
||||
for (auto& debris : debris_pool_) {
|
||||
debris.actiu = false;
|
||||
debris.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
int DebrisManager::get_num_actius() const {
|
||||
int DebrisManager::getActiveCount() const {
|
||||
int count = 0;
|
||||
for (const auto& debris : debris_pool_) {
|
||||
if (debris.actiu) {
|
||||
if (debris.active) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,20 +20,20 @@ class DebrisManager {
|
||||
public:
|
||||
explicit DebrisManager(SDL_Renderer* renderer);
|
||||
|
||||
// Crear explosió a partir d'una forma
|
||||
// - shape: forma vectorial a explotar
|
||||
// Crear explosió a partir d'una shape
|
||||
// - shape: shape vectorial a explode
|
||||
// - centre: posició del centre de l'objecte
|
||||
// - angle: orientació de l'objecte (radians)
|
||||
// - escala: escala de l'objecte (1.0 = normal)
|
||||
// - velocitat_base: velocitat inicial dels fragments (px/s)
|
||||
// - brightness: factor de brillantor heretat (0.0-1.0, per defecte 1.0)
|
||||
// - velocitat_objecte: velocitat de l'objecte que explota (px/s, per defecte 0)
|
||||
// - velocitat_angular: velocitat angular heretada (rad/s, per defecte 0)
|
||||
// - scale: scale de l'objecte (1.0 = normal)
|
||||
// - velocitat_base: velocity inicial dels fragments (px/s)
|
||||
// - brightness: factor de brightness heretat (0.0-1.0, per defecte 1.0)
|
||||
// - velocitat_objecte: velocity de l'objecte que explota (px/s, per defecte 0)
|
||||
// - velocitat_angular: velocity angular heretada (rad/s, per defecte 0)
|
||||
// - factor_herencia_visual: factor de herència rotació visual (0.0-1.0, per defecte 0.0)
|
||||
void explotar(const std::shared_ptr<Graphics::Shape>& shape,
|
||||
void explode(const std::shared_ptr<Graphics::Shape>& shape,
|
||||
const Vec2& centre,
|
||||
float angle,
|
||||
float escala,
|
||||
float scale,
|
||||
float velocitat_base,
|
||||
float brightness = 1.0F,
|
||||
const Vec2& velocitat_objecte = {.x = 0.0F, .y = 0.0F},
|
||||
@@ -41,33 +41,33 @@ class DebrisManager {
|
||||
float factor_herencia_visual = 0.0F,
|
||||
const std::string& sound = Defaults::Sound::EXPLOSION);
|
||||
|
||||
// Actualitzar tots els fragments actius
|
||||
// Actualitzar tots els fragments active
|
||||
void update(float delta_time);
|
||||
|
||||
// Dibuixar tots els fragments actius
|
||||
// Dibuixar tots els fragments active
|
||||
void draw() const;
|
||||
|
||||
// Reiniciar tots els fragments (neteja)
|
||||
void reiniciar();
|
||||
void reset();
|
||||
|
||||
// Obtenir número de fragments actius
|
||||
[[nodiscard]] int get_num_actius() const;
|
||||
// Obtenir número de fragments active
|
||||
[[nodiscard]] int getActiveCount() const;
|
||||
|
||||
private:
|
||||
SDL_Renderer* renderer_;
|
||||
|
||||
// Pool de fragments (màxim concurrent)
|
||||
// Un pentàgon té 5 línies, 15 enemics = 75 línies
|
||||
// + nau (3 línies) + bales (5 línies * 3) = 93 línies màxim
|
||||
// + ship (3 línies) + bales (5 línies * 3) = 93 línies màxim
|
||||
// Arrodonit a 100 per seguretat
|
||||
static constexpr int MAX_DEBRIS = 150;
|
||||
std::array<Debris, MAX_DEBRIS> debris_pool_;
|
||||
|
||||
// Trobar primer slot inactiu
|
||||
Debris* trobar_slot_lliure();
|
||||
Debris* findFreeSlot();
|
||||
|
||||
// Calcular direcció d'explosió (radial, des del centre cap al segment)
|
||||
[[nodiscard]] Vec2 calcular_direccio_explosio(const Vec2& p1, const Vec2& p2, const Vec2& centre_objecte) const;
|
||||
[[nodiscard]] Vec2 computeExplosionDirection(const Vec2& p1, const Vec2& p2, const Vec2& centre_objecte) const;
|
||||
};
|
||||
|
||||
} // namespace Effects
|
||||
|
||||
@@ -9,17 +9,17 @@
|
||||
|
||||
namespace Effects {
|
||||
|
||||
// PuntuacioFlotant: text animat que mostra punts guanyats
|
||||
// S'activa quan es destrueix un enemic i s'esvaeix després d'un temps
|
||||
struct PuntuacioFlotant {
|
||||
// FloatingScore: text animat que mostra points guanyats
|
||||
// S'activa quan es destrueix un enemy i s'esvaeix després d'un time
|
||||
struct FloatingScore {
|
||||
// Text a mostrar (e.g., "100", "150", "200")
|
||||
std::string text;
|
||||
|
||||
// Posició actual (coordenades mundials)
|
||||
Vec2 posicio;
|
||||
Vec2 position;
|
||||
|
||||
// Animació de moviment
|
||||
Vec2 velocitat; // px/s (normalment cap amunt: {0.0f, -30.0f})
|
||||
Vec2 velocity; // px/s (normalment cap amunt: {0.0f, -30.0f})
|
||||
|
||||
// Animació de fade
|
||||
float temps_vida; // Temps transcorregut (segons)
|
||||
@@ -27,7 +27,7 @@ struct PuntuacioFlotant {
|
||||
float brightness; // Brillantor calculada (0.0-1.0)
|
||||
|
||||
// Estat
|
||||
bool actiu;
|
||||
bool active;
|
||||
};
|
||||
|
||||
} // namespace Effects
|
||||
+26
-26
@@ -1,95 +1,95 @@
|
||||
// gestor_puntuacio_flotant.cpp - Implementació del gestor de números flotants
|
||||
// © 2025 Port a C++20 amb SDL3
|
||||
|
||||
#include "gestor_puntuacio_flotant.hpp"
|
||||
#include "floating_score_manager.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Effects {
|
||||
|
||||
GestorPuntuacioFlotant::GestorPuntuacioFlotant(SDL_Renderer* renderer)
|
||||
FloatingScoreManager::FloatingScoreManager(SDL_Renderer* renderer)
|
||||
: text_(renderer) {
|
||||
// Inicialitzar tots els slots com inactius
|
||||
for (auto& pf : pool_) {
|
||||
pf.actiu = false;
|
||||
pf.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GestorPuntuacioFlotant::crear(int punts, const Vec2& posicio) {
|
||||
void FloatingScoreManager::crear(int points, const Vec2& position) {
|
||||
// 1. Trobar slot lliure
|
||||
PuntuacioFlotant* pf = trobar_slot_lliure();
|
||||
FloatingScore* pf = findFreeSlot();
|
||||
if (pf == nullptr) {
|
||||
return; // Pool ple (improbable)
|
||||
}
|
||||
|
||||
// 2. Inicialitzar puntuació flotant
|
||||
pf->text = std::to_string(punts);
|
||||
pf->posicio = posicio;
|
||||
pf->velocitat = {.x = Defaults::FloatingScore::VELOCITY_X,
|
||||
pf->text = std::to_string(points);
|
||||
pf->position = position;
|
||||
pf->velocity = {.x = Defaults::FloatingScore::VELOCITY_X,
|
||||
.y = Defaults::FloatingScore::VELOCITY_Y};
|
||||
pf->temps_vida = 0.0F;
|
||||
pf->temps_max = Defaults::FloatingScore::LIFETIME;
|
||||
pf->brightness = 1.0F;
|
||||
pf->actiu = true;
|
||||
pf->active = true;
|
||||
}
|
||||
|
||||
void GestorPuntuacioFlotant::update(float delta_time) {
|
||||
void FloatingScoreManager::update(float delta_time) {
|
||||
for (auto& pf : pool_) {
|
||||
if (!pf.actiu) {
|
||||
if (!pf.active) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1. Actualitzar posició (deriva cap amunt)
|
||||
pf.posicio.x += pf.velocitat.x * delta_time;
|
||||
pf.posicio.y += pf.velocitat.y * delta_time;
|
||||
pf.position.x += pf.velocity.x * delta_time;
|
||||
pf.position.y += pf.velocity.y * delta_time;
|
||||
|
||||
// 2. Actualitzar temps de vida
|
||||
// 2. Actualitzar time de vida
|
||||
pf.temps_vida += delta_time;
|
||||
|
||||
// 3. Calcular brightness (fade lineal)
|
||||
float progress = pf.temps_vida / pf.temps_max; // 0.0 → 1.0
|
||||
pf.brightness = 1.0F - progress; // 1.0 → 0.0
|
||||
|
||||
// 4. Desactivar quan acaba el temps
|
||||
// 4. Desactivar quan acaba el time
|
||||
if (pf.temps_vida >= pf.temps_max) {
|
||||
pf.actiu = false;
|
||||
pf.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GestorPuntuacioFlotant::draw() {
|
||||
void FloatingScoreManager::draw() {
|
||||
for (const auto& pf : pool_) {
|
||||
if (!pf.actiu) {
|
||||
if (!pf.active) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Renderitzar centrat amb brightness (fade)
|
||||
constexpr float escala = Defaults::FloatingScore::SCALE;
|
||||
constexpr float scale = Defaults::FloatingScore::SCALE;
|
||||
constexpr float spacing = Defaults::FloatingScore::SPACING;
|
||||
|
||||
text_.render_centered(pf.text, pf.posicio, escala, spacing, pf.brightness);
|
||||
text_.renderCentered(pf.text, pf.position, scale, spacing, pf.brightness);
|
||||
}
|
||||
}
|
||||
|
||||
void GestorPuntuacioFlotant::reiniciar() {
|
||||
void FloatingScoreManager::reset() {
|
||||
for (auto& pf : pool_) {
|
||||
pf.actiu = false;
|
||||
pf.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
int GestorPuntuacioFlotant::get_num_actius() const {
|
||||
int FloatingScoreManager::getActiveCount() const {
|
||||
int count = 0;
|
||||
for (const auto& pf : pool_) {
|
||||
if (pf.actiu) {
|
||||
if (pf.active) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
PuntuacioFlotant* GestorPuntuacioFlotant::trobar_slot_lliure() {
|
||||
FloatingScore* FloatingScoreManager::findFreeSlot() {
|
||||
for (auto& pf : pool_) {
|
||||
if (!pf.actiu) {
|
||||
if (!pf.active) {
|
||||
return &pf;
|
||||
}
|
||||
}
|
||||
+14
-14
@@ -10,32 +10,32 @@
|
||||
#include "core/defaults.hpp"
|
||||
#include "core/graphics/vector_text.hpp"
|
||||
#include "core/types.hpp"
|
||||
#include "puntuacio_flotant.hpp"
|
||||
#include "floating_score.hpp"
|
||||
|
||||
namespace Effects {
|
||||
|
||||
// Gestor de números de puntuació flotants
|
||||
// Manté un pool de PuntuacioFlotant i gestiona el seu cicle de vida
|
||||
class GestorPuntuacioFlotant {
|
||||
// Manté un pool de FloatingScore i gestiona el seu cicle de vida
|
||||
class FloatingScoreManager {
|
||||
public:
|
||||
explicit GestorPuntuacioFlotant(SDL_Renderer* renderer);
|
||||
explicit FloatingScoreManager(SDL_Renderer* renderer);
|
||||
|
||||
// Crear número flotant
|
||||
// - punts: valor numèric (100, 150, 200)
|
||||
// - posicio: on apareix (normalment centre d'enemic destruït)
|
||||
void crear(int punts, const Vec2& posicio);
|
||||
// - points: valor numèric (100, 150, 200)
|
||||
// - position: on apareix (normalment centre d'enemy destruït)
|
||||
void crear(int points, const Vec2& position);
|
||||
|
||||
// Actualitzar tots els números actius
|
||||
// Actualitzar tots els números active
|
||||
void update(float delta_time);
|
||||
|
||||
// Dibuixar tots els números actius
|
||||
// Dibuixar tots els números active
|
||||
void draw();
|
||||
|
||||
// Reiniciar tots (neteja)
|
||||
void reiniciar();
|
||||
void reset();
|
||||
|
||||
// Obtenir número actius (debug)
|
||||
[[nodiscard]] int get_num_actius() const;
|
||||
// Obtenir número active (debug)
|
||||
[[nodiscard]] int getActiveCount() const;
|
||||
|
||||
private:
|
||||
Graphics::VectorText text_; // Sistema de text vectorial
|
||||
@@ -44,10 +44,10 @@ class GestorPuntuacioFlotant {
|
||||
// Màxim 15 enemics simultanis = màxim 15 números
|
||||
static constexpr int MAX_PUNTUACIONS =
|
||||
Defaults::FloatingScore::MAX_CONCURRENT;
|
||||
std::array<PuntuacioFlotant, MAX_PUNTUACIONS> pool_;
|
||||
std::array<FloatingScore, MAX_PUNTUACIONS> pool_;
|
||||
|
||||
// Trobar primer slot inactiu
|
||||
PuntuacioFlotant* trobar_slot_lliure();
|
||||
FloatingScore* findFreeSlot();
|
||||
};
|
||||
|
||||
} // namespace Effects
|
||||
Reference in New Issue
Block a user