Files
coffee-crisis/source/game/scenes/logo.cpp
T

131 lines
4.0 KiB
C++

#include "game/scenes/logo.h"
#include <SDL3/SDL.h>
#include <algorithm> // for min
#include <string> // for basic_string
#include "core/audio/audio.hpp" // for Audio::get, Audio::update
#include "core/input/global_inputs.hpp" // for GlobalInputs::handle
#include "core/input/input.h" // for Input, Input::Repeat::OFF, InputAction
#include "core/rendering/screen.h" // for Screen
#include "core/rendering/sprite.h" // for Sprite
#include "core/resources/resource.h"
#include "core/system/delta_time.hpp" // for DeltaTime::reset / tick
#include "game/defaults.hpp" // for bgColor, SECTION_PROG_LOGO, SECTION_PROG...
#include "utils/utils.h" // for Section, Color
// Durades de l'escena (segons). Time-based: ja no comptem frames. Valors
// equivalents al comportament anterior (frame counter a 15ms): 100 i 200
// frames ⇒ 1.5s i 3.0s; fi a 220 frames ⇒ 3.3s.
constexpr float FADE_START_S = 1.5F;
constexpr float FADE_END_S = 3.0F;
constexpr float SCENE_END_S = 3.3F;
// Constructor
Logo::Logo(SDL_Renderer *renderer, Section *section) {
// Copia la dirección de los objetos
this->renderer_ = renderer;
this->section_ = section;
// Reserva memoria para los punteros
event_handler_ = new SDL_Event();
texture_ = Resource::get()->getTexture("logo.png");
sprite_ = new Sprite(14, 75, 226, 44, texture_, renderer);
// Inicializa variables
section->name = SECTION_PROG_LOGO;
section->subsection = 0;
Audio::get()->stopMusic();
// Reset del rellotge: la primera crida a tick() retornarà ~0 i no un
// delta gegant arrossegat des del boot o l'escena anterior.
DeltaTime::reset();
}
// Destructor
Logo::~Logo() {
// texture es propiedad de Resource — no liberar aquí.
delete sprite_;
delete event_handler_;
}
// Comprueba si ha terminado el logo
void Logo::checkLogoEnd() {
if (elapsed_time_s_ >= SCENE_END_S) {
section_->name = SECTION_PROG_INTRO;
section_->subsection = 0;
}
}
// Comprueba las entradas
void Logo::checkInput() {
// ESC (Action::EXIT) ja el gestiona GlobalInputs::handle() amb doble
// pulsació; el quit es propaga via Director::iterate.
if (GlobalInputs::handle()) { return; }
if (Input::get()->checkInput(Input::Action::ACCEPT, Input::Repeat::OFF) || Input::get()->checkInput(Input::Action::FIRE_LEFT, Input::Repeat::OFF) || Input::get()->checkInput(Input::Action::FIRE_CENTER, Input::Repeat::OFF) || Input::get()->checkInput(Input::Action::FIRE_RIGHT, Input::Repeat::OFF)) {
section_->name = SECTION_PROG_TITLE;
section_->subsection = SUBSECTION_TITLE_1;
}
}
// Dibuja el fade
void Logo::renderFade() {
if (elapsed_time_s_ >= FADE_START_S) {
const float STEP = (elapsed_time_s_ - FADE_START_S) / (FADE_END_S - FADE_START_S);
const int ALPHA = std::min((int)(255 * STEP), 255);
SDL_SetRenderDrawColor(renderer_, BG_COLOR.r, BG_COLOR.g, BG_COLOR.b, ALPHA);
SDL_RenderFillRect(renderer_, nullptr);
}
}
// Actualiza las variables del objeto
void Logo::update(float delta_time_s) {
Audio::update();
checkInput();
elapsed_time_s_ += delta_time_s;
checkLogoEnd();
}
// Dibuja el objeto en pantalla
void Logo::render() {
// Prepara para empezar a dibujar en la textura de juego
Screen::get()->start();
// Limpia la pantalla
Screen::get()->clean({238, 238, 238});
// Dibuja los objetos
sprite_->render();
// Dibuja el fade
renderFade();
// Vuelca el contenido del renderizador en pantalla
Screen::get()->blit();
}
// Bucle para el logo del juego
void Logo::run() {
Audio::get()->stopMusic();
while (section_->name == SECTION_PROG_LOGO) {
iterate();
}
}
// Ejecuta un frame
void Logo::iterate() {
const float DELTA_TIME_S = DeltaTime::tick();
update(DELTA_TIME_S);
render();
}
// Procesa un evento individual
void Logo::handleEvent(const SDL_Event * /*event*/) {
// SDL_EVENT_QUIT ya lo maneja Director
}