Fase 1e: cierre de naming sweep (#pragma once, locals, comentarios castellano)
Tres tareas de pulido para cerrar la Fase 1 por completo: #pragma once uniforme: - sdl_manager.hpp y game_scene.hpp pasan de #ifndef/#define guards a #pragma once. Los archivos externos (stb_vorbis.h, fkyaml_node.hpp) se mantienen intactos (codigo de terceros). Variables locales y parametros restantes (catalan -> ingles): - fitxer -> file, moviment -> movement, inici -> start - comptador -> counter, escalada -> scaled - missatges -> messages, llista -> list - alçada -> height, amplada -> width, llargada -> length - origen -> origin, distancia -> distance, valor -> value, desti -> target - neteja -> clear, presenta -> present (SDLManager) - total_enemics -> total_enemies, configurar -> configure, iniciar -> start Comentarios catalan -> castellano: - Cabeceras de fichero actualizadas con nombres nuevos (escena_joc.hpp -> game_scene.hpp, etc.) - Palabras tecnicas: trasllacio->traslacion, col-lisio->colision, inicialitzacio->inicializacion, posicio->posicion, rotacio->rotacion, velocitat->velocidad, acceleracio->aceleracion, explosio->explosion, renderitzat->renderizado, calcul->calculo, transicio->transicion, comprovacio->comprobacion, substitucio->sustitucion, utilitzacio->utilizacion, opcio->opcion, configuracio->configuracion, funcio->funcion, distancia, animacio->animacion - Determinantes y conectores: aquest->este, aquesta->esta, amb->con, sense->sin, pero->pero, mai->nunca, nomes->solo, tambe->tambien, sempre->siempre, ja->ya, mateix->mismo, vegada->vez, dintre->dentro, fora->fuera, dreta->derecha, esquerra->izquierda, sortir->salir, sortida->salida, petit->pequeno, gran->grande, nou->nuevo, vell->viejo, molt->mucho, els->los, les->las, totes les->todas las, d'->de, com->como, quan->cuando, mentre->mientras, despres->despues, abans->antes, durant->durante, fins->hasta, encara->aun, llavors->entonces, aixi->asi, perque->porque - Sustantivos: classe->clase, metode->metodo, parametre->parametro, versio->version, entitat->entidad, joc->juego, nivell->nivel, enemic->enemigo, naus->naves, bales->balas, fitxer->archivo, pentagon->pentagono, pun- tuacio->puntuacion, flotant->flotante, titol->titulo, objectiu->objetivo, mostra->muestra, tipus->tipo Strings literales preservados en valenciano segun decision del usuario: el texto del HUD del juego (puntuaciones, mensajes en pantalla, archivo de config) se mantiene en valenciano original. 70 fitxers tocats, +1117 / -1123. Compila i enllaca. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// escena_joc.cpp - Implementació de la lògica del joc
|
||||
// © 1999 Visente i Sergi (versió Pascal)
|
||||
// © 2025 Port a C++20 amb SDL3
|
||||
// game_scene.cpp - Implementació de la lógica del juego
|
||||
// © 1999 Visente i Sergi (versión Pascal)
|
||||
// © 2025 Port a C++20 con SDL3
|
||||
|
||||
#include "game_scene.hpp"
|
||||
|
||||
@@ -34,39 +34,39 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context)
|
||||
floating_score_manager_(sdl.getRenderer()),
|
||||
text_(sdl.getRenderer()),
|
||||
init_hud_rect_sound_played_(false) {
|
||||
// Recuperar configuració de match des del context
|
||||
// Recuperar configuración de match des del context
|
||||
match_config_ = context_.getMatchConfig();
|
||||
|
||||
// Debug output de la configuració
|
||||
std::cout << "[GameScene] Configuració de match - P1: "
|
||||
// Debug output de la configuración
|
||||
std::cout << "[GameScene] Configuración de match - P1: "
|
||||
<< (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU")
|
||||
<< ", P2: "
|
||||
<< (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU")
|
||||
<< '\n';
|
||||
|
||||
// Consumir opcions (preparació per MODE_DEMO futur)
|
||||
// Consumir opciones (preparació per MODE_DEMO futur)
|
||||
auto option = context_.consumeOption();
|
||||
(void)option; // Suprimir warning de variable no usada
|
||||
|
||||
// Inicialitzar naus amb renderer (P1=ship.shp, P2=ship2.shp)
|
||||
// Inicialitzar naves con renderer (P1=ship.shp, P2=ship2.shp)
|
||||
ships_[0] = Ship(sdl.getRenderer(), "ship.shp"); // Jugador 1: nave estàndar
|
||||
ships_[1] = Ship(sdl.getRenderer(), "ship2.shp"); // Jugador 2: interceptor amb ales
|
||||
ships_[1] = Ship(sdl.getRenderer(), "ship2.shp"); // Jugador 2: interceptor con ales
|
||||
|
||||
// Inicialitzar bales amb renderer
|
||||
// Inicialitzar balas con renderer
|
||||
for (auto& bullet : bullets_) {
|
||||
bullet = Bullet(sdl.getRenderer());
|
||||
}
|
||||
|
||||
// Inicialitzar enemics amb renderer
|
||||
// Inicialitzar enemigos con renderer
|
||||
for (auto& enemy : enemies_) {
|
||||
enemy = Enemy(sdl.getRenderer());
|
||||
}
|
||||
}
|
||||
|
||||
void GameScene::run() {
|
||||
std::cout << "SceneType Joc: Inicialitzant...\n";
|
||||
std::cout << "SceneType Juego: Inicialitzant...\n";
|
||||
|
||||
// Inicialitzar state del joc
|
||||
// Inicialitzar state del juego
|
||||
init();
|
||||
|
||||
SDL_Event event;
|
||||
@@ -78,16 +78,16 @@ void GameScene::run() {
|
||||
float delta_time = (current_time - last_time) / 1000.0F;
|
||||
last_time = current_time;
|
||||
|
||||
// Limitar delta_time per evitar grans salts
|
||||
// Limitar delta_time per evitar grandes salts
|
||||
delta_time = std::min(delta_time, 0.05F);
|
||||
|
||||
// Actualitzar comptador de FPS
|
||||
// Actualitzar counter de FPS
|
||||
sdl_.updateFPS(delta_time);
|
||||
|
||||
// Actualitzar visibilitat del cursor (auto-ocultar)
|
||||
Mouse::updateCursorVisibility();
|
||||
|
||||
// Actualitzar sistema d'input ABANS del event loop
|
||||
// Actualitzar sistema de input ABANS del event loop
|
||||
Input::get()->update();
|
||||
|
||||
// Processar events SDL
|
||||
@@ -101,29 +101,29 @@ void GameScene::run() {
|
||||
GlobalEvents::handle(event, sdl_, context_);
|
||||
}
|
||||
|
||||
// Actualitzar física del joc amb delta_time real
|
||||
// Actualitzar física del juego con delta_time real
|
||||
update(delta_time);
|
||||
|
||||
// Actualitzar sistema d'audio
|
||||
// Actualitzar sistema de audio
|
||||
Audio::update();
|
||||
|
||||
// Actualitzar colors oscil·lats
|
||||
sdl_.updateColors(delta_time);
|
||||
|
||||
// Netejar pantalla (usa color oscil·lat)
|
||||
sdl_.neteja(0, 0, 0);
|
||||
sdl_.clear(0, 0, 0);
|
||||
|
||||
// Actualitzar context de renderitzat (factor d'scale global)
|
||||
// Actualitzar context de renderizado (factor de scale global)
|
||||
sdl_.updateRenderingContext();
|
||||
|
||||
// Dibuixar joc
|
||||
// Dibuixar juego
|
||||
draw();
|
||||
|
||||
// Presentar renderer (swap buffers)
|
||||
sdl_.presenta();
|
||||
sdl_.present();
|
||||
}
|
||||
|
||||
std::cout << "SceneType Joc: Finalitzant...\n";
|
||||
std::cout << "SceneType Juego: Finalitzant...\n";
|
||||
}
|
||||
|
||||
void GameScene::init() {
|
||||
@@ -145,7 +145,7 @@ void GameScene::init() {
|
||||
stage_manager_->init();
|
||||
|
||||
// [NEW] Set ship position reference for safe spawn (P1 for now, TODO: dual tracking)
|
||||
stage_manager_->get_spawn_controller().set_ship_position(&ships_[0].getCenter());
|
||||
stage_manager_->getSpawnController().set_ship_position(&ships_[0].getCenter());
|
||||
|
||||
// Inicialitzar timers de muerte per player
|
||||
hit_timer_per_player_[0] = 0.0F;
|
||||
@@ -165,12 +165,12 @@ void GameScene::init() {
|
||||
score_per_player_[1] = 0;
|
||||
floating_score_manager_.reset();
|
||||
|
||||
// DEPRECATED: spawn_position_ ja no s'usa, es calcula dinàmicament amb obtenir_punt_spawn(player_id)
|
||||
// DEPRECATED: spawn_position_ ya no s'usa, es calcula dinàmicament con obtenir_punt_spawn(player_id)
|
||||
// const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
||||
// spawn_position_.x = zona.x + zona.w * 0.5f;
|
||||
// spawn_position_.y = zona.y + zona.h * Defaults::Game::INIT_HUD_SHIP_START_Y_RATIO;
|
||||
|
||||
// Inicialitzar naus segons configuració (només jugadors active)
|
||||
// Inicialitzar naves segons configuración (solo jugadors active)
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu;
|
||||
|
||||
@@ -180,10 +180,10 @@ void GameScene::init() {
|
||||
ships_[i].init(&spawn_pos, false); // No invulnerability at start
|
||||
std::cout << "[GameScene] Jugador " << (i + 1) << " inicialitzat\n";
|
||||
} else {
|
||||
// Jugador inactiu: marcar com a mort permanent
|
||||
// Jugador inactiu: marcar como a mort permanent
|
||||
ships_[i].markHit();
|
||||
hit_timer_per_player_[i] = 999.0F; // Valor sentinella (permanent inactiu)
|
||||
lives_per_player_[i] = 0; // Sense vides
|
||||
lives_per_player_[i] = 0; // Sin vides
|
||||
std::cout << "[GameScene] Jugador " << (i + 1) << " inactiu\n";
|
||||
}
|
||||
}
|
||||
@@ -195,16 +195,16 @@ void GameScene::init() {
|
||||
// DON'T call enemy.init() here - stage system handles spawning
|
||||
}
|
||||
|
||||
// Inicialitzar bales (now 6 instead of 3)
|
||||
// Inicialitzar balas (now 6 instead of 3)
|
||||
for (auto& bullet : bullets_) {
|
||||
bullet.init();
|
||||
}
|
||||
|
||||
// [ELIMINAT] Iniciar música de joc (ara es gestiona en stage_manager)
|
||||
// La música s'inicia quan es transiciona de INIT_HUD a LEVEL_START
|
||||
// [ELIMINAT] Iniciar música de juego (ara es gestiona en stage_manager)
|
||||
// La música s'inicia cuando es transiciona de INIT_HUD a LEVEL_START
|
||||
// Audio::get()->playMusic("game.ogg");
|
||||
|
||||
// Reset flag de sons d'animació
|
||||
// Reset flag de sons de animación
|
||||
init_hud_rect_sound_played_ = false;
|
||||
}
|
||||
|
||||
@@ -213,14 +213,14 @@ void GameScene::update(float delta_time) {
|
||||
if (game_over_state_ == GameOverState::NONE) {
|
||||
auto* input = Input::get();
|
||||
|
||||
// Jugador 1 dispara (només si està active)
|
||||
// Jugador 1 dispara (solo si está active)
|
||||
if (match_config_.jugador1_actiu) {
|
||||
if (input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||
disparar_bala(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Jugador 2 dispara (només si està active)
|
||||
// Jugador 2 dispara (solo si está active)
|
||||
if (match_config_.jugador2_actiu) {
|
||||
if (input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||
disparar_bala(1);
|
||||
@@ -287,9 +287,9 @@ void GameScene::update(float delta_time) {
|
||||
game_over_timer_ -= delta_time;
|
||||
|
||||
if (game_over_timer_ <= 0.0F) {
|
||||
// Aturar música de joc abans de tornar al títol
|
||||
// Aturar música de juego antes de tornar al título
|
||||
Audio::get()->stopMusic();
|
||||
// Transició a pantalla de títol
|
||||
// Transición a pantalla de título
|
||||
context_.setNextScene(SceneType::TITLE);
|
||||
SceneManager::actual = SceneType::TITLE;
|
||||
return;
|
||||
@@ -374,8 +374,8 @@ void GameScene::update(float delta_time) {
|
||||
// Update stage manager timer (pot canviar l'state!)
|
||||
stage_manager_->update(delta_time);
|
||||
|
||||
// [FIX] Si l'state ha canviat durant update(), sortir immediatament
|
||||
// per evitar recalcular la posició de la ship amb el nou timer
|
||||
// [FIX] Si l'state ha canviat durante update(), salir immediatament
|
||||
// per evitar recalcular la posición de la ship con el nuevo timer
|
||||
if (stage_manager_->get_estat() != StageSystem::EstatStage::INIT_HUD) {
|
||||
break;
|
||||
}
|
||||
@@ -395,7 +395,7 @@ void GameScene::update(float delta_time) {
|
||||
Defaults::Game::INIT_HUD_SHIP2_RATIO_INIT,
|
||||
Defaults::Game::INIT_HUD_SHIP2_RATIO_END);
|
||||
|
||||
// [MODIFICAT] Animar AMBAS naus con sus progress respectivos
|
||||
// [MODIFICAT] Animar AMBAS naves con sus progress respectivos
|
||||
if (match_config_.jugador1_actiu && ship1_progress < 1.0F) {
|
||||
Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0);
|
||||
ships_[0].setCenter(pos_p1);
|
||||
@@ -406,8 +406,8 @@ void GameScene::update(float delta_time) {
|
||||
ships_[1].setCenter(pos_p2);
|
||||
}
|
||||
|
||||
// Una vegada l'animació acaba, permetre control normal
|
||||
// però mantenir la posició inicial especial fins LEVEL_START
|
||||
// Una vez l'animación acaba, permetre control normal
|
||||
// pero mantenir la posición inicial especial hasta LEVEL_START
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -444,13 +444,13 @@ void GameScene::update(float delta_time) {
|
||||
|
||||
case StageSystem::EstatStage::PLAYING: {
|
||||
// [NEW] Update stage manager (spawns enemies, pause if BOTH dead)
|
||||
bool pausar_spawn = (hit_timer_per_player_[0] > 0.0F && hit_timer_per_player_[1] > 0.0F);
|
||||
stage_manager_->get_spawn_controller().update(delta_time, enemies_, pausar_spawn);
|
||||
bool pause_spawn = (hit_timer_per_player_[0] > 0.0F && hit_timer_per_player_[1] > 0.0F);
|
||||
stage_manager_->getSpawnController().update(delta_time, enemies_, pause_spawn);
|
||||
|
||||
// [NEW] Check stage completion (only when at least one player alive)
|
||||
bool algun_jugador_viu = (hit_timer_per_player_[0] == 0.0F || hit_timer_per_player_[1] == 0.0F);
|
||||
if (algun_jugador_viu) {
|
||||
auto& spawn_ctrl = stage_manager_->get_spawn_controller();
|
||||
auto& spawn_ctrl = stage_manager_->getSpawnController();
|
||||
if (spawn_ctrl.tots_enemics_destruits(enemies_)) {
|
||||
stage_manager_->stage_completat();
|
||||
Audio::get()->playSound(Defaults::Sound::GOOD_JOB_COMMANDER, Audio::Group::GAME);
|
||||
@@ -552,7 +552,7 @@ void GameScene::draw() {
|
||||
constexpr float scale = Defaults::Game::GameOverScreen::TEXT_SCALE;
|
||||
constexpr float spacing = Defaults::Game::GameOverScreen::TEXT_SPACING;
|
||||
|
||||
// Calcular centre de l'àrea de joc usant constants
|
||||
// Calcular centro de l'àrea de juego usant constants
|
||||
const SDL_FRect& play_area = Defaults::Zones::PLAYAREA;
|
||||
float centre_x = play_area.x + (play_area.w / 2.0F);
|
||||
float centre_y = play_area.y + (play_area.h / 2.0F);
|
||||
@@ -568,7 +568,7 @@ void GameScene::draw() {
|
||||
|
||||
switch (state) {
|
||||
case StageSystem::EstatStage::INIT_HUD: {
|
||||
// Calcular progrés de cada animació independent
|
||||
// Calcular progrés de cada animación independent
|
||||
float timer = stage_manager_->get_timer_transicio();
|
||||
float total_time = Defaults::Game::INIT_HUD_DURATION;
|
||||
float global_progress = 1.0F - (timer / total_time);
|
||||
@@ -596,7 +596,7 @@ void GameScene::draw() {
|
||||
|
||||
// Dibuixar elements animats
|
||||
if (rect_progress > 0.0F) {
|
||||
// [NOU] Reproduir so quan comença l'animació del rectangle
|
||||
// [NOU] Reproduir so cuando comença l'animación del rectangle
|
||||
if (!init_hud_rect_sound_played_) {
|
||||
Audio::get()->playSound(Defaults::Sound::INIT_HUD, Audio::Group::GAME);
|
||||
init_hud_rect_sound_played_ = true;
|
||||
@@ -609,7 +609,7 @@ void GameScene::draw() {
|
||||
dibuixar_marcador_animat(score_progress);
|
||||
}
|
||||
|
||||
// [MODIFICAT] Dibuixar naus amb progress independent
|
||||
// [MODIFICAT] Dibuixar naves con progress independent
|
||||
if (ship1_progress > 0.0F && match_config_.jugador1_actiu && !ships_[0].isHit()) {
|
||||
ships_[0].draw();
|
||||
}
|
||||
@@ -735,7 +735,7 @@ void GameScene::tocado(uint8_t player_id) {
|
||||
}
|
||||
|
||||
void GameScene::dibuixar_marges() const {
|
||||
// Dibuixar rectangle de la zona de joc
|
||||
// Dibuixar rectangle de la zona de juego
|
||||
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
||||
|
||||
// Coordenades dels cantons
|
||||
@@ -755,22 +755,22 @@ void GameScene::dibuixar_marcador() {
|
||||
// Construir text del marcador
|
||||
std::string text = buildScoreboard();
|
||||
|
||||
// Paràmetres de renderització
|
||||
// Parámetros de renderització
|
||||
const float scale = 0.85F;
|
||||
const float spacing = 0.0F;
|
||||
|
||||
// Calcular centre de la zona del marcador
|
||||
// Calcular centro de la zona del marcador
|
||||
const SDL_FRect& scoreboard = Defaults::Zones::SCOREBOARD;
|
||||
float centre_x = scoreboard.w / 2.0F;
|
||||
float centre_y = scoreboard.y + (scoreboard.h / 2.0F);
|
||||
|
||||
// Renderitzar centrat
|
||||
// Renderizar centrat
|
||||
text_.renderCentered(text, {.x = centre_x, .y = centre_y}, scale, spacing);
|
||||
}
|
||||
|
||||
void GameScene::dibuixar_marges_animat(float progress) const {
|
||||
// Animació seqüencial del rectangle amb efecte de "pinzell"
|
||||
// Dos pinzells comencen al centre superior i baixen pels laterals
|
||||
// Animación seqüencial del rectangle con efecte de "pinzell"
|
||||
// Dos pinzells comencen al centro superior i baixen por los laterals
|
||||
|
||||
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
||||
|
||||
@@ -792,11 +792,11 @@ void GameScene::dibuixar_marges_animat(float progress) const {
|
||||
if (eased_progress > 0.0F) {
|
||||
float phase1_progress = std::min(eased_progress / PHASE_1_END, 1.0F);
|
||||
|
||||
// Línia esquerra: creix des del centre cap a l'esquerra
|
||||
// Línia izquierda: creix des del centro hacia l'izquierda
|
||||
int x1_phase1 = static_cast<int>(cx - ((cx - x1) * phase1_progress));
|
||||
Rendering::linea(sdl_.getRenderer(), cx, y1, x1_phase1, y1);
|
||||
|
||||
// Línia dreta: creix des del centre cap a la dreta
|
||||
// Línia derecha: creix des del centro hacia la derecha
|
||||
int x2_phase1 = static_cast<int>(cx + ((x2 - cx) * phase1_progress));
|
||||
Rendering::linea(sdl_.getRenderer(), cx, y1, x2_phase1, y1);
|
||||
}
|
||||
@@ -805,11 +805,11 @@ void GameScene::dibuixar_marges_animat(float progress) const {
|
||||
if (eased_progress > PHASE_1_END) {
|
||||
float phase2_progress = std::min((eased_progress - PHASE_1_END) / (PHASE_2_END - PHASE_1_END), 1.0F);
|
||||
|
||||
// Línia esquerra: creix des de dalt cap a baix
|
||||
// Línia izquierda: creix desde dalt hacia baix
|
||||
int y2_phase2 = static_cast<int>(y1 + ((y2 - y1) * phase2_progress));
|
||||
Rendering::linea(sdl_.getRenderer(), x1, y1, x1, y2_phase2);
|
||||
|
||||
// Línia dreta: creix des de dalt cap a baix
|
||||
// Línia derecha: creix desde dalt hacia baix
|
||||
Rendering::linea(sdl_.getRenderer(), x2, y1, x2, y2_phase2);
|
||||
}
|
||||
|
||||
@@ -817,46 +817,46 @@ void GameScene::dibuixar_marges_animat(float progress) const {
|
||||
if (eased_progress > PHASE_2_END) {
|
||||
float phase3_progress = (eased_progress - PHASE_2_END) / (1.0F - PHASE_2_END);
|
||||
|
||||
// Línia esquerra: creix des de l'esquerra cap al centre
|
||||
// Línia izquierda: creix desde l'izquierda hacia el centro
|
||||
int x_left_phase3 = static_cast<int>(x1 + ((cx - x1) * phase3_progress));
|
||||
Rendering::linea(sdl_.getRenderer(), x1, y2, x_left_phase3, y2);
|
||||
|
||||
// Línia dreta: creix des de la dreta cap al centre
|
||||
// Línia derecha: creix desde la derecha hacia el centro
|
||||
int x_right_phase3 = static_cast<int>(x2 - ((x2 - cx) * phase3_progress));
|
||||
Rendering::linea(sdl_.getRenderer(), x2, y2, x_right_phase3, y2);
|
||||
}
|
||||
}
|
||||
|
||||
void GameScene::dibuixar_marcador_animat(float progress) {
|
||||
// Animació del marcador pujant des de baix amb easing
|
||||
// Animación del marcador pujant desde baix con easing
|
||||
|
||||
// Calcular progrés amb easing
|
||||
// Calcular progrés con easing
|
||||
float eased_progress = Easing::ease_out_quad(progress);
|
||||
|
||||
// Construir text
|
||||
std::string text = buildScoreboard();
|
||||
|
||||
// Paràmetres
|
||||
// Parámetros
|
||||
const float scale = 0.85F;
|
||||
const float spacing = 0.0F;
|
||||
|
||||
// Calcular centre de la zona del marcador
|
||||
// Calcular centro de la zona del marcador
|
||||
const SDL_FRect& scoreboard = Defaults::Zones::SCOREBOARD;
|
||||
float centre_x = scoreboard.w / 2.0F;
|
||||
float centre_y_final = scoreboard.y + (scoreboard.h / 2.0F);
|
||||
|
||||
// Posició Y inicial (offscreen, sota de la pantalla)
|
||||
// Posición Y inicial (offscreen, sota de la pantalla)
|
||||
auto centre_y_inicial = static_cast<float>(Defaults::Game::HEIGHT);
|
||||
|
||||
// Interpolació amb easing
|
||||
// Interpolació con easing
|
||||
float centre_y_animada = centre_y_inicial + ((centre_y_final - centre_y_inicial) * eased_progress);
|
||||
|
||||
// Renderitzar centrat en posició animada
|
||||
// Renderizar centrat en posición animada
|
||||
text_.renderCentered(text, {.x = centre_x, .y = centre_y_animada}, scale, spacing);
|
||||
}
|
||||
|
||||
Vec2 GameScene::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const {
|
||||
// Animació de la ship pujant des de baix amb easing
|
||||
// Animación de la ship pujant desde baix con easing
|
||||
// [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END)
|
||||
|
||||
// Aplicar easing (uniforme para ambas naves)
|
||||
@@ -864,16 +864,16 @@ Vec2 GameScene::calcular_posicio_nau_init_hud(float progress, uint8_t player_id)
|
||||
|
||||
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
||||
|
||||
// Calcular posició final segons player (reutilitza obtenir_punt_spawn)
|
||||
// Calcular posición final segons player (reutilitza obtenir_punt_spawn)
|
||||
Vec2 spawn_final = obtenir_punt_spawn(player_id);
|
||||
float x_final = spawn_final.x;
|
||||
float y_final = spawn_final.y;
|
||||
|
||||
// Y inicial: offscreen, 50px sota la zona de joc
|
||||
// Y inicial: offscreen, 50px sota la zona de juego
|
||||
float y_inicial = zona.y + zona.h + 50.0F;
|
||||
|
||||
// X no canvia (destí segons player_id)
|
||||
// Y interpola amb easing
|
||||
// Y interpola con easing
|
||||
float y_animada = y_inicial + ((y_final - y_inicial) * eased_progress);
|
||||
|
||||
return {.x = x_final, .y = y_animada};
|
||||
@@ -905,7 +905,7 @@ float GameScene::calcular_progress_rango(float global_progress, float ratio_init
|
||||
}
|
||||
|
||||
std::string GameScene::buildScoreboard() const {
|
||||
// Puntuació P1 (6 dígits) - mostrar zeros si inactiu
|
||||
// Puntuación P1 (6 dígits) - mostrar zeros si inactiu
|
||||
std::string score_p1;
|
||||
std::string vides_p1;
|
||||
if (match_config_.jugador1_actiu) {
|
||||
@@ -919,12 +919,12 @@ std::string GameScene::buildScoreboard() const {
|
||||
vides_p1 = "00";
|
||||
}
|
||||
|
||||
// Nivell (2 dígits)
|
||||
// Nivel (2 dígits)
|
||||
uint8_t stage_num = stage_manager_->get_stage_actual();
|
||||
std::string stage_str = (stage_num < 10) ? "0" + std::to_string(stage_num)
|
||||
: std::to_string(stage_num);
|
||||
|
||||
// Puntuació P2 (6 dígits) - mostrar zeros si inactiu
|
||||
// Puntuación P2 (6 dígits) - mostrar zeros si inactiu
|
||||
std::string score_p2;
|
||||
std::string vides_p2;
|
||||
if (match_config_.jugador2_actiu) {
|
||||
@@ -939,7 +939,7 @@ std::string GameScene::buildScoreboard() const {
|
||||
}
|
||||
|
||||
// Format: "123456 03 LEVEL 01 654321 02"
|
||||
// Nota: dos espais entre seccions, mantenir ambdós slots sempre visibles
|
||||
// Nota: dos espais entre seccions, mantenir ambdós slots siempre visibles
|
||||
return score_p1 + " " + vides_p1 + " LEVEL " + stage_str + " " + score_p2 + " " + vides_p2;
|
||||
}
|
||||
|
||||
@@ -947,13 +947,13 @@ void GameScene::detectar_col·lisions_bales_enemics() {
|
||||
// Amplificador per hitbox més generós (115%)
|
||||
constexpr float AMPLIFIER = Defaults::Game::COLLISION_BULLET_ENEMY_AMPLIFIER;
|
||||
|
||||
// Velocitat d'explosió reduïda per efecte suau
|
||||
// Velocidad de explosión reduïda per efecte suau
|
||||
constexpr float VELOCITAT_EXPLOSIO = 80.0F; // px/s (en lloc de 80.0f per defecte)
|
||||
|
||||
// Iterar per totes les bales i enemics
|
||||
// Iterar per todas las balas i enemigos
|
||||
for (auto& bullet : bullets_) {
|
||||
for (auto& enemy : enemies_) {
|
||||
// Comprovar col·lisió utilitzant la interfície genèrica
|
||||
// Comprovar colisión utilitzant la interfície genèrica
|
||||
if (Physics::check_collision(bullet, enemy, AMPLIFIER)) {
|
||||
// *** COL·LISIÓ DETECTADA ***
|
||||
|
||||
@@ -980,17 +980,17 @@ void GameScene::detectar_col·lisions_bales_enemics() {
|
||||
// 3. Create floating score number
|
||||
floating_score_manager_.crear(points, pos_enemic);
|
||||
|
||||
// 4. Destruir enemy (marca com inactiu)
|
||||
// 4. Destruir enemy (marca como inactiu)
|
||||
enemy.destruir();
|
||||
|
||||
// 2. Crear explosió de fragments
|
||||
// 2. Crear explosión de fragments
|
||||
Vec2 vel_enemic = enemy.getVelocityVector();
|
||||
debris_manager_.explode(
|
||||
enemy.getShape(), // Forma vectorial del pentàgon
|
||||
pos_enemic, // Posició central
|
||||
0.0F, // Angle (enemy té rotació interna)
|
||||
enemy.getShape(), // Forma vectorial del pentágono
|
||||
pos_enemic, // Posición central
|
||||
0.0F, // Angle (enemy té rotación interna)
|
||||
1.0F, // Escala normal
|
||||
VELOCITAT_EXPLOSIO, // 50 px/s (explosió suau)
|
||||
VELOCITAT_EXPLOSIO, // 50 px/s (explosión suau)
|
||||
enemy.getBrightness(), // Heredar brightness
|
||||
vel_enemic, // Heredar velocity
|
||||
enemy.get_drotacio(), // Heredar velocity angular (trayectorias curvas)
|
||||
@@ -1000,7 +1000,7 @@ void GameScene::detectar_col·lisions_bales_enemics() {
|
||||
// 3. Desactivar bullet
|
||||
bullet.desactivar();
|
||||
|
||||
// 4. Eixir del bucle intern (bullet només destrueix 1 enemy)
|
||||
// 4. Eixir del bucle intern (bullet solo destrueix 1 enemy)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1031,7 +1031,7 @@ void GameScene::detectar_col·lisio_naus_enemics() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Comprovar col·lisió utilitzant la interfície genèrica
|
||||
// Comprovar colisión utilitzant la interfície genèrica
|
||||
if (Physics::check_collision(ships_[i], enemy, AMPLIFIER)) {
|
||||
tocado(i); // Trigger death sequence for player i
|
||||
break; // Only one collision per player per frame
|
||||
@@ -1082,7 +1082,7 @@ void GameScene::detectar_col·lisions_bales_jugadors() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Comprovar col·lisió utilitzant la interfície genèrica
|
||||
// Comprovar colisión utilitzant la interfície genèrica
|
||||
if (Physics::check_collision(bullet, ships_[player_id], AMPLIFIER)) {
|
||||
// *** FRIENDLY FIRE HIT ***
|
||||
|
||||
@@ -1095,7 +1095,7 @@ void GameScene::detectar_col·lisions_bales_jugadors() {
|
||||
// Victim loses 1 life
|
||||
tocado(player_id);
|
||||
|
||||
// Attacker gains 1 life (no cap)
|
||||
// Attacker gains 1 life (no sin)
|
||||
lives_per_player_[bullet_owner]++;
|
||||
}
|
||||
|
||||
@@ -1187,7 +1187,7 @@ Vec2 GameScene::obtenir_punt_spawn(uint8_t player_id) const {
|
||||
|
||||
float x_ratio;
|
||||
if (match_config_.es_un_jugador()) {
|
||||
// Un sol player: spawn al centre (50%)
|
||||
// Un sol player: spawn al centro (50%)
|
||||
x_ratio = 0.5F;
|
||||
} else {
|
||||
// Dos jugadors: spawn a posicions separades
|
||||
|
||||
Reference in New Issue
Block a user