Lint: rename públicos al inglés + refactor cognitive-complexity + unused-includes

Identifier-naming: rename de métodos públicos y cross-file al inglés
(camelBack), traducción de campos y locales en el proceso (TitleShip,
StageManager, SpawnController, ShipAnimator, helpers de PlayArea, etc.).

Refactor por cognitive-complexity (>25): GameScene::draw (59→3) con 9
helpers de estado, PhysicsWorld::resolveBodyCollisions (35→5) extrayendo
resolveBodyPair, Options::load{Window,Physics,Audio}ConfigFromYaml
(32/49/57→5/2/3) con templates readField, TitleScene::update (68→4) con
5 sub-pasos por estado + handleSkipInput/handleStartInput +
triggerExitForJoinedPlayers, DebrisManager::explode (39→3) con
extractSegments/spawnDebris/applyAngularVelocity/applyVisualRotation.

use-anyofallof: bucles → std::ranges::any_of/all_of en Input,
ShipAnimator y SpawnController.

readability-static-accessed-through-instance: Director::run y
VectorText::getTextWidth/Height invocados por clase.

readability-convert-member-functions-to-static: ResourcePack::decryptData.

unused-includes: eliminación de <utility>, <cstdint>, <vector>,
<iostream>, defaults.hpp y otros no usados directamente en headers y
unidades de traducción. Restablecido core/defaults.hpp en title_scene.cpp
(falsa "unused" del header).

