feat(demo): transició títol→demo amb dive de càmera + cortinilla negra (substitueix el fundido)
This commit is contained in:
@@ -39,11 +39,18 @@ namespace Defaults::Game {
|
||||
constexpr float LEVEL_COMPLETED_DURATION = 3.0F; // Duración total
|
||||
constexpr float LEVEL_COMPLETED_TYPING_RATIO = 0.05F; // ~150ms de typewriter (escan ràpid però visible)
|
||||
|
||||
// Attract mode: durada de la fosa a/desde negre a les transicions de demo.
|
||||
namespace Fade {
|
||||
constexpr float DEMO_OUT_DURATION = 0.6F; // TÍTOL → DEMO (fosa a negre abans del salt)
|
||||
constexpr float DEMO_IN_DURATION = 0.6F; // DEMO: fosa des de negre sobre el joc ja en marxa
|
||||
} // namespace Fade
|
||||
// Attract mode: transició TÍTOL → DEMO. Primer un "dive" de càmera cap al
|
||||
// punt de fuga (deixa enrere títol/naus/logo) i després una cortinilla negra
|
||||
// que cau per tapar; a la demo, la cortinilla segueix caient i destapa.
|
||||
namespace Dive {
|
||||
constexpr float DURATION = 0.55F; // Durada del dive (s), amb acceleració (ease-in)
|
||||
constexpr float CAMERA_DISTANCE = 450.0F; // Avanç de la càmera en +Z (passa les naus, a Z≈323)
|
||||
constexpr float ZOOM_MAX = 7.0F; // Zoom final dels elements 2D (logo + peu) en travessar-los
|
||||
} // namespace Dive
|
||||
namespace Curtain {
|
||||
constexpr float COVER_DURATION = 0.35F; // TÍTOL: la tela cau i tapa
|
||||
constexpr float REVEAL_DURATION = 0.45F; // DEMO: la tela segueix caient i destapa
|
||||
} // namespace Curtain
|
||||
|
||||
// Transición INIT_HUD (animación inicial del HUD)
|
||||
constexpr float INIT_HUD_DURATION = 3.0F; // Duración total del estado
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// curtain.cpp - Implementació de la cortinilla negra
|
||||
// © 2026 JailDesigner
|
||||
|
||||
#include "core/graphics/curtain.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "core/defaults/game.hpp"
|
||||
#include "core/math/easing.hpp"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
namespace {
|
||||
constexpr float SCREEN_H = static_cast<float>(Defaults::Game::HEIGHT);
|
||||
constexpr float SCREEN_W = static_cast<float>(Defaults::Game::WIDTH);
|
||||
} // namespace
|
||||
|
||||
Curtain::Curtain(Rendering::Renderer* renderer)
|
||||
: renderer_(renderer) {}
|
||||
|
||||
void Curtain::cover(float duration) {
|
||||
// Caire superior de -H (fora, a dalt) fins a 0 (tela tapant tota la pantalla).
|
||||
from_ = -SCREEN_H;
|
||||
to_ = 0.0F;
|
||||
duration_ = duration;
|
||||
elapsed_ = 0.0F;
|
||||
active_ = true;
|
||||
}
|
||||
|
||||
void Curtain::reveal(float duration) {
|
||||
// Caire superior de 0 (tapant) fins a +H (tela fora per baix).
|
||||
from_ = 0.0F;
|
||||
to_ = SCREEN_H;
|
||||
duration_ = duration;
|
||||
elapsed_ = 0.0F;
|
||||
active_ = true;
|
||||
}
|
||||
|
||||
void Curtain::update(float delta_time) {
|
||||
if (!active_) {
|
||||
return;
|
||||
}
|
||||
elapsed_ += delta_time;
|
||||
}
|
||||
|
||||
auto Curtain::topY() const -> float {
|
||||
if (duration_ <= 0.0F) {
|
||||
return to_;
|
||||
}
|
||||
const float T = std::clamp(elapsed_ / duration_, 0.0F, 1.0F);
|
||||
// Ease-in: la tela "cau" accelerant, com per gravetat.
|
||||
return Easing::lerp(from_, to_, Easing::easeInQuad(T));
|
||||
}
|
||||
|
||||
auto Curtain::isDone() const -> bool {
|
||||
return !active_ || elapsed_ >= duration_;
|
||||
}
|
||||
|
||||
void Curtain::draw() const {
|
||||
if (!active_) {
|
||||
return;
|
||||
}
|
||||
const float TOP = topY();
|
||||
// Si la tela ja ha sortit completament per baix, no hi ha res a pintar.
|
||||
if (TOP >= SCREEN_H) {
|
||||
return;
|
||||
}
|
||||
renderer_->pushRect(0.0F, TOP, SCREEN_W, SCREEN_H, 0.0F, 0.0F, 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
} // namespace Graphics
|
||||
@@ -0,0 +1,48 @@
|
||||
// curtain.hpp - Cortinilla negra per a transicions d'escena
|
||||
// © 2026 JailDesigner
|
||||
//
|
||||
// Tela negra a pantalla completa que es mou SEMPRE cap avall:
|
||||
// - cover(): cau des de dalt fins a tapar-ho tot (queda negre).
|
||||
// - reveal(): segueix caient i surt per baix, deixant veure l'escena.
|
||||
// Una escena la posseeix, l'actualitza cada frame i la dibuixa l'ÚLTIM (per
|
||||
// damunt de tot). En repòs (no arrencada o reveal acabada) el draw() és no-op.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/rendering/render_context.hpp"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
class Curtain {
|
||||
public:
|
||||
explicit Curtain(Rendering::Renderer* renderer);
|
||||
|
||||
// Tela que cau des de dalt fins a tapar tota la pantalla en 'duration' s.
|
||||
void cover(float duration);
|
||||
|
||||
// Tela que segueix caient i surt per baix (destapa) en 'duration' s.
|
||||
void reveal(float duration);
|
||||
|
||||
// Avança el temporitzador intern.
|
||||
void update(float delta_time);
|
||||
|
||||
// Dibuixa la tela negra a la seva posició vertical actual. No-op si no
|
||||
// queda res visible.
|
||||
void draw() const;
|
||||
|
||||
// Cert quan el moviment actual ha acabat (o no s'ha arrencat mai).
|
||||
[[nodiscard]] auto isDone() const -> bool;
|
||||
|
||||
private:
|
||||
// Posició actual del caire superior de la tela (píxels lògics).
|
||||
[[nodiscard]] auto topY() const -> float;
|
||||
|
||||
Rendering::Renderer* renderer_;
|
||||
float from_{0.0F};
|
||||
float to_{0.0F};
|
||||
float duration_{0.0F};
|
||||
float elapsed_{0.0F};
|
||||
bool active_{false};
|
||||
};
|
||||
|
||||
} // namespace Graphics
|
||||
@@ -1,62 +0,0 @@
|
||||
// screen_fade.cpp - Implementació de la fosa a/desde negre
|
||||
// © 2026 JailDesigner
|
||||
|
||||
#include "core/graphics/screen_fade.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include "core/defaults/game.hpp"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
ScreenFade::ScreenFade(Rendering::Renderer* renderer)
|
||||
: renderer_(renderer) {}
|
||||
|
||||
void ScreenFade::start(float from, float to, float duration) {
|
||||
from_ = from;
|
||||
to_ = to;
|
||||
duration_ = duration;
|
||||
elapsed_ = 0.0F;
|
||||
active_ = true;
|
||||
}
|
||||
|
||||
void ScreenFade::update(float delta_time) {
|
||||
if (!active_) {
|
||||
return;
|
||||
}
|
||||
elapsed_ += delta_time;
|
||||
}
|
||||
|
||||
auto ScreenFade::alpha() const -> float {
|
||||
if (!active_) {
|
||||
return 0.0F;
|
||||
}
|
||||
if (duration_ <= 0.0F) {
|
||||
return to_;
|
||||
}
|
||||
const float T = std::clamp(elapsed_ / duration_, 0.0F, 1.0F);
|
||||
return std::lerp(from_, to_, T);
|
||||
}
|
||||
|
||||
auto ScreenFade::isDone() const -> bool {
|
||||
return !active_ || elapsed_ >= duration_;
|
||||
}
|
||||
|
||||
void ScreenFade::draw() const {
|
||||
const float A = alpha();
|
||||
if (A <= 0.0F) {
|
||||
return;
|
||||
}
|
||||
renderer_->pushRect(
|
||||
0.0F,
|
||||
0.0F,
|
||||
static_cast<float>(Defaults::Game::WIDTH),
|
||||
static_cast<float>(Defaults::Game::HEIGHT),
|
||||
0.0F,
|
||||
0.0F,
|
||||
0.0F,
|
||||
A);
|
||||
}
|
||||
|
||||
} // namespace Graphics
|
||||
@@ -1,43 +0,0 @@
|
||||
// screen_fade.hpp - Fosa a/desde negre per a transicions d'escena
|
||||
// © 2026 JailDesigner
|
||||
//
|
||||
// Rect negre a pantalla completa amb l'alpha animat linealment. L'escena que el
|
||||
// posseeix l'actualitza cada frame i el dibuixa l'ÚLTIM (per damunt de tot). En
|
||||
// repòs (default-construït o fosa acabada amb alpha 0) el draw() és un no-op.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/rendering/render_context.hpp"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
class ScreenFade {
|
||||
public:
|
||||
explicit ScreenFade(Rendering::Renderer* renderer);
|
||||
|
||||
// Arrenca una fosa lineal d'alpha 'from' a 'to' en 'duration' segons.
|
||||
void start(float from, float to, float duration);
|
||||
|
||||
// Avança el temporitzador intern.
|
||||
void update(float delta_time);
|
||||
|
||||
// Dibuixa el rect negre a pantalla completa amb l'alpha actual.
|
||||
// No fa res si l'alpha és ~0 (estalvia el pushRect).
|
||||
void draw() const;
|
||||
|
||||
// Cert quan la fosa ha acabat (o no s'ha arrencat mai).
|
||||
[[nodiscard]] auto isDone() const -> bool;
|
||||
|
||||
// Alpha actual ∈ [0, 1].
|
||||
[[nodiscard]] auto alpha() const -> float;
|
||||
|
||||
private:
|
||||
Rendering::Renderer* renderer_;
|
||||
float from_{0.0F};
|
||||
float to_{0.0F};
|
||||
float duration_{0.0F};
|
||||
float elapsed_{0.0F};
|
||||
bool active_{false};
|
||||
};
|
||||
|
||||
} // namespace Graphics
|
||||
@@ -56,7 +56,7 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context)
|
||||
starfield_parallax_(sdl.getRenderer()),
|
||||
playfield_(sdl.getRenderer()),
|
||||
border_(sdl.getRenderer()),
|
||||
fade_(sdl.getRenderer()) {
|
||||
curtain_(sdl.getRenderer()) {
|
||||
// Recuperar configuración de match des del context
|
||||
match_config_ = context_.getMatchConfig();
|
||||
|
||||
@@ -171,8 +171,9 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context)
|
||||
Audio::get()->enableSound(false);
|
||||
// El fons (graella) ha d'aparèixer ja muntat: la demo és una partida en marxa.
|
||||
playfield_.completeBuild();
|
||||
// Fosa des de negre sobre el joc ja en marxa (transició suau des del títol).
|
||||
fade_.start(1.0F, 0.0F, Defaults::Game::Fade::DEMO_IN_DURATION);
|
||||
// La cortinilla arrenca tapant i cau per destapar la demo (continua el
|
||||
// moviment iniciat al títol, que va acabar amb la pantalla negra).
|
||||
curtain_.reveal(Defaults::Game::Curtain::REVEAL_DURATION);
|
||||
} else {
|
||||
stage_manager_->init();
|
||||
}
|
||||
@@ -366,7 +367,7 @@ void GameScene::updateShipsControl(float delta_time) {
|
||||
}
|
||||
|
||||
auto GameScene::stepDemo(float delta_time) -> bool {
|
||||
fade_.update(delta_time); // fosa d'entrada des de negre
|
||||
curtain_.update(delta_time); // cortinilla que destapa la demo
|
||||
|
||||
// Qualsevol input trenca la demo i torna al títol (música intacta).
|
||||
if (Input::get()->checkAnyPlayerAction(DEMO_EXIT_ACTIONS)) {
|
||||
@@ -714,9 +715,9 @@ void GameScene::draw() {
|
||||
break;
|
||||
}
|
||||
|
||||
// Fosa d'entrada de la demo: per damunt de tot. No-op fora del mode DEMO
|
||||
// (fade_ mai s'arrenca) i quan ja ha acabat (alpha 0).
|
||||
fade_.draw();
|
||||
// Cortinilla d'entrada de la demo: per damunt de tot. No-op fora del mode
|
||||
// DEMO (curtain_ mai s'arrenca) i quan ja ha sortit per baix.
|
||||
curtain_.draw();
|
||||
}
|
||||
|
||||
void GameScene::drawEnemies() const {
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <string>
|
||||
|
||||
#include "core/graphics/border.hpp"
|
||||
#include "core/graphics/curtain.hpp"
|
||||
#include "core/graphics/playfield.hpp"
|
||||
#include "core/graphics/screen_fade.hpp"
|
||||
#include "core/graphics/starfield_parallax.hpp"
|
||||
#include "core/graphics/vector_text.hpp"
|
||||
#include "core/physics/physics_world.hpp"
|
||||
@@ -96,8 +96,8 @@ class GameScene final : public Scene {
|
||||
// Border del playfield (4 línies amb desplaçaments i flash per impactes)
|
||||
Graphics::Border border_;
|
||||
|
||||
// Fosa des de negre en entrar a la demo (només mode DEMO; inactiu en partida normal).
|
||||
Graphics::ScreenFade fade_;
|
||||
// Cortinilla que destapa en entrar a la demo (només mode DEMO; inactiva en partida normal).
|
||||
Graphics::Curtain curtain_;
|
||||
|
||||
// [NEW] Stage system
|
||||
std::unique_ptr<StageSystem::StageSystemConfig> stage_config_;
|
||||
|
||||
@@ -38,7 +38,7 @@ TitleScene::TitleScene(SDLManager& sdl, SceneContext& context)
|
||||
: sdl_(sdl),
|
||||
context_(context),
|
||||
text_(sdl.getRenderer()),
|
||||
fade_(sdl.getRenderer()) {
|
||||
curtain_(sdl.getRenderer()) {
|
||||
std::cout << "SceneType Titol: Inicialitzant...\n";
|
||||
|
||||
match_config_.player1_active = false;
|
||||
@@ -277,8 +277,9 @@ void TitleScene::dibuixarPeuTitol(float spacing) const {
|
||||
// a 1.0 (a la mida i posició finals, "lluny" al VP).
|
||||
const float SCREEN_CENTRE_X = Defaults::Game::WIDTH / 2.0F;
|
||||
const float SCREEN_CENTRE_Y = Defaults::Game::HEIGHT / 2.0F;
|
||||
const float JAILGAMES_S = std::lerp(S::FOOTER_INTRO_SCALE_START, 1.0F, Easing::easeOutQuad(intro_jailgames_progress_));
|
||||
const float COPYRIGHT_S = std::lerp(S::FOOTER_INTRO_SCALE_START, 1.0F, Easing::easeOutQuad(intro_copyright_progress_));
|
||||
// dive_zoom_ (attract) afegeix el zoom del dive per travessar el peu.
|
||||
const float JAILGAMES_S = dive_zoom_ * std::lerp(S::FOOTER_INTRO_SCALE_START, 1.0F, Easing::easeOutQuad(intro_jailgames_progress_));
|
||||
const float COPYRIGHT_S = dive_zoom_ * std::lerp(S::FOOTER_INTRO_SCALE_START, 1.0F, Easing::easeOutQuad(intro_copyright_progress_));
|
||||
|
||||
const float JAILGAMES_RENDER_SCALE = Defaults::Title::Layout::JAILGAMES_SCALE * JAILGAMES_S;
|
||||
for (const auto& letter : letters_jailgames_) {
|
||||
@@ -334,8 +335,11 @@ void TitleScene::update(float delta_time) {
|
||||
case TitleState::BLACK_SCREEN:
|
||||
updateBlackScreenState(delta_time);
|
||||
break;
|
||||
case TitleState::DEMO_FADE_OUT:
|
||||
updateDemoFadeOutState(delta_time);
|
||||
case TitleState::DEMO_DIVE:
|
||||
updateDemoDiveState(delta_time);
|
||||
break;
|
||||
case TitleState::DEMO_CURTAIN:
|
||||
updateDemoCurtainState(delta_time);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -372,11 +376,14 @@ void TitleScene::update(float delta_time) {
|
||||
demo_cfg.player2_active = (SC.players >= 2);
|
||||
demo_cfg.mode = GameConfig::Mode::DEMO;
|
||||
context_.setMatchConfig(demo_cfg);
|
||||
// No saltem en sec: fosa a negre i, en acabar, canvi a GAME (el salt
|
||||
// real el fa updateDemoFadeOutState). L'estat deixa de ser MAIN, així
|
||||
// que ni es re-dispara la demo ni s'accepta START durant la fosa.
|
||||
current_state_ = TitleState::DEMO_FADE_OUT;
|
||||
fade_.start(0.0F, 1.0F, Defaults::Game::Fade::DEMO_OUT_DURATION);
|
||||
// No saltem en sec: primer un "dive" de càmera cap al punt de fuga
|
||||
// (deixa enrere títol/naus/logo) i després la cortinilla. L'estat
|
||||
// deixa de ser MAIN, així que ni es re-dispara la demo ni s'accepta
|
||||
// START durant la transició. Amaguem ja el "PREMEU START".
|
||||
press_start_visible_ = false;
|
||||
current_state_ = TitleState::DEMO_DIVE;
|
||||
dive_time_ = 0.0F;
|
||||
dive_zoom_ = 1.0F;
|
||||
temps_acumulat_ = 0.0F;
|
||||
}
|
||||
}
|
||||
@@ -482,9 +489,29 @@ void TitleScene::updateBlackScreenState(float delta_time) {
|
||||
}
|
||||
}
|
||||
|
||||
void TitleScene::updateDemoFadeOutState(float delta_time) {
|
||||
fade_.update(delta_time);
|
||||
if (fade_.isDone()) {
|
||||
void TitleScene::updateDemoDiveState(float delta_time) {
|
||||
namespace D = Defaults::Game::Dive;
|
||||
dive_time_ += delta_time;
|
||||
const float T = std::min(dive_time_ / D::DURATION, 1.0F);
|
||||
const float EASED = Easing::easeInQuad(T); // acceleració cap al punt de fuga
|
||||
|
||||
// Càmera 3D real cap a +Z: starfield i naus es projecten amb la càmera, així
|
||||
// que les estrelles es rasguen i les naus creixen i s'escapen pels costats.
|
||||
if (camera_ != nullptr) {
|
||||
camera_->setPosition(Vec3{.x = 0.0F, .y = 0.0F, .z = EASED * D::CAMERA_DISTANCE});
|
||||
}
|
||||
// Logo i peu són 2D: els fakegem el dive amb un zoom des del centre.
|
||||
dive_zoom_ = std::lerp(1.0F, D::ZOOM_MAX, EASED);
|
||||
|
||||
if (T >= 1.0F) {
|
||||
current_state_ = TitleState::DEMO_CURTAIN;
|
||||
curtain_.cover(Defaults::Game::Curtain::COVER_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
void TitleScene::updateDemoCurtainState(float delta_time) {
|
||||
curtain_.update(delta_time);
|
||||
if (curtain_.isDone()) {
|
||||
context_.setNextScene(SceneType::GAME);
|
||||
}
|
||||
}
|
||||
@@ -594,7 +621,8 @@ void TitleScene::draw() {
|
||||
current_state_ == TitleState::STARFIELD ||
|
||||
current_state_ == TitleState::MAIN ||
|
||||
current_state_ == TitleState::PLAYER_JOIN_PHASE ||
|
||||
current_state_ == TitleState::DEMO_FADE_OUT)) {
|
||||
current_state_ == TitleState::DEMO_DIVE ||
|
||||
current_state_ == TitleState::DEMO_CURTAIN)) {
|
||||
ship_animator_->draw();
|
||||
}
|
||||
drawFlashes();
|
||||
@@ -603,19 +631,21 @@ void TitleScene::draw() {
|
||||
return;
|
||||
}
|
||||
|
||||
// DEMO_FADE_OUT es pinta com MAIN (logo + text) perquè el títol segueixi
|
||||
// visible sota la fosa a negre.
|
||||
// DEMO_DIVE/DEMO_CURTAIN es pinten com MAIN (logo + peu) perquè el títol
|
||||
// segueixi visible sota el dive i la cortinilla.
|
||||
if (current_state_ != TitleState::MAIN &&
|
||||
current_state_ != TitleState::PLAYER_JOIN_PHASE &&
|
||||
current_state_ != TitleState::DEMO_FADE_OUT) {
|
||||
fade_.draw(); // BLACK_SCREEN i altres: només la fosa (si activa)
|
||||
current_state_ != TitleState::DEMO_DIVE &&
|
||||
current_state_ != TitleState::DEMO_CURTAIN) {
|
||||
curtain_.draw(); // BLACK_SCREEN i altres: només la cortinilla (si activa)
|
||||
return;
|
||||
}
|
||||
|
||||
// Factor d'escala+posició per simular un moviment 3D des de l'usuari (prop,
|
||||
// sprite gran i posició projectada extrema) cap al VP (lluny, sprite a la
|
||||
// seva mida i posició finals). Pivot: centre de pantalla (= projecció VP).
|
||||
const float LOGO_S = std::lerp(Defaults::Title::Sequence::LOGO_INTRO_SCALE_START, 1.0F, Easing::easeOutQuad(intro_logo_progress_));
|
||||
// El dive (attract) hi afegeix un zoom extra (dive_zoom_) per travessar-los.
|
||||
const float LOGO_S = dive_zoom_ * std::lerp(Defaults::Title::Sequence::LOGO_INTRO_SCALE_START, 1.0F, Easing::easeOutQuad(intro_logo_progress_));
|
||||
const float SCREEN_CENTRE_X = Defaults::Game::WIDTH / 2.0F;
|
||||
const float SCREEN_CENTRE_Y = Defaults::Game::HEIGHT / 2.0F;
|
||||
const float LOGO_RENDER_SCALE = Defaults::Title::Layout::LOGO_SCALE * LOGO_S;
|
||||
@@ -680,8 +710,8 @@ void TitleScene::draw() {
|
||||
|
||||
dibuixarPeuTitol(SPACING);
|
||||
|
||||
// Fosa a negre (attract): per damunt de tot. No-op si no està activa.
|
||||
fade_.draw();
|
||||
// Cortinilla negra (attract): per damunt de tot. No-op si no està activa.
|
||||
curtain_.draw();
|
||||
}
|
||||
|
||||
auto TitleScene::checkSkipButtonPressed() -> bool {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "core/graphics/camera3d.hpp"
|
||||
#include "core/graphics/screen_fade.hpp"
|
||||
#include "core/graphics/curtain.hpp"
|
||||
#include "core/graphics/shape.hpp"
|
||||
#include "core/graphics/starfield.hpp"
|
||||
#include "core/graphics/vector_text.hpp"
|
||||
@@ -47,7 +47,8 @@ class TitleScene final : public Scene {
|
||||
MAIN,
|
||||
PLAYER_JOIN_PHASE,
|
||||
BLACK_SCREEN,
|
||||
DEMO_FADE_OUT, // Attract: fosa a negre abans de saltar a la demo
|
||||
DEMO_DIVE, // Attract: dive de càmera cap al punt de fuga
|
||||
DEMO_CURTAIN, // Attract: cortinilla negra que cau i tapa abans del salt
|
||||
};
|
||||
|
||||
struct LogoLetter {
|
||||
@@ -62,7 +63,7 @@ class TitleScene final : public Scene {
|
||||
SceneManager::SceneContext& context_;
|
||||
GameConfig::MatchConfig match_config_;
|
||||
Graphics::VectorText text_;
|
||||
Graphics::ScreenFade fade_; // Fosa a negre en saltar a la demo (attract)
|
||||
Graphics::Curtain curtain_; // Cortinilla negra en saltar a la demo (attract)
|
||||
std::unique_ptr<Graphics::Camera3D> camera_;
|
||||
std::unique_ptr<Graphics::Starfield> starfield_;
|
||||
std::unique_ptr<Title::ShipAnimator> ship_animator_;
|
||||
@@ -84,6 +85,11 @@ class TitleScene final : public Scene {
|
||||
float temps_acumulat_{0.0F};
|
||||
float idle_timer_{0.0F}; // Attract mode: inactivitat acumulada al state MAIN
|
||||
|
||||
// Dive (attract): temps transcorregut i zoom aplicat als elements 2D
|
||||
// (logo + peu) mentre la càmera avança cap al punt de fuga.
|
||||
float dive_time_{0.0F};
|
||||
float dive_zoom_{1.0F};
|
||||
|
||||
std::vector<LogoLetter> letters_orni_;
|
||||
std::vector<LogoLetter> letters_attack_;
|
||||
float dynamic_attack_y_{0.0F};
|
||||
@@ -146,7 +152,8 @@ class TitleScene final : public Scene {
|
||||
void updateMainState(float delta_time);
|
||||
void updatePlayerJoinPhaseState(float delta_time);
|
||||
void updateBlackScreenState(float delta_time);
|
||||
void updateDemoFadeOutState(float delta_time);
|
||||
void updateDemoDiveState(float delta_time);
|
||||
void updateDemoCurtainState(float delta_time);
|
||||
void handleSkipInput();
|
||||
void handleStartInput();
|
||||
void triggerExitForJoinedPlayers(bool p1_was_active, bool p2_was_active, const char* log_prefix);
|
||||
|
||||
Reference in New Issue
Block a user