Files
orni_attack/source/core/defaults.hpp

372 lines
16 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)
// 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.33f;
constexpr float INIT_HUD_RECT_RATIO_END = 1.0f;
// SCORE (marcador de puntuación)
constexpr float INIT_HUD_SCORE_RATIO_INIT = 0.17f;
constexpr float INIT_HUD_SCORE_RATIO_END = 1.0f;
// 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
} // 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 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* EXPLOSION = "effects/explosion.wav"; // Explosión
constexpr const char* LASER = "effects/laser_shoot.wav"; // Disparo
constexpr const char* LOGO = "effects/logo.wav"; // Logo
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
// 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.75f; // Escala del text (0.75 = 75% del marcador)
constexpr float SPACING = 0.0f; // Espaiat entre caràcters
constexpr int MAX_CONCURRENT = 15; // Pool size (= MAX_ORNIS)
} // namespace FloatingScore
} // namespace Defaults