Files
orni-attack/source/core/graphics/starfield.cpp
T
JailDesigner 6d0df85e5e Lint: rename de métodos privados (camelBack + traducción al inglés)
Tanda grande de identifier-naming: 47 métodos privados pasan de
snake_case (en su mayoría catalán/spanish) a camelBack inglés. Solo
afecta a sus archivos hpp+cpp; ningún símbolo cruza fichero (los
públicos quedan para una pasada manual con VS Code).

Renames por clase:

- ShapeLoader: resolve_path → resolvePath.
- VectorText: load_charset → loadCharset, get_shape_filename →
  getShapeFilename.
- Shape: starts_with → startsWith (cuidado de no tocar
  std::string::starts_with que también usaba), extract_value →
  extractValue, parse_center → parseCenter, parse_points → parsePoints.
- Starfield: inicialitzar_estrella → initStar, fora_area →
  isOutsideArea, calcular_escala → computeScale, calcular_brightness →
  computeBrightness.
- TitleScene: actualitzar_animacio_logo → updateLogoAnimation,
  inicialitzar_titol → initTitle.
- LogoScene: inicialitzar_lletres → initLetters, actualitzar_explosions
  → updateExplosions, canviar_estat → changeState,
  totes_lletres_completes → allLettersComplete.
- SpawnController: generar_spawn_events → generateSpawnEvents,
  seleccionar_tipus_aleatori → selectRandomType, spawn_enemic →
  spawnEnemy, aplicar_multiplicadors → applyMultipliers.
- ShipAnimator: actualitzar_entering/floating/exiting →
  updateEntering/Floating/Exiting, configurar_nau_p1/p2 →
  configureShipP1/P2, calcular_posicio_fora_pantalla →
  computeOffscreenPosition.
- GameScene: dibuixar_marges → drawMargins, dibuixar_marcador →
  drawScoreboard, disparar_bala → fireBullet, obtenir_punt_spawn →
  getSpawnPoint, unir_jugador → joinPlayer, dibuixar_continue →
  drawContinue, dibuixar_missatge_stage → drawStageMessage.
- StageLoader: parse_metadata/stage/spawn_config/distribution/multipliers/
  spawn_mode → parseMetadata/Stage/SpawnConfig/Distribution/Multipliers/
  SpawnMode, validar_config → validateConfig.
- StageManager: canviar_estat → changeState,
  processar_init_hud/level_start/playing/level_completed →
  processInitHud/LevelStart/Playing/LevelCompleted, carregar_stage →
  loadStage.

Métodos públicos y funciones libres (cross-file) quedan a propósito sin
tocar — los renombrará el usuario con la herramienta de rename de VS Code.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 11:55:21 +02:00

169 lines
6.0 KiB
C++

