style: aplicar checks modernize-* (215 fixes)

Cambios aplicados:
- [[nodiscard]] añadido a funciones que retornan valores
- .starts_with() en lugar de .find() == 0
- Inicializadores designados {.x=0, .y=0}
- auto en castings obvios
- = default para constructores triviales
- Funciones deleted movidas a public
- std::numbers::pi_v<float> (C++20)

Checks excluidos:
- use-trailing-return-type: Estilo controversial
- avoid-c-arrays: Arrays C aceptables en ciertos contextos
This commit is contained in:
2025-12-18 20:16:46 +01:00
parent fdfb84170f
commit 7f6af6dd00
42 changed files with 178 additions and 178 deletions

View File

@@ -15,7 +15,10 @@ Checks:
- -readability-use-anyofallof # Excluido (C++20 ranges - no todos los compiladores)
- -readability-function-cognitive-complexity # Excluido (complejidad ciclomática aceptable)
- -clang-analyzer-security.insecureAPI.rand # Excluido (rand() es suficiente para juegos)
# - modernize-*
# ✅ Check 8: modernize-* (215 fixes aplicados)
- modernize-*
- -modernize-use-trailing-return-type # Excluido (estilo controversial)
- -modernize-avoid-c-arrays # Excluido (arrays C son OK en algunos contextos)
# - performance-*
# - bugprone-unchecked-optional-access
# - bugprone-sizeof-expression

View File

