forked from jaildesigner-jailgames/jaildoctors_dilemma
afegit pixel_reveal a credits i a ending
This commit is contained in:
@@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
#include <algorithm> // Para min
|
#include <algorithm> // Para min
|
||||||
#include <numeric> // Para iota
|
#include <numeric> // Para iota
|
||||||
|
#include <queue> // Para queue (BFS en modo ORDERED)
|
||||||
#include <random> // Para mt19937, shuffle
|
#include <random> // Para mt19937, shuffle
|
||||||
|
|
||||||
#include "core/rendering/surface.hpp" // Para Surface
|
#include "core/rendering/surface.hpp" // Para Surface
|
||||||
#include "utils/utils.hpp" // Para PaletteColor
|
#include "utils/utils.hpp" // Para PaletteColor
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
PixelReveal::PixelReveal(int width, int height, float pixels_per_second, float step_duration, int num_steps)
|
PixelReveal::PixelReveal(int width, int height, float pixels_per_second, float step_duration, int num_steps, bool reverse, RevealMode mode)
|
||||||
: cover_surface_(std::make_shared<Surface>(width, height)),
|
: cover_surface_(std::make_shared<Surface>(width, height)),
|
||||||
reveal_order_(height),
|
reveal_order_(height),
|
||||||
row_step_(height, 0),
|
row_step_(height, 0),
|
||||||
@@ -16,17 +17,52 @@ PixelReveal::PixelReveal(int width, int height, float pixels_per_second, float s
|
|||||||
height_(height),
|
height_(height),
|
||||||
pixels_per_second_(pixels_per_second),
|
pixels_per_second_(pixels_per_second),
|
||||||
step_duration_(step_duration),
|
step_duration_(step_duration),
|
||||||
num_steps_(num_steps) {
|
num_steps_(num_steps),
|
||||||
// Rellena la máscara con negro sólido
|
reverse_(reverse),
|
||||||
cover_surface_->clear(static_cast<Uint8>(PaletteColor::BLACK));
|
mode_(mode) {
|
||||||
|
// En modo normal: empieza negro sólido (se irá revelando a transparente)
|
||||||
|
// En modo inverso: empieza transparente (se irá cubriendo de negro)
|
||||||
|
const auto INITIAL_COLOR = reverse_ ? static_cast<Uint8>(PaletteColor::TRANSPARENT) : static_cast<Uint8>(PaletteColor::BLACK);
|
||||||
|
cover_surface_->clear(INITIAL_COLOR);
|
||||||
|
|
||||||
// Genera el orden aleatorio de columnas por fila usando la fila como semilla (reproducible)
|
if (mode_ == RevealMode::ORDERED) {
|
||||||
|
// Calcula offsets por bisección BFS: 0, N/2, N/4, 3N/4, ...
|
||||||
|
std::vector<int> offsets;
|
||||||
|
offsets.push_back(0);
|
||||||
|
std::queue<std::pair<int, int>> bq;
|
||||||
|
bq.push({0, num_steps_});
|
||||||
|
while (static_cast<int>(offsets.size()) < num_steps_) {
|
||||||
|
auto [lo, hi] = bq.front();
|
||||||
|
bq.pop();
|
||||||
|
if (hi - lo <= 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const int MID = (lo + hi) / 2;
|
||||||
|
offsets.push_back(MID);
|
||||||
|
bq.push({lo, MID});
|
||||||
|
bq.push({MID, hi});
|
||||||
|
}
|
||||||
|
// Genera el orden: para cada offset, todas las columnas col = offset, offset+N, offset+2N, ...
|
||||||
|
std::vector<int> ordered_cols;
|
||||||
|
ordered_cols.reserve(width_);
|
||||||
|
for (const int off : offsets) {
|
||||||
|
for (int col = off; col < width_; col += num_steps_) {
|
||||||
|
ordered_cols.push_back(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Todas las filas usan el mismo orden (sin aleatoriedad)
|
||||||
|
for (int r = 0; r < height_; r++) {
|
||||||
|
reveal_order_[r] = ordered_cols;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Modo RANDOM: orden aleatorio por fila usando la fila como semilla (reproducible)
|
||||||
for (int r = 0; r < height_; r++) {
|
for (int r = 0; r < height_; r++) {
|
||||||
reveal_order_[r].resize(width_);
|
reveal_order_[r].resize(width_);
|
||||||
std::iota(reveal_order_[r].begin(), reveal_order_[r].end(), 0);
|
std::iota(reveal_order_[r].begin(), reveal_order_[r].end(), 0);
|
||||||
std::mt19937 rng(static_cast<unsigned int>(r));
|
std::mt19937 rng(static_cast<unsigned int>(r));
|
||||||
std::shuffle(reveal_order_[r].begin(), reveal_order_[r].end(), rng);
|
std::shuffle(reveal_order_[r].begin(), reveal_order_[r].end(), rng);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
@@ -34,7 +70,8 @@ PixelReveal::~PixelReveal() = default;
|
|||||||
|
|
||||||
// Actualiza el estado del revelado
|
// Actualiza el estado del revelado
|
||||||
void PixelReveal::update(float time_active) {
|
void PixelReveal::update(float time_active) {
|
||||||
const auto TRANSPARENT = static_cast<Uint8>(PaletteColor::TRANSPARENT);
|
// En modo normal revela (pone transparente); en modo inverso cubre (pone negro)
|
||||||
|
const auto PIXEL_COLOR = reverse_ ? static_cast<Uint8>(PaletteColor::BLACK) : static_cast<Uint8>(PaletteColor::TRANSPARENT);
|
||||||
|
|
||||||
for (int r = 0; r < height_; r++) {
|
for (int r = 0; r < height_; r++) {
|
||||||
const float T_START = static_cast<float>(r) / pixels_per_second_;
|
const float T_START = static_cast<float>(r) / pixels_per_second_;
|
||||||
@@ -47,14 +84,14 @@ void PixelReveal::update(float time_active) {
|
|||||||
const int STEPS = std::min(num_steps_, static_cast<int>(TIME_IN_ROW / step_duration_));
|
const int STEPS = std::min(num_steps_, static_cast<int>(TIME_IN_ROW / step_duration_));
|
||||||
|
|
||||||
if (STEPS > row_step_[r]) {
|
if (STEPS > row_step_[r]) {
|
||||||
// Revela los píxeles de los pasos pendientes
|
// Procesa los píxeles de los pasos pendientes
|
||||||
for (int step = row_step_[r]; step < STEPS; step++) {
|
for (int step = row_step_[r]; step < STEPS; step++) {
|
||||||
const int START_IDX = step * width_ / num_steps_;
|
const int START_IDX = step * width_ / num_steps_;
|
||||||
const int END_IDX = (step == num_steps_ - 1) ? width_ : (step + 1) * width_ / num_steps_;
|
const int END_IDX = (step == num_steps_ - 1) ? width_ : (step + 1) * width_ / num_steps_;
|
||||||
|
|
||||||
for (int idx = START_IDX; idx < END_IDX; idx++) {
|
for (int idx = START_IDX; idx < END_IDX; idx++) {
|
||||||
const int COL = reveal_order_[r][idx];
|
const int COL = reveal_order_[r][idx];
|
||||||
cover_surface_->putPixel(COL, r, TRANSPARENT);
|
cover_surface_->putPixel(COL, r, PIXEL_COLOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
row_step_[r] = STEPS;
|
row_step_[r] = STEPS;
|
||||||
|
|||||||
@@ -6,11 +6,15 @@
|
|||||||
class Surface;
|
class Surface;
|
||||||
|
|
||||||
// Efecto de revelado pixel a pixel por filas, de arriba a abajo.
|
// Efecto de revelado pixel a pixel por filas, de arriba a abajo.
|
||||||
// Cada fila se revela en num_steps pasos, con píxeles aleatorios en cada paso.
|
// Cada fila se revela en num_steps pasos, con píxeles en orden aleatorio u ordenado (bisección).
|
||||||
class PixelReveal {
|
class PixelReveal {
|
||||||
public:
|
public:
|
||||||
|
// Modo de revelado: aleatorio por fila o en orden de bisección (dithering ordenado 1D)
|
||||||
|
enum class RevealMode { RANDOM,
|
||||||
|
ORDERED };
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
PixelReveal(int width, int height, float pixels_per_second, float step_duration, int num_steps = 4);
|
PixelReveal(int width, int height, float pixels_per_second, float step_duration, int num_steps = 4, bool reverse = false, RevealMode mode = RevealMode::RANDOM);
|
||||||
|
|
||||||
// Destructor definido en el .cpp para que unique_ptr<Surface> funcione con forward declaration
|
// Destructor definido en el .cpp para que unique_ptr<Surface> funcione con forward declaration
|
||||||
~PixelReveal();
|
~PixelReveal();
|
||||||
@@ -26,11 +30,13 @@ class PixelReveal {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Surface> cover_surface_; // Máscara negra que se va haciendo transparente
|
std::shared_ptr<Surface> cover_surface_; // Máscara negra que se va haciendo transparente
|
||||||
std::vector<std::vector<int>> reveal_order_; // Orden aleatorio de columnas por fila
|
std::vector<std::vector<int>> reveal_order_; // Orden de columnas por fila (aleatorio u ordenado por bisección)
|
||||||
std::vector<int> row_step_; // Paso actual de revelado por fila (0..num_steps_)
|
std::vector<int> row_step_; // Paso actual de revelado por fila (0..num_steps_)
|
||||||
int width_;
|
int width_;
|
||||||
int height_;
|
int height_;
|
||||||
float pixels_per_second_; // Filas reveladas por segundo
|
float pixels_per_second_; // Filas reveladas por segundo
|
||||||
float step_duration_; // Segundos por paso dentro de una fila
|
float step_duration_; // Segundos por paso dentro de una fila
|
||||||
int num_steps_; // Número de pasos de revelado por fila
|
int num_steps_; // Número de pasos de revelado por fila
|
||||||
|
bool reverse_; // Si true: transparente → negro (ocultar); si false: negro → transparente (revelar)
|
||||||
|
RevealMode mode_; // Modo de revelado: aleatorio u ordenado por bisección
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -100,21 +100,21 @@ namespace Game {
|
|||||||
|
|
||||||
namespace Room {
|
namespace Room {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
constexpr const char* INITIAL = "51.yaml"; // Habitación de inicio en debug
|
constexpr const char* INITIAL = "51.yaml"; // Habitación de inicio en debug
|
||||||
#else
|
#else
|
||||||
constexpr const char* INITIAL = "03.yaml"; // Habitación de inicio en release
|
constexpr const char* INITIAL = "03.yaml"; // Habitación de inicio en release
|
||||||
#endif
|
#endif
|
||||||
} // namespace Room
|
} // namespace Room
|
||||||
|
|
||||||
namespace Player {
|
namespace Player {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
constexpr int SPAWN_X = 26 * Tile::SIZE; // Posición X inicial en debug
|
constexpr int SPAWN_X = 26 * Tile::SIZE; // Posición X inicial en debug
|
||||||
constexpr int SPAWN_Y = 10 * Tile::SIZE; // Posición Y inicial en debug
|
constexpr int SPAWN_Y = 10 * Tile::SIZE; // Posición Y inicial en debug
|
||||||
constexpr SDL_FlipMode SPAWN_FLIP = Flip::LEFT; // Orientación inicial en debug
|
constexpr SDL_FlipMode SPAWN_FLIP = Flip::LEFT; // Orientación inicial en debug
|
||||||
#else
|
#else
|
||||||
constexpr int SPAWN_X = 25 * Tile::SIZE; // Posición X inicial en release
|
constexpr int SPAWN_X = 25 * Tile::SIZE; // Posición X inicial en release
|
||||||
constexpr int SPAWN_Y = 13 * Tile::SIZE; // Posición Y inicial en release
|
constexpr int SPAWN_Y = 13 * Tile::SIZE; // Posición Y inicial en release
|
||||||
constexpr SDL_FlipMode SPAWN_FLIP = Flip::LEFT; // Orientación inicial en release
|
constexpr SDL_FlipMode SPAWN_FLIP = Flip::LEFT; // Orientación inicial en release
|
||||||
#endif
|
#endif
|
||||||
} // namespace Player
|
} // namespace Player
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ enum class Options {
|
|||||||
|
|
||||||
// --- Variables de estado globales ---
|
// --- Variables de estado globales ---
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
inline Scene current = Scene::ENDING; // Escena actual
|
inline Scene current = Scene::CREDITS; // Escena actual
|
||||||
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
|
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
|
||||||
#else
|
#else
|
||||||
inline Scene current = Scene::LOGO; // Escena actual
|
inline Scene current = Scene::LOGO; // Escena actual
|
||||||
|
|||||||
@@ -31,11 +31,9 @@ Credits::Credits()
|
|||||||
SceneManager::options = SceneManager::Options::NONE;
|
SceneManager::options = SceneManager::Options::NONE;
|
||||||
shining_sprite_->setPos({194, 174, 8, 8});
|
shining_sprite_->setPos({194, 174, 8, 8});
|
||||||
|
|
||||||
// Cambia el color del borde
|
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK)); // Cambia el color del borde
|
||||||
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK));
|
fillTexture(); // Escribe el texto en la textura
|
||||||
|
Audio::get()->playMusic("title.ogg"); // Inicia la musica
|
||||||
// Escribe el texto en la textura
|
|
||||||
fillTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba el manejador de eventos
|
// Comprueba el manejador de eventos
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
#include <algorithm> // Para min
|
|
||||||
|
|
||||||
#include "core/audio/audio.hpp" // Para Audio
|
#include "core/audio/audio.hpp" // Para Audio
|
||||||
#include "core/input/global_inputs.hpp" // Para check
|
#include "core/input/global_inputs.hpp" // Para check
|
||||||
#include "core/input/input.hpp" // Para Input
|
#include "core/input/input.hpp" // Para Input
|
||||||
@@ -16,7 +14,6 @@
|
|||||||
#include "core/system/global_events.hpp" // Para check
|
#include "core/system/global_events.hpp" // Para check
|
||||||
#include "game/options.hpp" // Para Options, options, OptionsGame, SectionS...
|
#include "game/options.hpp" // Para Options, options, OptionsGame, SectionS...
|
||||||
#include "game/scene_manager.hpp" // Para SceneManager
|
#include "game/scene_manager.hpp" // Para SceneManager
|
||||||
#include "utils/defines.hpp" // Para GAME_SPEED
|
|
||||||
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
||||||
#include "utils/utils.hpp" // Para PaletteColor
|
#include "utils/utils.hpp" // Para PaletteColor
|
||||||
|
|
||||||
@@ -31,8 +28,6 @@ Ending::Ending()
|
|||||||
iniScenes(); // Inicializa las escenas
|
iniScenes(); // Inicializa las escenas
|
||||||
|
|
||||||
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK)); // Cambia el color del borde
|
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK)); // Cambia el color del borde
|
||||||
cover_surface_ = std::make_shared<Surface>(Options::game.width, Options::game.height + 8); // Crea la textura para cubrir el texto
|
|
||||||
fillCoverTexture(); // Rellena la textura para la cortinilla
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
@@ -81,7 +76,9 @@ void Ending::render() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dibuja la cortinilla de cambio de escena
|
// Dibuja la cortinilla de cambio de escena
|
||||||
renderCoverTexture();
|
if (scene_cover_) {
|
||||||
|
scene_cover_->render(0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vuelca el contenido del renderizador en pantalla
|
// Vuelca el contenido del renderizador en pantalla
|
||||||
@@ -107,9 +104,10 @@ void Ending::transitionToState(State new_state) {
|
|||||||
state_ = new_state;
|
state_ = new_state;
|
||||||
state_time_ = 0.0F;
|
state_time_ = 0.0F;
|
||||||
|
|
||||||
// Al cambiar a una escena, resetear fadeout_time_
|
// Al cambiar a una escena, resetear la cortinilla de salida y el contador de fade
|
||||||
if (new_state != State::WARMING_UP && new_state != State::ENDING) {
|
if (new_state != State::WARMING_UP && new_state != State::ENDING) {
|
||||||
fadeout_time_ = 0.0F;
|
fadeout_time_ = 0.0F;
|
||||||
|
scene_cover_.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,9 +125,12 @@ void Ending::updateState(float delta_time) {
|
|||||||
|
|
||||||
case State::SCENE_0:
|
case State::SCENE_0:
|
||||||
checkChangeScene();
|
checkChangeScene();
|
||||||
// Actualizar fadeout_time_ si estamos cerca del final
|
|
||||||
if (state_time_ >= SCENE_0_DURATION - FADEOUT_START_OFFSET) {
|
if (state_time_ >= SCENE_0_DURATION - FADEOUT_START_OFFSET) {
|
||||||
fadeout_time_ += delta_time;
|
fadeout_time_ += delta_time;
|
||||||
|
if (!scene_cover_) {
|
||||||
|
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
|
||||||
|
}
|
||||||
|
scene_cover_->update(fadeout_time_);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -137,6 +138,10 @@ void Ending::updateState(float delta_time) {
|
|||||||
checkChangeScene();
|
checkChangeScene();
|
||||||
if (state_time_ >= SCENE_1_DURATION - FADEOUT_START_OFFSET) {
|
if (state_time_ >= SCENE_1_DURATION - FADEOUT_START_OFFSET) {
|
||||||
fadeout_time_ += delta_time;
|
fadeout_time_ += delta_time;
|
||||||
|
if (!scene_cover_) {
|
||||||
|
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
|
||||||
|
}
|
||||||
|
scene_cover_->update(fadeout_time_);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -144,6 +149,10 @@ void Ending::updateState(float delta_time) {
|
|||||||
checkChangeScene();
|
checkChangeScene();
|
||||||
if (state_time_ >= SCENE_2_DURATION - FADEOUT_START_OFFSET) {
|
if (state_time_ >= SCENE_2_DURATION - FADEOUT_START_OFFSET) {
|
||||||
fadeout_time_ += delta_time;
|
fadeout_time_ += delta_time;
|
||||||
|
if (!scene_cover_) {
|
||||||
|
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
|
||||||
|
}
|
||||||
|
scene_cover_->update(fadeout_time_);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -151,6 +160,10 @@ void Ending::updateState(float delta_time) {
|
|||||||
checkChangeScene();
|
checkChangeScene();
|
||||||
if (state_time_ >= SCENE_3_DURATION - FADEOUT_START_OFFSET) {
|
if (state_time_ >= SCENE_3_DURATION - FADEOUT_START_OFFSET) {
|
||||||
fadeout_time_ += delta_time;
|
fadeout_time_ += delta_time;
|
||||||
|
if (!scene_cover_) {
|
||||||
|
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
|
||||||
|
}
|
||||||
|
scene_cover_->update(fadeout_time_);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -158,6 +171,10 @@ void Ending::updateState(float delta_time) {
|
|||||||
checkChangeScene();
|
checkChangeScene();
|
||||||
if (state_time_ >= SCENE_4_DURATION - FADEOUT_START_OFFSET) {
|
if (state_time_ >= SCENE_4_DURATION - FADEOUT_START_OFFSET) {
|
||||||
fadeout_time_ += delta_time;
|
fadeout_time_ += delta_time;
|
||||||
|
if (!scene_cover_) {
|
||||||
|
scene_cover_ = std::make_unique<PixelReveal>(Options::game.width, Options::game.height, COVER_PIXELS_PER_SECOND, STEP_DURATION, COVER_STEPS, true);
|
||||||
|
}
|
||||||
|
scene_cover_->update(fadeout_time_);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -432,42 +449,3 @@ void Ending::checkChangeScene() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rellena la textura para la cortinilla
|
|
||||||
void Ending::fillCoverTexture() {
|
|
||||||
// Rellena la textura que cubre el texto con color transparente
|
|
||||||
auto previuos_renderer = Screen::get()->getRendererSurface();
|
|
||||||
Screen::get()->setRendererSurface(cover_surface_);
|
|
||||||
cover_surface_->clear(static_cast<Uint8>(PaletteColor::TRANSPARENT));
|
|
||||||
|
|
||||||
// Los primeros 8 pixels crea una malla
|
|
||||||
const auto COLOR = static_cast<Uint8>(PaletteColor::BLACK);
|
|
||||||
auto surface = Screen::get()->getRendererSurface();
|
|
||||||
for (int i = 0; i < 256; i += 2) {
|
|
||||||
surface->putPixel(i + 0, Options::game.height + 0, COLOR);
|
|
||||||
surface->putPixel(i + 1, Options::game.height + 1, COLOR);
|
|
||||||
surface->putPixel(i + 0, Options::game.height + 2, COLOR);
|
|
||||||
surface->putPixel(i + 1, Options::game.height + 3, COLOR);
|
|
||||||
|
|
||||||
surface->putPixel(i, Options::game.height + 4, COLOR);
|
|
||||||
surface->putPixel(i, Options::game.height + 6, COLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// El resto se rellena de color sólido
|
|
||||||
SDL_FRect rect = {0, 0, 256, Options::game.height};
|
|
||||||
surface->fillRect(&rect, COLOR);
|
|
||||||
|
|
||||||
Screen::get()->setRendererSurface(previuos_renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dibuja la cortinilla de cambio de escena
|
|
||||||
void Ending::renderCoverTexture() {
|
|
||||||
if (fadeout_time_ > 0.0F) {
|
|
||||||
// Convertir fadeout_time_ a equivalente de cover_counter_ @ 60fps
|
|
||||||
const float FADEOUT_COUNTER = std::min(fadeout_time_ * 60.0F, 100.0F);
|
|
||||||
|
|
||||||
SDL_FRect src_rect = {0.0F, 200.0F - (FADEOUT_COUNTER * 2.0F), 256.0F, FADEOUT_COUNTER * 2.0F};
|
|
||||||
SDL_FRect dst_rect = {0.0F, 0.0F, 256.0F, FADEOUT_COUNTER * 2.0F};
|
|
||||||
cover_surface_->render(&src_rect, &dst_rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -58,7 +58,6 @@ class Ending {
|
|||||||
|
|
||||||
// --- Constantes de tiempo (basado en 60 FPS) ---
|
// --- Constantes de tiempo (basado en 60 FPS) ---
|
||||||
static constexpr float WARMUP_DURATION = 3.333F; // 200 frames @ 60fps
|
static constexpr float WARMUP_DURATION = 3.333F; // 200 frames @ 60fps
|
||||||
static constexpr float FADEOUT_DURATION = 1.667F; // 100 frames @ 60fps
|
|
||||||
static constexpr float SCENE_0_DURATION = 16.667F; // 1000 frames @ 60fps
|
static constexpr float SCENE_0_DURATION = 16.667F; // 1000 frames @ 60fps
|
||||||
static constexpr float SCENE_1_DURATION = 23.333F; // 1400 frames @ 60fps
|
static constexpr float SCENE_1_DURATION = 23.333F; // 1400 frames @ 60fps
|
||||||
static constexpr float SCENE_2_DURATION = 16.667F; // 1000 frames @ 60fps
|
static constexpr float SCENE_2_DURATION = 16.667F; // 1000 frames @ 60fps
|
||||||
@@ -67,9 +66,11 @@ class Ending {
|
|||||||
static constexpr float TEXT_PIXELS_PER_SECOND = 30.0F; // Filas de texto reveladas por segundo
|
static constexpr float TEXT_PIXELS_PER_SECOND = 30.0F; // Filas de texto reveladas por segundo
|
||||||
static constexpr float IMAGE_PIXELS_PER_SECOND = 60.0F; // Filas de imagen reveladas por segundo
|
static constexpr float IMAGE_PIXELS_PER_SECOND = 60.0F; // Filas de imagen reveladas por segundo
|
||||||
static constexpr float STEP_DURATION = 2.0F / 60.0F; // Segundos por paso de revelado (2 frames @ 60fps)
|
static constexpr float STEP_DURATION = 2.0F / 60.0F; // Segundos por paso de revelado (2 frames @ 60fps)
|
||||||
static constexpr int REVEAL_STEPS = 10; // Pasos de revelado por fila (más pasos = efecto más visible)
|
static constexpr int REVEAL_STEPS = 4; // Pasos de revelado por fila
|
||||||
static constexpr float TEXT_LAPSE = 1.333F; // 80 frames @ 60fps
|
static constexpr float TEXT_LAPSE = 1.333F; // 80 frames @ 60fps
|
||||||
static constexpr float FADEOUT_START_OFFSET = 1.667F; // Inicio fade-out 100 frames antes del fin
|
static constexpr float FADEOUT_START_OFFSET = 1.667F; // Inicio cortinilla 100 frames antes del fin
|
||||||
|
static constexpr float COVER_PIXELS_PER_SECOND = 120.0F; // Filas cubiertas por segundo
|
||||||
|
static constexpr int COVER_STEPS = 4; // Pasos por fila
|
||||||
static constexpr float ENDING_DURATION = 2.0F; // Duración del estado ENDING (2 segundos)
|
static constexpr float ENDING_DURATION = 2.0F; // Duración del estado ENDING (2 segundos)
|
||||||
static constexpr int MUSIC_FADE_DURATION = 1800; // Fade de audio en milisegundos (1.8 segundos)
|
static constexpr int MUSIC_FADE_DURATION = 1800; // Fade de audio en milisegundos (1.8 segundos)
|
||||||
|
|
||||||
@@ -85,13 +86,11 @@ class Ending {
|
|||||||
void transitionToState(State new_state); // Transición entre estados
|
void transitionToState(State new_state); // Transición entre estados
|
||||||
void updateSpriteCovers(); // Actualiza las cortinillas de los elementos
|
void updateSpriteCovers(); // Actualiza las cortinillas de los elementos
|
||||||
void checkChangeScene(); // Comprueba si se ha de cambiar de escena
|
void checkChangeScene(); // Comprueba si se ha de cambiar de escena
|
||||||
void fillCoverTexture(); // Rellena la textura para la cortinilla
|
|
||||||
void renderCoverTexture(); // Dibuja la cortinilla de cambio de escena
|
|
||||||
void updateMusicVolume() const; // Actualiza el volumen de la música
|
void updateMusicVolume() const; // Actualiza el volumen de la música
|
||||||
|
|
||||||
// --- Variables miembro ---
|
// --- Variables miembro ---
|
||||||
// Objetos y punteros a recursos
|
// Objetos y punteros a recursos
|
||||||
std::shared_ptr<Surface> cover_surface_; // Surface para cubrir el texto
|
std::unique_ptr<PixelReveal> scene_cover_; // Cortinilla de salida (negro sobre la escena)
|
||||||
std::unique_ptr<DeltaTimer> delta_timer_; // Timer para time-based update
|
std::unique_ptr<DeltaTimer> delta_timer_; // Timer para time-based update
|
||||||
std::vector<EndingSurface> sprite_texts_; // Vector con los sprites de texto con su cortinilla
|
std::vector<EndingSurface> sprite_texts_; // Vector con los sprites de texto con su cortinilla
|
||||||
std::vector<EndingSurface> sprite_pics_; // Vector con los sprites de imágenes con su cortinilla
|
std::vector<EndingSurface> sprite_pics_; // Vector con los sprites de imágenes con su cortinilla
|
||||||
@@ -101,6 +100,6 @@ class Ending {
|
|||||||
State state_{State::WARMING_UP}; // Estado actual
|
State state_{State::WARMING_UP}; // Estado actual
|
||||||
float state_time_{0.0F}; // Tiempo acumulado en el estado actual
|
float state_time_{0.0F}; // Tiempo acumulado en el estado actual
|
||||||
float total_time_{0.0F}; // Tiempo total acumulado desde el inicio
|
float total_time_{0.0F}; // Tiempo total acumulado desde el inicio
|
||||||
float fadeout_time_{0.0F}; // Tiempo acumulado para el fade-out
|
float fadeout_time_{0.0F}; // Tiempo acumulado para la cortinilla de salida
|
||||||
int current_scene_{0}; // Escena actual (0-4)
|
int current_scene_{0}; // Escena actual (0-4)
|
||||||
};
|
};
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "core/resources/resource_cache.hpp" // Para ResourceRoom, Resource
|
#include "core/resources/resource_cache.hpp" // Para ResourceRoom, Resource
|
||||||
#include "core/resources/resource_list.hpp" // Para Asset
|
#include "core/resources/resource_list.hpp" // Para Asset
|
||||||
#include "core/system/global_events.hpp" // Para check
|
#include "core/system/global_events.hpp" // Para check
|
||||||
|
#include "game/defaults.hpp" // Para Defaults::Game
|
||||||
#include "game/gameplay/cheevos.hpp" // Para Cheevos
|
#include "game/gameplay/cheevos.hpp" // Para Cheevos
|
||||||
#include "game/gameplay/item_tracker.hpp" // Para ItemTracker
|
#include "game/gameplay/item_tracker.hpp" // Para ItemTracker
|
||||||
#include "game/gameplay/room.hpp" // Para Room, RoomData
|
#include "game/gameplay/room.hpp" // Para Room, RoomData
|
||||||
@@ -26,7 +27,6 @@
|
|||||||
#include "game/ui/notifier.hpp" // Para Notifier, NotificationText, CHEEVO_NO...
|
#include "game/ui/notifier.hpp" // Para Notifier, NotificationText, CHEEVO_NO...
|
||||||
#include "utils/defines.hpp" // Para Tile::SIZE, PlayArea::HEIGHT, RoomBorder::BOTTOM
|
#include "utils/defines.hpp" // Para Tile::SIZE, PlayArea::HEIGHT, RoomBorder::BOTTOM
|
||||||
#include "utils/utils.hpp" // Para PaletteColor, stringToColor
|
#include "utils/utils.hpp" // Para PaletteColor, stringToColor
|
||||||
#include "game/defaults.hpp" // Para Defaults::Game
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#include "core/system/debug.hpp" // Para Debug
|
#include "core/system/debug.hpp" // Para Debug
|
||||||
@@ -40,8 +40,7 @@ Game::Game(Mode mode)
|
|||||||
stats_(std::make_shared<Stats>(Resource::List::get()->get("stats.csv"), Resource::List::get()->get("stats_buffer.csv"))),
|
stats_(std::make_shared<Stats>(Resource::List::get()->get("stats.csv"), Resource::List::get()->get("stats_buffer.csv"))),
|
||||||
mode_(mode),
|
mode_(mode),
|
||||||
current_room_(Defaults::Game::Room::INITIAL),
|
current_room_(Defaults::Game::Room::INITIAL),
|
||||||
spawn_data_(Player::SpawnData(Defaults::Game::Player::SPAWN_X, Defaults::Game::Player::SPAWN_Y, 0, 0, 0, Player::State::ON_GROUND, Defaults::Game::Player::SPAWN_FLIP))
|
spawn_data_(Player::SpawnData(Defaults::Game::Player::SPAWN_X, Defaults::Game::Player::SPAWN_Y, 0, 0, 0, Player::State::ON_GROUND, Defaults::Game::Player::SPAWN_FLIP)) {
|
||||||
{
|
|
||||||
// Crea objetos e inicializa variables
|
// Crea objetos e inicializa variables
|
||||||
ItemTracker::init();
|
ItemTracker::init();
|
||||||
demoInit();
|
demoInit();
|
||||||
|
|||||||
Reference in New Issue
Block a user