Compare commits

9 Commits

Author SHA1 Message Date
2cb22ed013 fix: els globos tenien un parell de setters mal asignats per culpa de buscar y reemplazar
fix: els globos verds s'inicialitzaven amb vy = 0 per gastar abs en lloc de fabs
fix: corregit un bug milenari que de sempre havia creat els balloons verds al popar al pare amb la meitat de velocitat en y. Lo que jo no se es com anava res. Supose que ara el joc serà un poc mes xungo. Quan rebotaven en el piso ja se'ls posava la velocitat bona (crec)
2024-10-20 22:58:15 +02:00
a3a583deb7 Precàrrega dels fitxers amb dades per al mode demostració 2024-10-20 21:23:04 +02:00
b263e0c4be Modificada la estructura on es guarden els datos de la demo 2024-10-20 20:43:03 +02:00
3bf61fc758 fix: no guardar el fitxer de puntuacions en el modo demo 2024-10-20 19:40:09 +02:00
2377815c02 Amb les textures en memoria i compartides ja no puc fer el trick de canvi de paleta per a la flama del segon jugador tal i com està plantejat el codi. Arreglat creant una segona textura 2024-10-20 19:38:28 +02:00
7434869894 Corregit un fallo amagat baix un ifdef ARCADE. Ja he posat que estiga definit per defecte pa que no torne a passar 2024-10-20 15:43:10 +02:00
848d61b5c0 He fet un "manolete" i he pasat a c++ i smartpointers la cárrega de surfaces desde gif. Sembla que no ha petat res
Precárrega i asignació de paletes a les textures
Ara si algú toca una paleta, que siga conscient que la textura es compartida durant tot el joc
2024-10-20 15:36:04 +02:00
cbc9b3f071 Eliminats els últimes defines i passats a enum class 2024-10-20 12:07:55 +02:00
8bca5095da Modificats, estructurats i ben formatats alguns missatges de consola
Canvis en els codis d'eixida del programa
2024-10-20 11:37:26 +02:00
46 changed files with 673 additions and 690 deletions

View File

Before

Width:  |  Height:  |  Size: 84 B

After

Width:  |  Height:  |  Size: 84 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View File

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 172 B

View File

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

View File

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 944 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 B

View File

@@ -6,35 +6,36 @@
#include "moving_sprite.h" // for MovingSprite #include "moving_sprite.h" // for MovingSprite
#include "param.h" // for param #include "param.h" // for param
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h"
#include "sprite.h" // for Sprite #include "sprite.h" // for Sprite
#include "texture.h" // for Texture #include "texture.h" // for Texture
// Constructor // Constructor
Background::Background(SDL_Renderer *renderer) Background::Background()
: renderer_(renderer), : renderer_(Screen::get()->getRenderer()),
buildings_texture_(Resource::get()->getTexture("game_buildings.png")), buildings_texture_(Resource::get()->getTexture("game_buildings.png")),
top_clouds_texture_(Resource::get()->getTexture("game_clouds1.png")), top_clouds_texture_(Resource::get()->getTexture("game_clouds1.png")),
bottom_clouds_texture_(Resource::get()->getTexture("game_clouds2.png")), bottom_clouds_texture_(Resource::get()->getTexture("game_clouds2.png")),
grass_texture_(Resource::get()->getTexture("game_grass.png")), grass_texture_(Resource::get()->getTexture("game_grass.png")),
gradients_texture_(Resource::get()->getTexture("game_sky_colors.png")) gradients_texture_(Resource::get()->getTexture("game_sky_colors.png")),
gradient_number_(0),
alpha_(0),
clouds_speed_(0),
transition_(0),
counter_(0),
rect_({0, 0, gradients_texture_->getWidth() / 2, gradients_texture_->getHeight() / 2}),
src_rect_({0, 0, 320, 240}),
dst_rect_({0, 0, 320, 240}),
base_(rect_.h),
color_({param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b}),
alpha_color_text_(param.background.attenuate_alpha),
alpha_color_text_temp_(param.background.attenuate_alpha)
{ {
// Inicializa variables // Inicializa variables
{ {
gradient_number_ = 0;
alpha_ = 0;
clouds_speed_ = 0;
transition_ = 0;
counter_ = 0;
rect_ = {0, 0, gradients_texture_->getWidth() / 2, gradients_texture_->getHeight() / 2};
src_rect_ = {0, 0, 320, 240};
dst_rect_ = {0, 0, 320, 240};
base_ = rect_.h;
color_ = {param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b};
alpha_color_text_ = alpha_color_text_temp_ = param.background.attenuate_alpha;
gradient_rect_[0] = {0, 0, rect_.w, rect_.h}; gradient_rect_[0] = {0, 0, rect_.w, rect_.h};
gradient_rect_[1] = {rect_.w, 0, rect_.w, rect_.h}; gradient_rect_[1] = {rect_.w, 0, rect_.w, rect_.h};
gradient_rect_[2] = {0, rect_.h, rect_.w, rect_.h}; gradient_rect_[2] = {0, rect_.h, rect_.w, rect_.h};
@@ -87,11 +88,11 @@ Background::Background(SDL_Renderer *renderer)
} }
// Crea la textura para componer el fondo // Crea la textura para componer el fondo
canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h); canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
SDL_SetTextureBlendMode(canvas_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(canvas_, SDL_BLENDMODE_BLEND);
// Crea la textura para atenuar el fondo // Crea la textura para atenuar el fondo
color_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h); color_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
SDL_SetTextureBlendMode(color_texture_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(color_texture_, SDL_BLENDMODE_BLEND);
setColor(color_); setColor(color_);
SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_); SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_);
@@ -120,7 +121,7 @@ void Background::update()
alpha_ = std::max((255 - (int)(255 * transition_)), 0); alpha_ = std::max((255 - (int)(255 * transition_)), 0);
// Incrementa el contador // Incrementa el contador
counter_++; ++counter_;
// Compone todos los elementos del fondo en la textura // Compone todos los elementos del fondo en la textura
fillCanvas(); fillCanvas();

View File

@@ -107,7 +107,7 @@ private:
public: public:
// Constructor // Constructor
explicit Background(SDL_Renderer *renderer); Background();
// Destructor // Destructor
~Background(); ~Background();

View File

@@ -121,10 +121,10 @@ Balloon::Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16
power_ = 1; power_ = 1;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
vel_y_ = abs(vel_x) * 2; vel_y_ = fabs(vel_x_ * 2.0f);
max_vel_y_ = abs(vel_x) * 2; max_vel_y_ = vel_y_;
gravity_ = 0.00f; gravity_ = 0.00f;
default_vel_y_ = abs(vel_x) * 2; default_vel_y_ = vel_y_;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
score_ = BALLOON_SCORE_1; score_ = BALLOON_SCORE_1;
@@ -142,10 +142,10 @@ Balloon::Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16
power_ = 3; power_ = 3;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
vel_y_ = abs(vel_x) * 2; vel_y_ = fabs(vel_x_ * 2.0f);
max_vel_y_ = abs(vel_x) * 2; max_vel_y_ = vel_y_;
gravity_ = 0.00f; gravity_ = 0.00f;
default_vel_y_ = abs(vel_x) * 2; default_vel_y_ = vel_y_;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
score_ = BALLOON_SCORE_2; score_ = BALLOON_SCORE_2;
@@ -163,10 +163,10 @@ Balloon::Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16
power_ = 7; power_ = 7;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
vel_y_ = abs(vel_x) * 2; vel_y_ = fabs(vel_x_ * 2.0f);
max_vel_y_ = abs(vel_x) * 2; max_vel_y_ = vel_y_;
gravity_ = 0.00f; gravity_ = 0.00f;
default_vel_y_ = abs(vel_x) * 2; default_vel_y_ = vel_y_;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
score_ = BALLOON_SCORE_3; score_ = BALLOON_SCORE_3;
@@ -184,10 +184,10 @@ Balloon::Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16
power_ = 15; power_ = 15;
// Inicializa los valores de velocidad y gravedad // Inicializa los valores de velocidad y gravedad
vel_y_ = abs(vel_x) * 2; vel_y_ = fabs(vel_x_ * 2.0f);
max_vel_y_ = abs(vel_x) * 2; max_vel_y_ = vel_y_;
gravity_ = 0.00f; gravity_ = 0.00f;
default_vel_y_ = abs(vel_x) * 2; default_vel_y_ = vel_y_;
// Puntos que da el globo al ser destruido // Puntos que da el globo al ser destruido
score_ = BALLOON_SCORE_4; score_ = BALLOON_SCORE_4;
@@ -238,13 +238,8 @@ Balloon::Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16
bouncing_.w = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f}; bouncing_.w = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f};
bouncing_.h = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f}; bouncing_.h = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f};
// Alto y ancho del sprite_ // Configura el sprite
sprite_->setWidth(width_); sprite_->setPos({static_cast<int>(pos_x_), static_cast<int>(pos_y_), width_, height_});
sprite_->setHeight(height_);
// Posición X,Y del sprite_
sprite_->setPosX((int)pos_x_);
sprite_->setPosY((int)pos_y_);
// Tamaño del circulo de colisión // Tamaño del circulo de colisión
collider_.r = width_ / 2; collider_.r = width_ / 2;
@@ -396,10 +391,6 @@ void Balloon::move()
// Aplica la gravedad al objeto sin pasarse de una velocidad máxima // Aplica la gravedad al objeto sin pasarse de una velocidad máxima
vel_y_ += gravity_; vel_y_ += gravity_;
// Al parecer esta asignación se quedó sin hacer y ahora el juego no funciona
// correctamente si se aplica, así que se deja sin efecto
// vel_y_ = std::min(vel_y_, max_vel_y_);
} }
// Actualiza la posición del sprite_ // Actualiza la posición del sprite_
@@ -460,7 +451,7 @@ void Balloon::update()
updateColliders(); updateColliders();
updateState(); updateState();
updateBounce(); updateBounce();
counter_++; ++counter_;
} }
} }
@@ -609,15 +600,15 @@ int Balloon::getHeight() const
} }
// Establece el valor de la variable // Establece el valor de la variable
void Balloon::setVelY(float vel_y_) void Balloon::setVelY(float vel_y)
{ {
this->vel_y_ = vel_y_; vel_y_ = vel_y;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Balloon::setSpeed(float speed_) void Balloon::setSpeed(float speed)
{ {
this->speed_ = speed_; speed_ = speed;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable

View File

@@ -37,15 +37,11 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[i].number_of_balloons = 0; balloon_formation_[i].number_of_balloons = 0;
for (int j = 0; j < MAX_NUMBER_OF_BALLOONS_IN_A_FORMATION; j++) for (int j = 0; j < MAX_NUMBER_OF_BALLOONS_IN_A_FORMATION; j++)
{ {
balloon_formation_[i].init[j].x = 0; balloon_formation_[i].init[j] = BalloonFormationParams();
balloon_formation_[i].init[j].y = 0;
balloon_formation_[i].init[j].vel_x = 0;
balloon_formation_[i].init[j].kind = 0;
balloon_formation_[i].init[j].creation_counter = 0;
} }
} }
const int creation_time = 300; constexpr int CREATION_TIME = 300;
int inc_x = 0; int inc_x = 0;
int inc_time = 0; int inc_time = 0;
int j = 0; int j = 0;
@@ -61,7 +57,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y4; balloon_formation_[j].init[i].y = y4;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1); balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1);
balloon_formation_[j].init[i].kind = BALLOON_4; balloon_formation_[j].init[i].kind = BALLOON_4;
balloon_formation_[j].init[i].creation_counter = creation_time + (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME + (inc_time * i);
} }
// #01 - Dos enemigos BALLOON4 uno a cada cuarto. Ambos van hacia el centro // #01 - Dos enemigos BALLOON4 uno a cada cuarto. Ambos van hacia el centro
@@ -75,7 +71,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y4; balloon_formation_[j].init[i].y = y4;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1); balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1);
balloon_formation_[j].init[i].kind = BALLOON_4; balloon_formation_[j].init[i].kind = BALLOON_4;
balloon_formation_[j].init[i].creation_counter = creation_time + (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME + (inc_time * i);
} }
// #02 - Cuatro enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro // #02 - Cuatro enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro
@@ -89,7 +85,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y2; balloon_formation_[j].init[i].y = y2;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_2; balloon_formation_[j].init[i].kind = BALLOON_2;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #03 - Cuatro enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro // #03 - Cuatro enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro
@@ -103,7 +99,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y2; balloon_formation_[j].init[i].y = y2;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_2; balloon_formation_[j].init[i].kind = BALLOON_2;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #04 - Tres enemigos BALLOON3. 0, 25, 50. Hacia la derecha // #04 - Tres enemigos BALLOON3. 0, 25, 50. Hacia la derecha
@@ -117,7 +113,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].kind = BALLOON_3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #05 - Tres enemigos BALLOON3. 50, 75, 100. Hacia la izquierda // #05 - Tres enemigos BALLOON3. 50, 75, 100. Hacia la izquierda
@@ -131,7 +127,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].kind = BALLOON_3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #06 - Tres enemigos BALLOON3. 0, 0, 0. Hacia la derecha // #06 - Tres enemigos BALLOON3. 0, 0, 0. Hacia la derecha
@@ -145,7 +141,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].kind = BALLOON_3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #07 - Tres enemigos BALLOON3. 100, 100, 100. Hacia la izquierda // #07 - Tres enemigos BALLOON3. 100, 100, 100. Hacia la izquierda
@@ -159,7 +155,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].kind = BALLOON_3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #08 - Seis enemigos BALLOON1. 0, 0, 0, 0, 0, 0. Hacia la derecha // #08 - Seis enemigos BALLOON1. 0, 0, 0, 0, 0, 0. Hacia la derecha
@@ -173,7 +169,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].kind = BALLOON_1;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #09 - Seis enemigos BALLOON1. 100, 100, 100, 100, 100, 100. Hacia la izquierda // #09 - Seis enemigos BALLOON1. 100, 100, 100, 100, 100, 100. Hacia la izquierda
@@ -187,7 +183,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].kind = BALLOON_1;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #10 - Tres enemigos BALLOON4 seguidos desde la izquierda // #10 - Tres enemigos BALLOON4 seguidos desde la izquierda
@@ -201,7 +197,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y4; balloon_formation_[j].init[i].y = y4;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_4; balloon_formation_[j].init[i].kind = BALLOON_4;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #11 - Tres enemigos BALLOON4 seguidos desde la derecha // #11 - Tres enemigos BALLOON4 seguidos desde la derecha
@@ -215,7 +211,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y4; balloon_formation_[j].init[i].y = y4;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_4; balloon_formation_[j].init[i].kind = BALLOON_4;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #12 - Seis enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro // #12 - Seis enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro
@@ -229,7 +225,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y2; balloon_formation_[j].init[i].y = y2;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_2; balloon_formation_[j].init[i].kind = BALLOON_2;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #13 - Seis enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro // #13 - Seis enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro
@@ -243,7 +239,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y2; balloon_formation_[j].init[i].y = y2;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_2; balloon_formation_[j].init[i].kind = BALLOON_2;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #14 - Cinco enemigos BALLOON3. Hacia la derecha. Separados // #14 - Cinco enemigos BALLOON3. Hacia la derecha. Separados
@@ -257,7 +253,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].kind = BALLOON_3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #15 - Cinco enemigos BALLOON3. Hacia la izquierda. Separados // #15 - Cinco enemigos BALLOON3. Hacia la izquierda. Separados
@@ -271,7 +267,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].kind = BALLOON_3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #16 - Cinco enemigos BALLOON3. Hacia la derecha. Juntos // #16 - Cinco enemigos BALLOON3. Hacia la derecha. Juntos
@@ -285,7 +281,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].kind = BALLOON_3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #17 - Cinco enemigos BALLOON3. Hacia la izquierda. Juntos // #17 - Cinco enemigos BALLOON3. Hacia la izquierda. Juntos
@@ -299,7 +295,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].kind = BALLOON_3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #18 - Doce enemigos BALLOON1. Hacia la derecha. Juntos // #18 - Doce enemigos BALLOON1. Hacia la derecha. Juntos
@@ -313,7 +309,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].kind = BALLOON_1;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #19 - Doce enemigos BALLOON1. Hacia la izquierda. Juntos // #19 - Doce enemigos BALLOON1. Hacia la izquierda. Juntos
@@ -327,7 +323,7 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].kind = BALLOON_1;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simetricos // #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simetricos
@@ -350,7 +346,7 @@ void BalloonFormations::initBalloonFormations()
} }
balloon_formation_[j].init[i].y = y4; balloon_formation_[j].init[i].y = y4;
balloon_formation_[j].init[i].kind = BALLOON_4; balloon_formation_[j].init[i].kind = BALLOON_4;
balloon_formation_[j].init[i].creation_counter = creation_time + (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME + (inc_time * i);
} }
// #21 - Diez enemigos BALLOON2 uno detras del otro. Izquierda/derecha. Simetricos // #21 - Diez enemigos BALLOON2 uno detras del otro. Izquierda/derecha. Simetricos
@@ -365,13 +361,13 @@ void BalloonFormations::initBalloonFormations()
{ {
balloon_formation_[j].init[i].x = x2_0 + (i * inc_x); balloon_formation_[j].init[i].x = x2_0 + (i * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * i); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * i);
} }
else else
{ {
balloon_formation_[j].init[i].x = x2_100 - ((i - half) * inc_x); balloon_formation_[j].init[i].x = x2_100 - ((i - half) * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * (i - half)); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * (i - half));
} }
balloon_formation_[j].init[i].y = y2; balloon_formation_[j].init[i].y = y2;
balloon_formation_[j].init[i].kind = BALLOON_2; balloon_formation_[j].init[i].kind = BALLOON_2;
@@ -389,13 +385,13 @@ void BalloonFormations::initBalloonFormations()
{ {
balloon_formation_[j].init[i].x = x3_0 + (i * inc_x); balloon_formation_[j].init[i].x = x3_0 + (i * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * i); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * i);
} }
else else
{ {
balloon_formation_[j].init[i].x = x3_100 - ((i - half) * inc_x); balloon_formation_[j].init[i].x = x3_100 - ((i - half) * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * (i - half)); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * (i - half));
} }
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].kind = BALLOON_3;
@@ -413,13 +409,13 @@ void BalloonFormations::initBalloonFormations()
{ {
balloon_formation_[j].init[i].x = x3_0 + (i * inc_x); balloon_formation_[j].init[i].x = x3_0 + (i * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * i); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * i);
} }
else else
{ {
balloon_formation_[j].init[i].x = x3_100 - ((i - half) * inc_x); balloon_formation_[j].init[i].x = x3_100 - ((i - half) * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * (i - half)); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * (i - half));
} }
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].kind = BALLOON_3;
@@ -436,13 +432,13 @@ void BalloonFormations::initBalloonFormations()
{ {
balloon_formation_[j].init[i].x = x1_50; balloon_formation_[j].init[i].x = x1_50;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) + (inc_time * i); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) + (inc_time * i);
} }
else else
{ {
balloon_formation_[j].init[i].x = x1_50; balloon_formation_[j].init[i].x = x1_50;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) + (inc_time * (i - half)); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) + (inc_time * (i - half));
} }
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].kind = BALLOON_1;
@@ -459,13 +455,13 @@ void BalloonFormations::initBalloonFormations()
{ {
balloon_formation_[j].init[i].x = x1_50 + 20; balloon_formation_[j].init[i].x = x1_50 + 20;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * i); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * i);
} }
else else
{ {
balloon_formation_[j].init[i].x = x1_50 - 20; balloon_formation_[j].init[i].x = x1_50 - 20;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * (i - half)); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * (i - half));
} }
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].kind = BALLOON_1;

