Compare commits
4 Commits
1f0184fde2
...
f2915aa4b4
| Author | SHA1 | Date | |
|---|---|---|---|
| f2915aa4b4 | |||
| cb4e4b450d | |||
| ca99f7be34 | |||
| f5245273a1 |
@@ -1,6 +1,8 @@
|
|||||||
Checks: >
|
Checks: >
|
||||||
readability-identifier-naming,
|
readability-*,
|
||||||
modernize-*
|
modernize-*,
|
||||||
|
-readability-identifier-length,
|
||||||
|
-readability-magic-numbers
|
||||||
|
|
||||||
WarningsAsErrors: '*'
|
WarningsAsErrors: '*'
|
||||||
# Solo incluir archivos de tu código fuente
|
# Solo incluir archivos de tu código fuente
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ Background::Background()
|
|||||||
|
|
||||||
// Inicializa objetos
|
// Inicializa objetos
|
||||||
{
|
{
|
||||||
constexpr float TOP_CLOUDS_SPEED = 0.1f;
|
constexpr float TOP_CLOUDS_SPEED = 0.1F;
|
||||||
constexpr float BOTTOM_CLOUDS_SPEED = 0.05f;
|
constexpr float BOTTOM_CLOUDS_SPEED = 0.05F;
|
||||||
|
|
||||||
top_clouds_sprite_a_->setSpriteClip(0, 0, top_clouds_texture_->getWidth(), top_clouds_texture_->getHeight());
|
top_clouds_sprite_a_->setSpriteClip(0, 0, top_clouds_texture_->getWidth(), top_clouds_texture_->getHeight());
|
||||||
top_clouds_sprite_a_->setVelX(-TOP_CLOUDS_SPEED);
|
top_clouds_sprite_a_->setVelX(-TOP_CLOUDS_SPEED);
|
||||||
@@ -187,7 +187,7 @@ void Background::renderBottomClouds() {
|
|||||||
// Compone todos los elementos del fondo en la textura
|
// Compone todos los elementos del fondo en la textura
|
||||||
void Background::fillCanvas() {
|
void Background::fillCanvas() {
|
||||||
// Cambia el destino del renderizador
|
// Cambia el destino del renderizador
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, canvas_);
|
SDL_SetRenderTarget(renderer_, canvas_);
|
||||||
|
|
||||||
// Dibuja el gradiente de fondo
|
// Dibuja el gradiente de fondo
|
||||||
@@ -234,7 +234,7 @@ void Background::setGradientNumber(int value) {
|
|||||||
|
|
||||||
// Ajusta el valor de la variable
|
// Ajusta el valor de la variable
|
||||||
void Background::setTransition(float value) {
|
void Background::setTransition(float value) {
|
||||||
transition_ = std::clamp(value, 0.0f, 1.0f);
|
transition_ = std::clamp(value, 0.0F, 1.0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece la posición del objeto
|
// Establece la posición del objeto
|
||||||
@@ -253,7 +253,7 @@ void Background::setColor(Color color) {
|
|||||||
attenuate_color_ = color;
|
attenuate_color_ = color;
|
||||||
|
|
||||||
// Colorea la textura
|
// Colorea la textura
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, color_texture_);
|
SDL_SetRenderTarget(renderer_, color_texture_);
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(renderer_, attenuate_color_.r, attenuate_color_.g, attenuate_color_.b, 255);
|
SDL_SetRenderDrawColor(renderer_, attenuate_color_.r, attenuate_color_.g, attenuate_color_.b, 255);
|
||||||
@@ -276,10 +276,9 @@ void Background::setAlpha(int alpha) {
|
|||||||
void Background::updateAlphaColorTexture() {
|
void Background::updateAlphaColorTexture() {
|
||||||
if (alpha_color_text_ == alpha_color_text_temp_) {
|
if (alpha_color_text_ == alpha_color_text_temp_) {
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
alpha_color_text_ > alpha_color_text_temp_ ? ++alpha_color_text_temp_ : --alpha_color_text_temp_;
|
|
||||||
SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_temp_);
|
|
||||||
}
|
}
|
||||||
|
alpha_color_text_ > alpha_color_text_temp_ ? ++alpha_color_text_temp_ : --alpha_color_text_temp_;
|
||||||
|
SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_temp_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las nubes
|
// Actualiza las nubes
|
||||||
@@ -359,12 +358,12 @@ void Background::createMoonPath() {
|
|||||||
|
|
||||||
// Establece la posición del sol
|
// Establece la posición del sol
|
||||||
void Background::setSunProgression(float progress) {
|
void Background::setSunProgression(float progress) {
|
||||||
progress = std::clamp(progress, 0.0f, 1.0f);
|
progress = std::clamp(progress, 0.0F, 1.0F);
|
||||||
sun_index_ = static_cast<size_t>(progress * (sun_path_.size() - 1));
|
sun_index_ = static_cast<size_t>(progress * (sun_path_.size() - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece la posición de la luna
|
// Establece la posición de la luna
|
||||||
void Background::setMoonProgression(float progress) {
|
void Background::setMoonProgression(float progress) {
|
||||||
progress = std::clamp(progress, 0.0f, 1.0f);
|
progress = std::clamp(progress, 0.0F, 1.0F);
|
||||||
moon_index_ = static_cast<size_t>(progress * (moon_path_.size() - 1));
|
moon_index_ = static_cast<size_t>(progress * (moon_path_.size() - 1));
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_FPoint, SDL_Texture, SDL_Renderer
|
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_FPoint, SDL_Texture, SDL_Renderer
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstddef> // Para size_t
|
#include <cstddef> // Para size_t
|
||||||
#include <memory> // Para unique_ptr, shared_ptr
|
#include <memory> // Para unique_ptr, shared_ptr
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
@@ -27,87 +28,87 @@ class Texture;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class Background {
|
class Background {
|
||||||
public:
|
public:
|
||||||
// Constructor y Destructor
|
// Constructor y Destructor
|
||||||
Background();
|
Background();
|
||||||
~Background();
|
~Background();
|
||||||
|
|
||||||
// Actualización y renderizado
|
// Actualización y renderizado
|
||||||
void update(); // Actualiza la lógica del objeto
|
void update(); // Actualiza la lógica del objeto
|
||||||
void render(); // Dibuja el objeto
|
void render(); // Dibuja el objeto
|
||||||
|
|
||||||
// Configuración de posición
|
// Configuración de posición
|
||||||
void setPos(SDL_FRect pos); // Establece la posición del objeto
|
void setPos(SDL_FRect pos); // Establece la posición del objeto
|
||||||
|
|
||||||
// Configuración de animaciones y efectos
|
// Configuración de animaciones y efectos
|
||||||
void setCloudsSpeed(float value); // Ajusta la velocidad de desplazamiento de las nubes
|
void setCloudsSpeed(float value); // Ajusta la velocidad de desplazamiento de las nubes
|
||||||
void setGradientNumber(int value); // Establece el degradado de fondo a usar
|
void setGradientNumber(int value); // Establece el degradado de fondo a usar
|
||||||
void setTransition(float value); // Ajusta la transición entre texturas de fondo
|
void setTransition(float value); // Ajusta la transición entre texturas de fondo
|
||||||
|
|
||||||
// Configuración de efectos visuales
|
// Configuración de efectos visuales
|
||||||
void setColor(Color color); // Establece el color de atenuación
|
void setColor(Color color); // Establece el color de atenuación
|
||||||
void setAlpha(int alpha); // Ajusta la transparencia del fondo
|
void setAlpha(int alpha); // Ajusta la transparencia del fondo
|
||||||
|
|
||||||
// Configuración del sol y la luna
|
// Configuración del sol y la luna
|
||||||
void setSunProgression(float progress); // Establece la posición del sol
|
void setSunProgression(float progress); // Establece la posición del sol
|
||||||
void setMoonProgression(float progress); // Establece la posición de la luna
|
void setMoonProgression(float progress); // Establece la posición de la luna
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Objetos y punteros
|
// Objetos y punteros
|
||||||
SDL_Renderer *renderer_; // Renderizador de la ventana
|
SDL_Renderer *renderer_; // Renderizador de la ventana
|
||||||
|
|
||||||
// Texturas
|
// Texturas
|
||||||
std::shared_ptr<Texture> buildings_texture_;
|
std::shared_ptr<Texture> buildings_texture_;
|
||||||
std::shared_ptr<Texture> top_clouds_texture_;
|
std::shared_ptr<Texture> top_clouds_texture_;
|
||||||
std::shared_ptr<Texture> bottom_clouds_texture_;
|
std::shared_ptr<Texture> bottom_clouds_texture_;
|
||||||
std::shared_ptr<Texture> grass_texture_;
|
std::shared_ptr<Texture> grass_texture_;
|
||||||
std::shared_ptr<Texture> gradients_texture_;
|
std::shared_ptr<Texture> gradients_texture_;
|
||||||
std::shared_ptr<Texture> sun_texture_;
|
std::shared_ptr<Texture> sun_texture_;
|
||||||
std::shared_ptr<Texture> moon_texture_;
|
std::shared_ptr<Texture> moon_texture_;
|
||||||
|
|
||||||
// Sprites
|
// Sprites
|
||||||
std::unique_ptr<MovingSprite> top_clouds_sprite_a_;
|
std::unique_ptr<MovingSprite> top_clouds_sprite_a_;
|
||||||
std::unique_ptr<MovingSprite> top_clouds_sprite_b_;
|
std::unique_ptr<MovingSprite> top_clouds_sprite_b_;
|
||||||
std::unique_ptr<MovingSprite> bottom_clouds_sprite_a_;
|
std::unique_ptr<MovingSprite> bottom_clouds_sprite_a_;
|
||||||
std::unique_ptr<MovingSprite> bottom_clouds_sprite_b_;
|
std::unique_ptr<MovingSprite> bottom_clouds_sprite_b_;
|
||||||
std::unique_ptr<Sprite> buildings_sprite_;
|
std::unique_ptr<Sprite> buildings_sprite_;
|
||||||
std::unique_ptr<Sprite> gradient_sprite_;
|
std::unique_ptr<Sprite> gradient_sprite_;
|
||||||
std::unique_ptr<Sprite> grass_sprite_;
|
std::unique_ptr<Sprite> grass_sprite_;
|
||||||
std::unique_ptr<Sprite> sun_sprite_;
|
std::unique_ptr<Sprite> sun_sprite_;
|
||||||
std::unique_ptr<Sprite> moon_sprite_;
|
std::unique_ptr<Sprite> moon_sprite_;
|
||||||
|
|
||||||
// Buffers de renderizado
|
// Buffers de renderizado
|
||||||
SDL_Texture *canvas_; // Textura para componer el fondo
|
SDL_Texture *canvas_; // Textura para componer el fondo
|
||||||
SDL_Texture *color_texture_; // Textura para atenuar el fondo
|
SDL_Texture *color_texture_; // Textura para atenuar el fondo
|
||||||
|
|
||||||
// Variables de control
|
// Variables de control
|
||||||
SDL_FRect gradient_rect_[4];
|
std::array<SDL_FRect, 4> gradient_rect_;
|
||||||
SDL_FRect top_clouds_rect_[4];
|
std::array<SDL_FRect, 4> top_clouds_rect_;
|
||||||
SDL_FRect bottom_clouds_rect_[4];
|
std::array<SDL_FRect, 4> bottom_clouds_rect_;
|
||||||
int gradient_number_ = 0;
|
int gradient_number_ = 0;
|
||||||
int alpha_ = 0;
|
int alpha_ = 0;
|
||||||
float clouds_speed_ = 0;
|
float clouds_speed_ = 0;
|
||||||
float transition_ = 0;
|
float transition_ = 0;
|
||||||
int counter_ = 0;
|
int counter_ = 0;
|
||||||
SDL_FRect rect_;
|
SDL_FRect rect_;
|
||||||
SDL_FRect src_rect_;
|
SDL_FRect src_rect_;
|
||||||
SDL_FRect dst_rect_;
|
SDL_FRect dst_rect_;
|
||||||
int base_;
|
int base_;
|
||||||
Color attenuate_color_;
|
Color attenuate_color_;
|
||||||
int alpha_color_text_;
|
int alpha_color_text_;
|
||||||
int alpha_color_text_temp_;
|
int alpha_color_text_temp_;
|
||||||
std::vector<SDL_FPoint> sun_path_;
|
std::vector<SDL_FPoint> sun_path_;
|
||||||
std::vector<SDL_FPoint> moon_path_;
|
std::vector<SDL_FPoint> moon_path_;
|
||||||
size_t sun_index_ = 0;
|
size_t sun_index_ = 0;
|
||||||
size_t moon_index_ = 0;
|
size_t moon_index_ = 0;
|
||||||
|
|
||||||
// Métodos internos
|
// Métodos internos
|
||||||
void renderGradient(); // Dibuja el gradiente de fondo
|
void renderGradient(); // Dibuja el gradiente de fondo
|
||||||
void renderTopClouds(); // Dibuja las nubes superiores
|
void renderTopClouds(); // Dibuja las nubes superiores
|
||||||
void renderBottomClouds(); // Dibuja las nubes inferiores
|
void renderBottomClouds(); // Dibuja las nubes inferiores
|
||||||
void fillCanvas(); // Compone todos los elementos en la textura
|
void fillCanvas(); // Compone todos los elementos en la textura
|
||||||
void updateAlphaColorTexture(); // Actualiza el alpha de la textura de atenuación
|
void updateAlphaColorTexture(); // Actualiza el alpha de la textura de atenuación
|
||||||
void updateClouds(); // Actualiza el movimiento de las nubes
|
void updateClouds(); // Actualiza el movimiento de las nubes
|
||||||
void createSunPath(); // Precalcula el recorrido del sol
|
void createSunPath(); // Precalcula el recorrido del sol
|
||||||
void createMoonPath(); // Precalcula el recorrido de la luna
|
void createMoonPath(); // Precalcula el recorrido de la luna
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
|
|||||||
switch (type_) {
|
switch (type_) {
|
||||||
case BalloonType::BALLOON: {
|
case BalloonType::BALLOON: {
|
||||||
vy_ = 0;
|
vy_ = 0;
|
||||||
max_vy_ = 3.0f;
|
max_vy_ = 3.0F;
|
||||||
|
|
||||||
const int INDEX = static_cast<int>(size_);
|
const int INDEX = static_cast<int>(size_);
|
||||||
gravity_ = param.balloon.settings.at(INDEX).grav;
|
gravity_ = param.balloon.settings.at(INDEX).grav;
|
||||||
@@ -44,8 +44,8 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
|
|||||||
}
|
}
|
||||||
|
|
||||||
case BalloonType::FLOATER: {
|
case BalloonType::FLOATER: {
|
||||||
default_vy_ = max_vy_ = vy_ = fabs(vx_ * 2.0f);
|
default_vy_ = max_vy_ = vy_ = fabs(vx_ * 2.0F);
|
||||||
gravity_ = 0.00f;
|
gravity_ = 0.00F;
|
||||||
|
|
||||||
const int INDEX = static_cast<int>(size_);
|
const int INDEX = static_cast<int>(size_);
|
||||||
h_ = w_ = BALLOON_SIZE[INDEX];
|
h_ = w_ = BALLOON_SIZE[INDEX];
|
||||||
@@ -66,12 +66,12 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
|
|||||||
power_ = score_ = menace_ = 0;
|
power_ = score_ = menace_ = 0;
|
||||||
|
|
||||||
vy_ = 0;
|
vy_ = 0;
|
||||||
max_vy_ = 3.0f;
|
max_vy_ = 3.0F;
|
||||||
gravity_ = param.balloon.settings.at(INDEX).grav;
|
gravity_ = param.balloon.settings.at(INDEX).grav;
|
||||||
default_vy_ = param.balloon.settings.at(INDEX).vel;
|
default_vy_ = param.balloon.settings.at(INDEX).vel;
|
||||||
|
|
||||||
sprite_->setRotate(creation_timer <= 0);
|
sprite_->setRotate(creation_timer <= 0);
|
||||||
sprite_->setRotateAmount(vx_ > 0.0f ? 2.0 : -2.0);
|
sprite_->setRotateAmount(vx_ > 0.0F ? 2.0 : -2.0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ void Balloon::render() {
|
|||||||
|
|
||||||
// Renderiza la estrella
|
// Renderiza la estrella
|
||||||
if (!invulnerable_) {
|
if (!invulnerable_) {
|
||||||
SDL_FPoint p = {24.0f, 24.0f};
|
SDL_FPoint p = {24.0F, 24.0F};
|
||||||
sprite_->setRotatingCenter(p);
|
sprite_->setRotatingCenter(p);
|
||||||
sprite_->render();
|
sprite_->render();
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ void Balloon::render() {
|
|||||||
// Renderizado para el resto de globos
|
// Renderizado para el resto de globos
|
||||||
if (isBeingCreated()) {
|
if (isBeingCreated()) {
|
||||||
// Renderizado con transparencia
|
// Renderizado con transparencia
|
||||||
sprite_->getTexture()->setAlpha(255 - (int)((float)creation_counter_ * (255.0f / (float)creation_counter_ini_)));
|
sprite_->getTexture()->setAlpha(255 - (int)((float)creation_counter_ * (255.0F / (float)creation_counter_ini_)));
|
||||||
sprite_->render();
|
sprite_->render();
|
||||||
sprite_->getTexture()->setAlpha(255);
|
sprite_->getTexture()->setAlpha(255);
|
||||||
} else {
|
} else {
|
||||||
@@ -150,8 +150,9 @@ void Balloon::move() {
|
|||||||
const float MIN_X = play_area_.x - CLIP;
|
const float MIN_X = play_area_.x - CLIP;
|
||||||
const float MAX_X = play_area_.x + play_area_.w - w_ + CLIP;
|
const float MAX_X = play_area_.x + play_area_.w - w_ + CLIP;
|
||||||
if (x_ < MIN_X || x_ > MAX_X) {
|
if (x_ < MIN_X || x_ > MAX_X) {
|
||||||
if (bouncing_sound_enabled_)
|
if (bouncing_sound_enabled_) {
|
||||||
playSound(bouncing_sound_);
|
playSound(bouncing_sound_);
|
||||||
|
}
|
||||||
x_ = std::clamp(x_, MIN_X, MAX_X);
|
x_ = std::clamp(x_, MIN_X, MAX_X);
|
||||||
vx_ = -vx_;
|
vx_ = -vx_;
|
||||||
// Activa el efecto de rebote o invierte la rotación
|
// Activa el efecto de rebote o invierte la rotación
|
||||||
@@ -169,8 +170,9 @@ void Balloon::move() {
|
|||||||
if (vy_ < 0) {
|
if (vy_ < 0) {
|
||||||
const int MIN_Y = play_area_.y;
|
const int MIN_Y = play_area_.y;
|
||||||
if (y_ < MIN_Y) {
|
if (y_ < MIN_Y) {
|
||||||
if (bouncing_sound_enabled_)
|
if (bouncing_sound_enabled_) {
|
||||||
playSound(bouncing_sound_);
|
playSound(bouncing_sound_);
|
||||||
|
}
|
||||||
y_ = MIN_Y;
|
y_ = MIN_Y;
|
||||||
vy_ = -vy_;
|
vy_ = -vy_;
|
||||||
enableBounce();
|
enableBounce();
|
||||||
@@ -180,8 +182,9 @@ void Balloon::move() {
|
|||||||
// Colisión en la parte inferior de la zona de juego
|
// Colisión en la parte inferior de la zona de juego
|
||||||
const int MAX_Y = play_area_.y + play_area_.h - h_;
|
const int MAX_Y = play_area_.y + play_area_.h - h_;
|
||||||
if (y_ > MAX_Y) {
|
if (y_ > MAX_Y) {
|
||||||
if (bouncing_sound_enabled_)
|
if (bouncing_sound_enabled_) {
|
||||||
playSound(bouncing_sound_);
|
playSound(bouncing_sound_);
|
||||||
|
}
|
||||||
y_ = MAX_Y;
|
y_ = MAX_Y;
|
||||||
vy_ = -default_vy_;
|
vy_ = -default_vy_;
|
||||||
if (type_ != BalloonType::POWERBALL) {
|
if (type_ != BalloonType::POWERBALL) {
|
||||||
@@ -204,9 +207,9 @@ void Balloon::move() {
|
|||||||
travel_y_ += speed_;
|
travel_y_ += speed_;
|
||||||
|
|
||||||
// Si la distancia acumulada en Y es igual a la velocidad, se aplica la gravedad
|
// Si la distancia acumulada en Y es igual a la velocidad, se aplica la gravedad
|
||||||
if (travel_y_ >= 1.0f) {
|
if (travel_y_ >= 1.0F) {
|
||||||
// Quita el excedente
|
// Quita el excedente
|
||||||
travel_y_ -= 1.0f;
|
travel_y_ -= 1.0F;
|
||||||
|
|
||||||
// Aplica la gravedad al objeto sin pasarse de una velocidad máxima
|
// Aplica la gravedad al objeto sin pasarse de una velocidad máxima
|
||||||
vy_ += gravity_;
|
vy_ += gravity_;
|
||||||
@@ -283,10 +286,11 @@ void Balloon::setAnimation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Establece el frame de animación
|
// Establece el frame de animación
|
||||||
if (use_reversed_colors_)
|
if (use_reversed_colors_) {
|
||||||
sprite_->setCurrentAnimation(creating_animation);
|
sprite_->setCurrentAnimation(creating_animation);
|
||||||
else
|
} else {
|
||||||
sprite_->setCurrentAnimation(isBeingCreated() ? creating_animation : normal_animation);
|
sprite_->setCurrentAnimation(isBeingCreated() ? creating_animation : normal_animation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detiene el globo
|
// Detiene el globo
|
||||||
@@ -319,8 +323,8 @@ void Balloon::shiftSprite() {
|
|||||||
|
|
||||||
// Establece el nivel de zoom del sprite
|
// Establece el nivel de zoom del sprite
|
||||||
void Balloon::zoomSprite() {
|
void Balloon::zoomSprite() {
|
||||||
sprite_->setZoomW(bouncing_.zoom_w);
|
sprite_->setZoomW(bouncing_.horizontal_zoom);
|
||||||
sprite_->setZoomH(bouncing_.zoom_h);
|
sprite_->setZoomH(bouncing_.verical_zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activa el efecto
|
// Activa el efecto
|
||||||
@@ -341,8 +345,8 @@ void Balloon::disableBounce() {
|
|||||||
void Balloon::updateBounce() {
|
void Balloon::updateBounce() {
|
||||||
if (bouncing_.enabled) {
|
if (bouncing_.enabled) {
|
||||||
const int INDEX = bouncing_.counter / bouncing_.speed;
|
const int INDEX = bouncing_.counter / bouncing_.speed;
|
||||||
bouncing_.zoom_w = bouncing_.w[INDEX];
|
bouncing_.horizontal_zoom = bouncing_.horizontal_zoom_values[INDEX];
|
||||||
bouncing_.zoom_h = bouncing_.h[INDEX];
|
bouncing_.verical_zoom = bouncing_.vertical_zoom_values[INDEX];
|
||||||
|
|
||||||
zoomSprite();
|
zoomSprite();
|
||||||
|
|
||||||
@@ -367,19 +371,21 @@ void Balloon::useNormalColor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reproduce sonido
|
// Reproduce sonido
|
||||||
void Balloon::playSound(const std::string &name) {
|
void Balloon::playSound(const std::string &name) const {
|
||||||
if (!sound_enabled_)
|
if (!sound_enabled_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static auto audio_ = Audio::get();
|
static auto *audio_ = Audio::get();
|
||||||
audio_->playSound(name);
|
audio_->playSound(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explota el globo
|
// Explota el globo
|
||||||
void Balloon::pop(bool should_sound) {
|
void Balloon::pop(bool should_sound) {
|
||||||
if (should_sound) {
|
if (should_sound) {
|
||||||
if (poping_sound_enabled_)
|
if (poping_sound_enabled_) {
|
||||||
playSound(popping_sound_);
|
playSound(popping_sound_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enabled_ = false;
|
enabled_ = false;
|
||||||
|
|||||||
253
source/balloon.h
253
source/balloon.h
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para Uint8, Uint16, SDL_FRect, Uint32
|
#include <SDL3/SDL.h> // Para Uint8, Uint16, SDL_FRect, Uint32
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <memory> // Para shared_ptr, unique_ptr
|
#include <memory> // Para shared_ptr, unique_ptr
|
||||||
#include <string> // Para basic_string, string
|
#include <string> // Para basic_string, string
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
@@ -14,12 +15,16 @@ class Texture;
|
|||||||
// --- Constantes relacionadas con globos ---
|
// --- Constantes relacionadas con globos ---
|
||||||
constexpr int MAX_BOUNCE = 10; // Cantidad de elementos del vector de deformación
|
constexpr int MAX_BOUNCE = 10; // Cantidad de elementos del vector de deformación
|
||||||
|
|
||||||
constexpr int BALLOON_SCORE[] = {50, 100, 200, 400};
|
constexpr std::array<int, 4> BALLOON_SCORE = {50, 100, 200, 400};
|
||||||
constexpr int BALLOON_POWER[] = {1, 3, 7, 15};
|
constexpr std::array<int, 4> BALLOON_POWER = {1, 3, 7, 15};
|
||||||
constexpr int BALLOON_MENACE[] = {1, 2, 4, 8};
|
constexpr std::array<int, 4> BALLOON_MENACE = {1, 2, 4, 8};
|
||||||
constexpr int BALLOON_SIZE[] = {10, 16, 26, 48, 49};
|
constexpr std::array<int, 5> BALLOON_SIZE = {10, 16, 26, 48, 49};
|
||||||
const std::string BALLOON_BOUNCING_SOUND[] = {"bubble1.wav", "bubble2.wav", "bubble3.wav", "bubble4.wav"};
|
|
||||||
const std::string BALLOON_POPPING_SOUND[] = {"balloon1.wav", "balloon2.wav", "balloon3.wav", "balloon4.wav"};
|
const std::array<std::string, 4> BALLOON_BOUNCING_SOUND = {
|
||||||
|
"bubble1.wav", "bubble2.wav", "bubble3.wav", "bubble4.wav"};
|
||||||
|
|
||||||
|
const std::array<std::string, 4> BALLOON_POPPING_SOUND = {
|
||||||
|
"balloon1.wav", "balloon2.wav", "balloon3.wav", "balloon4.wav"};
|
||||||
|
|
||||||
enum class BalloonSize : Uint8 {
|
enum class BalloonSize : Uint8 {
|
||||||
SIZE1 = 0,
|
SIZE1 = 0,
|
||||||
@@ -34,143 +39,143 @@ enum class BalloonType : Uint8 {
|
|||||||
POWERBALL = 2,
|
POWERBALL = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr float BALLOON_VELX_POSITIVE = 0.7f;
|
constexpr float BALLOON_VELX_POSITIVE = 0.7F;
|
||||||
constexpr float BALLOON_VELX_NEGATIVE = -0.7f;
|
constexpr float BALLOON_VELX_NEGATIVE = -0.7F;
|
||||||
|
|
||||||
constexpr int BALLOON_MOVING_ANIMATION = 0;
|
constexpr int BALLOON_MOVING_ANIMATION = 0;
|
||||||
constexpr int BALLOON_POP_ANIMATION = 1;
|
constexpr int BALLOON_POP_ANIMATION = 1;
|
||||||
constexpr int BALLOON_BORN_ANIMATION = 2;
|
constexpr int BALLOON_BORN_ANIMATION = 2;
|
||||||
|
|
||||||
constexpr float BALLOON_SPEED[] = {0.60f, 0.70f, 0.80f, 0.90f, 1.00f};
|
constexpr std::array<float, 5> BALLOON_SPEED = {0.60F, 0.70F, 0.80F, 0.90F, 1.00F};
|
||||||
|
|
||||||
constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10;
|
constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10;
|
||||||
constexpr int POWERBALL_COUNTER = 8;
|
constexpr int POWERBALL_COUNTER = 8;
|
||||||
|
|
||||||
// --- Clase Balloon ---
|
// --- Clase Balloon ---
|
||||||
class Balloon {
|
class Balloon {
|
||||||
public:
|
public:
|
||||||
// --- Constructores y destructor ---
|
// --- Constructores y destructor ---
|
||||||
Balloon(
|
Balloon(
|
||||||
float x,
|
float x,
|
||||||
float y,
|
float y,
|
||||||
BalloonType type,
|
BalloonType type,
|
||||||
BalloonSize size,
|
BalloonSize size,
|
||||||
float vel_x,
|
float vel_x,
|
||||||
float speed,
|
float speed,
|
||||||
Uint16 creation_timer,
|
Uint16 creation_timer,
|
||||||
SDL_FRect play_area,
|
SDL_FRect play_area,
|
||||||
std::shared_ptr<Texture> texture,
|
std::shared_ptr<Texture> texture,
|
||||||
const std::vector<std::string> &animation);
|
const std::vector<std::string> &animation);
|
||||||
~Balloon() = default;
|
~Balloon() = default;
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void alignTo(int x); // Centra el globo en la posición X
|
void alignTo(int x); // Centra el globo en la posición X
|
||||||
void render(); // Pinta el globo en la pantalla
|
void render(); // Pinta el globo en la pantalla
|
||||||
void move(); // Actualiza la posición y estados del globo
|
void move(); // Actualiza la posición y estados del globo
|
||||||
void update(); // Actualiza el globo (posición, animación, contadores)
|
void update(); // Actualiza el globo (posición, animación, contadores)
|
||||||
void stop(); // Detiene el globo
|
void stop(); // Detiene el globo
|
||||||
void start(); // Pone el globo en movimiento
|
void start(); // Pone el globo en movimiento
|
||||||
void pop(bool should_sound = false); // Explota el globo
|
void pop(bool should_sound = false); // Explota el globo
|
||||||
|
|
||||||
// --- Métodos de color ---
|
// --- Métodos de color ---
|
||||||
void useReverseColor(); // Pone el color alternativo en el globo
|
void useReverseColor(); // Pone el color alternativo en el globo
|
||||||
void useNormalColor(); // Pone el color normal en el globo
|
void useNormalColor(); // Pone el color normal en el globo
|
||||||
|
|
||||||
// --- Getters ---
|
// --- Getters ---
|
||||||
[[nodiscard]] auto getPosX() const -> float { return x_; }
|
[[nodiscard]] auto getPosX() const -> float { return x_; }
|
||||||
[[nodiscard]] auto getPosY() const -> float { return y_; }
|
[[nodiscard]] auto getPosY() const -> float { return y_; }
|
||||||
[[nodiscard]] auto getWidth() const -> int { return w_; }
|
[[nodiscard]] auto getWidth() const -> int { return w_; }
|
||||||
[[nodiscard]] auto getHeight() const -> int { return h_; }
|
[[nodiscard]] auto getHeight() const -> int { return h_; }
|
||||||
[[nodiscard]] auto getSize() const -> BalloonSize { return size_; }
|
[[nodiscard]] auto getSize() const -> BalloonSize { return size_; }
|
||||||
[[nodiscard]] auto getType() const -> BalloonType { return type_; }
|
[[nodiscard]] auto getType() const -> BalloonType { return type_; }
|
||||||
[[nodiscard]] auto getScore() const -> Uint16 { return score_; }
|
[[nodiscard]] auto getScore() const -> Uint16 { return score_; }
|
||||||
auto getCollider() -> Circle & { return collider_; }
|
auto getCollider() -> Circle & { return collider_; }
|
||||||
[[nodiscard]] auto getMenace() const -> Uint8 { return isEnabled() ? menace_ : 0; }
|
[[nodiscard]] auto getMenace() const -> Uint8 { return isEnabled() ? menace_ : 0; }
|
||||||
[[nodiscard]] auto getPower() const -> Uint8 { return power_; }
|
[[nodiscard]] auto getPower() const -> Uint8 { return power_; }
|
||||||
[[nodiscard]] auto isStopped() const -> bool { return stopped_; }
|
[[nodiscard]] auto isStopped() const -> bool { return stopped_; }
|
||||||
[[nodiscard]] auto isPowerBall() const -> bool { return type_ == BalloonType::POWERBALL; }
|
[[nodiscard]] auto isPowerBall() const -> bool { return type_ == BalloonType::POWERBALL; }
|
||||||
[[nodiscard]] auto isInvulnerable() const -> bool { return invulnerable_; }
|
[[nodiscard]] auto isInvulnerable() const -> bool { return invulnerable_; }
|
||||||
[[nodiscard]] auto isBeingCreated() const -> bool { return being_created_; }
|
[[nodiscard]] auto isBeingCreated() const -> bool { return being_created_; }
|
||||||
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }
|
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }
|
||||||
auto isUsingReversedColor() -> bool { return use_reversed_colors_; }
|
[[nodiscard]] auto isUsingReversedColor() const -> bool { return use_reversed_colors_; }
|
||||||
[[nodiscard]] auto canBePopped() const -> bool { return !isBeingCreated(); }
|
[[nodiscard]] auto canBePopped() const -> bool { return !isBeingCreated(); }
|
||||||
|
|
||||||
// --- Setters ---
|
// --- Setters ---
|
||||||
void setVelY(float vel_y) { vy_ = vel_y; }
|
void setVelY(float vel_y) { vy_ = vel_y; }
|
||||||
void setSpeed(float speed) { speed_ = speed; }
|
void setSpeed(float speed) { speed_ = speed; }
|
||||||
void setInvulnerable(bool value) { invulnerable_ = value; }
|
void setInvulnerable(bool value) { invulnerable_ = value; }
|
||||||
void setBouncingSound(bool value) { bouncing_sound_enabled_ = value; }
|
void setBouncingSound(bool value) { bouncing_sound_enabled_ = value; }
|
||||||
void setPoppingSound(bool value) { poping_sound_enabled_ = value; }
|
void setPoppingSound(bool value) { poping_sound_enabled_ = value; }
|
||||||
void setSound(bool value) { sound_enabled_ = value; }
|
void setSound(bool value) { sound_enabled_ = value; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Estructura para el efecto de rebote ---
|
// --- Estructura para el efecto de rebote ---
|
||||||
struct Bouncing {
|
struct Bouncing {
|
||||||
bool enabled = false; // Si el efecto está activo
|
bool enabled = false; // Si el efecto está activo
|
||||||
Uint8 counter = 0; // Contador para el efecto
|
Uint8 counter = 0; // Contador para el efecto
|
||||||
Uint8 speed = 2; // Velocidad del efecto
|
Uint8 speed = 2; // Velocidad del efecto
|
||||||
float zoom_w = 1.0f; // Zoom en anchura
|
float horizontal_zoom = 1.0F; // Zoom en anchura
|
||||||
float zoom_h = 1.0f; // Zoom en altura
|
float verical_zoom = 1.0F; // Zoom en altura
|
||||||
float desp_x = 0.0f; // Desplazamiento X antes de pintar
|
float desp_x = 0.0F; // Desplazamiento X antes de pintar
|
||||||
float desp_y = 0.0f; // Desplazamiento Y antes de pintar
|
float desp_y = 0.0F; // Desplazamiento Y antes de pintar
|
||||||
|
|
||||||
float w[MAX_BOUNCE] = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f}; // Zoom ancho
|
std::array<float, MAX_BOUNCE> horizontal_zoom_values = {1.10F, 1.05F, 1.00F, 0.95F, 0.90F, 0.95F, 1.00F, 1.02F, 1.05F, 1.02F}; // Zoom ancho
|
||||||
float h[MAX_BOUNCE] = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f}; // Zoom alto
|
std::array<float, MAX_BOUNCE> vertical_zoom_values = {0.90F, 0.95F, 1.00F, 1.05F, 1.10F, 1.05F, 1.00F, 0.98F, 0.95F, 0.98F}; // Zoom alto
|
||||||
|
|
||||||
Bouncing() = default;
|
Bouncing() = default;
|
||||||
void reset() {
|
void reset() {
|
||||||
counter = 0;
|
counter = 0;
|
||||||
zoom_w = 1.0f;
|
horizontal_zoom = 1.0F;
|
||||||
zoom_h = 1.0f;
|
verical_zoom = 1.0F;
|
||||||
desp_x = 0.0f;
|
desp_x = 0.0F;
|
||||||
desp_y = 0.0f;
|
desp_y = 0.0F;
|
||||||
}
|
}
|
||||||
} bouncing_;
|
} bouncing_;
|
||||||
|
|
||||||
// --- Objetos y punteros ---
|
// --- Objetos y punteros ---
|
||||||
std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo
|
std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo
|
||||||
|
|
||||||
// --- Variables de estado y físicas ---
|
// --- Variables de estado y físicas ---
|
||||||
float x_; // Posición X
|
float x_; // Posición X
|
||||||
float y_; // Posición Y
|
float y_; // Posición Y
|
||||||
float w_; // Ancho
|
float w_; // Ancho
|
||||||
float h_; // Alto
|
float h_; // Alto
|
||||||
float vx_; // Velocidad X
|
float vx_; // Velocidad X
|
||||||
float vy_; // Velocidad Y
|
float vy_; // Velocidad Y
|
||||||
float gravity_; // Aceleración en Y
|
float gravity_; // Aceleración en Y
|
||||||
float default_vy_; // Velocidad inicial al rebotar
|
float default_vy_; // Velocidad inicial al rebotar
|
||||||
float max_vy_; // Máxima velocidad en Y
|
float max_vy_; // Máxima velocidad en Y
|
||||||
bool being_created_; // Si el globo se está creando
|
bool being_created_; // Si el globo se está creando
|
||||||
bool enabled_ = true; // Si el globo está activo
|
bool enabled_ = true; // Si el globo está activo
|
||||||
bool invulnerable_; // Si el globo es invulnerable
|
bool invulnerable_; // Si el globo es invulnerable
|
||||||
bool stopped_; // Si el globo está parado
|
bool stopped_; // Si el globo está parado
|
||||||
bool use_reversed_colors_ = false; // Si se usa el color alternativo
|
bool use_reversed_colors_ = false; // Si se usa el color alternativo
|
||||||
Circle collider_; // Círculo de colisión
|
Circle collider_; // Círculo de colisión
|
||||||
Uint16 creation_counter_; // Temporizador de creación
|
Uint16 creation_counter_; // Temporizador de creación
|
||||||
Uint16 creation_counter_ini_; // Valor inicial del temporizador de creación
|
Uint16 creation_counter_ini_; // Valor inicial del temporizador de creación
|
||||||
Uint16 score_; // Puntos al destruir el globo
|
Uint16 score_; // Puntos al destruir el globo
|
||||||
BalloonType type_; // Tipo de globo
|
BalloonType type_; // Tipo de globo
|
||||||
BalloonSize size_; // Tamaño de globo
|
BalloonSize size_; // Tamaño de globo
|
||||||
Uint8 menace_; // Amenaza que genera el globo
|
Uint8 menace_; // Amenaza que genera el globo
|
||||||
Uint32 counter_ = 0; // Contador interno
|
Uint32 counter_ = 0; // Contador interno
|
||||||
float travel_y_ = 1.0f; // Distancia a recorrer en Y antes de aplicar gravedad
|
float travel_y_ = 1.0F; // Distancia a recorrer en Y antes de aplicar gravedad
|
||||||
float speed_; // Velocidad del globo
|
float speed_; // Velocidad del globo
|
||||||
Uint8 power_; // Poder que alberga el globo
|
Uint8 power_; // Poder que alberga el globo
|
||||||
SDL_FRect play_area_; // Zona de movimiento del globo
|
SDL_FRect play_area_; // Zona de movimiento del globo
|
||||||
std::string bouncing_sound_; // Archivo de sonido al rebotar
|
std::string bouncing_sound_; // Archivo de sonido al rebotar
|
||||||
std::string popping_sound_; // Archivo de sonido al explotar
|
std::string popping_sound_; // Archivo de sonido al explotar
|
||||||
bool bouncing_sound_enabled_ = false; // Si debe sonar el globo al rebotar
|
bool bouncing_sound_enabled_ = false; // Si debe sonar el globo al rebotar
|
||||||
bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar
|
bool poping_sound_enabled_ = true; // Si debe sonar el globo al explotar
|
||||||
bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido
|
bool sound_enabled_ = true; // Indica si los globos deben hacer algun sonido
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void shiftColliders(); // Alinea el círculo de colisión
|
void shiftColliders(); // Alinea el círculo de colisión
|
||||||
void shiftSprite(); // Alinea el sprite
|
void shiftSprite(); // Alinea el sprite
|
||||||
void zoomSprite(); // Establece el nivel de zoom del sprite
|
void zoomSprite(); // Establece el nivel de zoom del sprite
|
||||||
void enableBounce(); // Activa el efecto de rebote
|
void enableBounce(); // Activa el efecto de rebote
|
||||||
void disableBounce(); // Detiene el efecto de rebote
|
void disableBounce(); // Detiene el efecto de rebote
|
||||||
void updateBounce(); // Aplica el efecto de rebote
|
void updateBounce(); // Aplica el efecto de rebote
|
||||||
void updateState(); // Actualiza los estados del globo
|
void updateState(); // Actualiza los estados del globo
|
||||||
void setAnimation(); // Establece la animación correspondiente
|
void setAnimation(); // Establece la animación correspondiente
|
||||||
void playSound(const std::string &name); // Reproduce sonido
|
void playSound(const std::string &name) const; // Reproduce sonido
|
||||||
};
|
};
|
||||||
@@ -14,7 +14,7 @@ constexpr int NUMBER_OF_STAGES = 10;
|
|||||||
struct BalloonFormationParams {
|
struct BalloonFormationParams {
|
||||||
int x = 0; // Posición en el eje X donde crear el globo
|
int x = 0; // Posición en el eje X donde crear el globo
|
||||||
int y = 0; // Posición en el eje Y donde crear el globo
|
int y = 0; // Posición en el eje Y donde crear el globo
|
||||||
float vel_x = 0.0f; // Velocidad inicial en el eje X
|
float vel_x = 0.0F; // Velocidad inicial en el eje X
|
||||||
BalloonType type = BalloonType::BALLOON; // Tipo de globo
|
BalloonType type = BalloonType::BALLOON; // Tipo de globo
|
||||||
BalloonSize size = BalloonSize::SIZE1; // Tamaño de globo
|
BalloonSize size = BalloonSize::SIZE1; // Tamaño de globo
|
||||||
int creation_counter = 0; // Temporizador para la creación del globo
|
int creation_counter = 0; // Temporizador para la creación del globo
|
||||||
@@ -36,7 +36,7 @@ struct BalloonFormationUnit {
|
|||||||
: number_of_balloons(num_balloons), init(init_params) {}
|
: number_of_balloons(num_balloons), init(init_params) {}
|
||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
BalloonFormationUnit() : number_of_balloons(0), init() {}
|
BalloonFormationUnit() : number_of_balloons(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
using BalloonFormationPool = std::vector<const BalloonFormationUnit *>;
|
using BalloonFormationPool = std::vector<const BalloonFormationUnit *>;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "balloon_manager.h"
|
#include "balloon_manager.h"
|
||||||
|
|
||||||
#include <algorithm> // Para remove_if
|
#include <algorithm> // Para remove_if
|
||||||
#include <cstdlib> // Para rand
|
#include <array>
|
||||||
#include <numeric> // Para accumulate
|
#include <cstdlib> // Para rand
|
||||||
|
#include <numeric> // Para accumulate
|
||||||
|
|
||||||
#include "balloon.h" // Para Balloon, BALLOON_SCORE, BALLOON_VELX...
|
#include "balloon.h" // Para Balloon, BALLOON_SCORE, BALLOON_VELX...
|
||||||
#include "balloon_formations.h" // Para BalloonFormationParams, BalloonForma...
|
#include "balloon_formations.h" // Para BalloonFormationParams, BalloonForma...
|
||||||
@@ -185,7 +186,7 @@ void BalloonManager::createChildBalloon(const std::shared_ptr<Balloon> &balloon,
|
|||||||
|
|
||||||
// Establece parametros
|
// Establece parametros
|
||||||
b->alignTo(X);
|
b->alignTo(X);
|
||||||
b->setVelY(b->getType() == BalloonType::BALLOON ? -2.50f : BALLOON_VELX_NEGATIVE * 2.0f);
|
b->setVelY(b->getType() == BalloonType::BALLOON ? -2.50F : BALLOON_VELX_NEGATIVE * 2.0F);
|
||||||
|
|
||||||
// Herencia de estados
|
// Herencia de estados
|
||||||
if (balloon->isStopped()) {
|
if (balloon->isStopped()) {
|
||||||
@@ -209,8 +210,8 @@ void BalloonManager::createPowerBall() {
|
|||||||
const float RIGHT = param.game.play_area.rect.w - BALLOON_SIZE[4];
|
const float RIGHT = param.game.play_area.rect.w - BALLOON_SIZE[4];
|
||||||
|
|
||||||
const int LUCK = rand() % VALUES;
|
const int LUCK = rand() % VALUES;
|
||||||
const float POS_X[VALUES] = {LEFT, LEFT, CENTER, CENTER, RIGHT, RIGHT};
|
const std::array<float, VALUES> POS_X = {LEFT, LEFT, CENTER, CENTER, RIGHT, RIGHT};
|
||||||
const float VEL_X[VALUES] = {BALLOON_VELX_POSITIVE, BALLOON_VELX_POSITIVE, BALLOON_VELX_POSITIVE, BALLOON_VELX_NEGATIVE, BALLOON_VELX_NEGATIVE, BALLOON_VELX_NEGATIVE};
|
const std::array<float, VALUES> VEL_X = {BALLOON_VELX_POSITIVE, BALLOON_VELX_POSITIVE, BALLOON_VELX_POSITIVE, BALLOON_VELX_NEGATIVE, BALLOON_VELX_NEGATIVE, BALLOON_VELX_NEGATIVE};
|
||||||
|
|
||||||
balloons_.emplace_back(std::make_unique<Balloon>(POS_X[LUCK], POS_Y, BalloonType::POWERBALL, BalloonSize::SIZE4, VEL_X[LUCK], balloon_speed_, CREATION_TIME, play_area_, balloon_textures_[4], balloon_animations_[4]));
|
balloons_.emplace_back(std::make_unique<Balloon>(POS_X[LUCK], POS_Y, BalloonType::POWERBALL, BalloonSize::SIZE4, VEL_X[LUCK], balloon_speed_, CREATION_TIME, play_area_, balloon_textures_[4], balloon_animations_[4]));
|
||||||
balloons_.back()->setInvulnerable(true);
|
balloons_.back()->setInvulnerable(true);
|
||||||
|
|||||||
@@ -13,36 +13,52 @@ Bullet::Bullet(float x, float y, BulletType bullet_type, bool powered, int owner
|
|||||||
pos_y_(y),
|
pos_y_(y),
|
||||||
bullet_type_(bullet_type),
|
bullet_type_(bullet_type),
|
||||||
owner_(owner) {
|
owner_(owner) {
|
||||||
vel_x_ = (bullet_type_ == BulletType::LEFT) ? VEL_X_LEFT
|
|
||||||
: (bullet_type_ == BulletType::RIGHT) ? VEL_X_RIGHT
|
vel_x_ = calculateVelocity(bullet_type_);
|
||||||
: 0;
|
sprite_->setCurrentAnimation(buildAnimationString(bullet_type_, powered));
|
||||||
|
|
||||||
std::string powered_type = powered ? "powered_" : "normal_";
|
|
||||||
switch (bullet_type) {
|
|
||||||
case BulletType::UP:
|
|
||||||
sprite_->setCurrentAnimation(powered_type + "up");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BulletType::LEFT:
|
|
||||||
sprite_->setCurrentAnimation(powered_type + "left");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BulletType::RIGHT:
|
|
||||||
sprite_->setCurrentAnimation(powered_type + "right");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
collider_.r = WIDTH / 2;
|
collider_.r = WIDTH / 2;
|
||||||
shiftColliders();
|
shiftColliders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calcula la velocidad horizontal de la bala basada en su tipo
|
||||||
|
float Bullet::calculateVelocity(BulletType bullet_type) {
|
||||||
|
switch (bullet_type) {
|
||||||
|
case BulletType::LEFT:
|
||||||
|
return VEL_X_LEFT;
|
||||||
|
case BulletType::RIGHT:
|
||||||
|
return VEL_X_RIGHT;
|
||||||
|
default:
|
||||||
|
return VEL_X_CENTER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construye el string de animación basado en el tipo de bala y si está potenciada
|
||||||
|
std::string Bullet::buildAnimationString(BulletType bullet_type, bool powered) {
|
||||||
|
std::string animation_string = powered ? "powered_" : "normal_";
|
||||||
|
|
||||||
|
switch (bullet_type) {
|
||||||
|
case BulletType::UP:
|
||||||
|
animation_string += "up";
|
||||||
|
break;
|
||||||
|
case BulletType::LEFT:
|
||||||
|
animation_string += "left";
|
||||||
|
break;
|
||||||
|
case BulletType::RIGHT:
|
||||||
|
animation_string += "right";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return animation_string;
|
||||||
|
}
|
||||||
|
|
||||||
// Implementación de render (llama al render del sprite_)
|
// Implementación de render (llama al render del sprite_)
|
||||||
void Bullet::render() {
|
void Bullet::render() {
|
||||||
if (bullet_type_ != BulletType::NONE)
|
if (bullet_type_ != BulletType::NONE) {
|
||||||
sprite_->render();
|
sprite_->render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el estado del objeto
|
// Actualiza el estado del objeto
|
||||||
|
|||||||
@@ -23,46 +23,49 @@ enum class BulletMoveStatus : Uint8 {
|
|||||||
|
|
||||||
// Clase Bullet
|
// Clase Bullet
|
||||||
class Bullet {
|
class Bullet {
|
||||||
public:
|
public:
|
||||||
// Constantes
|
// Constantes
|
||||||
static constexpr float WIDTH = 12.0f;
|
static constexpr float WIDTH = 12.0F;
|
||||||
static constexpr float HEIGHT = 12.0f;
|
static constexpr float HEIGHT = 12.0F;
|
||||||
|
|
||||||
// Constructor y Destructor
|
// Constructor y Destructor
|
||||||
Bullet(float x, float y, BulletType bullet_type, bool powered, int owner);
|
Bullet(float x, float y, BulletType bullet_type, bool powered, int owner);
|
||||||
~Bullet() = default;
|
~Bullet() = default;
|
||||||
|
|
||||||
// Métodos principales
|
// Métodos principales
|
||||||
void render(); // Dibuja la bala en pantalla
|
void render(); // Dibuja la bala en pantalla
|
||||||
auto update() -> BulletMoveStatus; // Actualiza el estado del objeto
|
auto update() -> BulletMoveStatus; // Actualiza el estado del objeto
|
||||||
|
|
||||||
// Estado de la bala
|
// Estado de la bala
|
||||||
[[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activa
|
[[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activa
|
||||||
void disable(); // Desactiva la bala
|
void disable(); // Desactiva la bala
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
[[nodiscard]] auto getOwner() const -> int; // Devuelve el identificador del dueño
|
[[nodiscard]] auto getOwner() const -> int; // Devuelve el identificador del dueño
|
||||||
auto getCollider() -> Circle &; // Devuelve el círculo de colisión
|
auto getCollider() -> Circle &; // Devuelve el círculo de colisión
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Constantes
|
// Constantes
|
||||||
static constexpr float VEL_Y = -3.0f;
|
static constexpr float VEL_Y = -3.0F;
|
||||||
static constexpr float VEL_X_LEFT = -2.0f;
|
static constexpr float VEL_X_LEFT = -2.0F;
|
||||||
static constexpr float VEL_X_RIGHT = 2.0f;
|
static constexpr float VEL_X_RIGHT = 2.0F;
|
||||||
|
static constexpr float VEL_X_CENTER = 0.0F;
|
||||||
|
|
||||||
// Propiedades
|
// Propiedades
|
||||||
std::unique_ptr<AnimatedSprite> sprite_; // Sprite con los gráficos
|
std::unique_ptr<AnimatedSprite> sprite_; // Sprite con los gráficos
|
||||||
|
|
||||||
float pos_x_; // Posición en el eje X
|
float pos_x_; // Posición en el eje X
|
||||||
float pos_y_; // Posición en el eje Y
|
float pos_y_; // Posición en el eje Y
|
||||||
float vel_x_; // Velocidad en el eje X
|
float vel_x_; // Velocidad en el eje X
|
||||||
|
|
||||||
BulletType bullet_type_; // Tipo de bala
|
BulletType bullet_type_; // Tipo de bala
|
||||||
int owner_; // Identificador del dueño
|
int owner_; // Identificador del dueño
|
||||||
Circle collider_; // Círculo de colisión
|
Circle collider_; // Círculo de colisión
|
||||||
|
|
||||||
// Métodos internos
|
// Métodos internos
|
||||||
void shiftColliders(); // Ajusta el círculo de colisión
|
void shiftColliders(); // Ajusta el círculo de colisión
|
||||||
void shiftSprite(); // Ajusta el sprite
|
void shiftSprite(); // Ajusta el sprite
|
||||||
auto move() -> BulletMoveStatus; // Mueve la bala y devuelve su estado
|
auto move() -> BulletMoveStatus; // Mueve la bala y devuelve su estado
|
||||||
|
float calculateVelocity(BulletType bullet_type); // Calcula la velocidad horizontal de la bala basada en su tipo
|
||||||
|
std::string buildAnimationString(BulletType bullet_type, bool powered); // Construye el string de animación basado en el tipo de bala y si está potenciada
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "define_buttons.h"
|
#include "define_buttons.h"
|
||||||
|
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
#include "input.h" // Para Input, InputAction
|
#include "input.h" // Para Input, InputAction
|
||||||
#include "lang.h" // Para getText
|
#include "lang.h" // Para getText
|
||||||
#include "options.h" // Para OptionsController, Options, options
|
#include "options.h" // Para OptionsController, Options, options
|
||||||
@@ -86,9 +88,6 @@ auto DefineButtons::enable(int index) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si está habilitado
|
|
||||||
auto DefineButtons::isEnabled() const -> bool { return enabled_; }
|
|
||||||
|
|
||||||
// Incrementa el indice de los botones
|
// Incrementa el indice de los botones
|
||||||
void DefineButtons::incIndexButton() {
|
void DefineButtons::incIndexButton() {
|
||||||
if (index_button_ < buttons_.size() - 1) {
|
if (index_button_ < buttons_.size() - 1) {
|
||||||
@@ -100,7 +99,6 @@ void DefineButtons::incIndexButton() {
|
|||||||
|
|
||||||
// Guarda los cambios en las opciones
|
// Guarda los cambios en las opciones
|
||||||
void DefineButtons::saveBindingsToOptions() {
|
void DefineButtons::saveBindingsToOptions() {
|
||||||
// Modifica las opciones para colocar los valores asignados
|
|
||||||
auto &controller = Options::controllers.at(index_controller_);
|
auto &controller = Options::controllers.at(index_controller_);
|
||||||
controller.name = input_->getControllerName(index_controller_);
|
controller.name = input_->getControllerName(index_controller_);
|
||||||
for (size_t j = 0; j < controller.inputs.size(); ++j) {
|
for (size_t j = 0; j < controller.inputs.size(); ++j) {
|
||||||
@@ -110,12 +108,9 @@ void DefineButtons::saveBindingsToOptions() {
|
|||||||
|
|
||||||
// Comprueba que un botón no esté ya asignado
|
// Comprueba que un botón no esté ya asignado
|
||||||
auto DefineButtons::checkButtonNotInUse(SDL_GamepadButton button) -> bool {
|
auto DefineButtons::checkButtonNotInUse(SDL_GamepadButton button) -> bool {
|
||||||
for (const auto &b : buttons_) {
|
return std::ranges::all_of(buttons_, [button](const auto &b) {
|
||||||
if (b.button == button) {
|
return b.button != button;
|
||||||
return false;
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limpia la asignación de botones
|
// Limpia la asignación de botones
|
||||||
@@ -130,18 +125,10 @@ void DefineButtons::clearButtons() {
|
|||||||
|
|
||||||
// Comprueba si ha finalizado
|
// Comprueba si ha finalizado
|
||||||
void DefineButtons::checkEnd() {
|
void DefineButtons::checkEnd() {
|
||||||
// Comprueba si ha finalizado
|
|
||||||
if (finished_) {
|
if (finished_) {
|
||||||
// Asigna los botones definidos al input_
|
bindButtons(); // Asigna los botones definidos al input_
|
||||||
bindButtons();
|
saveBindingsToOptions(); // Guarda los cambios en las opciones
|
||||||
|
input_->resetInputStates(); // Reinicia los estados de las pulsaciones de los botones
|
||||||
// Guarda los cambios en las opciones
|
enabled_ = false; // Deshabilita
|
||||||
saveBindingsToOptions();
|
|
||||||
|
|
||||||
// Reinicia los estados de las pulsaciones de los botones
|
|
||||||
input_->resetInputStates();
|
|
||||||
|
|
||||||
// Deshabilita
|
|
||||||
enabled_ = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,45 +15,45 @@ enum class InputAction : int;
|
|||||||
|
|
||||||
// Estructura para definir botones
|
// Estructura para definir botones
|
||||||
struct DefineButtonsButton {
|
struct DefineButtonsButton {
|
||||||
std::string label; // Texto en pantalla
|
std::string label; // Texto en pantalla
|
||||||
InputAction input; // Acción asociada
|
InputAction input; // Acción asociada
|
||||||
SDL_GamepadButton button; // Botón del mando
|
SDL_GamepadButton button; // Botón del mando
|
||||||
|
|
||||||
DefineButtonsButton(std::string lbl, InputAction inp, SDL_GamepadButton btn)
|
DefineButtonsButton(std::string lbl, InputAction inp, SDL_GamepadButton btn)
|
||||||
: label(std::move(lbl)), input(inp), button(btn) {}
|
: label(std::move(lbl)), input(inp), button(btn) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clase DefineButtons
|
// Clase DefineButtons
|
||||||
class DefineButtons {
|
class DefineButtons {
|
||||||
public:
|
public:
|
||||||
DefineButtons();
|
DefineButtons();
|
||||||
~DefineButtons() = default;
|
~DefineButtons() = default;
|
||||||
|
|
||||||
void render(); // Dibuja el objeto en pantalla
|
void render(); // Dibuja el objeto en pantalla
|
||||||
void checkEvents(const SDL_Event &event); // Procesa los eventos
|
void checkEvents(const SDL_Event &event); // Procesa los eventos
|
||||||
auto enable(int index_controller) -> bool; // Habilita la redefinición de botones
|
auto enable(int index_controller) -> bool; // Habilita la redefinición de botones
|
||||||
[[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está habilitado
|
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }; // Comprueba si está habilitado
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Objetos
|
// Objetos
|
||||||
Input *input_ = nullptr; // Gestión de entrada
|
Input *input_ = nullptr; // Gestión de entrada
|
||||||
std::shared_ptr<Text> text_; // Renderizado de texto
|
std::shared_ptr<Text> text_; // Renderizado de texto
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
bool enabled_ = false; // Indica si está activo
|
bool enabled_ = false; // Indica si está activo
|
||||||
int x_ = 0, y_ = 0; // Coordenadas de texto
|
int x_ = 0, y_ = 0; // Coordenadas de texto
|
||||||
std::vector<DefineButtonsButton> buttons_; // Definiciones de botones
|
std::vector<DefineButtonsButton> buttons_; // Definiciones de botones
|
||||||
size_t index_controller_ = 0; // Índice del controlador asignado
|
size_t index_controller_ = 0; // Índice del controlador asignado
|
||||||
size_t index_button_ = 0; // Índice del botón en proceso
|
size_t index_button_ = 0; // Índice del botón en proceso
|
||||||
std::vector<std::string> controller_names_; // Nombres de los mandos
|
std::vector<std::string> controller_names_; // Nombres de los mandos
|
||||||
bool finished_ = false;
|
bool finished_ = false;
|
||||||
|
|
||||||
// Métodos internos
|
// Métodos internos
|
||||||
void incIndexButton(); // Incrementa el índice de botones
|
void incIndexButton(); // Incrementa el índice de botones
|
||||||
void doControllerButtonDown(const SDL_GamepadButtonEvent &event); // Procesa pulsaciones
|
void doControllerButtonDown(const SDL_GamepadButtonEvent &event); // Procesa pulsaciones
|
||||||
void bindButtons(); // Asigna botones al sistema de entrada
|
void bindButtons(); // Asigna botones al sistema de entrada
|
||||||
void saveBindingsToOptions(); // Guarda configuraciones
|
void saveBindingsToOptions(); // Guarda configuraciones
|
||||||
auto checkButtonNotInUse(SDL_GamepadButton button) -> bool; // Verifica uso de botones
|
auto checkButtonNotInUse(SDL_GamepadButton button) -> bool; // Verifica uso de botones
|
||||||
void clearButtons(); // Limpia asignaciones actuales
|
void clearButtons(); // Limpia asignaciones actuales
|
||||||
void checkEnd(); // Comprueba si ha finalizado
|
void checkEnd(); // Comprueba si ha finalizado
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <cstdlib> // Para exit, EXIT_FAILURE, size_t, srand
|
#include <cstdlib> // Para exit, EXIT_FAILURE, size_t, srand
|
||||||
#include <ctime> // Para time
|
#include <ctime> // Para time
|
||||||
#include <memory> // Para make_unique, unique_ptr
|
#include <memory> // Para make_unique, unique_ptr
|
||||||
|
#include <span>
|
||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <string> // Para operator+, basic_string, allocator
|
#include <string> // Para operator+, basic_string, allocator
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
@@ -41,7 +42,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Director::Director(int argc, const char *argv[]) {
|
Director::Director(int argc, std::span<char *> argv) {
|
||||||
#ifdef RECORDING
|
#ifdef RECORDING
|
||||||
Section::name = Section::Name::GAME;
|
Section::name = Section::Name::GAME;
|
||||||
Section::options = Section::Options::GAME_PLAY_1P;
|
Section::options = Section::Options::GAME_PLAY_1P;
|
||||||
@@ -434,7 +435,7 @@ void Director::setFileList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba los parametros del programa
|
// Comprueba los parametros del programa
|
||||||
void Director::checkProgramArguments(int argc, const char *argv[]) {
|
void Director::checkProgramArguments(int argc, std::span<char *> argv) {
|
||||||
// Establece la ruta del programa
|
// Establece la ruta del programa
|
||||||
executable_path_ = getPath(argv[0]);
|
executable_path_ = getPath(argv[0]);
|
||||||
|
|
||||||
@@ -587,7 +588,7 @@ void Director::reset() {
|
|||||||
Lang::setLanguage(Options::settings.language);
|
Lang::setLanguage(Options::settings.language);
|
||||||
Audio::get()->stopMusic();
|
Audio::get()->stopMusic();
|
||||||
Audio::get()->stopAllSounds();
|
Audio::get()->stopAllSounds();
|
||||||
if (Section::options == Section::Options::RELOAD || true) {
|
if (true) {
|
||||||
Resource::get()->reload();
|
Resource::get()->reload();
|
||||||
}
|
}
|
||||||
Input::get()->discoverGameControllers();
|
Input::get()->discoverGameControllers();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string> // Para manejar cadenas de texto
|
#include <string> // Para manejar cadenas de texto
|
||||||
|
#include <span>
|
||||||
|
|
||||||
namespace Lang {
|
namespace Lang {
|
||||||
enum class Code : int;
|
enum class Code : int;
|
||||||
@@ -9,7 +10,7 @@ enum class Code : int;
|
|||||||
class Director {
|
class Director {
|
||||||
public:
|
public:
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
Director(int argc, const char *argv[]);
|
Director(int argc, std::span<char*> argv);
|
||||||
~Director();
|
~Director();
|
||||||
|
|
||||||
// --- Bucle principal ---
|
// --- Bucle principal ---
|
||||||
@@ -25,29 +26,29 @@ private:
|
|||||||
void close(); // Cierra y libera recursos
|
void close(); // Cierra y libera recursos
|
||||||
|
|
||||||
// --- Configuración inicial ---
|
// --- Configuración inicial ---
|
||||||
void loadParams(); // Carga los parámetros del programa
|
static void loadParams(); // Carga los parámetros del programa
|
||||||
void loadScoreFile(); // Carga el fichero de puntuaciones
|
static void loadScoreFile(); // Carga el fichero de puntuaciones
|
||||||
void createSystemFolder(const std::string &folder); // Crea la carpeta del sistema
|
void createSystemFolder(const std::string &folder); // Crea la carpeta del sistema
|
||||||
|
|
||||||
// --- Gestión de entrada y archivos ---
|
// --- Gestión de entrada y archivos ---
|
||||||
void bindInputs(); // Asigna botones y teclas al sistema de entrada
|
static void bindInputs(); // Asigna botones y teclas al sistema de entrada
|
||||||
void setFileList(); // Crea el índice de archivos disponibles
|
void setFileList(); // Crea el índice de archivos disponibles
|
||||||
void checkProgramArguments(int argc, const char *argv[]); // Verifica los parámetros del programa
|
void checkProgramArguments(int argc, std::span<char*> argv); // Verifica los parámetros del programa // NOLINT(modernize-avoid-c-arrays)
|
||||||
|
|
||||||
// --- Secciones del programa ---
|
// --- Secciones del programa ---
|
||||||
void runLogo(); // Ejecuta la pantalla con el logo
|
static void runLogo(); // Ejecuta la pantalla con el logo
|
||||||
void runIntro(); // Ejecuta la introducción del juego
|
static void runIntro(); // Ejecuta la introducción del juego
|
||||||
void runTitle(); // Ejecuta la pantalla de título
|
static void runTitle(); // Ejecuta la pantalla de título
|
||||||
void runGame(); // Inicia el juego
|
static void runGame(); // Inicia el juego
|
||||||
void runInstructions(); // Muestra las instrucciones
|
static void runInstructions(); // Muestra las instrucciones
|
||||||
void runCredits(); // Muestra los créditos del juego
|
static void runCredits(); // Muestra los créditos del juego
|
||||||
void runHiScoreTable(); // Muestra la tabla de puntuaciones
|
static void runHiScoreTable(); // Muestra la tabla de puntuaciones
|
||||||
void runDemoGame(); // Ejecuta el modo demo
|
static void runDemoGame(); // Ejecuta el modo demo
|
||||||
void reset(); // Reinicia objetos y vuelve a la sección inicial
|
void reset(); // Reinicia objetos y vuelve a la sección inicial
|
||||||
|
|
||||||
// --- Gestión de archivos de idioma ---
|
// --- Gestión de archivos de idioma ---
|
||||||
auto getLangFile(Lang::Code code) -> std::string; // Obtiene un fichero de idioma según el código
|
auto getLangFile(Lang::Code code) -> std::string; // Obtiene un fichero de idioma según el código
|
||||||
|
|
||||||
// --- Apagado del sistema ---
|
// --- Apagado del sistema ---
|
||||||
void shutdownSystem(bool should_shutdown); // Apaga el sistema
|
static void shutdownSystem(bool should_shutdown); // Apaga el sistema
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ void EnterName::init(const std::string &name) {
|
|||||||
else {
|
else {
|
||||||
name_ = name;
|
name_ = name;
|
||||||
position_ = name_.length();
|
position_ = name_.length();
|
||||||
position_overflow_ = position_ >= NAME_SIZE ? true : false;
|
position_overflow_ = position_ >= NAME_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inicializa el vector de indices con el nombre y espacios
|
// Inicializa el vector de indices con el nombre y espacios
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ void Explosions::add(int x, int y, int size) {
|
|||||||
|
|
||||||
// Vacia el vector de elementos finalizados
|
// Vacia el vector de elementos finalizados
|
||||||
void Explosions::freeExplosions() {
|
void Explosions::freeExplosions() {
|
||||||
if (explosions_.empty() == false) {
|
if (!explosions_.empty()) {
|
||||||
for (int i = explosions_.size() - 1; i >= 0; --i) {
|
for (int i = explosions_.size() - 1; i >= 0; --i) {
|
||||||
if (explosions_[i]->animationIsCompleted()) {
|
if (explosions_[i]->animationIsCompleted()) {
|
||||||
explosions_.erase(explosions_.begin() + i);
|
explosions_.erase(explosions_.begin() + i);
|
||||||
|
|||||||
3
source/external/.clang-tidy
vendored
3
source/external/.clang-tidy
vendored
@@ -1 +1,4 @@
|
|||||||
|
# source/external/.clang-tidy
|
||||||
Checks: '-*'
|
Checks: '-*'
|
||||||
|
WarningsAsErrors: ''
|
||||||
|
HeaderFilterRegex: ''
|
||||||
@@ -86,7 +86,7 @@ void Fade::update() {
|
|||||||
|
|
||||||
case FadeType::CENTER: {
|
case FadeType::CENTER: {
|
||||||
// Dibuja sobre el backbuffer_
|
// Dibuja sobre el backbuffer_
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
SDL_SetRenderTarget(renderer_, backbuffer_);
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, a_);
|
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, a_);
|
||||||
@@ -115,7 +115,7 @@ void Fade::update() {
|
|||||||
case FadeType::RANDOM_SQUARE: {
|
case FadeType::RANDOM_SQUARE: {
|
||||||
if (counter_ % fade_random_squares_delay_ == 0) {
|
if (counter_ % fade_random_squares_delay_ == 0) {
|
||||||
// Cambia el renderizador al backbuffer_ y modifica sus opciones
|
// Cambia el renderizador al backbuffer_ y modifica sus opciones
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
SDL_SetRenderTarget(renderer_, backbuffer_);
|
||||||
SDL_BlendMode blend_mode;
|
SDL_BlendMode blend_mode;
|
||||||
SDL_GetRenderDrawBlendMode(renderer_, &blend_mode);
|
SDL_GetRenderDrawBlendMode(renderer_, &blend_mode);
|
||||||
@@ -134,7 +134,7 @@ void Fade::update() {
|
|||||||
SDL_SetRenderTarget(renderer_, temp);
|
SDL_SetRenderTarget(renderer_, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_ = calculateValue(0, static_cast<int>(num_squares_width_ * num_squares_height_), static_cast<int>(counter_ * fade_random_squares_mult_ / fade_random_squares_delay_));
|
value_ = calculateValue(0, (num_squares_width_ * num_squares_height_), (counter_ * fade_random_squares_mult_ / fade_random_squares_delay_));
|
||||||
|
|
||||||
// Comprueba si ha terminado
|
// Comprueba si ha terminado
|
||||||
if (counter_ * fade_random_squares_mult_ / fade_random_squares_delay_ >= num_squares_width_ * num_squares_height_) {
|
if (counter_ * fade_random_squares_mult_ / fade_random_squares_delay_ >= num_squares_width_ * num_squares_height_) {
|
||||||
@@ -148,7 +148,7 @@ void Fade::update() {
|
|||||||
// Counter debe ir de 0 a 150 <-- comprobar si esto es aún cierto
|
// Counter debe ir de 0 a 150 <-- comprobar si esto es aún cierto
|
||||||
if (square_.back().h < param.fade.venetian_size) {
|
if (square_.back().h < param.fade.venetian_size) {
|
||||||
// Dibuja sobre el backbuffer_
|
// Dibuja sobre el backbuffer_
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
SDL_SetRenderTarget(renderer_, backbuffer_);
|
||||||
SDL_BlendMode blend_mode;
|
SDL_BlendMode blend_mode;
|
||||||
SDL_GetRenderDrawBlendMode(renderer_, &blend_mode);
|
SDL_GetRenderDrawBlendMode(renderer_, &blend_mode);
|
||||||
@@ -223,8 +223,8 @@ void Fade::activate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case FadeType::CENTER: {
|
case FadeType::CENTER: {
|
||||||
rect1_ = {0, 0, static_cast<float>(param.game.width), 0};
|
rect1_ = {0, 0, param.game.width, 0};
|
||||||
rect2_ = {0, 0, static_cast<float>(param.game.width), 0};
|
rect2_ = {0, 0, param.game.width, 0};
|
||||||
a_ = 64;
|
a_ = 64;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ void Fade::activate() {
|
|||||||
|
|
||||||
// Añade los cuadrados al vector
|
// Añade los cuadrados al vector
|
||||||
square_.clear();
|
square_.clear();
|
||||||
rect1_ = {0, 0, static_cast<float>(param.game.width), 0};
|
rect1_ = {0, 0, param.game.width, 0};
|
||||||
const int MAX = param.game.height / param.fade.venetian_size;
|
const int MAX = param.game.height / param.fade.venetian_size;
|
||||||
|
|
||||||
for (int i = 0; i < MAX; ++i) {
|
for (int i = 0; i < MAX; ++i) {
|
||||||
@@ -300,7 +300,7 @@ void Fade::setColor(Color color) {
|
|||||||
// Limpia el backbuffer
|
// Limpia el backbuffer
|
||||||
void Fade::cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
|
void Fade::cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
|
||||||
// Dibujamos sobre el backbuffer_
|
// Dibujamos sobre el backbuffer_
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
SDL_SetRenderTarget(renderer_, backbuffer_);
|
||||||
|
|
||||||
// Pintamos la textura con el color del fade
|
// Pintamos la textura con el color del fade
|
||||||
|
|||||||
@@ -86,5 +86,5 @@ private:
|
|||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void init(); // Inicializa variables
|
void init(); // Inicializa variables
|
||||||
void cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a); // Limpia el backbuffer
|
void cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a); // Limpia el backbuffer
|
||||||
auto calculateValue(int min, int max, int current) -> int; // Calcula el valor del fade
|
static auto calculateValue(int min, int max, int current) -> int; // Calcula el valor del fade
|
||||||
};
|
};
|
||||||
@@ -45,17 +45,17 @@ void GameLogo::init() {
|
|||||||
coffee_crisis_status_ = Status::DISABLED;
|
coffee_crisis_status_ = Status::DISABLED;
|
||||||
arcade_edition_status_ = Status::DISABLED;
|
arcade_edition_status_ = Status::DISABLED;
|
||||||
shake_.init(1, 2, 8, XP);
|
shake_.init(1, 2, 8, XP);
|
||||||
zoom_ = 3.0f * ZOOM_FACTOR;
|
zoom_ = 3.0F * ZOOM_FACTOR;
|
||||||
|
|
||||||
// Inicializa el bitmap de 'Coffee'
|
// Inicializa el bitmap de 'Coffee'
|
||||||
coffee_sprite_->setPosX(XP);
|
coffee_sprite_->setPosX(XP);
|
||||||
coffee_sprite_->setPosY(y_ - coffee_texture_->getHeight() - DESP);
|
coffee_sprite_->setPosY(y_ - coffee_texture_->getHeight() - DESP);
|
||||||
coffee_sprite_->setWidth(coffee_texture_->getWidth());
|
coffee_sprite_->setWidth(coffee_texture_->getWidth());
|
||||||
coffee_sprite_->setHeight(coffee_texture_->getHeight());
|
coffee_sprite_->setHeight(coffee_texture_->getHeight());
|
||||||
coffee_sprite_->setVelX(0.0f);
|
coffee_sprite_->setVelX(0.0F);
|
||||||
coffee_sprite_->setVelY(2.5f);
|
coffee_sprite_->setVelY(2.5F);
|
||||||
coffee_sprite_->setAccelX(0.0f);
|
coffee_sprite_->setAccelX(0.0F);
|
||||||
coffee_sprite_->setAccelY(0.1f);
|
coffee_sprite_->setAccelY(0.1F);
|
||||||
coffee_sprite_->setSpriteClip(0, 0, coffee_texture_->getWidth(), coffee_texture_->getHeight());
|
coffee_sprite_->setSpriteClip(0, 0, coffee_texture_->getWidth(), coffee_texture_->getHeight());
|
||||||
coffee_sprite_->setEnabled(true);
|
coffee_sprite_->setEnabled(true);
|
||||||
coffee_sprite_->setFinishedCounter(0);
|
coffee_sprite_->setFinishedCounter(0);
|
||||||
@@ -67,10 +67,10 @@ void GameLogo::init() {
|
|||||||
crisis_sprite_->setPosY(y_ + DESP);
|
crisis_sprite_->setPosY(y_ + DESP);
|
||||||
crisis_sprite_->setWidth(crisis_texture_->getWidth());
|
crisis_sprite_->setWidth(crisis_texture_->getWidth());
|
||||||
crisis_sprite_->setHeight(crisis_texture_->getHeight());
|
crisis_sprite_->setHeight(crisis_texture_->getHeight());
|
||||||
crisis_sprite_->setVelX(0.0f);
|
crisis_sprite_->setVelX(0.0F);
|
||||||
crisis_sprite_->setVelY(-2.5f);
|
crisis_sprite_->setVelY(-2.5F);
|
||||||
crisis_sprite_->setAccelX(0.0f);
|
crisis_sprite_->setAccelX(0.0F);
|
||||||
crisis_sprite_->setAccelY(-0.1f);
|
crisis_sprite_->setAccelY(-0.1F);
|
||||||
crisis_sprite_->setSpriteClip(0, 0, crisis_texture_->getWidth(), crisis_texture_->getHeight());
|
crisis_sprite_->setSpriteClip(0, 0, crisis_texture_->getWidth(), crisis_texture_->getHeight());
|
||||||
crisis_sprite_->setEnabled(true);
|
crisis_sprite_->setEnabled(true);
|
||||||
crisis_sprite_->setFinishedCounter(0);
|
crisis_sprite_->setFinishedCounter(0);
|
||||||
@@ -169,11 +169,11 @@ void GameLogo::update() {
|
|||||||
|
|
||||||
switch (arcade_edition_status_) {
|
switch (arcade_edition_status_) {
|
||||||
case Status::MOVING: {
|
case Status::MOVING: {
|
||||||
zoom_ -= 0.1f * ZOOM_FACTOR;
|
zoom_ -= 0.1F * ZOOM_FACTOR;
|
||||||
arcade_edition_sprite_->setZoom(zoom_);
|
arcade_edition_sprite_->setZoom(zoom_);
|
||||||
if (zoom_ <= 1.0f) {
|
if (zoom_ <= 1.0F) {
|
||||||
arcade_edition_status_ = Status::SHAKING;
|
arcade_edition_status_ = Status::SHAKING;
|
||||||
zoom_ = 1.0f;
|
zoom_ = 1.0F;
|
||||||
arcade_edition_sprite_->setZoom(zoom_);
|
arcade_edition_sprite_->setZoom(zoom_);
|
||||||
shake_.init(1, 2, 8, arcade_edition_sprite_->getX());
|
shake_.init(1, 2, 8, arcade_edition_sprite_->getX());
|
||||||
Audio::get()->playSound("title.wav");
|
Audio::get()->playSound("title.wav");
|
||||||
@@ -224,7 +224,7 @@ auto GameLogo::hasFinished() const -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calcula el desplazamiento vertical inicial
|
// Calcula el desplazamiento vertical inicial
|
||||||
auto GameLogo::getInitialVerticalDesp() -> int {
|
auto GameLogo::getInitialVerticalDesp() const -> int {
|
||||||
const float OFFSET_UP = y_;
|
const float OFFSET_UP = y_;
|
||||||
const float OFFSET_DOWN = param.game.height - y_;
|
const float OFFSET_DOWN = param.game.height - y_;
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ private:
|
|||||||
// --- Variables de estado ---
|
// --- Variables de estado ---
|
||||||
float x_; // Posición X del logo
|
float x_; // Posición X del logo
|
||||||
float y_; // Posición Y del logo
|
float y_; // Posición Y del logo
|
||||||
float zoom_ = 1.0f; // Zoom aplicado al texto "ARCADE EDITION"
|
float zoom_ = 1.0F; // Zoom aplicado al texto "ARCADE EDITION"
|
||||||
int post_finished_counter_ = 1; // Contador final tras animaciones
|
int post_finished_counter_ = 1; // Contador final tras animaciones
|
||||||
|
|
||||||
Status coffee_crisis_status_ = Status::DISABLED; // Estado de "COFFEE CRISIS"
|
Status coffee_crisis_status_ = Status::DISABLED; // Estado de "COFFEE CRISIS"
|
||||||
@@ -78,5 +78,5 @@ private:
|
|||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void init(); // Inicializa las variables
|
void init(); // Inicializa las variables
|
||||||
auto getInitialVerticalDesp() -> int; // Calcula el desplazamiento vertical inicial
|
[[nodiscard]] auto getInitialVerticalDesp() const -> int; // Calcula el desplazamiento vertical inicial
|
||||||
};
|
};
|
||||||
@@ -99,7 +99,7 @@ void changeLang() {
|
|||||||
const std::string CODE = "LANG";
|
const std::string CODE = "LANG";
|
||||||
if (Notifier::get()->checkCode(CODE)) {
|
if (Notifier::get()->checkCode(CODE)) {
|
||||||
Options::settings.language = Lang::getNextLangCode(Options::settings.language);
|
Options::settings.language = Lang::getNextLangCode(Options::settings.language);
|
||||||
Lang::loadFromFile(getLangFile(static_cast<Lang::Code>(Options::settings.language)));
|
Lang::loadFromFile(getLangFile(Options::settings.language));
|
||||||
Section::name = Section::Name::RESET;
|
Section::name = Section::Name::RESET;
|
||||||
Section::options = Section::Options::RELOAD;
|
Section::options = Section::Options::RELOAD;
|
||||||
Notifier::get()->show({Lang::getText("[NOTIFICATIONS] 05") + getLangName(Options::settings.language)});
|
Notifier::get()->show({Lang::getText("[NOTIFICATIONS] 05") + getLangName(Options::settings.language)});
|
||||||
@@ -182,8 +182,9 @@ auto checkServiceButton() -> bool {
|
|||||||
|
|
||||||
// Comprueba las entradas del menú de servicio
|
// Comprueba las entradas del menú de servicio
|
||||||
auto checkServiceInputs() -> bool {
|
auto checkServiceInputs() -> bool {
|
||||||
if (!ServiceMenu::get()->isEnabled())
|
if (!ServiceMenu::get()->isEnabled()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Teclado
|
// Teclado
|
||||||
{
|
{
|
||||||
@@ -302,7 +303,7 @@ auto checkInputs() -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Saltar sección
|
// Saltar sección
|
||||||
if (Input::get()->checkAnyButton() && !ServiceMenu::get()->isEnabled()) {
|
if ((Input::get()->checkAnyButton() != 0) && !ServiceMenu::get()->isEnabled()) {
|
||||||
skipSection();
|
skipSection();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -362,12 +363,15 @@ auto checkInputs() -> bool {
|
|||||||
|
|
||||||
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
||||||
auto check() -> bool {
|
auto check() -> bool {
|
||||||
if (checkServiceButton())
|
if (checkServiceButton()) {
|
||||||
return true;
|
return true;
|
||||||
if (checkServiceInputs())
|
}
|
||||||
|
if (checkServiceInputs()) {
|
||||||
return true;
|
return true;
|
||||||
if (checkInputs())
|
}
|
||||||
|
if (checkInputs()) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // namespace GlobalInputs
|
} // namespace GlobalInputs
|
||||||
@@ -154,7 +154,7 @@ auto Input::discoverGameControllers() -> bool {
|
|||||||
joysticks_.clear();
|
joysticks_.clear();
|
||||||
for (int i = 0; i < num_joysticks_; ++i) {
|
for (int i = 0; i < num_joysticks_; ++i) {
|
||||||
// Usar el ID del joystick, no el índice
|
// Usar el ID del joystick, no el índice
|
||||||
auto joy = SDL_OpenJoystick(joystick_ids[i]);
|
auto *joy = SDL_OpenJoystick(joystick_ids[i]);
|
||||||
joysticks_.push_back(joy);
|
joysticks_.push_back(joy);
|
||||||
|
|
||||||
// En SDL3, SDL_IsGamepad toma un SDL_JoystickID, no un índice
|
// En SDL3, SDL_IsGamepad toma un SDL_JoystickID, no un índice
|
||||||
@@ -178,13 +178,13 @@ auto Input::discoverGameControllers() -> bool {
|
|||||||
for (int i = 0; i < num_joysticks_; i++) {
|
for (int i = 0; i < num_joysticks_; i++) {
|
||||||
if (SDL_IsGamepad(joystick_ids[i])) {
|
if (SDL_IsGamepad(joystick_ids[i])) {
|
||||||
// Abre el mando usando el ID del joystick
|
// Abre el mando usando el ID del joystick
|
||||||
auto pad = SDL_OpenGamepad(joystick_ids[i]);
|
auto *pad = SDL_OpenGamepad(joystick_ids[i]);
|
||||||
if (pad != nullptr) {
|
if (pad != nullptr) {
|
||||||
connected_controllers_.push_back(pad);
|
connected_controllers_.push_back(pad);
|
||||||
|
|
||||||
// Obtener el nombre usando el ID del joystick
|
// Obtener el nombre usando el ID del joystick
|
||||||
const char *name_cstr = SDL_GetGamepadNameForID(joystick_ids[i]);
|
const char *name_cstr = SDL_GetGamepadNameForID(joystick_ids[i]);
|
||||||
std::string name = name_cstr ? name_cstr : "Unknown Gamepad";
|
std::string name = (name_cstr != nullptr) ? name_cstr : "Unknown Gamepad";
|
||||||
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "#%d: %s", i, name.c_str());
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "#%d: %s", i, name.c_str());
|
||||||
controller_names_.push_back(name);
|
controller_names_.push_back(name);
|
||||||
@@ -198,7 +198,7 @@ auto Input::discoverGameControllers() -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Liberar el array de IDs
|
// Liberar el array de IDs
|
||||||
if (joystick_ids) {
|
if (joystick_ids != nullptr) {
|
||||||
SDL_free(joystick_ids);
|
SDL_free(joystick_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ auto Input::discoverGameControllers() -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si hay algun mando conectado
|
// Comprueba si hay algun mando conectado
|
||||||
auto Input::gameControllerFound() -> bool { return num_gamepads_ > 0 ? true : false; }
|
auto Input::gameControllerFound() const -> bool { return num_gamepads_ > 0; }
|
||||||
|
|
||||||
// Obten el nombre de un mando de juego
|
// Obten el nombre de un mando de juego
|
||||||
auto Input::getControllerName(int controller_index) const -> std::string { return num_gamepads_ > 0 ? controller_names_.at(controller_index) : std::string(); }
|
auto Input::getControllerName(int controller_index) const -> std::string { return num_gamepads_ > 0 ? controller_names_.at(controller_index) : std::string(); }
|
||||||
@@ -258,7 +258,7 @@ auto Input::getIndexByName(const std::string &name) const -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convierte un InputAction a std::string
|
// Convierte un InputAction a std::string
|
||||||
auto Input::inputToString(InputAction input) const -> std::string {
|
auto Input::inputToString(InputAction input) -> std::string {
|
||||||
switch (input) {
|
switch (input) {
|
||||||
case InputAction::FIRE_LEFT:
|
case InputAction::FIRE_LEFT:
|
||||||
return "input_fire_left";
|
return "input_fire_left";
|
||||||
@@ -276,7 +276,7 @@ auto Input::inputToString(InputAction input) const -> std::string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convierte un std::string a InputAction
|
// Convierte un std::string a InputAction
|
||||||
auto Input::stringToInput(const std::string &name) const -> InputAction {
|
auto Input::stringToInput(const std::string &name) -> InputAction {
|
||||||
static const std::unordered_map<std::string, InputAction> INPUT_MAP = {
|
static const std::unordered_map<std::string, InputAction> INPUT_MAP = {
|
||||||
{"input_fire_left", InputAction::FIRE_LEFT},
|
{"input_fire_left", InputAction::FIRE_LEFT},
|
||||||
{"input_fire_center", InputAction::FIRE_CENTER},
|
{"input_fire_center", InputAction::FIRE_CENTER},
|
||||||
@@ -316,19 +316,18 @@ auto Input::checkAxisInput(InputAction input, int controller_index, bool repeat)
|
|||||||
if (repeat) {
|
if (repeat) {
|
||||||
// Si se permite repetir, simplemente devolvemos el estado actual
|
// Si se permite repetir, simplemente devolvemos el estado actual
|
||||||
return axis_active_now;
|
return axis_active_now;
|
||||||
} else {
|
} // Si no se permite repetir, aplicamos la lógica de transición
|
||||||
// Si no se permite repetir, aplicamos la lógica de transición
|
if (axis_active_now && !binding.axis_active) {
|
||||||
if (axis_active_now && !binding.axis_active) {
|
// Transición de inactivo a activo
|
||||||
// Transición de inactivo a activo
|
binding.axis_active = true;
|
||||||
binding.axis_active = true;
|
return true;
|
||||||
return true;
|
|
||||||
} else if (!axis_active_now && binding.axis_active) {
|
|
||||||
// Transición de activo a inactivo
|
|
||||||
binding.axis_active = false;
|
|
||||||
}
|
|
||||||
// Mantener el estado actual
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
if (!axis_active_now && binding.axis_active) {
|
||||||
|
// Transición de activo a inactivo
|
||||||
|
binding.axis_active = false;
|
||||||
|
}
|
||||||
|
// Mantener el estado actual
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::initSDLGamePad() {
|
void Input::initSDLGamePad() {
|
||||||
@@ -373,7 +372,7 @@ void Input::update() {
|
|||||||
// --- MANDOS ---
|
// --- MANDOS ---
|
||||||
for (int c = 0; c < num_gamepads_; ++c) {
|
for (int c = 0; c < num_gamepads_; ++c) {
|
||||||
for (size_t i = 0; i < controller_bindings_[c].size(); ++i) {
|
for (size_t i = 0; i < controller_bindings_[c].size(); ++i) {
|
||||||
bool button_is_down_now = SDL_GetGamepadButton(connected_controllers_.at(c), controller_bindings_.at(c).at(i).button) != 0;
|
bool button_is_down_now = static_cast<int>(SDL_GetGamepadButton(connected_controllers_.at(c), controller_bindings_.at(c).at(i).button)) != 0;
|
||||||
|
|
||||||
// El estado .is_held del fotograma anterior nos sirve para saber si es un pulso nuevo
|
// El estado .is_held del fotograma anterior nos sirve para saber si es un pulso nuevo
|
||||||
controller_bindings_[c][i].just_pressed = button_is_down_now && !controller_bindings_[c][i].is_held;
|
controller_bindings_[c][i].just_pressed = button_is_down_now && !controller_bindings_[c][i].is_held;
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class Input {
|
|||||||
|
|
||||||
// --- Métodos de gestión de mandos ---
|
// --- Métodos de gestión de mandos ---
|
||||||
auto discoverGameControllers() -> bool; // Busca si hay mandos conectados
|
auto discoverGameControllers() -> bool; // Busca si hay mandos conectados
|
||||||
auto gameControllerFound() -> bool; // Comprueba si hay algún mando conectado
|
[[nodiscard]] auto gameControllerFound() const -> bool; // Comprueba si hay algún mando conectado
|
||||||
[[nodiscard]] auto getNumControllers() const -> int; // Obtiene el número de mandos conectados
|
[[nodiscard]] auto getNumControllers() const -> int; // Obtiene el número de mandos conectados
|
||||||
[[nodiscard]] auto getControllerName(int controller_index) const -> std::string; // Obtiene el nombre de un mando de juego
|
[[nodiscard]] auto getControllerName(int controller_index) const -> std::string; // Obtiene el nombre de un mando de juego
|
||||||
[[nodiscard]] auto getJoyIndex(SDL_JoystickID id) const -> int; // Obtiene el índice del controlador a partir de un event.id
|
[[nodiscard]] auto getJoyIndex(SDL_JoystickID id) const -> int; // Obtiene el índice del controlador a partir de un event.id
|
||||||
@@ -95,8 +95,8 @@ class Input {
|
|||||||
// --- Métodos de consulta y utilidades ---
|
// --- Métodos de consulta y utilidades ---
|
||||||
void printBindings(InputDevice device = InputDevice::KEYBOARD, int controller_index = 0) const; // Muestra por consola los controles asignados
|
void printBindings(InputDevice device = InputDevice::KEYBOARD, int controller_index = 0) const; // Muestra por consola los controles asignados
|
||||||
[[nodiscard]] auto getControllerBinding(int controller_index, InputAction input) const -> SDL_GamepadButton; // Obtiene el SDL_GamepadButton asignado a un input
|
[[nodiscard]] auto getControllerBinding(int controller_index, InputAction input) const -> SDL_GamepadButton; // Obtiene el SDL_GamepadButton asignado a un input
|
||||||
[[nodiscard]] auto inputToString(InputAction input) const -> std::string; // Convierte un InputAction a std::string
|
[[nodiscard]] static auto inputToString(InputAction input) -> std::string; // Convierte un InputAction a std::string
|
||||||
[[nodiscard]] auto stringToInput(const std::string &name) const -> InputAction; // Convierte un std::string a InputAction
|
[[nodiscard]] static auto stringToInput(const std::string &name) -> InputAction; // Convierte un std::string a InputAction
|
||||||
[[nodiscard]] auto getIndexByName(const std::string &name) const -> int; // Obtiene el índice a partir del nombre del mando
|
[[nodiscard]] auto getIndexByName(const std::string &name) const -> int; // Obtiene el índice a partir del nombre del mando
|
||||||
|
|
||||||
// --- Métodos de reseteo de estado de entrada ---
|
// --- Métodos de reseteo de estado de entrada ---
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ Item::Item(ItemType type, float x, float y, SDL_FRect &play_area, std::shared_pt
|
|||||||
height_ = COFFEE_MACHINE_HEIGHT;
|
height_ = COFFEE_MACHINE_HEIGHT;
|
||||||
pos_x_ = getCoffeeMachineSpawn(x, width_, play_area_.w);
|
pos_x_ = getCoffeeMachineSpawn(x, width_, play_area_.w);
|
||||||
pos_y_ = y;
|
pos_y_ = y;
|
||||||
vel_x_ = ((rand() % 3) - 1) * 0.5f;
|
vel_x_ = ((rand() % 3) - 1) * 0.5F;
|
||||||
vel_y_ = -0.1f;
|
vel_y_ = -0.1F;
|
||||||
accel_y_ = 0.1f;
|
accel_y_ = 0.1F;
|
||||||
collider_.r = 10;
|
collider_.r = 10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -29,9 +29,9 @@ Item::Item(ItemType type, float x, float y, SDL_FRect &play_area, std::shared_pt
|
|||||||
height_ = param.game.item_size;
|
height_ = param.game.item_size;
|
||||||
pos_x_ = x;
|
pos_x_ = x;
|
||||||
pos_y_ = y;
|
pos_y_ = y;
|
||||||
vel_x_ = -1.0f + ((rand() % 5) * 0.5f);
|
vel_x_ = -1.0F + ((rand() % 5) * 0.5F);
|
||||||
vel_y_ = -4.0f;
|
vel_y_ = -4.0F;
|
||||||
accel_y_ = 0.2f;
|
accel_y_ = 0.2F;
|
||||||
collider_.r = width_ / 2;
|
collider_.r = width_ / 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -105,24 +105,24 @@ void Item::move() {
|
|||||||
case ItemType::COFFEE_MACHINE:
|
case ItemType::COFFEE_MACHINE:
|
||||||
// La máquina de café es mas pesada y tiene una fisica diferente, ademas hace ruido
|
// La máquina de café es mas pesada y tiene una fisica diferente, ademas hace ruido
|
||||||
floor_collision_ = true;
|
floor_collision_ = true;
|
||||||
if (vel_y_ < 1.0f) {
|
if (vel_y_ < 1.0F) {
|
||||||
// Si la velocidad vertical es baja, detiene el objeto
|
// Si la velocidad vertical es baja, detiene el objeto
|
||||||
vel_y_ = vel_x_ = accel_x_ = accel_y_ = 0;
|
vel_y_ = vel_x_ = accel_x_ = accel_y_ = 0;
|
||||||
} else {
|
} else {
|
||||||
// Si la velocidad vertical es alta, el objeto rebota y pierde velocidad
|
// Si la velocidad vertical es alta, el objeto rebota y pierde velocidad
|
||||||
vel_y_ *= -0.20f;
|
vel_y_ *= -0.20F;
|
||||||
vel_x_ *= 0.75f;
|
vel_x_ *= 0.75F;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Si no es una máquina de café
|
// Si no es una máquina de café
|
||||||
if (vel_y_ < 1.0f) {
|
if (vel_y_ < 1.0F) {
|
||||||
// Si la velocidad vertical es baja, detiene el objeto
|
// Si la velocidad vertical es baja, detiene el objeto
|
||||||
vel_y_ = vel_x_ = accel_x_ = accel_y_ = 0;
|
vel_y_ = vel_x_ = accel_x_ = accel_y_ = 0;
|
||||||
} else {
|
} else {
|
||||||
// Si la velocidad vertical es alta, el objeto rebota y pierde velocidad
|
// Si la velocidad vertical es alta, el objeto rebota y pierde velocidad
|
||||||
vel_y_ *= -0.5f;
|
vel_y_ *= -0.5F;
|
||||||
vel_x_ *= 0.75f;
|
vel_x_ *= 0.75F;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -182,11 +182,11 @@ auto Item::getCoffeeMachineSpawn(int player_x, int item_width, int area_width, i
|
|||||||
if (rand() % 2 == 0) {
|
if (rand() % 2 == 0) {
|
||||||
// Lado izquierdo
|
// Lado izquierdo
|
||||||
return rand() % (exclude_left - LEFT_BOUND) + LEFT_BOUND;
|
return rand() % (exclude_left - LEFT_BOUND) + LEFT_BOUND;
|
||||||
} else {
|
} // Lado derecho
|
||||||
// Lado derecho
|
return rand() % (RIGHT_BOUND - exclude_right) + exclude_right;
|
||||||
return rand() % (RIGHT_BOUND - exclude_right) + exclude_right;
|
|
||||||
}
|
}
|
||||||
} else if (can_spawn_left) {
|
if (can_spawn_left) {
|
||||||
// Solo lado izquierdo disponible
|
// Solo lado izquierdo disponible
|
||||||
return rand() % (exclude_left - LEFT_BOUND) + LEFT_BOUND;
|
return rand() % (exclude_left - LEFT_BOUND) + LEFT_BOUND;
|
||||||
} else if (can_spawn_right) {
|
} else if (can_spawn_right) {
|
||||||
@@ -200,8 +200,7 @@ auto Item::getCoffeeMachineSpawn(int player_x, int item_width, int area_width, i
|
|||||||
|
|
||||||
if (distance_to_left > distance_to_right) {
|
if (distance_to_left > distance_to_right) {
|
||||||
return LEFT_BOUND;
|
return LEFT_BOUND;
|
||||||
} else {
|
|
||||||
return RIGHT_BOUND - item_width;
|
|
||||||
}
|
}
|
||||||
|
return RIGHT_BOUND - item_width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ private:
|
|||||||
int height_; // Alto del objeto
|
int height_; // Alto del objeto
|
||||||
float vel_x_; // Velocidad en el eje X
|
float vel_x_; // Velocidad en el eje X
|
||||||
float vel_y_; // Velocidad en el eje Y
|
float vel_y_; // Velocidad en el eje Y
|
||||||
float accel_x_ = 0.0f; // Aceleración en el eje X
|
float accel_x_ = 0.0F; // Aceleración en el eje X
|
||||||
float accel_y_; // Aceleración en el eje Y
|
float accel_y_; // Aceleración en el eje Y
|
||||||
bool floor_collision_ = false; // Indica si el objeto colisiona con el suelo
|
bool floor_collision_ = false; // Indica si el objeto colisiona con el suelo
|
||||||
ItemType type_; // Tipo de objeto
|
ItemType type_; // Tipo de objeto
|
||||||
@@ -100,5 +100,5 @@ private:
|
|||||||
void updateTimeToLive();
|
void updateTimeToLive();
|
||||||
|
|
||||||
// Calcula la zona de aparición de la máquina de café
|
// Calcula la zona de aparición de la máquina de café
|
||||||
auto getCoffeeMachineSpawn(int player_x, int item_width, int area_width, int margin = 2) -> int;
|
static auto getCoffeeMachineSpawn(int player_x, int item_width, int area_width, int margin = 2) -> int;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,14 +27,15 @@ auto loadFromFile(const std::string &file_path) -> bool {
|
|||||||
texts.clear();
|
texts.clear();
|
||||||
|
|
||||||
std::ifstream rfile(file_path);
|
std::ifstream rfile(file_path);
|
||||||
if (!rfile.is_open())
|
if (!rfile.is_open()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
json j;
|
json j;
|
||||||
rfile >> j;
|
rfile >> j;
|
||||||
|
|
||||||
for (auto &el : j.items()) {
|
for (const auto &el : j.items()) {
|
||||||
texts[el.key()] = el.value();
|
texts[el.key()] = el.value();
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
@@ -48,10 +49,10 @@ auto loadFromFile(const std::string &file_path) -> bool {
|
|||||||
// Obtiene el texto por clave
|
// Obtiene el texto por clave
|
||||||
auto getText(const std::string &key) -> std::string {
|
auto getText(const std::string &key) -> std::string {
|
||||||
auto it = texts.find(key);
|
auto it = texts.find(key);
|
||||||
if (it != texts.end())
|
if (it != texts.end()) {
|
||||||
return it->second;
|
return it->second;
|
||||||
else
|
}
|
||||||
return "[missing text: " + key + "]";
|
return "[missing text: " + key + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el código del siguiente idioma disponible
|
// Obtiene el código del siguiente idioma disponible
|
||||||
@@ -68,8 +69,9 @@ auto getNextLangCode(Code lang) -> Code {
|
|||||||
// Obtiene un idioma del vector de idiomas a partir de un código
|
// Obtiene un idioma del vector de idiomas a partir de un código
|
||||||
auto getLanguage(Code code) -> Language {
|
auto getLanguage(Code code) -> Language {
|
||||||
for (const auto &lang : languages) {
|
for (const auto &lang : languages) {
|
||||||
if (lang.code == code)
|
if (lang.code == code) {
|
||||||
return lang;
|
return lang;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Si no se encuentra, devuelve el primero por defecto
|
// Si no se encuentra, devuelve el primero por defecto
|
||||||
return languages[0];
|
return languages[0];
|
||||||
@@ -78,8 +80,9 @@ auto getLanguage(Code code) -> Language {
|
|||||||
// Devuelve el código de un idioma a partir de un nombre
|
// Devuelve el código de un idioma a partir de un nombre
|
||||||
auto getCodeFromName(const std::string &name) -> Code {
|
auto getCodeFromName(const std::string &name) -> Code {
|
||||||
for (const auto &lang : languages) {
|
for (const auto &lang : languages) {
|
||||||
if (lang.name == name)
|
if (lang.name == name) {
|
||||||
return lang.code;
|
return lang.code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Si no se encuentra, devuelve el primero por defecto
|
// Si no se encuentra, devuelve el primero por defecto
|
||||||
return languages[0].code;
|
return languages[0].code;
|
||||||
@@ -88,8 +91,9 @@ auto getCodeFromName(const std::string &name) -> Code {
|
|||||||
// Devuelve el nombre de un idioma a partir de un código
|
// Devuelve el nombre de un idioma a partir de un código
|
||||||
auto getNameFromCode(Code code) -> std::string {
|
auto getNameFromCode(Code code) -> std::string {
|
||||||
for (const auto &lang : languages) {
|
for (const auto &lang : languages) {
|
||||||
if (lang.code == code)
|
if (lang.code == code) {
|
||||||
return lang.name;
|
return lang.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Si no se encuentra, devuelve el nombre del primer idioma por defecto
|
// Si no se encuentra, devuelve el nombre del primer idioma por defecto
|
||||||
return languages[0].name;
|
return languages[0].name;
|
||||||
@@ -138,8 +142,9 @@ void updateDifficultyNames() {
|
|||||||
// Obtiene una fichero a partir de un lang::Code
|
// Obtiene una fichero a partir de un lang::Code
|
||||||
auto getLanguageFileName(Lang::Code code) -> std::string {
|
auto getLanguageFileName(Lang::Code code) -> std::string {
|
||||||
for (const auto &lang : languages) {
|
for (const auto &lang : languages) {
|
||||||
if (lang.code == code)
|
if (lang.code == code) {
|
||||||
return Asset::get()->get(lang.file_name);
|
return Asset::get()->get(lang.file_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Si no se encuentra, devuelve el fichero del primer idioma por defecto
|
// Si no se encuentra, devuelve el fichero del primer idioma por defecto
|
||||||
return Asset::get()->get(languages[0].file_name);
|
return Asset::get()->get(languages[0].file_name);
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ Actualizando a la versión "Arcade Edition" en 08/05/2024
|
|||||||
|
|
||||||
#include "director.h" // Para Director
|
#include "director.h" // Para Director
|
||||||
|
|
||||||
auto main(int argc, char *argv[]) -> int {
|
auto main(int argc, char* argv[]) -> int {
|
||||||
// Crea el objeto Director
|
// Crea el objeto Director
|
||||||
auto director = std::make_unique<Director>(argc, const_cast<const char **>(argv));
|
auto director = std::make_unique<Director>(argc, std::span<char*>(argv, argc));
|
||||||
|
|
||||||
// Bucle principal
|
// Bucle principal
|
||||||
return director->run();
|
return director->run();
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ void ManageHiScoreTable::sort() {
|
|||||||
auto ManageHiScoreTable::loadFromFile(const std::string &file_path) -> bool {
|
auto ManageHiScoreTable::loadFromFile(const std::string &file_path) -> bool {
|
||||||
clear();
|
clear();
|
||||||
auto success = true;
|
auto success = true;
|
||||||
auto file = SDL_IOFromFile(file_path.c_str(), "rb");
|
auto *file = SDL_IOFromFile(file_path.c_str(), "rb");
|
||||||
|
|
||||||
if (file) {
|
if (file != nullptr) {
|
||||||
table_.clear(); // Limpia la tabla actual
|
table_.clear(); // Limpia la tabla actual
|
||||||
|
|
||||||
// Lee el número de entradas en la tabla
|
// Lee el número de entradas en la tabla
|
||||||
@@ -119,9 +119,9 @@ auto ManageHiScoreTable::loadFromFile(const std::string &file_path) -> bool {
|
|||||||
// Guarda la tabla en un fichero
|
// Guarda la tabla en un fichero
|
||||||
auto ManageHiScoreTable::saveToFile(const std::string &file_path) -> bool {
|
auto ManageHiScoreTable::saveToFile(const std::string &file_path) -> bool {
|
||||||
auto success = true;
|
auto success = true;
|
||||||
auto file = SDL_IOFromFile(file_path.c_str(), "w+b");
|
auto *file = SDL_IOFromFile(file_path.c_str(), "w+b");
|
||||||
|
|
||||||
if (file) {
|
if (file != nullptr) {
|
||||||
// Guarda el número de entradas en la tabla
|
// Guarda el número de entradas en la tabla
|
||||||
int table_size = static_cast<int>(table_.size());
|
int table_size = static_cast<int>(table_.size());
|
||||||
SDL_WriteIO(file, &table_size, sizeof(int));
|
SDL_WriteIO(file, &table_size, sizeof(int));
|
||||||
|
|||||||
@@ -16,34 +16,33 @@ MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_FRect pos)
|
|||||||
: Sprite(texture, pos),
|
: Sprite(texture, pos),
|
||||||
x_(pos.x),
|
x_(pos.x),
|
||||||
y_(pos.y),
|
y_(pos.y),
|
||||||
rotate_(Rotate()),
|
|
||||||
zoom_w_(1.0f),
|
zoom_w_(1.0F),
|
||||||
zoom_h_(1.0f),
|
zoom_h_(1.0F),
|
||||||
flip_(SDL_FLIP_NONE) {}
|
flip_(SDL_FLIP_NONE) {}
|
||||||
|
|
||||||
MovingSprite::MovingSprite(std::shared_ptr<Texture> texture)
|
MovingSprite::MovingSprite(std::shared_ptr<Texture> texture)
|
||||||
: Sprite(texture),
|
: Sprite(texture),
|
||||||
|
|
||||||
rotate_(Rotate()),
|
zoom_w_(1.0F),
|
||||||
zoom_w_(1.0f),
|
zoom_h_(1.0F),
|
||||||
zoom_h_(1.0f),
|
|
||||||
flip_(SDL_FLIP_NONE) { Sprite::clear(); }
|
flip_(SDL_FLIP_NONE) { Sprite::clear(); }
|
||||||
|
|
||||||
// Reinicia todas las variables
|
// Reinicia todas las variables
|
||||||
void MovingSprite::clear() {
|
void MovingSprite::clear() {
|
||||||
x_ = 0.0f; // Posición en el eje X
|
x_ = 0.0F; // Posición en el eje X
|
||||||
y_ = 0.0f; // Posición en el eje Y
|
y_ = 0.0F; // Posición en el eje Y
|
||||||
|
|
||||||
vx_ = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
|
vx_ = 0.0F; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
|
||||||
vy_ = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
|
vy_ = 0.0F; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
|
||||||
|
|
||||||
ax_ = 0.0f; // Aceleración en el eje X. Variación de la velocidad
|
ax_ = 0.0F; // Aceleración en el eje X. Variación de la velocidad
|
||||||
ay_ = 0.0f; // Aceleración en el eje Y. Variación de la velocidad
|
ay_ = 0.0F; // Aceleración en el eje Y. Variación de la velocidad
|
||||||
|
|
||||||
rotate_ = Rotate(); // Inicializa la estructura
|
rotate_ = Rotate(); // Inicializa la estructura
|
||||||
|
|
||||||
zoom_w_ = 1.0f; // Zoom aplicado a la anchura
|
zoom_w_ = 1.0F; // Zoom aplicado a la anchura
|
||||||
zoom_h_ = 1.0f; // Zoom aplicado a la altura
|
zoom_h_ = 1.0F; // Zoom aplicado a la altura
|
||||||
|
|
||||||
flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
|
flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
|
||||||
|
|
||||||
@@ -90,8 +89,8 @@ void MovingSprite::setRotate(bool enable) {
|
|||||||
|
|
||||||
// Establece la posición y_ el tamaño del objeto
|
// Establece la posición y_ el tamaño del objeto
|
||||||
void MovingSprite::setPos(SDL_FRect rect) {
|
void MovingSprite::setPos(SDL_FRect rect) {
|
||||||
x_ = static_cast<float>(rect.x);
|
x_ = rect.x;
|
||||||
y_ = static_cast<float>(rect.y);
|
y_ = rect.y;
|
||||||
|
|
||||||
pos_ = rect;
|
pos_ = rect;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,16 +15,16 @@
|
|||||||
#include "texture.h" // Para Texture
|
#include "texture.h" // Para Texture
|
||||||
|
|
||||||
// Singleton
|
// Singleton
|
||||||
Notifier *Notifier::instance = nullptr;
|
Notifier* Notifier::instance = nullptr;
|
||||||
|
|
||||||
// Inicializa la instancia única del singleton
|
// Inicializa la instancia única del singleton
|
||||||
void Notifier::init(const std::string &icon_file, std::shared_ptr<Text> text) { Notifier::instance = new Notifier(icon_file, text); }
|
void Notifier::init(const std::string& icon_file, std::shared_ptr<Text> text) { Notifier::instance = new Notifier(icon_file, text); }
|
||||||
|
|
||||||
// Libera la instancia
|
// Libera la instancia
|
||||||
void Notifier::destroy() { delete Notifier::instance; }
|
void Notifier::destroy() { delete Notifier::instance; }
|
||||||
|
|
||||||
// Obtiene la instancia
|
// Obtiene la instancia
|
||||||
auto Notifier::get() -> Notifier * { return Notifier::instance; }
|
auto Notifier::get() -> Notifier* { return Notifier::instance; }
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Notifier::Notifier(std::string icon_file, std::shared_ptr<Text> text)
|
Notifier::Notifier(std::string icon_file, std::shared_ptr<Text> text)
|
||||||
@@ -46,71 +46,108 @@ void Notifier::render() {
|
|||||||
// Actualiza el estado de las notificaiones
|
// Actualiza el estado de las notificaiones
|
||||||
void Notifier::update() {
|
void Notifier::update() {
|
||||||
for (int i = 0; i < (int)notifications_.size(); ++i) {
|
for (int i = 0; i < (int)notifications_.size(); ++i) {
|
||||||
// Si la notificación anterior está "saliendo", no hagas nada
|
if (!shouldProcessNotification(i)) {
|
||||||
if (i > 0) {
|
break;
|
||||||
if (notifications_[i - 1].state == NotificationStatus::RISING) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifications_[i].counter++;
|
processNotification(i);
|
||||||
|
|
||||||
// Hace sonar la notificación en el primer frame
|
|
||||||
if (notifications_[i].counter == 1) {
|
|
||||||
if (param.notification.sound) {
|
|
||||||
if (notifications_[i].state == NotificationStatus::RISING) {
|
|
||||||
// Reproduce el sonido de la notificación
|
|
||||||
Audio::get()->playSound("notify.wav", Audio::Group::INTERFACE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comprueba los estados
|
|
||||||
if (notifications_[i].state == NotificationStatus::RISING) {
|
|
||||||
const float STEP = ((float)notifications_[i].counter / notifications_[i].travel_dist);
|
|
||||||
const int ALPHA = 255 * STEP;
|
|
||||||
|
|
||||||
if (param.notification.pos_v == NotifyPosition::TOP) {
|
|
||||||
notifications_[i].rect.y++;
|
|
||||||
} else {
|
|
||||||
notifications_[i].rect.y--;
|
|
||||||
}
|
|
||||||
notifications_[i].texture->setAlpha(ALPHA);
|
|
||||||
|
|
||||||
if (notifications_[i].rect.y == notifications_[i].y) {
|
|
||||||
notifications_[i].state = NotificationStatus::STAY;
|
|
||||||
notifications_[i].texture->setAlpha(255);
|
|
||||||
notifications_[i].counter = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (notifications_[i].state == NotificationStatus::STAY) {
|
|
||||||
if (notifications_[i].counter == wait_time_) {
|
|
||||||
notifications_[i].state = NotificationStatus::VANISHING;
|
|
||||||
notifications_[i].counter = 0;
|
|
||||||
}
|
|
||||||
} else if (notifications_[i].state == NotificationStatus::VANISHING) {
|
|
||||||
const float STEP = (notifications_[i].counter / (float)notifications_[i].travel_dist);
|
|
||||||
const int ALPHA = 255 * (1 - STEP);
|
|
||||||
|
|
||||||
if (param.notification.pos_v == NotifyPosition::TOP) {
|
|
||||||
notifications_[i].rect.y--;
|
|
||||||
} else {
|
|
||||||
notifications_[i].rect.y++;
|
|
||||||
}
|
|
||||||
notifications_[i].texture->setAlpha(ALPHA);
|
|
||||||
|
|
||||||
if (notifications_[i].rect.y == notifications_[i].y - notifications_[i].travel_dist) {
|
|
||||||
notifications_[i].state = NotificationStatus::FINISHED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
notifications_[i].sprite->setPosition(notifications_[i].rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clearFinishedNotifications();
|
clearFinishedNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Notifier::shouldProcessNotification(int index) const {
|
||||||
|
// Si la notificación anterior está "saliendo", no hagas nada
|
||||||
|
if (index > 0 && notifications_[index - 1].state == NotificationStatus::RISING) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Notifier::processNotification(int index) {
|
||||||
|
auto& notification = notifications_[index];
|
||||||
|
notification.counter++;
|
||||||
|
|
||||||
|
playNotificationSoundIfNeeded(notification);
|
||||||
|
updateNotificationState(index);
|
||||||
|
notification.sprite->setPosition(notification.rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Notifier::playNotificationSoundIfNeeded(const Notification& notification) {
|
||||||
|
// Hace sonar la notificación en el primer frame
|
||||||
|
if (notification.counter == 1 &&
|
||||||
|
param.notification.sound &&
|
||||||
|
notification.state == NotificationStatus::RISING) {
|
||||||
|
Audio::get()->playSound("notify.wav", Audio::Group::INTERFACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Notifier::updateNotificationState(int index) {
|
||||||
|
auto& notification = notifications_[index];
|
||||||
|
|
||||||
|
switch (notification.state) {
|
||||||
|
case NotificationStatus::RISING:
|
||||||
|
handleRisingState(index);
|
||||||
|
break;
|
||||||
|
case NotificationStatus::STAY:
|
||||||
|
handleStayState(index);
|
||||||
|
break;
|
||||||
|
case NotificationStatus::VANISHING:
|
||||||
|
handleVanishingState(index);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Notifier::handleRisingState(int index) {
|
||||||
|
auto& notification = notifications_[index];
|
||||||
|
|
||||||
|
const float step = (float)notification.counter / notification.travel_dist;
|
||||||
|
const int alpha = 255 * step;
|
||||||
|
|
||||||
|
moveNotificationVertically(notification, param.notification.pos_v == NotifyPosition::TOP ? 1 : -1);
|
||||||
|
notification.texture->setAlpha(alpha);
|
||||||
|
|
||||||
|
if (notification.rect.y == notification.y) {
|
||||||
|
transitionToStayState(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Notifier::handleStayState(int index) {
|
||||||
|
auto& notification = notifications_[index];
|
||||||
|
|
||||||
|
if (notification.counter == wait_time_) {
|
||||||
|
notification.state = NotificationStatus::VANISHING;
|
||||||
|
notification.counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Notifier::handleVanishingState(int index) {
|
||||||
|
auto& notification = notifications_[index];
|
||||||
|
|
||||||
|
const float step = notification.counter / (float)notification.travel_dist;
|
||||||
|
const int alpha = 255 * (1 - step);
|
||||||
|
|
||||||
|
moveNotificationVertically(notification, param.notification.pos_v == NotifyPosition::TOP ? -1 : 1);
|
||||||
|
notification.texture->setAlpha(alpha);
|
||||||
|
|
||||||
|
if (notification.rect.y == notification.y - notification.travel_dist) {
|
||||||
|
notification.state = NotificationStatus::FINISHED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Notifier::moveNotificationVertically(Notification& notification, int direction) {
|
||||||
|
notification.rect.y += direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Notifier::transitionToStayState(int index) {
|
||||||
|
auto& notification = notifications_[index];
|
||||||
|
notification.state = NotificationStatus::STAY;
|
||||||
|
notification.texture->setAlpha(255);
|
||||||
|
notification.counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Elimina las notificaciones finalizadas
|
// Elimina las notificaciones finalizadas
|
||||||
void Notifier::clearFinishedNotifications() {
|
void Notifier::clearFinishedNotifications() {
|
||||||
for (int i = (int)notifications_.size() - 1; i >= 0; --i) {
|
for (int i = (int)notifications_.size() - 1; i >= 0; --i) {
|
||||||
@@ -120,7 +157,7 @@ void Notifier::clearFinishedNotifications() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notifier::show(std::vector<std::string> texts, int icon, const std::string &code) {
|
void Notifier::show(std::vector<std::string> texts, int icon, const std::string& code) {
|
||||||
// Si no hay texto, acaba
|
// Si no hay texto, acaba
|
||||||
if (texts.empty()) {
|
if (texts.empty()) {
|
||||||
return;
|
return;
|
||||||
@@ -132,14 +169,15 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Elimina las cadenas vacías
|
// Elimina las cadenas vacías
|
||||||
texts.erase(std::remove_if(texts.begin(), texts.end(), [](const std::string &s) { return s.empty(); }),
|
texts.erase(std::remove_if(texts.begin(), texts.end(), [](const std::string& s) { return s.empty(); }),
|
||||||
texts.end());
|
texts.end());
|
||||||
|
|
||||||
// Encuentra la cadena más larga
|
// Encuentra la cadena más larga
|
||||||
std::string longest;
|
std::string longest;
|
||||||
for (const auto &text : texts) {
|
for (const auto& text : texts) {
|
||||||
if (text.length() > longest.length())
|
if (text.length() > longest.length()) {
|
||||||
longest = text;
|
longest = text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inicializa variables
|
// Inicializa variables
|
||||||
@@ -237,7 +275,7 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string
|
|||||||
// Escribe el texto de la notificación
|
// Escribe el texto de la notificación
|
||||||
const Color COLOR{255, 255, 255};
|
const Color COLOR{255, 255, 255};
|
||||||
int iterator = 0;
|
int iterator = 0;
|
||||||
for (const auto &text : texts) {
|
for (const auto& text : texts) {
|
||||||
text_->writeColored(PADDING_IN_H + ICON_SPACE, PADDING_IN_V + iterator * (text_->getCharacterSize() + 1), text, COLOR);
|
text_->writeColored(PADDING_IN_H + ICON_SPACE, PADDING_IN_V + iterator * (text_->getCharacterSize() + 1), text, COLOR);
|
||||||
++iterator;
|
++iterator;
|
||||||
}
|
}
|
||||||
@@ -257,7 +295,7 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string
|
|||||||
|
|
||||||
// Finaliza y elimnina todas las notificaciones activas
|
// Finaliza y elimnina todas las notificaciones activas
|
||||||
void Notifier::clearAllNotifications() {
|
void Notifier::clearAllNotifications() {
|
||||||
for (auto ¬ification : notifications_) {
|
for (auto& notification : notifications_) {
|
||||||
notification.state = NotificationStatus::FINISHED;
|
notification.state = NotificationStatus::FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +305,7 @@ void Notifier::clearAllNotifications() {
|
|||||||
// Obtiene los códigos de las notificaciones
|
// Obtiene los códigos de las notificaciones
|
||||||
auto Notifier::getCodes() -> std::vector<std::string> {
|
auto Notifier::getCodes() -> std::vector<std::string> {
|
||||||
std::vector<std::string> codes;
|
std::vector<std::string> codes;
|
||||||
for (const auto ¬ification : notifications_) {
|
for (const auto& notification : notifications_) {
|
||||||
codes.emplace_back(notification.code);
|
codes.emplace_back(notification.code);
|
||||||
}
|
}
|
||||||
return codes;
|
return codes;
|
||||||
|
|||||||
@@ -14,74 +14,83 @@ class Texture;
|
|||||||
|
|
||||||
// --- Clase Notifier: gestiona las notificaciones en pantalla (singleton) ---
|
// --- Clase Notifier: gestiona las notificaciones en pantalla (singleton) ---
|
||||||
class Notifier {
|
class Notifier {
|
||||||
public:
|
public:
|
||||||
// --- Métodos de singleton ---
|
// --- Métodos de singleton ---
|
||||||
static void init(const std::string &icon_file, std::shared_ptr<Text> text); // Inicializa el singleton
|
static void init(const std::string &icon_file, std::shared_ptr<Text> text); // Inicializa el singleton
|
||||||
static void destroy(); // Libera el singleton
|
static void destroy(); // Libera el singleton
|
||||||
static auto get() -> Notifier *; // Obtiene la instancia
|
static auto get() -> Notifier *; // Obtiene la instancia
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void render(); // Dibuja las notificaciones por pantalla
|
void render(); // Dibuja las notificaciones por pantalla
|
||||||
void update(); // Actualiza el estado de las notificaciones
|
void update(); // Actualiza el estado de las notificaciones
|
||||||
|
|
||||||
// --- Gestión de notificaciones ---
|
// --- Gestión de notificaciones ---
|
||||||
void show(std::vector<std::string> texts, int icon = -1, const std::string &code = std::string()); // Muestra una notificación de texto por pantalla
|
void show(std::vector<std::string> texts, int icon = -1, const std::string &code = std::string()); // Muestra una notificación de texto por pantalla
|
||||||
[[nodiscard]] auto isActive() const -> bool { return !notifications_.empty(); } // Indica si hay notificaciones activas
|
[[nodiscard]] auto isActive() const -> bool { return !notifications_.empty(); } // Indica si hay notificaciones activas
|
||||||
auto getCodes() -> std::vector<std::string>; // Obtiene los códigos de las notificaciones activas
|
auto getCodes() -> std::vector<std::string>; // Obtiene los códigos de las notificaciones activas
|
||||||
auto checkCode(const std::string &code) -> bool { return stringInVector(getCodes(), code); } // Comprueba si hay alguna notificación con un código concreto
|
auto checkCode(const std::string &code) -> bool { return stringInVector(getCodes(), code); } // Comprueba si hay alguna notificación con un código concreto
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Singleton ---
|
// --- Tipos internos ---
|
||||||
static Notifier *instance;
|
enum class NotificationStatus {
|
||||||
|
RISING,
|
||||||
|
STAY,
|
||||||
|
VANISHING,
|
||||||
|
FINISHED,
|
||||||
|
};
|
||||||
|
|
||||||
// --- Tipos internos ---
|
enum class NotificationShape {
|
||||||
enum class NotificationStatus {
|
ROUNDED,
|
||||||
RISING,
|
SQUARED,
|
||||||
STAY,
|
};
|
||||||
VANISHING,
|
|
||||||
FINISHED,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class NotificationShape {
|
// --- Estructura Notification ---
|
||||||
ROUNDED,
|
struct Notification {
|
||||||
SQUARED,
|
std::shared_ptr<Texture> texture; // Textura de la notificación
|
||||||
};
|
std::shared_ptr<Sprite> sprite; // Sprite asociado
|
||||||
|
std::vector<std::string> texts; // Textos a mostrar
|
||||||
|
int counter{0}; // Contador de tiempo
|
||||||
|
NotificationStatus state{NotificationStatus::RISING}; // Estado de la notificación
|
||||||
|
NotificationShape shape{NotificationShape::SQUARED}; // Forma de la notificación
|
||||||
|
SDL_FRect rect; // Rectángulo de la notificación
|
||||||
|
int y{0}; // Posición vertical
|
||||||
|
int travel_dist{0}; // Distancia a recorrer
|
||||||
|
std::string code; // Código identificador de la notificación
|
||||||
|
|
||||||
// --- Estructura Notification ---
|
// Constructor
|
||||||
struct Notification {
|
explicit Notification()
|
||||||
std::shared_ptr<Texture> texture; // Textura de la notificación
|
: texture(nullptr), sprite(nullptr), rect{0, 0, 0, 0} {}
|
||||||
std::shared_ptr<Sprite> sprite; // Sprite asociado
|
};
|
||||||
std::vector<std::string> texts; // Textos a mostrar
|
|
||||||
int counter{0}; // Contador de tiempo
|
|
||||||
NotificationStatus state{NotificationStatus::RISING}; // Estado de la notificación
|
|
||||||
NotificationShape shape{NotificationShape::SQUARED}; // Forma de la notificación
|
|
||||||
SDL_FRect rect; // Rectángulo de la notificación
|
|
||||||
int y{0}; // Posición vertical
|
|
||||||
int travel_dist{0}; // Distancia a recorrer
|
|
||||||
std::string code; // Código identificador de la notificación
|
|
||||||
|
|
||||||
// Constructor
|
// --- Objetos y punteros ---
|
||||||
explicit Notification()
|
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||||
: texture(nullptr), sprite(nullptr), texts(), rect{0, 0, 0, 0}, code("") {}
|
std::shared_ptr<Texture> icon_texture_; // Textura para los iconos de las notificaciones
|
||||||
};
|
std::shared_ptr<Text> text_; // Objeto para dibujar texto
|
||||||
|
|
||||||
// --- Objetos y punteros ---
|
// --- Variables de estado ---
|
||||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
Color bg_color_; // Color de fondo de las notificaciones
|
||||||
std::shared_ptr<Texture> icon_texture_; // Textura para los iconos de las notificaciones
|
int wait_time_; // Tiempo que se ve la notificación
|
||||||
std::shared_ptr<Text> text_; // Objeto para dibujar texto
|
std::vector<Notification> notifications_; // Lista de notificaciones activas
|
||||||
|
bool stack_; // Indica si las notificaciones se apilan
|
||||||
|
bool has_icons_; // Indica si el notificador tiene textura para iconos
|
||||||
|
|
||||||
// --- Variables de estado ---
|
// --- Métodos internos ---
|
||||||
Color bg_color_; // Color de fondo de las notificaciones
|
void clearFinishedNotifications(); // Elimina las notificaciones cuyo estado es FINISHED
|
||||||
int wait_time_; // Tiempo que se ve la notificación
|
void clearAllNotifications(); // Elimina todas las notificaciones activas, sin importar el estado
|
||||||
std::vector<Notification> notifications_; // Lista de notificaciones activas
|
bool shouldProcessNotification(int index) const; // Determina si una notificación debe ser procesada (según su estado y posición)
|
||||||
bool stack_; // Indica si las notificaciones se apilan
|
void processNotification(int index); // Procesa una notificación en la posición dada: actualiza su estado y comportamiento visual
|
||||||
bool has_icons_; // Indica si el notificador tiene textura para iconos
|
void playNotificationSoundIfNeeded(const Notification ¬ification); // Reproduce sonido asociado si es necesario (dependiendo del estado o contenido)
|
||||||
|
void updateNotificationState(int index); // Actualiza el estado interno de una notificación (ej. de RISING a STAY)
|
||||||
|
void handleRisingState(int index); // Lógica de animación para el estado RISING (apareciendo)
|
||||||
|
void handleStayState(int index); // Lógica para mantener una notificación visible en el estado STAY
|
||||||
|
void handleVanishingState(int index); // Lógica de animación para el estado VANISHING (desapareciendo)
|
||||||
|
void moveNotificationVertically(Notification ¬ification, int direction); // Mueve verticalmente una notificación en una dirección dada (útil para animación en apilamiento)
|
||||||
|
void transitionToStayState(int index); // Cambia el estado de una notificación de RISING a STAY cuando ha alcanzado su posición final
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Constructor y destructor ---
|
||||||
void clearFinishedNotifications(); // Elimina las notificaciones finalizadas
|
Notifier(std::string icon_file, std::shared_ptr<Text> text); // Constructor privado
|
||||||
void clearAllNotifications(); // Finaliza y elimina todas las notificaciones activas
|
~Notifier() = default; // Destructor privado
|
||||||
|
|
||||||
// --- Constructor y destructor ---
|
// --- Singleton ---
|
||||||
Notifier(std::string icon_file, std::shared_ptr<Text> text); // Constructor privado
|
static Notifier *instance;
|
||||||
~Notifier() = default; // Destructor privado
|
|
||||||
};
|
};
|
||||||
@@ -300,18 +300,15 @@ void applyPendingChanges() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void checkPendingChanges() {
|
void checkPendingChanges() {
|
||||||
if (settings.language != pending_changes.new_language ||
|
pending_changes.has_pending_changes = settings.language != pending_changes.new_language ||
|
||||||
settings.difficulty != pending_changes.new_difficulty) {
|
settings.difficulty != pending_changes.new_difficulty;
|
||||||
pending_changes.has_pending_changes = true;
|
|
||||||
} else {
|
|
||||||
pending_changes.has_pending_changes = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto getDifficultyCodeFromName(const std::string &name) -> DifficultyCode {
|
auto getDifficultyCodeFromName(const std::string &name) -> DifficultyCode {
|
||||||
for (const auto &difficulty : difficulties) {
|
for (const auto &difficulty : difficulties) {
|
||||||
if (difficulty.name == name)
|
if (difficulty.name == name) {
|
||||||
return difficulty.code;
|
return difficulty.code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Si no se encuentra, devuelve el primero por defecto
|
// Si no se encuentra, devuelve el primero por defecto
|
||||||
return difficulties[0].code;
|
return difficulties[0].code;
|
||||||
@@ -319,8 +316,9 @@ auto getDifficultyCodeFromName(const std::string &name) -> DifficultyCode {
|
|||||||
|
|
||||||
auto getDifficultyNameFromCode(DifficultyCode code) -> std::string {
|
auto getDifficultyNameFromCode(DifficultyCode code) -> std::string {
|
||||||
for (const auto &difficulty : difficulties) {
|
for (const auto &difficulty : difficulties) {
|
||||||
if (difficulty.code == code)
|
if (difficulty.code == code) {
|
||||||
return difficulty.name;
|
return difficulty.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Si no se encuentra, devuelve el nombre del primero por defecto
|
// Si no se encuentra, devuelve el nombre del primero por defecto
|
||||||
return difficulties[0].name;
|
return difficulties[0].name;
|
||||||
|
|||||||
121
source/options.h
121
source/options.h
@@ -22,22 +22,22 @@ enum class DifficultyCode {
|
|||||||
|
|
||||||
// --- Estructura que representa un nivel de dificultad
|
// --- Estructura que representa un nivel de dificultad
|
||||||
struct Difficulty {
|
struct Difficulty {
|
||||||
DifficultyCode code; // Código que identifica la dificultad
|
DifficultyCode code; // Código que identifica la dificultad
|
||||||
std::string name; // Nombre que identifica la dificultad
|
std::string name; // Nombre que identifica la dificultad
|
||||||
|
|
||||||
Difficulty(DifficultyCode c, std::string n)
|
Difficulty(DifficultyCode c, std::string n)
|
||||||
: code(c), name(std::move(n)) {}
|
: code(c), name(std::move(n)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de ventana ---
|
// --- Opciones de ventana ---
|
||||||
struct WindowOptions {
|
struct WindowOptions {
|
||||||
std::string caption; // Texto que aparece en la barra de título de la ventana
|
std::string caption; // Texto que aparece en la barra de título de la ventana
|
||||||
int size{2}; // Valor por el que se multiplica el tamaño de la ventana
|
int size{2}; // Valor por el que se multiplica el tamaño de la ventana
|
||||||
int max_size{2}; // Tamaño máximo para que la ventana no sea mayor que la pantalla
|
int max_size{2}; // Tamaño máximo para que la ventana no sea mayor que la pantalla
|
||||||
|
|
||||||
// Constructor por defecto con valores iniciales
|
// Constructor por defecto con valores iniciales
|
||||||
WindowOptions()
|
WindowOptions()
|
||||||
: caption("Coffee Crisis Arcade Edition") {}
|
: caption("Coffee Crisis Arcade Edition") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de vídeo ---
|
// --- Opciones de vídeo ---
|
||||||
@@ -50,8 +50,7 @@ struct VideoOptions {
|
|||||||
std::string info; // Información sobre el modo de vídeo
|
std::string info; // Información sobre el modo de vídeo
|
||||||
|
|
||||||
// Constructor por defecto con valores iniciales
|
// Constructor por defecto con valores iniciales
|
||||||
VideoOptions()
|
VideoOptions() = default;
|
||||||
: info() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de música ---
|
// --- Opciones de música ---
|
||||||
@@ -60,9 +59,7 @@ struct MusicOptions {
|
|||||||
int volume{100}; // Volumen de la música
|
int volume{100}; // Volumen de la música
|
||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
MusicOptions()
|
MusicOptions() = default;
|
||||||
|
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de sonido ---
|
// --- Opciones de sonido ---
|
||||||
@@ -71,22 +68,18 @@ struct SoundOptions {
|
|||||||
int volume{100}; // Volumen de los sonidos
|
int volume{100}; // Volumen de los sonidos
|
||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
SoundOptions()
|
SoundOptions() = default;
|
||||||
|
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de audio ---
|
// --- Opciones de audio ---
|
||||||
struct AudioOptions {
|
struct AudioOptions {
|
||||||
MusicOptions music; // Opciones para la música
|
MusicOptions music; // Opciones para la música
|
||||||
SoundOptions sound; // Opciones para los efectos de sonido
|
SoundOptions sound; // Opciones para los efectos de sonido
|
||||||
bool enabled{true}; // Indica si el audio está activo o no
|
bool enabled{true}; // Indica si el audio está activo o no
|
||||||
int volume{100}; // Volumen general del audio
|
int volume{100}; // Volumen general del audio
|
||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
AudioOptions()
|
AudioOptions() = default;
|
||||||
: music(),
|
|
||||||
sound() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de configuración ---
|
// --- Opciones de configuración ---
|
||||||
@@ -101,45 +94,41 @@ struct SettingsOptions {
|
|||||||
|
|
||||||
// Constructor por defecto con valores iniciales
|
// Constructor por defecto con valores iniciales
|
||||||
SettingsOptions()
|
SettingsOptions()
|
||||||
: last_hi_score_entry({INVALID_INDEX, INVALID_INDEX}),
|
: last_hi_score_entry({INVALID_INDEX, INVALID_INDEX}) {}
|
||||||
config_file() {}
|
|
||||||
|
|
||||||
// Reinicia las últimas entradas de puntuación
|
// Reinicia las últimas entradas de puntuación
|
||||||
void clearLastHiScoreEntries() {
|
void clearLastHiScoreEntries() {
|
||||||
last_hi_score_entry[0] = INVALID_INDEX;
|
last_hi_score_entry[0] = INVALID_INDEX;
|
||||||
last_hi_score_entry[1] = INVALID_INDEX;
|
last_hi_score_entry[1] = INVALID_INDEX;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones de mando ---
|
// --- Opciones de mando ---
|
||||||
struct GamepadOptions {
|
struct GamepadOptions {
|
||||||
int index; // Índice en el vector de mandos
|
int index; // Índice en el vector de mandos
|
||||||
int player_id; // Jugador asociado al mando
|
int player_id; // Jugador asociado al mando
|
||||||
InputDevice type{InputDevice::CONTROLLER}; // Indica si se usará teclado, mando o ambos
|
InputDevice type{InputDevice::CONTROLLER}; // Indica si se usará teclado, mando o ambos
|
||||||
std::string name; // Nombre del dispositivo
|
std::string name; // Nombre del dispositivo
|
||||||
bool plugged{false}; // Indica si el mando está conectado
|
bool plugged{false}; // Indica si el mando está conectado
|
||||||
std::vector<InputAction> inputs; // Listado de acciones asignadas
|
std::vector<InputAction> inputs; // Listado de acciones asignadas
|
||||||
std::vector<SDL_GamepadButton> buttons; // Listado de botones asignados a cada acción
|
std::vector<SDL_GamepadButton> buttons; // Listado de botones asignados a cada acción
|
||||||
|
|
||||||
// Constructor por defecto
|
// Constructor por defecto
|
||||||
GamepadOptions()
|
GamepadOptions()
|
||||||
: index(INVALID_INDEX),
|
: index(INVALID_INDEX),
|
||||||
player_id(INVALID_INDEX),
|
player_id(INVALID_INDEX),
|
||||||
|
inputs{
|
||||||
name(),
|
InputAction::FIRE_LEFT,
|
||||||
|
InputAction::FIRE_CENTER,
|
||||||
inputs{
|
InputAction::FIRE_RIGHT,
|
||||||
InputAction::FIRE_LEFT,
|
InputAction::START,
|
||||||
InputAction::FIRE_CENTER,
|
InputAction::SERVICE},
|
||||||
InputAction::FIRE_RIGHT,
|
buttons{
|
||||||
InputAction::START,
|
SDL_GAMEPAD_BUTTON_WEST,
|
||||||
InputAction::SERVICE},
|
SDL_GAMEPAD_BUTTON_NORTH,
|
||||||
buttons{
|
SDL_GAMEPAD_BUTTON_EAST,
|
||||||
SDL_GAMEPAD_BUTTON_WEST,
|
SDL_GAMEPAD_BUTTON_START,
|
||||||
SDL_GAMEPAD_BUTTON_NORTH,
|
SDL_GAMEPAD_BUTTON_BACK} {}
|
||||||
SDL_GAMEPAD_BUTTON_EAST,
|
|
||||||
SDL_GAMEPAD_BUTTON_START,
|
|
||||||
SDL_GAMEPAD_BUTTON_BACK} {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Opciones pendientes de aplicar ---
|
// --- Opciones pendientes de aplicar ---
|
||||||
@@ -149,9 +138,7 @@ struct PendingChanges {
|
|||||||
bool has_pending_changes{false}; // Indica si hay cambios pendientes
|
bool has_pending_changes{false}; // Indica si hay cambios pendientes
|
||||||
|
|
||||||
// Constructor por defecto con valores iniciales
|
// Constructor por defecto con valores iniciales
|
||||||
PendingChanges()
|
PendingChanges() = default;
|
||||||
|
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Variables globales ---
|
// --- Variables globales ---
|
||||||
@@ -164,15 +151,15 @@ extern PendingChanges pending_changes; // Opciones que se aplican al c
|
|||||||
extern std::vector<Difficulty> difficulties; // Lista de los diferentes tipos de dificultad
|
extern std::vector<Difficulty> difficulties; // Lista de los diferentes tipos de dificultad
|
||||||
|
|
||||||
// --- Funciones de configuración ---
|
// --- Funciones de configuración ---
|
||||||
void init(); // Inicializa las opciones del programa
|
void init(); // Inicializa las opciones del programa
|
||||||
auto loadFromFile() -> bool; // Carga el fichero de configuración
|
auto loadFromFile() -> bool; // Carga el fichero de configuración
|
||||||
auto saveToFile() -> bool; // Guarda el fichero de configuración
|
auto saveToFile() -> bool; // Guarda el fichero de configuración
|
||||||
void setKeyboardToPlayer(int player_id); // Asigna el teclado al jugador
|
void setKeyboardToPlayer(int player_id); // Asigna el teclado al jugador
|
||||||
void swapKeyboard(); // Intercambia el teclado de jugador
|
void swapKeyboard(); // Intercambia el teclado de jugador
|
||||||
void swapControllers(); // Intercambia los jugadores asignados a los dos primeros mandos
|
void swapControllers(); // Intercambia los jugadores asignados a los dos primeros mandos
|
||||||
auto getPlayerWhoUsesKeyboard() -> int; // Averigua quién está usando el teclado
|
auto getPlayerWhoUsesKeyboard() -> int; // Averigua quién está usando el teclado
|
||||||
void applyPendingChanges(); // Aplica los cambios pendientes copiando los valores a sus variables
|
void applyPendingChanges(); // Aplica los cambios pendientes copiando los valores a sus variables
|
||||||
void checkPendingChanges(); // Verifica si hay cambios pendientes
|
void checkPendingChanges(); // Verifica si hay cambios pendientes
|
||||||
auto getDifficultyCodeFromName(const std::string &name) -> DifficultyCode; // Obtiene el código de dificultad a partir del nombre
|
auto getDifficultyCodeFromName(const std::string &name) -> DifficultyCode; // Obtiene el código de dificultad a partir del nombre
|
||||||
auto getDifficultyNameFromCode(DifficultyCode code) -> std::string; // Obtiene el nombre de la dificultad a partir del código
|
auto getDifficultyNameFromCode(DifficultyCode code) -> std::string; // Obtiene el nombre de la dificultad a partir del código
|
||||||
} // namespace Options
|
} // namespace Options
|
||||||
385
source/param.cpp
385
source/param.cpp
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_LogCategory, SDL_LogError, SDL_LogInfo
|
#include <SDL3/SDL.h> // Para SDL_LogCategory, SDL_LogError, SDL_LogInfo
|
||||||
|
|
||||||
#include <fstream> // Para basic_istream, basic_ifstream, ifstream
|
#include <fstream> // Para basic_istream, basic_ifstream, ifstream
|
||||||
|
#include <functional>
|
||||||
#include <sstream> // Para basic_istringstream
|
#include <sstream> // Para basic_istringstream
|
||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <string> // Para operator==, stoi, char_traits, string, ope...
|
#include <string> // Para operator==, stoi, char_traits, string, ope...
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "utils.h" // Para Zone, Color, NotifyPosition, getFileName
|
#include "utils.h" // Para Zone, Color, NotifyPosition, getFileName
|
||||||
|
|
||||||
@@ -15,7 +17,7 @@ Param param;
|
|||||||
void precalculateZones();
|
void precalculateZones();
|
||||||
|
|
||||||
// Asigna variables a partir de dos cadenas
|
// Asigna variables a partir de dos cadenas
|
||||||
auto setParams(const std::string &var, const std::string &value) -> bool;
|
auto setParams(const std::string& var, const std::string& value) -> bool;
|
||||||
|
|
||||||
// Establece valores por defecto a las variables
|
// Establece valores por defecto a las variables
|
||||||
void initParam() {
|
void initParam() {
|
||||||
@@ -63,10 +65,10 @@ void initParam() {
|
|||||||
param.background.attenuate_color = Color(255, 255, 255, 0);
|
param.background.attenuate_color = Color(255, 255, 255, 0);
|
||||||
|
|
||||||
// BALLOONS
|
// BALLOONS
|
||||||
param.balloon.settings.at(0) = ParamBalloon::Settings(0.09f, 2.60f);
|
param.balloon.settings.at(0) = ParamBalloon::Settings(0.09F, 2.60F);
|
||||||
param.balloon.settings.at(1) = ParamBalloon::Settings(0.10f, 3.50f);
|
param.balloon.settings.at(1) = ParamBalloon::Settings(0.10F, 3.50F);
|
||||||
param.balloon.settings.at(2) = ParamBalloon::Settings(0.10f, 4.50f);
|
param.balloon.settings.at(2) = ParamBalloon::Settings(0.10F, 4.50F);
|
||||||
param.balloon.settings.at(3) = ParamBalloon::Settings(0.10f, 4.95f);
|
param.balloon.settings.at(3) = ParamBalloon::Settings(0.10F, 4.95F);
|
||||||
|
|
||||||
param.balloon.color.at(0) = "blue";
|
param.balloon.color.at(0) = "blue";
|
||||||
param.balloon.color.at(1) = "orange";
|
param.balloon.color.at(1) = "orange";
|
||||||
@@ -89,7 +91,7 @@ void initParam() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Carga los parámetros desde un archivo
|
// Carga los parámetros desde un archivo
|
||||||
void loadParamsFromFile(const std::string &file_path) {
|
void loadParamsFromFile(const std::string& file_path) {
|
||||||
// Inicializa los parámetros con valores por defecto
|
// Inicializa los parámetros con valores por defecto
|
||||||
initParam();
|
initParam();
|
||||||
|
|
||||||
@@ -102,7 +104,9 @@ void loadParamsFromFile(const std::string &file_path) {
|
|||||||
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nReading file: %s", getFileName(file_path).c_str());
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nReading file: %s", getFileName(file_path).c_str());
|
||||||
|
|
||||||
std::string line, param1, param2;
|
std::string line;
|
||||||
|
std::string param1;
|
||||||
|
std::string param2;
|
||||||
while (std::getline(file, line)) {
|
while (std::getline(file, line)) {
|
||||||
// Elimina comentarios
|
// Elimina comentarios
|
||||||
auto comment_pos = line.find('#');
|
auto comment_pos = line.find('#');
|
||||||
@@ -126,219 +130,97 @@ void loadParamsFromFile(const std::string &file_path) {
|
|||||||
precalculateZones();
|
precalculateZones();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asigna variables a partir de dos cadenas
|
auto setParams(const std::string& var, const std::string& value) -> bool {
|
||||||
auto setParams(const std::string &var, const std::string &value) -> bool {
|
static const std::unordered_map<std::string, std::function<void(const std::string&)>> intParams = {
|
||||||
// Indicador de éxito en la asignación
|
{"game.width", [](const std::string& v) { param.game.width = std::stoi(v); }},
|
||||||
auto success = true;
|
{"game.height", [](const std::string& v) { param.game.height = std::stoi(v); }},
|
||||||
|
{"game.item_size", [](const std::string& v) { param.game.item_size = std::stoi(v); }},
|
||||||
|
{"game.play_area.rect.x", [](const std::string& v) { param.game.play_area.rect.x = std::stoi(v); }},
|
||||||
|
{"game.play_area.rect.y", [](const std::string& v) { param.game.play_area.rect.y = std::stoi(v); }},
|
||||||
|
{"game.play_area.rect.w", [](const std::string& v) { param.game.play_area.rect.w = std::stoi(v); }},
|
||||||
|
{"game.play_area.rect.h", [](const std::string& v) { param.game.play_area.rect.h = std::stoi(v); }},
|
||||||
|
{"game.name_entry_idle_time", [](const std::string& v) { param.game.name_entry_idle_time = std::stoi(v); }},
|
||||||
|
{"game.name_entry_total_time", [](const std::string& v) { param.game.name_entry_total_time = std::stoi(v); }},
|
||||||
|
{"game.hit_stop_ms", [](const std::string& v) { param.game.hit_stop_ms = std::stoi(v); }},
|
||||||
|
{"fade.num_squares_width", [](const std::string& v) { param.fade.num_squares_width = std::stoi(v); }},
|
||||||
|
{"fade.num_squares_height", [](const std::string& v) { param.fade.num_squares_height = std::stoi(v); }},
|
||||||
|
{"fade.random_squares_delay", [](const std::string& v) { param.fade.random_squares_delay = std::stoi(v); }},
|
||||||
|
{"fade.random_squares_mult", [](const std::string& v) { param.fade.random_squares_mult = std::stoi(v); }},
|
||||||
|
{"fade.post_duration", [](const std::string& v) { param.fade.post_duration = std::stoi(v); }},
|
||||||
|
{"fade.venetian_size", [](const std::string& v) { param.fade.venetian_size = std::stoi(v); }},
|
||||||
|
{"scoreboard.rect.x", [](const std::string& v) { param.scoreboard.rect.x = std::stoi(v); }},
|
||||||
|
{"scoreboard.rect.y", [](const std::string& v) { param.scoreboard.rect.y = std::stoi(v); }},
|
||||||
|
{"scoreboard.rect.w", [](const std::string& v) { param.scoreboard.rect.w = std::stoi(v); }},
|
||||||
|
{"scoreboard.rect.h", [](const std::string& v) { param.scoreboard.rect.h = std::stoi(v); }},
|
||||||
|
{"scoreboard.skip_countdown_value", [](const std::string& v) { param.scoreboard.skip_countdown_value = std::stoi(v); }},
|
||||||
|
{"title.press_start_position", [](const std::string& v) { param.title.press_start_position = std::stoi(v); }},
|
||||||
|
{"title.title_duration", [](const std::string& v) { param.title.title_duration = std::stoi(v); }},
|
||||||
|
{"title.arcade_edition_position", [](const std::string& v) { param.title.arcade_edition_position = std::stoi(v); }},
|
||||||
|
{"title.title_c_c_position", [](const std::string& v) { param.title.title_c_c_position = std::stoi(v); }},
|
||||||
|
{"intro.text_distance_from_bottom", [](const std::string& v) { param.intro.text_distance_from_bottom = std::stoi(v); }}};
|
||||||
|
|
||||||
// GAME
|
static const std::unordered_map<std::string, std::function<void(const std::string&)>> colorParams = {
|
||||||
if (var == "game.width") {
|
{"fade.color", [](const std::string& v) { param.fade.color = Color::fromHex(v); }},
|
||||||
param.game.width = std::stoi(value);
|
{"scoreboard.separator_color", [](const std::string& v) { param.scoreboard.separator_color = Color::fromHex(v); }},
|
||||||
|
{"scoreboard.easy_color", [](const std::string& v) { param.scoreboard.easy_color = Color::fromHex(v); }},
|
||||||
|
{"scoreboard.normal_color", [](const std::string& v) { param.scoreboard.normal_color = Color::fromHex(v); }},
|
||||||
|
{"scoreboard.hard_color", [](const std::string& v) { param.scoreboard.hard_color = Color::fromHex(v); }},
|
||||||
|
{"scoreboard.text_color1", [](const std::string& v) { param.scoreboard.text_color1 = Color::fromHex(v); }},
|
||||||
|
{"scoreboard.text_color2", [](const std::string& v) { param.scoreboard.text_color2 = Color::fromHex(v); }},
|
||||||
|
{"title.bg_color", [](const std::string& v) { param.title.bg_color = Color::fromHex(v); }},
|
||||||
|
{"background.attenuate_color", [](const std::string& v) { param.background.attenuate_color = Color::fromHex(v); }},
|
||||||
|
{"notification.color", [](const std::string& v) { param.notification.color = Color::fromHex(v); }},
|
||||||
|
{"service_menu.title_color", [](const std::string& v) { param.service_menu.title_color = Color::fromHex(v); }},
|
||||||
|
{"service_menu.text_color", [](const std::string& v) { param.service_menu.text_color = Color::fromHex(v); }},
|
||||||
|
{"service_menu.selected_color", [](const std::string& v) { param.service_menu.selected_color = Color::fromHex(v); }},
|
||||||
|
{"service_menu.bg_color", [](const std::string& v) { param.service_menu.bg_color = Color::fromHex(v); }},
|
||||||
|
{"intro.bg_color", [](const std::string& v) { param.intro.bg_color = Color::fromHex(v); }},
|
||||||
|
{"intro.card_color", [](const std::string& v) { param.intro.card_color = Color::fromHex(v); }},
|
||||||
|
{"intro.shadow_color", [](const std::string& v) { param.intro.shadow_color = Color::fromHex(v); }},
|
||||||
|
{"debug.color", [](const std::string& v) { param.debug.color = Color::fromHex(v); }},
|
||||||
|
{"resource.color", [](const std::string& v) { param.resource.color = Color::fromHex(v); }}};
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, std::function<void(const std::string&)>> boolParams = {
|
||||||
|
{"game.hit_stop", [](const std::string& v) { param.game.hit_stop = stringToBool(v); }},
|
||||||
|
{"scoreboard.separator_autocolor", [](const std::string& v) { param.scoreboard.separator_autocolor = stringToBool(v); }},
|
||||||
|
{"scoreboard.text_autocolor", [](const std::string& v) { param.scoreboard.text_autocolor = stringToBool(v); }},
|
||||||
|
{"balloon.bouncing_sound", [](const std::string& v) { param.balloon.bouncing_sound = stringToBool(v); }},
|
||||||
|
{"notification.sound", [](const std::string& v) { param.notification.sound = stringToBool(v); }},
|
||||||
|
{"service_menu.drop_shadow", [](const std::string& v) { param.service_menu.drop_shadow = stringToBool(v); }}};
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, std::function<void(const std::string&)>> floatParams = {
|
||||||
|
{"balloon.settings[0].vel", [](const std::string& v) { param.balloon.settings.at(0).vel = std::stof(v); }},
|
||||||
|
{"balloon.settings[0].grav", [](const std::string& v) { param.balloon.settings.at(0).grav = std::stof(v); }},
|
||||||
|
{"balloon.settings[1].vel", [](const std::string& v) { param.balloon.settings.at(1).vel = std::stof(v); }},
|
||||||
|
{"balloon.settings[1].grav", [](const std::string& v) { param.balloon.settings.at(1).grav = std::stof(v); }},
|
||||||
|
{"balloon.settings[2].vel", [](const std::string& v) { param.balloon.settings.at(2).vel = std::stof(v); }},
|
||||||
|
{"balloon.settings[2].grav", [](const std::string& v) { param.balloon.settings.at(2).grav = std::stof(v); }},
|
||||||
|
{"balloon.settings[3].vel", [](const std::string& v) { param.balloon.settings.at(3).vel = std::stof(v); }},
|
||||||
|
{"balloon.settings[3].grav", [](const std::string& v) { param.balloon.settings.at(3).grav = std::stof(v); }}};
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, std::function<void(const std::string&)>> stringParams = {
|
||||||
|
{"balloon.color[0]", [](const std::string& v) { param.balloon.color.at(0) = v; }},
|
||||||
|
{"balloon.color[1]", [](const std::string& v) { param.balloon.color.at(1) = v; }},
|
||||||
|
{"balloon.color[2]", [](const std::string& v) { param.balloon.color.at(2) = v; }},
|
||||||
|
{"balloon.color[3]", [](const std::string& v) { param.balloon.color.at(3) = v; }}};
|
||||||
|
|
||||||
|
// Intentar cada mapa de parámetros
|
||||||
|
auto tryMap = [&](const auto& paramMap) -> bool {
|
||||||
|
auto it = paramMap.find(var);
|
||||||
|
if (it != paramMap.end()) {
|
||||||
|
it->second(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (tryMap(intParams) || tryMap(colorParams) || tryMap(boolParams) ||
|
||||||
|
tryMap(floatParams) || tryMap(stringParams)) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (var == "game.height") {
|
// Casos especiales que necesitan lógica personalizada
|
||||||
param.game.height = std::stoi(value);
|
if (var == "notification.pos_h") {
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "game.item_size") {
|
|
||||||
param.game.item_size = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "game.play_area.rect.x") {
|
|
||||||
param.game.play_area.rect.x = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "game.play_area.rect.y") {
|
|
||||||
param.game.play_area.rect.y = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "game.play_area.rect.w") {
|
|
||||||
param.game.play_area.rect.w = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "game.play_area.rect.h") {
|
|
||||||
param.game.play_area.rect.h = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "game.name_entry_idle_time") {
|
|
||||||
param.game.name_entry_idle_time = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "game.name_entry_total_time") {
|
|
||||||
param.game.name_entry_total_time = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "game.hit_stop") {
|
|
||||||
param.game.hit_stop = stringToBool(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "game.hit_stop_ms") {
|
|
||||||
param.game.hit_stop_ms = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FADE
|
|
||||||
else if (var == "fade.color") {
|
|
||||||
param.fade.color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "fade.num_squares_width") {
|
|
||||||
param.fade.num_squares_width = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "fade.num_squares_height") {
|
|
||||||
param.fade.num_squares_height = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "fade.random_squares_delay") {
|
|
||||||
param.fade.random_squares_delay = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "fade.random_squares_mult") {
|
|
||||||
param.fade.random_squares_mult = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "fade.post_duration") {
|
|
||||||
param.fade.post_duration = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "fade.venetian_size") {
|
|
||||||
param.fade.venetian_size = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SCOREBOARD
|
|
||||||
else if (var == "scoreboard.rect.x") {
|
|
||||||
param.scoreboard.rect.x = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.rect.y") {
|
|
||||||
param.scoreboard.rect.y = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.rect.w") {
|
|
||||||
param.scoreboard.rect.w = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.rect.h") {
|
|
||||||
param.scoreboard.rect.h = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.separator_autocolor") {
|
|
||||||
param.scoreboard.separator_autocolor = stringToBool(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.separator_color") {
|
|
||||||
param.scoreboard.separator_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.easy_color") {
|
|
||||||
param.scoreboard.easy_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.normal_color") {
|
|
||||||
param.scoreboard.normal_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.hard_color") {
|
|
||||||
param.scoreboard.hard_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.text_autocolor") {
|
|
||||||
param.scoreboard.text_autocolor = stringToBool(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.text_color1") {
|
|
||||||
param.scoreboard.text_color1 = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.text_color2") {
|
|
||||||
param.scoreboard.text_color2 = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "scoreboard.skip_countdown_value") {
|
|
||||||
param.scoreboard.skip_countdown_value = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TITLE
|
|
||||||
else if (var == "title.press_start_position") {
|
|
||||||
param.title.press_start_position = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "title.title_duration") {
|
|
||||||
param.title.title_duration = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "title.arcade_edition_position") {
|
|
||||||
param.title.arcade_edition_position = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "title.title_c_c_position") {
|
|
||||||
param.title.title_c_c_position = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "title.bg_color") {
|
|
||||||
param.title.bg_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// BACKGROUND
|
|
||||||
else if (var == "background.attenuate_color") {
|
|
||||||
param.background.attenuate_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// BALLOON
|
|
||||||
else if (var == "balloon.settings[0].vel") {
|
|
||||||
param.balloon.settings.at(0).vel = std::stof(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.settings[0].grav") {
|
|
||||||
param.balloon.settings.at(0).grav = std::stof(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.settings[1].vel") {
|
|
||||||
param.balloon.settings.at(1).vel = std::stof(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.settings[1].grav") {
|
|
||||||
param.balloon.settings.at(1).grav = std::stof(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.settings[2].vel") {
|
|
||||||
param.balloon.settings.at(2).vel = std::stof(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.settings[2].grav") {
|
|
||||||
param.balloon.settings.at(2).grav = std::stof(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.settings[3].vel") {
|
|
||||||
param.balloon.settings.at(3).vel = std::stof(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.settings[3].grav") {
|
|
||||||
param.balloon.settings.at(3).grav = std::stof(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.color[0]") {
|
|
||||||
param.balloon.color.at(0) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.color[1]") {
|
|
||||||
param.balloon.color.at(1) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.color[2]") {
|
|
||||||
param.balloon.color.at(2) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.color[3]") {
|
|
||||||
param.balloon.color.at(3) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "balloon.bouncing_sound") {
|
|
||||||
param.balloon.bouncing_sound = stringToBool(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTIFICACIONES
|
|
||||||
else if (var == "notification.pos_h") {
|
|
||||||
if (value == "LEFT") {
|
if (value == "LEFT") {
|
||||||
param.notification.pos_h = NotifyPosition::LEFT;
|
param.notification.pos_h = NotifyPosition::LEFT;
|
||||||
} else if (value == "MIDDLE") {
|
} else if (value == "MIDDLE") {
|
||||||
@@ -346,74 +228,15 @@ auto setParams(const std::string &var, const std::string &value) -> bool {
|
|||||||
} else {
|
} else {
|
||||||
param.notification.pos_h = NotifyPosition::RIGHT;
|
param.notification.pos_h = NotifyPosition::RIGHT;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (var == "notification.pos_v") {
|
if (var == "notification.pos_v") {
|
||||||
param.notification.pos_v = value == "TOP" ? NotifyPosition::TOP : NotifyPosition::BOTTOM;
|
param.notification.pos_v = value == "TOP" ? NotifyPosition::TOP : NotifyPosition::BOTTOM;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (var == "notification.sound") {
|
return false; // Parámetro no encontrado
|
||||||
param.notification.sound = stringToBool(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "notification.color") {
|
|
||||||
param.notification.color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SERVICE MENU
|
|
||||||
else if (var == "service_menu.title_color") {
|
|
||||||
param.service_menu.title_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "service_menu.text_color") {
|
|
||||||
param.service_menu.text_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "service_menu.selected_color") {
|
|
||||||
param.service_menu.selected_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "service_menu.bg_color") {
|
|
||||||
param.service_menu.bg_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "service_menu.drop_shadow") {
|
|
||||||
param.service_menu.drop_shadow = stringToBool(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// INTRO
|
|
||||||
else if (var == "intro.bg_color") {
|
|
||||||
param.intro.bg_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "intro.card_color") {
|
|
||||||
param.intro.card_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "intro.shadow_color") {
|
|
||||||
param.intro.shadow_color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (var == "intro.text_distance_from_bottom") {
|
|
||||||
param.intro.text_distance_from_bottom = std::stoi(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
else if (var == "debug.color") {
|
|
||||||
param.debug.color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// RESOURCE
|
|
||||||
else if (var == "resource.color") {
|
|
||||||
param.resource.color = Color::fromHex(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// RESTO
|
|
||||||
else {
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcula variables a partir de otras variables
|
// Calcula variables a partir de otras variables
|
||||||
|
|||||||
@@ -51,21 +51,24 @@ void PathSprite::render() {
|
|||||||
// Añade un recorrido
|
// Añade un recorrido
|
||||||
void PathSprite::addPath(Path path, bool centered) {
|
void PathSprite::addPath(Path path, bool centered) {
|
||||||
PathCentered path_centered = PathCentered::NONE;
|
PathCentered path_centered = PathCentered::NONE;
|
||||||
if (centered)
|
if (centered) {
|
||||||
path_centered = (path.spots.back().x == path.spots.front().x) ? PathCentered::ON_X : PathCentered::ON_Y;
|
path_centered = (path.spots.back().x == path.spots.front().x) ? PathCentered::ON_X : PathCentered::ON_Y;
|
||||||
|
}
|
||||||
|
|
||||||
switch (path_centered) {
|
switch (path_centered) {
|
||||||
case PathCentered::ON_X: {
|
case PathCentered::ON_X: {
|
||||||
const int X = path.spots.back().x - pos_.w / 2;
|
const int X = path.spots.back().x - pos_.w / 2;
|
||||||
for (auto &spot : path.spots)
|
for (auto &spot : path.spots) {
|
||||||
spot.x = X;
|
spot.x = X;
|
||||||
|
}
|
||||||
paths_.emplace_back(path);
|
paths_.emplace_back(path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PathCentered::ON_Y: {
|
case PathCentered::ON_Y: {
|
||||||
const int Y = path.spots.back().y - pos_.h / 2;
|
const int Y = path.spots.back().y - pos_.h / 2;
|
||||||
for (auto &spot : path.spots)
|
for (auto &spot : path.spots) {
|
||||||
spot.y = Y;
|
spot.y = Y;
|
||||||
|
}
|
||||||
paths_.emplace_back(path);
|
paths_.emplace_back(path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -87,7 +90,7 @@ void PathSprite::addPath(std::vector<SDL_FPoint> spots, int waiting_counter) {
|
|||||||
|
|
||||||
// Habilita el objeto
|
// Habilita el objeto
|
||||||
void PathSprite::enable() {
|
void PathSprite::enable() {
|
||||||
if (paths_.size() == 0 || enabled_) {
|
if (paths_.empty() || enabled_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,4 +144,4 @@ void PathSprite::goToNextPathOrDie() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Indica si ha terminado todos los recorridos
|
// Indica si ha terminado todos los recorridos
|
||||||
auto PathSprite::hasFinished() -> bool { return has_finished_; }
|
auto PathSprite::hasFinished() const -> bool { return has_finished_; }
|
||||||
@@ -58,7 +58,7 @@ class PathSprite : public Sprite {
|
|||||||
|
|
||||||
// --- Estado y control ---
|
// --- Estado y control ---
|
||||||
void enable(); // Habilita el objeto
|
void enable(); // Habilita el objeto
|
||||||
auto hasFinished() -> bool; // Indica si ha terminado todos los recorridos
|
[[nodiscard]] auto hasFinished() const -> bool; // Indica si ha terminado todos los recorridos
|
||||||
|
|
||||||
// --- Getters ---
|
// --- Getters ---
|
||||||
[[nodiscard]] auto getCurrentPath() const -> int { return current_path_; } // Devuelve el índice del recorrido actual
|
[[nodiscard]] auto getCurrentPath() const -> int { return current_path_; } // Devuelve el índice del recorrido actual
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ void Player::init() {
|
|||||||
vel_x_ = 0;
|
vel_x_ = 0;
|
||||||
vel_y_ = 0;
|
vel_y_ = 0;
|
||||||
score_ = 0;
|
score_ = 0;
|
||||||
score_multiplier_ = 1.0f;
|
score_multiplier_ = 1.0F;
|
||||||
cant_fire_counter_ = 10;
|
cant_fire_counter_ = 10;
|
||||||
enter_name_->init(last_enter_name_);
|
enter_name_->init(last_enter_name_);
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ void Player::move() {
|
|||||||
|
|
||||||
// Si el jugador toca el suelo rebota y si tiene poca velocidad, se detiene y cambia de estado
|
// Si el jugador toca el suelo rebota y si tiene poca velocidad, se detiene y cambia de estado
|
||||||
if (player_sprite_->getPosY() > play_area_.h - HEIGHT) {
|
if (player_sprite_->getPosY() > play_area_.h - HEIGHT) {
|
||||||
if (player_sprite_->getVelY() < 2.0f) {
|
if (player_sprite_->getVelY() < 2.0F) {
|
||||||
// Si la velocidad de rebote es baja, lo detiene y cambia de estado
|
// Si la velocidad de rebote es baja, lo detiene y cambia de estado
|
||||||
const auto NEXT_PLAYER_STATUS = isEligibleForHighScore() ? PlayerState::ENTERING_NAME : PlayerState::CONTINUE;
|
const auto NEXT_PLAYER_STATUS = isEligibleForHighScore() ? PlayerState::ENTERING_NAME : PlayerState::CONTINUE;
|
||||||
demo_ ? setPlayingState(PlayerState::LYING_ON_THE_FLOOR_FOREVER) : setPlayingState(NEXT_PLAYER_STATUS);
|
demo_ ? setPlayingState(PlayerState::LYING_ON_THE_FLOOR_FOREVER) : setPlayingState(NEXT_PLAYER_STATUS);
|
||||||
@@ -184,8 +184,8 @@ void Player::move() {
|
|||||||
} else {
|
} else {
|
||||||
// Decrementa las velocidades de rebote
|
// Decrementa las velocidades de rebote
|
||||||
player_sprite_->setPosY(play_area_.h - HEIGHT);
|
player_sprite_->setPosY(play_area_.h - HEIGHT);
|
||||||
player_sprite_->setVelY(player_sprite_->getVelY() * -0.5f);
|
player_sprite_->setVelY(player_sprite_->getVelY() * -0.5F);
|
||||||
player_sprite_->setVelX(player_sprite_->getVelX() * 0.75f);
|
player_sprite_->setVelX(player_sprite_->getVelX() * 0.75F);
|
||||||
player_sprite_->setAnimationSpeed(player_sprite_->getAnimationSpeed() * 2);
|
player_sprite_->setAnimationSpeed(player_sprite_->getAnimationSpeed() * 2);
|
||||||
playSound("jump.wav");
|
playSound("jump.wav");
|
||||||
}
|
}
|
||||||
@@ -218,7 +218,7 @@ void Player::move() {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pos_x_ += vel_x_ * 2.0f;
|
pos_x_ += vel_x_ * 2.0F;
|
||||||
const float MIN_X = -WIDTH;
|
const float MIN_X = -WIDTH;
|
||||||
const float MAX_X = play_area_.w;
|
const float MAX_X = play_area_.w;
|
||||||
pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X);
|
pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X);
|
||||||
@@ -295,7 +295,7 @@ void Player::move() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PlayerState::CREDITS: {
|
case PlayerState::CREDITS: {
|
||||||
pos_x_ += vel_x_ / 2.0f;
|
pos_x_ += vel_x_ / 2.0F;
|
||||||
if (vel_x_ > 0) {
|
if (vel_x_ > 0) {
|
||||||
// setInputPlaying(InputAction::RIGHT);
|
// setInputPlaying(InputAction::RIGHT);
|
||||||
if (pos_x_ > param.game.game_area.rect.w - WIDTH) {
|
if (pos_x_ > param.game.game_area.rect.w - WIDTH) {
|
||||||
@@ -503,7 +503,7 @@ void Player::updateScoreboard() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cambia el modo del marcador
|
// Cambia el modo del marcador
|
||||||
void Player::setScoreboardMode(ScoreboardMode mode) {
|
void Player::setScoreboardMode(ScoreboardMode mode) const {
|
||||||
if (!demo_) {
|
if (!demo_) {
|
||||||
Scoreboard::get()->setMode(getScoreBoardPanel(), mode);
|
Scoreboard::get()->setMode(getScoreBoardPanel(), mode);
|
||||||
}
|
}
|
||||||
@@ -555,9 +555,9 @@ void Player::setPlayingState(PlayerState state) {
|
|||||||
// Activa la animación de rodar
|
// Activa la animación de rodar
|
||||||
player_sprite_->setCurrentAnimation("rolling");
|
player_sprite_->setCurrentAnimation("rolling");
|
||||||
player_sprite_->setAnimationSpeed(4);
|
player_sprite_->setAnimationSpeed(4);
|
||||||
player_sprite_->setAccelY(0.2f);
|
player_sprite_->setAccelY(0.2F);
|
||||||
player_sprite_->setVelY(-6.6f);
|
player_sprite_->setVelY(-6.6F);
|
||||||
(rand() % 2 == 0) ? player_sprite_->setVelX(3.3f) : player_sprite_->setVelX(-3.3f);
|
(rand() % 2 == 0) ? player_sprite_->setVelX(3.3F) : player_sprite_->setVelX(-3.3F);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PlayerState::TITLE_ANIMATION: {
|
case PlayerState::TITLE_ANIMATION: {
|
||||||
@@ -567,15 +567,15 @@ void Player::setPlayingState(PlayerState state) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PlayerState::TITLE_HIDDEN: {
|
case PlayerState::TITLE_HIDDEN: {
|
||||||
player_sprite_->setVelX(0.0f);
|
player_sprite_->setVelX(0.0F);
|
||||||
player_sprite_->setVelY(0.0f);
|
player_sprite_->setVelY(0.0F);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PlayerState::CONTINUE_TIME_OUT: {
|
case PlayerState::CONTINUE_TIME_OUT: {
|
||||||
// Activa la animación de morir
|
// Activa la animación de morir
|
||||||
player_sprite_->setAccelY(0.2f);
|
player_sprite_->setAccelY(0.2F);
|
||||||
player_sprite_->setVelY(-4.0f);
|
player_sprite_->setVelY(-4.0F);
|
||||||
player_sprite_->setVelX(0.0f);
|
player_sprite_->setVelX(0.0F);
|
||||||
player_sprite_->setCurrentAnimation("rolling");
|
player_sprite_->setCurrentAnimation("rolling");
|
||||||
player_sprite_->setAnimationSpeed(5);
|
player_sprite_->setAnimationSpeed(5);
|
||||||
setScoreboardMode(ScoreboardMode::GAME_OVER);
|
setScoreboardMode(ScoreboardMode::GAME_OVER);
|
||||||
@@ -631,14 +631,14 @@ void Player::setPlayingState(PlayerState state) {
|
|||||||
|
|
||||||
// Aumenta el valor de la variable hasta un máximo
|
// Aumenta el valor de la variable hasta un máximo
|
||||||
void Player::incScoreMultiplier() {
|
void Player::incScoreMultiplier() {
|
||||||
score_multiplier_ += 0.1f;
|
score_multiplier_ += 0.1F;
|
||||||
score_multiplier_ = std::min(score_multiplier_, 5.0f);
|
score_multiplier_ = std::min(score_multiplier_, 5.0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrementa el valor de la variable hasta un mínimo
|
// Decrementa el valor de la variable hasta un mínimo
|
||||||
void Player::decScoreMultiplier() {
|
void Player::decScoreMultiplier() {
|
||||||
score_multiplier_ -= 0.1f;
|
score_multiplier_ -= 0.1F;
|
||||||
score_multiplier_ = std::max(score_multiplier_, 1.0f);
|
score_multiplier_ = std::max(score_multiplier_, 1.0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece el valor del estado
|
// Establece el valor del estado
|
||||||
@@ -649,7 +649,7 @@ void Player::setInvulnerable(bool value) {
|
|||||||
|
|
||||||
// Monitoriza el estado
|
// Monitoriza el estado
|
||||||
void Player::updateInvulnerable() {
|
void Player::updateInvulnerable() {
|
||||||
if (playing_state_ == PlayerState::PLAYING)
|
if (playing_state_ == PlayerState::PLAYING) {
|
||||||
if (invulnerable_) {
|
if (invulnerable_) {
|
||||||
if (invulnerable_counter_ > 0) {
|
if (invulnerable_counter_ > 0) {
|
||||||
--invulnerable_counter_;
|
--invulnerable_counter_;
|
||||||
@@ -659,6 +659,7 @@ void Player::updateInvulnerable() {
|
|||||||
player_sprite_->getTexture()->setPalette(coffees_);
|
player_sprite_->getTexture()->setPalette(coffees_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece el valor de la variable
|
// Establece el valor de la variable
|
||||||
@@ -669,11 +670,12 @@ void Player::setPowerUp() {
|
|||||||
|
|
||||||
// Actualiza el valor de la variable
|
// Actualiza el valor de la variable
|
||||||
void Player::updatePowerUp() {
|
void Player::updatePowerUp() {
|
||||||
if (playing_state_ == PlayerState::PLAYING)
|
if (playing_state_ == PlayerState::PLAYING) {
|
||||||
if (power_up_) {
|
if (power_up_) {
|
||||||
--power_up_counter_;
|
--power_up_counter_;
|
||||||
power_up_ = power_up_counter_ > 0;
|
power_up_ = power_up_counter_ > 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concede un toque extra al jugador
|
// Concede un toque extra al jugador
|
||||||
@@ -693,13 +695,13 @@ void Player::removeExtraHit() {
|
|||||||
player_sprite_->getTexture()->setPalette(coffees_);
|
player_sprite_->getTexture()->setPalette(coffees_);
|
||||||
}
|
}
|
||||||
|
|
||||||
extra_hit_ = coffees_ == 0 ? false : true;
|
extra_hit_ = coffees_ != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el circulo de colisión a la posición del jugador
|
// Actualiza el circulo de colisión a la posición del jugador
|
||||||
void Player::shiftColliders() {
|
void Player::shiftColliders() {
|
||||||
collider_.x = static_cast<int>(pos_x_ + (WIDTH / 2));
|
collider_.x = static_cast<int>(pos_x_ + (WIDTH / 2));
|
||||||
collider_.y = static_cast<int>(pos_y_ + (HEIGHT / 2));
|
collider_.y = (pos_y_ + (HEIGHT / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pone las texturas del jugador
|
// Pone las texturas del jugador
|
||||||
@@ -787,16 +789,23 @@ void Player::shiftSprite() {
|
|||||||
power_sprite_->setPosX(getPosX() - power_up_desp_x_);
|
power_sprite_->setPosX(getPosX() - power_up_desp_x_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::playSound(const std::string &name) {
|
// Hace sonar un sonido
|
||||||
if (demo_)
|
void Player::playSound(const std::string &name) const {
|
||||||
|
if (demo_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static auto audio_ = Audio::get();
|
static auto *audio_ = Audio::get();
|
||||||
audio_->playSound(name);
|
audio_->playSound(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Indica si se puede dibujar el objeto
|
||||||
|
auto Player::isRenderable() const -> bool {
|
||||||
|
return !isWaiting() && !isGameOver() && !isTitleHidden();
|
||||||
|
};
|
||||||
|
|
||||||
// Añade una puntuación a la tabla de records
|
// Añade una puntuación a la tabla de records
|
||||||
void Player::addScoreToScoreBoard() {
|
void Player::addScoreToScoreBoard() const {
|
||||||
const auto ENTRY = HiScoreEntry(trim(getLastEnterName()), getScore(), get1CC());
|
const auto ENTRY = HiScoreEntry(trim(getLastEnterName()), getScore(), get1CC());
|
||||||
auto manager = std::make_unique<ManageHiScoreTable>(Options::settings.hi_score_table);
|
auto manager = std::make_unique<ManageHiScoreTable>(Options::settings.hi_score_table);
|
||||||
Options::settings.last_hi_score_entry.at(getId() - 1) = manager->add(ENTRY);
|
Options::settings.last_hi_score_entry.at(getId() - 1) = manager->add(ENTRY);
|
||||||
|
|||||||
304
source/player.h
304
source/player.h
@@ -61,171 +61,171 @@ enum class PlayerState {
|
|||||||
|
|
||||||
// --- Clase Player ---
|
// --- Clase Player ---
|
||||||
class Player {
|
class Player {
|
||||||
public:
|
public:
|
||||||
// --- Constructor y destructor ---
|
// --- Constructor y destructor ---
|
||||||
Player(int id, float x, int y, bool demo, SDL_FRect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations);
|
Player(int id, float x, int y, bool demo, SDL_FRect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations);
|
||||||
~Player() = default;
|
~Player() = default;
|
||||||
|
|
||||||
// --- Inicialización y ciclo de vida ---
|
// --- Inicialización y ciclo de vida ---
|
||||||
void init(); // Inicializa el jugador
|
void init(); // Inicializa el jugador
|
||||||
void update(); // Actualiza estado, animación y contadores
|
void update(); // Actualiza estado, animación y contadores
|
||||||
void render(); // Dibuja el jugador en pantalla
|
void render(); // Dibuja el jugador en pantalla
|
||||||
|
|
||||||
// --- Entrada y control ---
|
// --- Entrada y control ---
|
||||||
void setInput(InputAction input); // Procesa entrada general
|
void setInput(InputAction input); // Procesa entrada general
|
||||||
void setInputPlaying(InputAction input); // Procesa entrada en modo jugando
|
void setInputPlaying(InputAction input); // Procesa entrada en modo jugando
|
||||||
void setInputEnteringName(InputAction input); // Procesa entrada al introducir nombre
|
void setInputEnteringName(InputAction input); // Procesa entrada al introducir nombre
|
||||||
|
|
||||||
// --- Movimiento y animación ---
|
// --- Movimiento y animación ---
|
||||||
void move(); // Mueve el jugador
|
void move(); // Mueve el jugador
|
||||||
void setAnimation(); // Establece la animación según el estado
|
void setAnimation(); // Establece la animación según el estado
|
||||||
|
|
||||||
// --- Texturas y animaciones ---
|
// --- Texturas y animaciones ---
|
||||||
void setPlayerTextures(const std::vector<std::shared_ptr<Texture>> &texture); // Cambia las texturas del jugador
|
void setPlayerTextures(const std::vector<std::shared_ptr<Texture>> &texture); // Cambia las texturas del jugador
|
||||||
|
|
||||||
// --- Estados y contadores ---
|
// --- Estados y contadores ---
|
||||||
void updateCooldown(); // Actualiza el cooldown de disparo
|
void updateCooldown(); // Actualiza el cooldown de disparo
|
||||||
|
|
||||||
// --- Puntuación y marcador ---
|
// --- Puntuación y marcador ---
|
||||||
void addScore(int score); // Añade puntos
|
void addScore(int score); // Añade puntos
|
||||||
void incScoreMultiplier(); // Incrementa el multiplicador
|
void incScoreMultiplier(); // Incrementa el multiplicador
|
||||||
void decScoreMultiplier(); // Decrementa el multiplicador
|
void decScoreMultiplier(); // Decrementa el multiplicador
|
||||||
|
|
||||||
// --- Estados de juego ---
|
// --- Estados de juego ---
|
||||||
void setPlayingState(PlayerState state); // Cambia el estado de juego
|
void setPlayingState(PlayerState state); // Cambia el estado de juego
|
||||||
void setInvulnerable(bool value); // Establece el valor del estado de invulnerabilidad
|
void setInvulnerable(bool value); // Establece el valor del estado de invulnerabilidad
|
||||||
void setPowerUp(); // Activa el modo PowerUp
|
void setPowerUp(); // Activa el modo PowerUp
|
||||||
void updatePowerUp(); // Actualiza el valor de PowerUp
|
void updatePowerUp(); // Actualiza el valor de PowerUp
|
||||||
void giveExtraHit(); // Concede un toque extra al jugador
|
void giveExtraHit(); // Concede un toque extra al jugador
|
||||||
void removeExtraHit(); // Quita el toque extra al jugador
|
void removeExtraHit(); // Quita el toque extra al jugador
|
||||||
void decContinueCounter(); // Decrementa el contador de continuar
|
void decContinueCounter(); // Decrementa el contador de continuar
|
||||||
|
|
||||||
// --- Getters y comprobaciones de estado ---
|
// --- Getters y comprobaciones de estado ---
|
||||||
[[nodiscard]] auto getRecordNamePos() const -> int; // Obtiene la posición que se está editando del nombre del jugador para la tabla de mejores puntuaciones
|
[[nodiscard]] auto getRecordNamePos() const -> int; // Obtiene la posición que se está editando del nombre del jugador para la tabla de mejores puntuaciones
|
||||||
|
|
||||||
// Comprobación de playing_state
|
// Comprobación de playing_state
|
||||||
[[nodiscard]] auto isLyingOnTheFloorForever() const -> bool { return playing_state_ == PlayerState::LYING_ON_THE_FLOOR_FOREVER; }
|
[[nodiscard]] auto isLyingOnTheFloorForever() const -> bool { return playing_state_ == PlayerState::LYING_ON_THE_FLOOR_FOREVER; }
|
||||||
[[nodiscard]] auto isCelebrating() const -> bool { return playing_state_ == PlayerState::CELEBRATING; }
|
[[nodiscard]] auto isCelebrating() const -> bool { return playing_state_ == PlayerState::CELEBRATING; }
|
||||||
[[nodiscard]] auto isContinue() const -> bool { return playing_state_ == PlayerState::CONTINUE; }
|
[[nodiscard]] auto isContinue() const -> bool { return playing_state_ == PlayerState::CONTINUE; }
|
||||||
[[nodiscard]] auto isDying() const -> bool { return playing_state_ == PlayerState::ROLLING; }
|
[[nodiscard]] auto isDying() const -> bool { return playing_state_ == PlayerState::ROLLING; }
|
||||||
[[nodiscard]] auto isEnteringName() const -> bool { return playing_state_ == PlayerState::ENTERING_NAME; }
|
[[nodiscard]] auto isEnteringName() const -> bool { return playing_state_ == PlayerState::ENTERING_NAME; }
|
||||||
[[nodiscard]] auto isShowingName() const -> bool { return playing_state_ == PlayerState::SHOWING_NAME; }
|
[[nodiscard]] auto isShowingName() const -> bool { return playing_state_ == PlayerState::SHOWING_NAME; }
|
||||||
[[nodiscard]] auto isEnteringNameGameCompleted() const -> bool { return playing_state_ == PlayerState::ENTERING_NAME_GAME_COMPLETED; }
|
[[nodiscard]] auto isEnteringNameGameCompleted() const -> bool { return playing_state_ == PlayerState::ENTERING_NAME_GAME_COMPLETED; }
|
||||||
[[nodiscard]] auto isLeavingScreen() const -> bool { return playing_state_ == PlayerState::LEAVING_SCREEN; }
|
[[nodiscard]] auto isLeavingScreen() const -> bool { return playing_state_ == PlayerState::LEAVING_SCREEN; }
|
||||||
[[nodiscard]] auto isGameOver() const -> bool { return playing_state_ == PlayerState::GAME_OVER; }
|
[[nodiscard]] auto isGameOver() const -> bool { return playing_state_ == PlayerState::GAME_OVER; }
|
||||||
[[nodiscard]] auto isPlaying() const -> bool { return playing_state_ == PlayerState::PLAYING; }
|
[[nodiscard]] auto isPlaying() const -> bool { return playing_state_ == PlayerState::PLAYING; }
|
||||||
[[nodiscard]] auto isWaiting() const -> bool { return playing_state_ == PlayerState::WAITING; }
|
[[nodiscard]] auto isWaiting() const -> bool { return playing_state_ == PlayerState::WAITING; }
|
||||||
[[nodiscard]] auto isTitleHidden() const -> bool { return playing_state_ == PlayerState::TITLE_HIDDEN; }
|
[[nodiscard]] auto isTitleHidden() const -> bool { return playing_state_ == PlayerState::TITLE_HIDDEN; }
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
[[nodiscard]] auto canFire() const -> bool { return cant_fire_counter_ <= 0; }
|
[[nodiscard]] auto canFire() const -> bool { return cant_fire_counter_ <= 0; }
|
||||||
[[nodiscard]] auto hasExtraHit() const -> bool { return extra_hit_; }
|
[[nodiscard]] auto hasExtraHit() const -> bool { return extra_hit_; }
|
||||||
[[nodiscard]] auto isCooling() const -> bool { return firing_state_ == PlayerState::COOLING_LEFT || firing_state_ == PlayerState::COOLING_UP || firing_state_ == PlayerState::COOLING_RIGHT; }
|
[[nodiscard]] auto isCooling() const -> bool { return firing_state_ == PlayerState::COOLING_LEFT || firing_state_ == PlayerState::COOLING_UP || firing_state_ == PlayerState::COOLING_RIGHT; }
|
||||||
[[nodiscard]] auto isRecoiling() const -> bool { return firing_state_ == PlayerState::RECOILING_LEFT || firing_state_ == PlayerState::RECOILING_UP || firing_state_ == PlayerState::RECOILING_RIGHT; }
|
[[nodiscard]] auto isRecoiling() const -> bool { return firing_state_ == PlayerState::RECOILING_LEFT || firing_state_ == PlayerState::RECOILING_UP || firing_state_ == PlayerState::RECOILING_RIGHT; }
|
||||||
[[nodiscard]] auto isEligibleForHighScore() const -> bool { return score_ > Options::settings.hi_score_table.back().score; }
|
[[nodiscard]] auto isEligibleForHighScore() const -> bool { return score_ > Options::settings.hi_score_table.back().score; }
|
||||||
[[nodiscard]] auto isInvulnerable() const -> bool { return invulnerable_; }
|
[[nodiscard]] auto isInvulnerable() const -> bool { return invulnerable_; }
|
||||||
[[nodiscard]] auto isPowerUp() const -> bool { return power_up_; }
|
[[nodiscard]] auto isPowerUp() const -> bool { return power_up_; }
|
||||||
auto getCollider() -> Circle & { return collider_; }
|
auto getCollider() -> Circle & { return collider_; }
|
||||||
[[nodiscard]] auto getScoreMultiplier() const -> float { return score_multiplier_; }
|
[[nodiscard]] auto getScoreMultiplier() const -> float { return score_multiplier_; }
|
||||||
[[nodiscard]] auto getCoffees() const -> int { return coffees_; }
|
[[nodiscard]] auto getCoffees() const -> int { return coffees_; }
|
||||||
[[nodiscard]] auto getContinueCounter() const -> int { return continue_counter_; }
|
[[nodiscard]] auto getContinueCounter() const -> int { return continue_counter_; }
|
||||||
[[nodiscard]] auto getController() const -> int { return controller_index_; }
|
[[nodiscard]] auto getController() const -> int { return controller_index_; }
|
||||||
[[nodiscard]] auto getHeight() const -> int { return HEIGHT; }
|
[[nodiscard]] static auto getHeight() -> int { return HEIGHT; }
|
||||||
[[nodiscard]] auto getId() const -> int { return id_; }
|
[[nodiscard]] auto getId() const -> int { return id_; }
|
||||||
[[nodiscard]] auto getInvulnerableCounter() const -> int { return invulnerable_counter_; }
|
[[nodiscard]] auto getInvulnerableCounter() const -> int { return invulnerable_counter_; }
|
||||||
[[nodiscard]] auto getPosX() const -> int { return static_cast<int>(pos_x_); }
|
[[nodiscard]] auto getPosX() const -> int { return static_cast<int>(pos_x_); }
|
||||||
[[nodiscard]] auto getPosY() const -> int { return pos_y_; }
|
[[nodiscard]] auto getPosY() const -> int { return pos_y_; }
|
||||||
[[nodiscard]] auto getPowerUpCounter() const -> int { return power_up_counter_; }
|
[[nodiscard]] auto getPowerUpCounter() const -> int { return power_up_counter_; }
|
||||||
[[nodiscard]] auto getRecordName() const -> std::string { return enter_name_ ? enter_name_->getFinalName() : "xxx"; }
|
[[nodiscard]] auto getRecordName() const -> std::string { return enter_name_ ? enter_name_->getFinalName() : "xxx"; }
|
||||||
[[nodiscard]] auto getLastEnterName() const -> std::string { return last_enter_name_; }
|
[[nodiscard]] auto getLastEnterName() const -> std::string { return last_enter_name_; }
|
||||||
[[nodiscard]] auto getScore() const -> int { return score_; }
|
[[nodiscard]] auto getScore() const -> int { return score_; }
|
||||||
[[nodiscard]] auto getScoreBoardPanel() const -> int { return scoreboard_panel_; }
|
[[nodiscard]] auto getScoreBoardPanel() const -> int { return scoreboard_panel_; }
|
||||||
[[nodiscard]] auto getWidth() const -> int { return WIDTH; }
|
[[nodiscard]] static auto getWidth() -> int { return WIDTH; }
|
||||||
[[nodiscard]] auto getPlayingState() const -> PlayerState { return playing_state_; }
|
[[nodiscard]] auto getPlayingState() const -> PlayerState { return playing_state_; }
|
||||||
[[nodiscard]] auto getName() const -> const std::string & { return name_; }
|
[[nodiscard]] auto getName() const -> const std::string & { return name_; }
|
||||||
[[nodiscard]] auto get1CC() const -> bool { return game_completed_ && credits_used_ == 1; }
|
[[nodiscard]] auto get1CC() const -> bool { return game_completed_ && credits_used_ == 1; }
|
||||||
[[nodiscard]] auto getEnterNamePositionOverflow() const -> bool { return enter_name_ ? enter_name_->getPositionOverflow() : false; }
|
[[nodiscard]] auto getEnterNamePositionOverflow() const -> bool { return enter_name_ ? enter_name_->getPositionOverflow() : false; }
|
||||||
|
|
||||||
// Setters inline
|
// Setters inline
|
||||||
void setController(int index) { controller_index_ = index; }
|
void setController(int index) { controller_index_ = index; }
|
||||||
void setCantFireCounter(int counter) { recoiling_state_duration_ = cant_fire_counter_ = counter; }
|
void setCantFireCounter(int counter) { recoiling_state_duration_ = cant_fire_counter_ = counter; }
|
||||||
void setFiringState(PlayerState state) { firing_state_ = state; }
|
void setFiringState(PlayerState state) { firing_state_ = state; }
|
||||||
void setInvulnerableCounter(int value) { invulnerable_counter_ = value; }
|
void setInvulnerableCounter(int value) { invulnerable_counter_ = value; }
|
||||||
void setName(const std::string &name) { name_ = name; }
|
void setName(const std::string &name) { name_ = name; }
|
||||||
void setPowerUpCounter(int value) { power_up_counter_ = value; }
|
void setPowerUpCounter(int value) { power_up_counter_ = value; }
|
||||||
void setScore(int score) { score_ = score; }
|
void setScore(int score) { score_ = score; }
|
||||||
void setScoreBoardPanel(int panel) { scoreboard_panel_ = panel; }
|
void setScoreBoardPanel(int panel) { scoreboard_panel_ = panel; }
|
||||||
void setScoreMultiplier(float value) { score_multiplier_ = value; }
|
void setScoreMultiplier(float value) { score_multiplier_ = value; }
|
||||||
void setWalkingState(PlayerState state) { walking_state_ = state; }
|
void setWalkingState(PlayerState state) { walking_state_ = state; }
|
||||||
void addCredit() { ++credits_used_; }
|
void addCredit() { ++credits_used_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Constantes ---
|
// --- Constantes ---
|
||||||
static constexpr int POWERUP_COUNTER = 1500; // Duración del estado PowerUp
|
static constexpr int POWERUP_COUNTER = 1500; // Duración del estado PowerUp
|
||||||
static constexpr int INVULNERABLE_COUNTER = 200; // Duración del estado invulnerable
|
static constexpr int INVULNERABLE_COUNTER = 200; // Duración del estado invulnerable
|
||||||
static constexpr int WIDTH = 30; // Anchura
|
static constexpr int WIDTH = 30; // Anchura
|
||||||
static constexpr int HEIGHT = 30; // Altura
|
static constexpr int HEIGHT = 30; // Altura
|
||||||
static constexpr float BASE_SPEED = 1.5f; // Velocidad base del jugador
|
static constexpr float BASE_SPEED = 1.5F; // Velocidad base del jugador
|
||||||
static constexpr int COOLING_DURATION = 50;
|
static constexpr int COOLING_DURATION = 50;
|
||||||
static constexpr int COOLING_COMPLETE = 0;
|
static constexpr int COOLING_COMPLETE = 0;
|
||||||
|
|
||||||
// --- Objetos y punteros ---
|
// --- Objetos y punteros ---
|
||||||
std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador
|
std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador
|
||||||
std::unique_ptr<AnimatedSprite> power_sprite_; // Sprite para dibujar el aura del jugador con el poder a tope
|
std::unique_ptr<AnimatedSprite> power_sprite_; // Sprite para dibujar el aura del jugador con el poder a tope
|
||||||
std::unique_ptr<EnterName> enter_name_; // Clase utilizada para introducir el nombre
|
std::unique_ptr<EnterName> enter_name_; // Clase utilizada para introducir el nombre
|
||||||
|
|
||||||
// --- Variables de estado ---
|
// --- Variables de estado ---
|
||||||
int id_; // Número de identificación para el jugador. Player1 = 1, Player2 = 2
|
int id_; // Número de identificación para el jugador. Player1 = 1, Player2 = 2
|
||||||
SDL_FRect play_area_; // Rectángulo con la zona de juego
|
SDL_FRect play_area_; // Rectángulo con la zona de juego
|
||||||
float pos_x_ = 0.0f; // Posición en el eje X
|
float pos_x_ = 0.0F; // Posición en el eje X
|
||||||
int pos_y_ = 0; // Posición en el eje Y
|
int pos_y_ = 0; // Posición en el eje Y
|
||||||
float default_pos_x_; // Posición inicial para el jugador
|
float default_pos_x_; // Posición inicial para el jugador
|
||||||
int default_pos_y_; // Posición inicial para el jugador
|
int default_pos_y_; // Posición inicial para el jugador
|
||||||
float vel_x_ = 0.0f; // Cantidad de píxeles a desplazarse en el eje X
|
float vel_x_ = 0.0F; // Cantidad de píxeles a desplazarse en el eje X
|
||||||
int vel_y_ = 0.0f; // Cantidad de píxeles a desplazarse en el eje Y
|
int vel_y_ = 0.0F; // Cantidad de píxeles a desplazarse en el eje Y
|
||||||
int cant_fire_counter_ = 0; // Contador durante el cual no puede disparar
|
int cant_fire_counter_ = 0; // Contador durante el cual no puede disparar
|
||||||
int recoiling_state_counter_ = 0; // Contador para la animación del estado de retroceso
|
int recoiling_state_counter_ = 0; // Contador para la animación del estado de retroceso
|
||||||
int recoiling_state_duration_ = 0; // Numero de frames que dura el estado de retroceso
|
int recoiling_state_duration_ = 0; // Numero de frames que dura el estado de retroceso
|
||||||
int cooling_state_counter_ = 0; // Contador para la animación del estado cooling
|
int cooling_state_counter_ = 0; // Contador para la animación del estado cooling
|
||||||
int score_ = 0; // Puntos del jugador
|
int score_ = 0; // Puntos del jugador
|
||||||
float score_multiplier_ = 1.0f; // Multiplicador de puntos
|
float score_multiplier_ = 1.0F; // Multiplicador de puntos
|
||||||
PlayerState walking_state_ = PlayerState::WALKING_STOP; // Estado del jugador al moverse
|
PlayerState walking_state_ = PlayerState::WALKING_STOP; // Estado del jugador al moverse
|
||||||
PlayerState firing_state_ = PlayerState::FIRING_NONE; // Estado del jugador al disparar
|
PlayerState firing_state_ = PlayerState::FIRING_NONE; // Estado del jugador al disparar
|
||||||
PlayerState playing_state_ = PlayerState::WAITING; // Estado del jugador en el juego
|
PlayerState playing_state_ = PlayerState::WAITING; // Estado del jugador en el juego
|
||||||
bool invulnerable_ = true; // Indica si el jugador es invulnerable
|
bool invulnerable_ = true; // Indica si el jugador es invulnerable
|
||||||
int invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad
|
int invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad
|
||||||
bool extra_hit_ = false; // Indica si el jugador tiene un toque extra
|
bool extra_hit_ = false; // Indica si el jugador tiene un toque extra
|
||||||
int coffees_ = 0; // Indica cuántos cafés lleva acumulados
|
int coffees_ = 0; // Indica cuántos cafés lleva acumulados
|
||||||
bool power_up_ = false; // Indica si el jugador tiene activo el modo PowerUp
|
bool power_up_ = false; // Indica si el jugador tiene activo el modo PowerUp
|
||||||
int power_up_counter_ = POWERUP_COUNTER; // Temporizador para el modo PowerUp
|
int power_up_counter_ = POWERUP_COUNTER; // Temporizador para el modo PowerUp
|
||||||
int power_up_desp_x_ = 0; // Desplazamiento del sprite de PowerUp respecto al sprite del jugador
|
int power_up_desp_x_ = 0; // Desplazamiento del sprite de PowerUp respecto al sprite del jugador
|
||||||
Circle collider_ = Circle(0, 0, 9); // Círculo de colisión del jugador
|
Circle collider_ = Circle(0, 0, 9); // Círculo de colisión del jugador
|
||||||
int continue_counter_ = 10; // Contador para poder continuar
|
int continue_counter_ = 10; // Contador para poder continuar
|
||||||
Uint32 continue_ticks_ = 0; // Variable para poder cambiar el contador de continue en función del tiempo
|
Uint32 continue_ticks_ = 0; // Variable para poder cambiar el contador de continue en función del tiempo
|
||||||
int scoreboard_panel_ = 0; // Panel del marcador asociado al jugador
|
int scoreboard_panel_ = 0; // Panel del marcador asociado al jugador
|
||||||
std::string name_; // Nombre del jugador
|
std::string name_; // Nombre del jugador
|
||||||
int controller_index_ = 0; // Índice del array de mandos que utilizará para moverse
|
int controller_index_ = 0; // Índice del array de mandos que utilizará para moverse
|
||||||
bool demo_ = false; // Para que el jugador sepa si está en el modo demostración
|
bool demo_ = false; // Para que el jugador sepa si está en el modo demostración
|
||||||
int name_entry_idle_counter_ = 0; // Contador para poner nombre
|
int name_entry_idle_counter_ = 0; // Contador para poner nombre
|
||||||
int name_entry_total_counter_ = 0; // Segundos totales que lleva acumulados poniendo nombre
|
int name_entry_total_counter_ = 0; // Segundos totales que lleva acumulados poniendo nombre
|
||||||
Uint32 name_entry_ticks_ = 0; // Variable para poder cambiar el contador de poner nombre en función del tiempo
|
Uint32 name_entry_ticks_ = 0; // Variable para poder cambiar el contador de poner nombre en función del tiempo
|
||||||
Uint32 showing_name_ticks_ = 0; // Tiempo en el que se entra al estado SHOWING_NAME
|
Uint32 showing_name_ticks_ = 0; // Tiempo en el que se entra al estado SHOWING_NAME
|
||||||
int step_counter_ = 0; // Cuenta los pasos para los estados en los que camina automáticamente
|
int step_counter_ = 0; // Cuenta los pasos para los estados en los que camina automáticamente
|
||||||
bool game_completed_ = false; // Indica si ha completado el juego
|
bool game_completed_ = false; // Indica si ha completado el juego
|
||||||
int credits_used_ = 1; // Indica el número de veces que ha continuado
|
int credits_used_ = 1; // Indica el número de veces que ha continuado
|
||||||
std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones
|
std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void shiftColliders(); // Actualiza el círculo de colisión a la posición del jugador
|
void shiftColliders(); // Actualiza el círculo de colisión a la posición del jugador
|
||||||
void shiftSprite(); // Recoloca el sprite
|
void shiftSprite(); // Recoloca el sprite
|
||||||
void updateInvulnerable(); // Monitoriza el estado de invulnerabilidad
|
void updateInvulnerable(); // Monitoriza el estado de invulnerabilidad
|
||||||
void updateContinueCounter(); // Actualiza el contador de continue
|
void updateContinueCounter(); // Actualiza el contador de continue
|
||||||
void updateEnterNameCounter(); // Actualiza el contador de entrar nombre
|
void updateEnterNameCounter(); // Actualiza el contador de entrar nombre
|
||||||
void updateShowingName(); // Actualiza el estado SHOWING_NAME
|
void updateShowingName(); // Actualiza el estado SHOWING_NAME
|
||||||
void decNameEntryCounter(); // Decrementa el contador de entrar nombre
|
void decNameEntryCounter(); // Decrementa el contador de entrar nombre
|
||||||
void updateScoreboard(); // Actualiza el panel del marcador
|
void updateScoreboard(); // Actualiza el panel del marcador
|
||||||
void setScoreboardMode(ScoreboardMode mode); // Cambia el modo del marcador
|
void setScoreboardMode(ScoreboardMode mode) const; // Cambia el modo del marcador
|
||||||
void playSound(const std::string &name); // Hace sonar un sonido
|
void playSound(const std::string &name) const; // Hace sonar un sonido
|
||||||
[[nodiscard]] auto isRenderable() const -> bool { return !isWaiting() && !isGameOver() && !isTitleHidden(); }
|
[[nodiscard]] auto isRenderable() const -> bool; // Indica si se puede dibujar el objeto
|
||||||
void addScoreToScoreBoard(); // Añade una puntuación a la tabla de records
|
void addScoreToScoreBoard() const; // Añade una puntuación a la tabla de records
|
||||||
};
|
};
|
||||||
@@ -54,8 +54,8 @@ void Resource::load() {
|
|||||||
initProgressBar();
|
initProgressBar();
|
||||||
|
|
||||||
// Muerstra la ventana y desactiva el sincronismo vertical
|
// Muerstra la ventana y desactiva el sincronismo vertical
|
||||||
auto screen = Screen::get();
|
auto *screen = Screen::get();
|
||||||
auto vsync = screen->getVSync();
|
auto vsync = Screen::getVSync();
|
||||||
screen->setVSync(false);
|
screen->setVSync(false);
|
||||||
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** LOADING RESOURCES");
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** LOADING RESOURCES");
|
||||||
@@ -337,7 +337,7 @@ void Resource::createText() {
|
|||||||
// Vacía el vector de sonidos y libera la memoria asociada
|
// Vacía el vector de sonidos y libera la memoria asociada
|
||||||
void Resource::clearSounds() {
|
void Resource::clearSounds() {
|
||||||
for (auto &sound : sounds_) {
|
for (auto &sound : sounds_) {
|
||||||
if (sound.sound) {
|
if (sound.sound != nullptr) {
|
||||||
JA_DeleteSound(sound.sound);
|
JA_DeleteSound(sound.sound);
|
||||||
sound.sound = nullptr;
|
sound.sound = nullptr;
|
||||||
}
|
}
|
||||||
@@ -348,7 +348,7 @@ void Resource::clearSounds() {
|
|||||||
// Vacía el vector de músicas y libera la memoria asociada
|
// Vacía el vector de músicas y libera la memoria asociada
|
||||||
void Resource::clearMusics() {
|
void Resource::clearMusics() {
|
||||||
for (auto &music : musics_) {
|
for (auto &music : musics_) {
|
||||||
if (music.music) {
|
if (music.music != nullptr) {
|
||||||
JA_DeleteMusic(music.music);
|
JA_DeleteMusic(music.music);
|
||||||
music.music = nullptr;
|
music.music = nullptr;
|
||||||
}
|
}
|
||||||
@@ -378,8 +378,8 @@ void Resource::calculateTotalResources() {
|
|||||||
// Muestra el progreso de carga en pantalla (barra y texto)
|
// Muestra el progreso de carga en pantalla (barra y texto)
|
||||||
void Resource::renderProgress() {
|
void Resource::renderProgress() {
|
||||||
// Obtiene la pantalla y el renderer
|
// Obtiene la pantalla y el renderer
|
||||||
auto screen = Screen::get();
|
auto *screen = Screen::get();
|
||||||
auto renderer = screen->getRenderer();
|
auto *renderer = screen->getRenderer();
|
||||||
|
|
||||||
// Actualiza la lógica principal de la pantalla (input, etc.)
|
// Actualiza la lógica principal de la pantalla (input, etc.)
|
||||||
screen->coreUpdate();
|
screen->coreUpdate();
|
||||||
@@ -437,9 +437,9 @@ void Resource::updateLoadingProgress(std::string name) {
|
|||||||
|
|
||||||
// Inicializa los rectangulos que definen la barra de progreso
|
// Inicializa los rectangulos que definen la barra de progreso
|
||||||
void Resource::initProgressBar() {
|
void Resource::initProgressBar() {
|
||||||
constexpr float X_PADDING = 20.0f;
|
constexpr float X_PADDING = 20.0F;
|
||||||
constexpr float Y_PADDING = 20.0f;
|
constexpr float Y_PADDING = 20.0F;
|
||||||
constexpr float BAR_HEIGHT = 10.0f;
|
constexpr float BAR_HEIGHT = 10.0F;
|
||||||
const float BAR_Y_POSITION = param.game.height - BAR_HEIGHT - Y_PADDING;
|
const float BAR_Y_POSITION = param.game.height - BAR_HEIGHT - Y_PADDING;
|
||||||
|
|
||||||
const float WIRED_BAR_WIDTH = param.game.width - (X_PADDING * 2);
|
const float WIRED_BAR_WIDTH = param.game.width - (X_PADDING * 2);
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ class Resource {
|
|||||||
// --- Métodos internos para gestionar el progreso ---
|
// --- Métodos internos para gestionar el progreso ---
|
||||||
void calculateTotalResources(); // Calcula el número de recursos para cargar
|
void calculateTotalResources(); // Calcula el número de recursos para cargar
|
||||||
void renderProgress(); // Muestra el progreso de carga
|
void renderProgress(); // Muestra el progreso de carga
|
||||||
void checkEvents(); // Comprueba los eventos durante la carga
|
static void checkEvents(); // Comprueba los eventos durante la carga
|
||||||
void updateLoadingProgress(std::string name); // Actualiza el progreso de carga
|
void updateLoadingProgress(std::string name); // Actualiza el progreso de carga
|
||||||
void initProgressBar(); // Inicializa los rectangulos que definen la barra de progreso
|
void initProgressBar(); // Inicializa los rectangulos que definen la barra de progreso
|
||||||
void updateProgressBar(); // Actualiza la barra de estado
|
void updateProgressBar(); // Actualiza la barra de estado
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ Scoreboard::Scoreboard()
|
|||||||
recalculateAnchors();
|
recalculateAnchors();
|
||||||
power_meter_sprite_->setPosition(SDL_FRect{
|
power_meter_sprite_->setPosition(SDL_FRect{
|
||||||
static_cast<float>(slot4_2_.x - 20),
|
static_cast<float>(slot4_2_.x - 20),
|
||||||
static_cast<float>(slot4_2_.y),
|
slot4_2_.y,
|
||||||
40,
|
40,
|
||||||
7});
|
7});
|
||||||
|
|
||||||
@@ -76,12 +76,12 @@ Scoreboard::Scoreboard()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scoreboard::~Scoreboard() {
|
Scoreboard::~Scoreboard() {
|
||||||
if (background_) {
|
if (background_ != nullptr) {
|
||||||
SDL_DestroyTexture(background_);
|
SDL_DestroyTexture(background_);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto texture : panel_texture_) {
|
for (auto *texture : panel_texture_) {
|
||||||
if (texture) {
|
if (texture != nullptr) {
|
||||||
SDL_DestroyTexture(texture);
|
SDL_DestroyTexture(texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,7 @@ void Scoreboard::setPos(SDL_FRect rect) {
|
|||||||
// Rellena los diferentes paneles del marcador
|
// Rellena los diferentes paneles del marcador
|
||||||
void Scoreboard::fillPanelTextures() {
|
void Scoreboard::fillPanelTextures() {
|
||||||
// Guarda a donde apunta actualmente el renderizador
|
// Guarda a donde apunta actualmente el renderizador
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
|
|
||||||
// Genera el contenido de cada panel_
|
// Genera el contenido de cada panel_
|
||||||
for (size_t i = 0; i < SCOREBOARD_MAX_PANELS; ++i) {
|
for (size_t i = 0; i < SCOREBOARD_MAX_PANELS; ++i) {
|
||||||
@@ -153,148 +153,177 @@ void Scoreboard::fillPanelTextures() {
|
|||||||
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
||||||
SDL_RenderClear(renderer_);
|
SDL_RenderClear(renderer_);
|
||||||
|
|
||||||
switch (panel_[i].mode) {
|
renderPanelContent(i);
|
||||||
case ScoreboardMode::SCORE: {
|
|
||||||
// SCORE
|
|
||||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_1_.x, slot4_1_.y, name_[i], 1, text_color1_);
|
|
||||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_2_.x, slot4_2_.y, updateScoreText(score_[i]), 1, text_color2_);
|
|
||||||
|
|
||||||
// MULT
|
|
||||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 3"), 1, text_color1_);
|
|
||||||
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_4_.x, slot4_4_.y, "x" + std::to_string(mult_[i]).substr(0, 3), 1, text_color2_);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ScoreboardMode::DEMO: {
|
|
||||||
// DEMO MODE
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 6"), 1, text_color1_);
|
|
||||||
|
|
||||||
// PRESS START TO PLAY
|
|
||||||
if (time_counter_ % 10 < 8) {
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 8"), 1, text_color1_);
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 9"), 1, text_color1_);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ScoreboardMode::WAITING: {
|
|
||||||
// GAME OVER
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
|
||||||
|
|
||||||
// PRESS START TO PLAY
|
|
||||||
if (time_counter_ % 10 < 8) {
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 8"), 1, text_color1_);
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 9"), 1, text_color1_);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ScoreboardMode::GAME_OVER: {
|
|
||||||
// GAME OVER
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
|
||||||
|
|
||||||
// PLEASE WAIT
|
|
||||||
if (time_counter_ % 10 < 8) {
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 12"), 1, text_color1_);
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 13"), 1, text_color1_);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ScoreboardMode::STAGE_INFO: {
|
|
||||||
// STAGE
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, Lang::getText("[SCOREBOARD] 5") + std::to_string(stage_), 1, text_color1_);
|
|
||||||
|
|
||||||
// POWERMETER
|
|
||||||
power_meter_sprite_->setSpriteClip(0, 0, 40, 7);
|
|
||||||
power_meter_sprite_->render();
|
|
||||||
power_meter_sprite_->setSpriteClip(40, 0, int(power_ * 40.0f), 7);
|
|
||||||
power_meter_sprite_->render();
|
|
||||||
|
|
||||||
// HI-SCORE
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 4"), 1, text_color1_);
|
|
||||||
const std::string NAME = hi_score_name_ == "" ? "" : hi_score_name_ + " - ";
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, NAME + updateScoreText(hi_score_), 1, text_color2_);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ScoreboardMode::CONTINUE: {
|
|
||||||
// SCORE
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_[i], 1, text_color1_);
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_[i]), 1, text_color2_);
|
|
||||||
|
|
||||||
// CONTINUE
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 10"), 1, text_color1_);
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, std::to_string(continue_counter_[i]), 1, text_color2_);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ScoreboardMode::ENTER_NAME: {
|
|
||||||
// SCORE
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_[i], 1, text_color1_);
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_[i]), 1, text_color2_);
|
|
||||||
|
|
||||||
// ENTER NAME
|
|
||||||
{
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
|
||||||
SDL_FRect rect = {enter_name_pos_.x, enter_name_pos_.y, 5.0f, 7.0f};
|
|
||||||
|
|
||||||
// Recorre todos los slots de letras del nombre
|
|
||||||
for (size_t j = 0; j < NAME_SIZE; ++j) {
|
|
||||||
// Selecciona el color
|
|
||||||
const Color COLOR = j < selector_pos_[i] ? text_color2_ : text_color1_;
|
|
||||||
|
|
||||||
if (j != selector_pos_[i] || time_counter_ % 3 == 0) {
|
|
||||||
// Dibuja la linea
|
|
||||||
if (j >= selector_pos_[i]) {
|
|
||||||
SDL_SetRenderDrawColor(renderer_, COLOR.r, COLOR.g, COLOR.b, 255);
|
|
||||||
SDL_RenderLine(renderer_, rect.x, rect.y + rect.h, rect.x + rect.w, rect.y + rect.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dibuja la letra
|
|
||||||
if (j < record_name_[i].size()) {
|
|
||||||
text_scoreboard_->writeColored(rect.x, rect.y, record_name_[i].substr(j, 1), COLOR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rect.x += 7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ScoreboardMode::SHOW_NAME: {
|
|
||||||
// SCORE
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_[i], 1, text_color1_);
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_[i]), 1, text_color2_);
|
|
||||||
|
|
||||||
// NAME
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
|
||||||
|
|
||||||
/* TEXTO CENTRADO */
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, record_name_[i], 1, getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
|
||||||
|
|
||||||
/* TEXTO A LA IZQUIERDA */
|
|
||||||
// text_scoreboard_->writeColored(enter_name_pos_.x, enter_name_pos_.y, record_name_[i], getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ScoreboardMode::GAME_COMPLETED: {
|
|
||||||
// GAME OVER
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
|
||||||
|
|
||||||
// SCORE
|
|
||||||
if (time_counter_ % 10 < 8) {
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 14"), 1, text_color1_);
|
|
||||||
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, updateScoreText(score_[i]), 1, text_color2_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deja el renderizador apuntando donde estaba
|
// Deja el renderizador apuntando donde estaba
|
||||||
SDL_SetRenderTarget(renderer_, temp);
|
SDL_SetRenderTarget(renderer_, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderPanelContent(size_t panelIndex) {
|
||||||
|
switch (panel_[panelIndex].mode) {
|
||||||
|
case ScoreboardMode::SCORE:
|
||||||
|
renderScoreMode(panelIndex);
|
||||||
|
break;
|
||||||
|
case ScoreboardMode::DEMO:
|
||||||
|
renderDemoMode();
|
||||||
|
break;
|
||||||
|
case ScoreboardMode::WAITING:
|
||||||
|
renderWaitingMode();
|
||||||
|
break;
|
||||||
|
case ScoreboardMode::GAME_OVER:
|
||||||
|
renderGameOverMode();
|
||||||
|
break;
|
||||||
|
case ScoreboardMode::STAGE_INFO:
|
||||||
|
renderStageInfoMode();
|
||||||
|
break;
|
||||||
|
case ScoreboardMode::CONTINUE:
|
||||||
|
renderContinueMode(panelIndex);
|
||||||
|
break;
|
||||||
|
case ScoreboardMode::ENTER_NAME:
|
||||||
|
renderEnterNameMode(panelIndex);
|
||||||
|
break;
|
||||||
|
case ScoreboardMode::SHOW_NAME:
|
||||||
|
renderShowNameMode(panelIndex);
|
||||||
|
break;
|
||||||
|
case ScoreboardMode::GAME_COMPLETED:
|
||||||
|
renderGameCompletedMode(panelIndex);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderScoreMode(size_t panelIndex) {
|
||||||
|
// SCORE
|
||||||
|
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_1_.x, slot4_1_.y, name_[panelIndex], 1, text_color1_);
|
||||||
|
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_2_.x, slot4_2_.y, updateScoreText(score_[panelIndex]), 1, text_color2_);
|
||||||
|
|
||||||
|
// MULT
|
||||||
|
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 3"), 1, text_color1_);
|
||||||
|
text_scoreboard_->writeDX(TEXT_COLOR | TEXT_CENTER, slot4_4_.x, slot4_4_.y, "x" + std::to_string(mult_[panelIndex]).substr(0, 3), 1, text_color2_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderDemoMode() {
|
||||||
|
// DEMO MODE
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 6"), 1, text_color1_);
|
||||||
|
|
||||||
|
// PRESS START TO PLAY
|
||||||
|
if (time_counter_ % 10 < 8) {
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 8"), 1, text_color1_);
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 9"), 1, text_color1_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderWaitingMode() {
|
||||||
|
// GAME OVER
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
||||||
|
|
||||||
|
// PRESS START TO PLAY
|
||||||
|
if (time_counter_ % 10 < 8) {
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 8"), 1, text_color1_);
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 9"), 1, text_color1_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderGameOverMode() {
|
||||||
|
// GAME OVER
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
||||||
|
|
||||||
|
// PLEASE WAIT
|
||||||
|
if (time_counter_ % 10 < 8) {
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 12"), 1, text_color1_);
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, Lang::getText("[SCOREBOARD] 13"), 1, text_color1_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderStageInfoMode() {
|
||||||
|
// STAGE
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, Lang::getText("[SCOREBOARD] 5") + std::to_string(stage_), 1, text_color1_);
|
||||||
|
|
||||||
|
// POWERMETER
|
||||||
|
power_meter_sprite_->setSpriteClip(0, 0, 40, 7);
|
||||||
|
power_meter_sprite_->render();
|
||||||
|
power_meter_sprite_->setSpriteClip(40, 0, int(power_ * 40.0F), 7);
|
||||||
|
power_meter_sprite_->render();
|
||||||
|
|
||||||
|
// HI-SCORE
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 4"), 1, text_color1_);
|
||||||
|
const std::string NAME = hi_score_name_.empty() ? "" : hi_score_name_ + " - ";
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, NAME + updateScoreText(hi_score_), 1, text_color2_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderContinueMode(size_t panelIndex) {
|
||||||
|
// SCORE
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_[panelIndex], 1, text_color1_);
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_[panelIndex]), 1, text_color2_);
|
||||||
|
|
||||||
|
// CONTINUE
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 10"), 1, text_color1_);
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, std::to_string(continue_counter_[panelIndex]), 1, text_color2_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderEnterNameMode(size_t panelIndex) {
|
||||||
|
// SCORE
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_[panelIndex], 1, text_color1_);
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_[panelIndex]), 1, text_color2_);
|
||||||
|
|
||||||
|
// ENTER NAME
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
||||||
|
|
||||||
|
renderNameInputField(panelIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderNameInputField(size_t panelIndex) {
|
||||||
|
SDL_FRect rect = {enter_name_pos_.x, enter_name_pos_.y, 5.0F, 7.0F};
|
||||||
|
|
||||||
|
// Recorre todos los slots de letras del nombre
|
||||||
|
for (size_t j = 0; j < NAME_SIZE; ++j) {
|
||||||
|
// Selecciona el color
|
||||||
|
const Color COLOR = j < selector_pos_[panelIndex] ? text_color2_ : text_color1_;
|
||||||
|
|
||||||
|
if (j != selector_pos_[panelIndex] || time_counter_ % 3 == 0) {
|
||||||
|
// Dibuja la linea
|
||||||
|
if (j >= selector_pos_[panelIndex]) {
|
||||||
|
SDL_SetRenderDrawColor(renderer_, COLOR.r, COLOR.g, COLOR.b, 255);
|
||||||
|
SDL_RenderLine(renderer_, rect.x, rect.y + rect.h, rect.x + rect.w, rect.y + rect.h);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dibuja la letra
|
||||||
|
if (j < record_name_[panelIndex].size()) {
|
||||||
|
text_scoreboard_->writeColored(rect.x, rect.y, record_name_[panelIndex].substr(j, 1), COLOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rect.x += 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderShowNameMode(size_t panelIndex) {
|
||||||
|
// SCORE
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y, name_[panelIndex], 1, text_color1_);
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_2_.x, slot4_2_.y, updateScoreText(score_[panelIndex]), 1, text_color2_);
|
||||||
|
|
||||||
|
// NAME
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
|
||||||
|
|
||||||
|
/* TEXTO CENTRADO */
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y, record_name_[panelIndex], 1, getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
||||||
|
|
||||||
|
/* TEXTO A LA IZQUIERDA */
|
||||||
|
// text_scoreboard_->writeColored(enter_name_pos_.x, enter_name_pos_.y, record_name_[panelIndex], getColorLikeKnightRider(name_colors_, loop_counter_ / 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scoreboard::renderGameCompletedMode(size_t panelIndex) {
|
||||||
|
// GAME OVER
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_1_.x, slot4_1_.y + 4, Lang::getText("[SCOREBOARD] 7"), 1, text_color1_);
|
||||||
|
|
||||||
|
// SCORE
|
||||||
|
if (time_counter_ % 10 < 8) {
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_3_.x, slot4_3_.y - 2, Lang::getText("[SCOREBOARD] 14"), 1, text_color1_);
|
||||||
|
text_scoreboard_->writeDX(TEXT_CENTER | TEXT_COLOR, slot4_4_.x, slot4_4_.y - 2, updateScoreText(score_[panelIndex]), 1, text_color2_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Rellena la textura de fondo
|
// Rellena la textura de fondo
|
||||||
void Scoreboard::fillBackgroundTexture() {
|
void Scoreboard::fillBackgroundTexture() {
|
||||||
// Rellena los diferentes paneles del marcador
|
// Rellena los diferentes paneles del marcador
|
||||||
@@ -323,7 +352,7 @@ void Scoreboard::fillBackgroundTexture() {
|
|||||||
// Recalcula las anclas de los elementos
|
// Recalcula las anclas de los elementos
|
||||||
void Scoreboard::recalculateAnchors() {
|
void Scoreboard::recalculateAnchors() {
|
||||||
// Recalcula la posición y el tamaño de los paneles
|
// Recalcula la posición y el tamaño de los paneles
|
||||||
const float PANEL_WIDTH = (float)rect_.w / (float)SCOREBOARD_MAX_PANELS;
|
const float PANEL_WIDTH = rect_.w / (float)SCOREBOARD_MAX_PANELS;
|
||||||
for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i) {
|
for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i) {
|
||||||
panel_[i].pos.x = roundf(PANEL_WIDTH * i);
|
panel_[i].pos.x = roundf(PANEL_WIDTH * i);
|
||||||
panel_[i].pos.y = 0;
|
panel_[i].pos.y = 0;
|
||||||
@@ -365,7 +394,7 @@ void Scoreboard::recalculateAnchors() {
|
|||||||
// Crea la textura de fondo
|
// Crea la textura de fondo
|
||||||
void Scoreboard::createBackgroundTexture() {
|
void Scoreboard::createBackgroundTexture() {
|
||||||
// Elimina la textura en caso de existir
|
// Elimina la textura en caso de existir
|
||||||
if (background_) {
|
if (background_ != nullptr) {
|
||||||
SDL_DestroyTexture(background_);
|
SDL_DestroyTexture(background_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +406,7 @@ void Scoreboard::createBackgroundTexture() {
|
|||||||
// Crea las texturas de los paneles
|
// Crea las texturas de los paneles
|
||||||
void Scoreboard::createPanelTextures() {
|
void Scoreboard::createPanelTextures() {
|
||||||
// Elimina las texturas en caso de existir
|
// Elimina las texturas en caso de existir
|
||||||
for (auto texture : panel_texture_) {
|
for (auto *texture : panel_texture_) {
|
||||||
if (texture != nullptr) {
|
if (texture != nullptr) {
|
||||||
SDL_DestroyTexture(texture);
|
SDL_DestroyTexture(texture);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_FPoint, SDL_GetTicks, SDL_FRect, SDL_Texture, SDL_Renderer, Uint64
|
#include <SDL3/SDL.h> // Para SDL_FPoint, SDL_GetTicks, SDL_FRect, SDL_Texture, SDL_Renderer, Uint64
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstddef> // Para size_t
|
#include <cstddef> // Para size_t
|
||||||
#include <memory> // Para shared_ptr, unique_ptr
|
#include <memory> // Para shared_ptr, unique_ptr
|
||||||
#include <string> // Para basic_string, string
|
#include <string> // Para basic_string, string
|
||||||
@@ -35,87 +36,99 @@ enum class ScoreboardMode : int {
|
|||||||
|
|
||||||
// --- Structs ---
|
// --- Structs ---
|
||||||
struct Panel {
|
struct Panel {
|
||||||
ScoreboardMode mode; // Modo en el que se encuentra el panel
|
ScoreboardMode mode; // Modo en el que se encuentra el panel
|
||||||
SDL_FRect pos; // Posición donde dibujar el panel dentro del marcador
|
SDL_FRect pos; // Posición donde dibujar el panel dentro del marcador
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Clase Scoreboard ---
|
// --- Clase Scoreboard ---
|
||||||
class Scoreboard {
|
class Scoreboard {
|
||||||
public:
|
public:
|
||||||
// --- Métodos de singleton ---
|
// --- Métodos de singleton ---
|
||||||
static void init(); // Crea el objeto Scoreboard
|
static void init(); // Crea el objeto Scoreboard
|
||||||
static void destroy(); // Libera el objeto Scoreboard
|
static void destroy(); // Libera el objeto Scoreboard
|
||||||
static auto get() -> Scoreboard *; // Obtiene el puntero al objeto Scoreboard
|
static auto get() -> Scoreboard *; // Obtiene el puntero al objeto Scoreboard
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void update(); // Actualiza la lógica del marcador
|
void update(); // Actualiza la lógica del marcador
|
||||||
void render(); // Pinta el marcador
|
void render(); // Pinta el marcador
|
||||||
|
|
||||||
// --- Setters ---
|
// --- Setters ---
|
||||||
void setColor(Color color); // Establece el color del marcador
|
void setColor(Color color); // Establece el color del marcador
|
||||||
void setPos(SDL_FRect rect); // Establece la posición y tamaño del marcador
|
void setPos(SDL_FRect rect); // Establece la posición y tamaño del marcador
|
||||||
void setContinue(int panel, int continue_counter) { continue_counter_[panel] = continue_counter; }
|
void setContinue(int panel, int continue_counter) { continue_counter_[panel] = continue_counter; }
|
||||||
void setHiScore(int hi_score) { hi_score_ = hi_score; }
|
void setHiScore(int hi_score) { hi_score_ = hi_score; }
|
||||||
void setHiScoreName(const std::string &name) { hi_score_name_ = name; }
|
void setHiScoreName(const std::string &name) { hi_score_name_ = name; }
|
||||||
void setMode(int index, ScoreboardMode mode) { panel_[index].mode = mode; }
|
void setMode(int index, ScoreboardMode mode) { panel_[index].mode = mode; }
|
||||||
void setMult(int panel, float mult) { mult_[panel] = mult; }
|
void setMult(int panel, float mult) { mult_[panel] = mult; }
|
||||||
void setName(int panel, const std::string &name) { name_[panel] = name; }
|
void setName(int panel, const std::string &name) { name_[panel] = name; }
|
||||||
void setPower(float power) { power_ = power; }
|
void setPower(float power) { power_ = power; }
|
||||||
void setRecordName(int panel, const std::string &record_name) { record_name_[panel] = record_name; }
|
void setRecordName(int panel, const std::string &record_name) { record_name_[panel] = record_name; }
|
||||||
void setScore(int panel, int score) { score_[panel] = score; }
|
void setScore(int panel, int score) { score_[panel] = score; }
|
||||||
void setSelectorPos(int panel, int pos) { selector_pos_[panel] = pos; }
|
void setSelectorPos(int panel, int pos) { selector_pos_[panel] = pos; }
|
||||||
void setStage(int stage) { stage_ = stage; }
|
void setStage(int stage) { stage_ = stage; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Objetos y punteros ---
|
// --- Objetos y punteros ---
|
||||||
SDL_Renderer *renderer_; // El renderizador de la ventana
|
SDL_Renderer *renderer_; // El renderizador de la ventana
|
||||||
std::shared_ptr<Texture> game_power_meter_texture_; // Textura con el marcador de poder de la fase
|
std::shared_ptr<Texture> game_power_meter_texture_; // Textura con el marcador de poder de la fase
|
||||||
std::unique_ptr<Sprite> power_meter_sprite_; // Sprite para el medidor de poder de la fase
|
std::unique_ptr<Sprite> power_meter_sprite_; // Sprite para el medidor de poder de la fase
|
||||||
std::shared_ptr<Text> text_scoreboard_; // Fuente para el marcador del juego
|
std::shared_ptr<Text> text_scoreboard_; // Fuente para el marcador del juego
|
||||||
SDL_Texture *background_ = nullptr; // Textura para dibujar el marcador
|
SDL_Texture *background_ = nullptr; // Textura para dibujar el marcador
|
||||||
std::vector<SDL_Texture *> panel_texture_; // Texturas para dibujar cada panel
|
std::vector<SDL_Texture *> panel_texture_; // Texturas para dibujar cada panel
|
||||||
|
|
||||||
// --- Variables de estado ---
|
// --- Variables de estado ---
|
||||||
std::string name_[SCOREBOARD_MAX_PANELS] = {}; // Nombre de cada jugador
|
std::array<std::string, SCOREBOARD_MAX_PANELS> name_ = {}; // Nombre de cada jugador
|
||||||
std::string record_name_[SCOREBOARD_MAX_PANELS] = {}; // Nombre introducido para la tabla de records
|
std::array<std::string, SCOREBOARD_MAX_PANELS> record_name_ = {}; // Nombre introducido para la tabla de records
|
||||||
size_t selector_pos_[SCOREBOARD_MAX_PANELS] = {}; // Posición del selector de letra para introducir el nombre
|
std::array<size_t, SCOREBOARD_MAX_PANELS> selector_pos_ = {}; // Posición del selector de letra para introducir el nombre
|
||||||
int score_[SCOREBOARD_MAX_PANELS] = {}; // Puntuación de los jugadores
|
std::array<int, SCOREBOARD_MAX_PANELS> score_ = {}; // Puntuación de los jugadores
|
||||||
float mult_[SCOREBOARD_MAX_PANELS] = {}; // Multiplicador de los jugadores
|
std::array<float, SCOREBOARD_MAX_PANELS> mult_ = {}; // Multiplicador de los jugadores
|
||||||
int continue_counter_[SCOREBOARD_MAX_PANELS] = {}; // Tiempo para continuar de los jugadores
|
std::array<int, SCOREBOARD_MAX_PANELS> continue_counter_ = {}; // Tiempo para continuar de los jugadores
|
||||||
Panel panel_[SCOREBOARD_MAX_PANELS] = {}; // Lista con todos los paneles del marcador
|
std::array<Panel, SCOREBOARD_MAX_PANELS> panel_ = {}; // Lista con todos los paneles del marcador
|
||||||
int stage_ = 1; // Número de fase actual
|
|
||||||
int hi_score_ = 0; // Máxima puntuación
|
|
||||||
float power_ = 0; // Poder actual de la fase
|
|
||||||
std::string hi_score_name_ = std::string(); // Nombre del jugador con la máxima puntuación
|
|
||||||
Color color_ = Color(); // Color del marcador
|
|
||||||
SDL_FRect rect_ = {0, 0, 320, 40}; // Posición y dimensiones del marcador
|
|
||||||
Uint64 ticks_ = SDL_GetTicks(); // Variable donde almacenar el valor de SDL_GetTicks()
|
|
||||||
int time_counter_ = 0; // Contador de segundos
|
|
||||||
int loop_counter_ = 0; // Contador de bucle
|
|
||||||
std::vector<Color> name_colors_; // Colores para destacar el nombre una vez introducido
|
|
||||||
|
|
||||||
// --- Variables de aspecto ---
|
int stage_ = 1; // Número de fase actual
|
||||||
Color text_color1_, text_color2_; // Colores para los marcadores del texto;
|
int hi_score_ = 0; // Máxima puntuación
|
||||||
|
float power_ = 0; // Poder actual de la fase
|
||||||
|
std::string hi_score_name_; // Nombre del jugador con la máxima puntuación
|
||||||
|
Color color_; // Color del marcador
|
||||||
|
SDL_FRect rect_ = {0, 0, 320, 40}; // Posición y dimensiones del marcador
|
||||||
|
Uint64 ticks_ = SDL_GetTicks(); // Variable donde almacenar el valor de SDL_GetTicks()
|
||||||
|
int time_counter_ = 0; // Contador de segundos
|
||||||
|
int loop_counter_ = 0; // Contador de bucle
|
||||||
|
std::vector<Color> name_colors_; // Colores para destacar el nombre una vez introducido
|
||||||
|
|
||||||
// --- Puntos predefinidos para colocar elementos en los paneles ---
|
// --- Variables de aspecto ---
|
||||||
SDL_FPoint slot4_1_, slot4_2_, slot4_3_, slot4_4_;
|
Color text_color1_, text_color2_; // Colores para los marcadores del texto;
|
||||||
SDL_FPoint enter_name_pos_;
|
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Puntos predefinidos para colocar elementos en los paneles ---
|
||||||
void recalculateAnchors(); // Recalcula las anclas de los elementos
|
SDL_FPoint slot4_1_, slot4_2_, slot4_3_, slot4_4_;
|
||||||
auto updateScoreText(int num) -> std::string; // Transforma un valor numérico en una cadena de 7 cifras
|
SDL_FPoint enter_name_pos_;
|
||||||
void createBackgroundTexture(); // Crea la textura de fondo
|
|
||||||
void createPanelTextures(); // Crea las texturas de los paneles
|
|
||||||
void fillPanelTextures(); // Rellena los diferentes paneles del marcador
|
|
||||||
void fillBackgroundTexture(); // Rellena la textura de fondo
|
|
||||||
void updateTimeCounter(); // Actualiza el contador
|
|
||||||
void renderSeparator(); // Dibuja la línea que separa la zona de juego del marcador
|
|
||||||
void iniNameColors(); // Inicializa el vector de colores para el nombre
|
|
||||||
|
|
||||||
// --- Constructor y destructor privados (singleton) ---
|
// --- Métodos internos ---
|
||||||
Scoreboard();
|
void recalculateAnchors(); // Recalcula las anclas de los elementos
|
||||||
~Scoreboard();
|
static auto updateScoreText(int num) -> std::string; // Transforma un valor numérico en una cadena de 7 cifras
|
||||||
|
void createBackgroundTexture(); // Crea la textura de fondo
|
||||||
|
void createPanelTextures(); // Crea las texturas de los paneles
|
||||||
|
void fillPanelTextures(); // Rellena los diferentes paneles del marcador
|
||||||
|
void fillBackgroundTexture(); // Rellena la textura de fondo
|
||||||
|
void updateTimeCounter(); // Actualiza el contador
|
||||||
|
void renderSeparator(); // Dibuja la línea que separa la zona de juego del marcador
|
||||||
|
void iniNameColors(); // Inicializa el vector de colores para el nombre
|
||||||
|
void renderPanelContent(size_t panelIndex);
|
||||||
|
void renderScoreMode(size_t panelIndex);
|
||||||
|
void renderDemoMode();
|
||||||
|
void renderWaitingMode();
|
||||||
|
void renderGameOverMode();
|
||||||
|
void renderStageInfoMode();
|
||||||
|
void renderContinueMode(size_t panelIndex);
|
||||||
|
void renderEnterNameMode(size_t panelIndex);
|
||||||
|
void renderNameInputField(size_t panelIndex);
|
||||||
|
void renderShowNameMode(size_t panelIndex);
|
||||||
|
void renderGameCompletedMode(size_t panelIndex);
|
||||||
|
|
||||||
// --- Singleton ---
|
// --- Constructor y destructor privados (singleton) ---
|
||||||
static Scoreboard *instance;
|
Scoreboard();
|
||||||
|
~Scoreboard();
|
||||||
|
|
||||||
|
// --- Singleton ---
|
||||||
|
static Scoreboard *instance;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class Screen {
|
|||||||
void show() { SDL_ShowWindow(window_); } // Muestra la ventana
|
void show() { SDL_ShowWindow(window_); } // Muestra la ventana
|
||||||
void hide() { SDL_HideWindow(window_); } // Oculta la ventana
|
void hide() { SDL_HideWindow(window_); } // Oculta la ventana
|
||||||
void getSingletons(); // Obtiene los punteros a los singletones
|
void getSingletons(); // Obtiene los punteros a los singletones
|
||||||
[[nodiscard]] auto getVSync() const -> bool { return Options::video.v_sync; } // Obtiene el valor de V-Sync
|
[[nodiscard]] static auto getVSync() -> bool { return Options::video.v_sync; } // Obtiene el valor de V-Sync
|
||||||
[[nodiscard]] auto getText() const -> std::shared_ptr<Text> { return text_; } // Obtiene el puntero al texto de Screen
|
[[nodiscard]] auto getText() const -> std::shared_ptr<Text> { return text_; } // Obtiene el puntero al texto de Screen
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -70,7 +70,7 @@ class Screen {
|
|||||||
int frame_count{0}; // Número acumulado de frames en el intervalo.
|
int frame_count{0}; // Número acumulado de frames en el intervalo.
|
||||||
int last_value{0}; // Número de frames calculado en el último segundo.
|
int last_value{0}; // Número de frames calculado en el último segundo.
|
||||||
|
|
||||||
FPS() {}
|
FPS() = default;
|
||||||
void increment() { frame_count++; }
|
void increment() { frame_count++; }
|
||||||
auto calculate(Uint32 current_ticks) -> int {
|
auto calculate(Uint32 current_ticks) -> int {
|
||||||
if (current_ticks - ticks >= 1000) {
|
if (current_ticks - ticks >= 1000) {
|
||||||
@@ -93,8 +93,8 @@ class Screen {
|
|||||||
explicit FlashEffect(bool enabled = false, int lenght = 0, int delay = 0, Color color = Color(0xFF, 0xFF, 0xFF))
|
explicit FlashEffect(bool enabled = false, int lenght = 0, int delay = 0, Color color = Color(0xFF, 0xFF, 0xFF))
|
||||||
: enabled(enabled), lenght(lenght), delay(delay), counter(lenght), color(color) {}
|
: enabled(enabled), lenght(lenght), delay(delay), counter(lenght), color(color) {}
|
||||||
|
|
||||||
void update() { (enabled && counter > 0) ? counter-- : enabled = false; }
|
void update() { (enabled && counter > 0) ? counter-- : static_cast<int>(enabled = false); }
|
||||||
auto isRendarable() -> bool { return enabled && counter < lenght - delay; }
|
[[nodiscard]] auto isRendarable() const -> bool { return enabled && counter < lenght - delay; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Efecto de sacudida/agitación de pantalla: mueve la imagen para simular un temblor
|
// Efecto de sacudida/agitación de pantalla: mueve la imagen para simular un temblor
|
||||||
@@ -119,12 +119,15 @@ class Screen {
|
|||||||
original_width = src_rect.w;
|
original_width = src_rect.w;
|
||||||
|
|
||||||
// Usar nuevos valores si se proporcionan, sino mantener los actuales
|
// Usar nuevos valores si se proporcionan, sino mantener los actuales
|
||||||
if (new_desp != -1)
|
if (new_desp != -1) {
|
||||||
desp = new_desp;
|
desp = new_desp;
|
||||||
if (new_delay != -1)
|
}
|
||||||
|
if (new_delay != -1) {
|
||||||
delay = new_delay;
|
delay = new_delay;
|
||||||
if (new_lenght != -1)
|
}
|
||||||
|
if (new_lenght != -1) {
|
||||||
lenght = new_lenght;
|
lenght = new_lenght;
|
||||||
|
}
|
||||||
|
|
||||||
src_rect.w -= desp;
|
src_rect.w -= desp;
|
||||||
dst_rect.w = src_rect.w;
|
dst_rect.w = src_rect.w;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <cmath> // Para abs
|
#include <cmath> // Para abs
|
||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <string> // Para basic_string, string
|
#include <string> // Para basic_string, string
|
||||||
|
#include <string_view>
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
|
|
||||||
#include "audio.h" // Para Audio
|
#include "audio.h" // Para Audio
|
||||||
@@ -30,7 +31,8 @@
|
|||||||
#include "utils.h" // Para Color, Zone, SHADOW_TEXT_COLOR, NO_TEXT...
|
#include "utils.h" // Para Color, Zone, SHADOW_TEXT_COLOR, NO_TEXT...
|
||||||
|
|
||||||
// Textos
|
// Textos
|
||||||
constexpr const char TEXT_COPYRIGHT[] = "@2020,2025 JailDesigner";
|
constexpr std::string_view TEXT_COPYRIGHT = "@2020,2025 JailDesigner";
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Credits::Credits()
|
Credits::Credits()
|
||||||
@@ -40,7 +42,7 @@ Credits::Credits()
|
|||||||
fade_out_(std::make_unique<Fade>()),
|
fade_out_(std::make_unique<Fade>()),
|
||||||
text_texture_(SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
|
text_texture_(SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
|
||||||
canvas_(SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)) {
|
canvas_(SDL_CreateTexture(Screen::get()->getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)) {
|
||||||
if (!text_texture_) {
|
if (text_texture_ == nullptr) {
|
||||||
throw std::runtime_error("Failed to create SDL texture for text.");
|
throw std::runtime_error("Failed to create SDL texture for text.");
|
||||||
}
|
}
|
||||||
Section::name = Section::Name::CREDITS;
|
Section::name = Section::Name::CREDITS;
|
||||||
@@ -131,7 +133,7 @@ void Credits::checkInput() {
|
|||||||
|
|
||||||
if (!ServiceMenu::get()->isEnabled()) {
|
if (!ServiceMenu::get()->isEnabled()) {
|
||||||
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
||||||
if (Input::get()->checkAnyButton(INPUT_ALLOW_REPEAT)) {
|
if (Input::get()->checkAnyButton(INPUT_ALLOW_REPEAT) != 0) {
|
||||||
want_to_pass_ = true;
|
want_to_pass_ = true;
|
||||||
fading_ = mini_logo_on_position_;
|
fading_ = mini_logo_on_position_;
|
||||||
} else {
|
} else {
|
||||||
@@ -218,7 +220,7 @@ void Credits::fillTextTexture() {
|
|||||||
|
|
||||||
// Texto con el copyright
|
// Texto con el copyright
|
||||||
y += mini_logo_sprite->getHeight() + 3;
|
y += mini_logo_sprite->getHeight() + 3;
|
||||||
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, TEXT_COPYRIGHT, 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
text->writeDX(TEXT_CENTER | TEXT_SHADOW, param.game.game_area.center_x, y, std::string(TEXT_COPYRIGHT), 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR);
|
||||||
|
|
||||||
// Resetea el renderizador
|
// Resetea el renderizador
|
||||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
|
||||||
@@ -233,7 +235,7 @@ void Credits::fillTextTexture() {
|
|||||||
// Dibuja todos los sprites en la textura
|
// Dibuja todos los sprites en la textura
|
||||||
void Credits::fillCanvas() {
|
void Credits::fillCanvas() {
|
||||||
// Cambia el destino del renderizador
|
// Cambia el destino del renderizador
|
||||||
auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
auto *temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
||||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), canvas_);
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), canvas_);
|
||||||
|
|
||||||
// Dibuja el fondo, los globos y los jugadores
|
// Dibuja el fondo, los globos y los jugadores
|
||||||
@@ -376,7 +378,7 @@ void Credits::updateBlackRects() {
|
|||||||
bottom_black_rect_.y = std::max(bottom_black_rect_.y - 1, param.game.game_area.center_y + 1);
|
bottom_black_rect_.y = std::max(bottom_black_rect_.y - 1, param.game.game_area.center_y + 1);
|
||||||
|
|
||||||
--current_step_;
|
--current_step_;
|
||||||
setVolume(static_cast<int>(initial_volume_ * current_step_ / steps_));
|
setVolume((initial_volume_ * current_step_ / steps_));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Si los rectangulos superior e inferior han llegado al centro
|
// Si los rectangulos superior e inferior han llegado al centro
|
||||||
@@ -391,7 +393,7 @@ void Credits::updateBlackRects() {
|
|||||||
right_black_rect_.x = std::max(right_black_rect_.x - SPEED, param.game.game_area.center_x);
|
right_black_rect_.x = std::max(right_black_rect_.x - SPEED, param.game.game_area.center_x);
|
||||||
|
|
||||||
--current_step_;
|
--current_step_;
|
||||||
setVolume(static_cast<int>(initial_volume_ * current_step_ / steps_));
|
setVolume((initial_volume_ * current_step_ / steps_));
|
||||||
} else {
|
} else {
|
||||||
// Si los rectangulos izquierdo y derecho han llegado al centro
|
// Si los rectangulos izquierdo y derecho han llegado al centro
|
||||||
setVolume(0);
|
setVolume(0);
|
||||||
@@ -438,7 +440,7 @@ void Credits::setVolume(int amount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reestablece el nivel de volumen
|
// Reestablece el nivel de volumen
|
||||||
void Credits::resetVolume() {
|
void Credits::resetVolume() const {
|
||||||
Options::audio.music.volume = initial_volume_;
|
Options::audio.music.volume = initial_volume_;
|
||||||
Audio::get()->setMusicVolume(Options::audio.music.volume);
|
Audio::get()->setMusicVolume(Options::audio.music.volume);
|
||||||
}
|
}
|
||||||
@@ -454,9 +456,9 @@ void Credits::cycleColors() {
|
|||||||
static auto r_ = static_cast<float>(UPPER_LIMIT);
|
static auto r_ = static_cast<float>(UPPER_LIMIT);
|
||||||
static auto g_ = static_cast<float>(LOWER_LIMIT);
|
static auto g_ = static_cast<float>(LOWER_LIMIT);
|
||||||
static auto b_ = static_cast<float>(LOWER_LIMIT);
|
static auto b_ = static_cast<float>(LOWER_LIMIT);
|
||||||
static float step_r_ = -0.5f; // Paso flotante para transiciones suaves
|
static float step_r_ = -0.5F; // Paso flotante para transiciones suaves
|
||||||
static float step_g_ = 0.3f;
|
static float step_g_ = 0.3F;
|
||||||
static float step_b_ = 0.1f;
|
static float step_b_ = 0.1F;
|
||||||
|
|
||||||
// Ajustar valores de R
|
// Ajustar valores de R
|
||||||
r_ += step_r_;
|
r_ += step_r_;
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class Credits {
|
|||||||
// --- Métodos del bucle principal ---
|
// --- Métodos del bucle principal ---
|
||||||
void update(); // Actualización principal de la lógica
|
void update(); // Actualización principal de la lógica
|
||||||
void render(); // Renderizado de la escena
|
void render(); // Renderizado de la escena
|
||||||
void checkEvents(); // Manejo de eventos
|
static void checkEvents(); // Manejo de eventos
|
||||||
void checkInput(); // Procesamiento de entrada
|
void checkInput(); // Procesamiento de entrada
|
||||||
|
|
||||||
// --- Métodos de renderizado ---
|
// --- Métodos de renderizado ---
|
||||||
@@ -124,6 +124,6 @@ class Credits {
|
|||||||
void updateRedRect(); // Actualizar rectángulo rojo (borde)
|
void updateRedRect(); // Actualizar rectángulo rojo (borde)
|
||||||
|
|
||||||
// --- Métodos de audio ---
|
// --- Métodos de audio ---
|
||||||
void setVolume(int amount); // Establecer volumen
|
static void setVolume(int amount); // Establecer volumen
|
||||||
void resetVolume(); // Restablecer volumen
|
void resetVolume() const; // Restablecer volumen
|
||||||
};
|
};
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderTarget
|
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderTarget
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <algorithm> // Para find_if, clamp, find, min
|
#include <algorithm> // Para find_if, clamp, find, min
|
||||||
#include <cstdlib> // Para rand, size_t
|
#include <cstdlib> // Para rand, size_t
|
||||||
#include <functional> // Para function
|
#include <functional> // Para function
|
||||||
@@ -89,10 +90,11 @@ Game::Game(int player_id, int current_stage, bool demo)
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Si se empieza en una fase que no es la primera
|
// Si se empieza en una fase que no es la primera
|
||||||
if (!demo_.enabled)
|
if (!demo_.enabled) {
|
||||||
for (int i = 0; i < Stage::number; ++i) {
|
for (int i = 0; i < Stage::number; ++i) {
|
||||||
Stage::total_power += Stage::get(i).power_to_complete;
|
Stage::total_power += Stage::get(i).power_to_complete;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +185,7 @@ void Game::updateHiScore() {
|
|||||||
hi_score_.name.clear();
|
hi_score_.name.clear();
|
||||||
|
|
||||||
// Si se supera la máxima puntuación emite sonido
|
// Si se supera la máxima puntuación emite sonido
|
||||||
if (hi_score_achieved_ == false) {
|
if (!hi_score_achieved_) {
|
||||||
hi_score_achieved_ = true;
|
hi_score_achieved_ = true;
|
||||||
playSound("hi_score_achieved.wav");
|
playSound("hi_score_achieved.wav");
|
||||||
}
|
}
|
||||||
@@ -298,7 +300,7 @@ void Game::updateGameStateGameOver() {
|
|||||||
|
|
||||||
if (fade_out_->isEnabled()) {
|
if (fade_out_->isEnabled()) {
|
||||||
if (Options::audio.enabled) {
|
if (Options::audio.enabled) {
|
||||||
const float VOL = static_cast<float>(64 * (100 - fade_out_->getValue())) / 100.0f;
|
const float VOL = static_cast<float>(64 * (100 - fade_out_->getValue())) / 100.0F;
|
||||||
Audio::get()->setSoundVolume(static_cast<int>(VOL), Audio::Group::GAME);
|
Audio::get()->setSoundVolume(static_cast<int>(VOL), Audio::Group::GAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,13 +354,14 @@ void Game::updateGameStateCompleted() {
|
|||||||
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("game_text_congratulations"));
|
createMessage({paths_.at(4), paths_.at(5)}, Resource::get()->getTexture("game_text_congratulations"));
|
||||||
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("game_text_1000000_points"));
|
createMessage({paths_.at(6), paths_.at(7)}, Resource::get()->getTexture("game_text_1000000_points"));
|
||||||
|
|
||||||
for (auto &player : players_)
|
for (auto &player : players_) {
|
||||||
if (player->isPlaying()) {
|
if (player->isPlaying()) {
|
||||||
player->addScore(1000000);
|
player->addScore(1000000);
|
||||||
player->setPlayingState(PlayerState::CELEBRATING);
|
player->setPlayingState(PlayerState::CELEBRATING);
|
||||||
} else {
|
} else {
|
||||||
player->setPlayingState(PlayerState::GAME_OVER);
|
player->setPlayingState(PlayerState::GAME_OVER);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateHiScore();
|
updateHiScore();
|
||||||
}
|
}
|
||||||
@@ -373,7 +376,7 @@ void Game::updateGameStateCompleted() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Si los jugadores ya no estan y no quedan mensajes en pantalla
|
// Si los jugadores ya no estan y no quedan mensajes en pantalla
|
||||||
if (allPlayersAreGameOver() && path_sprites_.size() == 0) {
|
if (allPlayersAreGameOver() && path_sprites_.empty()) {
|
||||||
setState(GameState::GAME_OVER);
|
setState(GameState::GAME_OVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,8 +397,9 @@ void Game::checkState() {
|
|||||||
|
|
||||||
// Destruye todos los items
|
// Destruye todos los items
|
||||||
void Game::destroyAllItems() {
|
void Game::destroyAllItems() {
|
||||||
for (auto &item : items_)
|
for (auto &item : items_) {
|
||||||
item->disable();
|
item->disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba la colisión entre el jugador y los globos activos
|
// Comprueba la colisión entre el jugador y los globos activos
|
||||||
@@ -413,8 +417,9 @@ auto Game::checkPlayerBalloonCollision(std::shared_ptr<Player> &player) -> std::
|
|||||||
|
|
||||||
// Comprueba la colisión entre el jugador y los items
|
// Comprueba la colisión entre el jugador y los items
|
||||||
void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player) {
|
void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player) {
|
||||||
if (!player->isPlaying())
|
if (!player->isPlaying()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &item : items_) {
|
for (auto &item : items_) {
|
||||||
if (item->isEnabled()) {
|
if (item->isEnabled()) {
|
||||||
@@ -491,7 +496,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player) {
|
|||||||
void Game::checkBulletCollision() {
|
void Game::checkBulletCollision() {
|
||||||
for (auto &bullet : bullets_) {
|
for (auto &bullet : bullets_) {
|
||||||
// Comprueba la colisión con el Tabe
|
// Comprueba la colisión con el Tabe
|
||||||
if (bullet->isEnabled() && tabe_->isEnabled())
|
if (bullet->isEnabled() && tabe_->isEnabled()) {
|
||||||
if (checkCollision(bullet->getCollider(), tabe_->getCollider())) {
|
if (checkCollision(bullet->getCollider(), tabe_->getCollider())) {
|
||||||
tabe_->setState(TabeState::HIT);
|
tabe_->setState(TabeState::HIT);
|
||||||
bullet->disable();
|
bullet->disable();
|
||||||
@@ -507,6 +512,7 @@ void Game::checkBulletCollision() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Comprueba la colisión con los globos
|
// Comprueba la colisión con los globos
|
||||||
for (auto &balloon : balloon_manager_->getBalloons()) {
|
for (auto &balloon : balloon_manager_->getBalloons()) {
|
||||||
@@ -558,8 +564,9 @@ void Game::updateBullets() {
|
|||||||
|
|
||||||
// Pinta las balas activas
|
// Pinta las balas activas
|
||||||
void Game::renderBullets() {
|
void Game::renderBullets() {
|
||||||
for (auto &bullet : bullets_)
|
for (auto &bullet : bullets_) {
|
||||||
bullet->render();
|
bullet->render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea un objeto bala
|
// Crea un objeto bala
|
||||||
@@ -569,15 +576,18 @@ void Game::createBullet(int x, int y, BulletType kind, bool powered_up, int owne
|
|||||||
|
|
||||||
// Vacia el vector de balas
|
// Vacia el vector de balas
|
||||||
void Game::freeBullets() {
|
void Game::freeBullets() {
|
||||||
if (!bullets_.empty())
|
if (!bullets_.empty()) {
|
||||||
for (int i = bullets_.size() - 1; i >= 0; --i)
|
for (int i = bullets_.size() - 1; i >= 0; --i) {
|
||||||
if (!bullets_[i]->isEnabled())
|
if (!bullets_[i]->isEnabled()) {
|
||||||
bullets_.erase(bullets_.begin() + i);
|
bullets_.erase(bullets_.begin() + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza los items
|
// Actualiza los items
|
||||||
void Game::updateItems() {
|
void Game::updateItems() {
|
||||||
for (auto &item : items_)
|
for (auto &item : items_) {
|
||||||
if (item->isEnabled()) {
|
if (item->isEnabled()) {
|
||||||
item->update();
|
item->update();
|
||||||
if (item->isOnFloor()) {
|
if (item->isOnFloor()) {
|
||||||
@@ -585,12 +595,14 @@ void Game::updateItems() {
|
|||||||
screen_->shake(1, 2, 4);
|
screen_->shake(1, 2, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pinta los items activos
|
// Pinta los items activos
|
||||||
void Game::renderItems() {
|
void Game::renderItems() {
|
||||||
for (auto &item : items_)
|
for (auto &item : items_) {
|
||||||
item->render();
|
item->render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Devuelve un item al azar y luego segun sus probabilidades
|
// Devuelve un item al azar y luego segun sus probabilidades
|
||||||
@@ -656,10 +668,13 @@ void Game::createItem(ItemType type, float x, float y) {
|
|||||||
|
|
||||||
// Vacia el vector de items
|
// Vacia el vector de items
|
||||||
void Game::freeItems() {
|
void Game::freeItems() {
|
||||||
if (!items_.empty())
|
if (!items_.empty()) {
|
||||||
for (int i = items_.size() - 1; i >= 0; --i)
|
for (int i = items_.size() - 1; i >= 0; --i) {
|
||||||
if (!items_[i]->isEnabled())
|
if (!items_[i]->isEnabled()) {
|
||||||
items_.erase(items_.begin() + i);
|
items_.erase(items_.begin() + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea un objeto PathSprite
|
// Crea un objeto PathSprite
|
||||||
@@ -698,18 +713,24 @@ void Game::createMessage(const std::vector<Path> &paths, std::shared_ptr<Texture
|
|||||||
|
|
||||||
// Vacia el vector de smartsprites
|
// Vacia el vector de smartsprites
|
||||||
void Game::freeSmartSprites() {
|
void Game::freeSmartSprites() {
|
||||||
if (!smart_sprites_.empty())
|
if (!smart_sprites_.empty()) {
|
||||||
for (int i = smart_sprites_.size() - 1; i >= 0; --i)
|
for (int i = smart_sprites_.size() - 1; i >= 0; --i) {
|
||||||
if (smart_sprites_[i]->hasFinished())
|
if (smart_sprites_[i]->hasFinished()) {
|
||||||
smart_sprites_.erase(smart_sprites_.begin() + i);
|
smart_sprites_.erase(smart_sprites_.begin() + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vacia el vector de pathsprites
|
// Vacia el vector de pathsprites
|
||||||
void Game::freePathSprites() {
|
void Game::freePathSprites() {
|
||||||
if (!path_sprites_.empty())
|
if (!path_sprites_.empty()) {
|
||||||
for (int i = path_sprites_.size() - 1; i >= 0; --i)
|
for (int i = path_sprites_.size() - 1; i >= 0; --i) {
|
||||||
if (path_sprites_[i]->hasFinished())
|
if (path_sprites_[i]->hasFinished()) {
|
||||||
path_sprites_.erase(path_sprites_.begin() + i);
|
path_sprites_.erase(path_sprites_.begin() + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crea un SpriteSmart para arrojar el item café al recibir un impacto
|
// Crea un SpriteSmart para arrojar el item café al recibir un impacto
|
||||||
@@ -720,10 +741,10 @@ void Game::throwCoffee(int x, int y) {
|
|||||||
smart_sprites_.back()->setPosY(y - 8);
|
smart_sprites_.back()->setPosY(y - 8);
|
||||||
smart_sprites_.back()->setWidth(param.game.item_size);
|
smart_sprites_.back()->setWidth(param.game.item_size);
|
||||||
smart_sprites_.back()->setHeight(param.game.item_size);
|
smart_sprites_.back()->setHeight(param.game.item_size);
|
||||||
smart_sprites_.back()->setVelX(-1.0f + ((rand() % 5) * 0.5f));
|
smart_sprites_.back()->setVelX(-1.0F + ((rand() % 5) * 0.5F));
|
||||||
smart_sprites_.back()->setVelY(-4.0f);
|
smart_sprites_.back()->setVelY(-4.0F);
|
||||||
smart_sprites_.back()->setAccelX(0.0f);
|
smart_sprites_.back()->setAccelX(0.0F);
|
||||||
smart_sprites_.back()->setAccelY(0.2f);
|
smart_sprites_.back()->setAccelY(0.2F);
|
||||||
smart_sprites_.back()->setDestX(x + (smart_sprites_.back()->getVelX() * 50));
|
smart_sprites_.back()->setDestX(x + (smart_sprites_.back()->getVelX() * 50));
|
||||||
smart_sprites_.back()->setDestY(param.game.height + 1);
|
smart_sprites_.back()->setDestY(param.game.height + 1);
|
||||||
smart_sprites_.back()->setEnabled(true);
|
smart_sprites_.back()->setEnabled(true);
|
||||||
@@ -864,14 +885,14 @@ void Game::updateBackground() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calcula la velocidad en función de los globos explotados y el total de globos a explotar para acabar el juego
|
// Calcula la velocidad en función de los globos explotados y el total de globos a explotar para acabar el juego
|
||||||
constexpr float CLOUDS_INITIAL_SPEED = 0.05f;
|
constexpr float CLOUDS_INITIAL_SPEED = 0.05F;
|
||||||
constexpr float CLOUDS_FINAL_SPEED = 2.00f - CLOUDS_INITIAL_SPEED;
|
constexpr float CLOUDS_FINAL_SPEED = 2.00F - CLOUDS_INITIAL_SPEED;
|
||||||
const float CLOUDS_SPEED = (-CLOUDS_INITIAL_SPEED) + (-CLOUDS_FINAL_SPEED * (static_cast<float>(Stage::total_power) / total_power_to_complete_game_));
|
const float CLOUDS_SPEED = (-CLOUDS_INITIAL_SPEED) + (-CLOUDS_FINAL_SPEED * (static_cast<float>(Stage::total_power) / total_power_to_complete_game_));
|
||||||
background_->setCloudsSpeed(CLOUDS_SPEED);
|
background_->setCloudsSpeed(CLOUDS_SPEED);
|
||||||
|
|
||||||
// Calcula la transición de los diferentes fondos
|
// Calcula la transición de los diferentes fondos
|
||||||
constexpr float NUM = 1525.0f; // total_power_to_complete div 4
|
constexpr float NUM = 1525.0F; // total_power_to_complete div 4
|
||||||
const float GRADIENT_NUMBER = std::min(Stage::total_power / NUM, 3.0f);
|
const float GRADIENT_NUMBER = std::min(Stage::total_power / NUM, 3.0F);
|
||||||
const float PERCENT = GRADIENT_NUMBER - static_cast<int>(GRADIENT_NUMBER);
|
const float PERCENT = GRADIENT_NUMBER - static_cast<int>(GRADIENT_NUMBER);
|
||||||
background_->setGradientNumber(static_cast<int>(GRADIENT_NUMBER));
|
background_->setGradientNumber(static_cast<int>(GRADIENT_NUMBER));
|
||||||
background_->setTransition(PERCENT);
|
background_->setTransition(PERCENT);
|
||||||
@@ -888,7 +909,7 @@ void Game::updateBackground() {
|
|||||||
// Dibuja los elementos de la zona de juego en su textura
|
// Dibuja los elementos de la zona de juego en su textura
|
||||||
void Game::fillCanvas() {
|
void Game::fillCanvas() {
|
||||||
// Dibujamos el contenido de la zona de juego en su textura
|
// Dibujamos el contenido de la zona de juego en su textura
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, canvas_);
|
SDL_SetRenderTarget(renderer_, canvas_);
|
||||||
|
|
||||||
// Dibuja los objetos
|
// Dibuja los objetos
|
||||||
@@ -1023,8 +1044,9 @@ void Game::updateHelper() {
|
|||||||
// Comprueba si todos los jugadores han terminado de jugar
|
// Comprueba si todos los jugadores han terminado de jugar
|
||||||
auto Game::allPlayersAreWaitingOrGameOver() -> bool {
|
auto Game::allPlayersAreWaitingOrGameOver() -> bool {
|
||||||
auto success = true;
|
auto success = true;
|
||||||
for (const auto &player : players_)
|
for (const auto &player : players_) {
|
||||||
success &= player->isWaiting() || player->isGameOver();
|
success &= player->isWaiting() || player->isGameOver();
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@@ -1032,8 +1054,9 @@ auto Game::allPlayersAreWaitingOrGameOver() -> bool {
|
|||||||
// Comprueba si todos los jugadores han terminado de jugar
|
// Comprueba si todos los jugadores han terminado de jugar
|
||||||
auto Game::allPlayersAreGameOver() -> bool {
|
auto Game::allPlayersAreGameOver() -> bool {
|
||||||
auto success = true;
|
auto success = true;
|
||||||
for (const auto &player : players_)
|
for (const auto &player : players_) {
|
||||||
success &= player->isGameOver();
|
success &= player->isGameOver();
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@@ -1041,8 +1064,9 @@ auto Game::allPlayersAreGameOver() -> bool {
|
|||||||
// Comprueba si todos los jugadores han terminado de jugar
|
// Comprueba si todos los jugadores han terminado de jugar
|
||||||
auto Game::allPlayersAreNotPlaying() -> bool {
|
auto Game::allPlayersAreNotPlaying() -> bool {
|
||||||
auto success = true;
|
auto success = true;
|
||||||
for (const auto &player : players_)
|
for (const auto &player : players_) {
|
||||||
success &= !player->isPlaying();
|
success &= !player->isPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@@ -1189,7 +1213,7 @@ void Game::checkPauseInput() {
|
|||||||
|
|
||||||
// Gestiona las entradas de los jugadores en el modo demo para saltarse la demo.
|
// Gestiona las entradas de los jugadores en el modo demo para saltarse la demo.
|
||||||
void Game::demoHandlePassInput() {
|
void Game::demoHandlePassInput() {
|
||||||
if (input_->checkAnyButton()) {
|
if (input_->checkAnyButton() != 0) {
|
||||||
Section::name = Section::Name::TITLE; // Salir del modo demo y regresar al menú principal.
|
Section::name = Section::Name::TITLE; // Salir del modo demo y regresar al menú principal.
|
||||||
Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO; // El juego volverá a mostrar la demo
|
Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO; // El juego volverá a mostrar la demo
|
||||||
return;
|
return;
|
||||||
@@ -1404,7 +1428,7 @@ void Game::initDemo(int player_id) {
|
|||||||
{
|
{
|
||||||
constexpr auto NUM_DEMOS = 3;
|
constexpr auto NUM_DEMOS = 3;
|
||||||
const auto DEMO = rand() % NUM_DEMOS;
|
const auto DEMO = rand() % NUM_DEMOS;
|
||||||
const int STAGES[NUM_DEMOS] = {0, 3, 5};
|
constexpr std::array<int, NUM_DEMOS> STAGES = {0, 3, 5};
|
||||||
Stage::number = STAGES[DEMO];
|
Stage::number = STAGES[DEMO];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1422,8 +1446,9 @@ void Game::initDemo(int player_id) {
|
|||||||
|
|
||||||
// Asigna cafes a los jugadores
|
// Asigna cafes a los jugadores
|
||||||
for (auto &player : players_) {
|
for (auto &player : players_) {
|
||||||
for (int i = 0; i < rand() % 3; ++i)
|
for (int i = 0; i < rand() % 3; ++i) {
|
||||||
player->giveExtraHit();
|
player->giveExtraHit();
|
||||||
|
}
|
||||||
|
|
||||||
player->setInvulnerable(true);
|
player->setInvulnerable(true);
|
||||||
}
|
}
|
||||||
@@ -1471,21 +1496,21 @@ void Game::initDifficultyVars() {
|
|||||||
switch (difficulty_) {
|
switch (difficulty_) {
|
||||||
case Options::DifficultyCode::EASY: {
|
case Options::DifficultyCode::EASY: {
|
||||||
balloon_manager_->setDefaultBalloonSpeed(BALLOON_SPEED[0]);
|
balloon_manager_->setDefaultBalloonSpeed(BALLOON_SPEED[0]);
|
||||||
difficulty_score_multiplier_ = 0.5f;
|
difficulty_score_multiplier_ = 0.5F;
|
||||||
scoreboard_->setColor(param.scoreboard.easy_color);
|
scoreboard_->setColor(param.scoreboard.easy_color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Options::DifficultyCode::NORMAL: {
|
case Options::DifficultyCode::NORMAL: {
|
||||||
balloon_manager_->setDefaultBalloonSpeed(BALLOON_SPEED[0]);
|
balloon_manager_->setDefaultBalloonSpeed(BALLOON_SPEED[0]);
|
||||||
difficulty_score_multiplier_ = 1.0f;
|
difficulty_score_multiplier_ = 1.0F;
|
||||||
scoreboard_->setColor(param.scoreboard.normal_color);
|
scoreboard_->setColor(param.scoreboard.normal_color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Options::DifficultyCode::HARD: {
|
case Options::DifficultyCode::HARD: {
|
||||||
balloon_manager_->setDefaultBalloonSpeed(BALLOON_SPEED[4]);
|
balloon_manager_->setDefaultBalloonSpeed(BALLOON_SPEED[4]);
|
||||||
difficulty_score_multiplier_ = 1.5f;
|
difficulty_score_multiplier_ = 1.5F;
|
||||||
scoreboard_->setColor(param.scoreboard.hard_color);
|
scoreboard_->setColor(param.scoreboard.hard_color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1529,7 +1554,7 @@ void Game::playMusic() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Detiene la música
|
// Detiene la música
|
||||||
void Game::stopMusic() {
|
void Game::stopMusic() const {
|
||||||
if (!demo_.enabled) {
|
if (!demo_.enabled) {
|
||||||
Audio::get()->stopMusic();
|
Audio::get()->stopMusic();
|
||||||
}
|
}
|
||||||
@@ -1538,7 +1563,7 @@ void Game::stopMusic() {
|
|||||||
// Actualiza las variables durante el modo demo
|
// Actualiza las variables durante el modo demo
|
||||||
void Game::updateDemo() {
|
void Game::updateDemo() {
|
||||||
if (demo_.enabled) {
|
if (demo_.enabled) {
|
||||||
balloon_manager_->setCreationTimeEnabled((balloon_manager_->getNumBalloons() == 0) ? false : true);
|
balloon_manager_->setCreationTimeEnabled(balloon_manager_->getNumBalloons() != 0);
|
||||||
|
|
||||||
// Actualiza ambos fades
|
// Actualiza ambos fades
|
||||||
fade_in_->update();
|
fade_in_->update();
|
||||||
@@ -1617,7 +1642,7 @@ void Game::updateGameStateShowingGetReadyMessage() {
|
|||||||
updateScoreboard();
|
updateScoreboard();
|
||||||
updateBackground();
|
updateBackground();
|
||||||
freePathSprites();
|
freePathSprites();
|
||||||
if (path_sprites_.size() == 0) {
|
if (path_sprites_.empty()) {
|
||||||
setState(GameState::PLAYING);
|
setState(GameState::PLAYING);
|
||||||
}
|
}
|
||||||
if (counter_ == 100) {
|
if (counter_ == 100) {
|
||||||
@@ -1691,11 +1716,12 @@ void Game::evaluateAndSetMenace() {
|
|||||||
|
|
||||||
// Actualiza la velocidad de los globos en funcion del poder acumulado de la fase
|
// Actualiza la velocidad de los globos en funcion del poder acumulado de la fase
|
||||||
void Game::checkAndUpdateBalloonSpeed() {
|
void Game::checkAndUpdateBalloonSpeed() {
|
||||||
if (difficulty_ != Options::DifficultyCode::NORMAL)
|
if (difficulty_ != Options::DifficultyCode::NORMAL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const float PERCENT = static_cast<float>(Stage::power) / Stage::get(Stage::number).power_to_complete;
|
const float PERCENT = static_cast<float>(Stage::power) / Stage::get(Stage::number).power_to_complete;
|
||||||
const float THRESHOLDS[] = {0.2f, 0.4f, 0.6f, 0.8f};
|
constexpr std::array<float, 4> THRESHOLDS = {0.2F, 0.4F, 0.6F, 0.8F};
|
||||||
|
|
||||||
for (size_t i = 0; i < std::size(THRESHOLDS); ++i) {
|
for (size_t i = 0; i < std::size(THRESHOLDS); ++i) {
|
||||||
if (balloon_manager_->getBalloonSpeed() == BALLOON_SPEED[i] && PERCENT > THRESHOLDS[i]) {
|
if (balloon_manager_->getBalloonSpeed() == BALLOON_SPEED[i] && PERCENT > THRESHOLDS[i]) {
|
||||||
@@ -1711,18 +1737,20 @@ void Game::setState(GameState state) {
|
|||||||
counter_ = 0;
|
counter_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::playSound(const std::string &name) {
|
void Game::playSound(const std::string &name) const {
|
||||||
if (demo_.enabled)
|
if (demo_.enabled) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static auto audio_ = Audio::get();
|
static auto *audio_ = Audio::get();
|
||||||
audio_->playSound(name);
|
audio_->playSound(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Organiza los jugadores para que los vivos se pinten sobre los muertos
|
// Organiza los jugadores para que los vivos se pinten sobre los muertos
|
||||||
void Game::movePlayersToFront() {
|
void Game::movePlayersToFront() {
|
||||||
if (players_to_reorder_.empty())
|
if (players_to_reorder_.empty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &player : players_to_reorder_) {
|
for (auto &player : players_to_reorder_) {
|
||||||
auto it = std::find(players_.begin(), players_.end(), player);
|
auto it = std::find(players_.begin(), players_.end(), player);
|
||||||
@@ -1737,8 +1765,9 @@ void Game::movePlayersToFront() {
|
|||||||
|
|
||||||
// Comprueba si está activo el menu de servicio para poner el juego en pausa
|
// Comprueba si está activo el menu de servicio para poner el juego en pausa
|
||||||
void Game::checkServiceMenu() {
|
void Game::checkServiceMenu() {
|
||||||
if (demo_.enabled)
|
if (demo_.enabled) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static bool was_paused_before_service_menu_ = false;
|
static bool was_paused_before_service_menu_ = false;
|
||||||
static bool service_menu_was_active_ = false;
|
static bool service_menu_was_active_ = false;
|
||||||
@@ -1760,7 +1789,7 @@ void Game::checkServiceMenu() {
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Comprueba los eventos en el modo DEBUG
|
// Comprueba los eventos en el modo DEBUG
|
||||||
void Game::checkDebugEvents(const SDL_Event &event) {
|
void Game::checkDebugEvents(const SDL_Event &event) {
|
||||||
if (event.type == SDL_EVENT_KEY_DOWN && event.key.repeat == 0) {
|
if (event.type == SDL_EVENT_KEY_DOWN && static_cast<int>(event.key.repeat) == 0) {
|
||||||
switch (event.key.key) {
|
switch (event.key.key) {
|
||||||
case SDLK_1: // Crea una powerball
|
case SDLK_1: // Crea una powerball
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ class Game {
|
|||||||
void checkAndUpdatePlayerStatus(int active_player_index, int inactive_player_index); // Saca del estado de GAME OVER al jugador si el otro está activo
|
void checkAndUpdatePlayerStatus(int active_player_index, int inactive_player_index); // Saca del estado de GAME OVER al jugador si el otro está activo
|
||||||
void checkPlayersStatusPlaying(); // Comprueba el estado de juego de los jugadores
|
void checkPlayersStatusPlaying(); // Comprueba el estado de juego de los jugadores
|
||||||
auto getPlayer(int id) -> std::shared_ptr<Player>; // Obtiene un jugador a partir de su "id"
|
auto getPlayer(int id) -> std::shared_ptr<Player>; // Obtiene un jugador a partir de su "id"
|
||||||
auto getController(int player_id) -> int; // Obtiene un controlador a partir del "id" del jugador
|
static auto getController(int player_id) -> int; // Obtiene un controlador a partir del "id" del jugador
|
||||||
void checkInput(); // Gestiona la entrada durante el juego
|
void checkInput(); // Gestiona la entrada durante el juego
|
||||||
void checkPauseInput(); // Verifica si alguno de los controladores ha solicitado una pausa y actualiza el estado de pausa del juego.
|
void checkPauseInput(); // Verifica si alguno de los controladores ha solicitado una pausa y actualiza el estado de pausa del juego.
|
||||||
void demoHandleInput(); // Gestiona las entradas de los jugadores en el modo demo, incluyendo movimientos y disparos automáticos.
|
void demoHandleInput(); // Gestiona las entradas de los jugadores en el modo demo, incluyendo movimientos y disparos automáticos.
|
||||||
@@ -222,9 +222,9 @@ class Game {
|
|||||||
void initScoreboard(); // Inicializa el marcador
|
void initScoreboard(); // Inicializa el marcador
|
||||||
void initDifficultyVars(); // Inicializa las opciones relacionadas con la dificultad
|
void initDifficultyVars(); // Inicializa las opciones relacionadas con la dificultad
|
||||||
void initPlayers(int player_id); // Inicializa los jugadores
|
void initPlayers(int player_id); // Inicializa los jugadores
|
||||||
void playMusic(); // Hace sonar la música
|
static void playMusic(); // Hace sonar la música
|
||||||
void stopMusic(); // Detiene la música
|
void stopMusic() const; // Detiene la música
|
||||||
void playSound(const std::string &name); // Hace sonar un sonido
|
void playSound(const std::string &name) const; // Hace sonar un sonido
|
||||||
void updateDemo(); // Actualiza las variables durante el modo demo
|
void updateDemo(); // Actualiza las variables durante el modo demo
|
||||||
void updateGameStateFadeIn(); // Actualiza las variables durante dicho estado
|
void updateGameStateFadeIn(); // Actualiza las variables durante dicho estado
|
||||||
void updateGameStateEnteringPlayer(); // Actualiza las variables durante dicho estado
|
void updateGameStateEnteringPlayer(); // Actualiza las variables durante dicho estado
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ HiScoreTable::HiScoreTable()
|
|||||||
background_(std::make_unique<Background>()),
|
background_(std::make_unique<Background>()),
|
||||||
|
|
||||||
ticks_(0),
|
ticks_(0),
|
||||||
view_area_(SDL_FRect{0, 0, static_cast<float>(param.game.width), static_cast<float>(param.game.height)}),
|
view_area_(SDL_FRect{0, 0, param.game.width, param.game.height}),
|
||||||
fade_mode_(FadeMode::IN),
|
fade_mode_(FadeMode::IN),
|
||||||
background_fade_color_(Color(0, 0, 0)) {
|
background_fade_color_(Color(0, 0, 0)) {
|
||||||
// Inicializa el resto
|
// Inicializa el resto
|
||||||
@@ -83,7 +83,7 @@ void HiScoreTable::update() {
|
|||||||
// Dibuja los sprites en la textura
|
// Dibuja los sprites en la textura
|
||||||
void HiScoreTable::fillTexture() {
|
void HiScoreTable::fillTexture() {
|
||||||
// Pinta en el backbuffer el texto y los sprites
|
// Pinta en el backbuffer el texto y los sprites
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
SDL_SetRenderTarget(renderer_, backbuffer_);
|
||||||
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
||||||
SDL_RenderClear(renderer_);
|
SDL_RenderClear(renderer_);
|
||||||
@@ -112,7 +112,7 @@ void HiScoreTable::render() {
|
|||||||
background_->render();
|
background_->render();
|
||||||
|
|
||||||
// Establece la ventana del backbuffer
|
// Establece la ventana del backbuffer
|
||||||
view_area_.y = std::max(0.0f, param.game.height - counter_ + 100);
|
view_area_.y = std::max(0.0F, param.game.height - counter_ + 100);
|
||||||
|
|
||||||
// Copia el backbuffer al renderizador
|
// Copia el backbuffer al renderizador
|
||||||
SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_area_);
|
SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_area_);
|
||||||
@@ -218,7 +218,7 @@ void HiScoreTable::createSprites() {
|
|||||||
const auto TABLE_POSITION = format(i + 1) + ". ";
|
const auto TABLE_POSITION = format(i + 1) + ". ";
|
||||||
const auto SCORE = format(Options::settings.hi_score_table.at(i).score);
|
const auto SCORE = format(Options::settings.hi_score_table.at(i).score);
|
||||||
const auto NUM_DOTS = ENTRY_LENGHT - Options::settings.hi_score_table.at(i).name.size() - SCORE.size();
|
const auto NUM_DOTS = ENTRY_LENGHT - Options::settings.hi_score_table.at(i).name.size() - SCORE.size();
|
||||||
const auto ONE_CC = Options::settings.hi_score_table.at(i).one_credit_complete ? " }" : "";
|
const auto *const ONE_CC = Options::settings.hi_score_table.at(i).one_credit_complete ? " }" : "";
|
||||||
std::string dots;
|
std::string dots;
|
||||||
for (int j = 0; j < (int)NUM_DOTS; ++j) {
|
for (int j = 0; j < (int)NUM_DOTS; ++j) {
|
||||||
dots = dots + ".";
|
dots = dots + ".";
|
||||||
@@ -301,16 +301,16 @@ void HiScoreTable::initFade() {
|
|||||||
// Inicializa el fondo
|
// Inicializa el fondo
|
||||||
void HiScoreTable::initBackground() {
|
void HiScoreTable::initBackground() {
|
||||||
background_->setPos(param.game.game_area.rect);
|
background_->setPos(param.game.game_area.rect);
|
||||||
background_->setCloudsSpeed(-0.1f);
|
background_->setCloudsSpeed(-0.1F);
|
||||||
|
|
||||||
const int LUCKY = rand() % 3;
|
const int LUCKY = rand() % 3;
|
||||||
switch (LUCKY) {
|
switch (LUCKY) {
|
||||||
case 0: // Fondo verde
|
case 0: // Fondo verde
|
||||||
{
|
{
|
||||||
background_->setGradientNumber(2);
|
background_->setGradientNumber(2);
|
||||||
background_->setTransition(0.0f);
|
background_->setTransition(0.0F);
|
||||||
background_->setSunProgression(1.0f);
|
background_->setSunProgression(1.0F);
|
||||||
background_->setMoonProgression(0.0f);
|
background_->setMoonProgression(0.0F);
|
||||||
background_fade_color_ = GREEN_SKY_COLOR;
|
background_fade_color_ = GREEN_SKY_COLOR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -318,9 +318,9 @@ void HiScoreTable::initBackground() {
|
|||||||
case 1: // Fondo naranja
|
case 1: // Fondo naranja
|
||||||
{
|
{
|
||||||
background_->setGradientNumber(1);
|
background_->setGradientNumber(1);
|
||||||
background_->setTransition(0.0f);
|
background_->setTransition(0.0F);
|
||||||
background_->setSunProgression(0.65f);
|
background_->setSunProgression(0.65F);
|
||||||
background_->setMoonProgression(0.0f);
|
background_->setMoonProgression(0.0F);
|
||||||
background_fade_color_ = PINK_SKY_COLOR;
|
background_fade_color_ = PINK_SKY_COLOR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -328,9 +328,9 @@ void HiScoreTable::initBackground() {
|
|||||||
case 2: // Fondo azul
|
case 2: // Fondo azul
|
||||||
{
|
{
|
||||||
background_->setGradientNumber(0);
|
background_->setGradientNumber(0);
|
||||||
background_->setTransition(0.0f);
|
background_->setTransition(0.0F);
|
||||||
background_->setSunProgression(0.0f);
|
background_->setSunProgression(0.0F);
|
||||||
background_->setMoonProgression(0.0f);
|
background_->setMoonProgression(0.0F);
|
||||||
background_fade_color_ = BLUE_SKY_COLOR;
|
background_fade_color_ = BLUE_SKY_COLOR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ class HiScoreTable {
|
|||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void update(); // Actualiza las variables
|
void update(); // Actualiza las variables
|
||||||
void render(); // Pinta en pantalla
|
void render(); // Pinta en pantalla
|
||||||
void checkEvents(); // Comprueba los eventos
|
static void checkEvents(); // Comprueba los eventos
|
||||||
void checkInput(); // Comprueba las entradas
|
static void checkInput(); // Comprueba las entradas
|
||||||
auto format(int number) -> std::string; // Convierte un entero a un string con separadores de miles
|
static auto format(int number) -> std::string; // Convierte un entero a un string con separadores de miles
|
||||||
void fillTexture(); // Dibuja los sprites en la textura
|
void fillTexture(); // Dibuja los sprites en la textura
|
||||||
void updateFade(); // Gestiona el fade
|
void updateFade(); // Gestiona el fade
|
||||||
void createSprites(); // Crea los sprites con los textos
|
void createSprites(); // Crea los sprites con los textos
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ void Instructions::fillTexture() {
|
|||||||
const int DESP_X = param.game.item_size + 8;
|
const int DESP_X = param.game.item_size + 8;
|
||||||
|
|
||||||
// Modifica el renderizador para pintar en la textura
|
// Modifica el renderizador para pintar en la textura
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, texture_);
|
SDL_SetRenderTarget(renderer_, texture_);
|
||||||
|
|
||||||
// Limpia la textura
|
// Limpia la textura
|
||||||
@@ -128,9 +128,9 @@ void Instructions::fillTexture() {
|
|||||||
|
|
||||||
constexpr int SPACE_POST_HEADER = 20;
|
constexpr int SPACE_POST_HEADER = 20;
|
||||||
constexpr int SPACE_PRE_HEADER = 28;
|
constexpr int SPACE_PRE_HEADER = 28;
|
||||||
const int SPACE_BETWEEN_LINES = text_->getCharacterSize() * 1.5f;
|
const int SPACE_BETWEEN_LINES = text_->getCharacterSize() * 1.5F;
|
||||||
const int SPACE_BETWEEN_ITEM_LINES = param.game.item_size + item_space_;
|
const int SPACE_BETWEEN_ITEM_LINES = param.game.item_size + item_space_;
|
||||||
const int SPACE_NEW_PARAGRAPH = SPACE_BETWEEN_LINES * 0.5f;
|
const int SPACE_NEW_PARAGRAPH = SPACE_BETWEEN_LINES * 0.5F;
|
||||||
|
|
||||||
const int SIZE = (NUM_LINES * SPACE_BETWEEN_LINES) + (NUM_ITEM_LINES * SPACE_BETWEEN_ITEM_LINES) + (NUM_POST_HEADERS * SPACE_POST_HEADER) + (NUM_PRE_HEADERS * SPACE_PRE_HEADER) + (SPACE_NEW_PARAGRAPH);
|
const int SIZE = (NUM_LINES * SPACE_BETWEEN_LINES) + (NUM_ITEM_LINES * SPACE_BETWEEN_ITEM_LINES) + (NUM_POST_HEADERS * SPACE_POST_HEADER) + (NUM_PRE_HEADERS * SPACE_PRE_HEADER) + (SPACE_NEW_PARAGRAPH);
|
||||||
const int FIRST_LINE = (param.game.height - SIZE) / 2;
|
const int FIRST_LINE = (param.game.height - SIZE) / 2;
|
||||||
@@ -182,7 +182,7 @@ void Instructions::fillTexture() {
|
|||||||
// Rellena el backbuffer
|
// Rellena el backbuffer
|
||||||
void Instructions::fillBackbuffer() {
|
void Instructions::fillBackbuffer() {
|
||||||
// Modifica el renderizador para pintar en la textura
|
// Modifica el renderizador para pintar en la textura
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, backbuffer_);
|
SDL_SetRenderTarget(renderer_, backbuffer_);
|
||||||
|
|
||||||
// Limpia la textura
|
// Limpia la textura
|
||||||
@@ -242,10 +242,11 @@ void Instructions::render() {
|
|||||||
tiled_bg_->render();
|
tiled_bg_->render();
|
||||||
|
|
||||||
// Copia la textura y el backbuffer al renderizador
|
// Copia la textura y el backbuffer al renderizador
|
||||||
if (view_.y == 0)
|
if (view_.y == 0) {
|
||||||
renderLines(renderer_, backbuffer_, lines_);
|
renderLines(renderer_, backbuffer_, lines_);
|
||||||
else
|
} else {
|
||||||
SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_);
|
SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_);
|
||||||
|
}
|
||||||
|
|
||||||
fade_->render();
|
fade_->render();
|
||||||
|
|
||||||
@@ -283,7 +284,7 @@ auto Instructions::initializeLines(int height) -> std::vector<Line> {
|
|||||||
std::vector<Line> lines;
|
std::vector<Line> lines;
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
int direction = (y % 2 == 0) ? -1 : 1; // Pares a la izquierda, impares a la derecha
|
int direction = (y % 2 == 0) ? -1 : 1; // Pares a la izquierda, impares a la derecha
|
||||||
lines.emplace_back(y, 0.0f, direction);
|
lines.emplace_back(y, 0.0F, direction);
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
@@ -299,7 +300,7 @@ auto Instructions::moveLines(std::vector<Line> &lines, int width, float duration
|
|||||||
line.start_time = current_time + line.y * start_delay;
|
line.start_time = current_time + line.y * start_delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
float elapsed_time = (current_time - line.start_time) / 1000.0f; // Convertir a segundos
|
float elapsed_time = (current_time - line.start_time) / 1000.0F; // Convertir a segundos
|
||||||
if (elapsed_time < 0) {
|
if (elapsed_time < 0) {
|
||||||
all_lines_off_screen = false; // Si aún no se debe mover esta línea, no están todas fuera de pantalla
|
all_lines_off_screen = false; // Si aún no se debe mover esta línea, no están todas fuera de pantalla
|
||||||
continue;
|
continue;
|
||||||
@@ -329,7 +330,7 @@ void Instructions::renderLines(SDL_Renderer *renderer, SDL_Texture *texture, con
|
|||||||
// Gestiona la textura con los graficos
|
// Gestiona la textura con los graficos
|
||||||
void Instructions::updateBackbuffer() {
|
void Instructions::updateBackbuffer() {
|
||||||
// Establece la ventana del backbuffer
|
// Establece la ventana del backbuffer
|
||||||
view_.y = std::max(0.0f, param.game.height - counter_ + 100);
|
view_.y = std::max(0.0F, param.game.height - counter_ + 100);
|
||||||
|
|
||||||
// Verifica si view_.y == 0 y gestiona el temporizador
|
// Verifica si view_.y == 0 y gestiona el temporizador
|
||||||
if (view_.y == 0) {
|
if (view_.y == 0) {
|
||||||
@@ -339,7 +340,7 @@ void Instructions::updateBackbuffer() {
|
|||||||
start_delay_time_ = SDL_GetTicks();
|
start_delay_time_ = SDL_GetTicks();
|
||||||
} else if (SDL_GetTicks() - start_delay_time_ >= 4000) {
|
} else if (SDL_GetTicks() - start_delay_time_ >= 4000) {
|
||||||
// Han pasado tres segundos, mover líneas
|
// Han pasado tres segundos, mover líneas
|
||||||
all_lines_off_screen_ = moveLines(lines_, 320, 1.0f, 5);
|
all_lines_off_screen_ = moveLines(lines_, 320, 1.0F, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,14 +74,14 @@ class Instructions {
|
|||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void update(); // Actualiza las variables
|
void update(); // Actualiza las variables
|
||||||
void render(); // Pinta en pantalla
|
void render(); // Pinta en pantalla
|
||||||
void checkEvents(); // Comprueba los eventos
|
static void checkEvents(); // Comprueba los eventos
|
||||||
void checkInput(); // Comprueba las entradas
|
static void checkInput(); // Comprueba las entradas
|
||||||
void fillTexture(); // Rellena la textura de texto
|
void fillTexture(); // Rellena la textura de texto
|
||||||
void fillBackbuffer(); // Rellena el backbuffer
|
void fillBackbuffer(); // Rellena el backbuffer
|
||||||
void iniSprites(); // Inicializa los sprites de los items
|
void iniSprites(); // Inicializa los sprites de los items
|
||||||
void updateSprites(); // Actualiza los sprites
|
void updateSprites(); // Actualiza los sprites
|
||||||
auto initializeLines(int height) -> std::vector<Line>; // Inicializa las líneas animadas
|
static auto initializeLines(int height) -> std::vector<Line>; // Inicializa las líneas animadas
|
||||||
auto moveLines(std::vector<Line> &lines, int width, float duration, Uint32 start_delay) -> bool; // Mueve las líneas
|
static auto moveLines(std::vector<Line> &lines, int width, float duration, Uint32 start_delay) -> bool; // Mueve las líneas
|
||||||
void renderLines(SDL_Renderer *renderer, SDL_Texture *texture, const std::vector<Line> &lines); // Renderiza las líneas
|
static void renderLines(SDL_Renderer *renderer, SDL_Texture *texture, const std::vector<Line> &lines); // Renderiza las líneas
|
||||||
void updateBackbuffer(); // Gestiona la textura con los gráficos
|
void updateBackbuffer(); // Gestiona la textura con los gráficos
|
||||||
};
|
};
|
||||||
@@ -42,7 +42,7 @@ Intro::Intro()
|
|||||||
initTexts();
|
initTexts();
|
||||||
|
|
||||||
// Configura el fondo
|
// Configura el fondo
|
||||||
tiled_bg_->setSpeed(0.3f);
|
tiled_bg_->setSpeed(0.3F);
|
||||||
tiled_bg_->setColor(bg_color_);
|
tiled_bg_->setColor(bg_color_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,55 +51,67 @@ void Intro::checkEvents() {
|
|||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (event.type == SDL_EVENT_KEY_DOWN && event.key.repeat == 1) {
|
if (event.type == SDL_EVENT_KEY_DOWN && static_cast<int>(event.key.repeat) == 1) {
|
||||||
static Color color_ = param.intro.bg_color;
|
static Color color_ = param.intro.bg_color;
|
||||||
switch (event.key.key) {
|
switch (event.key.key) {
|
||||||
case SDLK_A:
|
case SDLK_A:
|
||||||
if (color_.r < 255)
|
if (color_.r < 255) {
|
||||||
++color_.r;
|
++color_.r;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_Z:
|
case SDLK_Z:
|
||||||
if (color_.r > 0)
|
if (color_.r > 0) {
|
||||||
--color_.r;
|
--color_.r;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_S:
|
case SDLK_S:
|
||||||
if (color_.g < 255)
|
if (color_.g < 255) {
|
||||||
++color_.g;
|
++color_.g;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_X:
|
case SDLK_X:
|
||||||
if (color_.g > 0)
|
if (color_.g > 0) {
|
||||||
--color_.g;
|
--color_.g;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_D:
|
case SDLK_D:
|
||||||
if (color_.b < 255)
|
if (color_.b < 255) {
|
||||||
++color_.b;
|
++color_.b;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_C:
|
case SDLK_C:
|
||||||
if (color_.b > 0)
|
if (color_.b > 0) {
|
||||||
--color_.b;
|
--color_.b;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_F:
|
case SDLK_F:
|
||||||
if (color_.r < 255)
|
if (color_.r < 255) {
|
||||||
++color_.r;
|
++color_.r;
|
||||||
if (color_.g < 255)
|
}
|
||||||
|
if (color_.g < 255) {
|
||||||
++color_.g;
|
++color_.g;
|
||||||
if (color_.b < 255)
|
}
|
||||||
|
if (color_.b < 255) {
|
||||||
++color_.b;
|
++color_.b;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_V:
|
case SDLK_V:
|
||||||
if (color_.r > 0)
|
if (color_.r > 0) {
|
||||||
--color_.r;
|
--color_.r;
|
||||||
if (color_.g > 0)
|
}
|
||||||
|
if (color_.g > 0) {
|
||||||
--color_.g;
|
--color_.g;
|
||||||
if (color_.b > 0)
|
}
|
||||||
|
if (color_.b > 0) {
|
||||||
--color_.b;
|
--color_.b;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -335,7 +347,7 @@ void Intro::initSprites() {
|
|||||||
|
|
||||||
// Constantes
|
// Constantes
|
||||||
constexpr int TOTAL_SPRITES = TEXTURE_LIST.size();
|
constexpr int TOTAL_SPRITES = TEXTURE_LIST.size();
|
||||||
const float BORDER = 2.0f;
|
const float BORDER = 2.0F;
|
||||||
|
|
||||||
auto texture = Resource::get()->getTexture(TEXTURE_LIST.front());
|
auto texture = Resource::get()->getTexture(TEXTURE_LIST.front());
|
||||||
const float CARD_WIDTH = texture->getWidth() + (BORDER * 2);
|
const float CARD_WIDTH = texture->getWidth() + (BORDER * 2);
|
||||||
@@ -351,7 +363,7 @@ void Intro::initSprites() {
|
|||||||
card_texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
card_texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
// Apuntamos el renderizador a la textura
|
// Apuntamos el renderizador a la textura
|
||||||
auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
auto *temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
||||||
card_texture->setAsRenderTarget(Screen::get()->getRenderer());
|
card_texture->setAsRenderTarget(Screen::get()->getRenderer());
|
||||||
|
|
||||||
// Limpia la textura
|
// Limpia la textura
|
||||||
@@ -406,7 +418,7 @@ void Intro::initSprites() {
|
|||||||
shadow_texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
shadow_texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
// Apuntamos el renderizador a la textura
|
// Apuntamos el renderizador a la textura
|
||||||
auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
auto *temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
||||||
shadow_texture->setAsRenderTarget(Screen::get()->getRenderer());
|
shadow_texture->setAsRenderTarget(Screen::get()->getRenderer());
|
||||||
|
|
||||||
// Limpia la textura
|
// Limpia la textura
|
||||||
@@ -572,7 +584,7 @@ void Intro::updatePostState() {
|
|||||||
|
|
||||||
void Intro::renderTextRect() {
|
void Intro::renderTextRect() {
|
||||||
static const float HEIGHT = Resource::get()->getText("04b_25_metal")->getCharacterSize();
|
static const float HEIGHT = Resource::get()->getText("04b_25_metal")->getCharacterSize();
|
||||||
static SDL_FRect rect_ = {0.0f, param.game.height - param.intro.text_distance_from_bottom - HEIGHT, param.game.width, HEIGHT * 3};
|
static SDL_FRect rect_ = {0.0F, param.game.height - param.intro.text_distance_from_bottom - HEIGHT, param.game.width, HEIGHT * 3};
|
||||||
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), param.intro.shadow_color.r, param.intro.shadow_color.g, param.intro.shadow_color.b, param.intro.shadow_color.a);
|
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), param.intro.shadow_color.r, param.intro.shadow_color.g, param.intro.shadow_color.b, param.intro.shadow_color.a);
|
||||||
SDL_RenderFillRect(Screen::get()->getRenderer(), &rect_);
|
SDL_RenderFillRect(Screen::get()->getRenderer(), &rect_);
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ class Intro {
|
|||||||
void update(); // Actualiza las variables del objeto
|
void update(); // Actualiza las variables del objeto
|
||||||
void render(); // Dibuja el objeto en pantalla
|
void render(); // Dibuja el objeto en pantalla
|
||||||
void checkEvents(); // Comprueba los eventos
|
void checkEvents(); // Comprueba los eventos
|
||||||
void checkInput(); // Comprueba las entradas
|
static void checkInput(); // Comprueba las entradas
|
||||||
void updateScenes(); // Actualiza las escenas de la intro
|
void updateScenes(); // Actualiza las escenas de la intro
|
||||||
void initSprites(); // Inicializa las imágenes
|
void initSprites(); // Inicializa las imágenes
|
||||||
void initTexts(); // Inicializa los textos
|
void initTexts(); // Inicializa los textos
|
||||||
@@ -67,6 +67,6 @@ class Intro {
|
|||||||
void updateTexts(); // Actualiza los textos
|
void updateTexts(); // Actualiza los textos
|
||||||
void renderSprites(); // Dibuja los sprites
|
void renderSprites(); // Dibuja los sprites
|
||||||
void renderTexts(); // Dibuja los textos
|
void renderTexts(); // Dibuja los textos
|
||||||
void renderTextRect(); // Dibuja el rectangulo de fondo del texto;
|
static void renderTextRect(); // Dibuja el rectangulo de fondo del texto;
|
||||||
void updatePostState(); // Actualiza el estado POST
|
void updatePostState(); // Actualiza el estado POST
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ class Logo {
|
|||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void update(); // Actualiza las variables
|
void update(); // Actualiza las variables
|
||||||
void render(); // Dibuja en pantalla
|
void render(); // Dibuja en pantalla
|
||||||
void checkEvents(); // Comprueba el manejador de eventos
|
static void checkEvents(); // Comprueba el manejador de eventos
|
||||||
void checkInput(); // Comprueba las entradas
|
static void checkInput(); // Comprueba las entradas
|
||||||
void updateJAILGAMES(); // Gestiona el logo de JAILGAMES
|
void updateJAILGAMES(); // Gestiona el logo de JAILGAMES
|
||||||
void renderJAILGAMES(); // Renderiza el logo de JAILGAMES
|
void renderJAILGAMES(); // Renderiza el logo de JAILGAMES
|
||||||
void updateTextureColors(); // Gestiona el color de las texturas
|
void updateTextureColors(); // Gestiona el color de las texturas
|
||||||
|
|||||||
@@ -108,55 +108,67 @@ void Title::checkEvents() {
|
|||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (event.type == SDL_EVENT_KEY_DOWN && event.key.repeat == 1) {
|
if (event.type == SDL_EVENT_KEY_DOWN && static_cast<int>(event.key.repeat) == 1) {
|
||||||
static Color color_ = param.title.bg_color;
|
static Color color_ = param.title.bg_color;
|
||||||
switch (event.key.key) {
|
switch (event.key.key) {
|
||||||
case SDLK_A:
|
case SDLK_A:
|
||||||
if (color_.r < 255)
|
if (color_.r < 255) {
|
||||||
++color_.r;
|
++color_.r;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_Z:
|
case SDLK_Z:
|
||||||
if (color_.r > 0)
|
if (color_.r > 0) {
|
||||||
--color_.r;
|
--color_.r;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_S:
|
case SDLK_S:
|
||||||
if (color_.g < 255)
|
if (color_.g < 255) {
|
||||||
++color_.g;
|
++color_.g;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_X:
|
case SDLK_X:
|
||||||
if (color_.g > 0)
|
if (color_.g > 0) {
|
||||||
--color_.g;
|
--color_.g;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_D:
|
case SDLK_D:
|
||||||
if (color_.b < 255)
|
if (color_.b < 255) {
|
||||||
++color_.b;
|
++color_.b;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_C:
|
case SDLK_C:
|
||||||
if (color_.b > 0)
|
if (color_.b > 0) {
|
||||||
--color_.b;
|
--color_.b;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_F:
|
case SDLK_F:
|
||||||
if (color_.r < 255)
|
if (color_.r < 255) {
|
||||||
++color_.r;
|
++color_.r;
|
||||||
if (color_.g < 255)
|
}
|
||||||
|
if (color_.g < 255) {
|
||||||
++color_.g;
|
++color_.g;
|
||||||
if (color_.b < 255)
|
}
|
||||||
|
if (color_.b < 255) {
|
||||||
++color_.b;
|
++color_.b;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDLK_V:
|
case SDLK_V:
|
||||||
if (color_.r > 0)
|
if (color_.r > 0) {
|
||||||
--color_.r;
|
--color_.r;
|
||||||
if (color_.g > 0)
|
}
|
||||||
|
if (color_.g > 0) {
|
||||||
--color_.g;
|
--color_.g;
|
||||||
if (color_.b > 0)
|
}
|
||||||
|
if (color_.b > 0) {
|
||||||
--color_.b;
|
--color_.b;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -171,7 +183,7 @@ void Title::checkEvents() {
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (event.type == SDL_EVENT_KEY_DOWN && event.key.repeat == 0) {
|
if (event.type == SDL_EVENT_KEY_DOWN && static_cast<int>(event.key.repeat) == 0) {
|
||||||
switch (event.key.key) {
|
switch (event.key.key) {
|
||||||
case SDLK_1: // Redefine los botones del mando #0
|
case SDLK_1: // Redefine los botones del mando #0
|
||||||
define_buttons_->enable(0);
|
define_buttons_->enable(0);
|
||||||
@@ -211,8 +223,9 @@ void Title::checkEvents() {
|
|||||||
// Comprueba las entradas
|
// Comprueba las entradas
|
||||||
void Title::checkInput() {
|
void Title::checkInput() {
|
||||||
// Comprueba las entradas solo si no se estan definiendo los botones
|
// Comprueba las entradas solo si no se estan definiendo los botones
|
||||||
if (define_buttons_->isEnabled())
|
if (define_buttons_->isEnabled()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Input::get()->update();
|
Input::get()->update();
|
||||||
|
|
||||||
@@ -263,8 +276,9 @@ void Title::resetCounter() { counter_ = 0; }
|
|||||||
|
|
||||||
// Intercambia la asignación de mandos a los jugadores
|
// Intercambia la asignación de mandos a los jugadores
|
||||||
void Title::swapControllers() {
|
void Title::swapControllers() {
|
||||||
if (Input::get()->getNumControllers() == 0)
|
if (Input::get()->getNumControllers() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Options::swapControllers();
|
Options::swapControllers();
|
||||||
showControllers();
|
showControllers();
|
||||||
@@ -433,7 +447,7 @@ void Title::renderCopyright() {
|
|||||||
text_->writeDX(TEXT_CENTER | TEXT_SHADOW,
|
text_->writeDX(TEXT_CENTER | TEXT_SHADOW,
|
||||||
param.game.game_area.center_x,
|
param.game.game_area.center_x,
|
||||||
anchor_.copyright_text,
|
anchor_.copyright_text,
|
||||||
TEXT_COPYRIGHT,
|
std::string(TEXT_COPYRIGHT),
|
||||||
1,
|
1,
|
||||||
NO_TEXT_COLOR,
|
NO_TEXT_COLOR,
|
||||||
1,
|
1,
|
||||||
@@ -443,8 +457,9 @@ void Title::renderCopyright() {
|
|||||||
|
|
||||||
// Cambia el estado
|
// Cambia el estado
|
||||||
void Title::setState(TitleState state) {
|
void Title::setState(TitleState state) {
|
||||||
if (state_ == state)
|
if (state_ == state) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
state_ = state;
|
state_ = state;
|
||||||
switch (state_) {
|
switch (state_) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <memory> // Para unique_ptr, shared_ptr
|
#include <memory> // Para unique_ptr, shared_ptr
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include "section.h" // Para Options
|
#include "section.h" // Para Options
|
||||||
|
|
||||||
@@ -16,7 +17,8 @@ class Text;
|
|||||||
class TiledBG;
|
class TiledBG;
|
||||||
|
|
||||||
// Textos
|
// Textos
|
||||||
constexpr const char TEXT_COPYRIGHT[] = "@2020,2025 JailDesigner";
|
constexpr std::string_view TEXT_COPYRIGHT = "@2020,2025 JailDesigner";
|
||||||
|
|
||||||
|
|
||||||
// Parámetros
|
// Parámetros
|
||||||
constexpr bool ALLOW_TITLE_ANIMATION_SKIP = false;
|
constexpr bool ALLOW_TITLE_ANIMATION_SKIP = false;
|
||||||
@@ -81,8 +83,8 @@ class Title {
|
|||||||
void checkInput(); // Comprueba las entradas
|
void checkInput(); // Comprueba las entradas
|
||||||
void resetCounter(); // Reinicia el contador interno
|
void resetCounter(); // Reinicia el contador interno
|
||||||
void swapControllers(); // Intercambia la asignación de mandos a los jugadores
|
void swapControllers(); // Intercambia la asignación de mandos a los jugadores
|
||||||
void swapKeyboard(); // Intercambia el teclado de jugador
|
static void swapKeyboard(); // Intercambia el teclado de jugador
|
||||||
void showControllers(); // Muestra información sobre los controles y los jugadores
|
static void showControllers(); // Muestra información sobre los controles y los jugadores
|
||||||
void updateFade(); // Actualiza el efecto de fundido (fade in/out)
|
void updateFade(); // Actualiza el efecto de fundido (fade in/out)
|
||||||
void updateState(); // Actualiza el estado actual del título
|
void updateState(); // Actualiza el estado actual del título
|
||||||
void updateStartPrompt(); // Actualiza el mensaje de "Pulsa Start"
|
void updateStartPrompt(); // Actualiza el mensaje de "Pulsa Start"
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ void SmartSprite::checkMove() {
|
|||||||
setPosX(dest_x_);
|
setPosX(dest_x_);
|
||||||
|
|
||||||
// Lo detiene
|
// Lo detiene
|
||||||
setVelX(0.0f);
|
setVelX(0.0F);
|
||||||
setAccelX(0.0f);
|
setAccelX(0.0F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Comprueba si se desplaza en el eje X hacia la izquierda
|
// Comprueba si se desplaza en el eje X hacia la izquierda
|
||||||
@@ -40,8 +40,8 @@ void SmartSprite::checkMove() {
|
|||||||
setPosX(dest_x_);
|
setPosX(dest_x_);
|
||||||
|
|
||||||
// Lo detiene
|
// Lo detiene
|
||||||
setVelX(0.0f);
|
setVelX(0.0F);
|
||||||
setAccelX(0.0f);
|
setAccelX(0.0F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,8 +53,8 @@ void SmartSprite::checkMove() {
|
|||||||
setPosY(dest_y_);
|
setPosY(dest_y_);
|
||||||
|
|
||||||
// Lo detiene
|
// Lo detiene
|
||||||
setVelY(0.0f);
|
setVelY(0.0F);
|
||||||
setAccelY(0.0f);
|
setAccelY(0.0F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Comprueba si se desplaza en el eje Y hacia arriba
|
// Comprueba si se desplaza en el eje Y hacia arriba
|
||||||
@@ -65,8 +65,8 @@ void SmartSprite::checkMove() {
|
|||||||
setPosY(dest_y_);
|
setPosY(dest_y_);
|
||||||
|
|
||||||
// Lo detiene
|
// Lo detiene
|
||||||
setVelY(0.0f);
|
setVelY(0.0F);
|
||||||
setAccelY(0.0f);
|
setAccelY(0.0F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
104
source/tabe.cpp
104
source/tabe.cpp
@@ -4,6 +4,7 @@
|
|||||||
#include <SDL3/SDL.h> // Para SDL_FlipMode, SDL_GetTicks
|
#include <SDL3/SDL.h> // Para SDL_FlipMode, SDL_GetTicks
|
||||||
|
|
||||||
#include <algorithm> // Para max
|
#include <algorithm> // Para max
|
||||||
|
#include <array>
|
||||||
#include <cmath> // Para abs
|
#include <cmath> // Para abs
|
||||||
#include <cstdlib> // Para rand, abs
|
#include <cstdlib> // Para rand, abs
|
||||||
#include <string> // Para basic_string
|
#include <string> // Para basic_string
|
||||||
@@ -25,7 +26,7 @@ void Tabe::update() {
|
|||||||
move();
|
move();
|
||||||
updateState();
|
updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_.update();
|
timer_.update();
|
||||||
if (timer_.shouldSpawn()) {
|
if (timer_.shouldSpawn()) {
|
||||||
enable();
|
enable();
|
||||||
@@ -41,49 +42,62 @@ void Tabe::render() {
|
|||||||
|
|
||||||
// Mueve el objeto
|
// Mueve el objeto
|
||||||
void Tabe::move() {
|
void Tabe::move() {
|
||||||
const int X = static_cast<int>(x_);
|
const int X = static_cast<int>(x_);
|
||||||
speed_ += accel_;
|
speed_ += accel_;
|
||||||
x_ += speed_;
|
x_ += speed_;
|
||||||
fly_distance_ -= std::abs(X - static_cast<int>(x_));
|
fly_distance_ -= std::abs(X - static_cast<int>(x_));
|
||||||
|
|
||||||
// Comprueba si sale por los bordes
|
// Comprueba si sale por los bordes
|
||||||
const float MIN_X = param.game.game_area.rect.x - WIDTH;
|
const float MIN_X = param.game.game_area.rect.x - WIDTH;
|
||||||
const float MAX_X = param.game.game_area.rect.x + param.game.game_area.rect.w;
|
const float MAX_X = param.game.game_area.rect.x + param.game.game_area.rect.w;
|
||||||
switch (destiny_) {
|
switch (destiny_) {
|
||||||
case TabeDirection::TO_THE_LEFT: {
|
case TabeDirection::TO_THE_LEFT: {
|
||||||
if (x_ < MIN_X) {
|
if (x_ < MIN_X) {
|
||||||
disable();
|
disable();
|
||||||
}
|
}
|
||||||
if (x_ > param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH && direction_ == TabeDirection::TO_THE_RIGHT) {
|
if (x_ > param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH && direction_ == TabeDirection::TO_THE_RIGHT) {
|
||||||
setRandomFlyPath(TabeDirection::TO_THE_LEFT, 80);
|
setRandomFlyPath(TabeDirection::TO_THE_LEFT, 80);
|
||||||
x_ = param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH;
|
x_ = param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TabeDirection::TO_THE_RIGHT: {
|
case TabeDirection::TO_THE_RIGHT: {
|
||||||
if (x_ > MAX_X) {
|
if (x_ > MAX_X) {
|
||||||
disable();
|
disable();
|
||||||
}
|
}
|
||||||
if (x_ < param.game.game_area.rect.x && direction_ == TabeDirection::TO_THE_LEFT) {
|
if (x_ < param.game.game_area.rect.x && direction_ == TabeDirection::TO_THE_LEFT) {
|
||||||
setRandomFlyPath(TabeDirection::TO_THE_RIGHT, 80);
|
setRandomFlyPath(TabeDirection::TO_THE_RIGHT, 80);
|
||||||
x_ = param.game.game_area.rect.x;
|
x_ = param.game.game_area.rect.x;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fly_distance_ <= 0) {
|
if (fly_distance_ <= 0) {
|
||||||
if (waiting_counter_ > 0) {
|
if (waiting_counter_ > 0) {
|
||||||
accel_ = speed_ = 0.0F;
|
accel_ = speed_ = 0.0F;
|
||||||
--waiting_counter_;
|
--waiting_counter_;
|
||||||
} else {
|
} else {
|
||||||
constexpr int CHOICES = 4;
|
constexpr int CHOICES = 4;
|
||||||
const TabeDirection LEFT[CHOICES] = {TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_RIGHT};
|
const std::array<TabeDirection, CHOICES> LEFT = {
|
||||||
const TabeDirection RIGHT[CHOICES] = {TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_RIGHT, TabeDirection::TO_THE_RIGHT, TabeDirection::TO_THE_RIGHT};
|
TabeDirection::TO_THE_LEFT,
|
||||||
const TabeDirection DIRECTION = destiny_ == TabeDirection::TO_THE_LEFT ? LEFT[rand() % CHOICES] : RIGHT[rand() % CHOICES];
|
TabeDirection::TO_THE_LEFT,
|
||||||
|
TabeDirection::TO_THE_LEFT,
|
||||||
|
TabeDirection::TO_THE_RIGHT};
|
||||||
|
|
||||||
|
const std::array<TabeDirection, CHOICES> RIGHT = {
|
||||||
|
TabeDirection::TO_THE_LEFT,
|
||||||
|
TabeDirection::TO_THE_RIGHT,
|
||||||
|
TabeDirection::TO_THE_RIGHT,
|
||||||
|
TabeDirection::TO_THE_RIGHT};
|
||||||
|
|
||||||
|
const TabeDirection DIRECTION = destiny_ == TabeDirection::TO_THE_LEFT
|
||||||
|
? LEFT[rand() % CHOICES]
|
||||||
|
: RIGHT[rand() % CHOICES];
|
||||||
|
|
||||||
setRandomFlyPath(DIRECTION, 20 + rand() % 40);
|
setRandomFlyPath(DIRECTION, 20 + rand() % 40);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,10 +137,10 @@ void Tabe::setRandomFlyPath(TabeDirection direction, int lenght) {
|
|||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case TabeDirection::TO_THE_LEFT: {
|
case TabeDirection::TO_THE_LEFT: {
|
||||||
speed_ = -1.0F * SPEED;
|
speed_ = -1.0F * SPEED;
|
||||||
accel_ = -1.0F * (1 + rand() % 10) / 30.0F;
|
accel_ = -1.0F * (1 + rand() % 10) / 30.0F;
|
||||||
sprite_->setFlip(SDL_FLIP_NONE);
|
sprite_->setFlip(SDL_FLIP_NONE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TabeDirection::TO_THE_RIGHT: {
|
case TabeDirection::TO_THE_RIGHT: {
|
||||||
@@ -175,11 +189,11 @@ void Tabe::updateState() {
|
|||||||
|
|
||||||
// Intenta obtener el bonus
|
// Intenta obtener el bonus
|
||||||
auto Tabe::tryToGetBonus() -> bool {
|
auto Tabe::tryToGetBonus() -> bool {
|
||||||
if (has_bonus_ && rand() % std::max(1, 15 - number_of_hits_) == 0) {
|
if (has_bonus_ && rand() % std::max(1, 15 - number_of_hits_) == 0) {
|
||||||
has_bonus_ = false;
|
has_bonus_ = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza el temporizador
|
// Actualiza el temporizador
|
||||||
|
|||||||
@@ -45,8 +45,9 @@ auto loadTextFile(const std::string &file_path) -> std::shared_ptr<TextFile> {
|
|||||||
auto line_read = 0;
|
auto line_read = 0;
|
||||||
while (std::getline(file, buffer)) {
|
while (std::getline(file, buffer)) {
|
||||||
// Almacena solo las lineas impares
|
// Almacena solo las lineas impares
|
||||||
if (line_read % 2 == 1)
|
if (line_read % 2 == 1) {
|
||||||
tf->offset[index++].w = std::stoi(buffer);
|
tf->offset[index++].w = std::stoi(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
// Limpia el buffer
|
// Limpia el buffer
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
@@ -116,8 +117,9 @@ Text::Text(std::shared_ptr<Texture> texture, std::shared_ptr<TextFile> text_file
|
|||||||
void Text::write(int x, int y, const std::string &text, int kerning, int lenght) {
|
void Text::write(int x, int y, const std::string &text, int kerning, int lenght) {
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
|
|
||||||
if (lenght == -1)
|
if (lenght == -1) {
|
||||||
lenght = text.length();
|
lenght = text.length();
|
||||||
|
}
|
||||||
|
|
||||||
sprite_->setY(y);
|
sprite_->setY(y);
|
||||||
for (int i = 0; i < lenght; ++i) {
|
for (int i = 0; i < lenght; ++i) {
|
||||||
@@ -135,18 +137,18 @@ void Text::write2X(int x, int y, const std::string &text, int kerning) {
|
|||||||
for (size_t i = 0; i < text.length(); ++i) {
|
for (size_t i = 0; i < text.length(); ++i) {
|
||||||
auto index = static_cast<size_t>(text[i]);
|
auto index = static_cast<size_t>(text[i]);
|
||||||
SDL_FRect rect = {static_cast<float>(offset_[index].x), static_cast<float>(offset_[index].y), static_cast<float>(box_width_), static_cast<float>(box_height_)};
|
SDL_FRect rect = {static_cast<float>(offset_[index].x), static_cast<float>(offset_[index].y), static_cast<float>(box_width_), static_cast<float>(box_height_)};
|
||||||
sprite_->getTexture()->render(x + shift, y, &rect, 2.0f, 2.0f);
|
sprite_->getTexture()->render(x + shift, y, &rect, 2.0F, 2.0F);
|
||||||
shift += (offset_[index].w + kerning) * 2;
|
shift += (offset_[index].w + kerning) * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Escribe el texto en una textura
|
// Escribe el texto en una textura
|
||||||
auto Text::writeToTexture(const std::string &text, int zoom, int kerning) -> std::shared_ptr<Texture> {
|
auto Text::writeToTexture(const std::string &text, int zoom, int kerning) -> std::shared_ptr<Texture> {
|
||||||
auto renderer = Screen::get()->getRenderer();
|
auto *renderer = Screen::get()->getRenderer();
|
||||||
auto texture = std::make_shared<Texture>(renderer);
|
auto texture = std::make_shared<Texture>(renderer);
|
||||||
auto width = lenght(text, kerning) * zoom;
|
auto width = lenght(text, kerning) * zoom;
|
||||||
auto height = box_height_ * zoom;
|
auto height = box_height_ * zoom;
|
||||||
auto temp = SDL_GetRenderTarget(renderer);
|
auto *temp = SDL_GetRenderTarget(renderer);
|
||||||
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
||||||
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||||
texture->setAsRenderTarget(renderer);
|
texture->setAsRenderTarget(renderer);
|
||||||
@@ -160,11 +162,11 @@ auto Text::writeToTexture(const std::string &text, int zoom, int kerning) -> std
|
|||||||
|
|
||||||
// Escribe el texto con extras en una textura
|
// Escribe el texto con extras en una textura
|
||||||
auto Text::writeDXToTexture(Uint8 flags, const std::string &text, int kerning, Color text_color, Uint8 shadow_distance, Color shadow_color, int lenght) -> std::shared_ptr<Texture> {
|
auto Text::writeDXToTexture(Uint8 flags, const std::string &text, int kerning, Color text_color, Uint8 shadow_distance, Color shadow_color, int lenght) -> std::shared_ptr<Texture> {
|
||||||
auto renderer = Screen::get()->getRenderer();
|
auto *renderer = Screen::get()->getRenderer();
|
||||||
auto texture = std::make_shared<Texture>(renderer);
|
auto texture = std::make_shared<Texture>(renderer);
|
||||||
auto width = Text::lenght(text, kerning) + shadow_distance;
|
auto width = Text::lenght(text, kerning) + shadow_distance;
|
||||||
auto height = box_height_ + shadow_distance;
|
auto height = box_height_ + shadow_distance;
|
||||||
auto temp = SDL_GetRenderTarget(renderer);
|
auto *temp = SDL_GetRenderTarget(renderer);
|
||||||
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
|
||||||
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
texture->setBlendMode(SDL_BLENDMODE_BLEND);
|
||||||
texture->setAsRenderTarget(renderer);
|
texture->setAsRenderTarget(renderer);
|
||||||
@@ -232,8 +234,9 @@ void Text::writeDX(Uint8 flags, int x, int y, const std::string &text, int kerni
|
|||||||
// Obtiene la longitud en pixels de una cadena
|
// Obtiene la longitud en pixels de una cadena
|
||||||
auto Text::lenght(const std::string &text, int kerning) const -> int {
|
auto Text::lenght(const std::string &text, int kerning) const -> int {
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
for (size_t i = 0; i < text.length(); ++i)
|
for (size_t i = 0; i < text.length(); ++i) {
|
||||||
shift += (offset_[static_cast<int>(text[i])].w + kerning);
|
shift += (offset_[static_cast<int>(text[i])].w + kerning);
|
||||||
|
}
|
||||||
|
|
||||||
// Descuenta el kerning del último caracter
|
// Descuenta el kerning del último caracter
|
||||||
return shift - kerning;
|
return shift - kerning;
|
||||||
@@ -251,7 +254,7 @@ void Text::setFixedWidth(bool value) {
|
|||||||
|
|
||||||
// Establece una paleta
|
// Establece una paleta
|
||||||
void Text::setPalette(int number) {
|
void Text::setPalette(int number) {
|
||||||
auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
auto *temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
|
||||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
|
||||||
sprite_->getTexture()->setPalette(number);
|
sprite_->getTexture()->setPalette(number);
|
||||||
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
|
SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para Uint8
|
#include <SDL3/SDL.h> // Para Uint8
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <memory> // Para unique_ptr, shared_ptr
|
#include <memory> // Para unique_ptr, shared_ptr
|
||||||
#include <string> // Para string
|
#include <string> // Para string
|
||||||
|
|
||||||
@@ -18,13 +19,13 @@ constexpr int TEXT_STROKE = 8;
|
|||||||
|
|
||||||
// --- Estructuras auxiliares ---
|
// --- Estructuras auxiliares ---
|
||||||
struct TextOffset {
|
struct TextOffset {
|
||||||
int x, y, w;
|
int x, y, w;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextFile {
|
struct TextFile {
|
||||||
int box_width; // Anchura de la caja de cada caracter en el png
|
int box_width; // Anchura de la caja de cada caracter en el png
|
||||||
int box_height; // Altura de la caja de cada caracter en el png
|
int box_height; // Altura de la caja de cada caracter en el png
|
||||||
TextOffset offset[128]; // Vector con las posiciones y ancho de cada letra
|
std::array<TextOffset, 128> offset = {}; // Vector con las posiciones y ancho de cada letra
|
||||||
};
|
};
|
||||||
|
|
||||||
// Llena una estructura TextFile desde un fichero
|
// Llena una estructura TextFile desde un fichero
|
||||||
@@ -32,41 +33,42 @@ auto loadTextFile(const std::string &file_path) -> std::shared_ptr<TextFile>;
|
|||||||
|
|
||||||
// --- Clase Text: pinta texto en pantalla a partir de un bitmap ---
|
// --- Clase Text: pinta texto en pantalla a partir de un bitmap ---
|
||||||
class Text {
|
class Text {
|
||||||
public:
|
public:
|
||||||
// --- Constructores y destructor ---
|
// --- Constructores y destructor ---
|
||||||
Text(std::shared_ptr<Texture> texture, const std::string &text_file);
|
Text(std::shared_ptr<Texture> texture, const std::string &text_file);
|
||||||
Text(std::shared_ptr<Texture> texture, std::shared_ptr<TextFile> text_file);
|
Text(std::shared_ptr<Texture> texture, std::shared_ptr<TextFile> text_file);
|
||||||
~Text() = default;
|
~Text() = default;
|
||||||
|
|
||||||
// --- Métodos de escritura en pantalla ---
|
// --- Métodos de escritura en pantalla ---
|
||||||
void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla
|
void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla
|
||||||
void write2X(int x, int y, const std::string &text, int kerning = 1); // Escribe el texto al doble de tamaño
|
void write2X(int x, int y, const std::string &text, int kerning = 1); // Escribe el texto al doble de tamaño
|
||||||
|
|
||||||
// --- Escritura en textura ---
|
// --- Escritura en textura ---
|
||||||
auto writeToTexture(const std::string &text, int zoom = 1, int kerning = 1) -> std::shared_ptr<Texture>; // Escribe el texto en una textura
|
auto writeToTexture(const std::string &text, int zoom = 1, int kerning = 1) -> std::shared_ptr<Texture>; // Escribe el texto en una textura
|
||||||
auto writeDXToTexture(Uint8 flags, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1) -> std::shared_ptr<Texture>; // Escribe el texto con extras en una textura
|
auto writeDXToTexture(Uint8 flags, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1) -> std::shared_ptr<Texture>; // Escribe el texto con extras en una textura
|
||||||
|
|
||||||
// --- Métodos de escritura avanzada ---
|
// --- Métodos de escritura avanzada ---
|
||||||
void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1); // Escribe el texto con colores
|
void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1); // Escribe el texto con colores
|
||||||
void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadow_distance = 1, int kerning = 1, int lenght = -1); // Escribe el texto con sombra
|
void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadow_distance = 1, int kerning = 1, int lenght = -1); // Escribe el texto con sombra
|
||||||
void writeCentered(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto centrado en un punto x
|
void writeCentered(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto centrado en un punto x
|
||||||
void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1); // Escribe texto con extras
|
void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1); // Escribe texto con extras
|
||||||
|
|
||||||
// --- Utilidades ---
|
// --- Utilidades ---
|
||||||
[[nodiscard]] auto lenght(const std::string &text, int kerning = 1) const -> int; // Obtiene la longitud en pixels de una cadena
|
[[nodiscard]] auto lenght(const std::string &text, int kerning = 1) const -> int; // Obtiene la longitud en pixels de una cadena
|
||||||
[[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el tamaño de caracter actual
|
[[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el tamaño de caracter actual
|
||||||
|
|
||||||
// --- Configuración ---
|
// --- Configuración ---
|
||||||
void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra
|
void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra
|
||||||
void setPalette(int number); // Establece una paleta
|
void setPalette(int number); // Establece una paleta
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Objetos y punteros ---
|
// --- Objetos y punteros ---
|
||||||
std::unique_ptr<Sprite> sprite_ = nullptr; // Objeto con los gráficos para el texto
|
std::unique_ptr<Sprite> sprite_ = nullptr; // Objeto con los gráficos para el texto
|
||||||
|
|
||||||
// --- Variables ---
|
// --- Variables ---
|
||||||
int box_width_ = 0; // Anchura de la caja de cada caracter en el png
|
int box_width_ = 0; // Anchura de la caja de cada caracter en el png
|
||||||
int box_height_ = 0; // Altura de la caja de cada caracter en el png
|
int box_height_ = 0; // Altura de la caja de cada caracter en el png
|
||||||
bool fixed_width_ = false; // Indica si el texto se ha de escribir con longitud fija en todas las letras
|
bool fixed_width_ = false; // Indica si el texto se ha de escribir con longitud fija en todas las letras
|
||||||
TextOffset offset_[128] = {}; // Vector con las posiciones y ancho de cada letra
|
std::array<TextOffset, 128> offset_ = {};
|
||||||
|
; // Vector con las posiciones y ancho de cada letra
|
||||||
};
|
};
|
||||||
@@ -55,18 +55,20 @@ Texture::~Texture() {
|
|||||||
|
|
||||||
// Carga una imagen desde un fichero
|
// Carga una imagen desde un fichero
|
||||||
auto Texture::loadFromFile(const std::string &file_path) -> bool {
|
auto Texture::loadFromFile(const std::string &file_path) -> bool {
|
||||||
if (file_path.empty())
|
if (file_path.empty()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int req_format = STBI_rgb_alpha;
|
int req_format = STBI_rgb_alpha;
|
||||||
int width, height, orig_format;
|
int width;
|
||||||
|
int height;
|
||||||
|
int orig_format;
|
||||||
unsigned char *data = stbi_load(file_path.c_str(), &width, &height, &orig_format, req_format);
|
unsigned char *data = stbi_load(file_path.c_str(), &width, &height, &orig_format, req_format);
|
||||||
if (!data) {
|
if (data == nullptr) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", getFileName(file_path).c_str());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", getFileName(file_path).c_str());
|
||||||
throw std::runtime_error("Fichero no encontrado: " + getFileName(file_path));
|
throw std::runtime_error("Fichero no encontrado: " + getFileName(file_path));
|
||||||
} else {
|
|
||||||
printWithDots("Texture : ", getFileName(file_path), "[ LOADED ]");
|
|
||||||
}
|
}
|
||||||
|
printWithDots("Texture : ", getFileName(file_path), "[ LOADED ]");
|
||||||
|
|
||||||
int pitch;
|
int pitch;
|
||||||
SDL_PixelFormat pixel_format;
|
SDL_PixelFormat pixel_format;
|
||||||
@@ -82,7 +84,7 @@ auto Texture::loadFromFile(const std::string &file_path) -> bool {
|
|||||||
SDL_Texture *new_texture = nullptr;
|
SDL_Texture *new_texture = nullptr;
|
||||||
|
|
||||||
// Carga la imagen desde una ruta específica
|
// Carga la imagen desde una ruta específica
|
||||||
auto loaded_surface = SDL_CreateSurfaceFrom(width, height, pixel_format, static_cast<void *>(data), pitch);
|
auto *loaded_surface = SDL_CreateSurfaceFrom(width, height, pixel_format, static_cast<void *>(data), pitch);
|
||||||
if (loaded_surface == nullptr) {
|
if (loaded_surface == nullptr) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to load image %s", file_path.c_str());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to load image %s", file_path.c_str());
|
||||||
} else {
|
} else {
|
||||||
@@ -110,7 +112,7 @@ auto Texture::loadFromFile(const std::string &file_path) -> bool {
|
|||||||
auto Texture::createBlank(int width, int height, SDL_PixelFormat format, SDL_TextureAccess access) -> bool {
|
auto Texture::createBlank(int width, int height, SDL_PixelFormat format, SDL_TextureAccess access) -> bool {
|
||||||
// Crea una textura sin inicializar
|
// Crea una textura sin inicializar
|
||||||
texture_ = SDL_CreateTexture(renderer_, format, access, width, height);
|
texture_ = SDL_CreateTexture(renderer_, format, access, width, height);
|
||||||
if (!texture_) {
|
if (texture_ == nullptr) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create blank texture! SDL Error: %s", SDL_GetError());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create blank texture! SDL Error: %s", SDL_GetError());
|
||||||
} else {
|
} else {
|
||||||
width_ = width;
|
width_ = width;
|
||||||
@@ -123,7 +125,7 @@ auto Texture::createBlank(int width, int height, SDL_PixelFormat format, SDL_Tex
|
|||||||
// Libera la memoria de la textura
|
// Libera la memoria de la textura
|
||||||
void Texture::unloadTexture() {
|
void Texture::unloadTexture() {
|
||||||
// Libera la textura
|
// Libera la textura
|
||||||
if (texture_) {
|
if (texture_ != nullptr) {
|
||||||
SDL_DestroyTexture(texture_);
|
SDL_DestroyTexture(texture_);
|
||||||
texture_ = nullptr;
|
texture_ = nullptr;
|
||||||
width_ = 0;
|
width_ = 0;
|
||||||
@@ -161,7 +163,7 @@ void Texture::render(int x, int y, SDL_FRect *clip, float zoom_w, float zoom_h,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calcula el zoom y las coordenadas
|
// Calcula el zoom y las coordenadas
|
||||||
if (zoom_h != 1.0f || zoom_w != 1.0f) {
|
if (zoom_h != 1.0F || zoom_w != 1.0F) {
|
||||||
render_quad.x = render_quad.x + (render_quad.w / 2);
|
render_quad.x = render_quad.x + (render_quad.w / 2);
|
||||||
render_quad.y = render_quad.y + (render_quad.h / 2);
|
render_quad.y = render_quad.y + (render_quad.h / 2);
|
||||||
render_quad.w = render_quad.w * zoom_w;
|
render_quad.w = render_quad.w * zoom_w;
|
||||||
@@ -180,12 +182,12 @@ void Texture::setAsRenderTarget(SDL_Renderer *renderer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el ancho de la imagen
|
// Obtiene el ancho de la imagen
|
||||||
auto Texture::getWidth() -> int {
|
auto Texture::getWidth() const -> int {
|
||||||
return width_;
|
return width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtiene el alto de la imagen
|
// Obtiene el alto de la imagen
|
||||||
auto Texture::getHeight() -> int {
|
auto Texture::getHeight() const -> int {
|
||||||
return height_;
|
return height_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +233,8 @@ auto Texture::loadSurface(const std::string &file_path) -> std::shared_ptr<Surfa
|
|||||||
|
|
||||||
// Crear un objeto Gif y llamar a la función loadGif
|
// Crear un objeto Gif y llamar a la función loadGif
|
||||||
GIF::Gif gif;
|
GIF::Gif gif;
|
||||||
Uint16 w = 0, h = 0;
|
Uint16 w = 0;
|
||||||
|
Uint16 h = 0;
|
||||||
std::vector<Uint8> raw_pixels = gif.loadGif(buffer.data(), w, h);
|
std::vector<Uint8> raw_pixels = gif.loadGif(buffer.data(), w, h);
|
||||||
if (raw_pixels.empty()) {
|
if (raw_pixels.empty()) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: No se pudo cargar el GIF %s", file_path.c_str());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: No se pudo cargar el GIF %s", file_path.c_str());
|
||||||
@@ -240,7 +243,7 @@ auto Texture::loadSurface(const std::string &file_path) -> std::shared_ptr<Surfa
|
|||||||
|
|
||||||
// Si el constructor de Surface espera un std::shared_ptr<Uint8[]>:
|
// Si el constructor de Surface espera un std::shared_ptr<Uint8[]>:
|
||||||
size_t pixel_count = raw_pixels.size();
|
size_t pixel_count = raw_pixels.size();
|
||||||
auto pixels = std::shared_ptr<Uint8[]>(new Uint8[pixel_count], std::default_delete<Uint8[]>());
|
auto pixels = std::shared_ptr<Uint8[]>(new Uint8[pixel_count], std::default_delete<Uint8[]>()); // NOLINT(modernize-avoid-c-arrays)
|
||||||
std::memcpy(pixels.get(), raw_pixels.data(), pixel_count);
|
std::memcpy(pixels.get(), raw_pixels.data(), pixel_count);
|
||||||
|
|
||||||
auto surface = std::make_shared<Surface>(w, h, pixels);
|
auto surface = std::make_shared<Surface>(w, h, pixels);
|
||||||
@@ -256,7 +259,7 @@ auto Texture::loadSurface(const std::string &file_path) -> std::shared_ptr<Surfa
|
|||||||
// Vuelca la surface en la textura
|
// Vuelca la surface en la textura
|
||||||
void Texture::flipSurface() {
|
void Texture::flipSurface() {
|
||||||
// Limpia la textura
|
// Limpia la textura
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, texture_);
|
SDL_SetRenderTarget(renderer_, texture_);
|
||||||
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
|
||||||
SDL_RenderClear(renderer_);
|
SDL_RenderClear(renderer_);
|
||||||
@@ -286,9 +289,8 @@ auto Texture::loadPaletteFromFile(const std::string &file_path) -> Palette {
|
|||||||
if (!file) {
|
if (!file) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", file_path.c_str());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", file_path.c_str());
|
||||||
throw std::runtime_error("Fichero no encontrado: " + file_path);
|
throw std::runtime_error("Fichero no encontrado: " + file_path);
|
||||||
} else {
|
|
||||||
printWithDots("Palette : ", getFileName(file_path), "[ LOADED ]");
|
|
||||||
}
|
}
|
||||||
|
printWithDots("Palette : ", getFileName(file_path), "[ LOADED ]");
|
||||||
|
|
||||||
// Obtener el tamaño del archivo y leerlo en un buffer
|
// Obtener el tamaño del archivo y leerlo en un buffer
|
||||||
std::streamsize size = file.tellg();
|
std::streamsize size = file.tellg();
|
||||||
@@ -364,7 +366,9 @@ auto Texture::readPalFile(const std::string &file_path) -> Palette {
|
|||||||
|
|
||||||
// Procesar las líneas restantes con valores RGB
|
// Procesar las líneas restantes con valores RGB
|
||||||
std::istringstream ss(line);
|
std::istringstream ss(line);
|
||||||
int r, g, b;
|
int r;
|
||||||
|
int g;
|
||||||
|
int b;
|
||||||
if (ss >> r >> g >> b) {
|
if (ss >> r >> g >> b) {
|
||||||
// Construir el color RGBA (A = 255 por defecto)
|
// Construir el color RGBA (A = 255 por defecto)
|
||||||
Uint32 color = (r << 24) | (g << 16) | (b << 8) | 255;
|
Uint32 color = (r << 24) | (g << 16) | (b << 8) | 255;
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ using Palette = std::array<Uint32, 256>;
|
|||||||
|
|
||||||
// Definición de Surface para imágenes con paleta
|
// Definición de Surface para imágenes con paleta
|
||||||
struct Surface {
|
struct Surface {
|
||||||
std::shared_ptr<Uint8[]> data;
|
std::shared_ptr<Uint8[]> data; // NOLINT(modernize-avoid-c-arrays)
|
||||||
Uint16 w, h;
|
Uint16 w, h;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Surface(Uint16 width, Uint16 height, std::shared_ptr<Uint8[]> pixels)
|
Surface(Uint16 width, Uint16 height, std::shared_ptr<Uint8[]> pixels) // NOLINT(modernize-avoid-c-arrays)
|
||||||
: data(std::move(pixels)), w(width), h(height) {}
|
: data(std::move(pixels)), w(width), h(height) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,8 +53,8 @@ class Texture {
|
|||||||
void setPalette(size_t palette); // Cambia la paleta de la textura
|
void setPalette(size_t palette); // Cambia la paleta de la textura
|
||||||
|
|
||||||
// --- Getters ---
|
// --- Getters ---
|
||||||
auto getWidth() -> int; // Obtiene el ancho de la imagen
|
[[nodiscard]] auto getWidth() const -> int; // Obtiene el ancho de la imagen
|
||||||
auto getHeight() -> int; // Obtiene el alto de la imagen
|
[[nodiscard]] auto getHeight() const -> int; // Obtiene el alto de la imagen
|
||||||
auto getSDLTexture() -> SDL_Texture *; // Obtiene la textura SDL
|
auto getSDLTexture() -> SDL_Texture *; // Obtiene la textura SDL
|
||||||
auto getRenderer() -> SDL_Renderer *; // Obtiene el renderizador
|
auto getRenderer() -> SDL_Renderer *; // Obtiene el renderizador
|
||||||
|
|
||||||
@@ -74,8 +74,8 @@ class Texture {
|
|||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
auto loadSurface(const std::string &file_name) -> std::shared_ptr<Surface>; // Crea una surface desde un fichero .gif
|
auto loadSurface(const std::string &file_name) -> std::shared_ptr<Surface>; // Crea una surface desde un fichero .gif
|
||||||
void flipSurface(); // Vuelca la surface en la textura
|
void flipSurface(); // Vuelca la surface en la textura
|
||||||
auto loadPaletteFromFile(const std::string &file_name) -> Palette; // Carga una paleta desde un fichero
|
static auto loadPaletteFromFile(const std::string &file_name) -> Palette; // Carga una paleta desde un fichero
|
||||||
void unloadTexture(); // Libera la memoria de la textura
|
void unloadTexture(); // Libera la memoria de la textura
|
||||||
void unloadSurface(); // Libera la surface actual
|
void unloadSurface(); // Libera la surface actual
|
||||||
auto readPalFile(const std::string &file_path) -> Palette; // Carga una paleta desde un archivo .pal
|
static auto readPalFile(const std::string &file_path) -> Palette; // Carga una paleta desde un archivo .pal
|
||||||
};
|
};
|
||||||
@@ -27,7 +27,7 @@ TiledBG::TiledBG(SDL_FRect pos, TiledBGMode mode)
|
|||||||
switch (mode_) {
|
switch (mode_) {
|
||||||
case TiledBGMode::STATIC:
|
case TiledBGMode::STATIC:
|
||||||
window_ = {0, 0, pos_.w, pos_.h};
|
window_ = {0, 0, pos_.w, pos_.h};
|
||||||
speed_ = 0.0f;
|
speed_ = 0.0F;
|
||||||
break;
|
break;
|
||||||
case TiledBGMode::DIAGONAL:
|
case TiledBGMode::DIAGONAL:
|
||||||
window_ = {0, 0, pos_.w, pos_.h};
|
window_ = {0, 0, pos_.w, pos_.h};
|
||||||
@@ -57,7 +57,7 @@ void TiledBG::fillTexture() {
|
|||||||
auto tile = std::make_unique<Sprite>(Resource::get()->getTexture("title_bg_tile.png"), (SDL_FRect){0, 0, TILE_WIDTH, TILE_HEIGHT});
|
auto tile = std::make_unique<Sprite>(Resource::get()->getTexture("title_bg_tile.png"), (SDL_FRect){0, 0, TILE_WIDTH, TILE_HEIGHT});
|
||||||
|
|
||||||
// Prepara para dibujar sobre la textura
|
// Prepara para dibujar sobre la textura
|
||||||
auto temp = SDL_GetRenderTarget(renderer_);
|
auto *temp = SDL_GetRenderTarget(renderer_);
|
||||||
SDL_SetRenderTarget(renderer_, canvas_);
|
SDL_SetRenderTarget(renderer_, canvas_);
|
||||||
|
|
||||||
// Rellena la textura con el tile
|
// Rellena la textura con el tile
|
||||||
@@ -114,17 +114,17 @@ void TiledBG::updateStop() {
|
|||||||
|
|
||||||
// Desacelerar si estamos cerca de completar el ciclo (ventana a punto de regresar a 0)
|
// Desacelerar si estamos cerca de completar el ciclo (ventana a punto de regresar a 0)
|
||||||
if (window_.x >= TILE_WIDTH - UMBRAL) {
|
if (window_.x >= TILE_WIDTH - UMBRAL) {
|
||||||
speed_ /= 1.05f; // Reduce gradualmente la velocidad
|
speed_ /= 1.05F; // Reduce gradualmente la velocidad
|
||||||
|
|
||||||
// Asegura que no baje demasiado
|
// Asegura que no baje demasiado
|
||||||
if (speed_ < 0.1f) {
|
if (speed_ < 0.1F) {
|
||||||
speed_ = 0.1f;
|
speed_ = 0.1F;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si estamos en 0, detener
|
// Si estamos en 0, detener
|
||||||
if (window_.x == 0) {
|
if (window_.x == 0) {
|
||||||
speed_ = 0.0f;
|
speed_ = 0.0F;
|
||||||
stopping_ = false; // Desactivamos el estado de "stopping"
|
stopping_ = false; // Desactivamos el estado de "stopping"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_SetTextureColorMod, SDL_Renderer, SDL_Texture
|
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_SetTextureColorMod, SDL_Renderer, SDL_Texture
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "utils.h" // Para Color
|
#include "utils.h" // Para Color
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ class TiledBG {
|
|||||||
void setColor(Color color) { SDL_SetTextureColorMod(canvas_, color.r, color.g, color.b); } // Cambia el color de la textura
|
void setColor(Color color) { SDL_SetTextureColorMod(canvas_, color.r, color.g, color.b); } // Cambia el color de la textura
|
||||||
|
|
||||||
// --- Getters ---
|
// --- Getters ---
|
||||||
[[nodiscard]] auto isStopped() const -> bool { return speed_ == 0.0f; } // Indica si está parado
|
[[nodiscard]] auto isStopped() const -> bool { return speed_ == 0.0F; } // Indica si está parado
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Constantes ---
|
// --- Constantes ---
|
||||||
@@ -50,9 +51,9 @@ private:
|
|||||||
SDL_FRect pos_; // Posición y tamaño del mosaico
|
SDL_FRect pos_; // Posición y tamaño del mosaico
|
||||||
SDL_FRect window_; // Ventana visible para la textura de fondo del título
|
SDL_FRect window_; // Ventana visible para la textura de fondo del título
|
||||||
TiledBGMode mode_; // Tipo de movimiento del mosaico
|
TiledBGMode mode_; // Tipo de movimiento del mosaico
|
||||||
double sin_[360]; // Vector con los valores del seno precalculados
|
std::array<double, 360> sin_; // Vector con los valores del seno precalculados
|
||||||
float desp_ = 0.0f; // Desplazamiento aplicado
|
float desp_ = 0.0F; // Desplazamiento aplicado
|
||||||
float speed_ = 1.0f; // Incremento que se añade al desplazamiento a cada bucle
|
float speed_ = 1.0F; // Incremento que se añade al desplazamiento a cada bucle
|
||||||
bool stopping_ = false; // Indica si se está deteniendo
|
bool stopping_ = false; // Indica si se está deteniendo
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
|
|||||||
@@ -123,8 +123,9 @@ class ListOption : public MenuOption {
|
|||||||
return value_list_.empty() ? "" : value_list_[list_index_];
|
return value_list_.empty() ? "" : value_list_[list_index_];
|
||||||
}
|
}
|
||||||
void adjustValue(bool adjust_up) override {
|
void adjustValue(bool adjust_up) override {
|
||||||
if (value_list_.empty())
|
if (value_list_.empty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
size_t size = value_list_.size();
|
size_t size = value_list_.size();
|
||||||
list_index_ = (adjust_up) ? (list_index_ + 1) % size
|
list_index_ = (adjust_up) ? (list_index_ + 1) % size
|
||||||
: (list_index_ + size - 1) % size;
|
: (list_index_ + size - 1) % size;
|
||||||
@@ -164,8 +165,9 @@ class ActionOption : public MenuOption {
|
|||||||
|
|
||||||
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::SELECT; }
|
[[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::SELECT; }
|
||||||
void executeAction() override {
|
void executeAction() override {
|
||||||
if (action_)
|
if (action_) {
|
||||||
action_();
|
action_();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -103,10 +103,10 @@ void MenuRenderer::setAnchors(const ServiceMenu *menu_state) {
|
|||||||
auto MenuRenderer::calculateNewRect(const ServiceMenu *menu_state) -> SDL_FRect {
|
auto MenuRenderer::calculateNewRect(const ServiceMenu *menu_state) -> SDL_FRect {
|
||||||
width_ = getMenuWidthForGroup(menu_state->getCurrentGroup());
|
width_ = getMenuWidthForGroup(menu_state->getCurrentGroup());
|
||||||
const auto &display_options = menu_state->getDisplayOptions();
|
const auto &display_options = menu_state->getDisplayOptions();
|
||||||
lower_height_ = ((display_options.size() > 0 ? display_options.size() - 1 : 0) * (options_height_ + options_padding_)) + options_height_ + (lower_padding_ * 2);
|
lower_height_ = ((!display_options.empty() ? display_options.size() - 1 : 0) * (options_height_ + options_padding_)) + options_height_ + (lower_padding_ * 2);
|
||||||
height_ = upper_height_ + lower_height_;
|
height_ = upper_height_ + lower_height_;
|
||||||
|
|
||||||
return {(param.game.width - width_) / 2.0f, (param.game.height - height_) / 2.0f, (float)width_, (float)height_};
|
return {(param.game.width - width_) / 2.0F, (param.game.height - height_) / 2.0F, (float)width_, (float)height_};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuRenderer::resize(const ServiceMenu *menu_state) {
|
void MenuRenderer::resize(const ServiceMenu *menu_state) {
|
||||||
@@ -131,11 +131,12 @@ void MenuRenderer::setSize(const ServiceMenu *menu_state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MenuRenderer::updateResizeAnimation() {
|
void MenuRenderer::updateResizeAnimation() {
|
||||||
if (!resizing_)
|
if (!resizing_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
++resize_anim_step_;
|
++resize_anim_step_;
|
||||||
float t = static_cast<float>(resize_anim_step_) / resize_anim_steps_;
|
float t = static_cast<float>(resize_anim_step_) / resize_anim_steps_;
|
||||||
if (t >= 1.0f) {
|
if (t >= 1.0F) {
|
||||||
rect_ = setRect(rect_anim_to_);
|
rect_ = setRect(rect_anim_to_);
|
||||||
resizing_ = false;
|
resizing_ = false;
|
||||||
return;
|
return;
|
||||||
@@ -150,15 +151,17 @@ void MenuRenderer::updateResizeAnimation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MenuRenderer::precalculateMenuWidths(const std::vector<std::unique_ptr<MenuOption>> &all_options, const ServiceMenu *menu_state) {
|
void MenuRenderer::precalculateMenuWidths(const std::vector<std::unique_ptr<MenuOption>> &all_options, const ServiceMenu *menu_state) {
|
||||||
for (int &w : group_menu_widths_)
|
for (int &w : group_menu_widths_) {
|
||||||
w = ServiceMenu::MIN_WIDTH;
|
w = ServiceMenu::MIN_WIDTH;
|
||||||
|
}
|
||||||
for (int group = 0; group < 5; ++group) {
|
for (int group = 0; group < 5; ++group) {
|
||||||
auto sg = static_cast<ServiceMenu::SettingsGroup>(group);
|
auto sg = static_cast<ServiceMenu::SettingsGroup>(group);
|
||||||
int max_option_width = 0;
|
int max_option_width = 0;
|
||||||
int max_value_width = 0;
|
int max_value_width = 0;
|
||||||
for (const auto &option : all_options) {
|
for (const auto &option : all_options) {
|
||||||
if (option->getGroup() != sg)
|
if (option->getGroup() != sg) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
max_option_width = std::max(max_option_width, element_text_->lenght(option->getCaption(), -2));
|
max_option_width = std::max(max_option_width, element_text_->lenght(option->getCaption(), -2));
|
||||||
if (menu_state->getCurrentGroupAlignment() == ServiceMenu::GroupAlignment::LEFT) {
|
if (menu_state->getCurrentGroupAlignment() == ServiceMenu::GroupAlignment::LEFT) {
|
||||||
max_value_width = std::max(max_value_width, option->getMaxValueWidth(element_text_.get()));
|
max_value_width = std::max(max_value_width, option->getMaxValueWidth(element_text_.get()));
|
||||||
@@ -185,7 +188,7 @@ void MenuRenderer::updateColorCounter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto MenuRenderer::getAnimatedSelectedColor() -> Color {
|
auto MenuRenderer::getAnimatedSelectedColor() const -> Color {
|
||||||
static auto color_cycle_ = generateMirroredCycle(param.service_menu.selected_color, ColorCycleStyle::HUE_WAVE);
|
static auto color_cycle_ = generateMirroredCycle(param.service_menu.selected_color, ColorCycleStyle::HUE_WAVE);
|
||||||
return color_cycle_.at(color_counter_ % color_cycle_.size());
|
return color_cycle_.at(color_counter_ % color_cycle_.size());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // Para SDL_FRect, Uint32
|
#include <SDL3/SDL.h> // Para SDL_FRect, Uint32
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstddef> // Para size_t
|
#include <cstddef> // Para size_t
|
||||||
#include <memory> // Para shared_ptr, unique_ptr
|
#include <memory> // Para shared_ptr, unique_ptr
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
@@ -14,59 +15,59 @@ class MenuOption;
|
|||||||
class Text;
|
class Text;
|
||||||
|
|
||||||
class MenuRenderer {
|
class MenuRenderer {
|
||||||
public:
|
public:
|
||||||
MenuRenderer(const ServiceMenu *menu_state, std::shared_ptr<Text> element_text, std::shared_ptr<Text> title_text);
|
MenuRenderer(const ServiceMenu *menu_state, std::shared_ptr<Text> element_text, std::shared_ptr<Text> title_text);
|
||||||
|
|
||||||
// Métodos principales de la vista
|
// Métodos principales de la vista
|
||||||
void render(const ServiceMenu *menu_state);
|
void render(const ServiceMenu *menu_state);
|
||||||
void update(const ServiceMenu *menu_state);
|
void update(const ServiceMenu *menu_state);
|
||||||
|
|
||||||
// Método para notificar al renderer que el layout puede haber cambiado
|
// Método para notificar al renderer que el layout puede haber cambiado
|
||||||
void onLayoutChanged(const ServiceMenu *menu_state);
|
void onLayoutChanged(const ServiceMenu *menu_state);
|
||||||
void setLayout(const ServiceMenu *menu_state);
|
void setLayout(const ServiceMenu *menu_state);
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
[[nodiscard]] auto getRect() const -> const SDL_FRect & { return rect_; }
|
[[nodiscard]] auto getRect() const -> const SDL_FRect & { return rect_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Referencias a los renderizadores de texto ---
|
// --- Referencias a los renderizadores de texto ---
|
||||||
std::shared_ptr<Text> element_text_;
|
std::shared_ptr<Text> element_text_;
|
||||||
std::shared_ptr<Text> title_text_;
|
std::shared_ptr<Text> title_text_;
|
||||||
|
|
||||||
// --- Variables de estado de la vista (layout y animación) ---
|
// --- Variables de estado de la vista (layout y animación) ---
|
||||||
SDL_FRect rect_{};
|
SDL_FRect rect_{};
|
||||||
SDL_FRect border_rect_{};
|
SDL_FRect border_rect_{};
|
||||||
size_t width_ = 0;
|
size_t width_ = 0;
|
||||||
size_t height_ = 0;
|
size_t height_ = 0;
|
||||||
size_t options_height_ = 0;
|
size_t options_height_ = 0;
|
||||||
size_t options_padding_ = 0;
|
size_t options_padding_ = 0;
|
||||||
size_t options_y_ = 0;
|
size_t options_y_ = 0;
|
||||||
size_t title_height_ = 0;
|
size_t title_height_ = 0;
|
||||||
size_t title_padding_ = 0;
|
size_t title_padding_ = 0;
|
||||||
size_t upper_height_ = 0;
|
size_t upper_height_ = 0;
|
||||||
size_t lower_height_ = 0;
|
size_t lower_height_ = 0;
|
||||||
size_t lower_padding_ = 0;
|
size_t lower_padding_ = 0;
|
||||||
Uint32 color_counter_ = 0;
|
Uint32 color_counter_ = 0;
|
||||||
|
|
||||||
// --- Variables para animación de resize ---
|
// --- Variables para animación de resize ---
|
||||||
SDL_FRect rect_anim_from_{};
|
SDL_FRect rect_anim_from_{};
|
||||||
SDL_FRect rect_anim_to_{};
|
SDL_FRect rect_anim_to_{};
|
||||||
int resize_anim_step_ = 0;
|
int resize_anim_step_ = 0;
|
||||||
int resize_anim_steps_ = 8;
|
int resize_anim_steps_ = 8;
|
||||||
bool resizing_ = false;
|
bool resizing_ = false;
|
||||||
|
|
||||||
// --- Anchos precalculados ---
|
// --- Anchos precalculados ---
|
||||||
int group_menu_widths_[5]{};
|
std::array<int, 5> group_menu_widths_ = {};
|
||||||
|
|
||||||
// --- Métodos privados de la vista ---
|
// --- Métodos privados de la vista ---
|
||||||
void setAnchors(const ServiceMenu *menu_state);
|
void setAnchors(const ServiceMenu *menu_state);
|
||||||
auto calculateNewRect(const ServiceMenu *menu_state) -> SDL_FRect;
|
auto calculateNewRect(const ServiceMenu *menu_state) -> SDL_FRect;
|
||||||
void resize(const ServiceMenu *menu_state);
|
void resize(const ServiceMenu *menu_state);
|
||||||
void setSize(const ServiceMenu *menu_state);
|
void setSize(const ServiceMenu *menu_state);
|
||||||
void updateResizeAnimation();
|
void updateResizeAnimation();
|
||||||
void precalculateMenuWidths(const std::vector<std::unique_ptr<MenuOption>> &all_options, const ServiceMenu *menu_state);
|
void precalculateMenuWidths(const std::vector<std::unique_ptr<MenuOption>> &all_options, const ServiceMenu *menu_state);
|
||||||
[[nodiscard]] auto getMenuWidthForGroup(ServiceMenu::SettingsGroup group) const -> int;
|
[[nodiscard]] auto getMenuWidthForGroup(ServiceMenu::SettingsGroup group) const -> int;
|
||||||
auto getAnimatedSelectedColor() -> Color;
|
[[nodiscard]] auto getAnimatedSelectedColor() const -> Color;
|
||||||
void updateColorCounter();
|
void updateColorCounter();
|
||||||
auto setRect(SDL_FRect rect) -> SDL_FRect;
|
auto setRect(SDL_FRect rect) -> SDL_FRect;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,20 +40,22 @@ void ServiceMenu::toggle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServiceMenu::render() {
|
void ServiceMenu::render() {
|
||||||
if (!enabled_)
|
if (!enabled_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
renderer_->render(this);
|
renderer_->render(this);
|
||||||
|
|
||||||
// El mensaje de reinicio se dibuja por encima, así que lo gestionamos aquí
|
// El mensaje de reinicio se dibuja por encima, así que lo gestionamos aquí
|
||||||
const float MSG_X = param.game.game_area.center_x;
|
const float MSG_X = param.game.game_area.center_x;
|
||||||
const float MSG_Y = renderer_->getRect().y + 39.0f;
|
const float MSG_Y = renderer_->getRect().y + 39.0F;
|
||||||
restart_message_ui_->setPosition(MSG_X, MSG_Y);
|
restart_message_ui_->setPosition(MSG_X, MSG_Y);
|
||||||
restart_message_ui_->render();
|
restart_message_ui_->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceMenu::update() {
|
void ServiceMenu::update() {
|
||||||
if (!enabled_)
|
if (!enabled_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
renderer_->update(this);
|
renderer_->update(this);
|
||||||
|
|
||||||
@@ -77,22 +79,25 @@ void ServiceMenu::reset() {
|
|||||||
|
|
||||||
// --- Lógica de Navegación ---
|
// --- Lógica de Navegación ---
|
||||||
void ServiceMenu::setSelectorUp() {
|
void ServiceMenu::setSelectorUp() {
|
||||||
if (display_options_.empty())
|
if (display_options_.empty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
selected_ = (selected_ > 0) ? selected_ - 1 : display_options_.size() - 1;
|
selected_ = (selected_ > 0) ? selected_ - 1 : display_options_.size() - 1;
|
||||||
playMoveSound();
|
playMoveSound();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceMenu::setSelectorDown() {
|
void ServiceMenu::setSelectorDown() {
|
||||||
if (display_options_.empty())
|
if (display_options_.empty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
selected_ = (selected_ + 1) % display_options_.size();
|
selected_ = (selected_ + 1) % display_options_.size();
|
||||||
playMoveSound();
|
playMoveSound();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceMenu::adjustOption(bool adjust_up) {
|
void ServiceMenu::adjustOption(bool adjust_up) {
|
||||||
if (display_options_.empty())
|
if (display_options_.empty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
auto &selected_option = display_options_.at(selected_);
|
auto &selected_option = display_options_.at(selected_);
|
||||||
if (selected_option->getBehavior() == MenuOption::Behavior::ADJUST) {
|
if (selected_option->getBehavior() == MenuOption::Behavior::ADJUST) {
|
||||||
selected_option->adjustValue(adjust_up);
|
selected_option->adjustValue(adjust_up);
|
||||||
@@ -102,18 +107,20 @@ void ServiceMenu::adjustOption(bool adjust_up) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServiceMenu::selectOption() {
|
void ServiceMenu::selectOption() {
|
||||||
if (display_options_.empty())
|
if (display_options_.empty()) {
|
||||||
return;
|
return;
|
||||||
if (current_settings_group_ == SettingsGroup::MAIN)
|
}
|
||||||
|
if (current_settings_group_ == SettingsGroup::MAIN) {
|
||||||
main_menu_selected_ = selected_;
|
main_menu_selected_ = selected_;
|
||||||
|
}
|
||||||
|
|
||||||
auto *selected_option = display_options_.at(selected_);
|
auto *selected_option = display_options_.at(selected_);
|
||||||
if (!selected_option) {
|
if (selected_option == nullptr) {
|
||||||
// This shouldn't happen in normal operation, but protects against null pointer
|
// This shouldn't happen in normal operation, but protects against null pointer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto folder = dynamic_cast<FolderOption *>(selected_option)) {
|
if (auto *folder = dynamic_cast<FolderOption *>(selected_option)) {
|
||||||
previous_settings_group_ = current_settings_group_;
|
previous_settings_group_ = current_settings_group_;
|
||||||
current_settings_group_ = folder->getTargetGroup();
|
current_settings_group_ = folder->getTargetGroup();
|
||||||
selected_ = 0;
|
selected_ = 0;
|
||||||
@@ -166,12 +173,15 @@ void ServiceMenu::updateMenu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServiceMenu::applySettings() {
|
void ServiceMenu::applySettings() {
|
||||||
if (current_settings_group_ == SettingsGroup::VIDEO)
|
if (current_settings_group_ == SettingsGroup::VIDEO) {
|
||||||
applyVideoSettings();
|
applyVideoSettings();
|
||||||
if (current_settings_group_ == SettingsGroup::AUDIO)
|
}
|
||||||
|
if (current_settings_group_ == SettingsGroup::AUDIO) {
|
||||||
applyAudioSettings();
|
applyAudioSettings();
|
||||||
if (current_settings_group_ == SettingsGroup::SETTINGS)
|
}
|
||||||
|
if (current_settings_group_ == SettingsGroup::SETTINGS) {
|
||||||
applySettingsSettings();
|
applySettingsSettings();
|
||||||
|
}
|
||||||
|
|
||||||
// Actualiza los valores de las opciones
|
// Actualiza los valores de las opciones
|
||||||
updateOptionPairs();
|
updateOptionPairs();
|
||||||
@@ -262,7 +272,7 @@ void ServiceMenu::initializeOptions() {
|
|||||||
// Sincroniza los valores de las opciones tipo lista
|
// Sincroniza los valores de las opciones tipo lista
|
||||||
void ServiceMenu::adjustListValues() {
|
void ServiceMenu::adjustListValues() {
|
||||||
for (auto &option : options_) {
|
for (auto &option : options_) {
|
||||||
if (auto list_option = dynamic_cast<ListOption *>(option.get())) {
|
if (auto *list_option = dynamic_cast<ListOption *>(option.get())) {
|
||||||
list_option->sync();
|
list_option->sync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,7 +285,7 @@ void ServiceMenu::playSelectSound() { Audio::get()->playSound("service_menu_sele
|
|||||||
void ServiceMenu::playBackSound() { Audio::get()->playSound("service_menu_select.wav", Audio::Group::INTERFACE); }
|
void ServiceMenu::playBackSound() { Audio::get()->playSound("service_menu_select.wav", Audio::Group::INTERFACE); }
|
||||||
|
|
||||||
// Devuelve el nombre del grupo como string para el título
|
// Devuelve el nombre del grupo como string para el título
|
||||||
auto ServiceMenu::settingsGroupToString(SettingsGroup group) const -> std::string {
|
auto ServiceMenu::settingsGroupToString(SettingsGroup group) -> std::string {
|
||||||
switch (group) {
|
switch (group) {
|
||||||
case SettingsGroup::MAIN:
|
case SettingsGroup::MAIN:
|
||||||
return Lang::getText("[SERVICE_MENU] TITLE");
|
return Lang::getText("[SERVICE_MENU] TITLE");
|
||||||
@@ -295,15 +305,17 @@ auto ServiceMenu::settingsGroupToString(SettingsGroup group) const -> std::strin
|
|||||||
// Establece el estado de oculto de ciertas opciones
|
// Establece el estado de oculto de ciertas opciones
|
||||||
void ServiceMenu::setHiddenOptions() {
|
void ServiceMenu::setHiddenOptions() {
|
||||||
{
|
{
|
||||||
auto option = getOptionByCaption(Lang::getText("[SERVICE_MENU] WINDOW_SIZE"));
|
auto *option = getOptionByCaption(Lang::getText("[SERVICE_MENU] WINDOW_SIZE"));
|
||||||
if (option)
|
if (option != nullptr) {
|
||||||
option->setHidden(Options::video.fullscreen);
|
option->setHidden(Options::video.fullscreen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto option = getOptionByCaption(Lang::getText("[SERVICE_MENU] SHUTDOWN"));
|
auto *option = getOptionByCaption(Lang::getText("[SERVICE_MENU] SHUTDOWN"));
|
||||||
if (option)
|
if (option != nullptr) {
|
||||||
option->setHidden(!Options::settings.shutdown_enabled);
|
option->setHidden(!Options::settings.shutdown_enabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMenu(); // El menú debe refrescarse si algo se oculta
|
updateMenu(); // El menú debe refrescarse si algo se oculta
|
||||||
|
|||||||
@@ -31,10 +31,14 @@ class ServiceMenu {
|
|||||||
static constexpr size_t MIN_WIDTH = 240;
|
static constexpr size_t MIN_WIDTH = 240;
|
||||||
static constexpr size_t MIN_GAP_OPTION_VALUE = 30;
|
static constexpr size_t MIN_GAP_OPTION_VALUE = 30;
|
||||||
|
|
||||||
|
// --- Métodos de singleton ---
|
||||||
static void init();
|
static void init();
|
||||||
static void destroy();
|
static void destroy();
|
||||||
static auto get() -> ServiceMenu *;
|
static auto get() -> ServiceMenu *;
|
||||||
|
ServiceMenu(const ServiceMenu &) = delete;
|
||||||
|
auto operator=(const ServiceMenu &) -> ServiceMenu & = delete;
|
||||||
|
|
||||||
|
// --- Métodos principales ---
|
||||||
void toggle();
|
void toggle();
|
||||||
void render();
|
void render();
|
||||||
void update();
|
void update();
|
||||||
@@ -85,21 +89,21 @@ private:
|
|||||||
void updateMenu();
|
void updateMenu();
|
||||||
void applySettings();
|
void applySettings();
|
||||||
void applyVideoSettings();
|
void applyVideoSettings();
|
||||||
void applyAudioSettings();
|
static void applyAudioSettings();
|
||||||
void applySettingsSettings();
|
void applySettingsSettings();
|
||||||
[[nodiscard]] auto getOptionByCaption(const std::string &caption) const -> MenuOption *;
|
[[nodiscard]] auto getOptionByCaption(const std::string &caption) const -> MenuOption *;
|
||||||
void adjustListValues();
|
void adjustListValues();
|
||||||
void playMoveSound();
|
static void playMoveSound();
|
||||||
void playAdjustSound();
|
static void playAdjustSound();
|
||||||
void playSelectSound();
|
static void playSelectSound();
|
||||||
void playBackSound();
|
static void playBackSound();
|
||||||
[[nodiscard]] auto settingsGroupToString(SettingsGroup group) const -> std::string;
|
[[nodiscard]] static auto settingsGroupToString(SettingsGroup group) -> std::string;
|
||||||
void setHiddenOptions();
|
void setHiddenOptions();
|
||||||
|
|
||||||
// --- Singleton ---
|
// --- Constructores y destructor privados (singleton) ---
|
||||||
ServiceMenu();
|
ServiceMenu();
|
||||||
~ServiceMenu() = default;
|
~ServiceMenu() = default;
|
||||||
ServiceMenu(const ServiceMenu &) = delete;
|
|
||||||
auto operator=(const ServiceMenu &) -> ServiceMenu & = delete;
|
// --- Instancia singleton ---
|
||||||
static ServiceMenu *instance;
|
static ServiceMenu *instance;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,11 +11,12 @@ UIMessage::UIMessage(std::shared_ptr<Text> text_renderer, std::string message_te
|
|||||||
|
|
||||||
// Muestra el mensaje en la posición base_x, base_y con animación de entrada desde arriba
|
// Muestra el mensaje en la posición base_x, base_y con animación de entrada desde arriba
|
||||||
void UIMessage::show() {
|
void UIMessage::show() {
|
||||||
if (visible_ && target_y_ == 0.0f)
|
if (visible_ && target_y_ == 0.0F) {
|
||||||
return; // Ya está visible y quieto
|
return; // Ya está visible y quieto
|
||||||
|
}
|
||||||
|
|
||||||
start_y_ = DESP; // Empieza 8 píxeles arriba de la posición base
|
start_y_ = DESP; // Empieza 8 píxeles arriba de la posición base
|
||||||
target_y_ = 0.0f; // La posición final es la base
|
target_y_ = 0.0F; // La posición final es la base
|
||||||
y_offset_ = start_y_;
|
y_offset_ = start_y_;
|
||||||
anim_step_ = 0;
|
anim_step_ = 0;
|
||||||
animating_ = true;
|
animating_ = true;
|
||||||
@@ -24,8 +25,9 @@ void UIMessage::show() {
|
|||||||
|
|
||||||
// Oculta el mensaje con animación de salida hacia arriba
|
// Oculta el mensaje con animación de salida hacia arriba
|
||||||
void UIMessage::hide() {
|
void UIMessage::hide() {
|
||||||
if (!visible_)
|
if (!visible_) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
start_y_ = y_offset_; // Comienza desde la posición actual
|
start_y_ = y_offset_; // Comienza desde la posición actual
|
||||||
target_y_ = DESP; // Termina 8 píxeles arriba de la base
|
target_y_ = DESP; // Termina 8 píxeles arriba de la base
|
||||||
@@ -58,8 +60,9 @@ void UIMessage::updateAnimation() {
|
|||||||
if (anim_step_ >= ANIMATION_STEPS) {
|
if (anim_step_ >= ANIMATION_STEPS) {
|
||||||
y_offset_ = target_y_;
|
y_offset_ = target_y_;
|
||||||
animating_ = false;
|
animating_ = false;
|
||||||
if (target_y_ < 0.0f)
|
if (target_y_ < 0.0F) {
|
||||||
visible_ = false;
|
visible_ = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,16 +40,16 @@ class UIMessage {
|
|||||||
// --- Estado ---
|
// --- Estado ---
|
||||||
bool visible_ = false; // Indica si el mensaje está visible
|
bool visible_ = false; // Indica si el mensaje está visible
|
||||||
bool animating_ = false; // Indica si el mensaje está en proceso de animación
|
bool animating_ = false; // Indica si el mensaje está en proceso de animación
|
||||||
float base_x_ = 0.0f; // Posición X base donde se muestra el mensaje
|
float base_x_ = 0.0F; // Posición X base donde se muestra el mensaje
|
||||||
float base_y_ = 0.0f; // Posición Y base donde se muestra el mensaje
|
float base_y_ = 0.0F; // Posición Y base donde se muestra el mensaje
|
||||||
float y_offset_ = 0.0f; // Desplazamiento vertical actual del mensaje (para animación)
|
float y_offset_ = 0.0F; // Desplazamiento vertical actual del mensaje (para animación)
|
||||||
|
|
||||||
// --- Animación ---
|
// --- Animación ---
|
||||||
float start_y_ = 0.0f; // Posición Y inicial de la animación
|
float start_y_ = 0.0F; // Posición Y inicial de la animación
|
||||||
float target_y_ = 0.0f; // Posición Y objetivo de la animación
|
float target_y_ = 0.0F; // Posición Y objetivo de la animación
|
||||||
int anim_step_ = 0; // Paso actual de la animación
|
int anim_step_ = 0; // Paso actual de la animación
|
||||||
static constexpr int ANIMATION_STEPS = 8; // Número total de pasos de la animación
|
static constexpr int ANIMATION_STEPS = 8; // Número total de pasos de la animación
|
||||||
static constexpr float DESP = -8.0f; // Distancia a desplazarse
|
static constexpr float DESP = -8.0F; // Distancia a desplazarse
|
||||||
|
|
||||||
// Actualiza la interpolación de la animación (ease out/in cubic)
|
// Actualiza la interpolación de la animación (ease out/in cubic)
|
||||||
void updateAnimation();
|
void updateAnimation();
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class Writer {
|
|||||||
int pos_x_ = 0; // Posición en el eje X donde empezar a escribir el texto
|
int pos_x_ = 0; // Posición en el eje X donde empezar a escribir el texto
|
||||||
int pos_y_ = 0; // Posición en el eje Y donde empezar a escribir el texto
|
int pos_y_ = 0; // Posición en el eje Y donde empezar a escribir el texto
|
||||||
int kerning_ = 0; // Kerning del texto, es decir, espaciado entre caracteres
|
int kerning_ = 0; // Kerning del texto, es decir, espaciado entre caracteres
|
||||||
std::string caption_ = std::string(); // El texto para escribir
|
std::string caption_; // El texto para escribir
|
||||||
int speed_ = 0; // Velocidad de escritura
|
int speed_ = 0; // Velocidad de escritura
|
||||||
int writing_counter_ = 0; // Temporizador de escritura para cada caracter
|
int writing_counter_ = 0; // Temporizador de escritura para cada caracter
|
||||||
int index_ = 0; // Posición del texto que se está escribiendo
|
int index_ = 0; // Posición del texto que se está escribiendo
|
||||||
|
|||||||
Reference in New Issue
Block a user