Bug fix: eliminado isActive() duplicado en Bullet (redeclaración tras
rename de esta_activa→isActive que chocaba con el override de Entity).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 13:41:33 +02:00
parent 4e5ab6be1d
commit bbbb8d47ae
53 changed files with 818 additions and 894 deletions
+136 -133
View File
@@ -62,147 +62,150 @@ void DebrisManager::explode(const std::shared_ptr<Graphics::Shape>& shape,
// Reproducir sonido de explosión
Audio::get()->playSound(sound, Audio::Group::GAME);
// Obtenir centro de la shape para transformacions
const Vec2& shape_centre = shape->getCenter();
// Iterar sobre todas las primitives de la shape
for (const auto& primitive : shape->get_primitives()) {
// Processar cada segment de línia
std::vector<std::pair<Vec2, Vec2>> segments;
for (const auto& primitive : shape->getPrimitives()) {
for (const auto& [local_p1, local_p2] : extractSegments(primitive)) {
// Transformar points locals → coordenades mundials
Vec2 world_p1 = transformPoint(local_p1, shape_centre, centro, angle, scale);
Vec2 world_p2 = transformPoint(local_p2, shape_centre, centro, angle, scale);
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
// Polyline: extreure segments consecutius
for (size_t i = 0; i < primitive.points.size() - 1; i++) {
segments.emplace_back(primitive.points[i], primitive.points[i + 1]);
}
} else { // PrimitiveType::LINE
// Line: un únic segment
if (primitive.points.size() >= 2) {
segments.emplace_back(primitive.points[0], primitive.points[1]);
// Si el pool es ple, no té sentit continuar amb la resta de segments
if (!spawnDebris(world_p1, world_p2, centro, velocitat_base, brightness,
velocitat_objecte, velocitat_angular,
factor_herencia_visual, color)) {
return;
}
}
}
}
// Crear debris para cada segment
for (const auto& [local_p1, local_p2] : segments) {
// 1. Transformar points locals → coordenades mundials
Vec2 world_p1 =
transformPoint(local_p1, shape_centre, centro, angle, scale);
Vec2 world_p2 =
transformPoint(local_p2, shape_centre, centro, angle, scale);
auto DebrisManager::extractSegments(const Graphics::ShapePrimitive& primitive)
-> std::vector<std::pair<Vec2, Vec2>> {
std::vector<std::pair<Vec2, Vec2>> segments;
// 2. Trobar slot lliure
Debris* debris = findFreeSlot();
if (debris == nullptr) {
std::cerr << "[DebrisManager] Warning: no debris slots disponibles\n";
return; // Pool ple
}
// 3. Inicialitzar geometria
debris->p1 = world_p1;
debris->p2 = world_p2;
// 4. Calcular direcció de explosión (radial, des del centro hacia fuera)
Vec2 direccio = computeExplosionDirection(world_p1, world_p2, centro);
// 5. Velocidad 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 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 velocity angular con sin + conversió de excés
// 6a. Rotación de TRAYECTORIA con sin + conversió tangencial
if (std::abs(velocitat_angular) > 0.01F) {
// FASE 1: Aplicar herència i variació (igual que antes)
float factor_herencia =
Defaults::Physics::Debris::FACTOR_HERENCIA_MIN +
((std::rand() / static_cast<float>(RAND_MAX)) *
(Defaults::Physics::Debris::FACTOR_HERENCIA_MAX -
Defaults::Physics::Debris::FACTOR_HERENCIA_MIN));
float velocitat_ang_heretada = velocitat_angular * factor_herencia;
float variacio =
((std::rand() / static_cast<float>(RAND_MAX)) * 0.2F) - 0.1F;
velocitat_ang_heretada *= (1.0F + variacio);
// FASE 2: Aplicar sin i calcular excés
constexpr float CAP = Defaults::Physics::Debris::VELOCITAT_ROT_MAX;
float abs_ang = std::abs(velocitat_ang_heretada);
float sign_ang = (velocitat_ang_heretada >= 0.0F) ? 1.0F : -1.0F;
if (abs_ang > CAP) {
// Excés: convertir a velocity tangencial
float excess = abs_ang - CAP;
// Radi de la shape (enemigos = 20 px)
float radius = 20.0F;
// Velocidad tangencial = ω_excés × radi
float v_tangential = excess * radius;
// Direcció tangencial: perpendicular a la radial (90° CCW)
// Si direccio = (dx, dy), tangent = (-dy, dx)
float tangent_x = -direccio.y;
float tangent_y = direccio.x;
// Añadir velocity tangencial (suma vectorial)
debris->velocity.x += tangent_x * v_tangential;
debris->velocity.y += tangent_y * v_tangential;
// Aplicar hacia velocity angular (preservar signe)
debris->velocitat_rot = sign_ang * CAP;
} else {
// Per sota del sin: comportament normal
debris->velocitat_rot = velocitat_ang_heretada;
}
} else {
debris->velocitat_rot = 0.0F; // Nave: sin curvas
}
// 6b. Rotación VISUAL (proporcional según factor_herencia_visual)
if (factor_herencia_visual > 0.01F && std::abs(velocitat_angular) > 0.01F) {
// Heredar rotación visual con factor proporcional
debris->velocitat_rot_visual = debris->velocitat_rot * factor_herencia_visual;
// Variació aleatòria pequeña (±5%) per naturalitat
float variacio_visual =
((std::rand() / static_cast<float>(RAND_MAX)) * 0.1F) - 0.05F;
debris->velocitat_rot_visual *= (1.0F + variacio_visual);
} else {
// Rotación visual aleatòria (factor = 0.0 o sin velocidad angular)
debris->velocitat_rot_visual =
Defaults::Physics::Debris::ROTACIO_MIN +
((std::rand() / static_cast<float>(RAND_MAX)) *
(Defaults::Physics::Debris::ROTACIO_MAX -
Defaults::Physics::Debris::ROTACIO_MIN));
// 50% probabilitat de rotación en sentit contrari
if (std::rand() % 2 == 0) {
debris->velocitat_rot_visual = -debris->velocitat_rot_visual;
}
}
debris->angle_rotacio = 0.0F;
// 7. Configurar vida i shrinking
debris->temps_vida = 0.0F;
debris->temps_max = Defaults::Physics::Debris::TEMPS_VIDA;
debris->factor_shrink = Defaults::Physics::Debris::SHRINK_RATE;
// 8. Heredar brightness y color del padre
debris->brightness = brightness;
debris->color = color;
// 9. Activar
debris->active = true;
if (primitive.type == Graphics::PrimitiveType::POLYLINE) {
// Polyline: extreure segments consecutius
for (size_t i = 0; i + 1 < primitive.points.size(); i++) {
segments.emplace_back(primitive.points[i], primitive.points[i + 1]);
}
return segments;
}
// PrimitiveType::LINE: un únic segment (si té els 2 punts)
if (primitive.points.size() >= 2) {
segments.emplace_back(primitive.points[0], primitive.points[1]);
}
return segments;
}
auto DebrisManager::spawnDebris(const Vec2& world_p1, const Vec2& world_p2,
const Vec2& centro, float velocitat_base, float brightness,
const Vec2& velocitat_objecte, float velocitat_angular,
float factor_herencia_visual, SDL_Color color) -> bool {
Debris* debris = findFreeSlot();
if (debris == nullptr) {
std::cerr << "[DebrisManager] Warning: no debris slots disponibles\n";
return false;
}
// Geometria
debris->p1 = world_p1;
debris->p2 = world_p2;
// Direcció radial (desde el centro hacia el segment)
Vec2 direccio = computeExplosionDirection(world_p1, world_p2, centro);
// Velocidad inicial (base ± variació aleatòria + velocity heretada de l'objecte)
float speed =
velocitat_base +
(((std::rand() / static_cast<float>(RAND_MAX)) * 2.0F - 1.0F) *
Defaults::Physics::Debris::VARIACIO_VELOCITAT);
debris->velocity.x = (direccio.x * speed) + velocitat_objecte.x;
debris->velocity.y = (direccio.y * speed) + velocitat_objecte.y;
debris->acceleration = Defaults::Physics::Debris::ACCELERACIO;
// Rotación de trayectoria (con conversió a tangencial si excedeix cap)
applyAngularVelocity(*debris, direccio, velocitat_angular);
// Rotación visual (proporcional o aleatòria)
applyVisualRotation(*debris, velocitat_angular, factor_herencia_visual);
debris->angle_rotacio = 0.0F;
// Vida i shrinking
debris->temps_vida = 0.0F;
debris->temps_max = Defaults::Physics::Debris::TEMPS_VIDA;
debris->factor_shrink = Defaults::Physics::Debris::SHRINK_RATE;
// Visuals heretades
debris->brightness = brightness;
debris->color = color;
debris->active = true;
return true;
}
void DebrisManager::applyAngularVelocity(Debris& debris, const Vec2& direccio,
float velocitat_angular) {
if (std::abs(velocitat_angular) <= 0.01F) {
debris.velocitat_rot = 0.0F; // Nave: sin curvas
return;
}
// FASE 1: Aplicar herència i variació
float factor_herencia =
Defaults::Physics::Debris::FACTOR_HERENCIA_MIN +
((std::rand() / static_cast<float>(RAND_MAX)) *
(Defaults::Physics::Debris::FACTOR_HERENCIA_MAX -
Defaults::Physics::Debris::FACTOR_HERENCIA_MIN));
float velocitat_ang_heretada = velocitat_angular * factor_herencia;
float variacio = ((std::rand() / static_cast<float>(RAND_MAX)) * 0.2F) - 0.1F;
velocitat_ang_heretada *= (1.0F + variacio);
// FASE 2: Cap a la velocity màxima; l'excés es converteix en tangencial
constexpr float CAP = Defaults::Physics::Debris::VELOCITAT_ROT_MAX;
float abs_ang = std::abs(velocitat_ang_heretada);
float sign_ang = (velocitat_ang_heretada >= 0.0F) ? 1.0F : -1.0F;
if (abs_ang <= CAP) {
debris.velocitat_rot = velocitat_ang_heretada;
return;
}
// Excés: converteix l'excés de velocitat angular en velocitat tangencial lineal
float excess = abs_ang - CAP;
constexpr float RADIUS = 20.0F; // Radi típic de la shape (enemigos = 20 px)
float v_tangential = excess * RADIUS;
// Direcció tangencial: perpendicular a la radial (90° CCW): tangent = (-dy, dx)
debris.velocity.x += -direccio.y * v_tangential;
debris.velocity.y += direccio.x * v_tangential;
// Velocitat angular limitada al cap (preservant el signe)
debris.velocitat_rot = sign_ang * CAP;
}
void DebrisManager::applyVisualRotation(Debris& debris, float velocitat_angular,
float factor_herencia_visual) {
if (factor_herencia_visual > 0.01F && std::abs(velocitat_angular) > 0.01F) {
// Heredar rotación visual con factor proporcional + ±5% de variació
debris.velocitat_rot_visual = debris.velocitat_rot * factor_herencia_visual;
float variacio_visual =
((std::rand() / static_cast<float>(RAND_MAX)) * 0.1F) - 0.05F;
debris.velocitat_rot_visual *= (1.0F + variacio_visual);
return;
}
// Rotación visual aleatòria (factor = 0.0 o sin velocidad angular)
debris.velocitat_rot_visual =
Defaults::Physics::Debris::ROTACIO_MIN +
((std::rand() / static_cast<float>(RAND_MAX)) *
(Defaults::Physics::Debris::ROTACIO_MAX -
Defaults::Physics::Debris::ROTACIO_MIN));
// 50% probabilitat de rotación en sentit contrari
if (std::rand() % 2 == 0) {
debris.velocitat_rot_visual = -debris.velocitat_rot_visual;
}
}