Comença a estar tot mes o menos be el desaguisao de les classes Sprite. Encara algunes animacions sembla que van massa ràpides

This commit is contained in:
2024-10-17 19:26:39 +02:00
parent 59de566c5b
commit 50a376e582
12 changed files with 246 additions and 208 deletions

View File

@@ -6,148 +6,6 @@
#include <sstream> // for basic_stringstream
#include "texture.h" // for Texture
// Carga la animación desde un fichero
std::vector<Animation> loadAnimationFromFile(std::shared_ptr<Texture> texture, std::string file_path)
{
// Inicializa variables
std::vector<Animation> 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<int>(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> texture, const std::string &file_path)
: MovingSprite(texture),
@@ -156,8 +14,9 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> 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> texture, std::vector<std::string> *animations)
@@ -168,6 +27,7 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, std::vector<std
{
loadFromVector(animations);
}
//setSpriteClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}
// Constructor
@@ -455,7 +315,8 @@ bool AnimatedSprite::loadFromVector(std::vector<std::string> *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<Animation> AnimatedSprite::loadFromFile(std::string file_path)
{
// Inicializa variables
std::vector<Animation> 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<int>(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;
}

View File

@@ -19,9 +19,6 @@ struct Animation
int counter; // Contador para las animaciones
};
// Carga la animación desde un fichero
std::vector<Animation> loadAnimationFromFile(std::shared_ptr<Texture> 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<Animation> loadFromFile(std::string filePath);
// Carga la animación desde un vector
bool loadFromVector(std::vector<std::string> *source);
public:
// Constructor
AnimatedSprite(std::shared_ptr<Texture> 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<std::string> *source);
// Establece la animacion actual
void setCurrentAnimation(const std::string &name = "default");
void setCurrentAnimation(int index = 0);

View File

@@ -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());

View File

@@ -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

View File

@@ -1,10 +1,13 @@
#pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_video.h> // for SDL_Window
#include <string> // for string
#include <vector> // for vector
namespace lang { enum class Code : int; }
#include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_video.h> // for SDL_Window
#include <string> // for string
#include <vector> // 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<SoundFile> sounds_; // Vector con los sonidos
std::vector<MusicFile> musics_; // Vector con las musicas
std::vector<SoundFile> sounds_; // Vector con los sonidos
std::vector<MusicFile> musics_; // Vector con las musicas
// Inicializa jail_audio
void initJailAudio();

View File

@@ -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;
}
}

View File

@@ -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<Director>(argc, const_cast<const char **>(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();
}

View File

@@ -6,6 +6,10 @@ MovingSprite::MovingSprite(std::shared_ptr<Texture> 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> 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> 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<int>(x_);
pos_.y = static_cast<int>(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<float>(rect.x);
y_ = static_cast<float>(rect.y);
pos_ = rect;
}
@@ -249,21 +258,22 @@ void MovingSprite::setPos(float x, float y)
x_ = x;
y_ = y;
syncPos();
pos_.x = static_cast<int>(x_);
pos_.y = static_cast<int>(y_);
}
// Establece el valor de la variable
void MovingSprite::setPosX(float value)
{
x_ = value;
pos_.x = (int)x_;
pos_.x = static_cast<int>(x_);
}
// Establece el valor de la variable
void MovingSprite::setPosY(float value)
{
y_ = value;
pos_.y = (int)y_;
pos_.y = static_cast<int>(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_;
}
}

View File

@@ -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> 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;

View File

@@ -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_);

View File

@@ -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};
}

View File

@@ -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;