@@ -3,6 +3,7 @@
#include <cmath>
#include <cstdint>
#include <numbers>
namespace Defaults {
// Configuración de ventana
@@ -232,7 +233,7 @@ constexpr float VELOCITAT_ROT_MAX = 1.5F; // rad/s (~86°/s)
// Matemáticas
namespace Math {
constexpr float PI = 3.14159265359F;
constexpr float PI = std::numbers::pi_v<float>;
} // namespace Math
// Colores (oscilación para efecto CRT)

View File

@@ -11,7 +11,7 @@
namespace Graphics {
Shape::Shape(const std::string& filepath)
: centre_({0.0F, 0.0F}),
: centre_({.x = 0.0F, .y = 0.0F}),
escala_defecte_(1.0F),
nom_("unnamed") {
carregar(filepath);
@@ -106,7 +106,7 @@ bool Shape::starts_with(const std::string& str,
if (str.length() < prefix.length()) {
return false;
}
return str.compare(0, prefix.length(), prefix) == 0;
return str.starts_with(prefix);
}
// Helper: extract value after ':'
@@ -128,7 +128,7 @@ void Shape::parse_center(const std::string& value) {
centre_.y = std::stof(trim(val.substr(comma + 1)));
} catch (...) {
std::cerr << "[Shape] Warning: centre invàlid, usant (0,0)" << std::endl;
centre_ = {0.0F, 0.0F};
centre_ = {.x = 0.0F, .y = 0.0F};
}
}
}

View File

@@ -36,16 +36,16 @@ class Shape {
bool parsejar_fitxer(const std::string& contingut);
// Getters
const std::vector<ShapePrimitive>& get_primitives() const {
[[nodiscard]] const std::vector<ShapePrimitive>& get_primitives() const {
return primitives_;
}
const Punt& get_centre() const { return centre_; }
float get_escala_defecte() const { return escala_defecte_; }
bool es_valida() const { return !primitives_.empty(); }
[[nodiscard]] const Punt& get_centre() const { return centre_; }
[[nodiscard]] float get_escala_defecte() const { return escala_defecte_; }
[[nodiscard]] bool es_valida() const { return !primitives_.empty(); }
// Info de depuració
std::string get_nom() const { return nom_; }
size_t get_num_primitives() const { return primitives_.size(); }
[[nodiscard]] std::string get_nom() const { return nom_; }
[[nodiscard]] size_t get_num_primitives() const { return primitives_.size(); }
private:
std::vector<ShapePrimitive> primitives_;
@@ -54,11 +54,11 @@ class Shape {
std::string nom_; // Nom de la forma (per depuració)
// Helpers privats per parsejar
std::string trim(const std::string& str) const;
bool starts_with(const std::string& str, const std::string& prefix) const;
std::string extract_value(const std::string& line) const;
[[nodiscard]] std::string trim(const std::string& str) const;
[[nodiscard]] bool starts_with(const std::string& str, const std::string& prefix) const;
[[nodiscard]] std::string extract_value(const std::string& line) const;
void parse_center(const std::string& value);
std::vector<Punt> parse_points(const std::string& str) const;
[[nodiscard]] std::vector<Punt> parse_points(const std::string& str) const;
};
} // namespace Graphics

View File

@@ -24,7 +24,7 @@ std::shared_ptr<Shape> ShapeLoader::load(const std::string& filename) {
// Normalize path: "ship.shp" → "shapes/ship.shp"
// "logo/letra_j.shp" → "shapes/logo/letra_j.shp"
std::string normalized = filename;
if (normalized.find("shapes/") != 0) {
if (!normalized.starts_with("shapes/")) {
// Doesn't start with "shapes/", so add it
normalized = "shapes/" + normalized;
}
@@ -75,7 +75,7 @@ std::string ShapeLoader::resolve_path(const std::string& filename) {
}
// Si ja conté el prefix base_path, usar-lo directament
if (filename.find(base_path_) == 0) {
if (filename.starts_with(base_path_)) {
return filename;
}

View File

@@ -57,13 +57,13 @@ class Starfield {
void inicialitzar_estrella(Estrella& estrella) const;
// Verificar si una estrella està fora de l'àrea
bool fora_area(const Estrella& estrella) const;
[[nodiscard]] bool fora_area(const Estrella& estrella) const;
// Calcular escala dinàmica segons distància del centre
float calcular_escala(const Estrella& estrella) const;
[[nodiscard]] float calcular_escala(const Estrella& estrella) const;
// Calcular brightness dinàmica segons distància del centre
float calcular_brightness(const Estrella& estrella) const;
[[nodiscard]] float calcular_brightness(const Estrella& estrella) const;
// Dades
std::vector<Estrella> estrelles_;

View File

@@ -201,7 +201,7 @@ void VectorText::render(const std::string& text, const Punt& posicio, float esca
// Iterar sobre cada byte del string (con detecció UTF-8)
for (size_t i = 0; i < text.length(); i++) {
unsigned char c = static_cast<unsigned char>(text[i]);
auto c = static_cast<unsigned char>(text[i]);
// Detectar copyright UTF-8 (0xC2 0xA9)
if (c == 0xC2 && i + 1 < text.length() &&
@@ -222,7 +222,7 @@ void VectorText::render(const std::string& text, const Punt& posicio, float esca
// Renderizar carácter
// Ajustar X e Y para que posicio represente esquina superior izquierda
// (render_shape espera el centro, así que sumamos la mitad de ancho y altura)
Punt char_pos = {current_x + (char_width_scaled / 2.0F), posicio.y + (char_height_scaled / 2.0F)};
Punt char_pos = {.x = current_x + (char_width_scaled / 2.0F), .y = posicio.y + (char_height_scaled / 2.0F)};
Rendering::render_shape(renderer_, it->second, char_pos, 0.0F, escala, true, 1.0F, brightness);
// Avanzar posición
@@ -244,8 +244,8 @@ void VectorText::render_centered(const std::string& text, const Punt& centre_pun
// 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)};
.x = centre_punt.x - (text_width / 2.0F),
.y = centre_punt.y - (text_height / 2.0F)};
// Delegar al mètode render() existent
render(text, posicio_esquerra, escala, spacing, brightness);
@@ -262,7 +262,7 @@ float VectorText::get_text_width(const std::string& text, float escala, float sp
// Contar caracteres visuals (no bytes) - manejar UTF-8
size_t visual_chars = 0;
for (size_t i = 0; i < text.length(); i++) {
unsigned char c = static_cast<unsigned char>(text[i]);
auto c = static_cast<unsigned char>(text[i]);
// Detectar copyright UTF-8 (0xC2 0xA9) - igual que render()
if (c == 0xC2 && i + 1 < text.length() &&

View File

@@ -36,20 +36,20 @@ class VectorText {
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)
float get_text_width(const std::string& text, float escala = 1.0F, float spacing = 2.0F) const;
[[nodiscard]] float get_text_width(const std::string& text, float escala = 1.0F, float spacing = 2.0F) const;
// Calcular altura del texto (útil para centrado vertical)
float get_text_height(float escala = 1.0F) const;
[[nodiscard]] float get_text_height(float escala = 1.0F) const;
// Verificar si un carácter está soportado
bool is_supported(char c) const;
[[nodiscard]] bool is_supported(char c) const;
private:
SDL_Renderer* renderer_;
std::unordered_map<char, std::shared_ptr<Shape>> chars_;
void load_charset();
std::string get_shape_filename(char c) const;
[[nodiscard]] std::string get_shape_filename(char c) const;
};
} // namespace Graphics

View File

@@ -115,12 +115,12 @@ class Input {
// --- Gestión de gamepads ---
[[nodiscard]] auto gameControllerFound() const -> bool;
[[nodiscard]] auto getNumGamepads() const -> int;
auto getGamepad(SDL_JoystickID id) const -> std::shared_ptr<Gamepad>;
auto getGamepadByName(const std::string& name) const -> std::shared_ptr<Input::Gamepad>;
auto getGamepads() const -> const Gamepads& { return gamepads_; }
[[nodiscard]] auto getGamepad(SDL_JoystickID id) const -> std::shared_ptr<Gamepad>;
[[nodiscard]] auto getGamepadByName(const std::string& name) const -> std::shared_ptr<Input::Gamepad>;
[[nodiscard]] auto getGamepads() const -> const Gamepads& { return gamepads_; }
auto findAvailableGamepadByName(const std::string& gamepad_name) -> std::shared_ptr<Gamepad>;
static auto getControllerName(const std::shared_ptr<Gamepad>& gamepad) -> std::string;
auto getControllerNames() const -> std::vector<std::string>;
[[nodiscard]] auto getControllerNames() const -> std::vector<std::string>;
[[nodiscard]] static auto getControllerBinding(const std::shared_ptr<Gamepad>& gamepad, Action action) -> SDL_GamepadButton;
void printConnectedGamepads() const;

View File

@@ -12,14 +12,14 @@ namespace Rendering {
ColorOscillator::ColorOscillator()
: accumulated_time_(0.0F) {
// Inicialitzar amb el color mínim
current_line_color_ = {Defaults::Color::LINE_MIN_R,
Defaults::Color::LINE_MIN_G,
Defaults::Color::LINE_MIN_B,
255};
current_background_color_ = {Defaults::Color::BACKGROUND_MIN_R,
Defaults::Color::BACKGROUND_MIN_G,
Defaults::Color::BACKGROUND_MIN_B,
255};
current_line_color_ = {.r = Defaults::Color::LINE_MIN_R,
.g = Defaults::Color::LINE_MIN_G,
.b = Defaults::Color::LINE_MIN_B,
.a = 255};
current_background_color_ = {.r = Defaults::Color::BACKGROUND_MIN_R,
.g = Defaults::Color::BACKGROUND_MIN_G,
.b = Defaults::Color::BACKGROUND_MIN_B,
.a = 255};
}
void ColorOscillator::update(float delta_time) {

View File

@@ -12,8 +12,8 @@ class ColorOscillator {
void update(float delta_time);
SDL_Color getCurrentLineColor() const { return current_line_color_; }
SDL_Color getCurrentBackgroundColor() const {
[[nodiscard]] SDL_Color getCurrentLineColor() const { return current_line_color_; }
[[nodiscard]] SDL_Color getCurrentBackgroundColor() const {
return current_background_color_;
}

View File

@@ -40,7 +40,7 @@ class SDLManager {
// Getters
SDL_Renderer* obte_renderer() { return renderer_; }
float getScaleFactor() const { return zoom_factor_; }
[[nodiscard]] float getScaleFactor() const { return zoom_factor_; }
// [NUEVO] Actualitzar títol de la finestra
void setWindowTitle(const std::string& title);

View File

@@ -38,7 +38,7 @@ static Punt apply_3d_rotation(float x, float y, const Rotation3D& rot) {
constexpr float perspective_factor = 500.0F;
float scale_factor = perspective_factor / (perspective_factor + z2);
return {x3 * scale_factor, y3 * scale_factor};
return {.x = x3 * scale_factor, .y = y3 * scale_factor};
}
// Helper: transformar un punt amb rotació, escala i trasllació
@@ -69,7 +69,7 @@ static Punt transform_point(const Punt& point, const Punt& shape_centre, const P
float rotated_y = (scaled_x * sin_a) + (scaled_y * cos_a);
// 5. Aplicar trasllació a posició mundial
return {rotated_x + posicio.x, rotated_y + posicio.y};
return {.x = rotated_x + posicio.x, .y = rotated_y + posicio.y};
}
void render_shape(SDL_Renderer* renderer,

View File

@@ -27,7 +27,7 @@ struct Rotation3D {
yaw(y),
roll(r) {}
bool has_rotation() const {
[[nodiscard]] bool has_rotation() const {
return pitch != 0.0F || yaw != 0.0F || roll != 0.0F;
}
};

View File

@@ -8,8 +8,7 @@
#include "resource_loader.hpp"
namespace Resource {
namespace Helper {
namespace Resource::Helper {
// Inicialitzar el sistema de recursos
bool initializeResourceSystem(const std::string& pack_file, bool fallback) {
@@ -79,5 +78,4 @@ bool isPackLoaded() {
return Loader::get().isPackLoaded();
}
} // namespace Helper
} // namespace Resource
} // namespace Resource::Helper

View File

@@ -7,8 +7,7 @@
#include <string>
#include <vector>
namespace Resource {
namespace Helper {
namespace Resource::Helper {
// Inicialització del sistema
bool initializeResourceSystem(const std::string& pack_file, bool fallback);
@@ -24,5 +23,4 @@ std::string normalizePath(const std::string& path);
// Estat
bool isPackLoaded();
} // namespace Helper
} // namespace Resource
} // namespace Resource::Helper

View File

@@ -27,20 +27,20 @@ class Loader {
// Validació
bool validatePack();
bool isPackLoaded() const;
[[nodiscard]] bool isPackLoaded() const;
// Estat
void setBasePath(const std::string& path);
std::string getBasePath() const;
private:
Loader() = default;
~Loader() = default;
[[nodiscard]] std::string getBasePath() const;
// No es pot copiar ni moure
Loader(const Loader&) = delete;
Loader& operator=(const Loader&) = delete;
private:
Loader() = default;
~Loader() = default;
// Dades
std::unique_ptr<Pack> pack_;
bool fallback_enabled_ = false;

View File

@@ -41,11 +41,11 @@ class Pack {
// Accés a recursos
std::vector<uint8_t> getResource(const std::string& filename);
bool hasResource(const std::string& filename) const;
std::vector<std::string> getResourceList() const;
[[nodiscard]] bool hasResource(const std::string& filename) const;
[[nodiscard]] std::vector<std::string> getResourceList() const;
// Validació
bool validatePack() const;
[[nodiscard]] bool validatePack() const;
private:
// Constants
@@ -59,7 +59,7 @@ class Pack {
// Funcions auxiliars
std::vector<uint8_t> readFile(const std::string& filepath);
uint32_t calculateChecksum(const std::vector<uint8_t>& data) const;
[[nodiscard]] uint32_t calculateChecksum(const std::vector<uint8_t>& data) const;
void encryptData(std::vector<uint8_t>& data, const std::string& key);
void decryptData(std::vector<uint8_t>& data, const std::string& key);
};

View File

@@ -27,9 +27,7 @@ class ContextEscenes {
};
// Constructor inicial amb escena LOGO i sense opcions
ContextEscenes()
: escena_desti_(Escena::LOGO),
opcio_(Opcio::NONE) {}
ContextEscenes() = default;
// Canviar escena amb opció específica
void canviar_escena(Escena nova_escena, Opcio opcio = Opcio::NONE) {
@@ -71,8 +69,8 @@ class ContextEscenes {
}
private:
Escena escena_desti_; // Escena a la qual transicionar
Opcio opcio_; // Opció específica per l'escena
Escena escena_desti_{Escena::LOGO}; // Escena a la qual transicionar
Opcio opcio_{Opcio::NONE}; // Opció específica per l'escena
GameConfig::ConfigPartida config_partida_; // Configuració de partida (jugadors actius, mode)
};

View File

@@ -33,7 +33,7 @@ static Punt transform_point(const Punt& point, const Punt& shape_centre, const P
float rotated_y = (scaled_x * sin_a) + (scaled_y * cos_a);
// 4. Aplicar trasllació a posició mundial
return {rotated_x + posicio.x, rotated_y + posicio.y};
return {.x = rotated_x + posicio.x, .y = rotated_y + posicio.y};
}
DebrisManager::DebrisManager(SDL_Renderer* renderer)
@@ -72,12 +72,12 @@ void DebrisManager::explotar(const std::shared_ptr<Graphics::Shape>& shape,
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
// Polyline: extreure segments consecutius
for (size_t i = 0; i < primitive.points.size() - 1; i++) {
segments.push_back({primitive.points[i], primitive.points[i + 1]});
segments.emplace_back(primitive.points[i], primitive.points[i + 1]);
}
} else { // PrimitiveType::LINE
// Line: un únic segment
if (primitive.points.size() >= 2) {
segments.push_back({primitive.points[0], primitive.points[1]});
segments.emplace_back(primitive.points[0], primitive.points[1]);
}
}
@@ -271,8 +271,8 @@ void DebrisManager::actualitzar(float delta_time) {
}
// 3. Calcular centre del segment
Punt centre = {(debris.p1.x + debris.p2.x) / 2.0F,
(debris.p1.y + debris.p2.y) / 2.0F};
Punt centre = {.x = (debris.p1.x + debris.p2.x) / 2.0F,
.y = (debris.p1.y + debris.p2.y) / 2.0F};
// 4. Actualitzar posició del centre
centre.x += debris.velocitat.x * delta_time;
@@ -346,7 +346,7 @@ Punt DebrisManager::calcular_direccio_explosio(const Punt& p1,
// Segment al centre (cas extrem molt improbable), retornar direcció aleatòria
float angle_rand =
(std::rand() / static_cast<float>(RAND_MAX)) * 2.0F * Defaults::Math::PI;
return {std::cos(angle_rand), std::sin(angle_rand)};
return {.x = std::cos(angle_rand), .y = std::sin(angle_rand)};
}
dx /= length;
@@ -362,7 +362,7 @@ Punt DebrisManager::calcular_direccio_explosio(const Punt& p1,
float final_x = (dx * cos_v) - (dy * sin_v);
float final_y = (dx * sin_v) + (dy * cos_v);
return {final_x, final_y};
return {.x = final_x, .y = final_y};
}
void DebrisManager::reiniciar() {

View File

@@ -35,7 +35,7 @@ class DebrisManager {
float escala,
float velocitat_base,
float brightness = 1.0F,
const Punt& velocitat_objecte = {0.0F, 0.0F},
const Punt& velocitat_objecte = {.x = 0.0F, .y = 0.0F},
float velocitat_angular = 0.0F,
float factor_herencia_visual = 0.0F,
const std::string& sound = Defaults::Sound::EXPLOSION);
@@ -50,7 +50,7 @@ class DebrisManager {
void reiniciar();
// Obtenir número de fragments actius
int get_num_actius() const;
[[nodiscard]] int get_num_actius() const;
private:
SDL_Renderer* renderer_;
@@ -66,7 +66,7 @@ class DebrisManager {
Debris* trobar_slot_lliure();
// Calcular direcció d'explosió (radial, des del centre cap al segment)
Punt calcular_direccio_explosio(const Punt& p1, const Punt& p2, const Punt& centre_objecte) const;
[[nodiscard]] Punt calcular_direccio_explosio(const Punt& p1, const Punt& p2, const Punt& centre_objecte) const;
};
} // namespace Effects

View File

@@ -25,8 +25,8 @@ void GestorPuntuacioFlotant::crear(int punts, const Punt& posicio) {
// 2. Inicialitzar puntuació flotant
pf->text = std::to_string(punts);
pf->posicio = posicio;
pf->velocitat = {Defaults::FloatingScore::VELOCITY_X,
Defaults::FloatingScore::VELOCITY_Y};
pf->velocitat = {.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;

View File

@@ -35,7 +35,7 @@ class GestorPuntuacioFlotant {
void reiniciar();
// Obtenir número actius (debug)
int get_num_actius() const;
[[nodiscard]] int get_num_actius() const;
private:
Graphics::VectorText text_; // Sistema de text vectorial

View File

@@ -16,7 +16,7 @@
Bala::Bala(SDL_Renderer* renderer)
: renderer_(renderer),
centre_({0.0F, 0.0F}),
centre_({.x = 0.0F, .y = 0.0F}),
angle_(0.0F),
velocitat_(0.0F),
esta_(false),
@@ -33,7 +33,7 @@ Bala::Bala(SDL_Renderer* renderer)
void Bala::inicialitzar() {
// Inicialment inactiva
esta_ = false;
centre_ = {0.0F, 0.0F};
centre_ = {.x = 0.0F, .y = 0.0F};
angle_ = 0.0F;
velocitat_ = 0.0F;
grace_timer_ = 0.0F;

View File

@@ -22,10 +22,10 @@ class Bala {
void dibuixar() const;
// Getters (API pública sense canvis)
bool esta_activa() const { return esta_; }
const Punt& get_centre() const { return centre_; }
uint8_t get_owner_id() const { return owner_id_; }
float get_grace_timer() const { return grace_timer_; }
[[nodiscard]] bool esta_activa() const { return esta_; }
[[nodiscard]] const Punt& get_centre() const { return centre_; }
[[nodiscard]] uint8_t get_owner_id() const { return owner_id_; }
[[nodiscard]] float get_grace_timer() const { return grace_timer_; }
void desactivar() { esta_ = false; }
private:

View File

@@ -16,7 +16,7 @@
Enemic::Enemic(SDL_Renderer* renderer)
: renderer_(renderer),
centre_({0.0F, 0.0F}),
centre_({.x = 0.0F, .y = 0.0F}),
angle_(0.0F),
velocitat_(0.0F),
drotacio_(0.0F),

View File

@@ -45,25 +45,25 @@ class Enemic {
void dibuixar() const;
// Getters (API pública sense canvis)
bool esta_actiu() const { return esta_; }
const Punt& get_centre() const { return centre_; }
const std::shared_ptr<Graphics::Shape>& get_forma() const { return forma_; }
[[nodiscard]] bool esta_actiu() const { return esta_; }
[[nodiscard]] const Punt& get_centre() const { return centre_; }
[[nodiscard]] const std::shared_ptr<Graphics::Shape>& get_forma() const { return forma_; }
void destruir() { esta_ = false; }
float get_brightness() const { return brightness_; }
float get_drotacio() const { return drotacio_; }
Punt get_velocitat_vector() const {
[[nodiscard]] float get_brightness() const { return brightness_; }
[[nodiscard]] float get_drotacio() const { return drotacio_; }
[[nodiscard]] Punt get_velocitat_vector() const {
return {
velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)),
velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))};
.x = velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)),
.y = velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))};
}
// Set ship position reference for tracking behavior
void set_ship_position(const Punt* ship_pos) { ship_position_ = ship_pos; }
// [NEW] Getters for stage system (base stats)
float get_base_velocity() const;
float get_base_rotation() const;
TipusEnemic get_tipus() const { return tipus_; }
[[nodiscard]] float get_base_velocity() const;
[[nodiscard]] float get_base_rotation() const;
[[nodiscard]] TipusEnemic get_tipus() const { return tipus_; }
// [NEW] Setters for difficulty multipliers (stage system)
void set_velocity(float vel) { velocitat_ = vel; }
@@ -74,8 +74,8 @@ class Enemic {
void set_tracking_strength(float strength);
// [NEW] Invulnerability queries
bool es_invulnerable() const { return timer_invulnerabilitat_ > 0.0F; }
float get_temps_invulnerabilitat() const { return timer_invulnerabilitat_; }
[[nodiscard]] bool es_invulnerable() const { return timer_invulnerabilitat_ > 0.0F; }
[[nodiscard]] float get_temps_invulnerabilitat() const { return timer_invulnerabilitat_; }
private:
SDL_Renderer* renderer_;
@@ -116,6 +116,6 @@ class Enemic {
void comportament_pentagon(float delta_time);
void comportament_quadrat(float delta_time);
void comportament_molinillo(float delta_time);
float calcular_escala_actual() const; // Returns scale with palpitation applied
[[nodiscard]] float calcular_escala_actual() const; // Returns scale with palpitation applied
bool intent_spawn_safe(const Punt& ship_pos, float& out_x, float& out_y);
};

View File

@@ -18,7 +18,7 @@
Nau::Nau(SDL_Renderer* renderer, const char* shape_file)
: renderer_(renderer),
centre_({0.0F, 0.0F}),
centre_({.x = 0.0F, .y = 0.0F}),
angle_(0.0F),
velocitat_(0.0F),
esta_tocada_(false),

View File

@@ -23,17 +23,17 @@ class Nau {
void dibuixar() const;
// Getters (API pública sense canvis)
const Punt& get_centre() const { return centre_; }
float get_angle() const { return angle_; }
bool esta_viva() const { return !esta_tocada_; }
bool esta_tocada() const { return esta_tocada_; }
bool es_invulnerable() const { return invulnerable_timer_ > 0.0F; }
const std::shared_ptr<Graphics::Shape>& get_forma() const { return forma_; }
float get_brightness() const { return brightness_; }
Punt get_velocitat_vector() const {
[[nodiscard]] const Punt& get_centre() const { return centre_; }
[[nodiscard]] float get_angle() const { return angle_; }
[[nodiscard]] bool esta_viva() const { return !esta_tocada_; }
[[nodiscard]] bool esta_tocada() const { return esta_tocada_; }
[[nodiscard]] bool es_invulnerable() const { return invulnerable_timer_ > 0.0F; }
[[nodiscard]] const std::shared_ptr<Graphics::Shape>& get_forma() const { return forma_; }
[[nodiscard]] float get_brightness() const { return brightness_; }
[[nodiscard]] Punt get_velocitat_vector() const {
return {
velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)),
velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))};
.x = velocitat_ * std::cos(angle_ - (Constants::PI / 2.0F)),
.y = velocitat_ * std::sin(angle_ - (Constants::PI / 2.0F))};
}
// Setters

View File

@@ -555,7 +555,7 @@ void EscenaJoc::dibuixar() {
float centre_x = play_area.x + (play_area.w / 2.0F);
float centre_y = play_area.y + (play_area.h / 2.0F);
text_.render_centered(game_over_text, {centre_x, centre_y}, escala, spacing);
text_.render_centered(game_over_text, {.x = centre_x, .y = centre_y}, escala, spacing);
dibuixar_marcador();
return;
@@ -710,7 +710,7 @@ void EscenaJoc::tocado(uint8_t player_id) {
float ship_angle = naus_[player_id].get_angle();
Punt vel_nau = naus_[player_id].get_velocitat_vector();
// Reduir a 80% la velocitat heretada per la nau (més realista)
Punt vel_nau_80 = {vel_nau.x * 0.8F, vel_nau.y * 0.8F};
Punt vel_nau_80 = {.x = vel_nau.x * 0.8F, .y = vel_nau.y * 0.8F};
debris_manager_.explotar(
naus_[player_id].get_forma(), // Ship shape (3 lines)
@@ -763,7 +763,7 @@ void EscenaJoc::dibuixar_marcador() {
float centre_y = scoreboard.y + (scoreboard.h / 2.0F);
// Renderitzar centrat
text_.render_centered(text, {centre_x, centre_y}, escala, spacing);
text_.render_centered(text, {.x = centre_x, .y = centre_y}, escala, spacing);
}
void EscenaJoc::dibuixar_marges_animat(float progress) const {
@@ -844,13 +844,13 @@ void EscenaJoc::dibuixar_marcador_animat(float progress) {
float centre_y_final = scoreboard.y + (scoreboard.h / 2.0F);
// Posició Y inicial (offscreen, sota de la pantalla)
float centre_y_inicial = static_cast<float>(Defaults::Game::HEIGHT);
auto centre_y_inicial = static_cast<float>(Defaults::Game::HEIGHT);
// Interpolació amb easing
float centre_y_animada = centre_y_inicial + ((centre_y_final - centre_y_inicial) * eased_progress);
// Renderitzar centrat en posició animada
text_.render_centered(text, {centre_x, centre_y_animada}, escala, spacing);
text_.render_centered(text, {.x = centre_x, .y = centre_y_animada}, escala, spacing);
}
Punt EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const {
@@ -874,7 +874,7 @@ Punt EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id)
// Y interpola amb easing
float y_animada = y_inicial + ((y_final - y_inicial) * eased_progress);
return {x_final, y_animada};
return {.x = x_final, .y = y_animada};
}
float EscenaJoc::calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const {
@@ -1061,8 +1061,8 @@ void EscenaJoc::detectar_col·lisio_naus_enemics() {
const Punt& pos_enemic = enemic.get_centre();
// Calculate squared distance (avoid sqrt)
float dx = static_cast<float>(pos_nau.x - pos_enemic.x);
float dy = static_cast<float>(pos_nau.y - pos_enemic.y);
auto dx = static_cast<float>(pos_nau.x - pos_enemic.x);
auto dy = static_cast<float>(pos_nau.y - pos_enemic.y);
float distancia_quadrada = (dx * dx) + (dy * dy);
// Check collision
@@ -1220,7 +1220,7 @@ void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) {
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)
Punt pos = {x, y};
Punt pos = {.x = x, .y = y};
text_.render(partial_message, pos, escala, spacing);
}
@@ -1243,8 +1243,8 @@ Punt EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const {
}
return {
zona.x + (zona.w * x_ratio),
zona.y + (zona.h * Defaults::Game::SPAWN_Y_RATIO)};
.x = zona.x + (zona.w * x_ratio),
.y = zona.y + (zona.h * Defaults::Game::SPAWN_Y_RATIO)};
}
void EscenaJoc::disparar_bala(uint8_t player_id) {
@@ -1266,7 +1266,7 @@ void EscenaJoc::disparar_bala(uint8_t player_id) {
float sin_a = std::sin(ship_angle);
float tip_x = (LOCAL_TIP_X * cos_a) - (LOCAL_TIP_Y * sin_a) + ship_centre.x;
float tip_y = (LOCAL_TIP_X * sin_a) + (LOCAL_TIP_Y * cos_a) + ship_centre.y;
Punt posicio_dispar = {tip_x, tip_y};
Punt posicio_dispar = {.x = tip_x, .y = tip_y};
// Buscar primera bala inactiva en el pool del jugador
int start_idx = player_id * 3; // P1=[0,1,2], P2=[3,4,5]
@@ -1400,7 +1400,7 @@ void EscenaJoc::dibuixar_continue() {
float centre_x = play_area.x + (play_area.w / 2.0F);
float centre_y_continue = play_area.y + (play_area.h * y_ratio_continue);
text_.render_centered(continue_text, {centre_x, centre_y_continue}, escala_continue, spacing);
text_.render_centered(continue_text, {.x = centre_x, .y = centre_y_continue}, escala_continue, spacing);
// Countdown number (using constants)
const std::string counter_str = std::to_string(continue_counter_);
@@ -1409,7 +1409,7 @@ void EscenaJoc::dibuixar_continue() {
float centre_y_counter = play_area.y + (play_area.h * y_ratio_counter);
text_.render_centered(counter_str, {centre_x, centre_y_counter}, escala_counter, spacing);
text_.render_centered(counter_str, {.x = centre_x, .y = centre_y_counter}, escala_counter, spacing);
// "CONTINUES LEFT" (conditional + using constants)
if (!Defaults::Game::INFINITE_CONTINUES) {
@@ -1419,7 +1419,7 @@ void EscenaJoc::dibuixar_continue() {
float centre_y_info = play_area.y + (play_area.h * y_ratio_info);
text_.render_centered(continues_text, {centre_x, centre_y_info}, escala_info, spacing);
text_.render_centered(continues_text, {.x = centre_x, .y = centre_y_info}, escala_info, spacing);
}
}

View File

@@ -87,7 +87,7 @@ class EscenaJoc {
void dibuixar_marges() const; // Dibuixar vores de la zona de joc
void dibuixar_marcador(); // Dibuixar marcador de puntuació
void disparar_bala(uint8_t player_id); // Shoot bullet from player
Punt obtenir_punt_spawn(uint8_t player_id) const; // Get spawn position for player
[[nodiscard]] Punt obtenir_punt_spawn(uint8_t player_id) const; // Get spawn position for player
// [NEW] Continue & Join system
void unir_jugador(uint8_t player_id); // Join inactive player mid-game
@@ -102,13 +102,13 @@ class EscenaJoc {
// [NEW] Funcions d'animació per INIT_HUD
void dibuixar_marges_animat(float progress) const; // Rectangle amb creixement uniforme
void dibuixar_marcador_animat(float progress); // Marcador que puja des de baix
Punt calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la nau
[[nodiscard]] Punt calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la nau
// [NEW] Función helper del sistema de animación INIT_HUD
float calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const;
[[nodiscard]] float calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const;
// [NEW] Funció helper del marcador
std::string construir_marcador() const;
[[nodiscard]] std::string construir_marcador() const;
};
#endif // ESCENA_JOC_HPP

View File

@@ -167,7 +167,7 @@ void EscenaLogo::inicialitzar_lletres() {
float offset_centre = (forma->get_centre().x - min_x) * ESCALA_FINAL;
lletres_.push_back({forma,
{0.0F, 0.0F}, // Posició es calcularà després
{.x = 0.0F, .y = 0.0F}, // Posició es calcularà després
ancho,
offset_centre});
@@ -249,7 +249,7 @@ void EscenaLogo::actualitzar_explosions(float delta_time) {
ESCALA_FINAL, // Escala (lletres a escala final)
VELOCITAT_EXPLOSIO, // Velocitat base
1.0F, // Brightness màxim (per defecte)
{0.0F, 0.0F} // Sense velocitat (per defecte)
{.x = 0.0F, .y = 0.0F} // Sense velocitat (per defecte)
);
std::cout << "[EscenaLogo] Explota lletra " << lletra_explosio_index_ << "\n";
@@ -347,7 +347,7 @@ void EscenaLogo::dibuixar() {
? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F)
: 1.0F; // POST: mantenir al 100%
const Punt ORIGEN_ZOOM = {ORIGEN_ZOOM_X, ORIGEN_ZOOM_Y};
const Punt ORIGEN_ZOOM = {.x = ORIGEN_ZOOM_X, .y = ORIGEN_ZOOM_Y};
for (size_t i = 0; i < lletres_.size(); i++) {
const auto& lletra = lletres_[i];

View File

@@ -87,5 +87,5 @@ class EscenaLogo {
// Mètodes de gestió d'estats
void canviar_estat(EstatAnimacio nou_estat);
bool totes_lletres_completes() const;
[[nodiscard]] bool totes_lletres_completes() const;
};

View File

@@ -7,6 +7,7 @@
#include <cfloat>
#include <cmath>
#include <iostream>
#include <numbers>
#include <string>
#include "core/audio/audio.hpp"
@@ -51,8 +52,8 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context)
// Crear starfield de fons
Punt centre_pantalla{
Defaults::Game::WIDTH / 2.0F,
Defaults::Game::HEIGHT / 2.0F};
.x = Defaults::Game::WIDTH / 2.0F,
.y = Defaults::Game::HEIGHT / 2.0F};
SDL_FRect area_completa{
0,
@@ -146,7 +147,7 @@ void EscenaTitol::inicialitzar_titol() {
float altura = altura_sin_escalar * Defaults::Title::Layout::LOGO_SCALE;
float offset_centre = (forma->get_centre().x - min_x) * Defaults::Title::Layout::LOGO_SCALE;
lletres_orni_.push_back({forma, {0.0F, 0.0F}, ancho, altura, offset_centre});
lletres_orni_.push_back({forma, {.x = 0.0F, .y = 0.0F}, ancho, altura, offset_centre});
ancho_total_orni += ancho;
}
@@ -220,7 +221,7 @@ void EscenaTitol::inicialitzar_titol() {
float altura = altura_sin_escalar * Defaults::Title::Layout::LOGO_SCALE;
float offset_centre = (forma->get_centre().x - min_x) * Defaults::Title::Layout::LOGO_SCALE;
lletres_attack_.push_back({forma, {0.0F, 0.0F}, ancho, altura, offset_centre});
lletres_attack_.push_back({forma, {.x = 0.0F, .y = 0.0F}, ancho, altura, offset_centre});
ancho_total_attack += ancho;
}
@@ -653,7 +654,7 @@ void EscenaTitol::dibuixar() {
bool mostrar_text = true;
if (estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE) {
// Parpelleig: sin oscil·la entre -1 i 1, volem ON quan > 0
float fase = temps_acumulat_ * BLINK_FREQUENCY * 2.0F * 3.14159F; // 2π × freq × temps
float fase = temps_acumulat_ * BLINK_FREQUENCY * 2.0F * std::numbers::pi_v<float>; // 2π × freq × temps
mostrar_text = (std::sin(fase) > 0.0F);
}
@@ -664,7 +665,7 @@ void EscenaTitol::dibuixar() {
float centre_x = Defaults::Game::WIDTH / 2.0F;
float centre_y = Defaults::Game::HEIGHT * Defaults::Title::Layout::PRESS_START_POS;
text_.render_centered(main_text, {centre_x, centre_y}, escala_main, spacing);
text_.render_centered(main_text, {.x = centre_x, .y = centre_y}, escala_main, spacing);
}
// === Copyright a la part inferior (centrat horitzontalment, dues línies) ===
@@ -695,8 +696,8 @@ void EscenaTitol::dibuixar() {
// Renderitzar línees centrades
float centre_x = Defaults::Game::WIDTH / 2.0F;
text_.render_centered(copyright_original, {centre_x, y_line1}, escala_copy, spacing);
text_.render_centered(copyright_port, {centre_x, y_line2}, escala_copy, spacing);
text_.render_centered(copyright_original, {.x = centre_x, .y = y_line1}, escala_copy, spacing);
text_.render_centered(copyright_port, {.x = centre_x, .y = y_line2}, escala_copy, spacing);
}
}

View File

@@ -395,7 +395,7 @@ static void loadAudioConfigFromYaml(const fkyaml::node& yaml) {
if (aud.contains("volume")) {
try {
float val = aud["volume"].get_value<float>();
auto val = aud["volume"].get_value<float>();
audio.volume = (val >= 0.0F && val <= 1.0F) ? val : Defaults::Audio::VOLUME;
} catch (...) {
audio.volume = Defaults::Audio::VOLUME;
@@ -415,7 +415,7 @@ static void loadAudioConfigFromYaml(const fkyaml::node& yaml) {
if (mus.contains("volume")) {
try {
float val = mus["volume"].get_value<float>();
auto val = mus["volume"].get_value<float>();
audio.music.volume = (val >= 0.0F && val <= 1.0F) ? val : Defaults::Music::VOLUME;
} catch (...) {
audio.music.volume = Defaults::Music::VOLUME;
@@ -436,7 +436,7 @@ static void loadAudioConfigFromYaml(const fkyaml::node& yaml) {
if (snd.contains("volume")) {
try {
float val = snd["volume"].get_value<float>();
auto val = snd["volume"].get_value<float>();
audio.sound.volume = (val >= 0.0F && val <= 1.0F) ? val : Defaults::Sound::VOLUME;
} catch (...) {
audio.sound.volume = Defaults::Sound::VOLUME;

View File

@@ -5,6 +5,7 @@
#include <cstdlib>
#include <iostream>
#include <utility>
namespace StageSystem {
@@ -133,7 +134,7 @@ TipusEnemic SpawnController::seleccionar_tipus_aleatori() const {
// Weighted random selection based on distribution
int rand_val = std::rand() % 100;
if (rand_val < config_->distribucio.pentagon) {
if (std::cmp_less(rand_val, config_->distribucio.pentagon)) {
return TipusEnemic::PENTAGON;
}
if (rand_val < config_->distribucio.pentagon + config_->distribucio.quadrat) {

View File

@@ -33,10 +33,10 @@ class SpawnController {
void actualitzar(float delta_time, std::array<Enemic, 15>& orni_array, bool pausar = false);
// Status queries
bool tots_enemics_spawnejats() const;
bool tots_enemics_destruits(const std::array<Enemic, 15>& orni_array) const;
uint8_t get_enemics_vius(const std::array<Enemic, 15>& orni_array) const;
uint8_t get_enemics_spawnejats() const;
[[nodiscard]] bool tots_enemics_spawnejats() const;
[[nodiscard]] bool tots_enemics_destruits(const std::array<Enemic, 15>& orni_array) const;
[[nodiscard]] uint8_t get_enemics_vius(const std::array<Enemic, 15>& orni_array) const;
[[nodiscard]] uint8_t get_enemics_spawnejats() const;
// [NEW] Set ship position reference for safe spawn
void set_ship_position(const Punt* ship_pos) { ship_position_ = ship_pos; }
@@ -49,7 +49,7 @@ class SpawnController {
// Spawn generation
void generar_spawn_events();
TipusEnemic seleccionar_tipus_aleatori() const;
[[nodiscard]] TipusEnemic seleccionar_tipus_aleatori() const;
void spawn_enemic(Enemic& enemic, TipusEnemic tipus, const Punt* ship_pos = nullptr);
void aplicar_multiplicadors(Enemic& enemic) const;
const Punt* ship_position_; // [NEW] Non-owning pointer to ship position

View File

@@ -55,7 +55,7 @@ struct ConfigStage {
MultiplicadorsDificultat multiplicadors;
// Validació
bool es_valid() const {
[[nodiscard]] bool es_valid() const {
return stage_id >= 1 && stage_id <= 255 &&
total_enemics > 0 && total_enemics <= 15 &&
distribucio.pentagon + distribucio.quadrat + distribucio.molinillo == 100;
@@ -68,7 +68,7 @@ struct ConfigSistemaStages {
std::vector<ConfigStage> stages; // Índex [0] = stage 1
// Obtenir configuració d'un stage específic
const ConfigStage* obte_stage(uint8_t stage_id) const {
[[nodiscard]] const ConfigStage* obte_stage(uint8_t stage_id) const {
if (stage_id < 1 || stage_id > stages.size()) {
return nullptr;
}

View File

@@ -141,7 +141,7 @@ bool StageLoader::parse_spawn_config(const fkyaml::node& yaml, ConfigSpawn& conf
return false;
}
std::string mode_str = yaml["mode"].get_value<std::string>();
auto mode_str = yaml["mode"].get_value<std::string>();
config.mode = parse_spawn_mode(mode_str);
config.delay_inicial = yaml["initial_delay"].get_value<float>();
config.interval_spawn = yaml["spawn_interval"].get_value<float>();

View File

@@ -29,18 +29,18 @@ class StageManager {
// Stage progression
void stage_completat(); // Call when all enemies destroyed
bool tot_completat() const; // All 10 stages done?
[[nodiscard]] bool tot_completat() const; // All 10 stages done?
// Current state queries
EstatStage get_estat() const { return estat_; }
uint8_t get_stage_actual() const { return stage_actual_; }
const ConfigStage* get_config_actual() const;
float get_timer_transicio() const { return timer_transicio_; }
const std::string& get_missatge_level_start() const { return missatge_level_start_actual_; }
[[nodiscard]] EstatStage get_estat() const { return estat_; }
[[nodiscard]] uint8_t get_stage_actual() const { return stage_actual_; }
[[nodiscard]] const ConfigStage* get_config_actual() const;
[[nodiscard]] float get_timer_transicio() const { return timer_transicio_; }
[[nodiscard]] const std::string& get_missatge_level_start() const { return missatge_level_start_actual_; }
// Spawn control (delegate to SpawnController)
SpawnController& get_spawn_controller() { return spawn_controller_; }
const SpawnController& get_spawn_controller() const { return spawn_controller_; }
[[nodiscard]] const SpawnController& get_spawn_controller() const { return spawn_controller_; }
private:
const ConfigSistemaStages* config_; // Non-owning pointer

View File

@@ -232,7 +232,7 @@ void ShipAnimator::actualitzar_exiting(NauTitol& nau, float delta_time) {
float eased_progress = Easing::ease_in_quad(progress);
// Punt de fuga (centre del starfield)
constexpr Punt punt_fuga{VANISHING_POINT_X, VANISHING_POINT_Y};
constexpr Punt punt_fuga{.x = VANISHING_POINT_X, .y = VANISHING_POINT_Y};
// Lerp posició cap al punt de fuga (preservar posició inicial actual)
// Nota: posicio_inicial conté la posició on estava quan es va activar EXITING
@@ -257,7 +257,7 @@ void ShipAnimator::configurar_nau_p1(NauTitol& nau) {
nau.temps_estat = 0.0F;
// Posicions (clock 8, bottom-left)
nau.posicio_objectiu = {P1_TARGET_X(), P1_TARGET_Y()};
nau.posicio_objectiu = {.x = P1_TARGET_X(), .y = P1_TARGET_Y()};
// Calcular posició inicial (fora de pantalla)
nau.posicio_inicial = calcular_posicio_fora_pantalla(CLOCK_8_ANGLE);
@@ -292,7 +292,7 @@ void ShipAnimator::configurar_nau_p2(NauTitol& nau) {
nau.temps_estat = 0.0F;
// Posicions (clock 4, bottom-right)
nau.posicio_objectiu = {P2_TARGET_X(), P2_TARGET_Y()};
nau.posicio_objectiu = {.x = P2_TARGET_X(), .y = P2_TARGET_Y()};
// Calcular posició inicial (fora de pantalla)
nau.posicio_inicial = calcular_posicio_fora_pantalla(CLOCK_4_ANGLE);
@@ -330,7 +330,7 @@ Punt ShipAnimator::calcular_posicio_fora_pantalla(float angle_rellotge) const {
float x = (Defaults::Game::WIDTH / 2.0F) + (extended_radius * std::cos(angle_rellotge));
float y = (Defaults::Game::HEIGHT / 2.0F) + (extended_radius * std::sin(angle_rellotge));
return {x, y};
return {.x = x, .y = y};
}
} // namespace Title

View File

@@ -77,8 +77,8 @@ class ShipAnimator {
// Control de visibilitat
void set_visible(bool visible);
bool is_animation_complete() const;
bool is_visible() const; // Comprova si alguna nau és visible
[[nodiscard]] bool is_animation_complete() const;
[[nodiscard]] bool is_visible() const; // Comprova si alguna nau és visible
private:
SDL_Renderer* renderer_;
@@ -92,7 +92,7 @@ class ShipAnimator {
// Configuració
void configurar_nau_p1(NauTitol& nau);
void configurar_nau_p2(NauTitol& nau);
Punt calcular_posicio_fora_pantalla(float angle_rellotge) const;
[[nodiscard]] Punt calcular_posicio_fora_pantalla(float angle_rellotge) const;
};
} // namespace Title