Compare commits

8 Commits

24 changed files with 247 additions and 75 deletions

View File

@@ -30,7 +30,9 @@ Les tecles son les següents:
- **Tecla F5**: Activa o desactiva l'audio
- **Tecla F6**: Canvia el idioma del joc i reinicia
- **Tecla F6**: Activa o desactiva el dispar automàtic
- **Tecla F7**: Canvia el idioma del joc i reinicia
- **Tecla F10**: Reset

BIN
data/sound/voice_coffee.wav Normal file

Binary file not shown.

BIN
data/sound/voice_no.wav Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -5,6 +5,8 @@
#include "param.h" // Para Param, param, ParamBalloon, ParamGame
#include "sprite.h" // Para Sprite
#include "texture.h" // Para Texture
#include "resource.h"
#include "jail_audio.h"
// Constructor
Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, SDL_Rect play_area, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation)
@@ -36,6 +38,7 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
power_ = BALLOON_POWER[index];
menace_ = BALLOON_MENACE[index];
score_ = BALLOON_SCORE[index];
sound_ = BALLOON_SOUND[index];
break;
}
@@ -50,14 +53,16 @@ Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel
power_ = BALLOON_POWER[index];
menace_ = BALLOON_MENACE[index];
score_ = BALLOON_SCORE[index];
sound_ = BALLOON_SOUND[index];
break;
}
case BalloonType::POWERBALL:
{
const int index = 3;
constexpr int index = 3;
h_ = w_ = BALLOON_SIZE[4];
sound_ = BALLOON_SOUND[3];
power_ = score_ = menace_ = 0;
vy_ = 0;
@@ -145,6 +150,7 @@ void Balloon::move()
const float max_x = play_area_.x + play_area_.w - w_ + clip;
if (x_ < min_x || x_ > max_x)
{
playSound();
x_ = std::clamp(x_, min_x, max_x);
vx_ = -vx_;
// Activa el efecto de rebote o invierte la rotación
@@ -179,6 +185,7 @@ void Balloon::move()
const int min_y = play_area_.y;
if (y_ < min_y)
{
playSound();
y_ = min_y;
vy_ = -vy_;
enableBounce();
@@ -189,6 +196,7 @@ void Balloon::move()
const int max_y = play_area_.y + play_area_.h - h_;
if (y_ > max_y)
{
playSound();
y_ = max_y;
vy_ = -default_vy_;
if (type_ != BalloonType::POWERBALL)
@@ -402,3 +410,12 @@ void Balloon::useNormalColor()
use_reversed_colors_ = false;
setAnimation();
}
// Reproduce el sonido al rebotar
void Balloon::playSound()
{
if (sound_enabled_)
{
JA_PlaySound(Resource::get()->getSound(sound_));
}
}

View File

@@ -17,6 +17,7 @@ constexpr int BALLOON_SCORE[] = {50, 100, 200, 400};
constexpr int BALLOON_POWER[] = {1, 3, 7, 15};
constexpr int BALLOON_MENACE[] = {1, 2, 4, 8};
constexpr int BALLOON_SIZE[] = {10, 16, 26, 48, 49};
const std::string BALLOON_SOUND[] = {"bubble1.wav", "bubble2.wav", "bubble3.wav", "bubble4.wav"};
// Tamaños de globo
enum class BalloonSize : Uint8
@@ -113,6 +114,8 @@ private:
float speed_; // Velocidad a la que se mueven los globos
Uint8 power_; // Cantidad de poder que alberga el globo
SDL_Rect play_area_; // Zona por donde se puede mover el globo
std::string sound_; // Archivo de sonido que hace el globo al rebotar
bool sound_enabled_ = false; // Indica si ha de sonar el sonido del globo al rebotar
// Alinea el circulo de colisión con la posición del objeto globo
void shiftColliders();
@@ -138,6 +141,9 @@ private:
// Establece la animación correspondiente
void setAnimation();
// Reproduce el sonido al rebotar
void playSound();
public:
// Constructor
Balloon(
@@ -208,4 +214,5 @@ public:
void setVelY(float vel_y) { vy_ = vel_y; }
void setSpeed(float speed) { speed_ = speed; }
void setInvulnerable(bool value) { invulnerable_ = value; }
void setSound(bool value) { sound_enabled_ = value; }
};

View File

@@ -372,3 +372,12 @@ int BalloonManager::getMenace()
return std::accumulate(balloons_.begin(), balloons_.end(), 0, [](int sum, const auto &balloon)
{ return sum + (balloon->isEnabled() ? balloon->getMenace() : 0); });
}
// Establece el sonido de los globos
void BalloonManager::setSounds(bool value)
{
for (auto &balloon : balloons_)
{
balloon->setSound(value);
}
}

View File

@@ -111,6 +111,9 @@ public:
// Obtiene el nivel de ameza actual generado por los globos
int getMenace();
// Establece el sonido de los globos
void setSounds(bool value);
// Getters
float getBalloonSpeed() const { return balloon_speed_; }
Balloons &getBalloons() { return balloons_; }

View File

@@ -180,8 +180,9 @@ void Director::bindInputs()
Input::get()->bindKey(InputType::WINDOW_FULLSCREEN, SDL_SCANCODE_F3);
Input::get()->bindKey(InputType::VIDEO_SHADERS, SDL_SCANCODE_F4);
Input::get()->bindKey(InputType::MUTE, SDL_SCANCODE_F5);
Input::get()->bindKey(InputType::CHANGE_LANG, SDL_SCANCODE_F6);
Input::get()->bindKey(InputType::SHOWINFO, SDL_SCANCODE_F7);
Input::get()->bindKey(InputType::AUTO_FIRE, SDL_SCANCODE_F6);
Input::get()->bindKey(InputType::CHANGE_LANG, SDL_SCANCODE_F7);
Input::get()->bindKey(InputType::SHOWINFO, SDL_SCANCODE_F8);
Input::get()->bindKey(InputType::RESET, SDL_SCANCODE_F10);
// Asigna botones a inputs
@@ -295,8 +296,15 @@ bool Director::initSDL()
}
*/
// Obtiene información sobre la pantalla
SDL_DisplayMode DM;
SDL_GetCurrentDisplayMode(0, &DM);
// Calcula el máximo factor de zoom que se puede aplicar a la pantalla
options.video.window.max_size = std::min(DM.w / param.game.width, DM.h / param.game.height);
options.video.window.size = std::min(options.video.window.size, options.video.window.max_size);
// Muestra información sobre el tamaño de la pantalla y de la ventana de juego
std::cout << "\nCurrent display mode: " << DM.w << "x" << DM.h << " @ " << DM.refresh_rate << "Hz" << std::endl;
std::cout << "Window resolution : " << param.game.width << "x" << param.game.height << " x" << options.video.window.size << std::endl;
@@ -397,6 +405,9 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/sound/powerball.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/notify.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/logo.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/voice_coffee.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/voice_power_up.wav", AssetType::SOUND);
Asset::get()->add(prefix + "/data/sound/voice_no.wav", AssetType::SOUND);
// Shaders
Asset::get()->add(prefix + "/data/shaders/crtpi_256.glsl", AssetType::DATA);

View File

@@ -100,6 +100,8 @@ void Fade::update()
SDL_RenderFillRect(renderer_, &rect1_);
SDL_RenderFillRect(renderer_, &rect2_);
value_ = calculateValue(0, counter_, i);
}
// Deja el renderizador como estaba
@@ -139,6 +141,8 @@ void Fade::update()
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_));
// Comprueba si ha terminado
if (counter_ * fade_random_squares_mult_ / fade_random_squares_delay_ >= num_squares_width_ * num_squares_height_)
{
@@ -338,3 +342,11 @@ void Fade::cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
// Vuelve a dejar el renderizador como estaba
SDL_SetRenderTarget(renderer_, temp);
}
// Calcula el valor del estado del fade
int Fade::calculateValue(int min, int max, int current)
{
if (max == 0)
return 0;
return std::clamp(current * 100 / max, 0, 100);
}