View File

@@ -6,11 +6,15 @@ constexpr int MAX_NUMBER_OF_BALLOONS_IN_A_FORMATION = 50;
// Estructuras // Estructuras
struct BalloonFormationParams struct BalloonFormationParams
{ {
int x; // Posición en el eje X donde crear al enemigo int x = 0; // Posición en el eje X donde crear al enemigo
int y; // Posición en el eje Y donde crear al enemigo int y = 0; // Posición en el eje Y donde crear al enemigo
float vel_x; // Velocidad inicial en el eje X float vel_x = 0.0f; // Velocidad inicial en el eje X
int kind; // Tipo de enemigo int kind = 0; // Tipo de enemigo
int creation_counter; // Temporizador para la creación del enemigo int creation_counter = 0; // Temporizador para la creación del enemigo
// Constructor que inicializa todos los campos con valores proporcionados o predeterminados
BalloonFormationParams(int x_val = 0, int y_val = 0, float vel_x_val = 0.0f, int kind_val = 0, int creation_counter_val = 0)
: x(x_val), y(y_val), vel_x(vel_x_val), kind(kind_val), creation_counter(creation_counter_val) {}
}; };
struct BalloonFormationUnit // Contiene la información de una formación enemiga struct BalloonFormationUnit // Contiene la información de una formación enemiga

View File

@@ -106,7 +106,7 @@ void DefineButtons::checkInput()
case SDL_QUIT: case SDL_QUIT:
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_NORMAL; section::options = section::Options::QUIT_WITH_KEYBOARD;
break; break;
} }

View File

@@ -134,6 +134,8 @@ Director::~Director()
SDL_DestroyWindow(window_); SDL_DestroyWindow(window_);
SDL_Quit(); SDL_Quit();
std::cout << "\nBye!" << std::endl;
} }
// Asigna los botones y teclas al objeto Input // Asigna los botones y teclas al objeto Input
@@ -369,8 +371,12 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/shaders/crtpi.glsl", AssetType::DATA); Asset::get()->add(prefix + "/data/shaders/crtpi.glsl", AssetType::DATA);
// Texturas // Texturas
Asset::get()->add(prefix + "/data/gfx/controllers/controllers.png", AssetType::BITMAP);
{ // Controllers
Asset::get()->add(prefix + "/data/gfx/controllers/controllers.png", AssetType::BITMAP);
}
{ // Balloons
Asset::get()->add(prefix + "/data/gfx/balloon/balloon1.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/balloon/balloon1.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon1.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/balloon1.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon2.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/balloon/balloon2.png", AssetType::BITMAP);
@@ -379,7 +385,9 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/gfx/balloon/balloon3.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/balloon3.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon4.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/balloon/balloon4.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon4.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/balloon4.ani", AssetType::ANIMATION);
}
{ // Explosions
Asset::get()->add(prefix + "/data/gfx/balloon/explosion1.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/balloon/explosion1.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion1.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/explosion1.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion2.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/balloon/explosion2.png", AssetType::BITMAP);
@@ -388,31 +396,45 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/gfx/balloon/explosion3.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/explosion3.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion4.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/balloon/explosion4.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion4.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/explosion4.ani", AssetType::ANIMATION);
}
{ // Power Ball
Asset::get()->add(prefix + "/data/gfx/balloon/powerball.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/balloon/powerball.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/powerball.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/powerball.ani", AssetType::ANIMATION);
}
{ // Bala
Asset::get()->add(prefix + "/data/gfx/bullet/bullet.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/bullet/bullet.png", AssetType::BITMAP);
}
{ // Juego
Asset::get()->add(prefix + "/data/gfx/game/game_buildings.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_buildings.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game/game_clouds1.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_clouds1.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game/game_clouds2.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_clouds2.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game/game_grass.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_grass.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game/game_power_meter.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_power_meter.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game/game_sky_colors.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_sky_colors.png", AssetType::BITMAP);
}
{ // Game Text
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_1000_points.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game_text/game_text_1000_points.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_2500_points.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game_text/game_text_2500_points.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_5000_points.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game_text/game_text_5000_points.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_powerup.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game_text/game_text_powerup.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_one_hit.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game_text/game_text_one_hit.png", AssetType::BITMAP);
}
{ // Intro
Asset::get()->add(prefix + "/data/gfx/intro/intro.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/intro/intro.png", AssetType::BITMAP);
}
{ // Logo
Asset::get()->add(prefix + "/data/gfx/logo/logo_jailgames.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/logo/logo_jailgames.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/logo/logo_jailgames_mini.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/logo/logo_jailgames_mini.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/logo/logo_since_1998.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/logo/logo_since_1998.png", AssetType::BITMAP);
}
{ // Items
Asset::get()->add(prefix + "/data/gfx/item/item_points1_disk.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_points1_disk.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_points1_disk.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/item/item_points1_disk.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_points2_gavina.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_points2_gavina.png", AssetType::BITMAP);
@@ -425,29 +447,37 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/gfx/item/item_coffee.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/item/item_coffee.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.ani", AssetType::ANIMATION);
}
{ // Titulo
Asset::get()->add(prefix + "/data/gfx/title/title_bg_tile.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/title/title_bg_tile.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_coffee.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/title/title_coffee.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_crisis.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/title/title_crisis.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_arcade_edition.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/title/title_arcade_edition.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_dust.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/title/title_dust.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_dust.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/title/title_dust.ani", AssetType::ANIMATION);
}
{ // Jugador 1
Asset::get()->add(prefix + "/data/gfx/player/player1.gif", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/player/player1.gif", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player/player1_pal1.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/player/player1_one_coffee_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player1_pal2.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/player/player1_two_coffee_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player1_pal3.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/player/player1_all_white_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player1_power.png", AssetType::BITMAP);
}
{ // Jugador 2
Asset::get()->add(prefix + "/data/gfx/player/player2.gif", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/player/player2.gif", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player/player2_pal1.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/player/player2_one_coffee_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player2_pal2.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/player/player2_two_coffee_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player2_pal3.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/player/player2_all_white_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player2_power.png", AssetType::BITMAP);
}
{ // Animaciones del jugador
Asset::get()->add(prefix + "/data/gfx/player/player.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/player/player.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/player/player_power.gif", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player/player_power_pal.gif", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player_power.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/player/player_power.ani", AssetType::ANIMATION);
}
// Fuentes de texto // Fuentes de texto
Asset::get()->add(prefix + "/data/font/8bithud.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/8bithud.png", AssetType::BITMAP);
@@ -461,7 +491,7 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/font/smb2_big.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/smb2_big.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/smb2_big.txt", AssetType::FONT); Asset::get()->add(prefix + "/data/font/smb2_big.txt", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/smb2.gif", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/smb2.gif", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/smb2_pal1.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/font/smb2_palette1.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/font/smb2.txt", AssetType::FONT); Asset::get()->add(prefix + "/data/font/smb2.txt", AssetType::FONT);
// Textos // Textos
@@ -658,19 +688,20 @@ int Director::run()
#ifdef ARCADE #ifdef ARCADE
// Comprueba si ha de apagar el sistema // Comprueba si ha de apagar el sistema
if (section::options == section::Options::QUIT_SHUTDOWN) if (section::options == section::Options::QUIT_WITH_CONTROLLER)
shutdownSystem(); shutdownSystem();
#endif #endif
const auto return_code = (section::options == section::Options::QUIT_NORMAL) ? "keyboard" : "controller"; const auto return_code = (section::options == section::Options::QUIT_WITH_KEYBOARD) ? "with keyboard" : (section::options == section::Options::QUIT_WITH_CONTROLLER) ? "with controller"
std::cout << "\nGame end with " << return_code << std::endl; : "from event";
std::cout << "\nGame end " << return_code << std::endl;
#ifndef VERBOSE #ifndef VERBOSE
// Habilita de nuevo los std::cout // Habilita de nuevo los std::cout
std::cout.rdbuf(orig_buf); std::cout.rdbuf(orig_buf);
#endif #endif
return (return_code == std::string("keyboard")) ? 0 : 1; return (section::options == section::Options::QUIT_WITH_CONTROLLER) ? 1 : 0;
} }
// Obtiene una fichero a partir de un lang::Code // Obtiene una fichero a partir de un lang::Code

