Fase 1c: rename d'escenes i sistema d'escenes
Tots els tipus, fitxers, namespace, enums i metodes relacionats amb
les escenes passen del catala a l'angles seguint el .clang-tidy:
Fitxers (renames git):
- source/game/escenes/escena_joc.{hpp,cpp} -> game/scenes/game_scene.{hpp,cpp}
- source/game/escenes/escena_titol.{hpp,cpp} -> game/scenes/title_scene.{hpp,cpp}
- source/game/escenes/escena_logo.{hpp,cpp} -> game/scenes/logo_scene.{hpp,cpp}
- source/core/system/context_escenes.hpp -> core/system/scene_context.hpp
- Carpeta game/escenes/ -> game/scenes/
Tipus (CamelCase):
- EscenaJoc -> GameScene
- EscenaTitol -> TitleScene
- EscenaLogo -> LogoScene
- ContextEscenes -> SceneContext
- Escena (enum class) -> SceneType
- Opcio -> Option
- EstatGameOver -> GameOverState
- EstatTitol -> TitleState
- EstatAnimacio -> AnimationState
- ConfigPartida -> MatchConfig
Namespace:
- GestorEscenes -> SceneManager
Valors d'enum SceneType:
- TITOL -> TITLE
- JOC -> GAME
- EIXIR -> EXIT
(LOGO mantingut)
Metodes (camelBack):
- executar -> run
- canviar_escena -> setNextScene
- escena_desti -> nextScene
- opcio (getter) -> option
- consumir_opcio -> consumeOption
- reset_opcio -> resetOption
- set_config_partida -> setMatchConfig
- get_config_partida -> getMatchConfig
Camps privats (lower_case_):
- escena_desti_ -> next_scene_
- opcio_ -> option_
- config_partida_ -> match_config_
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,81 +0,0 @@
|
|||||||
// context_escenes.hpp - Sistema de gestió d'escenes i context de transicions
|
|
||||||
// © 2025 Port a C++20
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/system/game_config.hpp"
|
|
||||||
|
|
||||||
namespace GestorEscenes {
|
|
||||||
|
|
||||||
// Context de transició entre escenes
|
|
||||||
// Conté l'escena destinació i opcions específiques per aquella escena
|
|
||||||
class ContextEscenes {
|
|
||||||
public:
|
|
||||||
// Tipus d'escena del joc
|
|
||||||
enum class Escena {
|
|
||||||
LOGO, // Pantalla d'inici (logo JAILGAMES)
|
|
||||||
TITOL, // Pantalla de títol amb menú
|
|
||||||
JOC, // Joc principal (Asteroids)
|
|
||||||
EIXIR // Sortir del programa
|
|
||||||
};
|
|
||||||
|
|
||||||
// Opcions específiques per a cada escena
|
|
||||||
enum class Opcio {
|
|
||||||
NONE, // Sense opcions especials (comportament per defecte)
|
|
||||||
JUMP_TO_TITLE_MAIN, // TITOL: Saltar directament a MAIN (starfield instantani)
|
|
||||||
// MODE_DEMO, // JOC: Mode demostració amb IA (futur)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructor inicial amb escena LOGO i sense opcions
|
|
||||||
ContextEscenes() = default;
|
|
||||||
|
|
||||||
// Canviar escena amb opció específica
|
|
||||||
void canviar_escena(Escena nova_escena, Opcio opcio = Opcio::NONE) {
|
|
||||||
escena_desti_ = nova_escena;
|
|
||||||
opcio_ = opcio;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consultar escena destinació
|
|
||||||
[[nodiscard]] auto escena_desti() const -> Escena {
|
|
||||||
return escena_desti_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consultar opció actual
|
|
||||||
[[nodiscard]] auto opcio() const -> Opcio {
|
|
||||||
return opcio_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consumir opció (retorna valor i reseteja a NONE)
|
|
||||||
// Utilitzar quan l'escena processa l'opció
|
|
||||||
[[nodiscard]] auto consumir_opcio() -> Opcio {
|
|
||||||
Opcio valor = opcio_;
|
|
||||||
opcio_ = Opcio::NONE;
|
|
||||||
return valor;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset opció a NONE (sense retornar valor)
|
|
||||||
void reset_opcio() {
|
|
||||||
opcio_ = Opcio::NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configurar partida abans de transicionar a JOC
|
|
||||||
void set_config_partida(const GameConfig::ConfigPartida& config) {
|
|
||||||
config_partida_ = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Obtenir configuració de partida (consumit per EscenaJoc)
|
|
||||||
[[nodiscard]] const GameConfig::ConfigPartida& get_config_partida() const {
|
|
||||||
return config_partida_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Escena escena_desti_{Escena::LOGO}; // Escena a la qual transicionar
|
|
||||||
Opcio opcio_{Opcio::NONE}; // Opció específica per l'escena
|
|
||||||
GameConfig::ConfigPartida config_partida_; // Configuració de partida (jugadors actius, mode)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Variable global inline per gestionar l'escena actual (backward compatibility)
|
|
||||||
// Sincronitzada amb context.escena_desti() pel Director
|
|
||||||
inline ContextEscenes::Escena actual = ContextEscenes::Escena::LOGO;
|
|
||||||
|
|
||||||
} // namespace GestorEscenes
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "context_escenes.hpp"
|
#include "scene_context.hpp"
|
||||||
#include "core/audio/audio.hpp"
|
#include "core/audio/audio.hpp"
|
||||||
#include "core/audio/audio_cache.hpp"
|
#include "core/audio/audio_cache.hpp"
|
||||||
#include "core/defaults.hpp"
|
#include "core/defaults.hpp"
|
||||||
@@ -17,9 +17,9 @@
|
|||||||
#include "core/resources/resource_helper.hpp"
|
#include "core/resources/resource_helper.hpp"
|
||||||
#include "core/resources/resource_loader.hpp"
|
#include "core/resources/resource_loader.hpp"
|
||||||
#include "core/utils/path_utils.hpp"
|
#include "core/utils/path_utils.hpp"
|
||||||
#include "game/escenes/escena_joc.hpp"
|
#include "game/scenes/game_scene.hpp"
|
||||||
#include "game/escenes/escena_logo.hpp"
|
#include "game/scenes/logo_scene.hpp"
|
||||||
#include "game/escenes/escena_titol.hpp"
|
#include "game/scenes/title_scene.hpp"
|
||||||
#include "game/options.hpp"
|
#include "game/options.hpp"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Using declarations per simplificar el codi
|
// Using declarations per simplificar el codi
|
||||||
using GestorEscenes::ContextEscenes;
|
using SceneManager::SceneContext;
|
||||||
using Escena = ContextEscenes::Escena;
|
using SceneType = SceneContext::SceneType;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Director::Director(std::vector<std::string> const& args) {
|
Director::Director(std::vector<std::string> const& args) {
|
||||||
@@ -238,35 +238,35 @@ auto Director::run() -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Crear context d'escenes
|
// Crear context d'escenes
|
||||||
ContextEscenes context;
|
SceneContext context;
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
context.canviar_escena(Escena::TITOL);
|
context.setNextScene(SceneType::TITLE);
|
||||||
#else
|
#else
|
||||||
context.canviar_escena(Escena::LOGO);
|
context.setNextScene(SceneType::LOGO);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Bucle principal de gestió d'escenes
|
// Bucle principal de gestió d'escenes
|
||||||
while (context.escena_desti() != Escena::EIXIR) {
|
while (context.nextScene() != SceneType::EXIT) {
|
||||||
// Sincronitzar GestorEscenes::actual amb context
|
// Sincronitzar SceneManager::actual amb context
|
||||||
// (altres sistemes encara poden llegir GestorEscenes::actual)
|
// (altres sistemes encara poden llegir SceneManager::actual)
|
||||||
GestorEscenes::actual = context.escena_desti();
|
SceneManager::actual = context.nextScene();
|
||||||
|
|
||||||
switch (context.escena_desti()) {
|
switch (context.nextScene()) {
|
||||||
case Escena::LOGO: {
|
case SceneType::LOGO: {
|
||||||
EscenaLogo logo(sdl, context);
|
LogoScene logo(sdl, context);
|
||||||
logo.executar();
|
logo.run();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Escena::TITOL: {
|
case SceneType::TITLE: {
|
||||||
EscenaTitol titol(sdl, context);
|
TitleScene titol(sdl, context);
|
||||||
titol.executar();
|
titol.run();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Escena::JOC: {
|
case SceneType::GAME: {
|
||||||
EscenaJoc joc(sdl, context);
|
GameScene joc(sdl, context);
|
||||||
joc.executar();
|
joc.run();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,8 +275,8 @@ auto Director::run() -> int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sincronitzar final amb GestorEscenes::actual
|
// Sincronitzar final amb SceneManager::actual
|
||||||
GestorEscenes::actual = Escena::EIXIR;
|
SceneManager::actual = SceneType::EXIT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ enum class Mode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Configuració d'una partida
|
// Configuració d'una partida
|
||||||
struct ConfigPartida {
|
struct MatchConfig {
|
||||||
bool jugador1_actiu{false}; // És actiu el jugador 1?
|
bool jugador1_actiu{false}; // És actiu el jugador 1?
|
||||||
bool jugador2_actiu{false}; // És actiu el jugador 2?
|
bool jugador2_actiu{false}; // És actiu el jugador 2?
|
||||||
Mode mode{Mode::NORMAL}; // Mode de joc
|
Mode mode{Mode::NORMAL}; // Mode de joc
|
||||||
|
|||||||
@@ -5,18 +5,18 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "context_escenes.hpp"
|
#include "scene_context.hpp"
|
||||||
#include "core/input/input.hpp"
|
#include "core/input/input.hpp"
|
||||||
#include "core/input/mouse.hpp"
|
#include "core/input/mouse.hpp"
|
||||||
#include "core/rendering/sdl_manager.hpp"
|
#include "core/rendering/sdl_manager.hpp"
|
||||||
|
|
||||||
// Using declarations per simplificar el codi
|
// Using declarations per simplificar el codi
|
||||||
using GestorEscenes::ContextEscenes;
|
using SceneManager::SceneContext;
|
||||||
using Escena = ContextEscenes::Escena;
|
using SceneType = SceneContext::SceneType;
|
||||||
|
|
||||||
namespace GlobalEvents {
|
namespace GlobalEvents {
|
||||||
|
|
||||||
bool handle(const SDL_Event& event, SDLManager& sdl, ContextEscenes& context) {
|
bool handle(const SDL_Event& event, SDLManager& sdl, SceneContext& context) {
|
||||||
// 1. Permitir que Input procese el evento (para hotplug de gamepads)
|
// 1. Permitir que Input procese el evento (para hotplug de gamepads)
|
||||||
auto event_msg = Input::get()->handleEvent(event);
|
auto event_msg = Input::get()->handleEvent(event);
|
||||||
if (!event_msg.empty()) {
|
if (!event_msg.empty()) {
|
||||||
@@ -25,8 +25,8 @@ bool handle(const SDL_Event& event, SDLManager& sdl, ContextEscenes& context) {
|
|||||||
|
|
||||||
// 2. Procesar SDL_EVENT_QUIT directamente (no es input de juego)
|
// 2. Procesar SDL_EVENT_QUIT directamente (no es input de juego)
|
||||||
if (event.type == SDL_EVENT_QUIT) {
|
if (event.type == SDL_EVENT_QUIT) {
|
||||||
context.canviar_escena(Escena::EIXIR);
|
context.setNextScene(SceneType::EXIT);
|
||||||
GestorEscenes::actual = Escena::EIXIR;
|
SceneManager::actual = SceneType::EXIT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +54,8 @@ bool handle(const SDL_Event& event, SDLManager& sdl, ContextEscenes& context) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case SDL_SCANCODE_ESCAPE:
|
case SDL_SCANCODE_ESCAPE:
|
||||||
context.canviar_escena(Escena::EIXIR);
|
context.setNextScene(SceneType::EXIT);
|
||||||
GestorEscenes::actual = Escena::EIXIR;
|
SceneManager::actual = SceneType::EXIT;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class SDLManager;
|
class SDLManager;
|
||||||
namespace GestorEscenes {
|
namespace SceneManager {
|
||||||
class ContextEscenes;
|
class SceneContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace GlobalEvents {
|
namespace GlobalEvents {
|
||||||
// Processa events globals (F1/F2/F3/ESC/QUIT)
|
// Processa events globals (F1/F2/F3/ESC/QUIT)
|
||||||
// Retorna true si l'event ha estat processat i no cal seguir processant-lo
|
// Retorna true si l'event ha estat processat i no cal seguir processant-lo
|
||||||
bool handle(const SDL_Event& event, SDLManager& sdl, GestorEscenes::ContextEscenes& context);
|
bool handle(const SDL_Event& event, SDLManager& sdl, SceneManager::SceneContext& context);
|
||||||
} // namespace GlobalEvents
|
} // namespace GlobalEvents
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
// context_escenes.hpp - Sistema de gestió d'escenes i context de transicions
|
||||||
|
// © 2025 Port a C++20
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/system/game_config.hpp"
|
||||||
|
|
||||||
|
namespace SceneManager {
|
||||||
|
|
||||||
|
// Context de transició entre escenes
|
||||||
|
// Conté l'escena destinació i opcions específiques per aquella escena
|
||||||
|
class SceneContext {
|
||||||
|
public:
|
||||||
|
// Tipus d'escena del joc
|
||||||
|
enum class SceneType {
|
||||||
|
LOGO, // Pantalla d'inici (logo JAILGAMES)
|
||||||
|
TITLE, // Pantalla de títol amb menú
|
||||||
|
GAME, // Joc principal (Asteroids)
|
||||||
|
EXIT // Sortir del programa
|
||||||
|
};
|
||||||
|
|
||||||
|
// Opcions específiques per a cada escena
|
||||||
|
enum class Option {
|
||||||
|
NONE, // Sense opcions especials (comportament per defecte)
|
||||||
|
JUMP_TO_TITLE_MAIN, // TITLE: Saltar directament a MAIN (starfield instantani)
|
||||||
|
// MODE_DEMO, // GAME: Mode demostració amb IA (futur)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Constructor inicial amb escena LOGO i sense opcions
|
||||||
|
SceneContext() = default;
|
||||||
|
|
||||||
|
// Canviar escena amb opció específica
|
||||||
|
void setNextScene(SceneType next_scene, Option option = Option::NONE) {
|
||||||
|
next_scene_ = next_scene;
|
||||||
|
option_ = option;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consultar escena destinació
|
||||||
|
[[nodiscard]] auto nextScene() const -> SceneType {
|
||||||
|
return next_scene_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consultar opció actual
|
||||||
|
[[nodiscard]] auto option() const -> Option {
|
||||||
|
return option_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consumir opció (retorna valor i reseteja a NONE)
|
||||||
|
// Utilitzar quan l'escena processa l'opció
|
||||||
|
[[nodiscard]] auto consumeOption() -> Option {
|
||||||
|
Option valor = option_;
|
||||||
|
option_ = Option::NONE;
|
||||||
|
return valor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset opció a NONE (sense retornar valor)
|
||||||
|
void resetOption() {
|
||||||
|
option_ = Option::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configurar partida abans de transicionar a GAME
|
||||||
|
void setMatchConfig(const GameConfig::MatchConfig& config) {
|
||||||
|
match_config_ = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtenir configuració de partida (consumit per GameScene)
|
||||||
|
[[nodiscard]] const GameConfig::MatchConfig& getMatchConfig() const {
|
||||||
|
return match_config_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SceneType next_scene_{SceneType::LOGO}; // SceneType a la qual transicionar
|
||||||
|
Option option_{Option::NONE}; // Opció específica per l'escena
|
||||||
|
GameConfig::MatchConfig match_config_; // Configuració de partida (jugadors actius, mode)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Variable global inline per gestionar l'escena actual (backward compatibility)
|
||||||
|
// Sincronitzada amb context.nextScene() pel Director
|
||||||
|
inline SceneContext::SceneType actual = SceneContext::SceneType::LOGO;
|
||||||
|
|
||||||
|
} // namespace SceneManager
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// © 1999 Visente i Sergi (versió Pascal)
|
// © 1999 Visente i Sergi (versió Pascal)
|
||||||
// © 2025 Port a C++20 amb SDL3
|
// © 2025 Port a C++20 amb SDL3
|
||||||
|
|
||||||
#include "escena_joc.hpp"
|
#include "game_scene.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@@ -18,16 +18,16 @@
|
|||||||
#include "core/math/easing.hpp"
|
#include "core/math/easing.hpp"
|
||||||
#include "core/physics/collision.hpp"
|
#include "core/physics/collision.hpp"
|
||||||
#include "core/rendering/line_renderer.hpp"
|
#include "core/rendering/line_renderer.hpp"
|
||||||
#include "core/system/context_escenes.hpp"
|
#include "core/system/scene_context.hpp"
|
||||||
#include "core/system/global_events.hpp"
|
#include "core/system/global_events.hpp"
|
||||||
#include "game/stage_system/stage_loader.hpp"
|
#include "game/stage_system/stage_loader.hpp"
|
||||||
|
|
||||||
// Using declarations per simplificar el codi
|
// Using declarations per simplificar el codi
|
||||||
using GestorEscenes::ContextEscenes;
|
using SceneManager::SceneContext;
|
||||||
using Escena = ContextEscenes::Escena;
|
using SceneType = SceneContext::SceneType;
|
||||||
using Opcio = ContextEscenes::Opcio;
|
using Option = SceneContext::Option;
|
||||||
|
|
||||||
EscenaJoc::EscenaJoc(SDLManager& sdl, ContextEscenes& context)
|
GameScene::GameScene(SDLManager& sdl, SceneContext& context)
|
||||||
: sdl_(sdl),
|
: sdl_(sdl),
|
||||||
context_(context),
|
context_(context),
|
||||||
debris_manager_(sdl.obte_renderer()),
|
debris_manager_(sdl.obte_renderer()),
|
||||||
@@ -35,18 +35,18 @@ EscenaJoc::EscenaJoc(SDLManager& sdl, ContextEscenes& context)
|
|||||||
text_(sdl.obte_renderer()),
|
text_(sdl.obte_renderer()),
|
||||||
init_hud_rect_sound_played_(false) {
|
init_hud_rect_sound_played_(false) {
|
||||||
// Recuperar configuració de partida des del context
|
// Recuperar configuració de partida des del context
|
||||||
config_partida_ = context_.get_config_partida();
|
match_config_ = context_.getMatchConfig();
|
||||||
|
|
||||||
// Debug output de la configuració
|
// Debug output de la configuració
|
||||||
std::cout << "[EscenaJoc] Configuració de partida - P1: "
|
std::cout << "[GameScene] Configuració de partida - P1: "
|
||||||
<< (config_partida_.jugador1_actiu ? "ACTIU" : "INACTIU")
|
<< (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU")
|
||||||
<< ", P2: "
|
<< ", P2: "
|
||||||
<< (config_partida_.jugador2_actiu ? "ACTIU" : "INACTIU")
|
<< (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU")
|
||||||
<< '\n';
|
<< '\n';
|
||||||
|
|
||||||
// Consumir opcions (preparació per MODE_DEMO futur)
|
// Consumir opcions (preparació per MODE_DEMO futur)
|
||||||
auto opcio = context_.consumir_opcio();
|
auto option = context_.consumeOption();
|
||||||
(void)opcio; // Suprimir warning de variable no usada
|
(void)option; // Suprimir warning de variable no usada
|
||||||
|
|
||||||
// Inicialitzar naus amb renderer (P1=ship.shp, P2=ship2.shp)
|
// Inicialitzar naus amb renderer (P1=ship.shp, P2=ship2.shp)
|
||||||
naus_[0] = Ship(sdl.obte_renderer(), "ship.shp"); // Jugador 1: nave estàndar
|
naus_[0] = Ship(sdl.obte_renderer(), "ship.shp"); // Jugador 1: nave estàndar
|
||||||
@@ -63,8 +63,8 @@ EscenaJoc::EscenaJoc(SDLManager& sdl, ContextEscenes& context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::executar() {
|
void GameScene::run() {
|
||||||
std::cout << "Escena Joc: Inicialitzant...\n";
|
std::cout << "SceneType Joc: Inicialitzant...\n";
|
||||||
|
|
||||||
// Inicialitzar estat del joc
|
// Inicialitzar estat del joc
|
||||||
init();
|
init();
|
||||||
@@ -72,7 +72,7 @@ void EscenaJoc::executar() {
|
|||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
Uint64 last_time = SDL_GetTicks();
|
Uint64 last_time = SDL_GetTicks();
|
||||||
|
|
||||||
while (GestorEscenes::actual == Escena::JOC) {
|
while (SceneManager::actual == SceneType::GAME) {
|
||||||
// Calcular delta_time real
|
// Calcular delta_time real
|
||||||
Uint64 current_time = SDL_GetTicks();
|
Uint64 current_time = SDL_GetTicks();
|
||||||
float delta_time = (current_time - last_time) / 1000.0F;
|
float delta_time = (current_time - last_time) / 1000.0F;
|
||||||
@@ -123,10 +123,10 @@ void EscenaJoc::executar() {
|
|||||||
sdl_.presenta();
|
sdl_.presenta();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Escena Joc: Finalitzant...\n";
|
std::cout << "SceneType Joc: Finalitzant...\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::init() {
|
void GameScene::init() {
|
||||||
// Inicialitzar generador de números aleatoris
|
// Inicialitzar generador de números aleatoris
|
||||||
// Basat en el codi Pascal original: line 376
|
// Basat en el codi Pascal original: line 376
|
||||||
std::srand(static_cast<unsigned>(std::time(nullptr)));
|
std::srand(static_cast<unsigned>(std::time(nullptr)));
|
||||||
@@ -135,7 +135,7 @@ void EscenaJoc::init() {
|
|||||||
if (!stage_config_) {
|
if (!stage_config_) {
|
||||||
stage_config_ = StageSystem::StageLoader::carregar("data/stages/stages.yaml");
|
stage_config_ = StageSystem::StageLoader::carregar("data/stages/stages.yaml");
|
||||||
if (!stage_config_) {
|
if (!stage_config_) {
|
||||||
std::cerr << "[EscenaJoc] Error: no s'ha pogut carregar stages.yaml" << '\n';
|
std::cerr << "[GameScene] Error: no s'ha pogut carregar stages.yaml" << '\n';
|
||||||
// Continue without stage system (will crash, but helps debugging)
|
// Continue without stage system (will crash, but helps debugging)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ void EscenaJoc::init() {
|
|||||||
// Initialize lives and game over state (independent lives per player)
|
// Initialize lives and game over state (independent lives per player)
|
||||||
vides_per_jugador_[0] = Defaults::Game::STARTING_LIVES;
|
vides_per_jugador_[0] = Defaults::Game::STARTING_LIVES;
|
||||||
vides_per_jugador_[1] = Defaults::Game::STARTING_LIVES;
|
vides_per_jugador_[1] = Defaults::Game::STARTING_LIVES;
|
||||||
estat_game_over_ = EstatGameOver::NONE;
|
estat_game_over_ = GameOverState::NONE;
|
||||||
continue_counter_ = 0;
|
continue_counter_ = 0;
|
||||||
continue_tick_timer_ = 0.0F;
|
continue_tick_timer_ = 0.0F;
|
||||||
continues_usados_ = 0;
|
continues_usados_ = 0;
|
||||||
@@ -172,19 +172,19 @@ void EscenaJoc::init() {
|
|||||||
|
|
||||||
// Inicialitzar naus segons configuració (només jugadors actius)
|
// Inicialitzar naus segons configuració (només jugadors actius)
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu;
|
bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu;
|
||||||
|
|
||||||
if (jugador_actiu) {
|
if (jugador_actiu) {
|
||||||
// Jugador actiu: init normalment
|
// Jugador actiu: init normalment
|
||||||
Vec2 spawn_pos = obtenir_punt_spawn(i);
|
Vec2 spawn_pos = obtenir_punt_spawn(i);
|
||||||
naus_[i].init(&spawn_pos, false); // No invulnerability at start
|
naus_[i].init(&spawn_pos, false); // No invulnerability at start
|
||||||
std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inicialitzat\n";
|
std::cout << "[GameScene] Jugador " << (i + 1) << " inicialitzat\n";
|
||||||
} else {
|
} else {
|
||||||
// Jugador inactiu: marcar com a mort permanent
|
// Jugador inactiu: marcar com a mort permanent
|
||||||
naus_[i].markHit();
|
naus_[i].markHit();
|
||||||
itocado_per_jugador_[i] = 999.0F; // Valor sentinella (permanent inactiu)
|
itocado_per_jugador_[i] = 999.0F; // Valor sentinella (permanent inactiu)
|
||||||
vides_per_jugador_[i] = 0; // Sense vides
|
vides_per_jugador_[i] = 0; // Sense vides
|
||||||
std::cout << "[EscenaJoc] Jugador " << (i + 1) << " inactiu\n";
|
std::cout << "[GameScene] Jugador " << (i + 1) << " inactiu\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,20 +208,20 @@ void EscenaJoc::init() {
|
|||||||
init_hud_rect_sound_played_ = false;
|
init_hud_rect_sound_played_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::update(float delta_time) {
|
void GameScene::update(float delta_time) {
|
||||||
// Processar disparos (state-based, no event-based)
|
// Processar disparos (state-based, no event-based)
|
||||||
if (estat_game_over_ == EstatGameOver::NONE) {
|
if (estat_game_over_ == GameOverState::NONE) {
|
||||||
auto* input = Input::get();
|
auto* input = Input::get();
|
||||||
|
|
||||||
// Jugador 1 dispara (només si està actiu)
|
// Jugador 1 dispara (només si està actiu)
|
||||||
if (config_partida_.jugador1_actiu) {
|
if (match_config_.jugador1_actiu) {
|
||||||
if (input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) {
|
if (input->checkActionPlayer1(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||||
disparar_bala(0);
|
disparar_bala(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Jugador 2 dispara (només si està actiu)
|
// Jugador 2 dispara (només si està actiu)
|
||||||
if (config_partida_.jugador2_actiu) {
|
if (match_config_.jugador2_actiu) {
|
||||||
if (input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) {
|
if (input->checkActionPlayer2(InputAction::SHOOT, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||||
disparar_bala(1);
|
disparar_bala(1);
|
||||||
}
|
}
|
||||||
@@ -232,17 +232,17 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
if (stage_manager_->get_estat() == StageSystem::EstatStage::PLAYING) {
|
if (stage_manager_->get_estat() == StageSystem::EstatStage::PLAYING) {
|
||||||
// Check if at least one player is alive and playing (game in progress)
|
// Check if at least one player is alive and playing (game in progress)
|
||||||
bool algun_jugador_viu = false;
|
bool algun_jugador_viu = false;
|
||||||
if (config_partida_.jugador1_actiu && itocado_per_jugador_[0] != 999.0F) {
|
if (match_config_.jugador1_actiu && itocado_per_jugador_[0] != 999.0F) {
|
||||||
algun_jugador_viu = true;
|
algun_jugador_viu = true;
|
||||||
}
|
}
|
||||||
if (config_partida_.jugador2_actiu && itocado_per_jugador_[1] != 999.0F) {
|
if (match_config_.jugador2_actiu && itocado_per_jugador_[1] != 999.0F) {
|
||||||
algun_jugador_viu = true;
|
algun_jugador_viu = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only allow join if there's an active game
|
// Only allow join if there's an active game
|
||||||
if (algun_jugador_viu) {
|
if (algun_jugador_viu) {
|
||||||
// P2 can join if not currently playing (never joined OR dead without lives)
|
// P2 can join if not currently playing (never joined OR dead without lives)
|
||||||
bool p2_no_juga = !config_partida_.jugador2_actiu || // Never joined
|
bool p2_no_juga = !match_config_.jugador2_actiu || // Never joined
|
||||||
itocado_per_jugador_[1] == 999.0F; // Dead without lives
|
itocado_per_jugador_[1] == 999.0F; // Dead without lives
|
||||||
|
|
||||||
if (p2_no_juga) {
|
if (p2_no_juga) {
|
||||||
@@ -252,7 +252,7 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// P1 can join if not currently playing (never joined OR dead without lives)
|
// P1 can join if not currently playing (never joined OR dead without lives)
|
||||||
bool p1_no_juga = !config_partida_.jugador1_actiu || // Never joined
|
bool p1_no_juga = !match_config_.jugador1_actiu || // Never joined
|
||||||
itocado_per_jugador_[0] == 999.0F; // Dead without lives
|
itocado_per_jugador_[0] == 999.0F; // Dead without lives
|
||||||
|
|
||||||
if (p1_no_juga) {
|
if (p1_no_juga) {
|
||||||
@@ -265,7 +265,7 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle CONTINUE screen
|
// Handle CONTINUE screen
|
||||||
if (estat_game_over_ == EstatGameOver::CONTINUE) {
|
if (estat_game_over_ == GameOverState::CONTINUE) {
|
||||||
actualitzar_continue(delta_time);
|
actualitzar_continue(delta_time);
|
||||||
processar_input_continue();
|
processar_input_continue();
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle final GAME OVER state
|
// Handle final GAME OVER state
|
||||||
if (estat_game_over_ == EstatGameOver::GAME_OVER) {
|
if (estat_game_over_ == GameOverState::GAME_OVER) {
|
||||||
// Game over: only update timer, enemies, bullets, and debris
|
// Game over: only update timer, enemies, bullets, and debris
|
||||||
game_over_timer_ -= delta_time;
|
game_over_timer_ -= delta_time;
|
||||||
|
|
||||||
@@ -290,8 +290,8 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
// Aturar música de joc abans de tornar al títol
|
// Aturar música de joc abans de tornar al títol
|
||||||
Audio::get()->stopMusic();
|
Audio::get()->stopMusic();
|
||||||
// Transició a pantalla de títol
|
// Transició a pantalla de títol
|
||||||
context_.canviar_escena(Escena::TITOL);
|
context_.setNextScene(SceneType::TITLE);
|
||||||
GestorEscenes::actual = Escena::TITOL;
|
SceneManager::actual = SceneType::TITLE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,11 +335,11 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
itocado_per_jugador_[i] = 999.0F;
|
itocado_per_jugador_[i] = 999.0F;
|
||||||
|
|
||||||
// Check if ALL ACTIVE players are dead (trigger continue screen)
|
// Check if ALL ACTIVE players are dead (trigger continue screen)
|
||||||
bool p1_dead = !config_partida_.jugador1_actiu || vides_per_jugador_[0] <= 0;
|
bool p1_dead = !match_config_.jugador1_actiu || vides_per_jugador_[0] <= 0;
|
||||||
bool p2_dead = !config_partida_.jugador2_actiu || vides_per_jugador_[1] <= 0;
|
bool p2_dead = !match_config_.jugador2_actiu || vides_per_jugador_[1] <= 0;
|
||||||
|
|
||||||
if (p1_dead && p2_dead) {
|
if (p1_dead && p2_dead) {
|
||||||
estat_game_over_ = EstatGameOver::CONTINUE;
|
estat_game_over_ = GameOverState::CONTINUE;
|
||||||
continue_counter_ = Defaults::Game::CONTINUE_COUNT_START;
|
continue_counter_ = Defaults::Game::CONTINUE_COUNT_START;
|
||||||
continue_tick_timer_ = Defaults::Game::CONTINUE_TICK_DURATION;
|
continue_tick_timer_ = Defaults::Game::CONTINUE_TICK_DURATION;
|
||||||
}
|
}
|
||||||
@@ -396,12 +396,12 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
Defaults::Game::INIT_HUD_SHIP2_RATIO_END);
|
Defaults::Game::INIT_HUD_SHIP2_RATIO_END);
|
||||||
|
|
||||||
// [MODIFICAT] Animar AMBAS naus con sus progress respectivos
|
// [MODIFICAT] Animar AMBAS naus con sus progress respectivos
|
||||||
if (config_partida_.jugador1_actiu && ship1_progress < 1.0F) {
|
if (match_config_.jugador1_actiu && ship1_progress < 1.0F) {
|
||||||
Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0);
|
Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0);
|
||||||
naus_[0].setCenter(pos_p1);
|
naus_[0].setCenter(pos_p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_partida_.jugador2_actiu && ship2_progress < 1.0F) {
|
if (match_config_.jugador2_actiu && ship2_progress < 1.0F) {
|
||||||
Vec2 pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1);
|
Vec2 pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1);
|
||||||
naus_[1].setCenter(pos_p2);
|
naus_[1].setCenter(pos_p2);
|
||||||
}
|
}
|
||||||
@@ -425,7 +425,7 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
|
|
||||||
// [NEW] Allow both ships movement and shooting during intro
|
// [NEW] Allow both ships movement and shooting during intro
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu;
|
bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu;
|
||||||
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players
|
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players
|
||||||
naus_[i].processInput(delta_time, i);
|
naus_[i].processInput(delta_time, i);
|
||||||
naus_[i].update(delta_time);
|
naus_[i].update(delta_time);
|
||||||
@@ -460,7 +460,7 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
|
|
||||||
// [EXISTING] Normal gameplay - update active players
|
// [EXISTING] Normal gameplay - update active players
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu;
|
bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu;
|
||||||
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players
|
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players
|
||||||
naus_[i].processInput(delta_time, i);
|
naus_[i].processInput(delta_time, i);
|
||||||
naus_[i].update(delta_time);
|
naus_[i].update(delta_time);
|
||||||
@@ -489,7 +489,7 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
|
|
||||||
// [NEW] Allow both ships movement and shooting during outro
|
// [NEW] Allow both ships movement and shooting during outro
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu;
|
bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu;
|
||||||
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players
|
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) { // Only active, alive players
|
||||||
naus_[i].processInput(delta_time, i);
|
naus_[i].processInput(delta_time, i);
|
||||||
naus_[i].update(delta_time);
|
naus_[i].update(delta_time);
|
||||||
@@ -508,9 +508,9 @@ void EscenaJoc::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::draw() {
|
void GameScene::draw() {
|
||||||
// Handle CONTINUE screen
|
// Handle CONTINUE screen
|
||||||
if (estat_game_over_ == EstatGameOver::CONTINUE) {
|
if (estat_game_over_ == GameOverState::CONTINUE) {
|
||||||
// Draw game background elements first
|
// Draw game background elements first
|
||||||
dibuixar_marges();
|
dibuixar_marges();
|
||||||
|
|
||||||
@@ -532,7 +532,7 @@ void EscenaJoc::draw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle final GAME OVER state
|
// Handle final GAME OVER state
|
||||||
if (estat_game_over_ == EstatGameOver::GAME_OVER) {
|
if (estat_game_over_ == GameOverState::GAME_OVER) {
|
||||||
// Game over: draw enemies, bullets, debris, and "GAME OVER" text
|
// Game over: draw enemies, bullets, debris, and "GAME OVER" text
|
||||||
dibuixar_marges();
|
dibuixar_marges();
|
||||||
|
|
||||||
@@ -610,11 +610,11 @@ void EscenaJoc::draw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [MODIFICAT] Dibuixar naus amb progress independent
|
// [MODIFICAT] Dibuixar naus amb progress independent
|
||||||
if (ship1_progress > 0.0F && config_partida_.jugador1_actiu && !naus_[0].isHit()) {
|
if (ship1_progress > 0.0F && match_config_.jugador1_actiu && !naus_[0].isHit()) {
|
||||||
naus_[0].draw();
|
naus_[0].draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ship2_progress > 0.0F && config_partida_.jugador2_actiu && !naus_[1].isHit()) {
|
if (ship2_progress > 0.0F && match_config_.jugador2_actiu && !naus_[1].isHit()) {
|
||||||
naus_[1].draw();
|
naus_[1].draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,7 +625,7 @@ void EscenaJoc::draw() {
|
|||||||
dibuixar_marges();
|
dibuixar_marges();
|
||||||
// [NEW] Draw both ships if active and alive
|
// [NEW] Draw both ships if active and alive
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu;
|
bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu;
|
||||||
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) {
|
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) {
|
||||||
naus_[i].draw();
|
naus_[i].draw();
|
||||||
}
|
}
|
||||||
@@ -650,7 +650,7 @@ void EscenaJoc::draw() {
|
|||||||
|
|
||||||
// [EXISTING] Normal rendering - active ships
|
// [EXISTING] Normal rendering - active ships
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu;
|
bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu;
|
||||||
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) {
|
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) {
|
||||||
naus_[i].draw();
|
naus_[i].draw();
|
||||||
}
|
}
|
||||||
@@ -673,7 +673,7 @@ void EscenaJoc::draw() {
|
|||||||
dibuixar_marges();
|
dibuixar_marges();
|
||||||
// [NEW] Draw both ships if active and alive
|
// [NEW] Draw both ships if active and alive
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
bool jugador_actiu = (i == 0) ? config_partida_.jugador1_actiu : config_partida_.jugador2_actiu;
|
bool jugador_actiu = (i == 0) ? match_config_.jugador1_actiu : match_config_.jugador2_actiu;
|
||||||
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) {
|
if (jugador_actiu && itocado_per_jugador_[i] == 0.0F) {
|
||||||
naus_[i].draw();
|
naus_[i].draw();
|
||||||
}
|
}
|
||||||
@@ -695,7 +695,7 @@ void EscenaJoc::draw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::tocado(uint8_t player_id) {
|
void GameScene::tocado(uint8_t player_id) {
|
||||||
// Death sequence: 3 phases
|
// Death sequence: 3 phases
|
||||||
// Phase 1: First call (itocado_per_jugador_[player_id] == 0) - trigger explosion
|
// Phase 1: First call (itocado_per_jugador_[player_id] == 0) - trigger explosion
|
||||||
// Phase 2: Animation (0 < itocado_ < 3.0s) - debris animation
|
// Phase 2: Animation (0 < itocado_ < 3.0s) - debris animation
|
||||||
@@ -734,7 +734,7 @@ void EscenaJoc::tocado(uint8_t player_id) {
|
|||||||
// Phase 3 is handled in update() when itocado_per_jugador_ >= DEATH_DURATION
|
// Phase 3 is handled in update() when itocado_per_jugador_ >= DEATH_DURATION
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::dibuixar_marges() const {
|
void GameScene::dibuixar_marges() const {
|
||||||
// Dibuixar rectangle de la zona de joc
|
// Dibuixar rectangle de la zona de joc
|
||||||
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
||||||
|
|
||||||
@@ -751,7 +751,7 @@ void EscenaJoc::dibuixar_marges() const {
|
|||||||
Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2); // Right
|
Rendering::linea(sdl_.obte_renderer(), x2, y1, x2, y2); // Right
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::dibuixar_marcador() {
|
void GameScene::dibuixar_marcador() {
|
||||||
// Construir text del marcador
|
// Construir text del marcador
|
||||||
std::string text = construir_marcador();
|
std::string text = construir_marcador();
|
||||||
|
|
||||||
@@ -768,7 +768,7 @@ void EscenaJoc::dibuixar_marcador() {
|
|||||||
text_.render_centered(text, {.x = centre_x, .y = centre_y}, escala, spacing);
|
text_.render_centered(text, {.x = centre_x, .y = centre_y}, escala, spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::dibuixar_marges_animat(float progress) const {
|
void GameScene::dibuixar_marges_animat(float progress) const {
|
||||||
// Animació seqüencial del rectangle amb efecte de "pinzell"
|
// Animació seqüencial del rectangle amb efecte de "pinzell"
|
||||||
// Dos pinzells comencen al centre superior i baixen pels laterals
|
// Dos pinzells comencen al centre superior i baixen pels laterals
|
||||||
|
|
||||||
@@ -827,7 +827,7 @@ void EscenaJoc::dibuixar_marges_animat(float progress) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::dibuixar_marcador_animat(float progress) {
|
void GameScene::dibuixar_marcador_animat(float progress) {
|
||||||
// Animació del marcador pujant des de baix amb easing
|
// Animació del marcador pujant des de baix amb easing
|
||||||
|
|
||||||
// Calcular progrés amb easing
|
// Calcular progrés amb easing
|
||||||
@@ -855,7 +855,7 @@ void EscenaJoc::dibuixar_marcador_animat(float progress) {
|
|||||||
text_.render_centered(text, {.x = centre_x, .y = centre_y_animada}, escala, spacing);
|
text_.render_centered(text, {.x = centre_x, .y = centre_y_animada}, escala, spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2 EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const {
|
Vec2 GameScene::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const {
|
||||||
// Animació de la nau pujant des de baix amb easing
|
// Animació de la nau pujant des de baix amb easing
|
||||||
// [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END)
|
// [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END)
|
||||||
|
|
||||||
@@ -879,7 +879,7 @@ Vec2 EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id)
|
|||||||
return {.x = x_final, .y = y_animada};
|
return {.x = x_final, .y = y_animada};
|
||||||
}
|
}
|
||||||
|
|
||||||
float EscenaJoc::calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const {
|
float GameScene::calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const {
|
||||||
// Convierte global_progress (0.0→1.0) a element_progress usando ventana [INIT, END]
|
// Convierte global_progress (0.0→1.0) a element_progress usando ventana [INIT, END]
|
||||||
//
|
//
|
||||||
// Casos:
|
// Casos:
|
||||||
@@ -904,11 +904,11 @@ float EscenaJoc::calcular_progress_rango(float global_progress, float ratio_init
|
|||||||
return (global_progress - ratio_init) / (ratio_end - ratio_init);
|
return (global_progress - ratio_init) / (ratio_end - ratio_init);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EscenaJoc::construir_marcador() const {
|
std::string GameScene::construir_marcador() const {
|
||||||
// Puntuació P1 (6 dígits) - mostrar zeros si inactiu
|
// Puntuació P1 (6 dígits) - mostrar zeros si inactiu
|
||||||
std::string score_p1;
|
std::string score_p1;
|
||||||
std::string vides_p1;
|
std::string vides_p1;
|
||||||
if (config_partida_.jugador1_actiu) {
|
if (match_config_.jugador1_actiu) {
|
||||||
score_p1 = std::to_string(puntuacio_per_jugador_[0]);
|
score_p1 = std::to_string(puntuacio_per_jugador_[0]);
|
||||||
score_p1 = std::string(6 - std::min(6, static_cast<int>(score_p1.length())), '0') + score_p1;
|
score_p1 = std::string(6 - std::min(6, static_cast<int>(score_p1.length())), '0') + score_p1;
|
||||||
vides_p1 = (vides_per_jugador_[0] < 10)
|
vides_p1 = (vides_per_jugador_[0] < 10)
|
||||||
@@ -927,7 +927,7 @@ std::string EscenaJoc::construir_marcador() const {
|
|||||||
// Puntuació P2 (6 dígits) - mostrar zeros si inactiu
|
// Puntuació P2 (6 dígits) - mostrar zeros si inactiu
|
||||||
std::string score_p2;
|
std::string score_p2;
|
||||||
std::string vides_p2;
|
std::string vides_p2;
|
||||||
if (config_partida_.jugador2_actiu) {
|
if (match_config_.jugador2_actiu) {
|
||||||
score_p2 = std::to_string(puntuacio_per_jugador_[1]);
|
score_p2 = std::to_string(puntuacio_per_jugador_[1]);
|
||||||
score_p2 = std::string(6 - std::min(6, static_cast<int>(score_p2.length())), '0') + score_p2;
|
score_p2 = std::string(6 - std::min(6, static_cast<int>(score_p2.length())), '0') + score_p2;
|
||||||
vides_p2 = (vides_per_jugador_[1] < 10)
|
vides_p2 = (vides_per_jugador_[1] < 10)
|
||||||
@@ -943,7 +943,7 @@ std::string EscenaJoc::construir_marcador() const {
|
|||||||
return score_p1 + " " + vides_p1 + " LEVEL " + stage_str + " " + score_p2 + " " + vides_p2;
|
return score_p1 + " " + vides_p1 + " LEVEL " + stage_str + " " + score_p2 + " " + vides_p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::detectar_col·lisions_bales_enemics() {
|
void GameScene::detectar_col·lisions_bales_enemics() {
|
||||||
// Amplificador per hitbox més generós (115%)
|
// Amplificador per hitbox més generós (115%)
|
||||||
constexpr float AMPLIFIER = Defaults::Game::COLLISION_BULLET_ENEMY_AMPLIFIER;
|
constexpr float AMPLIFIER = Defaults::Game::COLLISION_BULLET_ENEMY_AMPLIFIER;
|
||||||
|
|
||||||
@@ -1007,7 +1007,7 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::detectar_col·lisio_naus_enemics() {
|
void GameScene::detectar_col·lisio_naus_enemics() {
|
||||||
// Amplificador per hitbox generós (80%)
|
// Amplificador per hitbox generós (80%)
|
||||||
constexpr float AMPLIFIER = Defaults::Game::COLLISION_SHIP_ENEMY_AMPLIFIER;
|
constexpr float AMPLIFIER = Defaults::Game::COLLISION_SHIP_ENEMY_AMPLIFIER;
|
||||||
|
|
||||||
@@ -1040,7 +1040,7 @@ void EscenaJoc::detectar_col·lisio_naus_enemics() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::detectar_col·lisions_bales_jugadors() {
|
void GameScene::detectar_col·lisions_bales_jugadors() {
|
||||||
// Skip if friendly fire disabled
|
// Skip if friendly fire disabled
|
||||||
if (!Defaults::Game::FRIENDLY_FIRE_ENABLED) {
|
if (!Defaults::Game::FRIENDLY_FIRE_ENABLED) {
|
||||||
return;
|
return;
|
||||||
@@ -1076,8 +1076,8 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip inactive players
|
// Skip inactive players
|
||||||
bool jugador_actiu = (player_id == 0) ? config_partida_.jugador1_actiu
|
bool jugador_actiu = (player_id == 0) ? match_config_.jugador1_actiu
|
||||||
: config_partida_.jugador2_actiu;
|
: match_config_.jugador2_actiu;
|
||||||
if (!jugador_actiu) {
|
if (!jugador_actiu) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1113,7 +1113,7 @@ void EscenaJoc::detectar_col·lisions_bales_jugadors() {
|
|||||||
|
|
||||||
// [NEW] Stage system helper methods
|
// [NEW] Stage system helper methods
|
||||||
|
|
||||||
void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) {
|
void GameScene::dibuixar_missatge_stage(const std::string& missatge) {
|
||||||
constexpr float escala_base = 1.0F;
|
constexpr float escala_base = 1.0F;
|
||||||
constexpr float spacing = 2.0F;
|
constexpr float spacing = 2.0F;
|
||||||
|
|
||||||
@@ -1182,11 +1182,11 @@ void EscenaJoc::dibuixar_missatge_stage(const std::string& missatge) {
|
|||||||
// Helper methods for 2-player support
|
// Helper methods for 2-player support
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
Vec2 EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const {
|
Vec2 GameScene::obtenir_punt_spawn(uint8_t player_id) const {
|
||||||
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
||||||
|
|
||||||
float x_ratio;
|
float x_ratio;
|
||||||
if (config_partida_.es_un_jugador()) {
|
if (match_config_.es_un_jugador()) {
|
||||||
// Un sol jugador: spawn al centre (50%)
|
// Un sol jugador: spawn al centre (50%)
|
||||||
x_ratio = 0.5F;
|
x_ratio = 0.5F;
|
||||||
} else {
|
} else {
|
||||||
@@ -1201,7 +1201,7 @@ Vec2 EscenaJoc::obtenir_punt_spawn(uint8_t player_id) const {
|
|||||||
.y = zona.y + (zona.h * Defaults::Game::SPAWN_Y_RATIO)};
|
.y = zona.y + (zona.h * Defaults::Game::SPAWN_Y_RATIO)};
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::disparar_bala(uint8_t player_id) {
|
void GameScene::disparar_bala(uint8_t player_id) {
|
||||||
// Verificar que el jugador está vivo
|
// Verificar que el jugador está vivo
|
||||||
if (itocado_per_jugador_[player_id] > 0.0F) {
|
if (itocado_per_jugador_[player_id] > 0.0F) {
|
||||||
return;
|
return;
|
||||||
@@ -1234,14 +1234,14 @@ void EscenaJoc::disparar_bala(uint8_t player_id) {
|
|||||||
|
|
||||||
// ==================== CONTINUE & JOIN SYSTEM ====================
|
// ==================== CONTINUE & JOIN SYSTEM ====================
|
||||||
|
|
||||||
void EscenaJoc::check_and_apply_continue_timeout() {
|
void GameScene::check_and_apply_continue_timeout() {
|
||||||
if (continue_counter_ < 0) {
|
if (continue_counter_ < 0) {
|
||||||
estat_game_over_ = EstatGameOver::GAME_OVER;
|
estat_game_over_ = GameOverState::GAME_OVER;
|
||||||
game_over_timer_ = Defaults::Game::GAME_OVER_DURATION;
|
game_over_timer_ = Defaults::Game::GAME_OVER_DURATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::actualitzar_continue(float delta_time) {
|
void GameScene::actualitzar_continue(float delta_time) {
|
||||||
continue_tick_timer_ -= delta_time;
|
continue_tick_timer_ -= delta_time;
|
||||||
|
|
||||||
if (continue_tick_timer_ <= 0.0F) {
|
if (continue_tick_timer_ <= 0.0F) {
|
||||||
@@ -1252,13 +1252,13 @@ void EscenaJoc::actualitzar_continue(float delta_time) {
|
|||||||
check_and_apply_continue_timeout();
|
check_and_apply_continue_timeout();
|
||||||
|
|
||||||
// Play sound only if still in CONTINUE state (not transitioned to GAME_OVER)
|
// Play sound only if still in CONTINUE state (not transitioned to GAME_OVER)
|
||||||
if (estat_game_over_ == EstatGameOver::CONTINUE) {
|
if (estat_game_over_ == GameOverState::CONTINUE) {
|
||||||
Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME);
|
Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::processar_input_continue() {
|
void GameScene::processar_input_continue() {
|
||||||
auto* input = Input::get();
|
auto* input = Input::get();
|
||||||
|
|
||||||
// Check START for both players
|
// Check START for both players
|
||||||
@@ -1269,7 +1269,7 @@ void EscenaJoc::processar_input_continue() {
|
|||||||
// Check continue limit (skip if infinite continues)
|
// Check continue limit (skip if infinite continues)
|
||||||
if (!Defaults::Game::INFINITE_CONTINUES && continues_usados_ >= Defaults::Game::MAX_CONTINUES) {
|
if (!Defaults::Game::INFINITE_CONTINUES && continues_usados_ >= Defaults::Game::MAX_CONTINUES) {
|
||||||
// Max continues reached → final game over
|
// Max continues reached → final game over
|
||||||
estat_game_over_ = EstatGameOver::GAME_OVER;
|
estat_game_over_ = GameOverState::GAME_OVER;
|
||||||
game_over_timer_ = Defaults::Game::GAME_OVER_DURATION;
|
game_over_timer_ = Defaults::Game::GAME_OVER_DURATION;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1289,9 +1289,9 @@ void EscenaJoc::processar_input_continue() {
|
|||||||
|
|
||||||
// Activate player if not already
|
// Activate player if not already
|
||||||
if (player_to_revive == 0) {
|
if (player_to_revive == 0) {
|
||||||
config_partida_.jugador1_actiu = true;
|
match_config_.jugador1_actiu = true;
|
||||||
} else {
|
} else {
|
||||||
config_partida_.jugador2_actiu = true;
|
match_config_.jugador2_actiu = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spawn with invulnerability
|
// Spawn with invulnerability
|
||||||
@@ -1304,13 +1304,13 @@ void EscenaJoc::processar_input_continue() {
|
|||||||
puntuacio_per_jugador_[other_player] = 0;
|
puntuacio_per_jugador_[other_player] = 0;
|
||||||
vides_per_jugador_[other_player] = Defaults::Game::STARTING_LIVES;
|
vides_per_jugador_[other_player] = Defaults::Game::STARTING_LIVES;
|
||||||
itocado_per_jugador_[other_player] = 0.0F;
|
itocado_per_jugador_[other_player] = 0.0F;
|
||||||
config_partida_.jugador2_actiu = true;
|
match_config_.jugador2_actiu = true;
|
||||||
Vec2 spawn_pos2 = obtenir_punt_spawn(other_player);
|
Vec2 spawn_pos2 = obtenir_punt_spawn(other_player);
|
||||||
naus_[other_player].init(&spawn_pos2, true);
|
naus_[other_player].init(&spawn_pos2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resume game
|
// Resume game
|
||||||
estat_game_over_ = EstatGameOver::NONE;
|
estat_game_over_ = GameOverState::NONE;
|
||||||
continue_counter_ = 0;
|
continue_counter_ = 0;
|
||||||
continue_tick_timer_ = 0.0F;
|
continue_tick_timer_ = 0.0F;
|
||||||
|
|
||||||
@@ -1333,7 +1333,7 @@ void EscenaJoc::processar_input_continue() {
|
|||||||
check_and_apply_continue_timeout();
|
check_and_apply_continue_timeout();
|
||||||
|
|
||||||
// Play sound only if still in CONTINUE state
|
// Play sound only if still in CONTINUE state
|
||||||
if (estat_game_over_ == EstatGameOver::CONTINUE) {
|
if (estat_game_over_ == GameOverState::CONTINUE) {
|
||||||
Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME);
|
Audio::get()->playSound(Defaults::Sound::CONTINUE, Audio::Group::GAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1342,7 +1342,7 @@ void EscenaJoc::processar_input_continue() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::dibuixar_continue() {
|
void GameScene::dibuixar_continue() {
|
||||||
const SDL_FRect& play_area = Defaults::Zones::PLAYAREA;
|
const SDL_FRect& play_area = Defaults::Zones::PLAYAREA;
|
||||||
constexpr float spacing = 4.0F;
|
constexpr float spacing = 4.0F;
|
||||||
|
|
||||||
@@ -1377,12 +1377,12 @@ void EscenaJoc::dibuixar_continue() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::unir_jugador(uint8_t player_id) {
|
void GameScene::unir_jugador(uint8_t player_id) {
|
||||||
// Activate player
|
// Activate player
|
||||||
if (player_id == 0) {
|
if (player_id == 0) {
|
||||||
config_partida_.jugador1_actiu = true;
|
match_config_.jugador1_actiu = true;
|
||||||
} else {
|
} else {
|
||||||
config_partida_.jugador2_actiu = true;
|
match_config_.jugador2_actiu = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset stats
|
// Reset stats
|
||||||
@@ -1396,5 +1396,5 @@ void EscenaJoc::unir_jugador(uint8_t player_id) {
|
|||||||
|
|
||||||
// No visual message, just spawn (per user requirement)
|
// No visual message, just spawn (per user requirement)
|
||||||
|
|
||||||
std::cout << "[EscenaJoc] Jugador " << (int)(player_id + 1) << " s'ha unit a la partida!" << '\n';
|
std::cout << "[GameScene] Jugador " << (int)(player_id + 1) << " s'ha unit a la partida!" << '\n';
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include "core/graphics/vector_text.hpp"
|
#include "core/graphics/vector_text.hpp"
|
||||||
#include "core/rendering/sdl_manager.hpp"
|
#include "core/rendering/sdl_manager.hpp"
|
||||||
#include "core/system/context_escenes.hpp"
|
#include "core/system/scene_context.hpp"
|
||||||
#include "core/system/game_config.hpp"
|
#include "core/system/game_config.hpp"
|
||||||
#include "core/types.hpp"
|
#include "core/types.hpp"
|
||||||
#include "game/constants.hpp"
|
#include "game/constants.hpp"
|
||||||
@@ -25,27 +25,27 @@
|
|||||||
#include "game/stage_system/stage_manager.hpp"
|
#include "game/stage_system/stage_manager.hpp"
|
||||||
|
|
||||||
// Game over state machine
|
// Game over state machine
|
||||||
enum class EstatGameOver {
|
enum class GameOverState {
|
||||||
NONE, // Normal gameplay
|
NONE, // Normal gameplay
|
||||||
CONTINUE, // Continue countdown screen (9→0)
|
CONTINUE, // Continue countdown screen (9→0)
|
||||||
GAME_OVER // Final game over (returning to title)
|
GAME_OVER // Final game over (returning to title)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Classe principal del joc (escena)
|
// Classe principal del joc (escena)
|
||||||
class EscenaJoc {
|
class GameScene {
|
||||||
public:
|
public:
|
||||||
explicit EscenaJoc(SDLManager& sdl, GestorEscenes::ContextEscenes& context);
|
explicit GameScene(SDLManager& sdl, SceneManager::SceneContext& context);
|
||||||
~EscenaJoc() = default;
|
~GameScene() = default;
|
||||||
|
|
||||||
void executar(); // Bucle principal de l'escena
|
void run(); // Bucle principal de l'escena
|
||||||
void init();
|
void init();
|
||||||
void update(float delta_time);
|
void update(float delta_time);
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDLManager& sdl_;
|
SDLManager& sdl_;
|
||||||
GestorEscenes::ContextEscenes& context_;
|
SceneManager::SceneContext& context_;
|
||||||
GameConfig::ConfigPartida config_partida_; // Configuració de jugadors actius
|
GameConfig::MatchConfig match_config_; // Configuració de jugadors actius
|
||||||
|
|
||||||
// Efectes visuals
|
// Efectes visuals
|
||||||
Effects::DebrisManager debris_manager_;
|
Effects::DebrisManager debris_manager_;
|
||||||
@@ -59,7 +59,7 @@ class EscenaJoc {
|
|||||||
|
|
||||||
// Lives and game over system
|
// Lives and game over system
|
||||||
std::array<int, 2> vides_per_jugador_; // [0]=P1, [1]=P2
|
std::array<int, 2> vides_per_jugador_; // [0]=P1, [1]=P2
|
||||||
EstatGameOver estat_game_over_; // Game over state machine (NONE, CONTINUE, GAME_OVER)
|
GameOverState estat_game_over_; // Game over state machine (NONE, CONTINUE, GAME_OVER)
|
||||||
int continue_counter_; // Continue countdown (9→0)
|
int continue_counter_; // Continue countdown (9→0)
|
||||||
float continue_tick_timer_; // Timer for countdown tick (1.0s)
|
float continue_tick_timer_; // Timer for countdown tick (1.0s)
|
||||||
int continues_usados_; // Continues used this game (0-3 max)
|
int continues_usados_; // Continues used this game (0-3 max)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// escena_logo.cpp - Implementació de l'escena logo
|
// escena_logo.cpp - Implementació de l'escena logo
|
||||||
// © 2025 Port a C++20
|
// © 2025 Port a C++20
|
||||||
|
|
||||||
#include "escena_logo.hpp"
|
#include "logo_scene.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
@@ -14,13 +14,13 @@
|
|||||||
#include "core/input/input.hpp"
|
#include "core/input/input.hpp"
|
||||||
#include "core/input/mouse.hpp"
|
#include "core/input/mouse.hpp"
|
||||||
#include "core/rendering/shape_renderer.hpp"
|
#include "core/rendering/shape_renderer.hpp"
|
||||||
#include "core/system/context_escenes.hpp"
|
#include "core/system/scene_context.hpp"
|
||||||
#include "core/system/global_events.hpp"
|
#include "core/system/global_events.hpp"
|
||||||
|
|
||||||
// Using declarations per simplificar el codi
|
// Using declarations per simplificar el codi
|
||||||
using GestorEscenes::ContextEscenes;
|
using SceneManager::SceneContext;
|
||||||
using Escena = ContextEscenes::Escena;
|
using SceneType = SceneContext::SceneType;
|
||||||
using Opcio = ContextEscenes::Opcio;
|
using Option = SceneContext::Option;
|
||||||
|
|
||||||
// Helper: calcular el progrés individual d'una lletra
|
// Helper: calcular el progrés individual d'una lletra
|
||||||
// en funció del progrés global (efecte seqüencial)
|
// en funció del progrés global (efecte seqüencial)
|
||||||
@@ -45,35 +45,35 @@ static float calcular_progress_letra(size_t letra_index, size_t num_letras, floa
|
|||||||
return (global_progress - start) / (end - start);
|
return (global_progress - start) / (end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
EscenaLogo::EscenaLogo(SDLManager& sdl, ContextEscenes& context)
|
LogoScene::LogoScene(SDLManager& sdl, SceneContext& context)
|
||||||
: sdl_(sdl),
|
: sdl_(sdl),
|
||||||
context_(context),
|
context_(context),
|
||||||
estat_actual_(EstatAnimacio::PRE_ANIMATION),
|
estat_actual_(AnimationState::PRE_ANIMATION),
|
||||||
temps_estat_actual_(0.0F),
|
temps_estat_actual_(0.0F),
|
||||||
debris_manager_(std::make_unique<Effects::DebrisManager>(sdl.obte_renderer())),
|
debris_manager_(std::make_unique<Effects::DebrisManager>(sdl.obte_renderer())),
|
||||||
lletra_explosio_index_(0),
|
lletra_explosio_index_(0),
|
||||||
temps_des_ultima_explosio_(0.0F) {
|
temps_des_ultima_explosio_(0.0F) {
|
||||||
std::cout << "Escena Logo: Inicialitzant...\n";
|
std::cout << "SceneType Logo: Inicialitzant...\n";
|
||||||
|
|
||||||
// Consumir opcions (LOGO no processa opcions actualment)
|
// Consumir opcions (LOGO no processa opcions actualment)
|
||||||
auto opcio = context_.consumir_opcio();
|
auto option = context_.consumeOption();
|
||||||
(void)opcio; // Suprimir warning
|
(void)option; // Suprimir warning
|
||||||
|
|
||||||
so_reproduit_.fill(false); // Inicialitzar seguiment de sons
|
so_reproduit_.fill(false); // Inicialitzar seguiment de sons
|
||||||
inicialitzar_lletres();
|
inicialitzar_lletres();
|
||||||
}
|
}
|
||||||
|
|
||||||
EscenaLogo::~EscenaLogo() {
|
LogoScene::~LogoScene() {
|
||||||
// Aturar tots els sons i la música
|
// Aturar tots els sons i la música
|
||||||
Audio::get()->stopAllSounds();
|
Audio::get()->stopAllSounds();
|
||||||
std::cout << "Escena Logo: Sons aturats\n";
|
std::cout << "SceneType Logo: Sons aturats\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaLogo::executar() {
|
void LogoScene::run() {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
Uint64 last_time = SDL_GetTicks();
|
Uint64 last_time = SDL_GetTicks();
|
||||||
|
|
||||||
while (GestorEscenes::actual == Escena::LOGO) {
|
while (SceneManager::actual == SceneType::LOGO) {
|
||||||
// Calcular delta_time real
|
// Calcular delta_time real
|
||||||
Uint64 current_time = SDL_GetTicks();
|
Uint64 current_time = SDL_GetTicks();
|
||||||
float delta_time = (current_time - last_time) / 1000.0F;
|
float delta_time = (current_time - last_time) / 1000.0F;
|
||||||
@@ -120,10 +120,10 @@ void EscenaLogo::executar() {
|
|||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Escena Logo: Finalitzant...\n";
|
std::cout << "SceneType Logo: Finalitzant...\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaLogo::inicialitzar_lletres() {
|
void LogoScene::inicialitzar_lletres() {
|
||||||
using namespace Graphics;
|
using namespace Graphics;
|
||||||
|
|
||||||
// Llista de fitxers .shp (A repetida per a les dues A's)
|
// Llista de fitxers .shp (A repetida per a les dues A's)
|
||||||
@@ -144,7 +144,7 @@ void EscenaLogo::inicialitzar_lletres() {
|
|||||||
for (const auto& fitxer : fitxers) {
|
for (const auto& fitxer : fitxers) {
|
||||||
auto forma = ShapeLoader::load(fitxer);
|
auto forma = ShapeLoader::load(fitxer);
|
||||||
if (!forma || !forma->es_valida()) {
|
if (!forma || !forma->es_valida()) {
|
||||||
std::cerr << "[EscenaLogo] Error carregant " << fitxer << '\n';
|
std::cerr << "[LogoScene] Error carregant " << fitxer << '\n';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,16 +198,16 @@ void EscenaLogo::inicialitzar_lletres() {
|
|||||||
x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES;
|
x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[EscenaLogo] " << lletres_.size()
|
std::cout << "[LogoScene] " << lletres_.size()
|
||||||
<< " lletres carregades, ancho total: " << ancho_total << " px\n";
|
<< " lletres carregades, ancho total: " << ancho_total << " px\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaLogo::canviar_estat(EstatAnimacio nou_estat) {
|
void LogoScene::canviar_estat(AnimationState nou_estat) {
|
||||||
estat_actual_ = nou_estat;
|
estat_actual_ = nou_estat;
|
||||||
temps_estat_actual_ = 0.0F; // Reset temps
|
temps_estat_actual_ = 0.0F; // Reset temps
|
||||||
|
|
||||||
// Inicialitzar estat d'explosió
|
// Inicialitzar estat d'explosió
|
||||||
if (nou_estat == EstatAnimacio::EXPLOSION) {
|
if (nou_estat == AnimationState::EXPLOSION) {
|
||||||
lletra_explosio_index_ = 0;
|
lletra_explosio_index_ = 0;
|
||||||
temps_des_ultima_explosio_ = 0.0F;
|
temps_des_ultima_explosio_ = 0.0F;
|
||||||
|
|
||||||
@@ -219,20 +219,20 @@ void EscenaLogo::canviar_estat(EstatAnimacio nou_estat) {
|
|||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
std::mt19937 g(rd());
|
std::mt19937 g(rd());
|
||||||
std::shuffle(ordre_explosio_.begin(), ordre_explosio_.end(), g);
|
std::shuffle(ordre_explosio_.begin(), ordre_explosio_.end(), g);
|
||||||
} else if (nou_estat == EstatAnimacio::POST_EXPLOSION) {
|
} else if (nou_estat == AnimationState::POST_EXPLOSION) {
|
||||||
Audio::get()->playMusic("title.ogg");
|
Audio::get()->playMusic("title.ogg");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[EscenaLogo] Canvi a estat: " << static_cast<int>(nou_estat)
|
std::cout << "[LogoScene] Canvi a estat: " << static_cast<int>(nou_estat)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EscenaLogo::totes_lletres_completes() const {
|
bool LogoScene::totes_lletres_completes() const {
|
||||||
// Quan global_progress = 1.0, totes les lletres tenen letra_progress = 1.0
|
// Quan global_progress = 1.0, totes les lletres tenen letra_progress = 1.0
|
||||||
return temps_estat_actual_ >= DURACIO_ZOOM;
|
return temps_estat_actual_ >= DURACIO_ZOOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaLogo::actualitzar_explosions(float delta_time) {
|
void LogoScene::actualitzar_explosions(float delta_time) {
|
||||||
temps_des_ultima_explosio_ += delta_time;
|
temps_des_ultima_explosio_ += delta_time;
|
||||||
|
|
||||||
// Comprovar si és el moment d'explotar la següent lletra
|
// Comprovar si és el moment d'explotar la següent lletra
|
||||||
@@ -252,29 +252,29 @@ void EscenaLogo::actualitzar_explosions(float delta_time) {
|
|||||||
{.x = 0.0F, .y = 0.0F} // Sense velocitat (per defecte)
|
{.x = 0.0F, .y = 0.0F} // Sense velocitat (per defecte)
|
||||||
);
|
);
|
||||||
|
|
||||||
std::cout << "[EscenaLogo] Explota lletra " << lletra_explosio_index_ << "\n";
|
std::cout << "[LogoScene] Explota lletra " << lletra_explosio_index_ << "\n";
|
||||||
|
|
||||||
// Passar a la següent lletra
|
// Passar a la següent lletra
|
||||||
lletra_explosio_index_++;
|
lletra_explosio_index_++;
|
||||||
temps_des_ultima_explosio_ = 0.0F;
|
temps_des_ultima_explosio_ = 0.0F;
|
||||||
} else {
|
} else {
|
||||||
// Totes les lletres han explotat, transició a POST_EXPLOSION
|
// Totes les lletres han explotat, transició a POST_EXPLOSION
|
||||||
canviar_estat(EstatAnimacio::POST_EXPLOSION);
|
canviar_estat(AnimationState::POST_EXPLOSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaLogo::update(float delta_time) {
|
void LogoScene::update(float delta_time) {
|
||||||
temps_estat_actual_ += delta_time;
|
temps_estat_actual_ += delta_time;
|
||||||
|
|
||||||
switch (estat_actual_) {
|
switch (estat_actual_) {
|
||||||
case EstatAnimacio::PRE_ANIMATION:
|
case AnimationState::PRE_ANIMATION:
|
||||||
if (temps_estat_actual_ >= DURACIO_PRE) {
|
if (temps_estat_actual_ >= DURACIO_PRE) {
|
||||||
canviar_estat(EstatAnimacio::ANIMATION);
|
canviar_estat(AnimationState::ANIMATION);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EstatAnimacio::ANIMATION: {
|
case AnimationState::ANIMATION: {
|
||||||
// Reproduir so per cada lletra quan comença a aparèixer
|
// Reproduir so per cada lletra quan comença a aparèixer
|
||||||
float global_progress = std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F);
|
float global_progress = std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F);
|
||||||
|
|
||||||
@@ -295,55 +295,55 @@ void EscenaLogo::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (totes_lletres_completes()) {
|
if (totes_lletres_completes()) {
|
||||||
canviar_estat(EstatAnimacio::POST_ANIMATION);
|
canviar_estat(AnimationState::POST_ANIMATION);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EstatAnimacio::POST_ANIMATION:
|
case AnimationState::POST_ANIMATION:
|
||||||
if (temps_estat_actual_ >= DURACIO_POST_ANIMATION) {
|
if (temps_estat_actual_ >= DURACIO_POST_ANIMATION) {
|
||||||
canviar_estat(EstatAnimacio::EXPLOSION);
|
canviar_estat(AnimationState::EXPLOSION);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EstatAnimacio::EXPLOSION:
|
case AnimationState::EXPLOSION:
|
||||||
actualitzar_explosions(delta_time);
|
actualitzar_explosions(delta_time);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EstatAnimacio::POST_EXPLOSION:
|
case AnimationState::POST_EXPLOSION:
|
||||||
if (temps_estat_actual_ >= DURACIO_POST_EXPLOSION) {
|
if (temps_estat_actual_ >= DURACIO_POST_EXPLOSION) {
|
||||||
// Transició a pantalla de títol
|
// Transició a pantalla de títol
|
||||||
context_.canviar_escena(Escena::TITOL);
|
context_.setNextScene(SceneType::TITLE);
|
||||||
GestorEscenes::actual = Escena::TITOL;
|
SceneManager::actual = SceneType::TITLE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar botones de skip (SHOOT P1/P2)
|
// Verificar botones de skip (SHOOT P1/P2)
|
||||||
if (checkSkipButtonPressed()) {
|
if (checkSkipButtonPressed()) {
|
||||||
context_.canviar_escena(Escena::TITOL, Opcio::JUMP_TO_TITLE_MAIN);
|
context_.setNextScene(SceneType::TITLE, Option::JUMP_TO_TITLE_MAIN);
|
||||||
GestorEscenes::actual = Escena::TITOL;
|
SceneManager::actual = SceneType::TITLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualitzar animacions de debris
|
// Actualitzar animacions de debris
|
||||||
debris_manager_->update(delta_time);
|
debris_manager_->update(delta_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaLogo::draw() {
|
void LogoScene::draw() {
|
||||||
// Fons negre
|
// Fons negre
|
||||||
sdl_.neteja(0, 0, 0);
|
sdl_.neteja(0, 0, 0);
|
||||||
|
|
||||||
// PRE_ANIMATION: Només pantalla negra
|
// PRE_ANIMATION: Només pantalla negra
|
||||||
if (estat_actual_ == EstatAnimacio::PRE_ANIMATION) {
|
if (estat_actual_ == AnimationState::PRE_ANIMATION) {
|
||||||
sdl_.presenta();
|
sdl_.presenta();
|
||||||
return; // No renderitzar lletres
|
return; // No renderitzar lletres
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANIMATION o POST_ANIMATION: Dibuixar lletres amb animació
|
// ANIMATION o POST_ANIMATION: Dibuixar lletres amb animació
|
||||||
if (estat_actual_ == EstatAnimacio::ANIMATION ||
|
if (estat_actual_ == AnimationState::ANIMATION ||
|
||||||
estat_actual_ == EstatAnimacio::POST_ANIMATION) {
|
estat_actual_ == AnimationState::POST_ANIMATION) {
|
||||||
float global_progress =
|
float global_progress =
|
||||||
(estat_actual_ == EstatAnimacio::ANIMATION)
|
(estat_actual_ == AnimationState::ANIMATION)
|
||||||
? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F)
|
? std::min(temps_estat_actual_ / DURACIO_ZOOM, 1.0F)
|
||||||
: 1.0F; // POST: mantenir al 100%
|
: 1.0F; // POST: mantenir al 100%
|
||||||
|
|
||||||
@@ -384,7 +384,7 @@ void EscenaLogo::draw() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EXPLOSION: Dibuixar només lletres que encara no han explotat
|
// EXPLOSION: Dibuixar només lletres que encara no han explotat
|
||||||
if (estat_actual_ == EstatAnimacio::EXPLOSION) {
|
if (estat_actual_ == AnimationState::EXPLOSION) {
|
||||||
// Crear conjunt de lletres ja explotades
|
// Crear conjunt de lletres ja explotades
|
||||||
std::set<size_t> explotades;
|
std::set<size_t> explotades;
|
||||||
for (size_t i = 0; i < lletra_explosio_index_; i++) {
|
for (size_t i = 0; i < lletra_explosio_index_; i++) {
|
||||||
@@ -415,10 +415,10 @@ void EscenaLogo::draw() {
|
|||||||
sdl_.presenta();
|
sdl_.presenta();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto EscenaLogo::checkSkipButtonPressed() -> bool {
|
auto LogoScene::checkSkipButtonPressed() -> bool {
|
||||||
return Input::get()->checkAnyPlayerAction(ARCADE_BUTTONS);
|
return Input::get()->checkAnyPlayerAction(ARCADE_BUTTONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaLogo::processar_events(const SDL_Event& event) {
|
void LogoScene::processar_events(const SDL_Event& event) {
|
||||||
// No procesar eventos genéricos aquí - la lógica se movió a update()
|
// No procesar eventos genéricos aquí - la lógica se movió a update()
|
||||||
}
|
}
|
||||||
@@ -14,19 +14,19 @@
|
|||||||
#include "core/graphics/shape.hpp"
|
#include "core/graphics/shape.hpp"
|
||||||
#include "core/input/input_types.hpp"
|
#include "core/input/input_types.hpp"
|
||||||
#include "core/rendering/sdl_manager.hpp"
|
#include "core/rendering/sdl_manager.hpp"
|
||||||
#include "core/system/context_escenes.hpp"
|
#include "core/system/scene_context.hpp"
|
||||||
#include "core/types.hpp"
|
#include "core/types.hpp"
|
||||||
#include "game/effects/debris_manager.hpp"
|
#include "game/effects/debris_manager.hpp"
|
||||||
|
|
||||||
class EscenaLogo {
|
class LogoScene {
|
||||||
public:
|
public:
|
||||||
explicit EscenaLogo(SDLManager& sdl, GestorEscenes::ContextEscenes& context);
|
explicit LogoScene(SDLManager& sdl, SceneManager::SceneContext& context);
|
||||||
~EscenaLogo(); // Destructor per aturar sons
|
~LogoScene(); // Destructor per aturar sons
|
||||||
void executar(); // Bucle principal de l'escena
|
void run(); // Bucle principal de l'escena
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Màquina d'estats per l'animació
|
// Màquina d'estats per l'animació
|
||||||
enum class EstatAnimacio {
|
enum class AnimationState {
|
||||||
PRE_ANIMATION, // Pantalla negra inicial
|
PRE_ANIMATION, // Pantalla negra inicial
|
||||||
ANIMATION, // Animació de zoom de lletres
|
ANIMATION, // Animació de zoom de lletres
|
||||||
POST_ANIMATION, // Logo complet visible
|
POST_ANIMATION, // Logo complet visible
|
||||||
@@ -35,8 +35,8 @@ class EscenaLogo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SDLManager& sdl_;
|
SDLManager& sdl_;
|
||||||
GestorEscenes::ContextEscenes& context_;
|
SceneManager::SceneContext& context_;
|
||||||
EstatAnimacio estat_actual_; // Estat actual de la màquina
|
AnimationState estat_actual_; // Estat actual de la màquina
|
||||||
float
|
float
|
||||||
temps_estat_actual_; // Temps en l'estat actual (reset en cada transició)
|
temps_estat_actual_; // Temps en l'estat actual (reset en cada transició)
|
||||||
|
|
||||||
@@ -86,6 +86,6 @@ class EscenaLogo {
|
|||||||
auto checkSkipButtonPressed() -> bool;
|
auto checkSkipButtonPressed() -> bool;
|
||||||
|
|
||||||
// Mètodes de gestió d'estats
|
// Mètodes de gestió d'estats
|
||||||
void canviar_estat(EstatAnimacio nou_estat);
|
void canviar_estat(AnimationState nou_estat);
|
||||||
[[nodiscard]] bool totes_lletres_completes() const;
|
[[nodiscard]] bool totes_lletres_completes() const;
|
||||||
};
|
};
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// escena_titol.cpp - Implementació de l'escena de títol
|
// escena_titol.cpp - Implementació de l'escena de títol
|
||||||
// © 2025 Port a C++20
|
// © 2025 Port a C++20
|
||||||
|
|
||||||
#include "escena_titol.hpp"
|
#include "title_scene.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
@@ -15,38 +15,38 @@
|
|||||||
#include "core/input/input.hpp"
|
#include "core/input/input.hpp"
|
||||||
#include "core/input/mouse.hpp"
|
#include "core/input/mouse.hpp"
|
||||||
#include "core/rendering/shape_renderer.hpp"
|
#include "core/rendering/shape_renderer.hpp"
|
||||||
#include "core/system/context_escenes.hpp"
|
#include "core/system/scene_context.hpp"
|
||||||
#include "core/system/global_events.hpp"
|
#include "core/system/global_events.hpp"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
|
||||||
// Using declarations per simplificar el codi
|
// Using declarations per simplificar el codi
|
||||||
using GestorEscenes::ContextEscenes;
|
using SceneManager::SceneContext;
|
||||||
using Escena = ContextEscenes::Escena;
|
using SceneType = SceneContext::SceneType;
|
||||||
using Opcio = ContextEscenes::Opcio;
|
using Option = SceneContext::Option;
|
||||||
|
|
||||||
EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context)
|
TitleScene::TitleScene(SDLManager& sdl, SceneContext& context)
|
||||||
: sdl_(sdl),
|
: sdl_(sdl),
|
||||||
context_(context),
|
context_(context),
|
||||||
text_(sdl.obte_renderer()),
|
text_(sdl.obte_renderer()),
|
||||||
estat_actual_(EstatTitol::STARFIELD_FADE_IN),
|
estat_actual_(TitleState::STARFIELD_FADE_IN),
|
||||||
temps_acumulat_(0.0F),
|
temps_acumulat_(0.0F),
|
||||||
temps_animacio_(0.0F),
|
temps_animacio_(0.0F),
|
||||||
temps_estat_main_(0.0F),
|
temps_estat_main_(0.0F),
|
||||||
animacio_activa_(false),
|
animacio_activa_(false),
|
||||||
factor_lerp_(0.0F) {
|
factor_lerp_(0.0F) {
|
||||||
std::cout << "Escena Titol: Inicialitzant...\n";
|
std::cout << "SceneType Titol: Inicialitzant...\n";
|
||||||
|
|
||||||
// Inicialitzar configuració de partida (cap jugador actiu per defecte)
|
// Inicialitzar configuració de partida (cap jugador actiu per defecte)
|
||||||
config_partida_.jugador1_actiu = false;
|
match_config_.jugador1_actiu = false;
|
||||||
config_partida_.jugador2_actiu = false;
|
match_config_.jugador2_actiu = false;
|
||||||
config_partida_.mode = GameConfig::Mode::NORMAL;
|
match_config_.mode = GameConfig::Mode::NORMAL;
|
||||||
|
|
||||||
// Processar opció del context
|
// Processar opció del context
|
||||||
auto opcio = context_.consumir_opcio();
|
auto option = context_.consumeOption();
|
||||||
|
|
||||||
if (opcio == Opcio::JUMP_TO_TITLE_MAIN) {
|
if (option == Option::JUMP_TO_TITLE_MAIN) {
|
||||||
std::cout << "Escena Titol: Opció JUMP_TO_TITLE_MAIN activada\n";
|
std::cout << "SceneType Titol: Opció JUMP_TO_TITLE_MAIN activada\n";
|
||||||
estat_actual_ = EstatTitol::MAIN;
|
estat_actual_ = TitleState::MAIN;
|
||||||
temps_estat_main_ = 0.0F;
|
temps_estat_main_ = 0.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context)
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Brightness depèn de l'opció
|
// Brightness depèn de l'opció
|
||||||
if (estat_actual_ == EstatTitol::MAIN) {
|
if (estat_actual_ == TitleState::MAIN) {
|
||||||
// Si saltem a MAIN, starfield instantàniament brillant
|
// Si saltem a MAIN, starfield instantàniament brillant
|
||||||
starfield_->set_brightness(BRIGHTNESS_STARFIELD);
|
starfield_->set_brightness(BRIGHTNESS_STARFIELD);
|
||||||
} else {
|
} else {
|
||||||
@@ -81,7 +81,7 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context)
|
|||||||
ship_animator_ = std::make_unique<Title::ShipAnimator>(sdl_.obte_renderer());
|
ship_animator_ = std::make_unique<Title::ShipAnimator>(sdl_.obte_renderer());
|
||||||
ship_animator_->init();
|
ship_animator_->init();
|
||||||
|
|
||||||
if (estat_actual_ == EstatTitol::MAIN) {
|
if (estat_actual_ == TitleState::MAIN) {
|
||||||
// Jump to MAIN: empezar entrada inmediatamente
|
// Jump to MAIN: empezar entrada inmediatamente
|
||||||
ship_animator_->set_visible(true);
|
ship_animator_->set_visible(true);
|
||||||
ship_animator_->start_entry_animation();
|
ship_animator_->start_entry_animation();
|
||||||
@@ -99,12 +99,12 @@ EscenaTitol::EscenaTitol(SDLManager& sdl, ContextEscenes& context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EscenaTitol::~EscenaTitol() {
|
TitleScene::~TitleScene() {
|
||||||
// Aturar música de títol quan es destrueix l'escena
|
// Aturar música de títol quan es destrueix l'escena
|
||||||
Audio::get()->stopMusic();
|
Audio::get()->stopMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaTitol::inicialitzar_titol() {
|
void TitleScene::inicialitzar_titol() {
|
||||||
using namespace Graphics;
|
using namespace Graphics;
|
||||||
|
|
||||||
// === LÍNIA 1: "ORNI" ===
|
// === LÍNIA 1: "ORNI" ===
|
||||||
@@ -120,7 +120,7 @@ void EscenaTitol::inicialitzar_titol() {
|
|||||||
for (const auto& fitxer : fitxers_orni) {
|
for (const auto& fitxer : fitxers_orni) {
|
||||||
auto forma = ShapeLoader::load(fitxer);
|
auto forma = ShapeLoader::load(fitxer);
|
||||||
if (!forma || !forma->es_valida()) {
|
if (!forma || !forma->es_valida()) {
|
||||||
std::cerr << "[EscenaTitol] Error carregant " << fitxer << '\n';
|
std::cerr << "[TitleScene] Error carregant " << fitxer << '\n';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ void EscenaTitol::inicialitzar_titol() {
|
|||||||
x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES;
|
x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[EscenaTitol] Línia 1 (ORNI): " << lletres_orni_.size()
|
std::cout << "[TitleScene] Línia 1 (ORNI): " << lletres_orni_.size()
|
||||||
<< " lletres, ancho total: " << ancho_total_orni << " px\n";
|
<< " lletres, ancho total: " << ancho_total_orni << " px\n";
|
||||||
|
|
||||||
// === Calcular posició Y dinàmica per "ATTACK!" ===
|
// === Calcular posició Y dinàmica per "ATTACK!" ===
|
||||||
@@ -175,7 +175,7 @@ void EscenaTitol::inicialitzar_titol() {
|
|||||||
float separacion_lineas = Defaults::Game::HEIGHT * Defaults::Title::Layout::LOGO_LINE_SPACING;
|
float separacion_lineas = Defaults::Game::HEIGHT * Defaults::Title::Layout::LOGO_LINE_SPACING;
|
||||||
y_attack_dinamica_ = y_orni + altura_orni + separacion_lineas;
|
y_attack_dinamica_ = y_orni + altura_orni + separacion_lineas;
|
||||||
|
|
||||||
std::cout << "[EscenaTitol] Altura ORNI: " << altura_orni
|
std::cout << "[TitleScene] Altura ORNI: " << altura_orni
|
||||||
<< " px, Y_ATTACK dinàmica: " << y_attack_dinamica_ << " px\n";
|
<< " px, Y_ATTACK dinàmica: " << y_attack_dinamica_ << " px\n";
|
||||||
|
|
||||||
// === LÍNIA 2: "ATTACK!" ===
|
// === LÍNIA 2: "ATTACK!" ===
|
||||||
@@ -194,7 +194,7 @@ void EscenaTitol::inicialitzar_titol() {
|
|||||||
for (const auto& fitxer : fitxers_attack) {
|
for (const auto& fitxer : fitxers_attack) {
|
||||||
auto forma = ShapeLoader::load(fitxer);
|
auto forma = ShapeLoader::load(fitxer);
|
||||||
if (!forma || !forma->es_valida()) {
|
if (!forma || !forma->es_valida()) {
|
||||||
std::cerr << "[EscenaTitol] Error carregant " << fitxer << '\n';
|
std::cerr << "[TitleScene] Error carregant " << fitxer << '\n';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ void EscenaTitol::inicialitzar_titol() {
|
|||||||
x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES;
|
x_actual += lletra.ancho + ESPAI_ENTRE_LLETRES;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[EscenaTitol] Línia 2 (ATTACK!): " << lletres_attack_.size()
|
std::cout << "[TitleScene] Línia 2 (ATTACK!): " << lletres_attack_.size()
|
||||||
<< " lletres, ancho total: " << ancho_total_attack << " px\n";
|
<< " lletres, ancho total: " << ancho_total_attack << " px\n";
|
||||||
|
|
||||||
// Guardar posicions originals per l'animació orbital
|
// Guardar posicions originals per l'animació orbital
|
||||||
@@ -253,14 +253,14 @@ void EscenaTitol::inicialitzar_titol() {
|
|||||||
posicions_originals_attack_.push_back(lletra.posicio);
|
posicions_originals_attack_.push_back(lletra.posicio);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[EscenaTitol] Animació: Posicions originals guardades\n";
|
std::cout << "[TitleScene] Animació: Posicions originals guardades\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaTitol::executar() {
|
void TitleScene::run() {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
Uint64 last_time = SDL_GetTicks();
|
Uint64 last_time = SDL_GetTicks();
|
||||||
|
|
||||||
while (GestorEscenes::actual == Escena::TITOL) {
|
while (SceneManager::actual == SceneType::TITLE) {
|
||||||
// Calcular delta_time real
|
// Calcular delta_time real
|
||||||
Uint64 current_time = SDL_GetTicks();
|
Uint64 current_time = SDL_GetTicks();
|
||||||
float delta_time = (current_time - last_time) / 1000.0F;
|
float delta_time = (current_time - last_time) / 1000.0F;
|
||||||
@@ -316,10 +316,10 @@ void EscenaTitol::executar() {
|
|||||||
sdl_.presenta();
|
sdl_.presenta();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Escena Titol: Finalitzant...\n";
|
std::cout << "SceneType Titol: Finalitzant...\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaTitol::update(float delta_time) {
|
void TitleScene::update(float delta_time) {
|
||||||
// Actualitzar starfield (sempre actiu)
|
// Actualitzar starfield (sempre actiu)
|
||||||
if (starfield_) {
|
if (starfield_) {
|
||||||
starfield_->update(delta_time);
|
starfield_->update(delta_time);
|
||||||
@@ -327,15 +327,15 @@ void EscenaTitol::update(float delta_time) {
|
|||||||
|
|
||||||
// Actualitzar naus (quan visibles)
|
// Actualitzar naus (quan visibles)
|
||||||
if (ship_animator_ &&
|
if (ship_animator_ &&
|
||||||
(estat_actual_ == EstatTitol::STARFIELD_FADE_IN ||
|
(estat_actual_ == TitleState::STARFIELD_FADE_IN ||
|
||||||
estat_actual_ == EstatTitol::STARFIELD ||
|
estat_actual_ == TitleState::STARFIELD ||
|
||||||
estat_actual_ == EstatTitol::MAIN ||
|
estat_actual_ == TitleState::MAIN ||
|
||||||
estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE)) {
|
estat_actual_ == TitleState::PLAYER_JOIN_PHASE)) {
|
||||||
ship_animator_->update(delta_time);
|
ship_animator_->update(delta_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (estat_actual_) {
|
switch (estat_actual_) {
|
||||||
case EstatTitol::STARFIELD_FADE_IN: {
|
case TitleState::STARFIELD_FADE_IN: {
|
||||||
temps_acumulat_ += delta_time;
|
temps_acumulat_ += delta_time;
|
||||||
|
|
||||||
// Calcular progrés del fade (0.0 → 1.0)
|
// Calcular progrés del fade (0.0 → 1.0)
|
||||||
@@ -347,17 +347,17 @@ void EscenaTitol::update(float delta_time) {
|
|||||||
|
|
||||||
// Transició a STARFIELD quan el fade es completa
|
// Transició a STARFIELD quan el fade es completa
|
||||||
if (temps_acumulat_ >= DURACIO_FADE_IN) {
|
if (temps_acumulat_ >= DURACIO_FADE_IN) {
|
||||||
estat_actual_ = EstatTitol::STARFIELD;
|
estat_actual_ = TitleState::STARFIELD;
|
||||||
temps_acumulat_ = 0.0F; // Reset timer per al següent estat
|
temps_acumulat_ = 0.0F; // Reset timer per al següent estat
|
||||||
starfield_->set_brightness(BRIGHTNESS_STARFIELD); // Assegurar valor final
|
starfield_->set_brightness(BRIGHTNESS_STARFIELD); // Assegurar valor final
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EstatTitol::STARFIELD:
|
case TitleState::STARFIELD:
|
||||||
temps_acumulat_ += delta_time;
|
temps_acumulat_ += delta_time;
|
||||||
if (temps_acumulat_ >= DURACIO_INIT) {
|
if (temps_acumulat_ >= DURACIO_INIT) {
|
||||||
estat_actual_ = EstatTitol::MAIN;
|
estat_actual_ = TitleState::MAIN;
|
||||||
temps_estat_main_ = 0.0F; // Reset timer al entrar a MAIN
|
temps_estat_main_ = 0.0F; // Reset timer al entrar a MAIN
|
||||||
animacio_activa_ = false; // Comença estàtic
|
animacio_activa_ = false; // Comença estàtic
|
||||||
factor_lerp_ = 0.0F; // Sense animació encara
|
factor_lerp_ = 0.0F; // Sense animació encara
|
||||||
@@ -366,7 +366,7 @@ void EscenaTitol::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EstatTitol::MAIN: {
|
case TitleState::MAIN: {
|
||||||
temps_estat_main_ += delta_time;
|
temps_estat_main_ += delta_time;
|
||||||
|
|
||||||
// Iniciar animació d'entrada de naus després del delay
|
// Iniciar animació d'entrada de naus després del delay
|
||||||
@@ -399,7 +399,7 @@ void EscenaTitol::update(float delta_time) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EstatTitol::PLAYER_JOIN_PHASE:
|
case TitleState::PLAYER_JOIN_PHASE:
|
||||||
temps_acumulat_ += delta_time;
|
temps_acumulat_ += delta_time;
|
||||||
|
|
||||||
// Continuar animació orbital durant la transició
|
// Continuar animació orbital durant la transició
|
||||||
@@ -407,22 +407,22 @@ void EscenaTitol::update(float delta_time) {
|
|||||||
|
|
||||||
// [NOU] Continuar comprovant si l'altre jugador vol unir-se durant la transició ("late join")
|
// [NOU] Continuar comprovant si l'altre jugador vol unir-se durant la transició ("late join")
|
||||||
{
|
{
|
||||||
bool p1_actiu_abans = config_partida_.jugador1_actiu;
|
bool p1_actiu_abans = match_config_.jugador1_actiu;
|
||||||
bool p2_actiu_abans = config_partida_.jugador2_actiu;
|
bool p2_actiu_abans = match_config_.jugador2_actiu;
|
||||||
|
|
||||||
if (checkStartGameButtonPressed()) {
|
if (checkStartGameButtonPressed()) {
|
||||||
// Updates config_partida_ if pressed, logs are in the method
|
// Updates match_config_ if pressed, logs are in the method
|
||||||
context_.set_config_partida(config_partida_);
|
context_.setMatchConfig(match_config_);
|
||||||
|
|
||||||
// Trigger animació de sortida per la nau que acaba d'unir-se
|
// Trigger animació de sortida per la nau que acaba d'unir-se
|
||||||
if (ship_animator_) {
|
if (ship_animator_) {
|
||||||
if (config_partida_.jugador1_actiu && !p1_actiu_abans) {
|
if (match_config_.jugador1_actiu && !p1_actiu_abans) {
|
||||||
ship_animator_->trigger_exit_animation_for_player(1);
|
ship_animator_->trigger_exit_animation_for_player(1);
|
||||||
std::cout << "[EscenaTitol] P1 late join - ship exiting\n";
|
std::cout << "[TitleScene] P1 late join - ship exiting\n";
|
||||||
}
|
}
|
||||||
if (config_partida_.jugador2_actiu && !p2_actiu_abans) {
|
if (match_config_.jugador2_actiu && !p2_actiu_abans) {
|
||||||
ship_animator_->trigger_exit_animation_for_player(2);
|
ship_animator_->trigger_exit_animation_for_player(2);
|
||||||
std::cout << "[EscenaTitol] P2 late join - ship exiting\n";
|
std::cout << "[TitleScene] P2 late join - ship exiting\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,35 +432,35 @@ void EscenaTitol::update(float delta_time) {
|
|||||||
// Reiniciar el timer per allargar el temps de transició
|
// Reiniciar el timer per allargar el temps de transició
|
||||||
temps_acumulat_ = 0.0F;
|
temps_acumulat_ = 0.0F;
|
||||||
|
|
||||||
std::cout << "[EscenaTitol] Segon jugador s'ha unit - so i timer reiniciats\n";
|
std::cout << "[TitleScene] Segon jugador s'ha unit - so i timer reiniciats\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temps_acumulat_ >= DURACIO_TRANSITION) {
|
if (temps_acumulat_ >= DURACIO_TRANSITION) {
|
||||||
// Transició a pantalla negra
|
// Transició a pantalla negra
|
||||||
estat_actual_ = EstatTitol::BLACK_SCREEN;
|
estat_actual_ = TitleState::BLACK_SCREEN;
|
||||||
temps_acumulat_ = 0.0F;
|
temps_acumulat_ = 0.0F;
|
||||||
std::cout << "[EscenaTitol] Passant a BLACK_SCREEN\n";
|
std::cout << "[TitleScene] Passant a BLACK_SCREEN\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EstatTitol::BLACK_SCREEN:
|
case TitleState::BLACK_SCREEN:
|
||||||
temps_acumulat_ += delta_time;
|
temps_acumulat_ += delta_time;
|
||||||
|
|
||||||
// No animation, no input checking - just wait
|
// No animation, no input checking - just wait
|
||||||
if (temps_acumulat_ >= DURACIO_BLACK_SCREEN) {
|
if (temps_acumulat_ >= DURACIO_BLACK_SCREEN) {
|
||||||
// Transició a escena JOC
|
// Transició a escena GAME
|
||||||
GestorEscenes::actual = Escena::JOC;
|
SceneManager::actual = SceneType::GAME;
|
||||||
std::cout << "[EscenaTitol] Canviant a escena JOC\n";
|
std::cout << "[TitleScene] Canviant a escena GAME\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar botones de skip (FIRE/THRUST/START) para saltar escenas ANTES de MAIN
|
// Verificar botones de skip (FIRE/THRUST/START) para saltar escenas ANTES de MAIN
|
||||||
if (estat_actual_ == EstatTitol::STARFIELD_FADE_IN || estat_actual_ == EstatTitol::STARFIELD) {
|
if (estat_actual_ == TitleState::STARFIELD_FADE_IN || estat_actual_ == TitleState::STARFIELD) {
|
||||||
if (checkSkipButtonPressed()) {
|
if (checkSkipButtonPressed()) {
|
||||||
// Saltar a MAIN
|
// Saltar a MAIN
|
||||||
estat_actual_ = EstatTitol::MAIN;
|
estat_actual_ = TitleState::MAIN;
|
||||||
starfield_->set_brightness(BRIGHTNESS_STARFIELD);
|
starfield_->set_brightness(BRIGHTNESS_STARFIELD);
|
||||||
temps_estat_main_ = 0.0F;
|
temps_estat_main_ = 0.0F;
|
||||||
|
|
||||||
@@ -469,10 +469,10 @@ void EscenaTitol::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verificar boton START para iniciar partida desde MAIN
|
// Verificar boton START para iniciar partida desde MAIN
|
||||||
if (estat_actual_ == EstatTitol::MAIN) {
|
if (estat_actual_ == TitleState::MAIN) {
|
||||||
// Guardar estat anterior per detectar qui ha premut START AQUEST frame
|
// Guardar estat anterior per detectar qui ha premut START AQUEST frame
|
||||||
bool p1_actiu_abans = config_partida_.jugador1_actiu;
|
bool p1_actiu_abans = match_config_.jugador1_actiu;
|
||||||
bool p2_actiu_abans = config_partida_.jugador2_actiu;
|
bool p2_actiu_abans = match_config_.jugador2_actiu;
|
||||||
|
|
||||||
if (checkStartGameButtonPressed()) {
|
if (checkStartGameButtonPressed()) {
|
||||||
// Si START es prem durant el delay (naus encara invisibles), saltar-les a FLOATING
|
// Si START es prem durant el delay (naus encara invisibles), saltar-les a FLOATING
|
||||||
@@ -482,26 +482,26 @@ void EscenaTitol::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Configurar partida abans de canviar d'escena
|
// Configurar partida abans de canviar d'escena
|
||||||
context_.set_config_partida(config_partida_);
|
context_.setMatchConfig(match_config_);
|
||||||
std::cout << "[EscenaTitol] Configuració de partida - P1: "
|
std::cout << "[TitleScene] Configuració de partida - P1: "
|
||||||
<< (config_partida_.jugador1_actiu ? "ACTIU" : "INACTIU")
|
<< (match_config_.jugador1_actiu ? "ACTIU" : "INACTIU")
|
||||||
<< ", P2: "
|
<< ", P2: "
|
||||||
<< (config_partida_.jugador2_actiu ? "ACTIU" : "INACTIU")
|
<< (match_config_.jugador2_actiu ? "ACTIU" : "INACTIU")
|
||||||
<< '\n';
|
<< '\n';
|
||||||
|
|
||||||
context_.canviar_escena(Escena::JOC);
|
context_.setNextScene(SceneType::GAME);
|
||||||
estat_actual_ = EstatTitol::PLAYER_JOIN_PHASE;
|
estat_actual_ = TitleState::PLAYER_JOIN_PHASE;
|
||||||
temps_acumulat_ = 0.0F;
|
temps_acumulat_ = 0.0F;
|
||||||
|
|
||||||
// Trigger animació de sortida NOMÉS per les naus que han premut START
|
// Trigger animació de sortida NOMÉS per les naus que han premut START
|
||||||
if (ship_animator_) {
|
if (ship_animator_) {
|
||||||
if (config_partida_.jugador1_actiu && !p1_actiu_abans) {
|
if (match_config_.jugador1_actiu && !p1_actiu_abans) {
|
||||||
ship_animator_->trigger_exit_animation_for_player(1);
|
ship_animator_->trigger_exit_animation_for_player(1);
|
||||||
std::cout << "[EscenaTitol] P1 ship exiting\n";
|
std::cout << "[TitleScene] P1 ship exiting\n";
|
||||||
}
|
}
|
||||||
if (config_partida_.jugador2_actiu && !p2_actiu_abans) {
|
if (match_config_.jugador2_actiu && !p2_actiu_abans) {
|
||||||
ship_animator_->trigger_exit_animation_for_player(2);
|
ship_animator_->trigger_exit_animation_for_player(2);
|
||||||
std::cout << "[EscenaTitol] P2 ship exiting\n";
|
std::cout << "[TitleScene] P2 ship exiting\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,7 +511,7 @@ void EscenaTitol::update(float delta_time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaTitol::actualitzar_animacio_logo(float delta_time) {
|
void TitleScene::actualitzar_animacio_logo(float delta_time) {
|
||||||
// Només calcular i aplicar offsets si l'animació està activa
|
// Només calcular i aplicar offsets si l'animació està activa
|
||||||
if (animacio_activa_) {
|
if (animacio_activa_) {
|
||||||
// Acumular temps escalat
|
// Acumular temps escalat
|
||||||
@@ -541,29 +541,29 @@ void EscenaTitol::actualitzar_animacio_logo(float delta_time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaTitol::draw() {
|
void TitleScene::draw() {
|
||||||
// Dibuixar starfield de fons (en tots els estats excepte BLACK_SCREEN)
|
// Dibuixar starfield de fons (en tots els estats excepte BLACK_SCREEN)
|
||||||
if (starfield_ && estat_actual_ != EstatTitol::BLACK_SCREEN) {
|
if (starfield_ && estat_actual_ != TitleState::BLACK_SCREEN) {
|
||||||
starfield_->draw();
|
starfield_->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dibuixar naus (després starfield, abans logo)
|
// Dibuixar naus (després starfield, abans logo)
|
||||||
if (ship_animator_ &&
|
if (ship_animator_ &&
|
||||||
(estat_actual_ == EstatTitol::STARFIELD_FADE_IN ||
|
(estat_actual_ == TitleState::STARFIELD_FADE_IN ||
|
||||||
estat_actual_ == EstatTitol::STARFIELD ||
|
estat_actual_ == TitleState::STARFIELD ||
|
||||||
estat_actual_ == EstatTitol::MAIN ||
|
estat_actual_ == TitleState::MAIN ||
|
||||||
estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE)) {
|
estat_actual_ == TitleState::PLAYER_JOIN_PHASE)) {
|
||||||
ship_animator_->draw();
|
ship_animator_->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
// En els estats STARFIELD_FADE_IN i STARFIELD, només mostrar starfield (sense text)
|
// En els estats STARFIELD_FADE_IN i STARFIELD, només mostrar starfield (sense text)
|
||||||
if (estat_actual_ == EstatTitol::STARFIELD_FADE_IN || estat_actual_ == EstatTitol::STARFIELD) {
|
if (estat_actual_ == TitleState::STARFIELD_FADE_IN || estat_actual_ == TitleState::STARFIELD) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Estat MAIN i PLAYER_JOIN_PHASE: Dibuixar títol i text (sobre el starfield)
|
// Estat MAIN i PLAYER_JOIN_PHASE: Dibuixar títol i text (sobre el starfield)
|
||||||
// BLACK_SCREEN: no draw res (fons negre ja està netejat)
|
// BLACK_SCREEN: no draw res (fons negre ja està netejat)
|
||||||
if (estat_actual_ == EstatTitol::MAIN || estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE) {
|
if (estat_actual_ == TitleState::MAIN || estat_actual_ == TitleState::PLAYER_JOIN_PHASE) {
|
||||||
// === Calcular i renderitzar ombra (només si animació activa) ===
|
// === Calcular i renderitzar ombra (només si animació activa) ===
|
||||||
if (animacio_activa_) {
|
if (animacio_activa_) {
|
||||||
float temps_shadow = temps_animacio_ - SHADOW_DELAY;
|
float temps_shadow = temps_animacio_ - SHADOW_DELAY;
|
||||||
@@ -648,7 +648,7 @@ void EscenaTitol::draw() {
|
|||||||
const float spacing = Defaults::Title::Layout::TEXT_SPACING;
|
const float spacing = Defaults::Title::Layout::TEXT_SPACING;
|
||||||
|
|
||||||
bool mostrar_text = true;
|
bool mostrar_text = true;
|
||||||
if (estat_actual_ == EstatTitol::PLAYER_JOIN_PHASE) {
|
if (estat_actual_ == TitleState::PLAYER_JOIN_PHASE) {
|
||||||
// Parpelleig: sin oscil·la entre -1 i 1, volem ON quan > 0
|
// Parpelleig: sin oscil·la entre -1 i 1, volem ON quan > 0
|
||||||
float fase = temps_acumulat_ * BLINK_FREQUENCY * 2.0F * std::numbers::pi_v<float>; // 2π × freq × temps
|
float fase = temps_acumulat_ * BLINK_FREQUENCY * 2.0F * std::numbers::pi_v<float>; // 2π × freq × temps
|
||||||
mostrar_text = (std::sin(fase) > 0.0F);
|
mostrar_text = (std::sin(fase) > 0.0F);
|
||||||
@@ -697,27 +697,27 @@ void EscenaTitol::draw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto EscenaTitol::checkSkipButtonPressed() -> bool {
|
auto TitleScene::checkSkipButtonPressed() -> bool {
|
||||||
return Input::get()->checkAnyPlayerAction(ARCADE_BUTTONS);
|
return Input::get()->checkAnyPlayerAction(ARCADE_BUTTONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto EscenaTitol::checkStartGameButtonPressed() -> bool {
|
auto TitleScene::checkStartGameButtonPressed() -> bool {
|
||||||
auto* input = Input::get();
|
auto* input = Input::get();
|
||||||
bool any_pressed = false;
|
bool any_pressed = false;
|
||||||
|
|
||||||
for (auto action : START_GAME_BUTTONS) {
|
for (auto action : START_GAME_BUTTONS) {
|
||||||
if (input->checkActionPlayer1(action, Input::DO_NOT_ALLOW_REPEAT)) {
|
if (input->checkActionPlayer1(action, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||||
if (!config_partida_.jugador1_actiu) {
|
if (!match_config_.jugador1_actiu) {
|
||||||
config_partida_.jugador1_actiu = true;
|
match_config_.jugador1_actiu = true;
|
||||||
any_pressed = true;
|
any_pressed = true;
|
||||||
std::cout << "[EscenaTitol] P1 pressed START\n";
|
std::cout << "[TitleScene] P1 pressed START\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (input->checkActionPlayer2(action, Input::DO_NOT_ALLOW_REPEAT)) {
|
if (input->checkActionPlayer2(action, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||||
if (!config_partida_.jugador2_actiu) {
|
if (!match_config_.jugador2_actiu) {
|
||||||
config_partida_.jugador2_actiu = true;
|
match_config_.jugador2_actiu = true;
|
||||||
any_pressed = true;
|
any_pressed = true;
|
||||||
std::cout << "[EscenaTitol] P2 pressed START\n";
|
std::cout << "[TitleScene] P2 pressed START\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -725,6 +725,6 @@ auto EscenaTitol::checkStartGameButtonPressed() -> bool {
|
|||||||
return any_pressed;
|
return any_pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaTitol::processar_events(const SDL_Event& event) {
|
void TitleScene::processar_events(const SDL_Event& event) {
|
||||||
// No procesar eventos genéricos aquí - la lógica se movió a update()
|
// No procesar eventos genéricos aquí - la lógica se movió a update()
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
#include "core/graphics/vector_text.hpp"
|
#include "core/graphics/vector_text.hpp"
|
||||||
#include "core/input/input_types.hpp"
|
#include "core/input/input_types.hpp"
|
||||||
#include "core/rendering/sdl_manager.hpp"
|
#include "core/rendering/sdl_manager.hpp"
|
||||||
#include "core/system/context_escenes.hpp"
|
#include "core/system/scene_context.hpp"
|
||||||
#include "core/system/game_config.hpp"
|
#include "core/system/game_config.hpp"
|
||||||
#include "core/types.hpp"
|
#include "core/types.hpp"
|
||||||
#include "game/title/ship_animator.hpp"
|
#include "game/title/ship_animator.hpp"
|
||||||
@@ -25,15 +25,15 @@
|
|||||||
static constexpr std::array<InputAction, 1> START_GAME_BUTTONS = {
|
static constexpr std::array<InputAction, 1> START_GAME_BUTTONS = {
|
||||||
InputAction::START};
|
InputAction::START};
|
||||||
|
|
||||||
class EscenaTitol {
|
class TitleScene {
|
||||||
public:
|
public:
|
||||||
explicit EscenaTitol(SDLManager& sdl, GestorEscenes::ContextEscenes& context);
|
explicit TitleScene(SDLManager& sdl, SceneManager::SceneContext& context);
|
||||||
~EscenaTitol(); // Destructor per aturar música
|
~TitleScene(); // Destructor per aturar música
|
||||||
void executar(); // Bucle principal de l'escena
|
void run(); // Bucle principal de l'escena
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Màquina d'estats per la pantalla de títol
|
// Màquina d'estats per la pantalla de títol
|
||||||
enum class EstatTitol {
|
enum class TitleState {
|
||||||
STARFIELD_FADE_IN, // Fade-in del starfield (3.0s)
|
STARFIELD_FADE_IN, // Fade-in del starfield (3.0s)
|
||||||
STARFIELD, // Pantalla amb camp d'estrelles (4.0s)
|
STARFIELD, // Pantalla amb camp d'estrelles (4.0s)
|
||||||
MAIN, // Pantalla de títol amb text (indefinit, fins START)
|
MAIN, // Pantalla de títol amb text (indefinit, fins START)
|
||||||
@@ -51,12 +51,12 @@ class EscenaTitol {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SDLManager& sdl_;
|
SDLManager& sdl_;
|
||||||
GestorEscenes::ContextEscenes& context_;
|
SceneManager::SceneContext& context_;
|
||||||
GameConfig::ConfigPartida config_partida_; // Configuració de jugadors actius
|
GameConfig::MatchConfig match_config_; // Configuració de jugadors actius
|
||||||
Graphics::VectorText text_; // Sistema de text vectorial
|
Graphics::VectorText text_; // Sistema de text vectorial
|
||||||
std::unique_ptr<Graphics::Starfield> starfield_; // Camp d'estrelles de fons
|
std::unique_ptr<Graphics::Starfield> starfield_; // Camp d'estrelles de fons
|
||||||
std::unique_ptr<Title::ShipAnimator> ship_animator_; // Naus 3D flotants
|
std::unique_ptr<Title::ShipAnimator> ship_animator_; // Naus 3D flotants
|
||||||
EstatTitol estat_actual_; // Estat actual de la màquina
|
TitleState estat_actual_; // Estat actual de la màquina
|
||||||
float temps_acumulat_; // Temps acumulat per l'estat INIT
|
float temps_acumulat_; // Temps acumulat per l'estat INIT
|
||||||
|
|
||||||
// Lletres del títol "ORNI ATTACK!"
|
// Lletres del títol "ORNI ATTACK!"
|
||||||
@@ -129,10 +129,10 @@ void StageManager::processar_level_start(float delta_time) {
|
|||||||
|
|
||||||
void StageManager::processar_playing(float delta_time, bool pausar_spawn) {
|
void StageManager::processar_playing(float delta_time, bool pausar_spawn) {
|
||||||
// Update spawn controller (pauses when pausar_spawn = true)
|
// Update spawn controller (pauses when pausar_spawn = true)
|
||||||
// Note: The actual enemy array update happens in EscenaJoc::update()
|
// Note: The actual enemy array update happens in GameScene::update()
|
||||||
// This is just for internal timekeeping
|
// This is just for internal timekeeping
|
||||||
(void)delta_time; // Spawn controller is updated externally
|
(void)delta_time; // Spawn controller is updated externally
|
||||||
(void)pausar_spawn; // Passed to spawn_controller_.update() by EscenaJoc
|
(void)pausar_spawn; // Passed to spawn_controller_.update() by GameScene
|
||||||
}
|
}
|
||||||
|
|
||||||
void StageManager::processar_level_completed(float delta_time) {
|
void StageManager::processar_level_completed(float delta_time) {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class ShipAnimator {
|
|||||||
void update(float delta_time);
|
void update(float delta_time);
|
||||||
void draw() const;
|
void draw() const;
|
||||||
|
|
||||||
// Control d'estat (cridat per EscenaTitol)
|
// Control d'estat (cridat per TitleScene)
|
||||||
void start_entry_animation();
|
void start_entry_animation();
|
||||||
void trigger_exit_animation(); // Anima totes les naus
|
void trigger_exit_animation(); // Anima totes les naus
|
||||||
void trigger_exit_animation_for_player(int jugador_id); // Anima només una nau (P1=1, P2=2)
|
void trigger_exit_animation_for_player(int jugador_id); // Anima només una nau (P1=1, P2=2)
|
||||||
|
|||||||
Reference in New Issue
Block a user