View File

@@ -45,6 +45,7 @@ private:
int fade_random_squares_mult_; // Cantidad de cuadrados que se pintaran cada vez
int post_duration_; // Duración posterior del fade tras finalizar
int post_counter_; // Contador para la duración posterior
int value_ = 0; // Estado actual del fade entre 0 y 100
// Inicializa las variables
void init();
@@ -52,6 +53,9 @@ private:
// Limpia el backbuffer
void cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
// Calcula el valor del estado del fade
int calculateValue(int min, int max, int current);
public:
// Constructor
Fade();
@@ -88,4 +92,7 @@ public:
// Establece la duración posterior
void setPost(int value);
// Getters
int getValue() const { return value_; }
};

View File

@@ -44,7 +44,8 @@ Game::Game(int player_id, int current_stage, bool demo)
input_(Input::get()),
background_(std::make_unique<Background>()),
canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.play_area.rect.w, param.game.play_area.rect.h)),
fade_(std::make_unique<Fade>()),
fade_in_(std::make_unique<Fade>()),
fade_out_(std::make_unique<Fade>()),
balloon_manager_(std::make_unique<BalloonManager>())
{
// Pasa variables
@@ -63,9 +64,15 @@ Game::Game(int player_id, int current_stage, bool demo)
Scoreboard::init();
scoreboard_ = Scoreboard::get();
fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
fade_->setPost(param.fade.post_duration);
fade_->setType(FadeType::VENETIAN);
fade_in_->setColor(fade_color.r, fade_color.g, fade_color.b);
fade_in_->setPost(param.fade.post_duration);
fade_in_->setType(FadeType::RANDOM_SQUARE);
fade_in_->setMode(FadeMode::IN);
fade_in_->activate();
fade_out_->setColor(fade_color.r, fade_color.g, fade_color.b);
fade_out_->setPost(param.fade.post_duration);
fade_out_->setType(FadeType::VENETIAN);
background_->setPos(param.game.play_area.rect);
@@ -213,8 +220,8 @@ void Game::updatePlayers()
if (demo_.enabled && allPlayersAreNotPlaying())
{
fade_->setType(FadeType::RANDOM_SQUARE);
fade_->activate();
fade_out_->setType(FadeType::RANDOM_SQUARE);
fade_out_->activate();
}
}
@@ -283,25 +290,21 @@ void Game::updateGameOverState()
if (game_over_counter_ > 0)
{
if (game_over_counter_ == GAME_OVER_COUNTER_)
{
createMessage({paths_.at(2), paths_.at(3)}, Resource::get()->getTexture("game_over"));
stopMusic();
balloon_manager_->setSounds(true);
}
game_over_counter_--;
if ((game_over_counter_ == 250) || (game_over_counter_ == 200) || (game_over_counter_ == 180) || (game_over_counter_ == 120) || (game_over_counter_ == 60))
{
// Hace sonar aleatoriamente uno de los 4 sonidos de burbujas
const auto index = rand() % 4;
JA_Sound_t *sound[4] = {Resource::get()->getSound("bubble1.wav"), Resource::get()->getSound("bubble2.wav"), Resource::get()->getSound("bubble3.wav"), Resource::get()->getSound("bubble4.wav")};
JA_PlaySound(sound[index], 0);
}
if (game_over_counter_ == 150)
{
fade_->activate();
fade_out_->activate();
}
}
if (fade_->hasEnded())
if (fade_out_->hasEnded())
{
if (game_completed_counter_ > 0)
{
@@ -474,6 +477,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
(item->getWidth() - game_text_textures_[4]->getWidth()) / 2;
createItemText(x, game_text_textures_[4]);
}
JA_PlaySound(Resource::get()->getSound("voice_coffee.wav"));
break;
}
case ItemType::COFFEE_MACHINE:
@@ -484,6 +488,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player)
item->getPosX() +
(item->getWidth() - game_text_textures_[3]->getWidth()) / 2;
createItemText(x, game_text_textures_[3]);
JA_PlaySound(Resource::get()->getSound("voice_power_up.wav"));
break;
}
default:
@@ -722,7 +727,9 @@ void Game::createMessage(const std::vector<Path> &paths, std::shared_ptr<Texture
// Inicializa
for (const auto &path : paths)
{
path_sprites_.back()->addPath(path, true);
}
path_sprites_.back()->enable();
}
@@ -815,13 +822,13 @@ void Game::killPlayer(std::shared_ptr<Player> &player)
else
{
// Si no tiene cafes, muere
pauseMusic();
// pauseMusic();
balloon_manager_->stopAllBalloons();
JA_PlaySound(Resource::get()->getSound("player_collision.wav"));
screen_->shake();
JA_PlaySound(Resource::get()->getSound("coffeeout.wav"));
JA_PlaySound(Resource::get()->getSound("voice_no.wav"));
player->setPlayingState(PlayerState::DYING);
allPlayersAreNotPlaying() ? stopMusic() : resumeMusic();
// allPlayersAreNotPlaying() ? stopMusic() : resumeMusic();
}
}
@@ -935,7 +942,8 @@ void Game::render()
scoreboard_->render();
// Dibuja el fade
fade_->render();
fade_in_->render();
fade_out_->render();
// Vuelca el contenido del renderizador en pantalla
screen_->blit();
@@ -960,10 +968,8 @@ void Game::disableTimeStopItem()
// Comprueba si la música ha de estar sonando
void Game::checkMusicStatus()
{
// Si la música no está sonando
if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED)
// Si se ha completado el juego o los jugadores han terminado, detiene la música
state_ == GameState::COMPLETED || allPlayersAreGameOver() ? JA_StopMusic() : JA_PlayMusic(Resource::get()->getMusic("playing.ogg"));
state_ == GameState::COMPLETED || allPlayersAreGameOver() ? stopMusic() : playMusic();
}
// Bucle para el juego
@@ -998,8 +1004,7 @@ void Game::initPaths()
paths_.emplace_back(Path(createPath(x1, x2, PathType::HORIZONTAL, y, 80, easeInQuint), 0));
}
// Recorrido para el texto de "Last Stage!" o de "X stages left" o "Game Over"
// (2,3)
// Recorrido para el texto de "Last Stage!" o de "X stages left" o "Game Over" (2,3)
{
const auto &texture = Resource::get()->getTexture("last_stage");
const auto h = texture->getHeight();
@@ -1691,6 +1696,16 @@ void Game::resumeMusic()
}
}
// Hace sonar la música
void Game::playMusic()
{
// Si la música no está sonando
if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED)
{
JA_PlayMusic(Resource::get()->getMusic("playing.ogg"));
}
}
// Detiene la música
void Game::stopMusic()
{
@@ -1712,12 +1727,12 @@ void Game::updateDemo()
// Activa el fundido antes de acabar con los datos de la demo
if (demo_.counter == TOTAL_DEMO_DATA - 200)
{
fade_->setType(FadeType::RANDOM_SQUARE);
fade_->activate();
fade_out_->setType(FadeType::RANDOM_SQUARE);
fade_out_->activate();
}
// Si ha terminado el fundido, cambia de sección
if (fade_->hasEnded())
if (fade_out_->hasEnded())
{
section::name = section::Name::HI_SCORE_TABLE;
return;
@@ -1756,7 +1771,8 @@ void Game::updateGame()
Stage::addPower(5);
}
#endif
fade_->update();
fade_in_->update();
fade_out_->update();
updatePlayers();
checkPlayersStatusPlaying();
updateScoreboard();

View File

@@ -140,7 +140,8 @@ private:
std::vector<std::vector<std::string>> item_animations_; // Vector con las animaciones de los items
std::vector<std::vector<std::string>> player_animations_; // Vector con las animaciones del jugador
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
std::unique_ptr<Fade> fade_in_; // Objeto para renderizar fades
std::unique_ptr<Fade> fade_out_; // Objeto para renderizar fades
std::unique_ptr<BalloonManager> balloon_manager_; // Objeto para gestionar los globos
std::vector<Path> paths_; // Vector con los recorridos precalculados almacenados
@@ -373,6 +374,9 @@ private:
// Reanuda la música
void resumeMusic();
// Hace sonar la música
void playMusic();
// Detiene la música
void stopMusic();

View File

@@ -1,4 +1,5 @@
#include "game_logo.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_render.h> // Para SDL_FLIP_HORIZONTAL
#include <algorithm> // Para max
#include "animated_sprite.h" // Para AnimatedSprite
@@ -8,6 +9,11 @@
#include "smart_sprite.h" // Para SmartSprite
#include "sprite.h" // Para Sprite
#include "texture.h" // Para Texture
#include "screen.h"
constexpr int ZOOM_FACTOR = 5;
constexpr int FLASH_DELAY = 3;
constexpr int FLASH_LENGHT = FLASH_DELAY + 3;
// Constructor
GameLogo::GameLogo(int x, int y)
@@ -32,15 +38,8 @@ void GameLogo::init()
// Variables
coffee_crisis_status_ = Status::DISABLED;
arcade_edition_status_ = Status::DISABLED;
shake_.desp = 1;
shake_.delay = 2;
shake_.lenght = 8;
shake_.remaining = shake_.lenght;
shake_.counter = shake_.delay;
shake_.origin = xp;
zoom_ = 3.0f;
shake_.init(1, 2, 8, xp);
zoom_ = 3.0f * ZOOM_FACTOR;
// Inicializa el bitmap de 'Coffee'
coffee_sprite_->setPosX(xp);
@@ -122,10 +121,11 @@ void GameLogo::update()
if (coffee_sprite_->hasFinished() && crisis_sprite_->hasFinished())
{
coffee_crisis_status_ = Status::SHAKING;
arcade_edition_status_ = Status::MOVING;
// Reproduce el efecto sonoro
JA_PlaySound(Resource::get()->getSound("title.wav"));
Screen::get()->flash(Color(0xFF, 0xFF, 0xFF), FLASH_LENGHT, FLASH_DELAY);
Screen::get()->shake();
}
break;
@@ -133,7 +133,7 @@ void GameLogo::update()
case Status::SHAKING:
{
// Agita el logo
// Agita "COFFEE CRISIS"
if (shake_.remaining > 0)
{
if (shake_.counter > 0)
@@ -154,6 +154,7 @@ void GameLogo::update()
coffee_sprite_->setPosX(shake_.origin);
crisis_sprite_->setPosX(shake_.origin + 15);
coffee_crisis_status_ = Status::FINISHED;
arcade_edition_status_ = Status::MOVING;
}
dust_right_sprite_->update();
@@ -178,12 +179,42 @@ void GameLogo::update()
{
case Status::MOVING:
{
zoom_ -= 0.1f;
zoom_ -= 0.1f * ZOOM_FACTOR;
arcade_edition_sprite_->setZoom(zoom_);
if (zoom_ <= 1.0f)
{
arcade_edition_status_ = Status::FINISHED;
arcade_edition_status_ = Status::SHAKING;
zoom_ = 1.0f;
arcade_edition_sprite_->setZoom(zoom_);
shake_.init(1, 2, 8, arcade_edition_sprite_->getX());
JA_PlaySound(Resource::get()->getSound("title.wav"));
Screen::get()->flash(Color(0xFF, 0xFF, 0xFF), FLASH_LENGHT, FLASH_DELAY);
Screen::get()->shake();
}
break;
}
case Status::SHAKING:
{
// Agita "ARCADE EDITION"
if (shake_.remaining > 0)
{
if (shake_.counter > 0)
{
shake_.counter--;
}
else
{
shake_.counter = shake_.delay;
const auto desp = shake_.remaining % 2 == 0 ? shake_.desp * (-1) : shake_.desp;
arcade_edition_sprite_->setX(shake_.origin + desp);
shake_.remaining--;
}
}
else
{
arcade_edition_sprite_->setX(shake_.origin);
arcade_edition_status_ = Status::FINISHED;
}
break;
}
@@ -191,6 +222,13 @@ void GameLogo::update()
default:
break;
}
if (coffee_crisis_status_ == Status::FINISHED &&
arcade_edition_status_ == Status::FINISHED &&
post_finished_counter_ > 0)
{
--post_finished_counter_;
}
}
// Activa la clase
@@ -203,7 +241,7 @@ void GameLogo::enable()
// Indica si ha terminado la animación
bool GameLogo::hasFinished() const
{
return coffee_crisis_status_ == Status::FINISHED && arcade_edition_status_ == Status::FINISHED;
return post_finished_counter_ == 0;
}
// Recarga las texturas

View File

@@ -20,12 +20,30 @@ private:
struct Shake
{
int desp; // Pixels de desplazamiento para agitar la pantalla en el eje x
int delay; // Retraso entre cada desplazamiento de la pantalla al agitarse
int counter; // Contador para el retraso
int lenght; // Cantidad de desplazamientos a realizar
int remaining; // Cantidad de desplazamientos pendientes a realizar
int desp = 1; // Pixels de desplazamiento para agitar la pantalla en el eje x
int delay = 2; // Retraso entre cada desplazamiento de la pantalla al agitarse
int lenght = 8; // Cantidad de desplazamientos a realizar
int remaining = lenght; // Cantidad de desplazamientos pendientes a realizar
int counter = delay; // Contador para el retraso
int origin; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento
// Constructor por defect
Shake() = default;
// Constructor
Shake(int d, int de, int l, int o)
: desp(d), delay(de), lenght(l), remaining(l), counter(de), origin(o) {}
// Inicializa los miembros
void init(int d, int de, int l, int o)
{
desp = d;
delay = de;
lenght = l;
remaining = l;
counter = de;
origin = o;
}
};
// Objetos y punteros
@@ -46,6 +64,7 @@ private:
int x_; // Posición donde dibujar el logo
int y_; // Posición donde dibujar el logo
float zoom_; // Zoom aplicado al texto "ARCADE EDITION"
int post_finished_counter_ = 1; // Contador final una vez terminada las animaciones de los logos
Status coffee_crisis_status_ = Status::DISABLED; // Estado en el que se encuentra el texto "COFFEE CRISIS"
Status arcade_edition_status_ = Status::DISABLED; // Estado en el que se encuentra el texto "ARCADE_EDITION"

View File

@@ -108,6 +108,13 @@ namespace globalInputs
Notifier::get()->showText({getLangName(options.game.language)});
}
// Cambia el modo de disparo
void toggleFireMode()
{
options.game.autofire = !options.game.autofire;
Notifier::get()->showText({"Autofire " + boolToOnOff(options.game.autofire)});
}
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
void check()
{
@@ -162,6 +169,13 @@ namespace globalInputs
return;
}
// Autofire
if (Input::get()->checkInput(InputType::AUTO_FIRE, INPUT_DO_NOT_ALLOW_REPEAT, InputDeviceToUse::KEYBOARD))
{
toggleFireMode();
return;
}
// Idioma
if (Input::get()->checkInput(InputType::CHANGE_LANG, INPUT_DO_NOT_ALLOW_REPEAT, InputDeviceToUse::KEYBOARD))
{

View File

@@ -44,6 +44,7 @@ enum class InputType : int
SHOWINFO,
CONFIG,
SWAP_CONTROLLERS,
AUTO_FIRE,
// Input obligatorio
NONE,

View File

@@ -59,7 +59,7 @@ Logo::~Logo()
{
jail_texture_->setColor(255, 255, 255);
since_texture_->setColor(255, 255, 255);
JA_PauseChannel(-1);
JA_StopChannel(-1);
}
// Recarga todas las texturas
@@ -101,7 +101,6 @@ void Logo::checkInput()
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
if (Input::get()->checkAnyButtonPressed())
{
JA_StopMusic();
section::name = section::Name::TITLE;
section::options = section::Options::TITLE_1;
return;

View File

@@ -23,7 +23,8 @@ enum class GameDifficulty
// Estructura para las opciones de la ventana
struct OptionsWindow
{
int size; // Contiene el valor por el que se multiplica el tamaño de la ventana
int size = 1; // Contiene el valor por el que se multiplica el tamaño de la ventana
int max_size = 1; // Tamaño máximo para que el tamaño de la ventana no sea mayor que el tamaño de la pantalla
};
// Estructura con opciones para el video

View File

@@ -8,6 +8,8 @@
#include "param.h" // Para Param, ParamGame, param
#include "scoreboard.h" // Para Scoreboard, ScoreboardMode
#include "texture.h" // Para Texture
#include "resource.h"
#include "jail_audio.h"
// Constructor
Player::Player(int id, float x, int y, bool demo, SDL_Rect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations)
@@ -175,6 +177,7 @@ void Player::move()
if ((player_sprite_->getPosX() < play_area_.x) || (player_sprite_->getPosX() + WIDTH_ > play_area_.w))
{
player_sprite_->setVelX(-player_sprite_->getVelX());
JA_PlaySound(Resource::get()->getSound("bubble4.wav"));
}
// Si el cadaver toca el suelo cambia el estado
@@ -188,6 +191,7 @@ void Player::move()
pos_y_ = default_pos_y_;
player_sprite_->clear();
shiftSprite();
JA_PlaySound(Resource::get()->getSound("bubble4.wav"));
}
else
{
@@ -195,6 +199,7 @@ void Player::move()
player_sprite_->setPosY(play_area_.h - HEIGHT_);
player_sprite_->setVelY(player_sprite_->getVelY() * -0.5f);
player_sprite_->setVelX(player_sprite_->getVelX() * 0.75f);
JA_PlaySound(Resource::get()->getSound("bubble4.wav"));
}
}
break;

