diff --git a/source/animated_sprite.cpp b/source/animated_sprite.cpp index 352143b..da0c483 100644 --- a/source/animated_sprite.cpp +++ b/source/animated_sprite.cpp @@ -6,148 +6,6 @@ #include // for basic_stringstream #include "texture.h" // for Texture -// Carga la animación desde un fichero -std::vector loadAnimationFromFile(std::shared_ptr texture, std::string file_path) -{ - // Inicializa variables - std::vector animations; - auto frames_per_row = 0; - auto frame_width = 0; - auto frame_height = 0; - auto max_tiles = 0; - - const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1); - std::ifstream file(file_path); - std::string line; - - // El fichero se puede abrir - if (file.good()) - { - // Procesa el fichero linea a linea - std::cout << "Animation loaded: " << file_name << std::endl; - while (std::getline(file, line)) - { - // Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación - if (line == "[animation]") - { - Animation animation; - animation.counter = 0; - animation.current_frame = 0; - animation.completed = false; - animation.name.clear(); - animation.speed = 5; - animation.loop = 0; - animation.frames.clear(); - - do - { - std::getline(file, line); - - // Encuentra la posición del caracter '=' - int pos = line.find("="); - - // Procesa las dos subcadenas - if (pos != static_cast(line.npos)) - { - if (line.substr(0, pos) == "name") - { - animation.name = line.substr(pos + 1, line.length()); - } - - else if (line.substr(0, pos) == "speed") - { - animation.speed = std::stoi(line.substr(pos + 1, line.length())); - } - - else if (line.substr(0, pos) == "loop") - { - animation.loop = std::stoi(line.substr(pos + 1, line.length())); - } - - else if (line.substr(0, pos) == "frames") - { - // Se introducen los valores separados por comas en un vector - std::stringstream ss(line.substr(pos + 1, line.length())); - std::string tmp; - SDL_Rect rect = {0, 0, frame_width, frame_height}; - while (getline(ss, tmp, ',')) - { - // Comprueba que el tile no sea mayor que el maximo indice permitido - const auto num_tile = std::stoi(tmp) > max_tiles ? 0 : std::stoi(tmp); - rect.x = (num_tile % frames_per_row) * frame_width; - rect.y = (num_tile / frames_per_row) * frame_height; - animation.frames.push_back(rect); - } - } - - else - { - std::cout << "Warning: file " << file_name.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; - } - } - } while (line != "[/animation]"); - - // Añade la animación al vector de animaciones - animations.push_back(animation); - } - - // En caso contrario se parsea el fichero para buscar las variables y los valores - else - { - // Encuentra la posición del caracter '=' - int pos = line.find("="); - - // Procesa las dos subcadenas - if (pos != (int)line.npos) - { - if (line.substr(0, pos) == "frames_per_row") - { - frames_per_row = std::stoi(line.substr(pos + 1, line.length())); - } - - else if (line.substr(0, pos) == "frame_width") - { - frame_width = std::stoi(line.substr(pos + 1, line.length())); - } - - else if (line.substr(0, pos) == "frame_height") - { - frame_height = std::stoi(line.substr(pos + 1, line.length())); - } - - else - { - std::cout << "Warning: file " << file_name.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; - } - - // Normaliza valores - if (frames_per_row == 0 && frame_width > 0) - { - frames_per_row = texture->getWidth() / frame_width; - } - - if (max_tiles == 0 && frame_width > 0 && frame_height > 0) - { - const auto w = texture->getWidth() / frame_width; - const auto h = texture->getHeight() / frame_height; - max_tiles = w * h; - } - } - } - } - - // Cierra el fichero - file.close(); - } - // El fichero no se puede abrir - else - { - std::cout << "Warning: Unable to open " << file_name.c_str() << " file" << std::endl; - } - - return animations; -} - // Constructor AnimatedSprite::AnimatedSprite(std::shared_ptr texture, const std::string &file_path) : MovingSprite(texture), @@ -156,8 +14,9 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr texture, const std::stri // Carga las animaciones if (!file_path.empty()) { - animations_ = loadAnimationFromFile(texture, file_path); + animations_ = loadFromFile(file_path); } + //setSpriteClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]); } AnimatedSprite::AnimatedSprite(std::shared_ptr texture, std::vector *animations) @@ -168,6 +27,7 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr texture, std::vector *source) } // Pone un valor por defecto - setPosition((SDL_Rect){0, 0, frame_width, frame_height}); + setWidth(frame_width); + setHeight(frame_height); return success; } @@ -514,4 +375,150 @@ void AnimatedSprite::resetAnimation() animations_[current_animation_].current_frame = 0; animations_[current_animation_].counter = 0; animations_[current_animation_].completed = false; +} + +// Carga la animación desde un fichero +std::vector AnimatedSprite::loadFromFile(std::string file_path) +{ + // Inicializa variables + std::vector animations; + auto frames_per_row = 0; + auto frame_width = 0; + auto frame_height = 0; + auto max_tiles = 0; + + const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1); + std::ifstream file(file_path); + std::string line; + + // El fichero se puede abrir + if (file.good()) + { + // Procesa el fichero linea a linea + std::cout << "Animation loaded: " << file_name << std::endl; + while (std::getline(file, line)) + { + // Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación + if (line == "[animation]") + { + Animation animation; + animation.counter = 0; + animation.current_frame = 0; + animation.completed = false; + animation.name.clear(); + animation.speed = 5; + animation.loop = 0; + animation.frames.clear(); + + do + { + std::getline(file, line); + + // Encuentra la posición del caracter '=' + int pos = line.find("="); + + // Procesa las dos subcadenas + if (pos != static_cast(line.npos)) + { + if (line.substr(0, pos) == "name") + { + animation.name = line.substr(pos + 1, line.length()); + } + + else if (line.substr(0, pos) == "speed") + { + animation.speed = std::stoi(line.substr(pos + 1, line.length())); + } + + else if (line.substr(0, pos) == "loop") + { + animation.loop = std::stoi(line.substr(pos + 1, line.length())); + } + + else if (line.substr(0, pos) == "frames") + { + // Se introducen los valores separados por comas en un vector + std::stringstream ss(line.substr(pos + 1, line.length())); + std::string tmp; + SDL_Rect rect = {0, 0, frame_width, frame_height}; + while (getline(ss, tmp, ',')) + { + // Comprueba que el tile no sea mayor que el maximo indice permitido + const auto num_tile = std::stoi(tmp) > max_tiles ? 0 : std::stoi(tmp); + rect.x = (num_tile % frames_per_row) * frame_width; + rect.y = (num_tile / frames_per_row) * frame_height; + animation.frames.push_back(rect); + } + } + + else + { + std::cout << "Warning: file " << file_name.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; + } + } + } while (line != "[/animation]"); + + // Añade la animación al vector de animaciones + animations.push_back(animation); + } + + // En caso contrario se parsea el fichero para buscar las variables y los valores + else + { + // Encuentra la posición del caracter '=' + int pos = line.find("="); + + // Procesa las dos subcadenas + if (pos != (int)line.npos) + { + if (line.substr(0, pos) == "frames_per_row") + { + frames_per_row = std::stoi(line.substr(pos + 1, line.length())); + } + + else if (line.substr(0, pos) == "frame_width") + { + frame_width = std::stoi(line.substr(pos + 1, line.length())); + } + + else if (line.substr(0, pos) == "frame_height") + { + frame_height = std::stoi(line.substr(pos + 1, line.length())); + } + + else + { + std::cout << "Warning: file " << file_name.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; + } + + // Normaliza valores + if (frames_per_row == 0 && frame_width > 0) + { + frames_per_row = texture_->getWidth() / frame_width; + } + + if (max_tiles == 0 && frame_width > 0 && frame_height > 0) + { + const auto w = texture_->getWidth() / frame_width; + const auto h = texture_->getHeight() / frame_height; + max_tiles = w * h; + } + } + } + } + + // Cierra el fichero + file.close(); + } + // El fichero no se puede abrir + else + { + std::cout << "Warning: Unable to open " << file_name.c_str() << " file" << std::endl; + } + + // Pone un valor por defecto + setWidth(frame_width); + setHeight(frame_height); + + return animations; } \ No newline at end of file diff --git a/source/animated_sprite.h b/source/animated_sprite.h index f12a9b1..8aafd98 100644 --- a/source/animated_sprite.h +++ b/source/animated_sprite.h @@ -19,9 +19,6 @@ struct Animation int counter; // Contador para las animaciones }; -// Carga la animación desde un fichero -std::vector loadAnimationFromFile(std::shared_ptr texture, std::string filePath); - class AnimatedSprite : public MovingSprite { protected: @@ -32,6 +29,12 @@ protected: // Calcula el frame correspondiente a la animación actual void animate(); + // Carga la animación desde un fichero + std::vector loadFromFile(std::string filePath); + + // Carga la animación desde un vector + bool loadFromVector(std::vector *source); + public: // Constructor AnimatedSprite(std::shared_ptr texture, const std::string &file_path); @@ -75,9 +78,6 @@ public: // Obtiene el indice de la animación a partir del nombre int getIndex(const std::string &name); - // Carga la animación desde un vector - bool loadFromVector(std::vector *source); - // Establece la animacion actual void setCurrentAnimation(const std::string &name = "default"); void setCurrentAnimation(int index = 0); diff --git a/source/background.cpp b/source/background.cpp index 48bffd0..526fdfe 100644 --- a/source/background.cpp +++ b/source/background.cpp @@ -69,17 +69,17 @@ Background::Background(SDL_Renderer *renderer) constexpr float top_clouds_speed = 0.1f; constexpr float bottom_clouds_speed = 0.05f; - top_clouds_sprite_a_->setVelX(-top_clouds_speed); 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_b_->setVelX(-top_clouds_speed); top_clouds_sprite_b_->setSpriteClip(0, 0, top_clouds_texture_->getWidth(), top_clouds_texture_->getHeight()); + top_clouds_sprite_b_->setVelX(-top_clouds_speed); - bottom_clouds_sprite_a_->setVelX(-bottom_clouds_speed); bottom_clouds_sprite_a_->setSpriteClip(0, 0, bottom_clouds_texture_->getWidth(), bottom_clouds_texture_->getHeight()); + bottom_clouds_sprite_a_->setVelX(-bottom_clouds_speed); - bottom_clouds_sprite_b_->setVelX(-bottom_clouds_speed); bottom_clouds_sprite_b_->setSpriteClip(0, 0, bottom_clouds_texture_->getWidth(), bottom_clouds_texture_->getHeight()); + bottom_clouds_sprite_b_->setVelX(-bottom_clouds_speed); buildings_sprite_->setY(base_ - buildings_sprite_->getHeight()); grass_sprite_->setY(base_ - grass_sprite_->getHeight()); diff --git a/source/director.cpp b/source/director.cpp index e4a5558..94d7c07 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -58,9 +58,12 @@ Director::Director(int argc, const char *argv[]) #ifndef VERBOSE // Deshabilita todos los std::cout std::ostream null_stream(nullptr); - std::streambuf *orig_buf = std::cout.rdbuf(null_stream.rdbuf()); + std::streambuf *orig_buf; + orig_buf = std::cout.rdbuf(null_stream.rdbuf()); #endif + std::cout << "Game start" << std::endl; + // Comprueba los parametros del programa checkProgramArguments(argc, argv); @@ -700,8 +703,14 @@ int Director::run() shutdownSystem(); #endif - const int return_code = section::options == section::Options::QUIT_NORMAL ? 0 : 1; - return return_code; + const auto return_code = (section::options == section::Options::QUIT_NORMAL) ? "keyboard" : "controller"; + std::cout << "\nGame end with " << return_code << std::endl; + + + // Habilita de nuevo los std::cout + //std::cout.rdbuf(orig_buf); + + return (return_code == std::string("keyboard")) ? 0 : 1; } // Obtiene una fichero a partir de un lang::Code diff --git a/source/director.h b/source/director.h index 81449c4..dc2b514 100644 --- a/source/director.h +++ b/source/director.h @@ -1,10 +1,13 @@ #pragma once -#include // for SDL_Renderer -#include // for SDL_Window -#include // for string -#include // for vector -namespace lang { enum class Code : int; } +#include // for SDL_Renderer +#include // for SDL_Window +#include // for string +#include // for vector +namespace lang +{ + enum class Code : int; +} struct MusicFile; struct SoundFile; @@ -15,15 +18,16 @@ class Director { private: // Objetos y punteros - SDL_Window *window_; // La ventana donde dibujamos + SDL_Window *window_; // La ventana donde dibujamos SDL_Renderer *renderer_; // El renderizador de la ventana + //std::streambuf *orig_buf; ///< Puntero al buffer de flujo original para restaurar std::cout // Variables - std::string executable_path_; // Path del ejecutable - std::string system_folder_; // Carpeta del sistema donde guardar datos + std::string executable_path_; // Path del ejecutable + std::string system_folder_; // Carpeta del sistema donde guardar datos std::string param_file_argument_; // Argumento para gestionar el fichero con los parametros del programa - std::vector sounds_; // Vector con los sonidos - std::vector musics_; // Vector con las musicas + std::vector sounds_; // Vector con los sonidos + std::vector musics_; // Vector con las musicas // Inicializa jail_audio void initJailAudio(); diff --git a/source/game_logo.cpp b/source/game_logo.cpp index 3af25e6..f7afcb5 100644 --- a/source/game_logo.cpp +++ b/source/game_logo.cpp @@ -124,7 +124,9 @@ void GameLogo::render() // Actualiza la lógica de la clase void GameLogo::update() { - if (status_ == Status::MOVING) + switch (status_) + { + case Status::MOVING: { coffee_sprite_->update(); crisis_sprite_->update(); @@ -137,9 +139,11 @@ void GameLogo::update() // Reproduce el efecto sonoro JA_PlaySound(crash_sound_); } + + break; } - else if (status_ == Status::SHAKING) + case Status::SHAKING: { // Agita el logo if (shake_.remaining > 0) @@ -166,12 +170,20 @@ void GameLogo::update() dust_right_sprite_->update(); dust_left_sprite_->update(); + + break; } - else if (status_ == Status::FINISHED) + case Status::FINISHED: { dust_right_sprite_->update(); dust_left_sprite_->update(); + + break; + } + + default: + break; } } diff --git a/source/main.cpp b/source/main.cpp index 759fe3e..f7f4fc1 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -13,16 +13,9 @@ Actualizando a la versión "Arcade Edition" en 08/05/2024 int main(int argc, char *argv[]) { - std::cout << "Game start" << std::endl; - // Crea el objeto Director auto director = std::make_unique(argc, const_cast(argv)); // Bucle principal - const auto exit = director->run(); - - const auto endType = exit == 0 ? "keyboard" : "controller"; - std::cout << "\nGame end with " << endType << std::endl; - - return exit; + return director->run(); } diff --git a/source/moving_sprite.cpp b/source/moving_sprite.cpp index 7c751c2..6f0a51c 100644 --- a/source/moving_sprite.cpp +++ b/source/moving_sprite.cpp @@ -6,6 +6,10 @@ MovingSprite::MovingSprite(std::shared_ptr texture, SDL_Rect pos, Rotat : Sprite(texture, pos), x_(pos.x), y_(pos.y), + vx_(0.0f), + vy_(0.0f), + ax_(0.0f), + ay_(0.0f), rotate_(rotate), zoom_w_(zoom_w), zoom_h_(zoom_h), @@ -15,17 +19,27 @@ MovingSprite::MovingSprite(std::shared_ptr texture, SDL_Rect pos) : Sprite(texture, pos), x_(pos.x), y_(pos.y), - rotate_({false, 0, 0, 0.0f, 0.0f, nullptr}), + vx_(0.0f), + vy_(0.0f), + ax_(0.0f), + ay_(0.0f), + rotate_(Rotate()), zoom_w_(1.0f), zoom_h_(1.0f), flip_(SDL_FLIP_NONE) {} MovingSprite::MovingSprite(std::shared_ptr texture) : Sprite(texture), - rotate_({false, 0, 0, 0.0f, 0.0f, nullptr}), + x_(0.0f), + y_(0.0f), + vx_(0.0f), + vy_(0.0f), + ax_(0.0f), + ay_(0.0f), + rotate_(Rotate()), zoom_w_(1.0f), zoom_h_(1.0f), - flip_(SDL_FLIP_NONE) {} + flip_(SDL_FLIP_NONE) { Sprite::clear(); } // Reinicia todas las variables void MovingSprite::clear() @@ -39,20 +53,14 @@ void MovingSprite::clear() 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 - rotate_.enabled = false; // Indica si ha de rotar - rotate_.counter = 0; // Contador - rotate_.speed = 0; // Velocidad de giro - rotate_.angle = 0.0f; // Angulo para dibujarlo - rotate_.amount = 0.0f; // Cantidad de grados a girar en cada iteración - rotate_.center = nullptr; // Centro de rotación + rotate_ = Rotate(); // Inicializa la estructura zoom_w_ = 1.0f; // Zoom aplicado a la anchura zoom_h_ = 1.0f; // Zoom aplicado a la altura flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite - setPos((SDL_Rect){0, 0, 0, 0}); - setSpriteClip((SDL_Rect){0, 0, 0, 0}); + Sprite::clear(); } // Mueve el sprite @@ -64,7 +72,8 @@ void MovingSprite::move() vx_ += ax_; vy_ += ay_; - syncPos(); + pos_.x = static_cast(x_); + pos_.y = static_cast(y_); } // Actualiza las variables internas del objeto @@ -237,8 +246,8 @@ float MovingSprite::getAccelY() const // Establece la posición y_ el tamaño del objeto void MovingSprite::setPos(SDL_Rect rect) { - x_ = (float)rect.x; - y_ = (float)rect.y; + x_ = static_cast(rect.x); + y_ = static_cast(rect.y); pos_ = rect; } @@ -249,21 +258,22 @@ void MovingSprite::setPos(float x, float y) x_ = x; y_ = y; - syncPos(); + pos_.x = static_cast(x_); + pos_.y = static_cast(y_); } // Establece el valor de la variable void MovingSprite::setPosX(float value) { x_ = value; - pos_.x = (int)x_; + pos_.x = static_cast(x_); } // Establece el valor de la variable void MovingSprite::setPosY(float value) { y_ = value; - pos_.y = (int)y_; + pos_.y = static_cast(y_); } // Establece el valor de la variable @@ -288,11 +298,4 @@ void MovingSprite::setAccelX(float value) void MovingSprite::setAccelY(float value) { ay_ = value; -} - -// Sincroniza la posición -void MovingSprite::syncPos() -{ - pos_.x = (int)x_; - pos_.y = (int)y_; -} +} \ No newline at end of file diff --git a/source/moving_sprite.h b/source/moving_sprite.h index 4e1c7d7..788b0ba 100644 --- a/source/moving_sprite.h +++ b/source/moving_sprite.h @@ -19,6 +19,8 @@ public: double angle; // Angulo para dibujarlo float amount; // Cantidad de grados a girar en cada iteración SDL_Point *center; // Centro de rotación + + Rotate() : enabled(false), counter(0), speed(0), angle(0.0), amount(0.0f), center(nullptr) {} }; protected: @@ -45,9 +47,6 @@ protected: // Rota el sprite void rotate(); - // Sincroniza la posición - void syncPos(); - public: // Constructor MovingSprite(std::shared_ptr texture, SDL_Rect pos, MovingSprite::Rotate rotate, float zoom_w, float zoom_h, SDL_RendererFlip flip); @@ -60,8 +59,8 @@ public: // Actualiza las variables internas del objeto virtual void update(); - // Reinicia todas las variables - void clear(); + // Reinicia todas las variables a cero + void clear() override; // Muestra el sprite por pantalla void render() override; diff --git a/source/player.cpp b/source/player.cpp index 4216bb3..626e851 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -70,6 +70,7 @@ void Player::init() cooldown_ = 10; // Establece la posición del sprite + player_sprite_->clear(); player_sprite_->setPosX(pos_x_); player_sprite_->setPosY(pos_y_); diff --git a/source/sprite.cpp b/source/sprite.cpp index f9609b1..4c4e748 100644 --- a/source/sprite.cpp +++ b/source/sprite.cpp @@ -136,4 +136,11 @@ void Sprite::incX(int value) void Sprite::incY(int value) { pos_.y += value; +} + +// Reinicia las variables a cero +void Sprite::clear() +{ + pos_ = {0, 0, 0, 0}; + sprite_clip_ = {0, 0, 0, 0}; } \ No newline at end of file diff --git a/source/sprite.h b/source/sprite.h index 95f8b2e..85b39f0 100644 --- a/source/sprite.h +++ b/source/sprite.h @@ -25,6 +25,9 @@ public: // Muestra el sprite por pantalla virtual void render(); + // Reinicia las variables a cero + virtual void clear(); + // Obten el valor de la variable int getX() const; int getY() const;