Merge branch 'tune/gameplay': balas, velocitat, stage 1 i so hit

This commit is contained in:
2026-05-21 19:05:53 +02:00
8 changed files with 60 additions and 55 deletions
Binary file not shown.
+3 -3
View File
@@ -9,11 +9,11 @@ metadata:
stages:
# STAGE 1: Tutorial - Only pentagons, slow speed
- stage_id: 1
total_enemies: 5
total_enemies: 50
spawn_config:
mode: "progressive"
initial_delay: 2.0
spawn_interval: 3.0
initial_delay: 0.3
spawn_interval: 0.4
enemy_distribution:
pentagon: 100
cuadrado: 0
+1
View File
@@ -38,6 +38,7 @@ namespace Defaults::Sound {
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* HIT = "effects/hit.wav"; // Enemic ferit (primer impacte → HURT)
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
+1 -1
View File
@@ -6,7 +6,7 @@
namespace Defaults::Entities {
constexpr int MAX_ORNIS = 15;
constexpr int MAX_BALES = 3;
constexpr int MAX_BALES = 50;
constexpr float SHIP_RADIUS = 12.0F;
constexpr float ENEMY_RADIUS = 20.0F;
+1 -1
View File
@@ -7,7 +7,7 @@ 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 MAX_VELOCITY = 180.0F; // px/s
constexpr float FRICTION = 20.0F; // px/s²
// Bullet — impacto físico contra enemigo (impulse mass-aware).
+2
View File
@@ -8,6 +8,7 @@
#include <cstdlib>
#include <iostream>
#include "core/audio/audio.hpp"
#include "core/defaults.hpp"
#include "core/entities/entity.hpp"
#include "core/graphics/shape_loader.hpp"
@@ -276,6 +277,7 @@ void Enemy::destruir() {
void Enemy::herir(uint8_t shooter_id) {
wounded_timer_ = Defaults::Enemies::Wounded::DURATION;
last_hit_by_ = shooter_id;
Audio::get()->playSound(Defaults::Sound::HIT, Audio::Group::GAME);
}
void Enemy::applyImpulse(const Vec2& impulse) {
+5 -3
View File
@@ -850,9 +850,11 @@ void GameScene::fireBullet(uint8_t player_id) {
float tip_y = (LOCAL_TIP_X * sin_a) + (LOCAL_TIP_Y * cos_a) + ship_centre.y;
Vec2 posicio_dispar = {.x = tip_x, .y = tip_y};
// Buscar primera bullet inactiva en el pool del player
int start_idx = player_id * 3; // P1=[0,1,2], P2=[3,4,5]
for (int i = start_idx; i < start_idx + 3; i++) {
// Buscar primera bullet inactiva en el pool del player.
// El pool global té MAX_BALES slots per jugador (P1=[0..MAX-1], P2=[MAX..2*MAX-1]).
constexpr int SLOTS_PER_PLAYER = Defaults::Entities::MAX_BALES;
const int START_IDX = player_id * SLOTS_PER_PLAYER;
for (int i = START_IDX; i < START_IDX + SLOTS_PER_PLAYER; i++) {
if (!bullets_[i].isActive()) {
bullets_[i].disparar(posicio_dispar, ship_angle, player_id);
break;
+47 -47
View File
@@ -10,46 +10,46 @@
namespace StageSystem {
// Tipo de mode de spawn
enum class ModeSpawn : std::uint8_t {
PROGRESSIVE, // Spawn progressiu con intervals
IMMEDIATE, // Todos los enemigos de cop
WAVE // Onades de 3-5 enemigos (futura extensió)
};
// Tipo de mode de spawn
enum class ModeSpawn : std::uint8_t {
PROGRESSIVE, // Spawn progressiu con intervals
IMMEDIATE, // Todos los enemigos de cop
WAVE // Onades de 3-5 enemigos (futura extensió)
};
// Configuración de spawn
struct ConfigSpawn {
// Configuración de spawn
struct ConfigSpawn {
ModeSpawn mode;
float delay_inicial; // Segons antes del primer spawn
float interval_spawn; // Segons entre spawns consecutius
};
};
// Distribució de type de enemigos (percentatges)
struct DistribucioEnemics {
// Distribució de type de enemigos (percentatges)
struct DistribucioEnemics {
uint8_t pentagon; // 0-100
uint8_t cuadrado; // 0-100
uint8_t cuadrado; // 0-100
uint8_t molinillo; // 0-100
// Suma ha de ser 100, validat en StageLoader
};
};
// Multiplicadors de dificultat
struct MultiplicadorsDificultat {
float velocity; // 0.5-2.0 típic
float rotation; // 0.5-2.0 típic
// Multiplicadors de dificultat
struct MultiplicadorsDificultat {
float velocity; // 0.5-2.0 típic
float rotation; // 0.5-2.0 típic
float tracking_strength; // 0.0-1.5 (aplicat a Cuadrado)
};
};
// Metadades del file YAML
struct MetadataStages {
// Metadades del file YAML
struct MetadataStages {
std::string version;
uint8_t total_stages;
std::string descripcio;
};
};
// Configuración completa de un stage
struct StageConfig {
// Configuración completa de un stage
struct StageConfig {
uint8_t stage_id; // 1-10
uint8_t total_enemies; // 5-15
uint8_t total_enemies; // 1-200 (el cap simultani en pantalla el marca MAX_ORNIS)
ConfigSpawn config_spawn;
DistribucioEnemics distribucio;
MultiplicadorsDificultat multiplicadors;
@@ -59,13 +59,13 @@ struct StageConfig {
// stage_id es uint8_t: el rango superior (<=255) está garantizado por
// el tipo; basta con confirmar que no es 0 (sentinela "sin asignar").
return stage_id >= 1 &&
total_enemies > 0 && total_enemies <= 15 &&
total_enemies > 0 && total_enemies <= 200 &&
distribucio.pentagon + distribucio.cuadrado + distribucio.molinillo == 100;
}
};
};
// Configuración completa del sistema (carregada desde YAML)
struct StageSystemConfig {
// Configuración completa del sistema (carregada desde YAML)
struct StageSystemConfig {
MetadataStages metadata;
std::vector<StageConfig> stages; // Índex [0] = stage 1
@@ -76,26 +76,26 @@ struct StageSystemConfig {
}
return &stages[stage_id - 1];
}
};
};
// Constants per messages de transición
namespace Constants {
// Pool de messages per start de level (selecció aleatòria)
inline constexpr std::array<const char*, 12> MISSATGES_LEVEL_START = {
"ORNI ALERT!",
"INCOMING ORNIS!",
"ROLLING THREAT!",
"ENEMY WAVE!",
"WAVE OF ORNIS DETECTED!",
"NEXT SWARM APPROACHING!",
"BRACE FOR THE NEXT WAVE!",
"ANOTHER ATTACK INCOMING!",
"SENSORS DETECT HOSTILE ORNIS...",
"UNIDENTIFIED ROLLING OBJECTS INBOUND!",
"ENEMY FORCES MOBILIZING!",
"PREPARE FOR IMPACT!"};
// Constants per messages de transición
namespace Constants {
// Pool de messages per start de level (selecció aleatòria)
inline constexpr std::array<const char*, 12> MISSATGES_LEVEL_START = {
"ORNI ALERT!",
"INCOMING ORNIS!",
"ROLLING THREAT!",
"ENEMY WAVE!",
"WAVE OF ORNIS DETECTED!",
"NEXT SWARM APPROACHING!",
"BRACE FOR THE NEXT WAVE!",
"ANOTHER ATTACK INCOMING!",
"SENSORS DETECT HOSTILE ORNIS...",
"UNIDENTIFIED ROLLING OBJECTS INBOUND!",
"ENEMY FORCES MOBILIZING!",
"PREPARE FOR IMPACT!"};
constexpr const char* MISSATGE_LEVEL_COMPLETED = "GOOD JOB COMMANDER!";
} // namespace Constants
constexpr const char* MISSATGE_LEVEL_COMPLETED = "GOOD JOB COMMANDER!";
} // namespace Constants
} // namespace StageSystem