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,16 +17,51 @@ 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) {
|
||||||
for (int r = 0; r < height_; r++) {
|
// Calcula offsets por bisección BFS: 0, N/2, N/4, 3N/4, ...
|
||||||
reveal_order_[r].resize(width_);
|
std::vector<int> offsets;
|
||||||
std::iota(reveal_order_[r].begin(), reveal_order_[r].end(), 0);
|
offsets.push_back(0);
|
||||||
std::mt19937 rng(static_cast<unsigned int>(r));
|
std::queue<std::pair<int, int>> bq;
|
||||||
std::shuffle(reveal_order_[r].begin(), reveal_order_[r].end(), rng);
|
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++) {
|
||||||
|
reveal_order_[r].resize(width_);
|
||||||
|
std::iota(reveal_order_[r].begin(), reveal_order_[r].end(), 0);
|
||||||
|
std::mt19937 rng(static_cast<unsigned int>(r));
|
||||||
|
std::shuffle(reveal_order_[r].begin(), reveal_order_[r].end(), rng);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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();
|
||||||
@@ -25,12 +29,14 @@ class PixelReveal {
|
|||||||
[[nodiscard]] bool isComplete() const;
|
[[nodiscard]] bool isComplete() const;
|
||||||
|
|
||||||
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
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -90,9 +90,9 @@ constexpr int GAMEPAD_BUTTON_JUMP = SDL_GAMEPAD_BUTTON_WEST; // Botón s
|
|||||||
|
|
||||||
// --- KIOSK ---
|
// --- KIOSK ---
|
||||||
namespace Kiosk {
|
namespace Kiosk {
|
||||||
constexpr bool ENABLED = false; // Modo kiosko desactivado por defecto
|
constexpr bool ENABLED = false; // Modo kiosko desactivado por defecto
|
||||||
constexpr const char* TEXT = ""; // Texto del modo kiosko por defecto
|
constexpr const char* TEXT = ""; // Texto del modo kiosko por defecto
|
||||||
constexpr bool INFINITE_LIVES = false; // Vidas infinitas en modo kiosko desactivadas por defecto
|
constexpr bool INFINITE_LIVES = false; // Vidas infinitas en modo kiosko desactivadas por defecto
|
||||||
} // namespace Kiosk
|
} // namespace Kiosk
|
||||||
|
|
||||||
// --- GAME (posición y habitación inicial) ---
|
// --- GAME (posición y habitación inicial) ---
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -872,14 +872,14 @@ auto Player::getProjection(Direction direction, float displacement) -> SDL_FRect
|
|||||||
.x = x_ + displacement,
|
.x = x_ + displacement,
|
||||||
.y = y_,
|
.y = y_,
|
||||||
.w = std::ceil(std::fabs(displacement)), // Para evitar que tenga una anchura de 0 pixels
|
.w = std::ceil(std::fabs(displacement)), // Para evitar que tenga una anchura de 0 pixels
|
||||||
.h = HEIGHT - 1}; // -1 para dar ventana de 2px en aperturas de altura exacta
|
.h = HEIGHT - 1}; // -1 para dar ventana de 2px en aperturas de altura exacta
|
||||||
|
|
||||||
case Direction::RIGHT:
|
case Direction::RIGHT:
|
||||||
return {
|
return {
|
||||||
.x = x_ + WIDTH,
|
.x = x_ + WIDTH,
|
||||||
.y = y_,
|
.y = y_,
|
||||||
.w = std::ceil(displacement), // Para evitar que tenga una anchura de 0 pixels
|
.w = std::ceil(displacement), // Para evitar que tenga una anchura de 0 pixels
|
||||||
.h = HEIGHT - 1}; // -1 para dar ventana de 2px en aperturas de altura exacta
|
.h = HEIGHT - 1}; // -1 para dar ventana de 2px en aperturas de altura exacta
|
||||||
|
|
||||||
case Direction::UP:
|
case Direction::UP:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ class Player {
|
|||||||
auto getRect() -> SDL_FRect { return {x_, y_, WIDTH, HEIGHT}; } // Obtiene el rectangulo que delimita al jugador
|
auto getRect() -> SDL_FRect { return {x_, y_, WIDTH, HEIGHT}; } // Obtiene el rectangulo que delimita al jugador
|
||||||
auto getCollider() -> SDL_FRect& { return collider_box_; } // Obtiene el rectangulo de colision del jugador
|
auto getCollider() -> SDL_FRect& { return collider_box_; } // Obtiene el rectangulo de colision del jugador
|
||||||
auto getSpawnParams() -> SpawnData { return {.x = x_, .y = y_, .vx = vx_, .vy = vy_, .last_grounded_position = last_grounded_position_, .state = state_, .flip = sprite_->getFlip()}; } // Obtiene el estado de reaparición del jugador
|
auto getSpawnParams() -> SpawnData { return {.x = x_, .y = y_, .vx = vx_, .vy = vy_, .last_grounded_position = last_grounded_position_, .state = state_, .flip = sprite_->getFlip()}; } // Obtiene el estado de reaparición del jugador
|
||||||
void setColor(Uint8 color = 0); // Establece el color del jugador (0 = automático según cheats)
|
void setColor(Uint8 color = 0); // Establece el color del jugador (0 = automático según cheats)
|
||||||
void setRoom(std::shared_ptr<Room> room) { room_ = std::move(room); } // Establece la habitación en la que se encuentra el jugador
|
void setRoom(std::shared_ptr<Room> room) { room_ = std::move(room); } // Establece la habitación en la que se encuentra el jugador
|
||||||
//[[nodiscard]] auto isAlive() const -> bool { return is_alive_ || (Options::cheats.invincible == Options::Cheat::State::ENABLED); } // Comprueba si el jugador esta vivo
|
//[[nodiscard]] auto isAlive() const -> bool { return is_alive_ || (Options::cheats.invincible == Options::Cheat::State::ENABLED); } // Comprueba si el jugador esta vivo
|
||||||
[[nodiscard]] auto isAlive() const -> bool { return is_alive_; } // Comprueba si el jugador esta vivo
|
[[nodiscard]] auto isAlive() const -> bool { return is_alive_; } // Comprueba si el jugador esta vivo
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ struct Stats {
|
|||||||
|
|
||||||
// Estructura para el modo kiosko
|
// Estructura para el modo kiosko
|
||||||
struct Kiosk {
|
struct Kiosk {
|
||||||
bool enabled{Defaults::Kiosk::ENABLED}; // Indica si el modo kiosko está activo
|
bool enabled{Defaults::Kiosk::ENABLED}; // Indica si el modo kiosko está activo
|
||||||
std::string text{Defaults::Kiosk::TEXT}; // Texto a mostrar en el modo kiosko
|
std::string text{Defaults::Kiosk::TEXT}; // Texto a mostrar en el modo kiosko
|
||||||
bool infinite_lives{Defaults::Kiosk::INFINITE_LIVES}; // Indica si el jugador tiene vidas infinitas en modo kiosko
|
bool infinite_lives{Defaults::Kiosk::INFINITE_LIVES}; // Indica si el jugador tiene vidas infinitas en modo kiosko
|
||||||
};
|
};
|
||||||
|
|
||||||
// Estructura con opciones de la ventana
|
// Estructura con opciones de la ventana
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ class Credits {
|
|||||||
static constexpr float TOTAL_DURATION = 20.0F; // 1200 frames @ 60fps
|
static constexpr float TOTAL_DURATION = 20.0F; // 1200 frames @ 60fps
|
||||||
static constexpr float SHINE_START_TIME = 12.833F; // 770 frames @ 60fps
|
static constexpr float SHINE_START_TIME = 12.833F; // 770 frames @ 60fps
|
||||||
static constexpr float FADE_OUT_START = 19.167F; // 1150 frames @ 60fps
|
static constexpr float FADE_OUT_START = 19.167F; // 1150 frames @ 60fps
|
||||||
static constexpr float PIXELS_PER_SECOND = 15.0F; // Filas reveladas por segundo (REVEAL_SPEED/8*2 = 60/8*2 = 15)
|
static constexpr float PIXELS_PER_SECOND = 15.0F; // Filas reveladas por segundo (REVEAL_SPEED/8*2 = 60/8*2 = 15)
|
||||||
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 = 16; // Pasos de revelado por fila (más pasos = efecto más visible)
|
static constexpr int REVEAL_STEPS = 16; // Pasos de revelado por fila (más pasos = efecto más visible)
|
||||||
|
|
||||||
// --- Métodos privados ---
|
// --- Métodos privados ---
|
||||||
void update(); // Actualiza las variables
|
void update(); // Actualiza las variables
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
@@ -30,9 +27,7 @@ Ending::Ending()
|
|||||||
iniPics(); // Inicializa las imagenes
|
iniPics(); // Inicializa las imagenes
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -57,21 +57,22 @@ 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
|
static constexpr float SCENE_3_DURATION = 13.333F; // 800 frames @ 60fps
|
||||||
static constexpr float SCENE_3_DURATION = 13.333F; // 800 frames @ 60fps
|
static constexpr float SCENE_4_DURATION = 16.667F; // 1000 frames @ 60fps
|
||||||
static constexpr float SCENE_4_DURATION = 16.667F; // 1000 frames @ 60fps
|
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 = 4; // Pasos de revelado por fila
|
||||||
static constexpr int REVEAL_STEPS = 10; // Pasos de revelado por fila (más pasos = efecto más visible)
|
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 cortinilla 100 frames antes del fin
|
||||||
static constexpr float FADEOUT_START_OFFSET = 1.667F; // Inicio fade-out 100 frames antes del fin
|
static constexpr float COVER_PIXELS_PER_SECOND = 120.0F; // Filas cubiertas por segundo
|
||||||
static constexpr float ENDING_DURATION = 2.0F; // Duración del estado ENDING (2 segundos)
|
static constexpr int COVER_STEPS = 4; // Pasos por fila
|
||||||
static constexpr int MUSIC_FADE_DURATION = 1800; // Fade de audio en milisegundos (1.8 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)
|
||||||
|
|
||||||
// --- Métodos ---
|
// --- Métodos ---
|
||||||
void update(); // Actualiza el objeto
|
void update(); // Actualiza el objeto
|
||||||
@@ -85,22 +86,20 @@ 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
|
||||||
std::vector<SceneData> scenes_; // Vector con los textos e imágenes de cada escena
|
std::vector<SceneData> scenes_; // Vector con los textos e imágenes de cada escena
|
||||||
|
|
||||||
// Variables de estado
|
// Variables de estado
|
||||||
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