293 lines
13 KiB
C++
293 lines
13 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)
|
|
namespace Zones {
|
|
// --- CONFIGURACIÓ DE PORCENTATGES ---
|
|
// Basats en valors originals 640x480
|
|
// Ajusta estos valors per canviar proporcions
|
|
|
|
constexpr float PLAYAREA_MARGIN_HORIZONTAL_PERCENT = 10.0f / Game::WIDTH;
|
|
constexpr float PLAYAREA_MARGIN_VERTICAL_PERCENT = 10.0f / Game::HEIGHT;
|
|
constexpr float SCOREBOARD_HEIGHT_PERCENT = 48.0f / Game::HEIGHT;
|
|
|
|
// --- CÀLCULS AUTOMÀTICS ---
|
|
// Estos valors es recalculen si canvien Game::WIDTH o Game::HEIGHT
|
|
|
|
constexpr float PLAYAREA_MARGIN_H =
|
|
Game::WIDTH * PLAYAREA_MARGIN_HORIZONTAL_PERCENT;
|
|
constexpr float PLAYAREA_MARGIN_V =
|
|
Game::HEIGHT * PLAYAREA_MARGIN_VERTICAL_PERCENT;
|
|
constexpr float SCOREBOARD_H = Game::HEIGHT * SCOREBOARD_HEIGHT_PERCENT;
|
|
|
|
// --- ZONES FINALS (SDL_FRect) ---
|
|
|
|
// Zona de joc principal
|
|
// Ocupa: tot menys marges (dalt, esq, dret) i scoreboard (baix)
|
|
constexpr SDL_FRect PLAYAREA = {
|
|
PLAYAREA_MARGIN_H, // x = 10.0
|
|
PLAYAREA_MARGIN_V, // y = 10.0
|
|
Game::WIDTH - 2.0f * PLAYAREA_MARGIN_H, // width = 620.0
|
|
Game::HEIGHT - PLAYAREA_MARGIN_V - SCOREBOARD_H // height = 406.0
|
|
};
|
|
|
|
// Zona de marcador
|
|
// Ocupa: tot l'ample, 64px d'alçada en la part inferior
|
|
constexpr SDL_FRect SCOREBOARD = {
|
|
0.0f, // x = 0.0
|
|
Game::HEIGHT - SCOREBOARD_H, // y = 416.0
|
|
static_cast<float>(Game::WIDTH), // width = 640.0
|
|
SCOREBOARD_H // height = 64.0
|
|
};
|
|
} // 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
|
|
|
|
// 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
|
|
constexpr float INIT_HUD_RECT_RATIO = 0.67f; // Proporción animación rectángulo (67% del total)
|
|
constexpr float INIT_HUD_SCORE_RATIO = 0.83f; // Proporción animación marcador (83% del total)
|
|
constexpr float INIT_HUD_SHIP_RATIO = 0.83f; // Proporción animación nave (83% del total)
|
|
|
|
// 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
|
|
} // 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
|
|
|
|
// 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
|