View File

@@ -235,7 +235,7 @@ void Screen::decWindowSize()
void Screen::incWindowSize()
{
++options.video.window.size;
options.video.window.size = std::min(options.video.window.size, 4);
options.video.window.size = std::min(options.video.window.size, options.video.window.max_size);
setVideoMode(ScreenVideoMode::WINDOW);
}
@@ -308,15 +308,15 @@ void Screen::updateShakeEffect()
}
// Pone la pantalla de color
void Screen::flash(Color color, int lenght)
void Screen::flash(Color color, int lenght, int delay)
{
flash_effect_ = FlashEffect(true, lenght, color);
flash_effect_ = FlashEffect(true, lenght, delay, color);
}
// Actualiza y dibuja el efecto de flash en la pantalla
void Screen::renderFlash()
{
if (flash_effect_.enabled)
if (flash_effect_.isRendarable())
{
SDL_SetRenderDrawColor(renderer_, flash_effect_.color.r, flash_effect_.color.g, flash_effect_.color.b, 0xFF);
SDL_RenderClear(renderer_);
@@ -326,10 +326,7 @@ void Screen::renderFlash()
// Actualiza el efecto de flash
void Screen::updateFlash()
{
if (flash_effect_.enabled)
{
flash_effect_.counter > 0 ? flash_effect_.counter-- : flash_effect_.enabled = false;
}
flash_effect_.update();
}
// Atenua la pantalla

View File

@@ -51,12 +51,20 @@ private:
struct FlashEffect
{
bool enabled; // Indica si el efecto está activo
int lenght; // Duración del efecto
int delay; // Frames iniciales en los que no se aplica
int counter; // Contador para el efecto
Color color; // Color del efecto
// Constructor
explicit FlashEffect(bool en = false, int cnt = 0, Color col = Color(0xFF, 0xFF, 0xFF))
: enabled(en), counter(cnt), color(col) {}
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) {}
// Actualiza
void update() { (enabled && counter > 0) ? counter-- : enabled = false; }
// Indica si se pude dibujar
bool isRendarable() { return enabled && counter < lenght - delay; }
};
struct ShakeEffect
@@ -155,7 +163,7 @@ public:
void shake();
// Pone la pantalla de color
void flash(Color color, int lenght);
void flash(Color color, int lenght, int delay = 0);
// Activa / desactiva los shaders
void toggleShaders();

View File

@@ -54,6 +54,7 @@ Title::Title()
Title::~Title()
{
Resource::get()->getTexture("smb2.gif")->setPalette(0);
JA_StopChannel(-1);
}
// Actualiza las variables del objeto
@@ -74,6 +75,7 @@ void Title::update()
// Comprueba el fundido y si se ha acabado
fade_->update();
JA_SetMusicVolume(100 - fade_->getValue());
if (fade_->hasEnded())
{
if (post_fade_ == -1)

View File

@@ -18,7 +18,7 @@ namespace section
constexpr const char TEXT_COPYRIGHT[] = "@2020,2024 JailDesigner";
// Parámetros
constexpr bool ALLOW_TITLE_ANIMATION_SKIP = true;
constexpr bool ALLOW_TITLE_ANIMATION_SKIP = false;
/*
Esta clase gestiona un estado del programa. Se encarga de la parte del titulo o menu