- Cambiar todos los literales float de minúscula a mayúscula (1.0f → 1.0F)
- 657 correcciones aplicadas automáticamente con clang-tidy
- Check 1/N completado
🤖 Generated with Claude Code
529 lines
23 KiB
C++
529 lines
23 KiB
C++
#pragma once
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include <cstdint>
|
|
|
|
namespace Defaults {
|
|
// Configuración de ventana
|
|
namespace Window {
|
|
constexpr int WIDTH = 640;
|
|
constexpr int HEIGHT = 480;
|
|
constexpr int MIN_WIDTH = 320; // Mínimo: mitad del original
|
|
constexpr int MIN_HEIGHT = 240;
|
|
// Zoom system
|
|
constexpr float BASE_ZOOM = 1.0F; // 640x480 baseline
|
|
constexpr float MIN_ZOOM = 0.5F; // 320x240 minimum
|
|
constexpr float ZOOM_INCREMENT = 0.1F; // 10% steps (F1/F2)
|
|
} // namespace Window
|
|
|
|
// Dimensions base del joc (coordenades lògiques)
|
|
namespace Game {
|
|
constexpr int WIDTH = 640;
|
|
constexpr int HEIGHT = 480;
|
|
} // namespace Game
|
|
|
|
// Zones del joc (SDL_FRect amb càlculs automàtics basat en percentatges)
|
|
namespace Zones {
|
|
// --- CONFIGURACIÓ DE PORCENTATGES ---
|
|
// Totes les zones definides com a percentatges de Game::WIDTH (640) i Game::HEIGHT (480)
|
|
|
|
// Percentatges d'alçada (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 per a PLAYAREA (dins de MAIN_PLAYAREA)
|
|
constexpr float PLAYAREA_PADDING_HORIZONTAL_PERCENT = 0.015F; // 5% a cada costat
|
|
|
|
// --- CÀLCULS AUTOMÀTICS DE PÍXELS ---
|
|
// Càlculs automàtics a partir dels percentatges
|
|
|
|
// 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 (reservat per a futur ús)
|
|
// Ocupa: 10% superior (0-48px)
|
|
constexpr SDL_FRect SCOREBOARD_TOP = {
|
|
0.0F, // x = 0.0
|
|
SCOREBOARD_TOP_Y, // y = 0.0
|
|
static_cast<float>(Game::WIDTH), // w = 640.0
|
|
SCOREBOARD_TOP_H // h = 48.0
|
|
};
|
|
|
|
// Àrea de joc principal (contenidor del 80% central, sense padding)
|
|
// Ocupa: 10-90% (48-432px), ample complet
|
|
constexpr SDL_FRect MAIN_PLAYAREA = {
|
|
0.0F, // x = 0.0
|
|
MAIN_PLAYAREA_Y, // y = 48.0
|
|
static_cast<float>(Game::WIDTH), // w = 640.0
|
|
MAIN_PLAYAREA_H // h = 384.0
|
|
};
|
|
|
|
// Zona de joc real (amb padding horizontal del 5%)
|
|
// Ocupa: dins de MAIN_PLAYAREA, amb marges laterals
|
|
// S'utilitza per a límits del joc, col·lisions, spawn
|
|
constexpr SDL_FRect PLAYAREA = {
|
|
PLAYAREA_PADDING_H, // x = 32.0
|
|
MAIN_PLAYAREA_Y, // y = 48.0 (igual que MAIN_PLAYAREA)
|
|
Game::WIDTH - 2.0F * PLAYAREA_PADDING_H, // w = 576.0
|
|
MAIN_PLAYAREA_H // h = 384.0 (igual que MAIN_PLAYAREA)
|
|
};
|
|
|
|
// Marcador inferior (marcador actual)
|
|
// Ocupa: 10% inferior (432-480px)
|
|
constexpr SDL_FRect SCOREBOARD = {
|
|
0.0F, // x = 0.0
|
|
SCOREBOARD_BOTTOM_Y, // y = 432.0
|
|
static_cast<float>(Game::WIDTH), // w = 640.0
|
|
SCOREBOARD_BOTTOM_H // h = 48.0
|
|
};
|
|
|
|
// Padding horizontal del marcador (per alinear zones esquerra/dreta amb 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 int MAX_IPUNTS = 30;
|
|
|
|
constexpr float SHIP_RADIUS = 12.0F;
|
|
constexpr float ENEMY_RADIUS = 20.0F;
|
|
constexpr float BULLET_RADIUS = 3.0F;
|
|
} // namespace Entities
|
|
|
|
// Ship (nave del jugador)
|
|
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)
|
|
|
|
// 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 marges)
|
|
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 jugador 1)
|
|
constexpr float INIT_HUD_SHIP1_RATIO_INIT = 0.0F;
|
|
constexpr float INIT_HUD_SHIP1_RATIO_END = 1.0F;
|
|
|
|
// SHIP2 (nave jugador 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 (valores actuales del juego, sincronizados con joc_asteroides.cpp)
|
|
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²
|
|
constexpr float ENEMY_SPEED = 2.0F; // unidades/frame
|
|
constexpr float BULLET_SPEED = 6.0F; // unidades/frame
|
|
constexpr float VELOCITY_SCALE = 20.0F; // factor conversión frame→tiempo
|
|
|
|
// Explosions (debris physics)
|
|
namespace Debris {
|
|
constexpr float VELOCITAT_BASE = 80.0F; // Velocitat 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ó mínima (rad/s ~5.7°/s)
|
|
constexpr float ROTACIO_MAX = 0.3F; // Rotació 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 velocitat 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 cap 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 = 3.14159265359F;
|
|
} // namespace Math
|
|
|
|
// Colores (oscilación para efecto CRT)
|
|
namespace Color {
|
|
// Frecuencia de oscilación
|
|
constexpr float FREQUENCY = 6.0F; // 1 Hz (1 ciclo/segundo)
|
|
|
|
// Color de líneas (efecto fósforo verde CRT)
|
|
constexpr uint8_t LINE_MIN_R = 100; // Verde oscuro
|
|
constexpr uint8_t LINE_MIN_G = 200;
|
|
constexpr uint8_t LINE_MIN_B = 100;
|
|
|
|
constexpr uint8_t LINE_MAX_R = 100; // Verde brillante
|
|
constexpr uint8_t LINE_MAX_G = 255;
|
|
constexpr uint8_t LINE_MAX_B = 100;
|
|
|
|
// Color de fondo (pulso sutil verde oscuro)
|
|
constexpr uint8_t BACKGROUND_MIN_R = 0; // Negro
|
|
constexpr uint8_t BACKGROUND_MIN_G = 5;
|
|
constexpr uint8_t BACKGROUND_MIN_B = 0;
|
|
|
|
constexpr uint8_t BACKGROUND_MAX_R = 0; // Verde muy oscuro
|
|
constexpr uint8_t BACKGROUND_MAX_G = 15;
|
|
constexpr uint8_t BACKGROUND_MAX_B = 0;
|
|
} // namespace Color
|
|
|
|
// Brillantor (control de intensitat per cada tipus d'entitat)
|
|
namespace Brightness {
|
|
// Brillantor estàtica per entitats de joc (0.0-1.0)
|
|
constexpr float NAU = 1.0F; // Màxima visibilitat (jugador)
|
|
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 distància al centre
|
|
// distancia_centre: 0.0 (centre) → 1.0 (vora pantalla)
|
|
// brightness = MIN + (MAX - MIN) * distancia_centre
|
|
constexpr float STARFIELD_MIN = 0.3F; // Estrelles llunyanes (prop del centre)
|
|
constexpr float STARFIELD_MAX = 0.8F; // Estrelles properes (vora pantalla)
|
|
} // namespace Brightness
|
|
|
|
// Renderització (V-Sync i altres opcions de render)
|
|
namespace Rendering {
|
|
constexpr int VSYNC_DEFAULT = 1; // 0=disabled, 1=enabled
|
|
} // namespace Rendering
|
|
|
|
// Audio (sistema de so i música)
|
|
namespace Audio {
|
|
constexpr float VOLUME = 1.0F; // Volumen maestro (0.0 a 1.0)
|
|
constexpr bool ENABLED = true; // Audio habilitado por defecto
|
|
} // namespace Audio
|
|
|
|
// Música (pistas de fondo)
|
|
namespace Music {
|
|
constexpr float VOLUME = 0.8F; // Volumen música
|
|
constexpr bool ENABLED = true; // Música habilitada
|
|
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 float VOLUME = 1.0F; // Volumen efectos
|
|
constexpr bool ENABLED = true; // Sonidos habilitados
|
|
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 jugador 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 (tipus d'enemics)
|
|
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
|
|
|
|
// Quadrat (perseguidor - tracks player)
|
|
namespace Quadrat {
|
|
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 Quadrat
|
|
|
|
// 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ó per tipus d'enemic)
|
|
namespace Scoring {
|
|
constexpr int PENTAGON_SCORE = 100; // Pentàgon (esquivador, 35 px/s)
|
|
constexpr int QUADRAT_SCORE = 150; // Quadrat (perseguidor, 40 px/s)
|
|
constexpr int MOLINILLO_SCORE = 200; // Molinillo (agressiu, 50 px/s)
|
|
} // namespace Scoring
|
|
|
|
} // namespace Enemies
|
|
|
|
// Title scene ship animations (naus 3D flotants a l'escena de títol)
|
|
namespace Title {
|
|
namespace Ships {
|
|
// ============================================================
|
|
// PARÀMETRES BASE (ajustar aquí per experimentar)
|
|
// ============================================================
|
|
|
|
// 1. Escala global de les naus
|
|
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 (distancia radial desde centro en coordenadas polares)
|
|
constexpr float CLOCK_RADIUS = 150.0F; // Distància des del centre
|
|
|
|
// 4. Ángulos de posición (clock positions en coordenadas polares)
|
|
// En coordenades de pantalla: 0° = dreta, 90° = baix, 180° = esquerra, 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 forma 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àticament - NO modificar)
|
|
// ============================================================
|
|
|
|
// Centre de la pantalla (punt de referència)
|
|
constexpr float CENTER_X = Game::WIDTH / 2.0F; // 320.0f
|
|
constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // 240.0f
|
|
|
|
// Posicions target (calculades dinàmicament des dels paràmetres base)
|
|
// Nota: std::cos/sin no són constexpr en C++20, però funcionen en runtime
|
|
// Les funcions inline són optimitzades pel compilador (zero overhead)
|
|
inline float P1_TARGET_X() {
|
|
return CENTER_X + CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE);
|
|
}
|
|
inline float P1_TARGET_Y() {
|
|
return CENTER_Y + (Game::HEIGHT / 2.0F) * TARGET_Y_RATIO;
|
|
}
|
|
inline float P2_TARGET_X() {
|
|
return CENTER_X + CLOCK_RADIUS * std::cos(CLOCK_4_ANGLE);
|
|
}
|
|
inline float P2_TARGET_Y() {
|
|
return CENTER_Y + (Game::HEIGHT / 2.0F) * TARGET_Y_RATIO;
|
|
}
|
|
|
|
// Escales d'animació (relatives a SHIP_BASE_SCALE)
|
|
constexpr float ENTRY_SCALE_START = 1.5F * SHIP_BASE_SCALE; // Entrada: 50% més gran
|
|
constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotant: escala base
|
|
|
|
// Offset d'entrada (ajustat automàticament a l'escala)
|
|
// Fórmula: (radi màxim de la nau * escala d'entrada) + marge
|
|
constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN;
|
|
|
|
// Punt de fuga (centre per a l'animació de sortida)
|
|
constexpr float VANISHING_POINT_X = CENTER_X; // 320.0f
|
|
constexpr float VANISHING_POINT_Y = CENTER_Y; // 240.0f
|
|
|
|
// ============================================================
|
|
// ANIMACIONS (durades, oscil·lacions, delays)
|
|
// ============================================================
|
|
|
|
// Durades d'animació
|
|
constexpr float ENTRY_DURATION = 2.0F; // Entrada (segons)
|
|
constexpr float EXIT_DURATION = 1.0F; // Sortida (segons)
|
|
|
|
// Flotació (oscil·lació reduïda i diferenciada per nau)
|
|
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 d'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 després
|
|
|
|
// Delay global abans d'iniciar l'animació d'entrada al estat MAIN
|
|
constexpr float ENTRANCE_DELAY = 5.0F; // Temps d'espera abans que les naus entrin
|
|
|
|
// Multiplicadors de freqüència per a cada nau (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 d'escala
|
|
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
|
|
|
|
// Espaiat entre caràcters (usat per VectorText)
|
|
constexpr float TEXT_SPACING = 2.0F;
|
|
} // namespace Layout
|
|
} // namespace Title
|
|
|
|
// Floating score numbers (números flotants de puntuació)
|
|
namespace FloatingScore {
|
|
constexpr float LIFETIME = 2.0F; // Duració màxima (segons)
|
|
constexpr float VELOCITY_Y = -30.0F; // Velocitat vertical (px/s, negatiu = amunt)
|
|
constexpr float VELOCITY_X = 0.0F; // Velocitat 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
|