time-based: migrada escena Title (AnimatedSprite/Fade amb dual-API, counters a acumuladors)
This commit is contained in:
@@ -2,9 +2,10 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <cstdlib> // for rand
|
||||
#include <iostream> // for basic_ostream, operator<<, basic_ostrea...
|
||||
#include <string> // for basic_string, operator+, char_traits
|
||||
#include <algorithm> // for min
|
||||
#include <cstdlib> // for rand
|
||||
#include <iostream> // for basic_ostream, operator<<, basic_ostrea...
|
||||
#include <string> // for basic_string, operator+, char_traits
|
||||
|
||||
#include "core/audio/audio.hpp" // for Audio
|
||||
#include "core/input/global_inputs.hpp" // for GlobalInputs::handle
|
||||
@@ -19,10 +20,11 @@
|
||||
#include "core/rendering/texture.h" // for Texture
|
||||
#include "core/resources/asset.h" // for Asset
|
||||
#include "core/resources/resource.h"
|
||||
#include "game/defaults.hpp" // for GAMECANVAS_CENTER_X, SECTION_PROG_QUIT
|
||||
#include "game/game.h" // for Game
|
||||
#include "game/options.hpp" // for Options
|
||||
#include "game/ui/menu.h" // for Menu
|
||||
#include "core/system/delta_time.hpp" // for DeltaTime::reset / tick
|
||||
#include "game/defaults.hpp" // for GAMECANVAS_CENTER_X, SECTION_PROG_QUIT
|
||||
#include "game/game.h" // for Game
|
||||
#include "game/options.hpp" // for Options
|
||||
#include "game/ui/menu.h" // for Menu
|
||||
|
||||
// Constructor
|
||||
Title::Title(SDL_Renderer *renderer, Section *section) {
|
||||
@@ -70,6 +72,9 @@ Title::Title(SDL_Renderer *renderer, Section *section) {
|
||||
|
||||
// Inicializa los valores
|
||||
init();
|
||||
|
||||
// Reset del rellotge: la primera crida a tick() retornarà ~0.
|
||||
DeltaTime::reset();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
@@ -92,18 +97,19 @@ Title::~Title() {
|
||||
void Title::init() {
|
||||
// Inicializa variables
|
||||
section_->subsection = SUBSECTION_TITLE_1;
|
||||
counter_ = COUNTER;
|
||||
background_counter_ = 0;
|
||||
demo_remaining_s_ = DEMO_TIMEOUT_S;
|
||||
bg_scroll_x_s_ = 0.0F;
|
||||
bg_scroll_y_s_ = 0.0F;
|
||||
bg_phase_s_ = 0.0F;
|
||||
blink_phase_s_ = 0.0F;
|
||||
background_mode_ = rand() % 2;
|
||||
menu_visible_ = false;
|
||||
menu_.active = menu_.title;
|
||||
next_section_.name = SECTION_PROG_GAME;
|
||||
post_fade_ = 0;
|
||||
ticks_ = 0;
|
||||
ticks_speed_ = 15;
|
||||
fade_->init(0x17, 0x17, 0x26);
|
||||
demo_ = true;
|
||||
vibration_step_ = 0;
|
||||
vibration_elapsed_s_ = 0.0F;
|
||||
vibration_initialized_ = false;
|
||||
instructions_active_ = false;
|
||||
demo_game_active_ = false;
|
||||
@@ -148,12 +154,12 @@ void Title::init() {
|
||||
coffee_bitmap_->setWidth(167);
|
||||
coffee_bitmap_->setHeight(46);
|
||||
coffee_bitmap_->setVelX(0.0F);
|
||||
coffee_bitmap_->setVelY(2.5F);
|
||||
coffee_bitmap_->setVelY(150.0F); // 2.5 px/tick ⇒ 150 px/s
|
||||
coffee_bitmap_->setAccelX(0.0F);
|
||||
coffee_bitmap_->setAccelY(0.1F);
|
||||
coffee_bitmap_->setAccelY(360.0F); // 0.1 px/tick² ⇒ 360 px/s²
|
||||
coffee_bitmap_->setSpriteClip(0, 0, 167, 46);
|
||||
coffee_bitmap_->setEnabled(true);
|
||||
coffee_bitmap_->setEnabledCounter(0);
|
||||
coffee_bitmap_->setRemainingTime(0.0F);
|
||||
coffee_bitmap_->setDestX(45);
|
||||
coffee_bitmap_->setDestY(11);
|
||||
|
||||
@@ -164,12 +170,12 @@ void Title::init() {
|
||||
crisis_bitmap_->setWidth(137);
|
||||
crisis_bitmap_->setHeight(46);
|
||||
crisis_bitmap_->setVelX(0.0F);
|
||||
crisis_bitmap_->setVelY(-2.5F);
|
||||
crisis_bitmap_->setVelY(-150.0F); // -2.5 px/tick ⇒ -150 px/s
|
||||
crisis_bitmap_->setAccelX(0.0F);
|
||||
crisis_bitmap_->setAccelY(-0.1F);
|
||||
crisis_bitmap_->setAccelY(-360.0F); // -0.1 px/tick² ⇒ -360 px/s²
|
||||
crisis_bitmap_->setSpriteClip(0, 0, 137, 46);
|
||||
crisis_bitmap_->setEnabled(true);
|
||||
crisis_bitmap_->setEnabledCounter(0);
|
||||
crisis_bitmap_->setRemainingTime(0.0F);
|
||||
crisis_bitmap_->setDestX(60);
|
||||
crisis_bitmap_->setDestY(57);
|
||||
|
||||
@@ -209,25 +215,20 @@ void Title::init() {
|
||||
updateMenuLabels();
|
||||
}
|
||||
|
||||
// Actualiza las variables del objeto
|
||||
void Title::update() {
|
||||
// Actualiza las variables del objeto (time-based)
|
||||
void Title::update(float dt_s) {
|
||||
Audio::update();
|
||||
checkInput();
|
||||
|
||||
if (SDL_GetTicks() - ticks_ <= ticks_speed_) {
|
||||
return;
|
||||
}
|
||||
ticks_ = SDL_GetTicks();
|
||||
|
||||
switch (section_->subsection) {
|
||||
case SUBSECTION_TITLE_1:
|
||||
updateTitle1();
|
||||
updateTitle1(dt_s);
|
||||
break;
|
||||
case SUBSECTION_TITLE_2:
|
||||
updateTitle2();
|
||||
updateTitle2(dt_s);
|
||||
break;
|
||||
case SUBSECTION_TITLE_3:
|
||||
updateTitle3();
|
||||
updateTitle3(dt_s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -235,9 +236,9 @@ void Title::update() {
|
||||
}
|
||||
|
||||
// Sección 1 - Titulo desplazandose
|
||||
void Title::updateTitle1() {
|
||||
coffee_bitmap_->update();
|
||||
crisis_bitmap_->update();
|
||||
void Title::updateTitle1(float dt_s) {
|
||||
coffee_bitmap_->update(dt_s);
|
||||
crisis_bitmap_->update(dt_s);
|
||||
|
||||
// Si los objetos han llegado a su destino, cambiamos de Sección
|
||||
if (coffee_bitmap_->hasFinished() && crisis_bitmap_->hasFinished()) {
|
||||
@@ -257,7 +258,7 @@ void Title::updateTitle1() {
|
||||
}
|
||||
|
||||
// Sección 2 - Titulo vibrando
|
||||
void Title::updateTitle2() {
|
||||
void Title::updateTitle2(float dt_s) {
|
||||
// Captura las posiciones base la primera vez
|
||||
if (!vibration_initialized_) {
|
||||
vibration_coffee_base_x_ = coffee_bitmap_->getPosX();
|
||||
@@ -265,37 +266,44 @@ void Title::updateTitle2() {
|
||||
vibration_initialized_ = true;
|
||||
}
|
||||
|
||||
// Patró d'offset horitzontal (15 valors, una vegada cadascun cada 3 frames)
|
||||
const int V[] = {-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 0};
|
||||
coffee_bitmap_->setPosX(vibration_coffee_base_x_ + V[vibration_step_ / 3]);
|
||||
crisis_bitmap_->setPosX(vibration_crisis_base_x_ + V[vibration_step_ / 3]);
|
||||
dust_bitmap_right_->update();
|
||||
dust_bitmap_left_->update();
|
||||
constexpr int V_SIZE = static_cast<int>(sizeof(V) / sizeof(V[0]));
|
||||
const int IDX = std::min(static_cast<int>(vibration_elapsed_s_ / VIBRATION_STEP_DURATION_S), V_SIZE - 1);
|
||||
coffee_bitmap_->setPosX(vibration_coffee_base_x_ + V[IDX]);
|
||||
crisis_bitmap_->setPosX(vibration_crisis_base_x_ + V[IDX]);
|
||||
dust_bitmap_right_->update(dt_s);
|
||||
dust_bitmap_left_->update(dt_s);
|
||||
|
||||
vibration_step_++;
|
||||
vibration_elapsed_s_ += dt_s;
|
||||
|
||||
if (vibration_step_ >= 33) {
|
||||
if (vibration_elapsed_s_ >= VIBRATION_DURATION_S) {
|
||||
section_->subsection = SUBSECTION_TITLE_3;
|
||||
vibration_step_ = 0;
|
||||
vibration_elapsed_s_ = 0.0F;
|
||||
vibration_initialized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Sección 3 - La pantalla de titulo con el menú y la música
|
||||
void Title::updateTitle3() {
|
||||
if (counter_ > 0) {
|
||||
void Title::updateTitle3(float dt_s) {
|
||||
if (demo_remaining_s_ > 0.0F) {
|
||||
if (Audio::getRealMusicState() == Audio::MusicState::STOPPED) {
|
||||
Audio::get()->playMusic(title_music_);
|
||||
}
|
||||
|
||||
dust_bitmap_right_->update();
|
||||
dust_bitmap_left_->update();
|
||||
fade_->update();
|
||||
dust_bitmap_right_->update(dt_s);
|
||||
dust_bitmap_left_->update(dt_s);
|
||||
fade_->update(dt_s);
|
||||
|
||||
if (fade_->hasEnded()) {
|
||||
handlePostFadeAction();
|
||||
}
|
||||
|
||||
updateBG();
|
||||
updateBG(dt_s);
|
||||
blink_phase_s_ += dt_s;
|
||||
if (blink_phase_s_ >= PRESS_ANY_KEY_PERIOD_S) {
|
||||
blink_phase_s_ -= PRESS_ANY_KEY_PERIOD_S;
|
||||
}
|
||||
|
||||
if (menu_visible_ && !fade_->isEnabled()) {
|
||||
menu_.active->update();
|
||||
@@ -312,9 +320,9 @@ void Title::updateTitle3() {
|
||||
}
|
||||
|
||||
if (menu_.active->getName() == "TITLE") {
|
||||
counter_--;
|
||||
demo_remaining_s_ -= dt_s;
|
||||
}
|
||||
} else if (counter_ == 0) {
|
||||
} else {
|
||||
if (demo_) {
|
||||
demo_then_instructions_ = true;
|
||||
runDemoGame();
|
||||
@@ -351,7 +359,7 @@ void Title::handlePostFadeAction() {
|
||||
break;
|
||||
|
||||
case 3: // TIME OUT
|
||||
counter_ = COUNTER;
|
||||
demo_remaining_s_ = DEMO_TIMEOUT_S;
|
||||
menu_.active->reset();
|
||||
if (demo_) {
|
||||
demo_then_instructions_ = true;
|
||||
@@ -602,8 +610,8 @@ void Title::render() {
|
||||
dust_bitmap_right_->render();
|
||||
dust_bitmap_left_->render();
|
||||
|
||||
// PRESS ANY KEY!
|
||||
if ((counter_ % 50 > 14) && (!menu_visible_)) {
|
||||
// PRESS ANY KEY! Blink: visible quan la fase passa l'umbral "off".
|
||||
if ((blink_phase_s_ > PRESS_ANY_KEY_OFF_S) && (!menu_visible_)) {
|
||||
text1_->writeDX(Text::FLAG_CENTER | Text::FLAG_SHADOW, GAMECANVAS_CENTER_X, PLAY_AREA_THIRD_QUARTER_Y + BLOCK, Lang::get()->getText(23), 1, NO_COLOR, 1, SHADOW_COLOR);
|
||||
}
|
||||
|
||||
@@ -626,15 +634,24 @@ void Title::checkInput() {
|
||||
GlobalInputs::handle();
|
||||
}
|
||||
|
||||
// Actualiza el tileado de fondo
|
||||
void Title::updateBG() {
|
||||
if (background_mode_ == 0) { // El tileado de fondo se desplaza en diagonal
|
||||
++background_window_.x %= 64;
|
||||
++background_window_.y %= 64;
|
||||
} else { // El tileado de fondo se desplaza en circulo
|
||||
++background_counter_ %= 360;
|
||||
background_window_.x = 128 + (int(sin_[(background_counter_ + 270) % 360] * 128));
|
||||
background_window_.y = 96 + (int(sin_[(360 - background_counter_) % 360] * 96));
|
||||
// Actualiza el tileado de fondo (time-based).
|
||||
void Title::updateBG(float dt_s) {
|
||||
if (background_mode_ == 0) {
|
||||
// Diagonal: 60 px/s a 60Hz ⇒ un cicle de 64 px cada 64/60 = 1.067 s.
|
||||
constexpr float SCROLL_PERIOD_S = 64.0F / BG_SCROLL_SPEED_PX_PER_S;
|
||||
bg_scroll_x_s_ += dt_s;
|
||||
bg_scroll_y_s_ += dt_s;
|
||||
if (bg_scroll_x_s_ >= SCROLL_PERIOD_S) { bg_scroll_x_s_ -= SCROLL_PERIOD_S; }
|
||||
if (bg_scroll_y_s_ >= SCROLL_PERIOD_S) { bg_scroll_y_s_ -= SCROLL_PERIOD_S; }
|
||||
background_window_.x = static_cast<int>(bg_scroll_x_s_ * BG_SCROLL_SPEED_PX_PER_S);
|
||||
background_window_.y = static_cast<int>(bg_scroll_y_s_ * BG_SCROLL_SPEED_PX_PER_S);
|
||||
} else {
|
||||
// Cercle: 360 graus en BG_CIRCLE_PERIOD_S segons.
|
||||
bg_phase_s_ += dt_s;
|
||||
if (bg_phase_s_ >= BG_CIRCLE_PERIOD_S) { bg_phase_s_ -= BG_CIRCLE_PERIOD_S; }
|
||||
const int ANGLE = static_cast<int>((bg_phase_s_ / BG_CIRCLE_PERIOD_S) * 360.0F) % 360;
|
||||
background_window_.x = 128 + (int(sin_[(ANGLE + 270) % 360] * 128));
|
||||
background_window_.y = 96 + (int(sin_[(360 - ANGLE) % 360] * 96));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -892,7 +909,8 @@ void Title::iterate() {
|
||||
}
|
||||
|
||||
// Ejecución normal del título
|
||||
update();
|
||||
const float DELTA_TIME_S = DeltaTime::tick();
|
||||
update(DELTA_TIME_S);
|
||||
render();
|
||||
}
|
||||
|
||||
@@ -918,7 +936,7 @@ void Title::handleEvent(const SDL_Event *event) {
|
||||
if (section_->subsection == SUBSECTION_TITLE_3) {
|
||||
if ((event->type == SDL_EVENT_KEY_UP) || (event->type == SDL_EVENT_JOYSTICK_BUTTON_UP)) {
|
||||
menu_visible_ = true;
|
||||
counter_ = COUNTER;
|
||||
demo_remaining_s_ = DEMO_TIMEOUT_S;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user