View File

@@ -38,6 +38,7 @@
#include "texture.h" // for Texture #include "texture.h" // for Texture
struct JA_Music_t; // lines 35-35 struct JA_Music_t; // lines 35-35
struct JA_Sound_t; // lines 36-36 struct JA_Sound_t; // lines 36-36
#include "dbgtxt.h"
// Constructor // Constructor
Game::Game(int player_id, int current_stage, bool demo) Game::Game(int player_id, int current_stage, bool demo)
@@ -55,11 +56,11 @@ Game::Game(int player_id, int current_stage, bool demo)
difficulty_ = options.game.difficulty; difficulty_ = options.game.difficulty;
// Crea los objetos // Crea los objetos
Scoreboard::init(renderer_); Scoreboard::init();
scoreboard_ = Scoreboard::get(); scoreboard_ = Scoreboard::get();
fade_ = std::make_unique<Fade>(); fade_ = std::make_unique<Fade>();
background_ = std::make_unique<Background>(renderer_); background_ = std::make_unique<Background>();
explosions_ = std::make_unique<Explosions>(); explosions_ = std::make_unique<Explosions>();
balloon_formations_ = std::make_unique<BalloonFormations>(); balloon_formations_ = std::make_unique<BalloonFormations>();
@@ -69,10 +70,10 @@ Game::Game(int player_id, int current_stage, bool demo)
// Inicializa los vectores con los datos para la demo // Inicializa los vectores con los datos para la demo
if (demo_.enabled) if (demo_.enabled)
{ // Aleatoriza la asignación del fichero { // Aleatoriza la asignación del fichero
const auto index1 = rand() % 2; const auto demo1 = rand() % 2;
const auto index2 = (index1 + 1) % 2; const auto demo2 = (demo1 == 0) ? 1 : 0;
loadDemoFile(asset_->get("demo1.bin"), &this->demo_.data_file[index1]); demo_.data.emplace_back(Resource::get()->getDemoData(demo1));
loadDemoFile(asset_->get("demo2.bin"), &this->demo_.data_file[index2]); demo_.data.emplace_back(Resource::get()->getDemoData(demo2));
} }
background_->setPos(param.game.play_area.rect); background_->setPos(param.game.play_area.rect);
@@ -92,10 +93,13 @@ Game::Game(int player_id, int current_stage, bool demo)
Game::~Game() Game::~Game()
{ {
// Guarda las puntuaciones en un fichero // Guarda las puntuaciones en un fichero
if (!demo_.enabled)
{
auto manager = std::make_unique<ManageHiScoreTable>(&options.game.hi_score_table); auto manager = std::make_unique<ManageHiScoreTable>(&options.game.hi_score_table);
manager->saveToFile(asset_->get("score.bin")); manager->saveToFile(asset_->get("score.bin"));
}
#ifdef RECORDING #ifdef RECORDING
saveDemoFile(asset->get("demo1.bin")); saveDemoFile(Asset::get()->get("demo1.bin"), demo_.data.at(0));
#endif #endif
// Elimina todos los objetos contenidos en vectores // Elimina todos los objetos contenidos en vectores
@@ -112,9 +116,6 @@ Game::~Game()
// Inicializa las variables necesarias para la sección 'Game' // Inicializa las variables necesarias para la sección 'Game'
void Game::init(int player_id) void Game::init(int player_id)
{ {
ticks_ = 0;
ticks_speed_ = 15;
// Elimina qualquier jugador que hubiese antes de crear los nuevos // Elimina qualquier jugador que hubiese antes de crear los nuevos
players_.clear(); players_.clear();
@@ -189,6 +190,7 @@ void Game::init(int player_id)
scoreboard_->setMode(SCOREBOARD_CENTER_PANEL, ScoreboardMode::STAGE_INFO); scoreboard_->setMode(SCOREBOARD_CENTER_PANEL, ScoreboardMode::STAGE_INFO);
// Resto de variables // Resto de variables
ticks_ = 0;
hi_score_.score = options.game.hi_score_table[0].score; hi_score_.score = options.game.hi_score_table[0].score;
hi_score_.name = options.game.hi_score_table[0].name; hi_score_.name = options.game.hi_score_table[0].name;
paused_ = false; paused_ = false;
@@ -200,8 +202,8 @@ void Game::init(int player_id)
menace_current_ = 0; menace_current_ = 0;
menace_threshold_ = 0; menace_threshold_ = 0;
hi_score_achieved_ = false; hi_score_achieved_ = false;
stage_bitmap_counter_ = STAGE_COUNTER; stage_bitmap_counter_ = STAGE_COUNTER_;
game_over_counter_ = GAME_OVER_COUNTER; game_over_counter_ = GAME_OVER_COUNTER_;
time_stopped_ = false; time_stopped_ = false;
time_stopped_counter_ = 0; time_stopped_counter_ = 0;
counter_ = 0; counter_ = 0;
@@ -211,13 +213,13 @@ void Game::init(int player_id)
helper_.need_coffee = false; helper_.need_coffee = false;
helper_.need_coffee_machine = false; helper_.need_coffee_machine = false;
helper_.need_power_ball = false; helper_.need_power_ball = false;
helper_.counter = HELP_COUNTER; helper_.counter = HELP_COUNTER_;
helper_.item_disk_odds = ITEM_POINTS_1_DISK_ODDS; helper_.item_disk_odds = ITEM_POINTS_1_DISK_ODDS_;
helper_.item_gavina_odds = ITEM_POINTS_2_GAVINA_ODDS; helper_.item_gavina_odds = ITEM_POINTS_2_GAVINA_ODDS_;
helper_.item_pacmar_odds = ITEM_POINTS_3_PACMAR_ODDS; helper_.item_pacmar_odds = ITEM_POINTS_3_PACMAR_ODDS_;
helper_.item_clock_odds = ITEM_CLOCK_ODDS; helper_.item_clock_odds = ITEM_CLOCK_ODDS_;
helper_.item_coffee_odds = ITEM_COFFEE_ODDS; helper_.item_coffee_odds = ITEM_COFFEE_ODDS_;
helper_.item_coffee_machine_odds = ITEM_COFFEE_MACHINE_ODDS; helper_.item_coffee_machine_odds = ITEM_COFFEE_MACHINE_ODDS_;
power_ball_enabled_ = false; power_ball_enabled_ = false;
power_ball_counter_ = 0; power_ball_counter_ = 0;
coffee_machine_enabled_ = false; coffee_machine_enabled_ = false;
@@ -279,7 +281,7 @@ void Game::init(int player_id)
// Modo grabar demo // Modo grabar demo
#ifdef RECORDING #ifdef RECORDING
demo.recording = true; demo_.recording = true;
#else #else
demo_.recording = false; demo_.recording = false;
#endif #endif
@@ -347,13 +349,7 @@ void Game::loadMedia()
{ {
std::vector<std::shared_ptr<Texture>> player_texture; std::vector<std::shared_ptr<Texture>> player_texture;
player_texture.emplace_back(Resource::get()->getTexture("player1.gif")); player_texture.emplace_back(Resource::get()->getTexture("player1.gif"));
player_texture.back()->addPalette(asset_->get("player1_pal1.gif")); player_texture.emplace_back(Resource::get()->getTexture("player1_power.png"));
player_texture.back()->addPalette(asset_->get("player1_pal2.gif"));
player_texture.back()->addPalette(asset_->get("player1_pal3.gif"));
player_texture.emplace_back(Resource::get()->getTexture("player_power.gif"));
player_texture.back()->addPalette(asset_->get("player_power_pal.gif"));
player_textures_.push_back(player_texture); player_textures_.push_back(player_texture);
} }
@@ -361,14 +357,7 @@ void Game::loadMedia()
{ {
std::vector<std::shared_ptr<Texture>> player_texture; std::vector<std::shared_ptr<Texture>> player_texture;
player_texture.emplace_back(Resource::get()->getTexture("player2.gif")); player_texture.emplace_back(Resource::get()->getTexture("player2.gif"));
player_texture.back()->addPalette(asset_->get("player2_pal1.gif")); player_texture.emplace_back(Resource::get()->getTexture("player2_power.png"));
player_texture.back()->addPalette(asset_->get("player2_pal2.gif"));
player_texture.back()->addPalette(asset_->get("player2_pal3.gif"));
player_texture.emplace_back(Resource::get()->getTexture("player_power.gif"));
player_texture.back()->addPalette(asset_->get("player_power_pal.gif"));
player_texture.back()->setPalette(1);
player_textures_.push_back(player_texture); player_textures_.push_back(player_texture);
} }
@@ -431,99 +420,6 @@ void Game::unloadMedia()
item_animations_.clear(); item_animations_.clear();
} }
// Carga el fichero de datos para la demo
bool Game::loadDemoFile(const std::string &file_path, DemoKeys (*data_file)[TOTAL_DEMO_DATA])
{
// Indicador de éxito en la carga
auto success = true;
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1);
auto file = SDL_RWFromFile(file_path.c_str(), "r+b");
if (!file)
{ // El fichero no existe
std::cout << "Warning: Unable to open " << file_name.c_str() << " file" << std::endl;
// Creamos el fichero para escritura
file = SDL_RWFromFile(file_path.c_str(), "w+b");
// Si ha creado el fichero
if (file)
{
std::cout << "New file (" << file_name.c_str() << ") created!" << std::endl;
// Inicializas los datos y los guarda en el fichero
for (int i = 0; i < TOTAL_DEMO_DATA; ++i)
{
DemoKeys dk;
dk.left = 0;
dk.right = 0;
dk.no_input = 0;
dk.fire = 0;
dk.fire_left = 0;
dk.fire_right = 0;
(*data_file)[i] = dk;
SDL_RWwrite(file, &dk, sizeof(DemoKeys), 1);
}
// Cerramos el fichero
SDL_RWclose(file);
}
else
{ // Si no puede crear el fichero
std::cout << "Error: Unable to create file " << file_name.c_str() << std::endl;
success = false;
}
}
// El fichero existe
else
{
// Mensaje de proceder a la carga de los datos
std::cout << "Reading file: " << file_name.c_str() << std::endl;
// Lee todos los datos del fichero y los deja en el destino
for (int i = 0; i < TOTAL_DEMO_DATA; ++i)
{
DemoKeys tmp;
SDL_RWread(file, &tmp, sizeof(DemoKeys), 1);
(*data_file)[i] = tmp;
}
// Cierra el fichero
SDL_RWclose(file);
}
return success;
}
#ifdef RECORDING
// Guarda el fichero de datos para la demo
bool Game::saveDemoFile(const std::string &file_path)
{
auto success = true;
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1);
auto file = SDL_RWFromFile(file_path.c_str(), "w+b");
if (file)
{
// Guarda los datos
for (int i = 0; i < TOTAL_DEMO_DATA; ++i)
{
SDL_RWwrite(file, &demo.dataFile[0][i], sizeof(DemoKeys), 1);
}
std::cout << "Writing file " << file_name.c_str() << std::endl;
// Cierra el fichero
SDL_RWclose(file);
}
else
{
std::cout << "Error: Unable to save " << file_name.c_str() << " file! " << SDL_GetError() << std::endl;
}
return success;
}
#endif // RECORDING
// Crea una formación de enemigos // Crea una formación de enemigos
void Game::deployBalloonFormation() void Game::deployBalloonFormation()
{ {
@@ -543,7 +439,7 @@ void Game::deployBalloonFormation()
else else
{ {
// Decrementa el contador de despliegues enemigos de la PowerBall // Decrementa el contador de despliegues enemigos de la PowerBall
power_ball_counter_ > 0 ? power_ball_counter_-- : power_ball_counter_ = 0; power_ball_counter_ = (power_ball_counter_ > 0) ? (power_ball_counter_ - 1) : 0;
// Elige una formación enemiga la azar // Elige una formación enemiga la azar
auto set = rand() % 10; auto set = rand() % 10;
@@ -679,7 +575,7 @@ void Game::updateStage()
} }
// Incrementa el contador del bitmap que aparece mostrando el cambio de fase // Incrementa el contador del bitmap que aparece mostrando el cambio de fase
if (stage_bitmap_counter_ < STAGE_COUNTER) if (stage_bitmap_counter_ < STAGE_COUNTER_)
{ {
stage_bitmap_counter_++; stage_bitmap_counter_++;
} }
@@ -751,9 +647,8 @@ void Game::renderBalloons()
std::shared_ptr<Balloon> Game::createBalloon(float x, int y, int kind, float velx, float speed, int creation_timer) std::shared_ptr<Balloon> Game::createBalloon(float x, int y, int kind, float velx, float speed, int creation_timer)
{ {
const auto index = (kind - 1) % 4; const auto index = (kind - 1) % 4;
auto b = std::make_shared<Balloon>(x, y, kind, velx, speed, creation_timer, balloon_textures_[index], balloon_animations_[index]); balloons_.emplace_back(std::make_shared<Balloon>(x, y, kind, velx, speed, creation_timer, balloon_textures_[index], balloon_animations_[index]));
balloons_.push_back(b); return balloons_.back();
return b;
} }
// Crea una PowerBall // Crea una PowerBall
@@ -852,11 +747,11 @@ void Game::popBalloon(std::shared_ptr<Balloon> balloon)
{ // En cualquier otro caso, crea dos globos de un tipo inferior { // En cualquier otro caso, crea dos globos de un tipo inferior
auto balloon_left = createBalloon(0, balloon->getPosY(), balloon->getKind() - 1, BALLOON_VELX_NEGATIVE, balloon_speed_, 0); auto balloon_left = createBalloon(0, balloon->getPosY(), balloon->getKind() - 1, BALLOON_VELX_NEGATIVE, balloon_speed_, 0);
balloon_left->allignTo(balloon->getPosX() + (balloon->getWidth() / 2)); balloon_left->allignTo(balloon->getPosX() + (balloon->getWidth() / 2));
balloon_left->setVelY(balloon_left->getClass() == BALLOON_CLASS ? -2.50f : BALLOON_VELX_NEGATIVE); balloon_left->setVelY(balloon_left->getClass() == BALLOON_CLASS ? -2.50f : BALLOON_VELX_NEGATIVE * 2.0f);
auto balloon_right = createBalloon(0, balloon->getPosY(), balloon->getKind() - 1, BALLOON_VELX_POSITIVE, balloon_speed_, 0); auto balloon_right = createBalloon(0, balloon->getPosY(), balloon->getKind() - 1, BALLOON_VELX_POSITIVE, balloon_speed_, 0);
balloon_right->allignTo(balloon->getPosX() + (balloon->getWidth() / 2)); balloon_right->allignTo(balloon->getPosX() + (balloon->getWidth() / 2));
balloon_right->setVelY(balloon_right->getClass() == BALLOON_CLASS ? -2.50f : BALLOON_VELX_NEGATIVE); balloon_right->setVelY(balloon_right->getClass() == BALLOON_CLASS ? -2.50f : BALLOON_VELX_NEGATIVE * 2.0f);
// Elimina el globo // Elimina el globo
explosions_->add(balloon->getPosX(), balloon->getPosY(), size); explosions_->add(balloon->getPosX(), balloon->getPosY(), size);
@@ -1241,7 +1136,7 @@ ItemType Game::dropItem()
case 4: case 4:
if (lucky_number < helper_.item_coffee_odds) if (lucky_number < helper_.item_coffee_odds)
{ {
helper_.item_coffee_odds = ITEM_COFFEE_ODDS; helper_.item_coffee_odds = ITEM_COFFEE_ODDS_;
return ItemType::COFFEE; return ItemType::COFFEE;
} }
else else
@@ -1256,7 +1151,7 @@ ItemType Game::dropItem()
case 5: case 5:
if (lucky_number < helper_.item_coffee_machine_odds) if (lucky_number < helper_.item_coffee_machine_odds)
{ {
helper_.item_coffee_machine_odds = ITEM_COFFEE_MACHINE_ODDS; helper_.item_coffee_machine_odds = ITEM_COFFEE_MACHINE_ODDS_;
if (!coffee_machine_enabled_ && helper_.need_coffee_machine) if (!coffee_machine_enabled_ && helper_.need_coffee_machine)
{ {
return ItemType::COFFEE_MACHINE; return ItemType::COFFEE_MACHINE;
@@ -1455,7 +1350,7 @@ void Game::updateTimeStoppedCounter()
if (time_stopped_counter_ > 0) if (time_stopped_counter_ > 0)
{ {
time_stopped_counter_--; time_stopped_counter_--;
stopAllBalloons(TIME_STOPPED_COUNTER); stopAllBalloons(TIME_STOPPED_COUNTER_);
} }
else else
{ {
@@ -1477,7 +1372,7 @@ void Game::updateBalloonDeployCounter()
void Game::update() void Game::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks_ > ticks_speed_) if (SDL_GetTicks() - ticks_ > TICKS_SPEED_)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
@@ -1513,9 +1408,9 @@ void Game::update()
checkInput(); checkInput();
// Incrementa el contador de la demo // Incrementa el contador de la demo
if (demo.counter < TOTAL_DEMO_DATA) if (demo_.counter < TOTAL_DEMO_DATA)
{ {
demo.counter++; demo_.counter++;
} }
// Si se ha llenado el vector con datos, sale del programa // Si se ha llenado el vector con datos, sale del programa
@@ -1703,7 +1598,7 @@ void Game::updateMenace()
void Game::renderMessages() void Game::renderMessages()
{ {
// GetReady // GetReady
if (counter_ < STAGE_COUNTER && !demo_.enabled) if (counter_ < STAGE_COUNTER_ && !demo_.enabled)
{ {
text_nokia2_big_->write((int)get_ready_bitmap_path_[counter_], param.game.play_area.center_y - 8, lang::getText(75), -2); text_nokia2_big_->write((int)get_ready_bitmap_path_[counter_], param.game.play_area.center_y - 8, lang::getText(75), -2);
} }
@@ -1733,7 +1628,7 @@ void Game::renderMessages()
} }
// STAGE NUMBER // STAGE NUMBER
if (stage_bitmap_counter_ < STAGE_COUNTER) if (stage_bitmap_counter_ < STAGE_COUNTER_)
{ {
const auto stage_number = balloon_formations_->getStage(current_stage_).number; const auto stage_number = balloon_formations_->getStage(current_stage_).number;
std::string text; std::string text;
@@ -1763,9 +1658,9 @@ void Game::renderMessages()
// Habilita el efecto del item de detener el tiempo // Habilita el efecto del item de detener el tiempo
void Game::enableTimeStopItem() void Game::enableTimeStopItem()
{ {
stopAllBalloons(TIME_STOPPED_COUNTER); stopAllBalloons(TIME_STOPPED_COUNTER_);
setTimeStopped(true); setTimeStopped(true);
incTimeStoppedCounter(TIME_STOPPED_COUNTER); incTimeStoppedCounter(TIME_STOPPED_COUNTER_);
if (JA_GetMusicState() == JA_MUSIC_PLAYING && !demo_.enabled) if (JA_GetMusicState() == JA_MUSIC_PLAYING && !demo_.enabled)
{ {
JA_PauseMusic(); JA_PauseMusic();
@@ -1836,7 +1731,7 @@ void Game::initPaths()
} }
// Letrero de STAGE # // Letrero de STAGE #
constexpr auto first_part = STAGE_COUNTER / 4; // 50 constexpr auto first_part = STAGE_COUNTER_ / 4; // 50
constexpr auto second_part = first_part * 3; // 150 constexpr auto second_part = first_part * 3; // 150
const auto center_point = param.game.play_area.center_y - (BLOCK * 2); const auto center_point = param.game.play_area.center_y - (BLOCK * 2);
const auto distance = (param.game.play_area.rect.h) - (param.game.play_area.center_y - 16); const auto distance = (param.game.play_area.rect.h) - (param.game.play_area.center_y - 16);
@@ -1851,7 +1746,7 @@ void Game::initPaths()
stage_bitmap_path_[i] = (int)center_point; stage_bitmap_path_[i] = (int)center_point;
} }
for (int i = second_part; i < STAGE_COUNTER; ++i) for (int i = second_part; i < STAGE_COUNTER_; ++i)
{ {
stage_bitmap_path_[i] = (sin[(int)(((i - 149) * 1.8f) + 90)] * (center_point + 17) - 17); stage_bitmap_path_[i] = (sin[(int)(((i - 149) * 1.8f) + 90)] * (center_point + 17) - 17);
} }
@@ -1878,7 +1773,7 @@ void Game::initPaths()
get_ready_bitmap_path_[i] = (int)finish1; get_ready_bitmap_path_[i] = (int)finish1;
} }
for (int i = second_part; i < STAGE_COUNTER; ++i) for (int i = second_part; i < STAGE_COUNTER_; ++i)
{ {
get_ready_bitmap_path_[i] = sin[(int)((i - second_part) * 1.8f)]; get_ready_bitmap_path_[i] = sin[(int)((i - second_part) * 1.8f)];
get_ready_bitmap_path_[i] *= distance2; get_ready_bitmap_path_[i] *= distance2;
@@ -1894,7 +1789,7 @@ void Game::updateGameCompleted()
game_completed_counter_++; game_completed_counter_++;
} }
if (game_completed_counter_ == GAME_COMPLETED_END) if (game_completed_counter_ == GAME_COMPLETED_END_)
{ {
section::name = section::Name::TITLE; section::name = section::Name::TITLE;
section::options = section::Options::TITLE_1; section::options = section::Options::TITLE_1;
@@ -1970,6 +1865,7 @@ void Game::checkEvents()
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
break; break;
} }
@@ -2041,20 +1937,6 @@ void Game::checkEvents()
break; break;
} }
// Ralentiza mucho la lógica
case SDLK_4:
{
ticks_speed_ *= 10;
break;
}
// Acelera mucho la lógica
case SDLK_5:
{
ticks_speed_ /= 10;
break;
}
default: default:
break; break;
} }
@@ -2254,7 +2136,7 @@ void Game::handleDemoMode()
// Incluye movimientos (izquierda, derecha, sin movimiento) y disparos automáticos. // Incluye movimientos (izquierda, derecha, sin movimiento) y disparos automáticos.
void Game::handleDemoPlayerInput(const std::shared_ptr<Player> &player, int index) void Game::handleDemoPlayerInput(const std::shared_ptr<Player> &player, int index)
{ {
const auto &demoData = demo_.data_file[index][demo_.counter]; const auto &demoData = demo_.data[index][demo_.counter];
if (demoData.left == 1) if (demoData.left == 1)
player->setInput(InputType::LEFT); player->setInput(InputType::LEFT);
@@ -2314,21 +2196,21 @@ void Game::handleNormalPlayerInput(const std::shared_ptr<Player> &player)
{ {
player->setInput(InputType::LEFT); player->setInput(InputType::LEFT);
#ifdef RECORDING #ifdef RECORDING
demo.keys.left = 1; demo_.keys.left = 1;
#endif #endif
} }
else if (input_->checkInput(InputType::RIGHT, INPUT_ALLOW_REPEAT, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index)) else if (input_->checkInput(InputType::RIGHT, INPUT_ALLOW_REPEAT, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
{ {
player->setInput(InputType::RIGHT); player->setInput(InputType::RIGHT);
#ifdef RECORDING #ifdef RECORDING
demo.keys.right = 1; demo_.keys.right = 1;
#endif #endif
} }
else else
{ {
player->setInput(InputType::NONE); player->setInput(InputType::NONE);
#ifdef RECORDING #ifdef RECORDING
demo.keys.no_input = 1; demo_.keys.no_input = 1;
#endif #endif
} }
@@ -2342,21 +2224,21 @@ void Game::handleFireInputs(const std::shared_ptr<Player> &player, bool autofire
{ {
handleFireInput(player, BulletType::UP); handleFireInput(player, BulletType::UP);
#ifdef RECORDING #ifdef RECORDING
demo.keys.fire = 1; demo_.keys.fire = 1;
#endif #endif
} }
else if (input_->checkInput(InputType::FIRE_LEFT, autofire, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index)) else if (input_->checkInput(InputType::FIRE_LEFT, autofire, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
{ {
handleFireInput(player, BulletType::LEFT); handleFireInput(player, BulletType::LEFT);
#ifdef RECORDING #ifdef RECORDING
demo.keys.fire_left = 1; demo_.keys.fire_left = 1;
#endif #endif
} }
else if (input_->checkInput(InputType::FIRE_RIGHT, autofire, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index)) else if (input_->checkInput(InputType::FIRE_RIGHT, autofire, options.controller[controllerIndex].device_type, options.controller[controllerIndex].index))
{ {
handleFireInput(player, BulletType::RIGHT); handleFireInput(player, BulletType::RIGHT);
#ifdef RECORDING #ifdef RECORDING
demo.keys.fire_right = 1; demo_.keys.fire_right = 1;
#endif #endif
} }
} }

View File

@@ -32,26 +32,6 @@ constexpr bool GAME_MODE_DEMO_ON = true;
// Cantidad de elementos a escribir en los ficheros de datos // Cantidad de elementos a escribir en los ficheros de datos
constexpr int TOTAL_SCORE_DATA = 3; constexpr int TOTAL_SCORE_DATA = 3;
constexpr int TOTAL_DEMO_DATA = 2000;
// Contadores
constexpr int STAGE_COUNTER = 200;
constexpr int HELP_COUNTER = 1000;
constexpr int GAME_COMPLETED_START_FADE = 500;
constexpr int GAME_COMPLETED_END = 700;
constexpr int GAME_OVER_COUNTER = 350;
// Porcentaje de aparición de los objetos
constexpr int ITEM_POINTS_1_DISK_ODDS = 10;
constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6;
constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3;
constexpr int ITEM_CLOCK_ODDS = 5;
constexpr int ITEM_COFFEE_ODDS = 5;
constexpr int ITEM_POWER_BALL_ODDS = 0;
constexpr int ITEM_COFFEE_MACHINE_ODDS = 4;
// Valores para las variables asociadas a los objetos
constexpr int TIME_STOPPED_COUNTER = 300;
/* /*
Esta clase gestiona un estado del programa. Se encarga de toda la parte en la Esta clase gestiona un estado del programa. Se encarga de toda la parte en la
@@ -83,6 +63,7 @@ constexpr int TIME_STOPPED_COUNTER = 300;
class Game class Game
{ {
private: private:
// Estructuras
struct Helper struct Helper
{ {
bool need_coffee; // Indica si se necesitan cafes bool need_coffee; // Indica si se necesitan cafes
@@ -97,14 +78,25 @@ private:
int item_coffee_machine_odds; // Probabilidad de aparición del objeto int item_coffee_machine_odds; // Probabilidad de aparición del objeto
}; };
struct Demo // Constantes
{
bool enabled; // Indica si está activo el modo demo // Contadores
bool recording; // Indica si está activado el modo para grabar la demo static constexpr int STAGE_COUNTER_ = 200;
int counter; // Contador para el modo demo static constexpr int HELP_COUNTER_ = 1000;
DemoKeys keys; // Variable con las pulsaciones de teclas del modo demo static constexpr int GAME_COMPLETED_START_FADE_ = 500;
DemoKeys data_file[2][TOTAL_DEMO_DATA]; // Vector con diferentes sets de datos con los movimientos para la demo static constexpr int GAME_COMPLETED_END_ = 700;
}; static constexpr int GAME_OVER_COUNTER_ = 350;
static constexpr int TIME_STOPPED_COUNTER_ = 300;
static constexpr int TICKS_SPEED_ = 15;
// Porcentaje de aparición de los objetos
static constexpr int ITEM_POINTS_1_DISK_ODDS_ = 10;
static constexpr int ITEM_POINTS_2_GAVINA_ODDS_ = 6;
static constexpr int ITEM_POINTS_3_PACMAR_ODDS_ = 3;
static constexpr int ITEM_CLOCK_ODDS_ = 5;
static constexpr int ITEM_COFFEE_ODDS_ = 5;
static constexpr int ITEM_POWER_BALL_ODDS_ = 0;
static constexpr int ITEM_COFFEE_MACHINE_ODDS_ = 4;
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
@@ -147,13 +139,12 @@ private:
// Variables // Variables
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa
bool hi_score_achieved_; // Indica si se ha superado la puntuación máxima bool hi_score_achieved_; // Indica si se ha superado la puntuación máxima
HiScoreEntry hi_score_; // Máxima puntuación y nombre de quien la ostenta HiScoreEntry hi_score_; // Máxima puntuación y nombre de quien la ostenta
int current_stage_; // Indica la fase actual int current_stage_; // Indica la fase actual
int stage_bitmap_counter_; // Contador para el tiempo visible del texto de Stage int stage_bitmap_counter_; // Contador para el tiempo visible del texto de Stage
float stage_bitmap_path_[STAGE_COUNTER]; // Vector con los puntos Y por donde se desplaza el texto float stage_bitmap_path_[STAGE_COUNTER_]; // Vector con los puntos Y por donde se desplaza el texto
float get_ready_bitmap_path_[STAGE_COUNTER]; // Vector con los puntos X por donde se desplaza el texto float get_ready_bitmap_path_[STAGE_COUNTER_]; // Vector con los puntos X por donde se desplaza el texto
int game_over_counter_; // Contador para el estado de fin de partida int game_over_counter_; // Contador para el estado de fin de partida
int menace_current_; // Nivel de amenaza actual int menace_current_; // Nivel de amenaza actual
int menace_threshold_; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos int menace_threshold_; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos
@@ -201,12 +192,6 @@ private:
// Libera los recursos previamente cargados // Libera los recursos previamente cargados
void unloadMedia(); void unloadMedia();
// Carga el fichero de datos para la demo
bool loadDemoFile(const std::string &file_path, DemoKeys (*data_file)[TOTAL_DEMO_DATA]);
#ifdef RECORDING
// Guarda el fichero de datos para la demo
bool saveDemoFile(const std::string &file_path);
#endif
// Crea una formación de enemigos // Crea una formación de enemigos
void deployBalloonFormation(); void deployBalloonFormation();

View File

@@ -39,7 +39,7 @@ namespace globalInputs
else else
{ {
#ifdef ARCADE #ifdef ARCADE
const int index = code == section::Options::QUIT_NORMAL ? 94 : 116; const int index = code == section::Options::QUIT_WITH_CONTROLLER ? 116 : 94;
Notifier::get()->showText(lang::getText(index), std::string(), -1, exit_code); Notifier::get()->showText(lang::getText(index), std::string(), -1, exit_code);
#else #else
Notifier::get()->showText(lang::getText(94), std::string(), -1, exit_code); Notifier::get()->showText(lang::getText(94), std::string(), -1, exit_code);
@@ -69,7 +69,7 @@ namespace globalInputs
// Comprueba si se sale con el teclado // Comprueba si se sale con el teclado
if (Input::get()->checkInput(InputType::EXIT, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_KEYBOARD)) if (Input::get()->checkInput(InputType::EXIT, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_KEYBOARD))
{ {
quit(section::Options::QUIT_NORMAL); quit(section::Options::QUIT_WITH_KEYBOARD);
return; return;
} }
@@ -107,7 +107,7 @@ namespace globalInputs
// Comprueba si se sale con el mando // Comprueba si se sale con el mando
if (Input::get()->checkModInput(InputType::SERVICE, InputType::EXIT, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i)) if (Input::get()->checkModInput(InputType::SERVICE, InputType::EXIT, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i))
{ {
quit(section::Options::QUIT_SHUTDOWN); quit(section::Options::QUIT_WITH_CONTROLLER);
return; return;
} }

View File

@@ -23,29 +23,21 @@
// Constructor // Constructor
HiScoreTable::HiScoreTable() HiScoreTable::HiScoreTable()
: renderer_(Screen::get()->getRenderer()),
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
fade_(std::make_unique<Fade>()),
background_(std::make_unique<Background>()),
text_(std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"))),
counter_(0),
ticks_(0),
view_area_({0, 0, param.game.width, param.game.height}),
fade_mode_(FadeMode::IN)
{ {
// Copia punteros // Inicializa el resto de variables
renderer_ = Screen::get()->getRenderer();
// Objetos
fade_ = std::make_unique<Fade>();
background_ = std::make_unique<Background>(renderer_);
text_ = std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"));
// Crea un backbuffer para el renderizador
backbuffer_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height);
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
// Inicializa variables
section::name = section::Name::HI_SCORE_TABLE; section::name = section::Name::HI_SCORE_TABLE;
ticks_ = 0;
ticks_speed_ = 15;
counter_ = 0;
counter_end_ = 800;
view_area_ = {0, 0, param.game.width, param.game.height};
fade_mode_ = FadeMode::IN;
// Inicializa objetos // Inicializa objetos
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
background_->setPos(param.game.game_area.rect); background_->setPos(param.game.game_area.rect);
background_->setCloudsSpeed(-0.1f); background_->setCloudsSpeed(-0.1f);
background_->setGradientNumber(1); background_->setGradientNumber(1);
@@ -70,7 +62,7 @@ HiScoreTable::~HiScoreTable()
void HiScoreTable::update() void HiScoreTable::update()
{ {
// Actualiza las variables // Actualiza las variables
if (SDL_GetTicks() - ticks_ > ticks_speed_) if (SDL_GetTicks() - ticks_ > TICKS_SPEED_)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
@@ -99,7 +91,7 @@ void HiScoreTable::update()
background_->setAlpha(96); background_->setAlpha(96);
} }
if (counter_ == counter_end_) if (counter_ == COUNTER_END_)
{ {
fade_->activate(); fade_->activate();
} }
@@ -188,6 +180,7 @@ void HiScoreTable::checkEvents()
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
break; break;
} }

View File

@@ -24,6 +24,10 @@ enum class FadeMode : Uint8; // lines 11-11
class HiScoreTable class HiScoreTable
{ {
private: private:
// Constantes
static constexpr Uint16 COUNTER_END_ = 800; // Valor final para el contador
static constexpr Uint32 TICKS_SPEED_ = 15; // Velocidad a la que se repiten los bucles del programa
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *backbuffer_; // Textura para usar como backbuffer SDL_Texture *backbuffer_; // Textura para usar como backbuffer
@@ -34,9 +38,7 @@ private:
// Variables // Variables
Uint16 counter_; // Contador Uint16 counter_; // Contador
Uint16 counter_end_; // Valor final para el contador
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa
SDL_Rect view_area_; // Parte de la textura que se muestra en pantalla SDL_Rect view_area_; // Parte de la textura que se muestra en pantalla
FadeMode fade_mode_; // Modo de fade a utilizar FadeMode fade_mode_; // Modo de fade a utilizar

View File

@@ -416,10 +416,9 @@ bool Input::discoverGameControllers()
} }
} }
{ std::cout << "\n** LOOKING FOR GAME CONTROLLERS" << std::endl;
std::cout << "\nChecking for game controllers...\n"; // std::cout << " " << num_joysticks_ << " joysticks found" << std::endl;
std::cout << num_joysticks_ << " joysticks found, " << num_gamepads_ << " are gamepads\n"; std::cout << "Gamepads found: " << num_gamepads_ << std::endl;
}
if (num_gamepads_ > 0) if (num_gamepads_ > 0)
{ {
@@ -434,7 +433,7 @@ bool Input::discoverGameControllers()
connected_controllers_.push_back(pad); connected_controllers_.push_back(pad);
const std::string name = SDL_GameControllerNameForIndex(i); const std::string name = SDL_GameControllerNameForIndex(i);
{ {
std::cout << name << std::endl; std::cout << "#" << i << ": " << name << std::endl;
} }
controller_names_.push_back(name); controller_names_.push_back(name);
} }
@@ -449,6 +448,8 @@ bool Input::discoverGameControllers()
SDL_GameControllerEventState(SDL_ENABLE); SDL_GameControllerEventState(SDL_ENABLE);
} }
std::cout << "\n** FINISHED LOOKING FOR GAME CONTROLLERS" << std::endl;
return found; return found;
} }

View File

@@ -31,7 +31,7 @@ Instructions::Instructions()
// Crea objetos // Crea objetos
text_ = std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt")); text_ = std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"));
tiled_bg_ = std::make_unique<TiledBG>((SDL_Rect){0, 0, param.game.width, param.game.height}, TILED_MODE_STATIC); tiled_bg_ = std::make_unique<TiledBG>((SDL_Rect){0, 0, param.game.width, param.game.height}, TiledBGMode::STATIC);
fade_ = std::make_unique<Fade>(); fade_ = std::make_unique<Fade>();
// Crea un backbuffer para el renderizador // Crea un backbuffer para el renderizador
@@ -297,6 +297,7 @@ void Instructions::checkEvents()
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
break; break;
} }

View File

@@ -170,6 +170,7 @@ void Intro::checkEvents()
case SDL_QUIT: case SDL_QUIT:
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
break; break;
} }

View File

@@ -73,6 +73,7 @@ void Logo::checkEvents()
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
break; break;
} }

View File

@@ -347,7 +347,7 @@ void Player::update()
setAnimation(); setAnimation();
shiftColliders(); shiftColliders();
updateCooldown(); updateCooldown();
updatePowerUpCounter(); updatePowerUp();
updateInvulnerable(); updateInvulnerable();
updateContinueCounter(); updateContinueCounter();
updateEnterNameCounter(); updateEnterNameCounter();
@@ -578,7 +578,7 @@ void Player::updateInvulnerable()
{ {
if (invulnerable_counter_ > 0) if (invulnerable_counter_ > 0)
{ {
invulnerable_counter_--; --invulnerable_counter_;
invulnerable_counter_ % 8 > 3 ? player_sprite_->getTexture()->setPalette(coffees_) : player_sprite_->getTexture()->setPalette(3); invulnerable_counter_ % 8 > 3 ? player_sprite_->getTexture()->setPalette(coffees_) : player_sprite_->getTexture()->setPalette(3);
} }
else else
@@ -615,15 +615,12 @@ void Player::setPowerUpCounter(int value)
} }
// Actualiza el valor de la variable // Actualiza el valor de la variable
void Player::updatePowerUpCounter() void Player::updatePowerUp()
{ {
if ((power_up_counter_ > 0) && (power_up_)) if (power_up_)
{ {
power_up_counter_--; --power_up_counter_;
} power_up_ = power_up_counter_ > 0;
else
{
power_up_ = false;
} }
} }

View File

@@ -49,7 +49,7 @@ private:
SDL_Rect *play_area_; // Rectangulo con la zona de juego SDL_Rect *play_area_; // Rectangulo con la zona de juego
// Variables // Variables
int id_; // Numero de identificación para el jugador int id_; // Numero de identificación para el jugador. Player1 = 1, Player2 = 2
float pos_x_; // Posicion en el eje X float pos_x_; // Posicion en el eje X
int pos_y_; // Posicion en el eje Y int pos_y_; // Posicion en el eje Y
float default_pos_x_; // Posición inicial para el jugador float default_pos_x_; // Posición inicial para el jugador
@@ -245,7 +245,7 @@ public:
void setPowerUpCounter(int value); void setPowerUpCounter(int value);
// Actualiza el valor de la variable // Actualiza el valor de la variable
void updatePowerUpCounter(); void updatePowerUp();
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool hasExtraHit() const; bool hasExtraHit() const;

View File

@@ -33,6 +33,8 @@ Resource::Resource()
loadTextures(); loadTextures();
loadTextFiles(); loadTextFiles();
loadAnimations(); loadAnimations();
loadDemoData();
addPalettes();
std::cout << "\n** RESOURCES LOADED" << std::endl; std::cout << "\n** RESOURCES LOADED" << std::endl;
} }
@@ -116,6 +118,12 @@ Animations &Resource::getAnimation(const std::string &name)
throw std::runtime_error("Animación no encontrada: " + name); throw std::runtime_error("Animación no encontrada: " + name);
} }
// Obtiene el fichero con los datos para el modo demostración a partir de un çindice
DemoData &Resource::getDemoData(int index)
{
return demos_.at(index);
}
// Carga los sonidos // Carga los sonidos
void Resource::loadSounds() void Resource::loadSounds()
{ {
@@ -220,3 +228,29 @@ void Resource::loadAnimations()
animations_.emplace_back(ResourceAnimation(name, loadAnimationsFromFile(l))); animations_.emplace_back(ResourceAnimation(name, loadAnimationsFromFile(l)));
} }
} }
// Carga los datos para el modo demostración
void Resource::loadDemoData()
{
std::cout << "\n>> DEMO_FILES" << std::endl;
demos_.emplace_back(loadDemoDataFromFile(Asset::get()->get("demo1.bin")));
demos_.emplace_back(loadDemoDataFromFile(Asset::get()->get("demo2.bin")));
}
// Añade paletas a las texturas
void Resource::addPalettes()
{
// Jugador 1
std::cout << "\n>> PALETTES" << std::endl;
getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_one_coffee_palette.pal"));
getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_two_coffee_palette.pal"));
getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_all_white_palette.pal"));
// Jugador 2
getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_one_coffee_palette.pal"));
getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_two_coffee_palette.pal"));
getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_all_white_palette.pal"));
// Fuentes
getTexture("smb2.gif")->addPaletteFromFile(Asset::get()->get("smb2_palette1.pal"));
}

View File

@@ -7,6 +7,7 @@
#include "jail_audio.h" #include "jail_audio.h"
#include "texture.h" #include "texture.h"
#include "text.h" #include "text.h"
#include "utils.h"
#include "animated_sprite.h" #include "animated_sprite.h"
// Estructura para almacenar ficheros de sonido y su nombre // Estructura para almacenar ficheros de sonido y su nombre
@@ -75,6 +76,7 @@ private:
std::vector<ResourceTexture> textures_; // Vector con las musicas std::vector<ResourceTexture> textures_; // Vector con las musicas
std::vector<ResourceTextFile> text_files_; // Vector con los ficheros de texto std::vector<ResourceTextFile> text_files_; // Vector con los ficheros de texto
std::vector<ResourceAnimation> animations_; // Vector con las animaciones std::vector<ResourceAnimation> animations_; // Vector con las animaciones
std::vector<DemoData> demos_; // Vector con los ficheros de datos para el modo demostración
// Carga los sonidos // Carga los sonidos
void loadSounds(); void loadSounds();
@@ -91,6 +93,12 @@ private:
// Carga las animaciones // Carga las animaciones
void loadAnimations(); void loadAnimations();
// Carga los datos para el modo demostración
void loadDemoData();
// Añade paletas a las texturas
void addPalettes();
// [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos resource desde fuera // [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos resource desde fuera
// Constructor // Constructor
@@ -123,4 +131,7 @@ public:
// Obtiene la animación a partir de un nombre // Obtiene la animación a partir de un nombre
Animations &getAnimation(const std::string &name); Animations &getAnimation(const std::string &name);
// Obtiene el fichero con los datos para el modo demostración a partir de un çindice
DemoData &getDemoData(int index);
}; };

View File

@@ -8,6 +8,7 @@
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "lang.h" // for getText #include "lang.h" // for getText
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h"
#include "sprite.h" // for Sprite #include "sprite.h" // for Sprite
#include "text.h" // for Text #include "text.h" // for Text
#include "texture.h" // for Texture #include "texture.h" // for Texture
@@ -16,9 +17,9 @@
Scoreboard *Scoreboard::scoreboard_ = nullptr; Scoreboard *Scoreboard::scoreboard_ = nullptr;
// [SINGLETON] Crearemos el objeto score_board con esta función estática // [SINGLETON] Crearemos el objeto score_board con esta función estática
void Scoreboard::init(SDL_Renderer *renderer) void Scoreboard::init()
{ {
Scoreboard::scoreboard_ = new Scoreboard(renderer); Scoreboard::scoreboard_ = new Scoreboard();
} }
// [SINGLETON] Destruiremos el objeto score_board con esta función estática // [SINGLETON] Destruiremos el objeto score_board con esta función estática
@@ -34,8 +35,8 @@ Scoreboard *Scoreboard::get()
} }
// Constructor // Constructor
Scoreboard::Scoreboard(SDL_Renderer *renderer) Scoreboard::Scoreboard()
: renderer_(renderer), : renderer_(Screen::get()->getRenderer()),
game_power_meter_texture_(Resource::get()->getTexture("game_power_meter.png")), game_power_meter_texture_(Resource::get()->getTexture("game_power_meter.png")),
power_meter_sprite_(std::make_unique<Sprite>(game_power_meter_texture_)), power_meter_sprite_(std::make_unique<Sprite>(game_power_meter_texture_)),
@@ -107,7 +108,7 @@ std::string Scoreboard::updateScoreText(int num)
// Actualiza el contador // Actualiza el contador
void Scoreboard::updateCounter() void Scoreboard::updateCounter()
{ {
if (SDL_GetTicks() - ticks_ > SCOREBOARD_TICK_SPEED) if (SDL_GetTicks() - ticks_ > SCOREBOARD_TICK_SPEED_)
{ {
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
counter_++; counter_++;

View File

@@ -16,7 +16,6 @@ constexpr int SCOREBOARD_LEFT_PANEL = 0;
constexpr int SCOREBOARD_CENTER_PANEL = 1; constexpr int SCOREBOARD_CENTER_PANEL = 1;
constexpr int SCOREBOARD_RIGHT_PANEL = 2; constexpr int SCOREBOARD_RIGHT_PANEL = 2;
constexpr int SCOREBOARD_MAX_PANELS = 3; constexpr int SCOREBOARD_MAX_PANELS = 3;
constexpr int SCOREBOARD_TICK_SPEED = 100;
// Enums // Enums
enum class ScoreboardMode : int enum class ScoreboardMode : int
@@ -42,6 +41,9 @@ struct Panel
class Scoreboard class Scoreboard
{ {
private: private:
// Constantes
static constexpr int SCOREBOARD_TICK_SPEED_ = 100;
// [SINGLETON] Objeto scoreboard privado para Don Melitón // [SINGLETON] Objeto scoreboard privado para Don Melitón
static Scoreboard *scoreboard_; static Scoreboard *scoreboard_;
@@ -103,14 +105,14 @@ private:
// [SINGLETON] Ahora el constructor y el destructor son privados // [SINGLETON] Ahora el constructor y el destructor son privados
// Constructor // Constructor
explicit Scoreboard(SDL_Renderer *renderer); Scoreboard();
// Destructor // Destructor
~Scoreboard(); ~Scoreboard();
public: public:
// [SINGLETON] Crearemos el objeto scoreboard con esta función estática // [SINGLETON] Crearemos el objeto scoreboard con esta función estática
static void init(SDL_Renderer *renderer); static void init();
// [SINGLETON] Destruiremos el objeto scoreboard con esta función estática // [SINGLETON] Destruiremos el objeto scoreboard con esta función estática
static void destroy(); static void destroy();

View File

@@ -23,9 +23,10 @@ namespace section
GAME_PLAY_2P = 1, GAME_PLAY_2P = 1,
TITLE_1 = 2, TITLE_1 = 2,
TITLE_2 = 3, TITLE_2 = 3,
QUIT_NORMAL = 4, QUIT_WITH_KEYBOARD = 4,
QUIT_SHUTDOWN = 5, QUIT_WITH_CONTROLLER = 5,
NONE = 6, QUIT_FROM_EVENT = 6,
NONE = 7,
}; };
extern Name name; extern Name name;

View File

@@ -77,33 +77,8 @@ std::shared_ptr<TextFile> loadTextFile(const std::string &file_path)
return tf; return tf;
} }
// Constructor
Text::Text(const std::string &bitmap_file, const std::string &text_file, SDL_Renderer *renderer)
{
// Carga los offsets desde el fichero
auto tf = loadTextFile(text_file);
// Inicializa variables desde la estructura
box_height_ = tf->box_height;
box_width_ = tf->box_width;
for (int i = 0; i < 128; ++i)
{
offset_[i].x = tf->offset[i].x;
offset_[i].y = tf->offset[i].y;
offset_[i].w = tf->offset[i].w;
}
// Crea los objetos
texture_ = std::make_shared<Texture>(renderer, bitmap_file);
sprite_ = std::make_unique<Sprite>(texture_, (SDL_Rect){0, 0, box_width_, box_height_});
// Inicializa variables
fixed_width_ = false;
}
// Constructor // Constructor
Text::Text(std::shared_ptr<Texture> texture, const std::string &text_file) Text::Text(std::shared_ptr<Texture> texture, const std::string &text_file)
: texture_(texture)
{ {
// Carga los offsets desde el fichero // Carga los offsets desde el fichero
auto tf = loadTextFile(text_file); auto tf = loadTextFile(text_file);
@@ -127,7 +102,6 @@ Text::Text(std::shared_ptr<Texture> texture, const std::string &text_file)
// Constructor // Constructor
Text::Text(std::shared_ptr<Texture> texture, std::shared_ptr<TextFile> text_file) Text::Text(std::shared_ptr<Texture> texture, std::shared_ptr<TextFile> text_file)
: texture_(texture)
{ {
// Inicializa variables desde la estructura // Inicializa variables desde la estructura
box_height_ = text_file->box_height; box_height_ = text_file->box_height;
@@ -266,15 +240,3 @@ void Text::setFixedWidth(bool value)
{ {
fixed_width_ = value; fixed_width_ = value;
} }
// Carga una paleta de colores para el texto
void Text::addPalette(const std::string &path)
{
texture_->addPalette(path);
}
// Establece una paleta de colores para el texto
void Text::setPalette(int index)
{
texture_->setPalette(index);
}

View File

@@ -34,7 +34,6 @@ class Text
private: private:
// Objetos y punteros // Objetos y punteros
std::unique_ptr<Sprite> sprite_; // Objeto con los graficos para el texto std::unique_ptr<Sprite> sprite_; // Objeto con los graficos para el texto
std::shared_ptr<Texture> texture_; // Textura con los bitmaps del texto
// Variables // Variables
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
@@ -44,7 +43,6 @@ private:
public: public:
// Constructor // Constructor
Text(const std::string &bitmap_file, const std::string &text_file, SDL_Renderer *renderer);
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);
@@ -77,10 +75,4 @@ public:
// Establece si se usa un tamaño fijo de letra // Establece si se usa un tamaño fijo de letra
void setFixedWidth(bool value); void setFixedWidth(bool value);
// Carga una paleta de colores para el texto
void addPalette(const std::string &path);
// Establece una paleta de colores para el texto
void setPalette(int index);
}; };

View File

@@ -7,22 +7,22 @@
#include <stdio.h> // for fseek, fclose, fopen, fread, ftell, NULL #include <stdio.h> // for fseek, fclose, fopen, fread, ftell, NULL
#include <stdlib.h> // for malloc, free, exit #include <stdlib.h> // for malloc, free, exit
#include <iostream> // for basic_ostream, operator<<, cout, endl #include <iostream> // for basic_ostream, operator<<, cout, endl
#include <fstream>
#include <sstream>
#include "gif.c" // for LoadGif, LoadPalette #include "gif.c" // for LoadGif, LoadPalette
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" // for stbi_failure_reason, stbi_image_free #include "stb_image.h" // for stbi_failure_reason, stbi_image_free
// Constructor // Constructor
Texture::Texture(SDL_Renderer *renderer, const std::string &path) Texture::Texture(SDL_Renderer *renderer, const std::string &path)
: renderer_(renderer), path_(path) : texture_(nullptr),
renderer_(renderer),
surface_(nullptr),
width_(0),
height_(0),
path_(path),
current_palette_(0)
{ {
// Inicializa
surface_ = nullptr;
texture_ = nullptr;
width_ = 0;
height_ = 0;
paletteIndex_ = 0;
palettes_.clear();
// Carga el fichero en la textura // Carga el fichero en la textura
if (!path_.empty()) if (!path_.empty())
{ {
@@ -38,9 +38,14 @@ Texture::Texture(SDL_Renderer *renderer, const std::string &path)
// .gif // .gif
else if (extension == "gif") else if (extension == "gif")
{ {
// Crea la surface desde un fichero
surface_ = loadSurface(path_); surface_ = loadSurface(path_);
addPalette(path_);
setPaletteColor(0, 0, 0x00000000); // Añade la propia paleta del fichero a la lista
addPaletteFromFile(path_);
//setPaletteColor(0, 0, 0x00000000);
// Crea la textura, establece el BlendMode y copia la surface a la textura
createBlank(width_, height_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING); createBlank(width_, height_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING);
SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
flipSurface(); flipSurface();
@@ -51,7 +56,9 @@ Texture::Texture(SDL_Renderer *renderer, const std::string &path)
// Destructor // Destructor
Texture::~Texture() Texture::~Texture()
{ {
unload(); unloadTexture();
unloadSurface();
palettes_.clear();
} }
// Carga una imagen desde un fichero // Carga una imagen desde un fichero
@@ -87,7 +94,7 @@ bool Texture::loadFromFile(const std::string &file_path)
} }
// Limpia // Limpia
unload(); unloadTexture();
// La textura final // La textura final
SDL_Texture *newTexture = nullptr; SDL_Texture *newTexture = nullptr;
@@ -142,7 +149,7 @@ bool Texture::createBlank(int width, int height, SDL_PixelFormatEnum format, SDL
} }
// Libera la memoria de la textura // Libera la memoria de la textura
void Texture::unload() void Texture::unloadTexture()
{ {
// Libera la textura // Libera la textura
if (texture_) if (texture_)
@@ -152,13 +159,6 @@ void Texture::unload()
width_ = 0; width_ = 0;
height_ = 0; height_ = 0;
} }
// Libera la surface
if (surface_)
{
deleteSurface(surface_);
surface_ = nullptr;
}
} }
// Establece el color para la modulacion // Establece el color para la modulacion
@@ -229,61 +229,56 @@ SDL_Texture *Texture::getSDLTexture()
return texture_; return texture_;
} }
// Crea una nueva surface // Desencadenar la superficie actual
/*Surface Texture::newSurface(int w, int h) void Texture::unloadSurface()
{ {
Surface surf = static_cast<Surface>(malloc(sizeof(surface_s))); surface_.reset(); // Resetea el shared_ptr
surf->w = w; width_ = 0;
surf->h = h; height_ = 0;
surf->data = static_cast<Uint8 *>(malloc(w * h));
return surf;
}*/
// Elimina una surface
void Texture::deleteSurface(Surface surface)
{
if (surface == nullptr)
{
return;
}
if (surface->data != nullptr)
{
free(surface->data);
}
free(surface);
} }
// Crea una surface desde un fichero .gif // Crea una surface desde un fichero .gif
Surface Texture::loadSurface(const std::string &file_name) std::shared_ptr<Surface> Texture::loadSurface(const std::string &file_path)
{ {
FILE *f = fopen(file_name.c_str(), "rb"); // Desencadenar la superficie actual
if (!f) unloadSurface();
// Abrir el archivo usando std::ifstream para manejo automático del recurso
std::ifstream file(file_path, std::ios::binary | std::ios::ate);
if (!file)
{ {
return nullptr; std::cerr << "Error: Fichero no encontrado " << file_path << std::endl;
throw std::runtime_error("Fichero no encontrado: " + file_path);
} }
fseek(f, 0, SEEK_END); // Obtener el tamaño del archivo
long size = ftell(f); std::streamsize size = file.tellg();
fseek(f, 0, SEEK_SET); file.seekg(0, std::ios::beg);
Uint8 *buffer = static_cast<Uint8 *>(malloc(size));
fread(buffer, size, 1, f);
fclose(f);
// Leer el contenido del archivo en un buffer
std::vector<Uint8> buffer(size);
if (!file.read(reinterpret_cast<char *>(buffer.data()), size))
{
std::cerr << "Error al leer el fichero " << file_path << std::endl;
throw std::runtime_error("Error al leer el fichero: " + file_path);
}
// Cerrar el archivo (automáticamente manejado por std::ifstream)
file.close();
// Llamar a la función LoadGif
Uint16 w, h; Uint16 w, h;
Uint8 *pixels = LoadGif(buffer, &w, &h); Uint8 *rawPixels = LoadGif(buffer.data(), &w, &h);
if (pixels == nullptr) if (!rawPixels)
{ {
return nullptr; return nullptr;
} }
Surface surface = static_cast<Surface>(malloc(sizeof(surface_s))); // Crear un std::shared_ptr con std::make_shared para pixels
surface->w = w; auto pixels = std::shared_ptr<Uint8[]>(rawPixels, std::default_delete<Uint8[]>());
surface->h = h; auto surface = std::make_shared<Surface>(w, h, pixels);
surface->data = pixels;
free(buffer);
// Actualizar la anchura y altura
width_ = w; width_ = w;
height_ = h; height_ = h;
@@ -306,7 +301,7 @@ void Texture::flipSurface()
SDL_LockTexture(texture_, nullptr, reinterpret_cast<void **>(&pixels), &pitch); SDL_LockTexture(texture_, nullptr, reinterpret_cast<void **>(&pixels), &pitch);
for (int i = 0; i < width_ * height_; ++i) for (int i = 0; i < width_ * height_; ++i)
{ {
pixels[i] = palettes_[paletteIndex_][surface_->data[i]]; pixels[i] = palettes_[current_palette_][surface_->data[i]];
} }
SDL_UnlockTexture(texture_); SDL_UnlockTexture(texture_);
} }
@@ -318,14 +313,20 @@ void Texture::setPaletteColor(int palette, int index, Uint32 color)
} }
// Carga una paleta desde un fichero // Carga una paleta desde un fichero
std::vector<Uint32> Texture::loadPal(const std::string &file_name) std::vector<Uint32> Texture::loadPaletteFromFile(const std::string &file_path)
{ {
std::vector<Uint32> palette; std::vector<Uint32> palette;
FILE *f = fopen(file_name.c_str(), "rb"); FILE *f = fopen(file_path.c_str(), "rb");
if (!f) if (!f)
{ {
return palette; std::cerr << "Error: Fichero no encontrado " << file_path << std::endl;
throw std::runtime_error("Fichero no encontrado: " + file_path);
}
else
{
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1);
printWithDots("Image : ", file_name, "[ LOADED ]");
} }
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
@@ -352,9 +353,9 @@ std::vector<Uint32> Texture::loadPal(const std::string &file_name)
} }
// Añade una paleta a la lista // Añade una paleta a la lista
void Texture::addPalette(const std::string &path) void Texture::addPaletteFromFile(const std::string &path)
{ {
palettes_.push_back(loadPal(path)); palettes_.emplace_back(loadPaletteFromFile(path));
setPaletteColor((int)palettes_.size() - 1, 0, 0x00000000); setPaletteColor((int)palettes_.size() - 1, 0, 0x00000000);
} }
@@ -363,7 +364,7 @@ void Texture::setPalette(int palette)
{ {
if (palette < (int)palettes_.size()) if (palette < (int)palettes_.size())
{ {
paletteIndex_ = palette; current_palette_ = palette;
flipSurface(); flipSurface();
} }
} }

View File

@@ -7,15 +7,18 @@
#include <SDL2/SDL_stdinc.h> // for Uint8, Uint32, Uint16 #include <SDL2/SDL_stdinc.h> // for Uint8, Uint32, Uint16
#include <string> // for string, basic_string #include <string> // for string, basic_string
#include <vector> // for vector #include <vector> // for vector
#include <memory>
// Definiciones de tipos // Definiciones de tipos
struct surface_s struct Surface
{ {
Uint8 *data; std::shared_ptr<Uint8[]> data;
Uint16 w, h; Uint16 w, h;
};
typedef struct surface_s *Surface; // Constructor
Surface(Uint16 width, Uint16 height, std::shared_ptr<Uint8[]> pixels)
: data(pixels), w(width), h(height) {}
};
class Texture class Texture
{ {
@@ -23,29 +26,29 @@ private:
// Objetos y punteros // Objetos y punteros
SDL_Texture *texture_; // La textura SDL_Texture *texture_; // La textura
SDL_Renderer *renderer_; // Renderizador donde dibujar la textura SDL_Renderer *renderer_; // Renderizador donde dibujar la textura
Surface surface_; // Surface para usar imagenes en formato gif con paleta std::shared_ptr<Surface> surface_; // Surface para usar imagenes en formato gif con paleta
// Variables // Variables
int width_; // Ancho de la imagen int width_; // Ancho de la imagen
int height_; // Alto de la imagen int height_; // Alto de la imagen
std::string path_; // Ruta de la imagen de la textura std::string path_; // Ruta de la imagen de la textura
std::vector<std::vector<Uint32>> palettes_; // Vector con las diferentes paletas std::vector<std::vector<Uint32>> palettes_; // Vector con las diferentes paletas
int paletteIndex_; // Indice de la paleta en uso int current_palette_; // Indice de la paleta en uso
// Crea una nueva surface
//Surface newSurface(int w, int h);
// Elimina una surface
void deleteSurface(Surface surface);
// Crea una surface desde un fichero .gif // Crea una surface desde un fichero .gif
Surface loadSurface(const std::string &file_name); std::shared_ptr<Surface> loadSurface(const std::string &file_name);
// Vuelca la surface en la textura // Vuelca la surface en la textura
void flipSurface(); void flipSurface();
// Carga una paleta desde un fichero // Carga una paleta desde un fichero
std::vector<Uint32> loadPal(const std::string &file_name); std::vector<Uint32> loadPaletteFromFile(const std::string &file_name);
// Libera la memoria de la textura
void unloadTexture();
// Desencadenar la superficie actual
void unloadSurface();
public: public:
// Constructor // Constructor
@@ -60,9 +63,6 @@ public:
// Crea una textura en blanco // Crea una textura en blanco
bool createBlank(int width, int height, SDL_PixelFormatEnum format = SDL_PIXELFORMAT_RGBA8888, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING); bool createBlank(int width, int height, SDL_PixelFormatEnum format = SDL_PIXELFORMAT_RGBA8888, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING);
// Libera la memoria de la textura
void unload();
// Establece el color para la modulacion // Establece el color para la modulacion
void setColor(Uint8 red, Uint8 green, Uint8 blue); void setColor(Uint8 red, Uint8 green, Uint8 blue);
@@ -91,7 +91,7 @@ public:
SDL_Texture *getSDLTexture(); SDL_Texture *getSDLTexture();
// Añade una paleta a la lista // Añade una paleta a la lista
void addPalette(const std::string &path); void addPaletteFromFile(const std::string &path);
// Establece un color de la paleta // Establece un color de la paleta
void setPaletteColor(int palette, int index, Uint32 color); void setPaletteColor(int palette, int index, Uint32 color);

View File

@@ -9,11 +9,11 @@
#include "texture.h" // for Texture #include "texture.h" // for Texture
// Constructor // Constructor
TiledBG::TiledBG(SDL_Rect pos, int mode) TiledBG::TiledBG(SDL_Rect pos, TiledBGMode mode)
: renderer_(Screen::get()->getRenderer()), : renderer_(Screen::get()->getRenderer()),
pos_(pos), pos_(pos),
counter_(0), counter_(0),
mode_(mode == TILED_MODE_RANDOM ? rand() % 2 : mode) mode_(mode == TiledBGMode::RANDOM ? static_cast<TiledBGMode>(rand() % 2) : mode)
{ {
// Crea la textura para el mosaico de fondo // Crea la textura para el mosaico de fondo
canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, pos_.w * 2, pos_.h * 2); canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, pos_.w * 2, pos_.h * 2);
@@ -28,7 +28,7 @@ TiledBG::TiledBG(SDL_Rect pos, int mode)
// Inicializa los valores del vector con los valores del seno // Inicializa los valores del vector con los valores del seno
for (int i = 0; i < 360; ++i) for (int i = 0; i < 360; ++i)
{ {
sin_[i] = std::sinf(i * 3.14159f / 180.0f); // Convierte grados a radianes y calcula el seno sin_[i] = std::sin(i * 3.14159 / 180.0); // Convierte grados a radianes y calcula el seno
} }
} }
@@ -75,16 +75,23 @@ void TiledBG::render()
// Actualiza la lógica de la clase // Actualiza la lógica de la clase
void TiledBG::update() void TiledBG::update()
{ {
if (mode_ == TILED_MODE_DIAGONAL) switch (mode_)
{
case TiledBGMode::DIAGONAL:
{ // El tileado de fondo se desplaza en diagonal { // El tileado de fondo se desplaza en diagonal
++window_.x %= TILE_WIDTH_; ++window_.x %= TILE_WIDTH_;
++window_.y %= TILE_HEIGHT_; ++window_.y %= TILE_HEIGHT_;
break;
} }
else if (mode_ == TILED_MODE_CIRCLE) case TiledBGMode::CIRCLE:
{ // El tileado de fondo se desplaza en circulo { // El tileado de fondo se desplaza en circulo
++counter_ %= 360; ++counter_ %= 360;
window_.x = 128 + (int(sin_[(counter_ + 270) % 360] * 128)); window_.x = 128 + (int(sin_[(counter_ + 270) % 360] * 128));
window_.y = 96 + (int(sin_[(360 - counter_) % 360] * 96)); window_.y = 96 + (int(sin_[(360 - counter_) % 360] * 96));
break;
}
default:
break;
} }
} }

View File

@@ -5,10 +5,13 @@
#include <string> // for string, basic_string #include <string> // for string, basic_string
// Modos de funcionamiento para el tileado de fondo // Modos de funcionamiento para el tileado de fondo
#define TILED_MODE_CIRCLE 0 enum class TiledBGMode : int
#define TILED_MODE_DIAGONAL 1 {
#define TILED_MODE_RANDOM 2 CIRCLE = 0,
#define TILED_MODE_STATIC 3 DIAGONAL = 1,
RANDOM = 2,
STATIC = 3,
};
/* /*
Esta clase dibuja un tileado de fondo. Para ello se sirve de una textura "canvas", que rellena con los tiles. Esta clase dibuja un tileado de fondo. Para ello se sirve de una textura "canvas", que rellena con los tiles.
@@ -32,15 +35,15 @@ private:
// Variables // Variables
SDL_Rect pos_; // Posición y tamaño del mosaico SDL_Rect pos_; // Posición y tamaño del mosaico
int counter_; // Contador int counter_; // Contador
int mode_; // Tipo de movimiento del mosaico TiledBGMode mode_; // Tipo de movimiento del mosaico
float sin_[360]; // Vector con los valores del seno precalculados double sin_[360]; // Vector con los valores del seno precalculados
// Rellena la textura con el contenido // Rellena la textura con el contenido
void fillTexture(); void fillTexture();
public: public:
// Constructor // Constructor
TiledBG(SDL_Rect pos, int mode); TiledBG(SDL_Rect pos, TiledBGMode mode);
// Destructor // Destructor
~TiledBG(); ~TiledBG();

View File

@@ -24,51 +24,43 @@ struct JA_Music_t; // lines 17-17
// Constructor // Constructor
Title::Title() Title::Title()
: text1_(std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"))),
text2_(std::make_unique<Text>(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt"))),
fade_(std::make_unique<Fade>()),
tiled_bg_(std::make_unique<TiledBG>((SDL_Rect){0, 0, param.game.width, param.game.height}, TiledBGMode::RANDOM)),
game_logo_(std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position)),
mini_logo_texture_(Resource::get()->getTexture("logo_jailgames_mini.png")),
mini_logo_sprite_(std::make_unique<Sprite>(mini_logo_texture_, param.game.game_area.center_x - mini_logo_texture_->getWidth() / 2, 0, mini_logo_texture_->getWidth(), mini_logo_texture_->getHeight())),
define_buttons_(std::make_unique<DefineButtons>(std::move(text2_))),
counter_(0),
ticks_(0),
demo_(true),
next_section_(section::Name::GAME),
post_fade_(0),
num_controllers_(Input::get()->getNumControllers())
{ {
// Reserva memoria y crea los objetos // Configura objetos
fade_ = std::make_unique<Fade>();
text1_ = std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"));
text1_->addPalette(Asset::get()->get("smb2_pal1.gif"));
text1_->setPalette(1);
text2_ = std::make_unique<Text>(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt"));
mini_logo_texture_ = Resource::get()->getTexture("logo_jailgames_mini.png");
mini_logo_sprite_ = std::make_unique<Sprite>(mini_logo_texture_, param.game.game_area.center_x - mini_logo_texture_->getWidth() / 2, 0, mini_logo_texture_->getWidth(), mini_logo_texture_->getHeight());
tiled_bg_ = std::make_unique<TiledBG>((SDL_Rect){0, 0, param.game.width, param.game.height}, TILED_MODE_RANDOM);
game_logo_ = std::make_unique<GameLogo>(param.game.game_area.center_x, param.title.title_c_c_position);
game_logo_->enable(); game_logo_->enable();
define_buttons_ = std::make_unique<DefineButtons>(std::move(text2_));
// Inicializa los valores
init();
}
// Inicializa los valores de las variables
void Title::init()
{
// Inicializa variables
section::options = section::Options::TITLE_1;
counter_ = 0;
next_section_ = section::Name::GAME;
post_fade_ = 0;
ticks_ = 0;
ticks_speed_ = 15;
fade_->setColor(fade_color.r, fade_color.g, fade_color.b); fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
fade_->setType(FadeType::RANDOM_SQUARE); fade_->setType(FadeType::RANDOM_SQUARE);
fade_->setPost(param.fade.post_duration); fade_->setPost(param.fade.post_duration);
demo_ = true; Resource::get()->getTexture("smb2.gif")->setPalette(1);
num_controllers_ = Input::get()->getNumControllers();
// Asigna valores a otras variables
section::options = section::Options::TITLE_1;
}
// Destructor
Title::~Title()
{
Resource::get()->getTexture("smb2.gif")->setPalette(0);
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
void Title::update() void Title::update()
{ {
// Calcula la lógica de los objetos // Calcula la lógica de los objetos
if (SDL_GetTicks() - ticks_ > ticks_speed_) if (SDL_GetTicks() - ticks_ > TICKS_SPEED_)
{ {
// Actualiza el contador de ticks_ // Actualiza el contador de ticks_
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
@@ -188,6 +180,7 @@ void Title::checkEvents()
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
break; break;
} }

View File

@@ -42,29 +42,28 @@ constexpr bool ALLOW_TITLE_ANIMATION_SKIP = true;
class Title class Title
{ {
private: private:
// Objetos y punteros // Constantes
std::unique_ptr<TiledBG> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo static constexpr Uint32 TICKS_SPEED_ = 15; // Velocidad a la que se repiten los bucles del programa
std::unique_ptr<GameLogo> game_logo_; // Objeto para dibujar el logo con el título del juego
std::unique_ptr<DefineButtons> define_buttons_; // Objeto para definir los botones del joystic
std::shared_ptr<Texture> mini_logo_texture_; // Textura con el logo de JailGames mini
std::unique_ptr<Sprite> mini_logo_sprite_; // Sprite con el logo de JailGames mini
// Objetos y punteros
std::unique_ptr<Text> text1_; // Objeto de texto para poder escribir textos en pantalla std::unique_ptr<Text> text1_; // Objeto de texto para poder escribir textos en pantalla
std::unique_ptr<Text> text2_; // Objeto de texto para poder escribir textos en pantalla std::unique_ptr<Text> text2_; // Objeto de texto para poder escribir textos en pantalla
std::unique_ptr<Fade> fade_; // Objeto para realizar fundidos en pantalla std::unique_ptr<Fade> fade_; // Objeto para realizar fundidos en pantalla
std::unique_ptr<TiledBG> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo
std::unique_ptr<GameLogo> game_logo_; // Objeto para dibujar el logo con el título del juego
std::shared_ptr<Texture> mini_logo_texture_; // Textura con el logo de JailGames mini
std::unique_ptr<Sprite> mini_logo_sprite_; // Sprite con el logo de JailGames mini
std::unique_ptr<DefineButtons> define_buttons_; // Objeto para definir los botones del joystic
// Variable // Variable
int counter_; // Temporizador para la pantalla de titulo int counter_; // Temporizador para la pantalla de titulo
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa
bool demo_; // Indica si el modo demo estará activo bool demo_; // Indica si el modo demo estará activo
section::Name next_section_; // Indica cual es la siguiente sección a cargar cuando termine el contador del titulo section::Name next_section_; // Indica cual es la siguiente sección a cargar cuando termine el contador del titulo
int post_fade_; // Opción a realizar cuando termina el fundido int post_fade_; // Opción a realizar cuando termina el fundido
int num_controllers_; // Número de mandos conectados int num_controllers_; // Número de mandos conectados
// Inicializa los valores de las variables
void init();
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update();
@@ -91,7 +90,7 @@ public:
Title(); Title();
// Destructor // Destructor
~Title() = default; ~Title();
// Bucle para el titulo del juego // Bucle para el titulo del juego
void run(); void run();

View File

@@ -197,9 +197,78 @@ void printWithDots(const std::string &text1, const std::string &text2, const std
std::cout.setf(std::ios::left, std::ios::adjustfield); std::cout.setf(std::ios::left, std::ios::adjustfield);
std::cout << text1; std::cout << text1;
std::cout.width(70 - text1.length() - text3.length()); std::cout.width(50 - text1.length() - text3.length());
std::cout.fill('.'); std::cout.fill('.');
std::cout << text2; std::cout << text2;
std::cout << text3 << std::endl; std::cout << text3 << std::endl;
} }
// Carga el fichero de datos para la demo
DemoData loadDemoDataFromFile(const std::string &file_path)
{
DemoData dd;
// Indicador de éxito en la carga
auto file = SDL_RWFromFile(file_path.c_str(), "r+b");
if (!file)
{
std::cerr << "Error: Fichero no encontrado " << file_path << std::endl;
throw std::runtime_error("Fichero no encontrado: " + file_path);
}
else
{
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1);
printWithDots("DemoData : ", file_name, "[ LOADED ]");
// Lee todos los datos del fichero y los deja en el destino
for (int i = 0; i < TOTAL_DEMO_DATA; ++i)
{
DemoKeys dk = DemoKeys();
SDL_RWread(file, &dk, sizeof(DemoKeys), 1);
dd.push_back(dk);
}
// Cierra el fichero
SDL_RWclose(file);
}
return dd;
}
#ifdef RECORDING
// Guarda el fichero de datos para la demo
bool saveDemoFile(const std::string &file_path, const DemoData &dd)
{
auto success = true;
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1);
auto file = SDL_RWFromFile(file_path.c_str(), "w+b");
if (file)
{
// Guarda los datos
for (const auto &data : dd)
{
if (SDL_RWwrite(file, &data, sizeof(DemoKeys), 1) != 1)
{
std::cerr << "Error al escribir el fichero " << file_name << std::endl;
success = false;
break;
}
}
if (success)
{
std::cout << "Writing file " << file_name.c_str() << std::endl;
}
// Cierra el fichero
SDL_RWclose(file);
}
else
{
std::cout << "Error: Unable to save " << file_name.c_str() << " file! " << SDL_GetError() << std::endl;
success = false;
}
return success;
}
#endif // RECORDING

View File

@@ -17,6 +17,10 @@ namespace lang
struct JA_Music_t; // lines 12-12 struct JA_Music_t; // lines 12-12
struct JA_Sound_t; // lines 13-13 struct JA_Sound_t; // lines 13-13
// Constantes
constexpr int BLOCK = 8;
constexpr int TOTAL_DEMO_DATA = 2000;
// Dificultad del juego // Dificultad del juego
enum class GameDifficulty enum class GameDifficulty
{ {
@@ -25,9 +29,6 @@ enum class GameDifficulty
HARD = 2, HARD = 2,
}; };
// Tamaño de bloque
constexpr int BLOCK = 8;
// Estructura para definir un circulo // Estructura para definir un circulo
struct Circle struct Circle
{ {
@@ -58,7 +59,6 @@ struct HiScoreEntry
int score; // Puntuación int score; // Puntuación
}; };
// Estructura para mapear el teclado usado en la demo
struct DemoKeys struct DemoKeys
{ {
Uint8 left; Uint8 left;
@@ -67,6 +67,21 @@ struct DemoKeys
Uint8 fire; Uint8 fire;
Uint8 fire_left; Uint8 fire_left;
Uint8 fire_right; Uint8 fire_right;
// Constructor que inicializa todos los campos
DemoKeys(Uint8 l = 0, Uint8 r = 0, Uint8 ni = 0, Uint8 f = 0, Uint8 fl = 0, Uint8 fr = 0)
: left(l), right(r), no_input(ni), fire(f), fire_left(fl), fire_right(fr) {}
};
using DemoData = std::vector<DemoKeys>;
struct Demo
{
bool enabled; // Indica si está activo el modo demo
bool recording; // Indica si está activado el modo para grabar la demo
int counter; // Contador para el modo demo
DemoKeys keys; // Variable con las pulsaciones de teclas del modo demo
std::vector<DemoData> data; // Vector con diferentes sets de datos con los movimientos para la demo
}; };
// Estructura para las opciones de la ventana // Estructura para las opciones de la ventana
@@ -215,7 +230,6 @@ struct Param
ParamNotification notification; // Opciones para las notificaciones ParamNotification notification; // Opciones para las notificaciones
}; };
// Calcula el cuadrado de la distancia entre dos puntos // Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2); double distanceSquared(int x1, int y1, int x2, int y2);
@@ -267,6 +281,14 @@ bool stringInVector(const std::vector<std::string> &vec, const std::string &str)
// Imprime por pantalla una linea de texto de tamaño fijo rellena con puntos // Imprime por pantalla una linea de texto de tamaño fijo rellena con puntos
void printWithDots(const std::string &text1, const std::string &text2, const std::string &text3); void printWithDots(const std::string &text1, const std::string &text2, const std::string &text3);
// Carga el fichero de datos para la demo
DemoData loadDemoDataFromFile(const std::string &file_path);
#ifdef RECORDING
// Guarda el fichero de datos para la demo
bool saveDemoFile(const std::string &file_path, const DemoData &dd);
#endif
// Colores // Colores
extern const Color bg_color; extern const Color bg_color;
extern const Color no_color; extern const Color no_color;