diff --git a/source/animated_sprite.cpp b/source/animated_sprite.cpp index 8f7f668..200d602 100644 --- a/source/animated_sprite.cpp +++ b/source/animated_sprite.cpp @@ -16,18 +16,16 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr texture, const std::stri { animations_ = loadFromFile(file_path); } - // setSpriteClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]); } -AnimatedSprite::AnimatedSprite(std::shared_ptr texture, std::vector *animations) +AnimatedSprite::AnimatedSprite(std::shared_ptr texture, const std::vector &animations) : MovingSprite(texture), current_animation_(0) { - if (animations) + if (!animations.empty()) { loadFromVector(animations); } - // setSpriteClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]); } // Constructor @@ -178,6 +176,149 @@ SDL_Rect AnimatedSprite::getAnimationClip(int indexA, Uint8 indexF) return animations_[indexA].frames[indexF]; } +// Carga la animación desde un vector +bool AnimatedSprite::loadFromVector(const std::vector &source) +{ + // Inicializa variables + auto frames_per_row = 0; + auto frame_width = 0; + auto frame_height = 0; + auto max_tiles = 0; + + // Indicador de éxito en el proceso + auto success = true; + std::string line; + + // Recorre todo el vector + auto index = 0; + while (index < (int)source.size()) + { + // Lee desde el vector + line = source.at(index); + + // 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 + { + // Aumenta el indice para leer la siguiente linea + index++; + line = source.at(index); + + // 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 int 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: unknown parameter " << line.substr(0, pos).c_str() << std::endl; + success = false; + } + } + } 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: unknown parameter " << line.substr(0, pos).c_str() << std::endl; + success = false; + } + + // 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 int w = texture_->getWidth() / frame_width; + const int h = texture_->getHeight() / frame_height; + max_tiles = w * h; + } + } + } + + // Una vez procesada la linea, aumenta el indice para pasar a la siguiente + index++; + } + + // Pone un valor por defecto + setWidth(frame_width); + setHeight(frame_height); + + return success; +} + // Establece la animacion actual void AnimatedSprite::setCurrentAnimation(const std::string &name) { @@ -235,7 +376,7 @@ void AnimatedSprite::resetAnimation() } // Carga la animación desde un fichero -std::vector AnimatedSprite::loadFromFile(std::string file_path) +std::vector AnimatedSprite::loadFromFile(const std::string &file_path) { // Inicializa variables std::vector animations; diff --git a/source/animated_sprite.h b/source/animated_sprite.h index 19c9c17..f8f69b1 100644 --- a/source/animated_sprite.h +++ b/source/animated_sprite.h @@ -32,15 +32,15 @@ protected: void animate(); // Carga la animación desde un fichero - std::vector loadFromFile(std::string filePath); + std::vector loadFromFile(const std::string &file_path); // Carga la animación desde un vector - bool loadFromVector(std::vector *source); + bool loadFromVector(const std::vector &source); public: // Constructor AnimatedSprite(std::shared_ptr texture, const std::string &file_path); - AnimatedSprite(std::shared_ptr texture, std::vector *animations); + AnimatedSprite(std::shared_ptr texture, const std::vector &animations); explicit AnimatedSprite(std::shared_ptr texture); // Destructor diff --git a/source/balloon.cpp b/source/balloon.cpp index 3630d27..49369fb 100644 --- a/source/balloon.cpp +++ b/source/balloon.cpp @@ -7,7 +7,7 @@ #include "texture.h" // for Texture // Constructor -Balloon::Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr texture, std::vector *animation) +Balloon::Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr texture, const std::vector &animation) : sprite_(std::make_unique(texture, animation)), pos_x_(x), pos_y_(y), diff --git a/source/balloon.h b/source/balloon.h index 1e0f34d..ed93dd0 100644 --- a/source/balloon.h +++ b/source/balloon.h @@ -141,7 +141,7 @@ private: public: // Constructor - Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr texture, std::vector *animation); + Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr texture, const std::vector &animation); // Destructor ~Balloon() = default; diff --git a/source/explosions.cpp b/source/explosions.cpp index 0e2198c..0a56c35 100644 --- a/source/explosions.cpp +++ b/source/explosions.cpp @@ -38,22 +38,17 @@ void Explosions::render() } // Añade texturas al objeto -void Explosions::addTexture(int size, std::shared_ptr texture, std::vector *animation) +void Explosions::addTexture(int size, std::shared_ptr texture, std::vector &animation) { - ExplosionTexture temp; - temp.size = size; - temp.texture = texture; - temp.animation = animation; - textures_.push_back(temp); + textures_.emplace_back(ExplosionTexture(size, texture, animation)); } // Añade una explosión void Explosions::add(int x, int y, int size) { - const int index = getIndexBySize(size); - auto sprite = std::make_unique(textures_[index].texture, textures_[index].animation); - sprite->setPos(x, y); - explosions_.push_back(std::move(sprite)); + const auto index = getIndexBySize(size); + explosions_.emplace_back(std::make_unique(textures_[index].texture, textures_[index].animation)); + explosions_.back()->setPos(x, y); } // Vacia el vector de elementos finalizados diff --git a/source/explosions.h b/source/explosions.h index b5566cf..9e2f178 100644 --- a/source/explosions.h +++ b/source/explosions.h @@ -8,9 +8,13 @@ class Texture; struct ExplosionTexture { - std::shared_ptr texture; // Textura para la explosión - std::vector *animation; // Animación para la textura - int size; // Tamaño de la explosión + int size; // Tamaño de la explosión + std::shared_ptr texture; // Textura para la explosión + std::vector animation; // Animación para la textura + + // Constructor + ExplosionTexture(int sz, std::shared_ptr tex, std::vector anim) + : size(sz), texture(tex), animation(anim) {} }; // Clase explosions @@ -41,7 +45,7 @@ public: void render(); // Añade texturas al objeto - void addTexture(int size, std::shared_ptr texture, std::vector *animation); + void addTexture(int size, std::shared_ptr texture, std::vector &animation); // Añade una explosión void add(int x, int y, int size); diff --git a/source/game.cpp b/source/game.cpp index 2cddea9..cbbcbf9 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -304,15 +304,18 @@ void Game::loadMedia() // Limpia { - player_animations_.clear(); - balloon_animations_.clear(); - item_animations_.clear(); - player1_textures_.clear(); - player2_textures_.clear(); - item_textures_.clear(); + // Texturas + game_text_textures_.clear(); balloon_textures_.clear(); explosions_textures_.clear(); - game_text_textures_.clear(); + item_textures_.clear(); + player_textures_.clear(); + + // Animaciones + player_animations_.clear(); + balloon_animations_.clear(); + explosions_animations_.clear(); + item_animations_.clear(); } // Texturas @@ -358,109 +361,64 @@ void Game::loadMedia() // Texturas - Player1 { - player1_textures_.emplace_back(std::make_shared(renderer_, asset_->get("player1.gif"))); - player1_textures_.back()->addPalette(asset_->get("player1_pal1.gif")); - player1_textures_.back()->addPalette(asset_->get("player1_pal2.gif")); - player1_textures_.back()->addPalette(asset_->get("player1_pal3.gif")); + std::vector> player_texture; + player_texture.emplace_back(std::make_shared(renderer_, asset_->get("player1.gif"))); + player_texture.back()->addPalette(asset_->get("player1_pal1.gif")); + player_texture.back()->addPalette(asset_->get("player1_pal2.gif")); + player_texture.back()->addPalette(asset_->get("player1_pal3.gif")); - player1_textures_.emplace_back(std::make_shared(renderer_, asset_->get("player_power.gif"))); - player1_textures_.back()->addPalette(asset_->get("player_power_pal.gif")); + player_texture.emplace_back(std::make_shared(renderer_, asset_->get("player_power.gif"))); + player_texture.back()->addPalette(asset_->get("player_power_pal.gif")); - player_textures_.push_back(player1_textures_); + player_textures_.push_back(player_texture); } // Texturas - Player2 { - player2_textures_.emplace_back(std::make_shared(renderer_, asset_->get("player2.gif"))); - player2_textures_.back()->addPalette(asset_->get("player2_pal1.gif")); - player2_textures_.back()->addPalette(asset_->get("player2_pal2.gif")); - player2_textures_.back()->addPalette(asset_->get("player2_pal3.gif")); + std::vector> player_texture; + player_texture.emplace_back(std::make_shared(renderer_, asset_->get("player2.gif"))); + player_texture.back()->addPalette(asset_->get("player2_pal1.gif")); + player_texture.back()->addPalette(asset_->get("player2_pal2.gif")); + player_texture.back()->addPalette(asset_->get("player2_pal3.gif")); - player2_textures_.emplace_back(std::make_shared(renderer_, asset_->get("player_power.gif"))); - player2_textures_.back()->addPalette(asset_->get("player_power_pal.gif")); - player2_textures_.back()->setPalette(1); + player_texture.emplace_back(std::make_shared(renderer_, asset_->get("player_power.gif"))); + player_texture.back()->addPalette(asset_->get("player_power_pal.gif")); + player_texture.back()->setPalette(1); - player_textures_.push_back(player2_textures_); + player_textures_.push_back(player_texture); } // Animaciones -- Jugador { - std::vector *player_animations = new std::vector; - loadAnimations(asset_->get("player.ani"), player_animations); - player_animations_.push_back(player_animations); - - std::vector *player_power_animations = new std::vector; - loadAnimations(asset_->get("player_power.ani"), player_power_animations); - player_animations_.push_back(player_power_animations); + player_animations_.emplace_back(loadAnimations(asset_->get("player.ani"))); + player_animations_.emplace_back(loadAnimations(asset_->get("player_power.ani"))); } // Animaciones -- Globos { - std::vector *balloon1_animations = new std::vector; - loadAnimations(asset_->get("balloon1.ani"), balloon1_animations); - balloon_animations_.push_back(balloon1_animations); - - std::vector *balloon2_animations = new std::vector; - loadAnimations(asset_->get("balloon2.ani"), balloon2_animations); - balloon_animations_.push_back(balloon2_animations); - - std::vector *balloon3_animations = new std::vector; - loadAnimations(asset_->get("balloon3.ani"), balloon3_animations); - balloon_animations_.push_back(balloon3_animations); - - std::vector *balloon4_animations = new std::vector; - loadAnimations(asset_->get("balloon4.ani"), balloon4_animations); - balloon_animations_.push_back(balloon4_animations); - - std::vector *balloon5_animations = new std::vector; - loadAnimations(asset_->get("powerball.ani"), balloon5_animations); - balloon_animations_.push_back(balloon5_animations); + balloon_animations_.emplace_back(loadAnimations(asset_->get("balloon1.ani"))); + balloon_animations_.emplace_back(loadAnimations(asset_->get("balloon2.ani"))); + balloon_animations_.emplace_back(loadAnimations(asset_->get("balloon3.ani"))); + balloon_animations_.emplace_back(loadAnimations(asset_->get("balloon4.ani"))); + balloon_animations_.emplace_back(loadAnimations(asset_->get("powerball.ani"))); } // Animaciones -- Explosiones { - std::vector *explosions1_animations = new std::vector; - loadAnimations(asset_->get("explosion1.ani"), explosions1_animations); - explosions_animations_.push_back(explosions1_animations); - - std::vector *explosions2_animations = new std::vector; - loadAnimations(asset_->get("explosion2.ani"), explosions2_animations); - explosions_animations_.push_back(explosions2_animations); - - std::vector *explosions3_animations = new std::vector; - loadAnimations(asset_->get("explosion3.ani"), explosions3_animations); - explosions_animations_.push_back(explosions3_animations); - - std::vector *explosions4_animations = new std::vector; - loadAnimations(asset_->get("explosion4.ani"), explosions4_animations); - explosions_animations_.push_back(explosions4_animations); + explosions_animations_.emplace_back(loadAnimations(asset_->get("explosion1.ani"))); + explosions_animations_.emplace_back(loadAnimations(asset_->get("explosion2.ani"))); + explosions_animations_.emplace_back(loadAnimations(asset_->get("explosion3.ani"))); + explosions_animations_.emplace_back(loadAnimations(asset_->get("explosion4.ani"))); } // Animaciones -- Items { - std::vector *item1_animations = new std::vector; - loadAnimations(asset_->get("item_points1_disk.ani"), item1_animations); - item_animations_.push_back(item1_animations); - - std::vector *item2_animations = new std::vector; - loadAnimations(asset_->get("item_points2_gavina.ani"), item2_animations); - item_animations_.push_back(item2_animations); - - std::vector *item3_animations = new std::vector; - loadAnimations(asset_->get("item_points3_pacmar.ani"), item3_animations); - item_animations_.push_back(item3_animations); - - std::vector *item4_animations = new std::vector; - loadAnimations(asset_->get("item_clock.ani"), item4_animations); - item_animations_.push_back(item4_animations); - - std::vector *item5_animations = new std::vector; - loadAnimations(asset_->get("item_coffee.ani"), item5_animations); - item_animations_.push_back(item5_animations); - - std::vector *item6_animations = new std::vector; - loadAnimations(asset_->get("item_coffee_machine.ani"), item6_animations); - item_animations_.push_back(item6_animations); + item_animations_.emplace_back(loadAnimations(asset_->get("item_points1_disk.ani"))); + item_animations_.emplace_back(loadAnimations(asset_->get("item_points2_gavina.ani"))); + item_animations_.emplace_back(loadAnimations(asset_->get("item_points3_pacmar.ani"))); + item_animations_.emplace_back(loadAnimations(asset_->get("item_clock.ani"))); + item_animations_.emplace_back(loadAnimations(asset_->get("item_coffee.ani"))); + item_animations_.emplace_back(loadAnimations(asset_->get("item_coffee_machine.ani"))); } // Texto @@ -498,11 +456,11 @@ void Game::loadMedia() void Game::unloadMedia() { // Texturas - player1_textures_.clear(); - player2_textures_.clear(); - item_textures_.clear(); + game_text_textures_.clear(); balloon_textures_.clear(); explosions_textures_.clear(); + item_textures_.clear(); + player_textures_.clear(); // Animaciones player_animations_.clear(); @@ -2158,21 +2116,24 @@ void Game::checkEvents() } // Carga las animaciones -void Game::loadAnimations(std::string filePath, std::vector *buffer) +std::vector Game::loadAnimations(const std::string &file_path) { - std::ifstream file(filePath); - std::string line; - - if (file) + std::vector buffer; + std::ifstream file(file_path); + if (!file) { - - std::cout << "Animation loaded: " << filePath.substr(filePath.find_last_of("\\/") + 1).c_str() << std::endl; - while (std::getline(file, line)) - { - buffer->push_back(line); - } - file.close(); + std::cerr << "Error: no se pudo abrir el archivo " << file_path << std::endl; + return buffer; } + + std::string line; + std::cout << "Animation loaded: " << file_path.substr(file_path.find_last_of("\\/") + 1) << std::endl; + while (std::getline(file, line)) + { + buffer.push_back(line); + } + + return buffer; } // Elimina todos los objetos contenidos en vectores @@ -2198,14 +2159,12 @@ void Game::reloadTextures() texture->reLoad(); } - for (auto &texture : player1_textures_) + for (auto &textures : player_textures_) { - texture->reLoad(); - } - - for (auto &texture : player2_textures_) - { - texture->reLoad(); + for (auto &texture : textures) + { + texture->reLoad(); + } } for (auto &texture : game_text_textures_) diff --git a/source/game.h b/source/game.h index dbe1464..13f98b7 100644 --- a/source/game.h +++ b/source/game.h @@ -129,17 +129,14 @@ private: std::vector> item_textures_; // Vector con las texturas de los items std::vector> balloon_textures_; // Vector con las texturas de los globos std::vector> explosions_textures_; // Vector con las texturas de las explosiones - std::vector> player1_textures_; // Vector con las texturas del jugador - std::vector> player2_textures_; // Vector con las texturas del jugador std::vector>> player_textures_; // Vector con todas las texturas de los jugadores; std::vector> game_text_textures_; // Vector con las texturas para los sprites con textos - // std::vector> game_text_sprites_; // Sprite con el textos que aparecen al coger items - std::vector *> item_animations_; // Vector con las animaciones de los items - std::vector *> player_animations_; // Vector con las animaciones del jugador - std::vector *> balloon_animations_; // Vector con las animaciones de los globos - std::vector *> explosions_animations_; // Vector con las animaciones de las explosiones + std::vector> item_animations_; // Vector con las animaciones de los items + std::vector> player_animations_; // Vector con las animaciones del jugador + std::vector> balloon_animations_; // Vector con las animaciones de los globos + std::vector> explosions_animations_; // Vector con las animaciones de las explosiones std::unique_ptr text_; // Fuente para los textos del juego std::unique_ptr text_big_; // Fuente de texto grande @@ -403,7 +400,7 @@ private: bool allPlayersAreNotPlaying(); // Carga las animaciones - void loadAnimations(std::string file_path, std::vector *buffer); + std::vector loadAnimations(const std::string &file_path); // Elimina todos los objetos contenidos en vectores void deleteAllVectorObjects(); diff --git a/source/item.cpp b/source/item.cpp index 3c39418..0e4fb06 100644 --- a/source/item.cpp +++ b/source/item.cpp @@ -5,7 +5,7 @@ class Texture; // Constructor -Item::Item(ItemType type, float x, float y, SDL_Rect *play_area, std::shared_ptr texture, std::vector *animation) +Item::Item(ItemType type, float x, float y, SDL_Rect *play_area, std::shared_ptr texture, const std::vector &animation) : sprite_(std::make_unique(texture, animation)), accel_x_(0.0f), floor_collision_(false), diff --git a/source/item.h b/source/item.h index 4248dcd..5c951d5 100644 --- a/source/item.h +++ b/source/item.h @@ -58,7 +58,7 @@ private: public: // Constructor - Item(ItemType type, float x, float y, SDL_Rect *play_area, std::shared_ptr texture, std::vector *animation); + Item(ItemType type, float x, float y, SDL_Rect *play_area, std::shared_ptr texture, const std::vector &animation); // Destructor ~Item() = default; diff --git a/source/player.cpp b/source/player.cpp index 626e851..d0391e3 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -11,7 +11,7 @@ #include "options.h" // Constructor -Player::Player(int id, float x, int y, bool demo, SDL_Rect *play_area, std::vector> texture, std::vector *> animations) +Player::Player(int id, float x, int y, bool demo, SDL_Rect *play_area, std::vector> texture, const std::vector> &animations) : player_sprite_(std::make_unique(texture[0], animations[0])), power_sprite_(std::make_unique(texture[1], animations[1])), enter_name_(std::make_unique()), diff --git a/source/player.h b/source/player.h index e7202b8..e0483a5 100644 --- a/source/player.h +++ b/source/player.h @@ -113,7 +113,7 @@ private: public: // Constructor - Player(int id, float x, int y, bool demo, SDL_Rect *play_area, std::vector> texture, std::vector *> animations); + Player(int id, float x, int y, bool demo, SDL_Rect *play_area, std::vector> texture, const std::vector> &animations); // Destructor ~Player() = default;