// starfield.cpp - Implementació del sistema de estrelles de fons
// © 2026 JailDesigner
#include "core/graphics/starfield.hpp"
#include <cmath>
#include <cstdlib>
#include <iostream>
#include "core/defaults.hpp"
#include "core/graphics/shape_loader.hpp"
#include "core/rendering/shape_renderer.hpp"
namespace Graphics {
// Constructor
Starfield::Starfield(Rendering::Renderer* renderer,
const Vec2& punt_fuga,
const SDL_FRect& area,
int densitat)
: shape_estrella_(ShapeLoader::load("star.shp")),
renderer_(renderer),
punt_fuga_(punt_fuga),
area_(area) {
if (!shape_estrella_ || !shape_estrella_->isValid()) {
std::cerr << "ERROR: No s'ha pogut load star.shp" << '\n';
return;
}
// Configurar 3 capes con diferents velocitats i escales
// Capa 0: Fons llunyà (lenta, pequeña)
capes_.push_back({20.0F, 0.3F, 0.8F, densitat / 3});
// Capa 1: Profunditat mitjana
capes_.push_back({40.0F, 0.5F, 1.2F, densitat / 3});
// Capa 2: Primer pla (ràpida, grande)
capes_.push_back({80.0F, 0.8F, 2.0F, densitat / 3});
// Calcular radi màxim (distancia del centro al racó més llunyà)
float dx = std::max(punt_fuga_.x, area_.w - punt_fuga_.x);
float dy = std::max(punt_fuga_.y, area_.h - punt_fuga_.y);
radi_max_ = std::sqrt((dx * dx) + (dy * dy));
// Inicialitzar estrelles con posicions distribuïdes (pre-omplir pantalla)
for (int capa_idx = 0; capa_idx < 3; capa_idx++) {
int num = capes_[capa_idx].num_estrelles;
for (int i = 0; i < num; i++) {
Estrella estrella;
estrella.capa = capa_idx;
// Angle aleatori
estrella.angle = (static_cast<float>(rand()) / RAND_MAX) * 2.0F * Defaults::Math::PI;
// Distancia aleatòria (0.0 a 1.0) per omplir toda la pantalla
estrella.distancia_centre = static_cast<float>(rand()) / RAND_MAX;
// Calcular posición desde la distancia
float radi = estrella.distancia_centre * radi_max_;
estrella.position.x = punt_fuga_.x + (radi * std::cos(estrella.angle));
estrella.position.y = punt_fuga_.y + (radi * std::sin(estrella.angle));
estrelles_.push_back(estrella);
}
}
}
// Inicialitzar una estrella (nueva o regenerada)
void Starfield::initStar(Estrella& estrella) const {
// Angle aleatori des del point de fuga hacia fuera
estrella.angle = (static_cast<float>(rand()) / RAND_MAX) * 2.0F * Defaults::Math::PI;
// Distancia inicial pequeña (5% del radi màxim) - neix prop del centro
estrella.distancia_centre = 0.05F;
// Posición inicial: mucho prop del point de fuga
float radi = estrella.distancia_centre * radi_max_;
estrella.position.x = punt_fuga_.x + (radi * std::cos(estrella.angle));
estrella.position.y = punt_fuga_.y + (radi * std::sin(estrella.angle));
}
// Verificar si una estrella está fuera de l'àrea
auto Starfield::isOutsideArea(const Estrella& estrella) const -> bool {
return (estrella.position.x < area_.x ||
estrella.position.x > area_.x + area_.w ||
estrella.position.y < area_.y ||
estrella.position.y > area_.y + area_.h);
}
// Calcular scale dinàmica segons distancia del centro
auto Starfield::computeScale(const Estrella& estrella) const -> float {
const CapaConfig& capa = capes_[estrella.capa];
// Interpolació lineal basada en distancia del centro
// distancia_centre: 0.0 (centro) → 1.0 (vora)
return capa.escala_min +
((capa.escala_max - capa.escala_min) * estrella.distancia_centre);
}
// Calcular brightness dinàmica segons distancia del centro
auto Starfield::computeBrightness(const Estrella& estrella) const -> float {
// Interpolació lineal: estrelles properes (vora) més brillants
// distancia_centre: 0.0 (centro, llunyanes) → 1.0 (vora, properes)
float brightness_base = Defaults::Brightness::STARFIELD_MIN +
((Defaults::Brightness::STARFIELD_MAX - Defaults::Brightness::STARFIELD_MIN) *
estrella.distancia_centre);
// Aplicar multiplicador i limitar a 1.0
return std::min(1.0F, brightness_base * multiplicador_brightness_);
}
// Actualitzar posicions de las estrelles
void Starfield::update(float delta_time) {
for (auto& estrella : estrelles_) {
// Obtenir configuración de la capa
const CapaConfig& capa = capes_[estrella.capa];
// Moure hacia fuera des del centro
float velocity = capa.velocitat_base;
float dx = velocity * std::cos(estrella.angle) * delta_time;
float dy = velocity * std::sin(estrella.angle) * delta_time;
estrella.position.x += dx;
estrella.position.y += dy;
// Actualitzar distancia del centro
float dx_centre = estrella.position.x - punt_fuga_.x;
float dy_centre = estrella.position.y - punt_fuga_.y;
float dist_px = std::sqrt((dx_centre * dx_centre) + (dy_centre * dy_centre));
estrella.distancia_centre = dist_px / radi_max_;
// Si ha sortit de l'àrea, regenerar-la
if (isOutsideArea(estrella)) {
initStar(estrella);
}
}
}
// Establir multiplicador de brightness
void Starfield::set_brightness(float multiplier) {
multiplicador_brightness_ = std::max(0.0F, multiplier); // Evitar valors negatius
}
// Dibuixar todas las estrelles
void Starfield::draw() {
if (!shape_estrella_->isValid()) {
return;
}
for (const auto& estrella : estrelles_) {
// Calcular scale i brightness dinàmicament
float scale = computeScale(estrella);
float brightness = computeBrightness(estrella);
// Renderizar estrella sin rotación
Rendering::render_shape(
renderer_,
shape_estrella_,
estrella.position,
0.0F, // angle (las estrelles no giren)
scale, // scale dinàmica
1.0F, // progress (siempre visible)
brightness // brightness dinàmica
);
}
}
} // namespace Graphics