diff --git a/source/core/defaults.hpp b/source/core/defaults.hpp index 9678341..528a61b 100644 --- a/source/core/defaults.hpp +++ b/source/core/defaults.hpp @@ -1,527 +1,25 @@ +// defaults.hpp - Umbrella header que reuneix totes les constants del joc. +// © 2026 JailDesigner +// +// El contingut viu ara a source/core/defaults/*.hpp (un fitxer per +// namespace). Es manté aquest umbrella per no haver de tocar els 22 +// includers existents. Codi nou pot incloure directament el subfitxer +// concret per millorar el temps de compilació incremental. + #pragma once -#include -#include -#include - -namespace Defaults { - // Configuración de ventana - namespace Window { - constexpr int WIDTH = 1280; - constexpr int HEIGHT = 720; - constexpr int MIN_WIDTH = 640; // Mínimo: mitad del baseline (16:9) - constexpr int MIN_HEIGHT = 360; - // Zoom system - constexpr float BASE_ZOOM = 1.0F; // 1280x720 baseline (16:9) - constexpr float MIN_ZOOM = 0.5F; // 640x360 minimum - constexpr float ZOOM_INCREMENT = 0.1F; // 10% steps (F1/F2) - constexpr bool FULLSCREEN = true; // Pantalla completa activada por defecto - } // namespace Window - - // Dimensiones base del juego (coordenadas lógicas, 16:9) - namespace Game { - constexpr int WIDTH = 1280; - constexpr int HEIGHT = 720; - } // namespace Game - - // Zones del juego (SDL_FRect con cálculos automáticos basat en porcentajes) - namespace Zones { - // --- CONFIGURACIÓ DE PORCENTATGES --- - // Todas las zones definides como a porcentajes de Game::WIDTH (640) i Game::HEIGHT (480) - - // Percentatges de height (divisió vertical) - constexpr float SCOREBOARD_TOP_HEIGHT_PERCENT = 0.02F; // 10% superior - constexpr float MAIN_PLAYAREA_HEIGHT_PERCENT = 0.88F; // 80% central - constexpr float SCOREBOARD_BOTTOM_HEIGHT_PERCENT = 0.10F; // 10% inferior - - // Padding horizontal para PLAYAREA (dentro de MAIN_PLAYAREA) - constexpr float PLAYAREA_PADDING_HORIZONTAL_PERCENT = 0.015F; // 5% a cada costat - - // --- CÀLCULS AUTOMÀTICS DE PÍXELS --- - // Cálculos automáticos a partir dels porcentajes - - // Alçades - constexpr float SCOREBOARD_TOP_H = Game::HEIGHT * SCOREBOARD_TOP_HEIGHT_PERCENT; - constexpr float MAIN_PLAYAREA_H = Game::HEIGHT * MAIN_PLAYAREA_HEIGHT_PERCENT; - constexpr float SCOREBOARD_BOTTOM_H = Game::HEIGHT * SCOREBOARD_BOTTOM_HEIGHT_PERCENT; - - // Posicions Y - constexpr float SCOREBOARD_TOP_Y = 0.0F; - constexpr float MAIN_PLAYAREA_Y = SCOREBOARD_TOP_H; - constexpr float SCOREBOARD_BOTTOM_Y = MAIN_PLAYAREA_Y + MAIN_PLAYAREA_H; - - // Padding horizontal de PLAYAREA - constexpr float PLAYAREA_PADDING_H = Game::WIDTH * PLAYAREA_PADDING_HORIZONTAL_PERCENT; - - // --- ZONES FINALS (SDL_FRect) --- - - // Marcador superior (reservado para futuro uso) - // Ocupa el 2% superior - constexpr SDL_FRect SCOREBOARD_TOP = { - 0.0F, // x = 0.0 - SCOREBOARD_TOP_Y, // y = 0.0 - static_cast(Game::WIDTH), // ancho completo - SCOREBOARD_TOP_H // alto - }; - - // Área de juego principal (contenedor del 80% central, sin padding) - // Ocupa el 88% central, ancho completo - constexpr SDL_FRect MAIN_PLAYAREA = { - 0.0F, // x = 0.0 - MAIN_PLAYAREA_Y, // debajo del scoreboard superior - static_cast(Game::WIDTH), // ancho completo - MAIN_PLAYAREA_H // alto - }; - - // Zona de juego real (con padding horizontal del 5%) - // Ocupa: dentro de MAIN_PLAYAREA, con márgenes laterales - // Se utiliza para límites del juego, colisiones, spawn - constexpr SDL_FRect PLAYAREA = { - PLAYAREA_PADDING_H, // padding horizontal - MAIN_PLAYAREA_Y, // debajo del scoreboard superior (igual que MAIN_PLAYAREA) - Game::WIDTH - (2.0F * PLAYAREA_PADDING_H), // ancho con padding - MAIN_PLAYAREA_H // alto (igual que MAIN_PLAYAREA) - }; - - // Marcador inferior (marcador actual) - // Ocupa el 10% inferior - constexpr SDL_FRect SCOREBOARD = { - 0.0F, // x = 0.0 - SCOREBOARD_BOTTOM_Y, // fondo - static_cast(Game::WIDTH), // ancho completo - SCOREBOARD_BOTTOM_H // alto - }; - - // Padding horizontal del marcador (para alinear zonas izquierda/derecha con PLAYAREA) - constexpr float SCOREBOARD_PADDING_H = 0.0F; // Game::WIDTH * 0.015f; - } // namespace Zones - - // Objetos del juego - namespace Entities { - constexpr int MAX_ORNIS = 15; - constexpr int MAX_BALES = 3; - - constexpr float SHIP_RADIUS = 12.0F; - constexpr float ENEMY_RADIUS = 20.0F; - constexpr float BULLET_RADIUS = 3.0F; - } // namespace Entities - - // Paleta semántica por tipo de entidad. Si una entity declara color, lo - // pasa al pipeline con alpha=255 (sentinela "color válido"); si no, se - // usa el color global del oscilador (g_current_line_color). - namespace Palette { - constexpr SDL_Color SHIP = {.r = 255, .g = 255, .b = 255, .a = 255}; // Blanco neutro - constexpr SDL_Color BULLET = {.r = 120, .g = 255, .b = 140, .a = 255}; // Verde laser - constexpr SDL_Color PENTAGON = {.r = 120, .g = 170, .b = 255, .a = 255}; // Azul "esquivador" - constexpr SDL_Color QUADRAT = {.r = 255, .g = 110, .b = 110, .a = 255}; // Rojo "tank" - constexpr SDL_Color MOLINILLO = {.r = 255, .g = 130, .b = 255, .a = 255}; // Magenta agresivo - } // namespace Palette - - // Ship (nave del player) - namespace Ship { - // Invulnerabilidad post-respawn - constexpr float INVULNERABILITY_DURATION = 3.0F; // Segundos de invulnerabilidad - - // Parpadeo visual durante invulnerabilidad - constexpr float BLINK_VISIBLE_TIME = 0.1F; // Tiempo visible (segundos) - constexpr float BLINK_INVISIBLE_TIME = 0.1F; // Tiempo invisible (segundos) - // Frecuencia total: 0.2s/ciclo = 5 Hz (~15 parpadeos en 3s) - } // namespace Ship - - // Game rules (lives, respawn, game over) - namespace Game { - constexpr int STARTING_LIVES = 3; // Initial lives - constexpr float DEATH_DURATION = 3.0F; // Seconds of death animation - constexpr float GAME_OVER_DURATION = 5.0F; // Seconds to display game over - constexpr float COLLISION_SHIP_ENEMY_AMPLIFIER = 0.80F; // 80% hitbox (generous) - constexpr float COLLISION_BULLET_ENEMY_AMPLIFIER = 1.15F; // 115% hitbox (generous) - - // Friendly fire system - constexpr bool FRIENDLY_FIRE_ENABLED = true; // Activar friendly fire - constexpr float COLLISION_BULLET_PLAYER_AMPLIFIER = 1.0F; // Hitbox exacto (100%) - constexpr float BULLET_GRACE_PERIOD = 0.2F; // Inmunidad post-disparo (s) - - // Transición LEVEL_START (mensajes aleatorios PRE-level) - constexpr float LEVEL_START_DURATION = 3.0F; // Duración total - constexpr float LEVEL_START_TYPING_RATIO = 0.3F; // 30% escribiendo, 70% mostrando - - // Transición LEVEL_COMPLETED (mensaje "GOOD JOB COMMANDER!") - constexpr float LEVEL_COMPLETED_DURATION = 3.0F; // Duración total - constexpr float LEVEL_COMPLETED_TYPING_RATIO = 0.0F; // 0.0 = sin typewriter (directo) - - // Transición INIT_HUD (animación inicial del HUD) - constexpr float INIT_HUD_DURATION = 3.0F; // Duración total del estado - - // Ratios de animación (inicio y fin como porcentajes del tiempo total) - // RECT (rectángulo de márgenes) - constexpr float INIT_HUD_RECT_RATIO_INIT = 0.30F; - constexpr float INIT_HUD_RECT_RATIO_END = 0.85F; - - // SCORE (marcador de puntuación) - constexpr float INIT_HUD_SCORE_RATIO_INIT = 0.60F; - constexpr float INIT_HUD_SCORE_RATIO_END = 0.90F; - - // SHIP1 (nave player 1) - constexpr float INIT_HUD_SHIP1_RATIO_INIT = 0.0F; - constexpr float INIT_HUD_SHIP1_RATIO_END = 1.0F; - - // SHIP2 (nave player 2) - constexpr float INIT_HUD_SHIP2_RATIO_INIT = 0.20F; - constexpr float INIT_HUD_SHIP2_RATIO_END = 1.0F; - - // Posición inicial de la nave en INIT_HUD (75% de altura de zona de juego) - constexpr float INIT_HUD_SHIP_START_Y_RATIO = 0.75F; // 75% desde el top de PLAYAREA - - // Spawn positions (distribución horizontal para 2 jugadores) - constexpr float P1_SPAWN_X_RATIO = 0.33F; // 33% desde izquierda - constexpr float P2_SPAWN_X_RATIO = 0.67F; // 67% desde izquierda - constexpr float SPAWN_Y_RATIO = 0.75F; // 75% desde arriba - - // Continue system behavior - constexpr int CONTINUE_COUNT_START = 9; // Countdown starts at 9 - constexpr float CONTINUE_TICK_DURATION = 1.0F; // Seconds per countdown tick - constexpr int MAX_CONTINUES = 3; // Maximum continues per game - constexpr bool INFINITE_CONTINUES = false; // If true, unlimited continues - - // Continue screen visual configuration - namespace ContinueScreen { - // "CONTINUE" text - constexpr float CONTINUE_TEXT_SCALE = 2.0F; // Text size - constexpr float CONTINUE_TEXT_Y_RATIO = 0.30F; // 35% from top of PLAYAREA - - // Countdown number (9, 8, 7...) - constexpr float COUNTER_TEXT_SCALE = 4.0F; // Text size (large) - constexpr float COUNTER_TEXT_Y_RATIO = 0.50F; // 50% from top of PLAYAREA - - // "CONTINUES LEFT: X" text - constexpr float INFO_TEXT_SCALE = 0.7F; // Text size (small) - constexpr float INFO_TEXT_Y_RATIO = 0.75F; // 65% from top of PLAYAREA - } // namespace ContinueScreen - - // Game Over screen visual configuration - namespace GameOverScreen { - constexpr float TEXT_SCALE = 2.0F; // "GAME OVER" text size - constexpr float TEXT_SPACING = 4.0F; // Character spacing - } // namespace GameOverScreen - - // Stage message configuration (LEVEL_START, LEVEL_COMPLETED) - constexpr float STAGE_MESSAGE_Y_RATIO = 0.25F; // 25% from top of PLAYAREA - constexpr float STAGE_MESSAGE_MAX_WIDTH_RATIO = 0.9F; // 90% of PLAYAREA width - } // namespace Game - - // Física del control de la nau (px/s, rad/s) - namespace Physics { - constexpr float ROTATION_SPEED = 3.14F; // rad/s (~180°/s) - constexpr float ACCELERATION = 400.0F; // px/s² - constexpr float MAX_VELOCITY = 120.0F; // px/s - constexpr float FRICTION = 20.0F; // px/s² - - // Explosions (debris physics) - namespace Debris { - constexpr float VELOCITAT_BASE = 80.0F; // Velocidad inicial (px/s) - constexpr float VARIACIO_VELOCITAT = 40.0F; // ±variació aleatòria (px/s) - constexpr float ACCELERACIO = -60.0F; // Fricció/desacceleració (px/s²) - constexpr float ROTACIO_MIN = 0.1F; // Rotación mínima (rad/s ~5.7°/s) - constexpr float ROTACIO_MAX = 0.3F; // Rotación màxima (rad/s ~17.2°/s) - constexpr float TEMPS_VIDA = 2.0F; // Duració màxima (segons) - enemy/bullet debris - constexpr float TEMPS_VIDA_NAU = 3.0F; // Ship debris lifetime (matches DEATH_DURATION) - constexpr float SHRINK_RATE = 0.5F; // Reducció de mida (factor/s) - - // Herència de velocity angular (trayectorias curvas) - constexpr float FACTOR_HERENCIA_MIN = 0.7F; // Mínimo 70% del drotacio heredat - constexpr float FACTOR_HERENCIA_MAX = 1.0F; // Màxim 100% del drotacio heredat - constexpr float FRICCIO_ANGULAR = 0.5F; // Desacceleració angular (rad/s²) - - // Angular velocity sin for trajectory inheritance - // Excess above this threshold is converted to tangential linear velocity - // Prevents "vortex trap" problem with high-rotation enemies - constexpr float VELOCITAT_ROT_MAX = 1.5F; // rad/s (~86°/s) - } // namespace Debris - } // namespace Physics - - // Matemáticas - namespace Math { - constexpr float PI = std::numbers::pi_v; - } // namespace Math - - // La antigua oscilación CPU (namespace Color) se ha migrado al shader de - // postpro. Los parámetros de flicker / background pulse viven ahora en - // data/config/postfx.yaml y se aplican en shaders/postfx.frag.glsl. - - // Brillantor (control de intensitat per cada type de entidad) - namespace Brightness { - // Brillantor estàtica per entidades de juego (0.0-1.0) - constexpr float NAU = 1.0F; // Màxima visibilitat (player) - constexpr float ENEMIC = 0.7F; // 30% més tènue (destaca menys) - constexpr float BALA = 1.0F; // Brillo a tope (màxima visibilitat) - - // Starfield: gradient segons distancia al centro - // distancia_centre: 0.0 (centro) → 1.0 (vora pantalla) - // brightness = MIN + (MAX - MIN) * distancia_centre - constexpr float STARFIELD_MIN = 0.3F; // Estrelles llunyanes (prop del centro) - constexpr float STARFIELD_MAX = 0.8F; // Estrelles properes (vora pantalla) - } // namespace Brightness - - // Renderització (V-Sync i altres opciones de render) - namespace Rendering { - constexpr int VSYNC_DEFAULT = 1; // 0=disabled, 1=enabled - } // namespace Rendering - - // Audio (sistema de sonido y música) — usado por Audio::Config en init() - namespace Audio { - constexpr bool ENABLED = true; // Audio habilitado por defecto - constexpr float VOLUME = 1.0F; // Volumen maestro (0..1) - constexpr bool MUSIC_ENABLED = true; // Música habilitada - constexpr float MUSIC_VOLUME = 0.8F; // Volumen música (0..1) - constexpr bool SOUND_ENABLED = true; // Efectos habilitados - constexpr float SOUND_VOLUME = 1.0F; // Volumen efectos (0..1) - constexpr float VOLUME_STEP = 0.05F; // Paso UI (5%) - constexpr int FREQUENCY = 48000; // Frecuencia de muestreo (Hz) - constexpr int CROSSFADE_MS = 1500; // Crossfade por defecto entre pistas (ms) - constexpr SDL_AudioFormat FORMAT = SDL_AUDIO_S16; // PCM 16-bit signed nativo - constexpr int CHANNELS = 2; // Estéreo - } // namespace Audio - - // Música (pistas de fondo) - namespace Music { - constexpr const char* GAME_TRACK = "game.ogg"; // Pista de juego - constexpr const char* TITLE_TRACK = "title.ogg"; // Pista de titulo - constexpr int FADE_DURATION_MS = 1000; // Fade out duration - } // namespace Music - - // Efectes de so (sons puntuals) - namespace Sound { - constexpr const char* CONTINUE = "effects/continue.wav"; // Cuenta atras - constexpr const char* EXPLOSION = "effects/explosion.wav"; // Explosión - constexpr const char* EXPLOSION2 = "effects/explosion2.wav"; // Explosión alternativa - constexpr const char* FRIENDLY_FIRE_HIT = "effects/friendly_fire.wav"; // Friendly fire hit - constexpr const char* INIT_HUD = "effects/init_hud.wav"; // Para la animación del HUD - constexpr const char* LASER = "effects/laser_shoot.wav"; // Disparo - constexpr const char* LOGO = "effects/logo.wav"; // Logo - constexpr const char* START = "effects/start.wav"; // El player pulsa START - constexpr const char* GOOD_JOB_COMMANDER = "voices/good_job_commander.wav"; // Voz: "Good job, commander" - } // namespace Sound - - // Controls (mapeo de teclas para los jugadores) - namespace Controls { - namespace P1 { - constexpr SDL_Scancode ROTATE_RIGHT = SDL_SCANCODE_RIGHT; - constexpr SDL_Scancode ROTATE_LEFT = SDL_SCANCODE_LEFT; - constexpr SDL_Scancode THRUST = SDL_SCANCODE_UP; - constexpr SDL_Keycode SHOOT = SDLK_SPACE; - } // namespace P1 - - namespace P2 { - constexpr SDL_Scancode ROTATE_RIGHT = SDL_SCANCODE_D; - constexpr SDL_Scancode ROTATE_LEFT = SDL_SCANCODE_A; - constexpr SDL_Scancode THRUST = SDL_SCANCODE_W; - constexpr SDL_Keycode SHOOT = SDLK_LSHIFT; - } // namespace P2 - } // namespace Controls - - // Enemy type configuration (type de enemigos) - namespace Enemies { - // Pentagon (esquivador - zigzag evasion) - namespace Pentagon { - constexpr float VELOCITAT = 35.0F; // px/s (slightly slower) - constexpr float CANVI_ANGLE_PROB = 0.20F; // 20% per wall hit (frequent zigzag) - constexpr float CANVI_ANGLE_MAX = 1.0F; // Max random angle change (rad) - constexpr float DROTACIO_MIN = 0.75F; // Min visual rotation (rad/s) [+50%] - constexpr float DROTACIO_MAX = 3.75F; // Max visual rotation (rad/s) [+50%] - constexpr const char* SHAPE_FILE = "enemy_pentagon.shp"; - } // namespace Pentagon - - // Cuadrado (perseguidor - tracks player) - namespace Cuadrado { - constexpr float VELOCITAT = 40.0F; // px/s (medium speed) - constexpr float TRACKING_STRENGTH = 0.5F; // Interpolation toward player (0.0-1.0) - constexpr float TRACKING_INTERVAL = 1.0F; // Seconds between angle updates - constexpr float DROTACIO_MIN = 0.3F; // Slow rotation [+50%] - constexpr float DROTACIO_MAX = 1.5F; // [+50%] - constexpr const char* SHAPE_FILE = "enemy_square.shp"; - } // namespace Cuadrado - - // Molinillo (agressiu - fast straight lines, proximity spin-up) - namespace Molinillo { - constexpr float VELOCITAT = 50.0F; // px/s (fastest) - constexpr float CANVI_ANGLE_PROB = 0.05F; // 5% per wall hit (rare direction change) - constexpr float CANVI_ANGLE_MAX = 0.3F; // Small angle adjustments - constexpr float DROTACIO_MIN = 3.0F; // Base rotation (rad/s) [+50%] - constexpr float DROTACIO_MAX = 6.0F; // [+50%] - constexpr float DROTACIO_PROXIMITY_MULTIPLIER = 3.0F; // Spin-up multiplier when near ship - constexpr float PROXIMITY_DISTANCE = 100.0F; // Distance threshold (px) - constexpr const char* SHAPE_FILE = "enemy_pinwheel.shp"; - } // namespace Molinillo - - // Animation parameters (shared) - namespace Animation { - // Palpitation - constexpr float PALPITACIO_TRIGGER_PROB = 0.01F; // 1% chance per second - constexpr float PALPITACIO_DURACIO_MIN = 1.0F; // Min duration (seconds) - constexpr float PALPITACIO_DURACIO_MAX = 3.0F; // Max duration (seconds) - constexpr float PALPITACIO_AMPLITUD_MIN = 0.08F; // Min scale variation - constexpr float PALPITACIO_AMPLITUD_MAX = 0.20F; // Max scale variation - constexpr float PALPITACIO_FREQ_MIN = 1.5F; // Min frequency (Hz) - constexpr float PALPITACIO_FREQ_MAX = 3.0F; // Max frequency (Hz) - - // Rotation acceleration - constexpr float ROTACIO_ACCEL_TRIGGER_PROB = 0.02F; // 2% chance per second [4x more frequent] - constexpr float ROTACIO_ACCEL_DURACIO_MIN = 3.0F; // Min transition time - constexpr float ROTACIO_ACCEL_DURACIO_MAX = 8.0F; // Max transition time - constexpr float ROTACIO_ACCEL_MULTIPLIER_MIN = 0.3F; // Min speed multiplier [more dramatic] - constexpr float ROTACIO_ACCEL_MULTIPLIER_MAX = 4.0F; // Max speed multiplier [more dramatic] - } // namespace Animation - - // Spawn safety and invulnerability system - namespace Spawn { - // Safe spawn distance from player - constexpr float SAFETY_DISTANCE_MULTIPLIER = 3.0F; // 3x ship radius - constexpr float SAFETY_DISTANCE = Defaults::Entities::SHIP_RADIUS * SAFETY_DISTANCE_MULTIPLIER; // 36.0f px - constexpr int MAX_SPAWN_ATTEMPTS = 50; // Max attempts to find safe position - - // Invulnerability system - constexpr float INVULNERABILITY_DURATION = 3.0F; // Seconds - constexpr float INVULNERABILITY_BRIGHTNESS_START = 0.3F; // Dim - constexpr float INVULNERABILITY_BRIGHTNESS_END = 0.7F; // Normal (same as Defaults::Brightness::ENEMIC) - constexpr float INVULNERABILITY_SCALE_START = 0.0F; // Invisible - constexpr float INVULNERABILITY_SCALE_END = 1.0F; // Full size - } // namespace Spawn - - // Scoring system (puntuación per type de enemy) - namespace Scoring { - constexpr int PENTAGON_SCORE = 100; // Pentágono (esquivador, 35 px/s) - constexpr int QUADRAT_SCORE = 150; // Cuadrado (perseguidor, 40 px/s) - constexpr int MOLINILLO_SCORE = 200; // Molinillo (agressiu, 50 px/s) - } // namespace Scoring - - } // namespace Enemies - - // Title scene ship animations (naves 3D flotantes a l'escena de título) - namespace Title { - namespace Ships { - // ============================================================ - // PARÀMETRES BASE (ajustar aquí per experimentar) - // ============================================================ - - // 1. Escala global de las naves - constexpr float SHIP_BASE_SCALE = 2.5F; // Multiplicador (1.0 = mida original del .shp) - - // 2. Altura vertical (cercanía al centro) - // Ratio Y desde el centro de la pantalla (0.0 = centro, 1.0 = bottom de pantalla) - constexpr float TARGET_Y_RATIO = 0.15625F; - - // 3. Radio orbital (distance radial desde centro en coordenadas polares) - constexpr float CLOCK_RADIUS = 150.0F; // Distancia des del centro - - // 4. Ángulos de posición (clock positions en coordenadas polares) - // En coordenadas de pantalla: 0° = derecha, 90° = baix, 180° = izquierda, 270° = dalt - constexpr float CLOCK_8_ANGLE = 150.0F * Math::PI / 180.0F; // 8 o'clock (bottom-left) - constexpr float CLOCK_4_ANGLE = 30.0F * Math::PI / 180.0F; // 4 o'clock (bottom-right) - - // 5. Radio máximo de la shape de la nave (para calcular offset automáticamente) - constexpr float SHIP_MAX_RADIUS = 30.0F; // Radi del cercle circumscrit a ship_starfield.shp - - // 6. Margen de seguridad para offset de entrada - constexpr float ENTRY_OFFSET_MARGIN = 227.5F; // Para offset total de ~340px (ajustado) - - // ============================================================ - // VALORS DERIVATS (calculats automáticoament - NO modificar) - // ============================================================ - - // Centro de la pantalla (point de referència) - constexpr float CENTER_X = Game::WIDTH / 2.0F; // auto-derivado de Game::WIDTH - constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // auto-derivado de Game::HEIGHT - - // Posicions target (calculades dinàmicament des dels parámetros base) - // Nota: std::cos/sin no són constexpr en C++20, pero funcionen en runtime - // Les funciones inline són optimitzades por el compilador (zero overhead) - inline auto p1TargetX() -> float { - return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE)); - } - inline auto p1TargetY() -> float { - return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO); - } - inline auto p2TargetX() -> float { - return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_4_ANGLE)); - } - inline auto p2TargetY() -> float { - return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO); - } - - // Escales de animación (relatives a SHIP_BASE_SCALE) - constexpr float ENTRY_SCALE_START = 1.5F * SHIP_BASE_SCALE; // Entrada: 50% més grande - constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotante: scale base - - // Offset de entrada (ajustat automáticoament a l'scale) - // Fórmula: (radi màxim de la ship * scale de entrada) + margen - constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN; - - // Vec2 de fuga (centro para l'animación de salida) - constexpr float VANISHING_POINT_X = CENTER_X; // auto-derivado de Game::WIDTH - constexpr float VANISHING_POINT_Y = CENTER_Y; // auto-derivado de Game::HEIGHT - - // ============================================================ - // ANIMACIONS (durades, oscil·lacions, delays) - // ============================================================ - - // Durades de animación - constexpr float ENTRY_DURATION = 2.0F; // Entrada (segons) - constexpr float EXIT_DURATION = 1.0F; // Salida (segons) - - // Flotació (oscil·lació reduïda y diferenciada per ship) - constexpr float FLOAT_AMPLITUDE_X = 4.0F; // Amplitud X (píxels) - constexpr float FLOAT_AMPLITUDE_Y = 2.5F; // Amplitud Y (píxels) - - // Freqüències base - constexpr float FLOAT_FREQUENCY_X_BASE = 0.5F; // Hz - constexpr float FLOAT_FREQUENCY_Y_BASE = 0.7F; // Hz - constexpr float FLOAT_PHASE_OFFSET = 1.57F; // π/2 (90°) - - // Delays de entrada (per a entrada escalonada) - constexpr float P1_ENTRY_DELAY = 0.0F; // P1 entra immediatament - constexpr float P2_ENTRY_DELAY = 0.5F; // P2 entra 0.5s después - - // Delay global antes de start l'animación de entrada al state MAIN - constexpr float ENTRANCE_DELAY = 5.0F; // Temps de espera antes que las naves entrin - - // Multiplicadors de freqüència para cada ship (variació sutil ±12%) - constexpr float P1_FREQUENCY_MULTIPLIER = 0.88F; // 12% més lenta - constexpr float P2_FREQUENCY_MULTIPLIER = 1.12F; // 12% més ràpida - - } // namespace Ships - - namespace Layout { - // Posicions verticals (anclatges des del TOP de pantalla lógica, 0.0-1.0) - constexpr float LOGO_POS = 0.20F; // Logo "ORNI" - constexpr float PRESS_START_POS = 0.75F; // "PRESS START TO PLAY" - constexpr float COPYRIGHT1_POS = 0.90F; // Primera línia copyright - - // Separacions relatives (proporció respecte Game::HEIGHT = 480px) - constexpr float LOGO_LINE_SPACING = 0.02F; // Entre "ORNI" i "ATTACK!" (10px) - constexpr float COPYRIGHT_LINE_SPACING = 0.0F; // Entre línies copyright (5px) - - // Factors de scale - constexpr float LOGO_SCALE = 0.6F; // Escala "ORNI ATTACK!" - constexpr float PRESS_START_SCALE = 1.0F; // Escala "PRESS START TO PLAY" - constexpr float COPYRIGHT_SCALE = 0.5F; // Escala copyright - constexpr float JAILGAMES_SCALE = 0.25F; // Escala del logo JAILGAMES pequeño sobre el copyright - - // Separación entre el logo JAILGAMES y la línea de copyright (proporción de Game::HEIGHT). - constexpr float JAILGAMES_COPYRIGHT_GAP = 0.015F; - - // Espaiat entre caràcters (usado per VectorText) - constexpr float TEXT_SPACING = 2.0F; - } // namespace Layout - } // namespace Title - - // Floating score numbers (números flotantes de puntuación) - namespace FloatingScore { - constexpr float LIFETIME = 2.0F; // Duració màxima (segons) - constexpr float VELOCITY_Y = -30.0F; // Velocidad vertical (px/s, negatiu = amunt) - constexpr float VELOCITY_X = 0.0F; // Velocidad horizontal (px/s) - constexpr float SCALE = 0.45F; // Escala del text (0.6 = 60% del marcador) - constexpr float SPACING = 0.0F; // Espaiat entre caràcters - constexpr int MAX_CONCURRENT = 15; // Pool size (= MAX_ORNIS) - } // namespace FloatingScore - -} // namespace Defaults +#include "core/defaults/audio.hpp" +#include "core/defaults/brightness.hpp" +#include "core/defaults/controls.hpp" +#include "core/defaults/enemies.hpp" +#include "core/defaults/entities.hpp" +#include "core/defaults/floating_score.hpp" +#include "core/defaults/game.hpp" +#include "core/defaults/math.hpp" +#include "core/defaults/palette.hpp" +#include "core/defaults/physics.hpp" +#include "core/defaults/rendering.hpp" +#include "core/defaults/ship.hpp" +#include "core/defaults/title.hpp" +#include "core/defaults/window.hpp" +#include "core/defaults/zones.hpp" diff --git a/source/core/defaults/audio.hpp b/source/core/defaults/audio.hpp new file mode 100644 index 0000000..6000c0f --- /dev/null +++ b/source/core/defaults/audio.hpp @@ -0,0 +1,47 @@ +// audio.hpp - Configuració d'audio (sistema), pistes de música i efectes +// © 2026 JailDesigner + +#pragma once + +#include + +// Audio (sistema de sonido y música) — usado por Audio::Config en init() +namespace Defaults::Audio { + + constexpr bool ENABLED = true; // Audio habilitado por defecto + constexpr float VOLUME = 1.0F; // Volumen maestro (0..1) + constexpr bool MUSIC_ENABLED = true; // Música habilitada + constexpr float MUSIC_VOLUME = 0.8F; // Volumen música (0..1) + constexpr bool SOUND_ENABLED = true; // Efectos habilitados + constexpr float SOUND_VOLUME = 1.0F; // Volumen efectos (0..1) + constexpr float VOLUME_STEP = 0.05F; // Paso UI (5%) + constexpr int FREQUENCY = 48000; // Frecuencia de muestreo (Hz) + constexpr int CROSSFADE_MS = 1500; // Crossfade por defecto entre pistas (ms) + constexpr SDL_AudioFormat FORMAT = SDL_AUDIO_S16; // PCM 16-bit signed nativo + constexpr int CHANNELS = 2; // Estéreo + +} // namespace Defaults::Audio + +// Música (pistas de fondo) +namespace Defaults::Music { + + constexpr const char* GAME_TRACK = "game.ogg"; // Pista de juego + constexpr const char* TITLE_TRACK = "title.ogg"; // Pista de titulo + constexpr int FADE_DURATION_MS = 1000; // Fade out duration + +} // namespace Defaults::Music + +// Efectes de so (sons puntuals) +namespace Defaults::Sound { + + constexpr const char* CONTINUE = "effects/continue.wav"; // Cuenta atras + constexpr const char* EXPLOSION = "effects/explosion.wav"; // Explosión + constexpr const char* EXPLOSION2 = "effects/explosion2.wav"; // Explosión alternativa + constexpr const char* FRIENDLY_FIRE_HIT = "effects/friendly_fire.wav"; // Friendly fire hit + constexpr const char* INIT_HUD = "effects/init_hud.wav"; // Para la animación del HUD + constexpr const char* LASER = "effects/laser_shoot.wav"; // Disparo + constexpr const char* LOGO = "effects/logo.wav"; // Logo + constexpr const char* START = "effects/start.wav"; // El player pulsa START + constexpr const char* GOOD_JOB_COMMANDER = "voices/good_job_commander.wav"; // Voz: "Good job, commander" + +} // namespace Defaults::Sound diff --git a/source/core/defaults/brightness.hpp b/source/core/defaults/brightness.hpp new file mode 100644 index 0000000..446e311 --- /dev/null +++ b/source/core/defaults/brightness.hpp @@ -0,0 +1,23 @@ +// brightness.hpp - Control d'intensitat per tipus d'entitat i starfield +// © 2026 JailDesigner + +#pragma once + +// La antigua oscilación CPU (namespace Color) se ha migrado al shader de +// postpro. Los parámetros de flicker / background pulse viven ahora en +// data/config/postfx.yaml y se aplican en shaders/postfx.frag.glsl. + +namespace Defaults::Brightness { + + // Brillantor estàtica per entidades de juego (0.0-1.0) + constexpr float NAU = 1.0F; // Màxima visibilitat (player) + constexpr float ENEMIC = 0.7F; // 30% més tènue (destaca menys) + constexpr float BALA = 1.0F; // Brillo a tope (màxima visibilitat) + + // Starfield: gradient segons distancia al centro + // distancia_centre: 0.0 (centro) → 1.0 (vora pantalla) + // brightness = MIN + (MAX - MIN) * distancia_centre + constexpr float STARFIELD_MIN = 0.3F; // Estrelles llunyanes (prop del centro) + constexpr float STARFIELD_MAX = 0.8F; // Estrelles properes (vora pantalla) + +} // namespace Defaults::Brightness diff --git a/source/core/defaults/controls.hpp b/source/core/defaults/controls.hpp new file mode 100644 index 0000000..e512fbf --- /dev/null +++ b/source/core/defaults/controls.hpp @@ -0,0 +1,24 @@ +// controls.hpp - Mapeig de tecles per defecte dels jugadors +// © 2026 JailDesigner + +#pragma once + +#include + +namespace Defaults::Controls { + + namespace P1 { + constexpr SDL_Scancode ROTATE_RIGHT = SDL_SCANCODE_RIGHT; + constexpr SDL_Scancode ROTATE_LEFT = SDL_SCANCODE_LEFT; + constexpr SDL_Scancode THRUST = SDL_SCANCODE_UP; + constexpr SDL_Keycode SHOOT = SDLK_SPACE; + } // namespace P1 + + namespace P2 { + constexpr SDL_Scancode ROTATE_RIGHT = SDL_SCANCODE_D; + constexpr SDL_Scancode ROTATE_LEFT = SDL_SCANCODE_A; + constexpr SDL_Scancode THRUST = SDL_SCANCODE_W; + constexpr SDL_Keycode SHOOT = SDLK_LSHIFT; + } // namespace P2 + +} // namespace Defaults::Controls diff --git a/source/core/defaults/enemies.hpp b/source/core/defaults/enemies.hpp new file mode 100644 index 0000000..b4c81ee --- /dev/null +++ b/source/core/defaults/enemies.hpp @@ -0,0 +1,83 @@ +// enemies.hpp - Configuració per tipus d'enemic (Pentagon/Cuadrado/Molinillo), spawn i scoring +// © 2026 JailDesigner + +#pragma once + +#include "core/defaults/entities.hpp" + +namespace Defaults::Enemies { + + // Pentagon (esquivador - zigzag evasion) + namespace Pentagon { + constexpr float VELOCITAT = 35.0F; // px/s (slightly slower) + constexpr float CANVI_ANGLE_PROB = 0.20F; // 20% per wall hit (frequent zigzag) + constexpr float CANVI_ANGLE_MAX = 1.0F; // Max random angle change (rad) + constexpr float DROTACIO_MIN = 0.75F; // Min visual rotation (rad/s) [+50%] + constexpr float DROTACIO_MAX = 3.75F; // Max visual rotation (rad/s) [+50%] + constexpr const char* SHAPE_FILE = "enemy_pentagon.shp"; + } // namespace Pentagon + + // Cuadrado (perseguidor - tracks player) + namespace Cuadrado { + constexpr float VELOCITAT = 40.0F; // px/s (medium speed) + constexpr float TRACKING_STRENGTH = 0.5F; // Interpolation toward player (0.0-1.0) + constexpr float TRACKING_INTERVAL = 1.0F; // Seconds between angle updates + constexpr float DROTACIO_MIN = 0.3F; // Slow rotation [+50%] + constexpr float DROTACIO_MAX = 1.5F; // [+50%] + constexpr const char* SHAPE_FILE = "enemy_square.shp"; + } // namespace Cuadrado + + // Molinillo (agressiu - fast straight lines, proximity spin-up) + namespace Molinillo { + constexpr float VELOCITAT = 50.0F; // px/s (fastest) + constexpr float CANVI_ANGLE_PROB = 0.05F; // 5% per wall hit (rare direction change) + constexpr float CANVI_ANGLE_MAX = 0.3F; // Small angle adjustments + constexpr float DROTACIO_MIN = 3.0F; // Base rotation (rad/s) [+50%] + constexpr float DROTACIO_MAX = 6.0F; // [+50%] + constexpr float DROTACIO_PROXIMITY_MULTIPLIER = 3.0F; // Spin-up multiplier when near ship + constexpr float PROXIMITY_DISTANCE = 100.0F; // Distance threshold (px) + constexpr const char* SHAPE_FILE = "enemy_pinwheel.shp"; + } // namespace Molinillo + + // Animation parameters (shared) + namespace Animation { + // Palpitation + constexpr float PALPITACIO_TRIGGER_PROB = 0.01F; // 1% chance per second + constexpr float PALPITACIO_DURACIO_MIN = 1.0F; // Min duration (seconds) + constexpr float PALPITACIO_DURACIO_MAX = 3.0F; // Max duration (seconds) + constexpr float PALPITACIO_AMPLITUD_MIN = 0.08F; // Min scale variation + constexpr float PALPITACIO_AMPLITUD_MAX = 0.20F; // Max scale variation + constexpr float PALPITACIO_FREQ_MIN = 1.5F; // Min frequency (Hz) + constexpr float PALPITACIO_FREQ_MAX = 3.0F; // Max frequency (Hz) + + // Rotation acceleration + constexpr float ROTACIO_ACCEL_TRIGGER_PROB = 0.02F; // 2% chance per second [4x more frequent] + constexpr float ROTACIO_ACCEL_DURACIO_MIN = 3.0F; // Min transition time + constexpr float ROTACIO_ACCEL_DURACIO_MAX = 8.0F; // Max transition time + constexpr float ROTACIO_ACCEL_MULTIPLIER_MIN = 0.3F; // Min speed multiplier [more dramatic] + constexpr float ROTACIO_ACCEL_MULTIPLIER_MAX = 4.0F; // Max speed multiplier [more dramatic] + } // namespace Animation + + // Spawn safety and invulnerability system + namespace Spawn { + // Safe spawn distance from player + constexpr float SAFETY_DISTANCE_MULTIPLIER = 3.0F; // 3x ship radius + constexpr float SAFETY_DISTANCE = Defaults::Entities::SHIP_RADIUS * SAFETY_DISTANCE_MULTIPLIER; // 36.0f px + constexpr int MAX_SPAWN_ATTEMPTS = 50; // Max attempts to find safe position + + // Invulnerability system + constexpr float INVULNERABILITY_DURATION = 3.0F; // Seconds + constexpr float INVULNERABILITY_BRIGHTNESS_START = 0.3F; // Dim + constexpr float INVULNERABILITY_BRIGHTNESS_END = 0.7F; // Normal (same as Defaults::Brightness::ENEMIC) + constexpr float INVULNERABILITY_SCALE_START = 0.0F; // Invisible + constexpr float INVULNERABILITY_SCALE_END = 1.0F; // Full size + } // namespace Spawn + + // Scoring system (puntuación per type de enemy) + namespace Scoring { + constexpr int PENTAGON_SCORE = 100; // Pentágono (esquivador, 35 px/s) + constexpr int QUADRAT_SCORE = 150; // Cuadrado (perseguidor, 40 px/s) + constexpr int MOLINILLO_SCORE = 200; // Molinillo (agressiu, 50 px/s) + } // namespace Scoring + +} // namespace Defaults::Enemies diff --git a/source/core/defaults/entities.hpp b/source/core/defaults/entities.hpp new file mode 100644 index 0000000..4bd5de4 --- /dev/null +++ b/source/core/defaults/entities.hpp @@ -0,0 +1,15 @@ +// entities.hpp - Configuració d'objectes del joc (límits i radis de col·lisió) +// © 2026 JailDesigner + +#pragma once + +namespace Defaults::Entities { + + constexpr int MAX_ORNIS = 15; + constexpr int MAX_BALES = 3; + + constexpr float SHIP_RADIUS = 12.0F; + constexpr float ENEMY_RADIUS = 20.0F; + constexpr float BULLET_RADIUS = 3.0F; + +} // namespace Defaults::Entities diff --git a/source/core/defaults/floating_score.hpp b/source/core/defaults/floating_score.hpp new file mode 100644 index 0000000..e69c1dd --- /dev/null +++ b/source/core/defaults/floating_score.hpp @@ -0,0 +1,15 @@ +// floating_score.hpp - Números flotants de puntuació +// © 2026 JailDesigner + +#pragma once + +namespace Defaults::FloatingScore { + + constexpr float LIFETIME = 2.0F; // Duració màxima (segons) + constexpr float VELOCITY_Y = -30.0F; // Velocidad vertical (px/s, negatiu = amunt) + constexpr float VELOCITY_X = 0.0F; // Velocidad horizontal (px/s) + constexpr float SCALE = 0.45F; // Escala del text (0.6 = 60% del marcador) + constexpr float SPACING = 0.0F; // Espaiat entre caràcters + constexpr int MAX_CONCURRENT = 15; // Pool size (= MAX_ORNIS) + +} // namespace Defaults::FloatingScore diff --git a/source/core/defaults/game.hpp b/source/core/defaults/game.hpp new file mode 100644 index 0000000..e5f4c9d --- /dev/null +++ b/source/core/defaults/game.hpp @@ -0,0 +1,91 @@ +// game.hpp - Dimensions del joc i regles de partida (vides, durades, colisions) +// © 2026 JailDesigner + +#pragma once + +namespace Defaults::Game { + + // Dimensiones base del juego (coordenadas lógicas, 16:9) + constexpr int WIDTH = 1280; + constexpr int HEIGHT = 720; + + // Regles de partida + constexpr int STARTING_LIVES = 3; // Initial lives + constexpr float DEATH_DURATION = 3.0F; // Seconds of death animation + constexpr float GAME_OVER_DURATION = 5.0F; // Seconds to display game over + constexpr float COLLISION_SHIP_ENEMY_AMPLIFIER = 0.80F; // 80% hitbox (generous) + constexpr float COLLISION_BULLET_ENEMY_AMPLIFIER = 1.15F; // 115% hitbox (generous) + + // Friendly fire system + constexpr bool FRIENDLY_FIRE_ENABLED = true; // Activar friendly fire + constexpr float COLLISION_BULLET_PLAYER_AMPLIFIER = 1.0F; // Hitbox exacto (100%) + constexpr float BULLET_GRACE_PERIOD = 0.2F; // Inmunidad post-disparo (s) + + // Transición LEVEL_START (mensajes aleatorios PRE-level) + constexpr float LEVEL_START_DURATION = 3.0F; // Duración total + constexpr float LEVEL_START_TYPING_RATIO = 0.3F; // 30% escribiendo, 70% mostrando + + // Transición LEVEL_COMPLETED (mensaje "GOOD JOB COMMANDER!") + constexpr float LEVEL_COMPLETED_DURATION = 3.0F; // Duración total + constexpr float LEVEL_COMPLETED_TYPING_RATIO = 0.0F; // 0.0 = sin typewriter (directo) + + // Transición INIT_HUD (animación inicial del HUD) + constexpr float INIT_HUD_DURATION = 3.0F; // Duración total del estado + + // Ratios de animación (inicio y fin como porcentajes del tiempo total) + // RECT (rectángulo de márgenes) + constexpr float INIT_HUD_RECT_RATIO_INIT = 0.30F; + constexpr float INIT_HUD_RECT_RATIO_END = 0.85F; + + // SCORE (marcador de puntuación) + constexpr float INIT_HUD_SCORE_RATIO_INIT = 0.60F; + constexpr float INIT_HUD_SCORE_RATIO_END = 0.90F; + + // SHIP1 (nave player 1) + constexpr float INIT_HUD_SHIP1_RATIO_INIT = 0.0F; + constexpr float INIT_HUD_SHIP1_RATIO_END = 1.0F; + + // SHIP2 (nave player 2) + constexpr float INIT_HUD_SHIP2_RATIO_INIT = 0.20F; + constexpr float INIT_HUD_SHIP2_RATIO_END = 1.0F; + + // Posición inicial de la nave en INIT_HUD (75% de altura de zona de juego) + constexpr float INIT_HUD_SHIP_START_Y_RATIO = 0.75F; // 75% desde el top de PLAYAREA + + // Spawn positions (distribución horizontal para 2 jugadores) + constexpr float P1_SPAWN_X_RATIO = 0.33F; // 33% desde izquierda + constexpr float P2_SPAWN_X_RATIO = 0.67F; // 67% desde izquierda + constexpr float SPAWN_Y_RATIO = 0.75F; // 75% desde arriba + + // Continue system behavior + constexpr int CONTINUE_COUNT_START = 9; // Countdown starts at 9 + constexpr float CONTINUE_TICK_DURATION = 1.0F; // Seconds per countdown tick + constexpr int MAX_CONTINUES = 3; // Maximum continues per game + constexpr bool INFINITE_CONTINUES = false; // If true, unlimited continues + + // Continue screen visual configuration + namespace ContinueScreen { + // "CONTINUE" text + constexpr float CONTINUE_TEXT_SCALE = 2.0F; // Text size + constexpr float CONTINUE_TEXT_Y_RATIO = 0.30F; // 35% from top of PLAYAREA + + // Countdown number (9, 8, 7...) + constexpr float COUNTER_TEXT_SCALE = 4.0F; // Text size (large) + constexpr float COUNTER_TEXT_Y_RATIO = 0.50F; // 50% from top of PLAYAREA + + // "CONTINUES LEFT: X" text + constexpr float INFO_TEXT_SCALE = 0.7F; // Text size (small) + constexpr float INFO_TEXT_Y_RATIO = 0.75F; // 65% from top of PLAYAREA + } // namespace ContinueScreen + + // Game Over screen visual configuration + namespace GameOverScreen { + constexpr float TEXT_SCALE = 2.0F; // "GAME OVER" text size + constexpr float TEXT_SPACING = 4.0F; // Character spacing + } // namespace GameOverScreen + + // Stage message configuration (LEVEL_START, LEVEL_COMPLETED) + constexpr float STAGE_MESSAGE_Y_RATIO = 0.25F; // 25% from top of PLAYAREA + constexpr float STAGE_MESSAGE_MAX_WIDTH_RATIO = 0.9F; // 90% of PLAYAREA width + +} // namespace Defaults::Game diff --git a/source/core/defaults/math.hpp b/source/core/defaults/math.hpp new file mode 100644 index 0000000..7cdf1db --- /dev/null +++ b/source/core/defaults/math.hpp @@ -0,0 +1,12 @@ +// math.hpp - Constants matemàtiques +// © 2026 JailDesigner + +#pragma once + +#include + +namespace Defaults::Math { + + constexpr float PI = std::numbers::pi_v; + +} // namespace Defaults::Math diff --git a/source/core/defaults/palette.hpp b/source/core/defaults/palette.hpp new file mode 100644 index 0000000..2c3eae5 --- /dev/null +++ b/source/core/defaults/palette.hpp @@ -0,0 +1,19 @@ +// palette.hpp - Paleta semàntica per tipus d'entitat +// © 2026 JailDesigner + +#pragma once + +#include + +// Paleta semántica por tipo de entidad. Si una entity declara color, lo +// pasa al pipeline con alpha=255 (sentinela "color válido"); si no, se +// usa el color global del oscilador (g_current_line_color). +namespace Defaults::Palette { + + constexpr SDL_Color SHIP = {.r = 255, .g = 255, .b = 255, .a = 255}; // Blanco neutro + constexpr SDL_Color BULLET = {.r = 120, .g = 255, .b = 140, .a = 255}; // Verde laser + constexpr SDL_Color PENTAGON = {.r = 120, .g = 170, .b = 255, .a = 255}; // Azul "esquivador" + constexpr SDL_Color QUADRAT = {.r = 255, .g = 110, .b = 110, .a = 255}; // Rojo "tank" + constexpr SDL_Color MOLINILLO = {.r = 255, .g = 130, .b = 255, .a = 255}; // Magenta agresivo + +} // namespace Defaults::Palette diff --git a/source/core/defaults/physics.hpp b/source/core/defaults/physics.hpp new file mode 100644 index 0000000..77704f5 --- /dev/null +++ b/source/core/defaults/physics.hpp @@ -0,0 +1,35 @@ +// physics.hpp - Constants de física del control de la nau i debris d'explosió +// © 2026 JailDesigner + +#pragma once + +namespace Defaults::Physics { + + constexpr float ROTATION_SPEED = 3.14F; // rad/s (~180°/s) + constexpr float ACCELERATION = 400.0F; // px/s² + constexpr float MAX_VELOCITY = 120.0F; // px/s + constexpr float FRICTION = 20.0F; // px/s² + + // Explosions (debris physics) + namespace Debris { + constexpr float VELOCITAT_BASE = 80.0F; // Velocidad inicial (px/s) + constexpr float VARIACIO_VELOCITAT = 40.0F; // ±variació aleatòria (px/s) + constexpr float ACCELERACIO = -60.0F; // Fricció/desacceleració (px/s²) + constexpr float ROTACIO_MIN = 0.1F; // Rotación mínima (rad/s ~5.7°/s) + constexpr float ROTACIO_MAX = 0.3F; // Rotación màxima (rad/s ~17.2°/s) + constexpr float TEMPS_VIDA = 2.0F; // Duració màxima (segons) - enemy/bullet debris + constexpr float TEMPS_VIDA_NAU = 3.0F; // Ship debris lifetime (matches DEATH_DURATION) + constexpr float SHRINK_RATE = 0.5F; // Reducció de mida (factor/s) + + // Herència de velocity angular (trayectorias curvas) + constexpr float FACTOR_HERENCIA_MIN = 0.7F; // Mínimo 70% del drotacio heredat + constexpr float FACTOR_HERENCIA_MAX = 1.0F; // Màxim 100% del drotacio heredat + constexpr float FRICCIO_ANGULAR = 0.5F; // Desacceleració angular (rad/s²) + + // Angular velocity sin for trajectory inheritance + // Excess above this threshold is converted to tangential linear velocity + // Prevents "vortex trap" problem with high-rotation enemies + constexpr float VELOCITAT_ROT_MAX = 1.5F; // rad/s (~86°/s) + } // namespace Debris + +} // namespace Defaults::Physics diff --git a/source/core/defaults/rendering.hpp b/source/core/defaults/rendering.hpp new file mode 100644 index 0000000..b6a636f --- /dev/null +++ b/source/core/defaults/rendering.hpp @@ -0,0 +1,10 @@ +// rendering.hpp - Opcions de renderització +// © 2026 JailDesigner + +#pragma once + +namespace Defaults::Rendering { + + constexpr int VSYNC_DEFAULT = 1; // 0=disabled, 1=enabled + +} // namespace Defaults::Rendering diff --git a/source/core/defaults/ship.hpp b/source/core/defaults/ship.hpp new file mode 100644 index 0000000..6156a3d --- /dev/null +++ b/source/core/defaults/ship.hpp @@ -0,0 +1,16 @@ +// ship.hpp - Configuració de la nau (invulnerabilitat, parpelleig) +// © 2026 JailDesigner + +#pragma once + +namespace Defaults::Ship { + + // Invulnerabilidad post-respawn + constexpr float INVULNERABILITY_DURATION = 3.0F; // Segundos de invulnerabilidad + + // Parpadeo visual durante invulnerabilidad + constexpr float BLINK_VISIBLE_TIME = 0.1F; // Tiempo visible (segundos) + constexpr float BLINK_INVISIBLE_TIME = 0.1F; // Tiempo invisible (segundos) + // Frecuencia total: 0.2s/ciclo = 5 Hz (~15 parpadeos en 3s) + +} // namespace Defaults::Ship diff --git a/source/core/defaults/title.hpp b/source/core/defaults/title.hpp new file mode 100644 index 0000000..cf2922b --- /dev/null +++ b/source/core/defaults/title.hpp @@ -0,0 +1,129 @@ +// title.hpp - Animacions de naves i layout de l'escena de títol +// © 2026 JailDesigner + +#pragma once + +#include + +#include "core/defaults/game.hpp" +#include "core/defaults/math.hpp" + +// Title scene ship animations (naves 3D flotantes a l'escena de título) +namespace Defaults::Title { + + namespace Ships { + // ============================================================ + // PARÀMETRES BASE (ajustar aquí per experimentar) + // ============================================================ + + // 1. Escala global de las naves + constexpr float SHIP_BASE_SCALE = 2.5F; // Multiplicador (1.0 = mida original del .shp) + + // 2. Altura vertical (cercanía al centro) + // Ratio Y desde el centro de la pantalla (0.0 = centro, 1.0 = bottom de pantalla) + constexpr float TARGET_Y_RATIO = 0.15625F; + + // 3. Radio orbital (distance radial desde centro en coordenadas polares) + constexpr float CLOCK_RADIUS = 150.0F; // Distancia des del centro + + // 4. Ángulos de posición (clock positions en coordenadas polares) + // En coordenadas de pantalla: 0° = derecha, 90° = baix, 180° = izquierda, 270° = dalt + constexpr float CLOCK_8_ANGLE = 150.0F * Math::PI / 180.0F; // 8 o'clock (bottom-left) + constexpr float CLOCK_4_ANGLE = 30.0F * Math::PI / 180.0F; // 4 o'clock (bottom-right) + + // 5. Radio máximo de la shape de la nave (para calcular offset automáticamente) + constexpr float SHIP_MAX_RADIUS = 30.0F; // Radi del cercle circumscrit a ship_starfield.shp + + // 6. Margen de seguridad para offset de entrada + constexpr float ENTRY_OFFSET_MARGIN = 227.5F; // Para offset total de ~340px (ajustado) + + // ============================================================ + // VALORS DERIVATS (calculats automáticoament - NO modificar) + // ============================================================ + + // Centro de la pantalla (point de referència) + constexpr float CENTER_X = Game::WIDTH / 2.0F; // auto-derivado de Game::WIDTH + constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // auto-derivado de Game::HEIGHT + + // Posicions target (calculades dinàmicament des dels parámetros base) + // Nota: std::cos/sin no són constexpr en C++20, pero funcionen en runtime + // Les funciones inline són optimitzades por el compilador (zero overhead) + inline auto p1TargetX() -> float { + return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE)); + } + inline auto p1TargetY() -> float { + return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO); + } + inline auto p2TargetX() -> float { + return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_4_ANGLE)); + } + inline auto p2TargetY() -> float { + return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO); + } + + // Escales de animación (relatives a SHIP_BASE_SCALE) + constexpr float ENTRY_SCALE_START = 1.5F * SHIP_BASE_SCALE; // Entrada: 50% més grande + constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotante: scale base + + // Offset de entrada (ajustat automáticoament a l'scale) + // Fórmula: (radi màxim de la ship * scale de entrada) + margen + constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN; + + // Vec2 de fuga (centro para l'animación de salida) + constexpr float VANISHING_POINT_X = CENTER_X; // auto-derivado de Game::WIDTH + constexpr float VANISHING_POINT_Y = CENTER_Y; // auto-derivado de Game::HEIGHT + + // ============================================================ + // ANIMACIONS (durades, oscil·lacions, delays) + // ============================================================ + + // Durades de animación + constexpr float ENTRY_DURATION = 2.0F; // Entrada (segons) + constexpr float EXIT_DURATION = 1.0F; // Salida (segons) + + // Flotació (oscil·lació reduïda y diferenciada per ship) + constexpr float FLOAT_AMPLITUDE_X = 4.0F; // Amplitud X (píxels) + constexpr float FLOAT_AMPLITUDE_Y = 2.5F; // Amplitud Y (píxels) + + // Freqüències base + constexpr float FLOAT_FREQUENCY_X_BASE = 0.5F; // Hz + constexpr float FLOAT_FREQUENCY_Y_BASE = 0.7F; // Hz + constexpr float FLOAT_PHASE_OFFSET = 1.57F; // π/2 (90°) + + // Delays de entrada (per a entrada escalonada) + constexpr float P1_ENTRY_DELAY = 0.0F; // P1 entra immediatament + constexpr float P2_ENTRY_DELAY = 0.5F; // P2 entra 0.5s después + + // Delay global antes de start l'animación de entrada al state MAIN + constexpr float ENTRANCE_DELAY = 5.0F; // Temps de espera antes que las naves entrin + + // Multiplicadors de freqüència para cada ship (variació sutil ±12%) + constexpr float P1_FREQUENCY_MULTIPLIER = 0.88F; // 12% més lenta + constexpr float P2_FREQUENCY_MULTIPLIER = 1.12F; // 12% més ràpida + + } // namespace Ships + + namespace Layout { + // Posicions verticals (anclatges des del TOP de pantalla lógica, 0.0-1.0) + constexpr float LOGO_POS = 0.20F; // Logo "ORNI" + constexpr float PRESS_START_POS = 0.75F; // "PRESS START TO PLAY" + constexpr float COPYRIGHT1_POS = 0.90F; // Primera línia copyright + + // Separacions relatives (proporció respecte Game::HEIGHT = 480px) + constexpr float LOGO_LINE_SPACING = 0.02F; // Entre "ORNI" i "ATTACK!" (10px) + constexpr float COPYRIGHT_LINE_SPACING = 0.0F; // Entre línies copyright (5px) + + // Factors de scale + constexpr float LOGO_SCALE = 0.6F; // Escala "ORNI ATTACK!" + constexpr float PRESS_START_SCALE = 1.0F; // Escala "PRESS START TO PLAY" + constexpr float COPYRIGHT_SCALE = 0.5F; // Escala copyright + constexpr float JAILGAMES_SCALE = 0.25F; // Escala del logo JAILGAMES pequeño sobre el copyright + + // Separación entre el logo JAILGAMES y la línea de copyright (proporción de Game::HEIGHT). + constexpr float JAILGAMES_COPYRIGHT_GAP = 0.015F; + + // Espaiat entre caràcters (usado per VectorText) + constexpr float TEXT_SPACING = 2.0F; + } // namespace Layout + +} // namespace Defaults::Title diff --git a/source/core/defaults/window.hpp b/source/core/defaults/window.hpp new file mode 100644 index 0000000..8d1d665 --- /dev/null +++ b/source/core/defaults/window.hpp @@ -0,0 +1,18 @@ +// window.hpp - Configuració de la finestra (mida, fullscreen, zoom) +// © 2026 JailDesigner + +#pragma once + +namespace Defaults::Window { + + constexpr int WIDTH = 1280; + constexpr int HEIGHT = 720; + constexpr int MIN_WIDTH = 640; // Mínimo: mitad del baseline (16:9) + constexpr int MIN_HEIGHT = 360; + // Zoom system + constexpr float BASE_ZOOM = 1.0F; // 1280x720 baseline (16:9) + constexpr float MIN_ZOOM = 0.5F; // 640x360 minimum + constexpr float ZOOM_INCREMENT = 0.1F; // 10% steps (F1/F2) + constexpr bool FULLSCREEN = true; // Pantalla completa activada por defecto + +} // namespace Defaults::Window diff --git a/source/core/defaults/zones.hpp b/source/core/defaults/zones.hpp new file mode 100644 index 0000000..d643d82 --- /dev/null +++ b/source/core/defaults/zones.hpp @@ -0,0 +1,81 @@ +// zones.hpp - Zones de l'àrea de joc (SDL_FRect amb càlculs automàtics per percentatges) +// © 2026 JailDesigner + +#pragma once + +#include + +#include "core/defaults/game.hpp" + +namespace Defaults::Zones { + + // --- CONFIGURACIÓ DE PORCENTATGES --- + // Todas las zones definides como a porcentajes de Game::WIDTH (640) i Game::HEIGHT (480) + + // Percentatges de height (divisió vertical) + constexpr float SCOREBOARD_TOP_HEIGHT_PERCENT = 0.02F; // 10% superior + constexpr float MAIN_PLAYAREA_HEIGHT_PERCENT = 0.88F; // 80% central + constexpr float SCOREBOARD_BOTTOM_HEIGHT_PERCENT = 0.10F; // 10% inferior + + // Padding horizontal para PLAYAREA (dentro de MAIN_PLAYAREA) + constexpr float PLAYAREA_PADDING_HORIZONTAL_PERCENT = 0.015F; // 5% a cada costat + + // --- CÀLCULS AUTOMÀTICS DE PÍXELS --- + // Cálculos automáticos a partir dels porcentajes + + // Alçades + constexpr float SCOREBOARD_TOP_H = Game::HEIGHT * SCOREBOARD_TOP_HEIGHT_PERCENT; + constexpr float MAIN_PLAYAREA_H = Game::HEIGHT * MAIN_PLAYAREA_HEIGHT_PERCENT; + constexpr float SCOREBOARD_BOTTOM_H = Game::HEIGHT * SCOREBOARD_BOTTOM_HEIGHT_PERCENT; + + // Posicions Y + constexpr float SCOREBOARD_TOP_Y = 0.0F; + constexpr float MAIN_PLAYAREA_Y = SCOREBOARD_TOP_H; + constexpr float SCOREBOARD_BOTTOM_Y = MAIN_PLAYAREA_Y + MAIN_PLAYAREA_H; + + // Padding horizontal de PLAYAREA + constexpr float PLAYAREA_PADDING_H = Game::WIDTH * PLAYAREA_PADDING_HORIZONTAL_PERCENT; + + // --- ZONES FINALS (SDL_FRect) --- + + // Marcador superior (reservado para futuro uso) + // Ocupa el 2% superior + constexpr SDL_FRect SCOREBOARD_TOP = { + 0.0F, // x = 0.0 + SCOREBOARD_TOP_Y, // y = 0.0 + static_cast(Game::WIDTH), // ancho completo + SCOREBOARD_TOP_H // alto + }; + + // Área de juego principal (contenedor del 80% central, sin padding) + // Ocupa el 88% central, ancho completo + constexpr SDL_FRect MAIN_PLAYAREA = { + 0.0F, // x = 0.0 + MAIN_PLAYAREA_Y, // debajo del scoreboard superior + static_cast(Game::WIDTH), // ancho completo + MAIN_PLAYAREA_H // alto + }; + + // Zona de juego real (con padding horizontal del 5%) + // Ocupa: dentro de MAIN_PLAYAREA, con márgenes laterales + // Se utiliza para límites del juego, colisiones, spawn + constexpr SDL_FRect PLAYAREA = { + PLAYAREA_PADDING_H, // padding horizontal + MAIN_PLAYAREA_Y, // debajo del scoreboard superior (igual que MAIN_PLAYAREA) + Game::WIDTH - (2.0F * PLAYAREA_PADDING_H), // ancho con padding + MAIN_PLAYAREA_H // alto (igual que MAIN_PLAYAREA) + }; + + // Marcador inferior (marcador actual) + // Ocupa el 10% inferior + constexpr SDL_FRect SCOREBOARD = { + 0.0F, // x = 0.0 + SCOREBOARD_BOTTOM_Y, // fondo + static_cast(Game::WIDTH), // ancho completo + SCOREBOARD_BOTTOM_H // alto + }; + + // Padding horizontal del marcador (para alinear zonas izquierda/derecha con PLAYAREA) + constexpr float SCOREBOARD_PADDING_H = 0.0F; // Game::WIDTH * 0.015f; + +} // namespace Defaults::Zones