clang-format

This commit is contained in:
2026-04-03 10:58:04 +02:00
parent 550a005ca6
commit c25d4dc7e5
50 changed files with 9735 additions and 11503 deletions

View File

@@ -1,538 +1,458 @@
#include "animatedsprite.h" #include "animatedsprite.h"
#include <fstream> // for basic_ostream, operator<<, basic_istream, basic...
#include <iostream> // for cout #include <fstream> // for basic_ostream, operator<<, basic_istream, basic...
#include <sstream> // for basic_stringstream #include <iostream> // for cout
#include <sstream> // for basic_stringstream
#include "texture.h" // for Texture #include "texture.h" // for Texture
// Carga la animación desde un fichero // Carga la animación desde un fichero
animatedSprite_t loadAnimationFromFile(Texture *texture, std::string filePath, bool verbose) animatedSprite_t loadAnimationFromFile(Texture *texture, std::string filePath, bool verbose) {
{ // Inicializa variables
// Inicializa variables animatedSprite_t as;
animatedSprite_t as; as.texture = texture;
as.texture = texture; int framesPerRow = 0;
int framesPerRow = 0; int frameWidth = 0;
int frameWidth = 0; int frameHeight = 0;
int frameHeight = 0; int maxTiles = 0;
int maxTiles = 0;
const std::string filename = filePath.substr(filePath.find_last_of("\\/") + 1); const std::string filename = filePath.substr(filePath.find_last_of("\\/") + 1);
std::ifstream file(filePath); std::ifstream file(filePath);
std::string line; std::string line;
// El fichero se puede abrir // El fichero se puede abrir
if (file.good()) if (file.good()) {
{ // Procesa el fichero linea a linea
// Procesa el fichero linea a linea if (verbose) {
if (verbose) std::cout << "Animation loaded: " << filename << std::endl;
{ }
std::cout << "Animation loaded: " << filename << std::endl; while (std::getline(file, line)) {
} // Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
while (std::getline(file, line)) if (line == "[animation]") {
{ animation_t buffer;
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación buffer.counter = 0;
if (line == "[animation]") buffer.currentFrame = 0;
{ buffer.completed = false;
animation_t buffer;
buffer.counter = 0;
buffer.currentFrame = 0;
buffer.completed = false;
do do {
{ std::getline(file, line);
std::getline(file, line);
// Encuentra la posición del caracter '=' // Encuentra la posición del caracter '='
int pos = line.find("="); int pos = line.find("=");
// Procesa las dos subcadenas // Procesa las dos subcadenas
if (pos != (int)line.npos) if (pos != (int)line.npos) {
{ if (line.substr(0, pos) == "name") {
if (line.substr(0, pos) == "name") buffer.name = line.substr(pos + 1, line.length());
{ }
buffer.name = line.substr(pos + 1, line.length());
}
else if (line.substr(0, pos) == "speed") else if (line.substr(0, pos) == "speed") {
{ buffer.speed = std::stoi(line.substr(pos + 1, line.length()));
buffer.speed = std::stoi(line.substr(pos + 1, line.length())); }
}
else if (line.substr(0, pos) == "loop") else if (line.substr(0, pos) == "loop") {
{ buffer.loop = std::stoi(line.substr(pos + 1, line.length()));
buffer.loop = std::stoi(line.substr(pos + 1, line.length())); }
}
else if (line.substr(0, pos) == "frames") else if (line.substr(0, pos) == "frames") {
{ // Se introducen los valores separados por comas en un vector
// Se introducen los valores separados por comas en un vector std::stringstream ss(line.substr(pos + 1, line.length()));
std::stringstream ss(line.substr(pos + 1, line.length())); std::string tmp;
std::string tmp; SDL_Rect rect = {0, 0, frameWidth, frameHeight};
SDL_Rect rect = {0, 0, frameWidth, frameHeight}; while (getline(ss, tmp, ',')) {
while (getline(ss, tmp, ',')) // Comprueba que el tile no sea mayor que el maximo indice permitido
{ const int numTile = std::stoi(tmp) > maxTiles ? 0 : std::stoi(tmp);
// Comprueba que el tile no sea mayor que el maximo indice permitido rect.x = (numTile % framesPerRow) * frameWidth;
const int numTile = std::stoi(tmp) > maxTiles ? 0 : std::stoi(tmp); rect.y = (numTile / framesPerRow) * frameHeight;
rect.x = (numTile % framesPerRow) * frameWidth; buffer.frames.push_back(rect);
rect.y = (numTile / framesPerRow) * frameHeight; }
buffer.frames.push_back(rect); }
}
}
else else {
{ std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; }
} }
} } while (line != "[/animation]");
} while (line != "[/animation]");
// Añade la animación al vector de animaciones // Añade la animación al vector de animaciones
as.animations.push_back(buffer); as.animations.push_back(buffer);
} }
// En caso contrario se parsea el fichero para buscar las variables y los valores // En caso contrario se parsea el fichero para buscar las variables y los valores
else else {
{ // Encuentra la posición del caracter '='
// Encuentra la posición del caracter '=' int pos = line.find("=");
int pos = line.find("=");
// Procesa las dos subcadenas // Procesa las dos subcadenas
if (pos != (int)line.npos) if (pos != (int)line.npos) {
{ if (line.substr(0, pos) == "framesPerRow") {
if (line.substr(0, pos) == "framesPerRow") framesPerRow = std::stoi(line.substr(pos + 1, line.length()));
{ }
framesPerRow = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frameWidth") else if (line.substr(0, pos) == "frameWidth") {
{ frameWidth = std::stoi(line.substr(pos + 1, line.length()));
frameWidth = std::stoi(line.substr(pos + 1, line.length())); }
}
else if (line.substr(0, pos) == "frameHeight") else if (line.substr(0, pos) == "frameHeight") {
{ frameHeight = std::stoi(line.substr(pos + 1, line.length()));
frameHeight = std::stoi(line.substr(pos + 1, line.length())); }
}
else else {
{ std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
std::cout << "Warning: file " << filename.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl; }
}
// Normaliza valores // Normaliza valores
if (framesPerRow == 0 && frameWidth > 0) if (framesPerRow == 0 && frameWidth > 0) {
{ framesPerRow = texture->getWidth() / frameWidth;
framesPerRow = texture->getWidth() / frameWidth; }
}
if (maxTiles == 0 && frameWidth > 0 && frameHeight > 0) if (maxTiles == 0 && frameWidth > 0 && frameHeight > 0) {
{ const int w = texture->getWidth() / frameWidth;
const int w = texture->getWidth() / frameWidth; const int h = texture->getHeight() / frameHeight;
const int h = texture->getHeight() / frameHeight; maxTiles = w * h;
maxTiles = w * h; }
} }
} }
} }
}
// Cierra el fichero // Cierra el fichero
file.close(); file.close();
} }
// El fichero no se puede abrir // El fichero no se puede abrir
else else {
{ if (verbose) {
if (verbose) std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl;
{ }
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl; }
}
}
return as; return as;
} }
// Constructor // Constructor
AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, std::string file, std::vector<std::string> *buffer) AnimatedSprite::AnimatedSprite(Texture *texture, SDL_Renderer *renderer, std::string file, std::vector<std::string> *buffer) {
{ // Copia los punteros
// Copia los punteros setTexture(texture);
setTexture(texture); setRenderer(renderer);
setRenderer(renderer);
// Carga las animaciones // Carga las animaciones
if (file != "") if (file != "") {
{ animatedSprite_t as = loadAnimationFromFile(texture, file);
animatedSprite_t as = loadAnimationFromFile(texture, file);
// Copia los datos de las animaciones // Copia los datos de las animaciones
for (auto animation : as.animations) for (auto animation : as.animations) {
{ this->animation.push_back(animation);
this->animation.push_back(animation); }
} }
}
else if (buffer) else if (buffer) {
{ loadFromVector(buffer);
loadFromVector(buffer); }
}
// Inicializa variables // Inicializa variables
currentAnimation = 0; currentAnimation = 0;
} }
// Constructor // Constructor
AnimatedSprite::AnimatedSprite(SDL_Renderer *renderer, animatedSprite_t *animation) AnimatedSprite::AnimatedSprite(SDL_Renderer *renderer, animatedSprite_t *animation) {
{ // Copia los punteros
// Copia los punteros setTexture(animation->texture);
setTexture(animation->texture); setRenderer(renderer);
setRenderer(renderer);
// Inicializa variables // Inicializa variables
currentAnimation = 0; currentAnimation = 0;
// Copia los datos de las animaciones // Copia los datos de las animaciones
for (auto a : animation->animations) for (auto a : animation->animations) {
{ this->animation.push_back(a);
this->animation.push_back(a); }
}
} }
// Destructor // Destructor
AnimatedSprite::~AnimatedSprite() AnimatedSprite::~AnimatedSprite() {
{ for (auto &a : animation) {
for (auto &a : animation) a.frames.clear();
{ }
a.frames.clear(); animation.clear();
}
animation.clear();
} }
// Obtiene el indice de la animación a partir del nombre // Obtiene el indice de la animación a partir del nombre
int AnimatedSprite::getIndex(std::string name) int AnimatedSprite::getIndex(std::string name) {
{ int index = -1;
int index = -1;
for (auto a : animation) for (auto a : animation) {
{ index++;
index++; if (a.name == name) {
if (a.name == name) return index;
{ }
return index; }
}
}
std::cout << "** Warning: could not find \"" << name.c_str() << "\" animation" << std::endl; std::cout << "** Warning: could not find \"" << name.c_str() << "\" animation" << std::endl;
return -1; return -1;
} }
// Calcula el frame correspondiente a la animación // Calcula el frame correspondiente a la animación
void AnimatedSprite::animate() void AnimatedSprite::animate() {
{ if (!enabled || animation[currentAnimation].speed == 0) {
if (!enabled || animation[currentAnimation].speed == 0) return;
{ }
return;
}
// Calcula el frame actual a partir del contador // Calcula el frame actual a partir del contador
animation[currentAnimation].currentFrame = animation[currentAnimation].counter / animation[currentAnimation].speed; animation[currentAnimation].currentFrame = animation[currentAnimation].counter / animation[currentAnimation].speed;
// Si alcanza el final de la animación, reinicia el contador de la animación // Si alcanza el final de la animación, reinicia el contador de la animación
// en función de la variable loop y coloca el nuevo frame // en función de la variable loop y coloca el nuevo frame
if (animation[currentAnimation].currentFrame >= (int)animation[currentAnimation].frames.size()) if (animation[currentAnimation].currentFrame >= (int)animation[currentAnimation].frames.size()) {
{ if (animation[currentAnimation].loop == -1) { // Si no hay loop, deja el último frame
if (animation[currentAnimation].loop == -1) animation[currentAnimation].currentFrame = animation[currentAnimation].frames.size();
{ // Si no hay loop, deja el último frame animation[currentAnimation].completed = true;
animation[currentAnimation].currentFrame = animation[currentAnimation].frames.size(); } else { // Si hay loop, vuelve al frame indicado
animation[currentAnimation].completed = true; animation[currentAnimation].counter = 0;
} animation[currentAnimation].currentFrame = animation[currentAnimation].loop;
else }
{ // Si hay loop, vuelve al frame indicado }
animation[currentAnimation].counter = 0; // En caso contrario
animation[currentAnimation].currentFrame = animation[currentAnimation].loop; else {
} // Escoge el frame correspondiente de la animación
} setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
// En caso contrario
else
{
// Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
// Incrementa el contador de la animacion // Incrementa el contador de la animacion
animation[currentAnimation].counter++; animation[currentAnimation].counter++;
} }
} }
// Obtiene el numero de frames de la animación actual // Obtiene el numero de frames de la animación actual
int AnimatedSprite::getNumFrames() int AnimatedSprite::getNumFrames() {
{ return (int)animation[currentAnimation].frames.size();
return (int)animation[currentAnimation].frames.size();
} }
// Establece el frame actual de la animación // Establece el frame actual de la animación
void AnimatedSprite::setCurrentFrame(int num) void AnimatedSprite::setCurrentFrame(int num) {
{ // Descarta valores fuera de rango
// Descarta valores fuera de rango if (num >= (int)animation[currentAnimation].frames.size()) {
if (num >= (int)animation[currentAnimation].frames.size()) num = 0;
{ }
num = 0;
}
// Cambia el valor de la variable // Cambia el valor de la variable
animation[currentAnimation].currentFrame = num; animation[currentAnimation].currentFrame = num;
animation[currentAnimation].counter = 0; animation[currentAnimation].counter = 0;
// Escoge el frame correspondiente de la animación // Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]); setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
} }
// Establece el valor del contador // Establece el valor del contador
void AnimatedSprite::setAnimationCounter(std::string name, int num) void AnimatedSprite::setAnimationCounter(std::string name, int num) {
{ animation[getIndex(name)].counter = num;
animation[getIndex(name)].counter = num;
} }
// Establece la velocidad de una animación // Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(std::string name, int speed) void AnimatedSprite::setAnimationSpeed(std::string name, int speed) {
{ animation[getIndex(name)].counter = speed;
animation[getIndex(name)].counter = speed;
} }
// Establece la velocidad de una animación // Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(int index, int speed) void AnimatedSprite::setAnimationSpeed(int index, int speed) {
{ animation[index].counter = speed;
animation[index].counter = speed;
} }
// Establece si la animación se reproduce en bucle // Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(std::string name, int loop) void AnimatedSprite::setAnimationLoop(std::string name, int loop) {
{ animation[getIndex(name)].loop = loop;
animation[getIndex(name)].loop = loop;
} }
// Establece si la animación se reproduce en bucle // Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(int index, int loop) void AnimatedSprite::setAnimationLoop(int index, int loop) {
{ animation[index].loop = loop;
animation[index].loop = loop;
} }
// Establece el valor de la variable // Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(std::string name, bool value) void AnimatedSprite::setAnimationCompleted(std::string name, bool value) {
{ animation[getIndex(name)].completed = value;
animation[getIndex(name)].completed = value;
} }
// OLD - Establece el valor de la variable // OLD - Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(int index, bool value) void AnimatedSprite::setAnimationCompleted(int index, bool value) {
{ animation[index].completed = value;
animation[index].completed = value;
} }
// Comprueba si ha terminado la animación // Comprueba si ha terminado la animación
bool AnimatedSprite::animationIsCompleted() bool AnimatedSprite::animationIsCompleted() {
{ return animation[currentAnimation].completed;
return animation[currentAnimation].completed;
} }
// Devuelve el rectangulo de una animación y frame concreto // Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(std::string name, Uint8 index) SDL_Rect AnimatedSprite::getAnimationClip(std::string name, Uint8 index) {
{ return animation[getIndex(name)].frames[index];
return animation[getIndex(name)].frames[index];
} }
// Devuelve el rectangulo de una animación y frame concreto // Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(int indexA, Uint8 indexF) SDL_Rect AnimatedSprite::getAnimationClip(int indexA, Uint8 indexF) {
{ return animation[indexA].frames[indexF];
return animation[indexA].frames[indexF];
} }
// Carga la animación desde un vector // Carga la animación desde un vector
bool AnimatedSprite::loadFromVector(std::vector<std::string> *source) bool AnimatedSprite::loadFromVector(std::vector<std::string> *source) {
{ // Inicializa variables
// Inicializa variables int framesPerRow = 0;
int framesPerRow = 0; int frameWidth = 0;
int frameWidth = 0; int frameHeight = 0;
int frameHeight = 0; int maxTiles = 0;
int maxTiles = 0;
// Indicador de éxito en el proceso // Indicador de éxito en el proceso
bool success = true; bool success = true;
std::string line; std::string line;
// Recorre todo el vector // Recorre todo el vector
int index = 0; int index = 0;
while (index < (int)source->size()) while (index < (int)source->size()) {
{ // Lee desde el vector
// Lee desde el vector line = source->at(index);
line = source->at(index);
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación // Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]") if (line == "[animation]") {
{ animation_t buffer;
animation_t buffer; buffer.counter = 0;
buffer.counter = 0; buffer.currentFrame = 0;
buffer.currentFrame = 0; buffer.completed = false;
buffer.completed = false;
do do {
{ // Aumenta el indice para leer la siguiente linea
// Aumenta el indice para leer la siguiente linea index++;
index++; line = source->at(index);
line = source->at(index);
// Encuentra la posición del caracter '=' // Encuentra la posición del caracter '='
int pos = line.find("="); int pos = line.find("=");
// Procesa las dos subcadenas // Procesa las dos subcadenas
if (pos != (int)line.npos) if (pos != (int)line.npos) {
{ if (line.substr(0, pos) == "name") {
if (line.substr(0, pos) == "name") buffer.name = line.substr(pos + 1, line.length());
{ }
buffer.name = line.substr(pos + 1, line.length());
}
else if (line.substr(0, pos) == "speed") else if (line.substr(0, pos) == "speed") {
{ buffer.speed = std::stoi(line.substr(pos + 1, line.length()));
buffer.speed = std::stoi(line.substr(pos + 1, line.length())); }
}
else if (line.substr(0, pos) == "loop") else if (line.substr(0, pos) == "loop") {
{ buffer.loop = std::stoi(line.substr(pos + 1, line.length()));
buffer.loop = std::stoi(line.substr(pos + 1, line.length())); }
}
else if (line.substr(0, pos) == "frames") else if (line.substr(0, pos) == "frames") {
{ // Se introducen los valores separados por comas en un vector
// Se introducen los valores separados por comas en un vector std::stringstream ss(line.substr(pos + 1, line.length()));
std::stringstream ss(line.substr(pos + 1, line.length())); std::string tmp;
std::string tmp; SDL_Rect rect = {0, 0, frameWidth, frameHeight};
SDL_Rect rect = {0, 0, frameWidth, frameHeight}; while (getline(ss, tmp, ',')) {
while (getline(ss, tmp, ',')) // Comprueba que el tile no sea mayor que el maximo indice permitido
{ const int numTile = std::stoi(tmp) > maxTiles ? 0 : std::stoi(tmp);
// Comprueba que el tile no sea mayor que el maximo indice permitido rect.x = (numTile % framesPerRow) * frameWidth;
const int numTile = std::stoi(tmp) > maxTiles ? 0 : std::stoi(tmp); rect.y = (numTile / framesPerRow) * frameHeight;
rect.x = (numTile % framesPerRow) * frameWidth; buffer.frames.push_back(rect);
rect.y = (numTile / framesPerRow) * frameHeight; }
buffer.frames.push_back(rect); }
}
}
else else {
{ std::cout << "Warning: unknown parameter " << line.substr(0, pos).c_str() << std::endl;
std::cout << "Warning: unknown parameter " << line.substr(0, pos).c_str() << std::endl; success = false;
success = false; }
} }
} } while (line != "[/animation]");
} while (line != "[/animation]");
// Añade la animación al vector de animaciones // Añade la animación al vector de animaciones
animation.push_back(buffer); animation.push_back(buffer);
} }
// En caso contrario se parsea el fichero para buscar las variables y los valores // En caso contrario se parsea el fichero para buscar las variables y los valores
else else {
{ // Encuentra la posición del caracter '='
// Encuentra la posición del caracter '=' int pos = line.find("=");
int pos = line.find("=");
// Procesa las dos subcadenas // Procesa las dos subcadenas
if (pos != (int)line.npos) if (pos != (int)line.npos) {
{ if (line.substr(0, pos) == "framesPerRow") {
if (line.substr(0, pos) == "framesPerRow") framesPerRow = std::stoi(line.substr(pos + 1, line.length()));
{ }
framesPerRow = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frameWidth") else if (line.substr(0, pos) == "frameWidth") {
{ frameWidth = std::stoi(line.substr(pos + 1, line.length()));
frameWidth = std::stoi(line.substr(pos + 1, line.length())); }
}
else if (line.substr(0, pos) == "frameHeight") else if (line.substr(0, pos) == "frameHeight") {
{ frameHeight = std::stoi(line.substr(pos + 1, line.length()));
frameHeight = std::stoi(line.substr(pos + 1, line.length())); }
}
else else {
{ std::cout << "Warning: unknown parameter " << line.substr(0, pos).c_str() << std::endl;
std::cout << "Warning: unknown parameter " << line.substr(0, pos).c_str() << std::endl; success = false;
success = false; }
}
// Normaliza valores // Normaliza valores
if (framesPerRow == 0 && frameWidth > 0) if (framesPerRow == 0 && frameWidth > 0) {
{ framesPerRow = texture->getWidth() / frameWidth;
framesPerRow = texture->getWidth() / frameWidth; }
}
if (maxTiles == 0 && frameWidth > 0 && frameHeight > 0) if (maxTiles == 0 && frameWidth > 0 && frameHeight > 0) {
{ const int w = texture->getWidth() / frameWidth;
const int w = texture->getWidth() / frameWidth; const int h = texture->getHeight() / frameHeight;
const int h = texture->getHeight() / frameHeight; maxTiles = w * h;
maxTiles = w * h; }
} }
} }
}
// Una vez procesada la linea, aumenta el indice para pasar a la siguiente // Una vez procesada la linea, aumenta el indice para pasar a la siguiente
index++; index++;
} }
// Pone un valor por defecto // Pone un valor por defecto
setRect({0, 0, frameWidth, frameHeight}); setRect({0, 0, frameWidth, frameHeight});
return success; return success;
} }
// Establece la animacion actual // Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(std::string name) void AnimatedSprite::setCurrentAnimation(std::string name) {
{ const int newAnimation = getIndex(name);
const int newAnimation = getIndex(name); if (currentAnimation != newAnimation) {
if (currentAnimation != newAnimation) currentAnimation = newAnimation;
{ animation[currentAnimation].currentFrame = 0;
currentAnimation = newAnimation; animation[currentAnimation].counter = 0;
animation[currentAnimation].currentFrame = 0; animation[currentAnimation].completed = false;
animation[currentAnimation].counter = 0; }
animation[currentAnimation].completed = false;
}
} }
// Establece la animacion actual // Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(int index) void AnimatedSprite::setCurrentAnimation(int index) {
{ const int newAnimation = index;
const int newAnimation = index; if (currentAnimation != newAnimation) {
if (currentAnimation != newAnimation) currentAnimation = newAnimation;
{ animation[currentAnimation].currentFrame = 0;
currentAnimation = newAnimation; animation[currentAnimation].counter = 0;
animation[currentAnimation].currentFrame = 0; animation[currentAnimation].completed = false;
animation[currentAnimation].counter = 0; }
animation[currentAnimation].completed = false;
}
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
void AnimatedSprite::update() void AnimatedSprite::update() {
{ animate();
animate(); MovingSprite::update();
MovingSprite::update();
} }
// Establece el rectangulo para un frame de una animación // Establece el rectangulo para un frame de una animación
void AnimatedSprite::setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h) void AnimatedSprite::setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h) {
{ animation[index_animation].frames.push_back({x, y, w, h});
animation[index_animation].frames.push_back({x, y, w, h});
} }
// OLD - Establece el contador para todas las animaciones // OLD - Establece el contador para todas las animaciones
void AnimatedSprite::setAnimationCounter(int value) void AnimatedSprite::setAnimationCounter(int value) {
{ for (auto &a : animation) {
for (auto &a : animation) a.counter = value;
{ }
a.counter = value;
}
} }
// Reinicia la animación // Reinicia la animación
void AnimatedSprite::resetAnimation() void AnimatedSprite::resetAnimation() {
{ animation[currentAnimation].currentFrame = 0;
animation[currentAnimation].currentFrame = 0; animation[currentAnimation].counter = 0;
animation[currentAnimation].counter = 0; animation[currentAnimation].completed = false;
animation[currentAnimation].completed = false;
} }

View File

@@ -1,39 +1,38 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string, basic_string
#include <vector> // for vector #include <string> // for string, basic_string
#include "movingsprite.h" // for MovingSprite #include <vector> // for vector
#include "movingsprite.h" // for MovingSprite
class Texture; class Texture;
struct animation_t struct animation_t {
{ std::string name; // Nombre de la animacion
std::string name; // Nombre de la animacion std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación int speed; // Velocidad de la animación
int speed; // Velocidad de la animación int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva bool completed; // Indica si ha finalizado la animación
bool completed; // Indica si ha finalizado la animación int currentFrame; // Frame actual
int currentFrame; // Frame actual int counter; // Contador para las animaciones
int counter; // Contador para las animaciones
}; };
struct animatedSprite_t struct animatedSprite_t {
{ std::vector<animation_t> animations; // Vector con las diferentes animaciones
std::vector<animation_t> animations; // Vector con las diferentes animaciones Texture *texture; // Textura con los graficos para el sprite
Texture *texture; // Textura con los graficos para el sprite
}; };
// Carga la animación desde un fichero // Carga la animación desde un fichero
animatedSprite_t loadAnimationFromFile(Texture *texture, std::string filePath, bool verbose = false); animatedSprite_t loadAnimationFromFile(Texture *texture, std::string filePath, bool verbose = false);
class AnimatedSprite : public MovingSprite class AnimatedSprite : public MovingSprite {
{ private:
private:
// Variables // Variables
std::vector<animation_t> animation; // Vector con las diferentes animaciones std::vector<animation_t> animation; // Vector con las diferentes animaciones
int currentAnimation; // Animacion activa int currentAnimation; // Animacion activa
public: public:
// Constructor // Constructor
AnimatedSprite(Texture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "", std::vector<std::string> *buffer = nullptr); AnimatedSprite(Texture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "", std::vector<std::string> *buffer = nullptr);
AnimatedSprite(SDL_Renderer *renderer, animatedSprite_t *animation); AnimatedSprite(SDL_Renderer *renderer, animatedSprite_t *animation);

View File

@@ -1,19 +1,19 @@
#include "asset.h" #include "asset.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <stddef.h> // for size_t #include <stddef.h> // for size_t
#include <iostream> // for basic_ostream, operator<<, cout, endl
#include <iostream> // for basic_ostream, operator<<, cout, endl
// Constructor // Constructor
Asset::Asset(std::string executablePath) Asset::Asset(std::string executablePath) {
{
this->executablePath = executablePath.substr(0, executablePath.find_last_of("\\/")); this->executablePath = executablePath.substr(0, executablePath.find_last_of("\\/"));
longestName = 0; longestName = 0;
verbose = true; verbose = true;
} }
// Añade un elemento a la lista // Añade un elemento a la lista
void Asset::add(std::string file, enum assetType type, bool required, bool absolute) void Asset::add(std::string file, enum assetType type, bool required, bool absolute) {
{
item_t temp; item_t temp;
temp.file = absolute ? file : executablePath + file; temp.file = absolute ? file : executablePath + file;
temp.type = type; temp.type = type;
@@ -25,33 +25,27 @@ void Asset::add(std::string file, enum assetType type, bool required, bool absol
} }
// Devuelve el fichero de un elemento de la lista a partir de una cadena // Devuelve el fichero de un elemento de la lista a partir de una cadena
std::string Asset::get(std::string text) std::string Asset::get(std::string text) {
{ for (auto f : fileList) {
for (auto f : fileList)
{
const size_t lastIndex = f.file.find_last_of("/") + 1; const size_t lastIndex = f.file.find_last_of("/") + 1;
const std::string file = f.file.substr(lastIndex, std::string::npos); const std::string file = f.file.substr(lastIndex, std::string::npos);
if (file == text) if (file == text) {
{
return f.file; return f.file;
} }
} }
if (verbose) if (verbose) {
{
std::cout << "Warning: file " << text.c_str() << " not found" << std::endl; std::cout << "Warning: file " << text.c_str() << " not found" << std::endl;
} }
return ""; return "";
} }
// Comprueba que existen todos los elementos // Comprueba que existen todos los elementos
bool Asset::check() bool Asset::check() {
{
bool success = true; bool success = true;
if (verbose) if (verbose) {
{
std::cout << "\n** Checking files" << std::endl; std::cout << "\n** Checking files" << std::endl;
std::cout << "Executable path is: " << executablePath << std::endl; std::cout << "Executable path is: " << executablePath << std::endl;
@@ -59,31 +53,24 @@ bool Asset::check()
} }
// Comprueba la lista de ficheros clasificandolos por tipo // Comprueba la lista de ficheros clasificandolos por tipo
for (int type = 0; type < t_maxAssetType; ++type) for (int type = 0; type < t_maxAssetType; ++type) {
{
// Comprueba si hay ficheros de ese tipo // Comprueba si hay ficheros de ese tipo
bool any = false; bool any = false;
for (auto f : fileList) for (auto f : fileList) {
{ if ((f.required) && (f.type == type)) {
if ((f.required) && (f.type == type))
{
any = true; any = true;
} }
} }
// Si hay ficheros de ese tipo, comprueba si existen // Si hay ficheros de ese tipo, comprueba si existen
if (any) if (any) {
{ if (verbose) {
if (verbose)
{
std::cout << "\n>> " << getTypeName(type).c_str() << " FILES" << std::endl; std::cout << "\n>> " << getTypeName(type).c_str() << " FILES" << std::endl;
} }
for (auto f : fileList) for (auto f : fileList) {
{ if ((f.required) && (f.type == type)) {
if ((f.required) && (f.type == type))
{
success &= checkFile(f.file); success &= checkFile(f.file);
} }
} }
@@ -91,15 +78,11 @@ bool Asset::check()
} }
// Resultado // Resultado
if (verbose) if (verbose) {
{ if (success) {
if (success)
{
std::cout << "\n** All files OK.\n" std::cout << "\n** All files OK.\n"
<< std::endl; << std::endl;
} } else {
else
{
std::cout << "\n** A file is missing. Exiting.\n" std::cout << "\n** A file is missing. Exiting.\n"
<< std::endl; << std::endl;
} }
@@ -109,8 +92,7 @@ bool Asset::check()
} }
// Comprueba que existe un fichero // Comprueba que existe un fichero
bool Asset::checkFile(std::string path) bool Asset::checkFile(std::string path) {
{
bool success = false; bool success = false;
std::string result = "ERROR"; std::string result = "ERROR";
@@ -118,15 +100,13 @@ bool Asset::checkFile(std::string path)
const std::string filename = path.substr(path.find_last_of("\\/") + 1); const std::string filename = path.substr(path.find_last_of("\\/") + 1);
SDL_IOStream *file = SDL_IOFromFile(path.c_str(), "rb"); SDL_IOStream *file = SDL_IOFromFile(path.c_str(), "rb");
if (file != nullptr) if (file != nullptr) {
{
result = "OK"; result = "OK";
success = true; success = true;
SDL_CloseIO(file); SDL_CloseIO(file);
} }
if (verbose) if (verbose) {
{
std::cout.setf(std::ios::left, std::ios::adjustfield); std::cout.setf(std::ios::left, std::ios::adjustfield);
std::cout << "Checking file: "; std::cout << "Checking file: ";
std::cout.width(longestName + 2); std::cout.width(longestName + 2);
@@ -139,54 +119,51 @@ bool Asset::checkFile(std::string path)
} }
// Devuelve el nombre del tipo de recurso // Devuelve el nombre del tipo de recurso
std::string Asset::getTypeName(int type) std::string Asset::getTypeName(int type) {
{ switch (type) {
switch (type) case t_bitmap:
{ return "BITMAP";
case t_bitmap: break;
return "BITMAP";
break;
case t_music: case t_music:
return "MUSIC"; return "MUSIC";
break; break;
case t_sound: case t_sound:
return "SOUND"; return "SOUND";
break; break;
case t_font: case t_font:
return "FONT"; return "FONT";
break; break;
case t_lang: case t_lang:
return "LANG"; return "LANG";
break; break;
case t_data: case t_data:
return "DATA"; return "DATA";
break; break;
case t_room: case t_room:
return "ROOM"; return "ROOM";
break; break;
case t_enemy: case t_enemy:
return "ENEMY"; return "ENEMY";
break; break;
case t_item: case t_item:
return "ITEM"; return "ITEM";
break; break;
default: default:
return "ERROR"; return "ERROR";
break; break;
} }
} }
// Establece si ha de mostrar texto por pantalla // Establece si ha de mostrar texto por pantalla
void Asset::setVerbose(bool value) void Asset::setVerbose(bool value) {
{
verbose = value; verbose = value;
} }

View File

@@ -3,58 +3,55 @@
#include <string> // for string, basic_string #include <string> // for string, basic_string
#include <vector> // for vector #include <vector> // for vector
enum assetType enum assetType {
{ t_bitmap,
t_bitmap, t_music,
t_music, t_sound,
t_sound, t_font,
t_font, t_lang,
t_lang, t_data,
t_data, t_room,
t_room, t_enemy,
t_enemy, t_item,
t_item, t_maxAssetType
t_maxAssetType
}; };
// Clase Asset // Clase Asset
class Asset class Asset {
{ private:
private: // Estructura para definir un item
// Estructura para definir un item struct item_t {
struct item_t std::string file; // Ruta del fichero desde la raiz del directorio
{ enum assetType type; // Indica el tipo de recurso
std::string file; // Ruta del fichero desde la raiz del directorio bool required; // Indica si es un fichero que debe de existir
enum assetType type; // Indica el tipo de recurso // bool absolute; // Indica si la ruta que se ha proporcionado es una ruta absoluta
bool required; // Indica si es un fichero que debe de existir };
//bool absolute; // Indica si la ruta que se ha proporcionado es una ruta absoluta
};
// Variables // Variables
int longestName; // Contiene la longitud del nombre de fichero mas largo int longestName; // Contiene la longitud del nombre de fichero mas largo
std::vector<item_t> fileList; // Listado con todas las rutas a los ficheros std::vector<item_t> fileList; // Listado con todas las rutas a los ficheros
std::string executablePath; // Ruta al ejecutable std::string executablePath; // Ruta al ejecutable
bool verbose; // Indica si ha de mostrar información por pantalla bool verbose; // Indica si ha de mostrar información por pantalla
// Comprueba que existe un fichero // Comprueba que existe un fichero
bool checkFile(std::string executablePath); bool checkFile(std::string executablePath);
// Devuelve el nombre del tipo de recurso // Devuelve el nombre del tipo de recurso
std::string getTypeName(int type); std::string getTypeName(int type);
public: public:
// Constructor // Constructor
Asset(std::string path); Asset(std::string path);
// Añade un elemento a la lista // Añade un elemento a la lista
void add(std::string file, enum assetType type, bool required = true, bool absolute = false); void add(std::string file, enum assetType type, bool required = true, bool absolute = false);
// Devuelve un elemento de la lista a partir de una cadena // Devuelve un elemento de la lista a partir de una cadena
std::string get(std::string text); std::string get(std::string text);
// Comprueba que existen todos los elementos // Comprueba que existen todos los elementos
bool check(); bool check();
// Establece si ha de mostrar texto por pantalla // Establece si ha de mostrar texto por pantalla
void setVerbose(bool value); void setVerbose(bool value);
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,11 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string
#include <vector> // for vector #include <string> // for string
#include "utils.h" // for circle_t #include <vector> // for vector
#include "utils.h" // for circle_t
class AnimatedSprite; class AnimatedSprite;
class Texture; class Texture;
@@ -67,184 +69,182 @@ constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10;
constexpr int POWERBALL_COUNTER = 8; constexpr int POWERBALL_COUNTER = 8;
// Clase Balloon // Clase Balloon
class Balloon class Balloon {
{ private:
private: // Estructura para las variables para el efecto de los rebotes
// Estructura para las variables para el efecto de los rebotes struct bouncing {
struct bouncing bool enabled; // Si el efecto está activo
{ Uint8 counter; // Countador para el efecto
bool enabled; // Si el efecto está activo Uint8 speed; // Velocidad a la que transcurre el efecto
Uint8 counter; // Countador para el efecto float zoomW; // Zoom aplicado a la anchura
Uint8 speed; // Velocidad a la que transcurre el efecto float zoomH; // Zoom aplicado a la altura
float zoomW; // Zoom aplicado a la anchura float despX; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom
float zoomH; // Zoom aplicado a la altura float despY; // Desplazamiento de pixeles en el eje Y antes de pintar el objeto con zoom
float despX; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom std::vector<float> w; // Vector con los valores de zoom para el ancho del globo
float despY; // Desplazamiento de pixeles en el eje Y antes de pintar el objeto con zoom std::vector<float> h; // Vector con los valores de zoom para el alto del globo
std::vector<float> w; // Vector con los valores de zoom para el ancho del globo };
std::vector<float> h; // Vector con los valores de zoom para el alto del globo
};
// Objetos y punteros // Objetos y punteros
AnimatedSprite *sprite; // Sprite del objeto globo AnimatedSprite *sprite; // Sprite del objeto globo
// Variables // Variables
float posX; // Posición en el eje X float posX; // Posición en el eje X
float posY; // Posición en el eje Y float posY; // Posición en el eje Y
Uint8 width; // Ancho Uint8 width; // Ancho
Uint8 height; // Alto Uint8 height; // Alto
float velX; // Velocidad en el eje X. Cantidad de pixeles a desplazarse float velX; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
float velY; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse float velY; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
float gravity; // Aceleración en el eje Y. Modifica la velocidad float gravity; // Aceleración en el eje Y. Modifica la velocidad
float defaultVelY; // Velocidad inicial que tienen al rebotar contra el suelo float defaultVelY; // Velocidad inicial que tienen al rebotar contra el suelo
float maxVelY; // Máxima velocidad que puede alcanzar el objeto en el eje Y float maxVelY; // Máxima velocidad que puede alcanzar el objeto en el eje Y
bool beingCreated; // Indica si el globo se está creando bool beingCreated; // Indica si el globo se está creando
bool blinking; // Indica si el globo está intermitente bool blinking; // Indica si el globo está intermitente
bool enabled; // Indica si el globo esta activo bool enabled; // Indica si el globo esta activo
bool invulnerable; // Indica si el globo es invulnerable bool invulnerable; // Indica si el globo es invulnerable
bool popping; // Indica si el globo está explotando bool popping; // Indica si el globo está explotando
bool stopped; // Indica si el globo está parado bool stopped; // Indica si el globo está parado
bool visible; // Indica si el globo es visible bool visible; // Indica si el globo es visible
circle_t collider; // Circulo de colisión del objeto circle_t collider; // Circulo de colisión del objeto
Uint16 creationCounter; // Temporizador para controlar el estado "creandose" Uint16 creationCounter; // Temporizador para controlar el estado "creandose"
Uint16 creationCounterIni; // Valor inicial para el temporizador para controlar el estado "creandose" Uint16 creationCounterIni; // Valor inicial para el temporizador para controlar el estado "creandose"
Uint16 score; // Puntos que da el globo al ser destruido Uint16 score; // Puntos que da el globo al ser destruido
Uint16 stoppedCounter; // Contador para controlar el estado "parado" Uint16 stoppedCounter; // Contador para controlar el estado "parado"
Uint8 kind; // Tipo de globo Uint8 kind; // Tipo de globo
Uint8 menace; // Cantidad de amenaza que genera el globo Uint8 menace; // Cantidad de amenaza que genera el globo
Uint32 counter; // Contador interno Uint32 counter; // Contador interno
float travelY; // Distancia que ha de recorrer el globo en el eje Y antes de que se le aplique la gravedad float travelY; // Distancia que ha de recorrer el globo en el eje Y antes de que se le aplique la gravedad
float speed; // Velocidad a la que se mueven los globos float speed; // Velocidad a la que se mueven los globos
Uint8 size; // Tamaño del globo Uint8 size; // Tamaño del globo
Uint8 power; // Cantidad de poder que alberga el globo Uint8 power; // Cantidad de poder que alberga el globo
bouncing bouncing; // Contiene las variables para el efecto de rebote bouncing bouncing; // Contiene las variables para el efecto de rebote
// Alinea el circulo de colisión con la posición del objeto globo // Alinea el circulo de colisión con la posición del objeto globo
void updateColliders(); void updateColliders();
// Activa el efecto // Activa el efecto
void bounceStart(); void bounceStart();
// Detiene el efecto // Detiene el efecto
void bounceStop(); void bounceStop();
// Aplica el efecto // Aplica el efecto
void updateBounce(); void updateBounce();
// Actualiza los estados del globo // Actualiza los estados del globo
void updateState(); void updateState();
// Establece la animación correspondiente // Establece la animación correspondiente
void updateAnimation(); void updateAnimation();
// Establece el valor de la variable // Establece el valor de la variable
void setBeingCreated(bool value); void setBeingCreated(bool value);
public: public:
// Constructor // Constructor
Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 creationtimer, Texture *texture, std::vector<std::string> *animation, SDL_Renderer *renderer); Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 creationtimer, Texture *texture, std::vector<std::string> *animation, SDL_Renderer *renderer);
// Destructor // Destructor
~Balloon(); ~Balloon();
// Centra el globo en la posición X // Centra el globo en la posición X
void allignTo(int x); void allignTo(int x);
// Pinta el globo en la pantalla // Pinta el globo en la pantalla
void render(); void render();
// Actualiza la posición y estados del globo // Actualiza la posición y estados del globo
void move(); void move();
// Deshabilita el globo y pone a cero todos los valores // Deshabilita el globo y pone a cero todos los valores
void disable(); void disable();
// Explosiona el globo // Explosiona el globo
void pop(); void pop();
// Actualiza al globo a su posicion, animación y controla los contadores // Actualiza al globo a su posicion, animación y controla los contadores
void update(); void update();
// Comprueba si el globo está habilitado // Comprueba si el globo está habilitado
bool isEnabled(); bool isEnabled();
// Obtiene del valor de la variable // Obtiene del valor de la variable
float getPosX(); float getPosX();
// Obtiene del valor de la variable // Obtiene del valor de la variable
float getPosY(); float getPosY();
// Obtiene del valor de la variable // Obtiene del valor de la variable
float getVelY(); float getVelY();
// Obtiene del valor de la variable // Obtiene del valor de la variable
int getWidth(); int getWidth();
// Obtiene del valor de la variable // Obtiene del valor de la variable
int getHeight(); int getHeight();
// Establece el valor de la variable // Establece el valor de la variable
void setVelY(float velY); void setVelY(float velY);
// Establece el valor de la variable // Establece el valor de la variable
void setSpeed(float speed); void setSpeed(float speed);
// Obtiene del valor de la variable // Obtiene del valor de la variable
int getKind(); int getKind();
// Obtiene del valor de la variable // Obtiene del valor de la variable
Uint8 getSize(); Uint8 getSize();
// Obtiene la clase a la que pertenece el globo // Obtiene la clase a la que pertenece el globo
Uint8 getClass(); Uint8 getClass();
// Establece el valor de la variable // Establece el valor de la variable
void setStop(bool value); void setStop(bool value);
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool isStopped(); bool isStopped();
// Establece el valor de la variable // Establece el valor de la variable
void setBlink(bool value); void setBlink(bool value);
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool isBlinking(); bool isBlinking();
// Establece el valor de la variable // Establece el valor de la variable
void setVisible(bool value); void setVisible(bool value);
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool isVisible(); bool isVisible();
// Establece el valor de la variable // Establece el valor de la variable
void setInvulnerable(bool value); void setInvulnerable(bool value);
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool isInvulnerable(); bool isInvulnerable();
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool isBeingCreated(); bool isBeingCreated();
// Establece el valor de la variable // Establece el valor de la variable
void setPopping(bool value); void setPopping(bool value);
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool isPopping(); bool isPopping();
// Establece el valor de la variable // Establece el valor de la variable
void setStoppedTimer(Uint16 time); void setStoppedTimer(Uint16 time);
// Obtiene del valor de la variable // Obtiene del valor de la variable
Uint16 getStoppedTimer(); Uint16 getStoppedTimer();
// Obtiene del valor de la variable // Obtiene del valor de la variable
Uint16 getScore(); Uint16 getScore();
// Obtiene el circulo de colisión // Obtiene el circulo de colisión
circle_t &getCollider(); circle_t &getCollider();
// Obtiene le valor de la variable // Obtiene le valor de la variable
Uint8 getMenace(); Uint8 getMenace();
// Obtiene le valor de la variable // Obtiene le valor de la variable
Uint8 getPower(); Uint8 getPower();
}; };

View File

@@ -1,213 +1,184 @@
#include "bullet.h" #include "bullet.h"
#include "const.h" // for NO_KIND, PLAY_AREA_LEFT, PLAY_AREA_RIGHT, PLAY_A... #include "const.h" // for NO_KIND, PLAY_AREA_LEFT, PLAY_AREA_RIGHT, PLAY_A...
#include "sprite.h" // for Sprite #include "sprite.h" // for Sprite
class Texture; class Texture;
// Constructor // Constructor
Bullet::Bullet(int x, int y, int kind, bool poweredUp, int owner, Texture *texture, SDL_Renderer *renderer) Bullet::Bullet(int x, int y, int kind, bool poweredUp, int owner, Texture *texture, SDL_Renderer *renderer) {
{ sprite = new Sprite({x, y, 10, 10}, texture, renderer);
sprite = new Sprite({x, y, 10, 10}, texture, renderer);
// Posición inicial del objeto // Posición inicial del objeto
posX = x; posX = x;
posY = y; posY = y;
// Alto y ancho del objeto // Alto y ancho del objeto
width = 10; width = 10;
height = 10; height = 10;
// Velocidad inicial en el eje Y // Velocidad inicial en el eje Y
velY = -3; velY = -3;
// Tipo de bala // Tipo de bala
this->kind = kind; this->kind = kind;
// Identificador del dueño del objeto // Identificador del dueño del objeto
this->owner = owner; this->owner = owner;
// Valores especificos según el tipo // Valores especificos según el tipo
switch (kind) switch (kind) {
{ case BULLET_UP:
case BULLET_UP: // Establece la velocidad inicial
// Establece la velocidad inicial velX = 0;
velX = 0;
// Rectangulo con los gráficos del objeto // Rectangulo con los gráficos del objeto
if (!poweredUp) if (!poweredUp) {
{ sprite->setSpriteClip(0 * width, 0, sprite->getWidth(), sprite->getHeight());
sprite->setSpriteClip(0 * width, 0, sprite->getWidth(), sprite->getHeight()); } else {
} sprite->setSpriteClip((0 + 3) * width, 0, sprite->getWidth(), sprite->getHeight());
else }
{ break;
sprite->setSpriteClip((0 + 3) * width, 0, sprite->getWidth(), sprite->getHeight());
}
break;
case BULLET_LEFT: case BULLET_LEFT:
// Establece la velocidad inicial // Establece la velocidad inicial
velX = -2; velX = -2;
// Rectangulo con los gráficos del objeto // Rectangulo con los gráficos del objeto
if (!poweredUp) if (!poweredUp) {
{ sprite->setSpriteClip(1 * width, 0, sprite->getWidth(), sprite->getHeight());
sprite->setSpriteClip(1 * width, 0, sprite->getWidth(), sprite->getHeight()); } else {
} sprite->setSpriteClip((1 + 3) * width, 0, sprite->getWidth(), sprite->getHeight());
else }
{ break;
sprite->setSpriteClip((1 + 3) * width, 0, sprite->getWidth(), sprite->getHeight());
}
break;
case BULLET_RIGHT: case BULLET_RIGHT:
// Establece la velocidad inicial // Establece la velocidad inicial
velX = 2; velX = 2;
// Rectangulo con los gráficos del objeto // Rectangulo con los gráficos del objeto
if (!poweredUp) if (!poweredUp) {
{ sprite->setSpriteClip(2 * width, 0, sprite->getWidth(), sprite->getHeight());
sprite->setSpriteClip(2 * width, 0, sprite->getWidth(), sprite->getHeight()); } else {
} sprite->setSpriteClip((2 + 3) * width, 0, sprite->getWidth(), sprite->getHeight());
else }
{ break;
sprite->setSpriteClip((2 + 3) * width, 0, sprite->getWidth(), sprite->getHeight());
}
break;
default: default:
break; break;
} }
// Establece el tamaño del circulo de colisión // Establece el tamaño del circulo de colisión
collider.r = width / 2; collider.r = width / 2;
// Alinea el circulo de colisión con el objeto // Alinea el circulo de colisión con el objeto
shiftColliders(); shiftColliders();
} }
// Destructor // Destructor
Bullet::~Bullet() Bullet::~Bullet() {
{ delete sprite;
delete sprite;
} }
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void Bullet::render() void Bullet::render() {
{ sprite->render();
sprite->render();
} }
// Actualiza la posición y estado del objeto en horizontal // Actualiza la posición y estado del objeto en horizontal
Uint8 Bullet::move() Uint8 Bullet::move() {
{ // Variable con el valor de retorno
// Variable con el valor de retorno Uint8 msg = BULLET_MOVE_OK;
Uint8 msg = BULLET_MOVE_OK;
// Mueve el objeto a su nueva posición // Mueve el objeto a su nueva posición
posX += velX; posX += velX;
// Si el objeto se sale del area de juego por los laterales // Si el objeto se sale del area de juego por los laterales
if ((posX < PLAY_AREA_LEFT - width) || (posX > PLAY_AREA_RIGHT)) if ((posX < PLAY_AREA_LEFT - width) || (posX > PLAY_AREA_RIGHT)) {
{ // Se deshabilita
// Se deshabilita kind = NO_KIND;
kind = NO_KIND;
// Mensaje de salida // Mensaje de salida
msg = BULLET_MOVE_OUT; msg = BULLET_MOVE_OUT;
} }
// Mueve el objeto a su nueva posición en vertical // Mueve el objeto a su nueva posición en vertical
posY += int(velY); posY += int(velY);
// Si el objeto se sale del area de juego por la parte superior // Si el objeto se sale del area de juego por la parte superior
if (posY < PLAY_AREA_TOP - height) if (posY < PLAY_AREA_TOP - height) {
{ // Se deshabilita
// Se deshabilita kind = NO_KIND;
kind = NO_KIND;
// Mensaje de salida // Mensaje de salida
msg = BULLET_MOVE_OUT; msg = BULLET_MOVE_OUT;
} }
// Actualiza la posición del sprite // Actualiza la posición del sprite
sprite->setPosX(posX); sprite->setPosX(posX);
sprite->setPosY(posY); sprite->setPosY(posY);
// Alinea el circulo de colisión con el objeto // Alinea el circulo de colisión con el objeto
shiftColliders(); shiftColliders();
return msg; return msg;
} }
// Comprueba si el objeto está habilitado // Comprueba si el objeto está habilitado
bool Bullet::isEnabled() bool Bullet::isEnabled() {
{ if (kind == NO_KIND) {
if (kind == NO_KIND) return false;
{ } else {
return false; return true;
} }
else
{
return true;
}
} }
// Deshabilita el objeto // Deshabilita el objeto
void Bullet::disable() void Bullet::disable() {
{ kind = NO_KIND;
kind = NO_KIND;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Bullet::getPosX() int Bullet::getPosX() {
{ return posX;
return posX;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Bullet::getPosY() int Bullet::getPosY() {
{ return posY;
return posY;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Bullet::setPosX(int x) void Bullet::setPosX(int x) {
{ posX = x;
posX = x;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Bullet::setPosY(int y) void Bullet::setPosY(int y) {
{ posY = y;
posY = y;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Bullet::getVelY() int Bullet::getVelY() {
{ return velY;
return velY;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Bullet::getKind() int Bullet::getKind() {
{ return kind;
return kind;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Bullet::getOwner() int Bullet::getOwner() {
{ return owner;
return owner;
} }
// Obtiene el circulo de colisión // Obtiene el circulo de colisión
circle_t &Bullet::getCollider() circle_t &Bullet::getCollider() {
{ return collider;
return collider;
} }
// Alinea el circulo de colisión con el objeto // Alinea el circulo de colisión con el objeto
void Bullet::shiftColliders() void Bullet::shiftColliders() {
{ collider.x = posX + collider.r;
collider.x = posX + collider.r; collider.y = posY + collider.r;
collider.y = posY + collider.r;
} }

View File

@@ -1,7 +1,8 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include "utils.h" // for circle_t
#include "utils.h" // for circle_t
class Sprite; class Sprite;
class Texture; class Texture;
@@ -15,66 +16,65 @@ constexpr int BULLET_MOVE_OK = 0;
constexpr int BULLET_MOVE_OUT = 1; constexpr int BULLET_MOVE_OUT = 1;
// Clase Bullet // Clase Bullet
class Bullet class Bullet {
{ private:
private: // Objetos y punteros
// Objetos y punteros Sprite *sprite; // Sprite con los graficos y métodos de pintado
Sprite *sprite; // Sprite con los graficos y métodos de pintado
// Variables // Variables
int posX; // Posición en el eje X int posX; // Posición en el eje X
int posY; // Posición en el eje Y int posY; // Posición en el eje Y
Uint8 width; // Ancho del objeto Uint8 width; // Ancho del objeto
Uint8 height; // Alto del objeto Uint8 height; // Alto del objeto
int velX; // Velocidad en el eje X int velX; // Velocidad en el eje X
int velY; // Velocidad en el eje Y int velY; // Velocidad en el eje Y
int kind; // Tipo de objeto int kind; // Tipo de objeto
int owner; // Identificador del dueño del objeto int owner; // Identificador del dueño del objeto
circle_t collider; // Circulo de colisión del objeto circle_t collider; // Circulo de colisión del objeto
// Alinea el circulo de colisión con el objeto // Alinea el circulo de colisión con el objeto
void shiftColliders(); void shiftColliders();
public: public:
// Constructor // Constructor
Bullet(int x, int y, int kind, bool poweredUp, int owner, Texture *texture, SDL_Renderer *renderer); Bullet(int x, int y, int kind, bool poweredUp, int owner, Texture *texture, SDL_Renderer *renderer);
// Destructor // Destructor
~Bullet(); ~Bullet();
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void render(); void render();
// Actualiza la posición y estado del objeto // Actualiza la posición y estado del objeto
Uint8 move(); Uint8 move();
// Comprueba si el objeto está habilitado // Comprueba si el objeto está habilitado
bool isEnabled(); bool isEnabled();
// Deshabilita el objeto // Deshabilita el objeto
void disable(); void disable();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getPosX(); int getPosX();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getPosY(); int getPosY();
// Establece el valor de la variable // Establece el valor de la variable
void setPosX(int x); void setPosX(int x);
// Establece el valor de la variable // Establece el valor de la variable
void setPosY(int y); void setPosY(int y);
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getVelY(); int getVelY();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getKind(); int getKind();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getOwner(); int getOwner();
// Obtiene el circulo de colisión // Obtiene el circulo de colisión
circle_t &getCollider(); circle_t &getCollider();
}; };

View File

@@ -1,8 +1,9 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include "utils.h"
#include "lang.h" #include "lang.h"
#include "utils.h"
// Tamaño de bloque // Tamaño de bloque
constexpr int BLOCK = 8; constexpr int BLOCK = 8;

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string, basic_string
#include <string> // for string, basic_string
class Asset; class Asset;
class Game; class Game;
class Input; class Input;
@@ -14,74 +15,73 @@ struct options_t;
struct section_t; struct section_t;
// Textos // Textos
constexpr const char* WINDOW_CAPTION = "© 2020 Coffee Crisis — JailDesigner"; constexpr const char *WINDOW_CAPTION = "© 2020 Coffee Crisis — JailDesigner";
class Director class Director {
{ private:
private: // Objetos y punteros
// Objetos y punteros SDL_Window *window; // La ventana donde dibujamos
SDL_Window *window; // La ventana donde dibujamos SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Renderer *renderer; // El renderizador de la ventana Screen *screen; // Objeto encargado de dibujar en pantalla
Screen *screen; // Objeto encargado de dibujar en pantalla Input *input; // Objeto Input para gestionar las entradas
Input *input; // Objeto Input para gestionar las entradas Lang *lang; // Objeto para gestionar los textos en diferentes idiomas
Lang *lang; // Objeto para gestionar los textos en diferentes idiomas Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Asset *asset; // Objeto que gestiona todos los ficheros de recursos section_t *section; // Sección y subsección actual del programa;
section_t *section; // Sección y subsección actual del programa;
// Variables // Variables
struct options_t *options; // Variable con todas las opciones del programa struct options_t *options; // Variable con todas las opciones del programa
std::string executablePath; // Path del ejecutable std::string executablePath; // Path del ejecutable
std::string systemFolder; // Carpeta del sistema donde guardar datos std::string systemFolder; // Carpeta del sistema donde guardar datos
// Inicializa jail_audio // Inicializa jail_audio
void initJailAudio(); void initJailAudio();
// Arranca SDL y crea la ventana // Arranca SDL y crea la ventana
bool initSDL(); bool initSDL();
// Inicializa el objeto input // Inicializa el objeto input
void initInput(); void initInput();
// Inicializa las opciones del programa // Inicializa las opciones del programa
void initOptions(); void initOptions();
// Asigna variables a partir de dos cadenas // Asigna variables a partir de dos cadenas
bool setOptions(options_t *options, std::string var, std::string value); bool setOptions(options_t *options, std::string var, std::string value);
// Crea el indice de ficheros // Crea el indice de ficheros
bool setFileList(); bool setFileList();
// Carga el fichero de configuración // Carga el fichero de configuración
bool loadConfigFile(); bool loadConfigFile();
// Guarda el fichero de configuración // Guarda el fichero de configuración
bool saveConfigFile(); bool saveConfigFile();
// Comprueba los parametros del programa // Comprueba los parametros del programa
void checkProgramArguments(int argc, const char *argv[]); void checkProgramArguments(int argc, const char *argv[]);
// Crea la carpeta del sistema donde guardar datos // Crea la carpeta del sistema donde guardar datos
void createSystemFolder(const std::string &folder); void createSystemFolder(const std::string &folder);
// Ejecuta la seccion de juego con el logo // Ejecuta la seccion de juego con el logo
void runLogo(); void runLogo();
// Ejecuta la seccion de juego de la introducción // Ejecuta la seccion de juego de la introducción
void runIntro(); void runIntro();
// Ejecuta la seccion de juego con el titulo y los menus // Ejecuta la seccion de juego con el titulo y los menus
void runTitle(); void runTitle();
// Ejecuta la seccion de juego donde se juega // Ejecuta la seccion de juego donde se juega
void runGame(); void runGame();
public: public:
// Constructor // Constructor
Director(int argc, const char *argv[]); Director(int argc, const char *argv[]);
// Destructor // Destructor
~Director(); ~Director();
// Bucle principal // Bucle principal
int run(); int run();
}; };

View File

@@ -1,175 +1,158 @@
#include "fade.h" #include "fade.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <stdlib.h> // for rand #include <stdlib.h> // for rand
#include <iostream> // for char_traits, basic_ostream, operator<<
#include "const.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH #include <iostream> // for char_traits, basic_ostream, operator<<
#include "const.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH
// Constructor // Constructor
Fade::Fade(SDL_Renderer *renderer) Fade::Fade(SDL_Renderer *renderer) {
{ mRenderer = renderer;
mRenderer = renderer;
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (mBackbuffer != nullptr) if (mBackbuffer != nullptr) {
{ SDL_SetTextureScaleMode(mBackbuffer, SDL_SCALEMODE_NEAREST);
SDL_SetTextureScaleMode(mBackbuffer, SDL_SCALEMODE_NEAREST); }
} if (mBackbuffer == nullptr) {
if (mBackbuffer == nullptr) std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
{ }
std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
} }
// Destructor // Destructor
Fade::~Fade() Fade::~Fade() {
{ SDL_DestroyTexture(mBackbuffer);
SDL_DestroyTexture(mBackbuffer); mBackbuffer = nullptr;
mBackbuffer = nullptr;
} }
// Inicializa las variables // Inicializa las variables
void Fade::init(Uint8 r, Uint8 g, Uint8 b) void Fade::init(Uint8 r, Uint8 g, Uint8 b) {
{ mFadeType = FADE_CENTER;
mFadeType = FADE_CENTER; mEnabled = false;
mEnabled = false; mFinished = false;
mFinished = false; mCounter = 0;
mCounter = 0; mR = r;
mR = r; mG = g;
mG = g; mB = b;
mB = b;
} }
// Pinta una transición en pantalla // Pinta una transición en pantalla
void Fade::render() void Fade::render() {
{ if (mEnabled && !mFinished) {
if (mEnabled && !mFinished) switch (mFadeType) {
{ case FADE_FULLSCREEN: {
switch (mFadeType) SDL_FRect fRect1 = {0, 0, (float)GAMECANVAS_WIDTH, (float)GAMECANVAS_HEIGHT};
{
case FADE_FULLSCREEN:
{
SDL_FRect fRect1 = {0, 0, (float)GAMECANVAS_WIDTH, (float)GAMECANVAS_HEIGHT};
for (int i = 0; i < 256; i += 4) for (int i = 0; i < 256; i += 4) {
{ // Dibujamos sobre el renderizador
// Dibujamos sobre el renderizador SDL_SetRenderTarget(mRenderer, nullptr);
SDL_SetRenderTarget(mRenderer, nullptr);
// Copia el backbuffer con la imagen que había al renderizador // Copia el backbuffer con la imagen que había al renderizador
SDL_RenderTexture(mRenderer, mBackbuffer, nullptr, nullptr); SDL_RenderTexture(mRenderer, mBackbuffer, nullptr, nullptr);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, i); SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, i);
SDL_RenderFillRect(mRenderer, &fRect1); SDL_RenderFillRect(mRenderer, &fRect1);
// Vuelca el renderizador en pantalla // Vuelca el renderizador en pantalla
SDL_RenderPresent(mRenderer); SDL_RenderPresent(mRenderer);
} }
// Deja todos los buffers del mismo color // Deja todos los buffers del mismo color
SDL_SetRenderTarget(mRenderer, mBackbuffer); SDL_SetRenderTarget(mRenderer, mBackbuffer);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255); SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
SDL_RenderClear(mRenderer); SDL_RenderClear(mRenderer);
SDL_SetRenderTarget(mRenderer, nullptr); SDL_SetRenderTarget(mRenderer, nullptr);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255); SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
SDL_RenderClear(mRenderer); SDL_RenderClear(mRenderer);
break; break;
} }
case FADE_CENTER: case FADE_CENTER: {
{ SDL_FRect fR1 = {0, 0, (float)GAMECANVAS_WIDTH, 0};
SDL_FRect fR1 = {0, 0, (float)GAMECANVAS_WIDTH, 0}; SDL_FRect fR2 = {0, 0, (float)GAMECANVAS_WIDTH, 0};
SDL_FRect fR2 = {0, 0, (float)GAMECANVAS_WIDTH, 0};
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 64); SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 64);
for (int i = 0; i < mCounter; i++) for (int i = 0; i < mCounter; i++) {
{ fR1.h = fR2.h = (float)(i * 4);
fR1.h = fR2.h = (float)(i * 4); fR2.y = (float)(GAMECANVAS_HEIGHT - (i * 4));
fR2.y = (float)(GAMECANVAS_HEIGHT - (i * 4));
SDL_RenderFillRect(mRenderer, &fR1); SDL_RenderFillRect(mRenderer, &fR1);
SDL_RenderFillRect(mRenderer, &fR2); SDL_RenderFillRect(mRenderer, &fR2);
} }
if ((mCounter * 4) > GAMECANVAS_HEIGHT) if ((mCounter * 4) > GAMECANVAS_HEIGHT)
mFinished = true; mFinished = true;
break; break;
} }
case FADE_RANDOM_SQUARE: case FADE_RANDOM_SQUARE: {
{ SDL_FRect fRs = {0, 0, 32, 32};
SDL_FRect fRs = {0, 0, 32, 32};
for (Uint16 i = 0; i < 50; i++) for (Uint16 i = 0; i < 50; i++) {
{ // Crea un color al azar
// Crea un color al azar mR = 255 * (rand() % 2);
mR = 255 * (rand() % 2); mG = 255 * (rand() % 2);
mG = 255 * (rand() % 2); mB = 255 * (rand() % 2);
mB = 255 * (rand() % 2); SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 64);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 64);
// Dibujamos sobre el backbuffer // Dibujamos sobre el backbuffer
SDL_SetRenderTarget(mRenderer, mBackbuffer); SDL_SetRenderTarget(mRenderer, mBackbuffer);
fRs.x = (float)(rand() % (GAMECANVAS_WIDTH - 32)); fRs.x = (float)(rand() % (GAMECANVAS_WIDTH - 32));
fRs.y = (float)(rand() % (GAMECANVAS_HEIGHT - 32)); fRs.y = (float)(rand() % (GAMECANVAS_HEIGHT - 32));
SDL_RenderFillRect(mRenderer, &fRs); SDL_RenderFillRect(mRenderer, &fRs);
// Volvemos a usar el renderizador de forma normal // Volvemos a usar el renderizador de forma normal
SDL_SetRenderTarget(mRenderer, nullptr); SDL_SetRenderTarget(mRenderer, nullptr);
// Copiamos el backbuffer al renderizador // Copiamos el backbuffer al renderizador
SDL_RenderTexture(mRenderer, mBackbuffer, nullptr, nullptr); SDL_RenderTexture(mRenderer, mBackbuffer, nullptr, nullptr);
// Volcamos el renderizador en pantalla // Volcamos el renderizador en pantalla
SDL_RenderPresent(mRenderer); SDL_RenderPresent(mRenderer);
SDL_Delay(100); SDL_Delay(100);
} }
break; break;
} }
default: default:
break; break;
} }
} }
if (mFinished) if (mFinished) {
{ SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255); SDL_RenderClear(mRenderer);
SDL_RenderClear(mRenderer); }
}
} }
// Actualiza las variables internas // Actualiza las variables internas
void Fade::update() void Fade::update() {
{ if (mEnabled)
if (mEnabled) mCounter++;
mCounter++;
} }
// Activa el fade // Activa el fade
void Fade::activateFade() void Fade::activateFade() {
{ mEnabled = true;
mEnabled = true; mFinished = false;
mFinished = false; mCounter = 0;
mCounter = 0;
} }
// Comprueba si está activo // Comprueba si está activo
bool Fade::isEnabled() bool Fade::isEnabled() {
{ return mEnabled;
return mEnabled;
} }
// Comprueba si ha terminado la transicion // Comprueba si ha terminado la transicion
bool Fade::hasEnded() bool Fade::hasEnded() {
{ return mFinished;
return mFinished;
} }
// Establece el tipo de fade // Establece el tipo de fade
void Fade::setFadeType(Uint8 fadeType) void Fade::setFadeType(Uint8 fadeType) {
{ mFadeType = fadeType;
mFadeType = fadeType;
} }

View File

@@ -8,44 +8,43 @@ constexpr int FADE_CENTER = 1;
constexpr int FADE_RANDOM_SQUARE = 2; constexpr int FADE_RANDOM_SQUARE = 2;
// Clase Fade // Clase Fade
class Fade class Fade {
{ private:
private: SDL_Renderer *mRenderer; // El renderizador de la ventana
SDL_Renderer *mRenderer; // El renderizador de la ventana SDL_Texture *mBackbuffer; // Textura para usar como backbuffer
SDL_Texture *mBackbuffer; // Textura para usar como backbuffer Uint8 mFadeType; // Tipo de fade a realizar
Uint8 mFadeType; // Tipo de fade a realizar Uint16 mCounter; // Contador interno
Uint16 mCounter; // Contador interno bool mEnabled; // Indica si el fade está activo
bool mEnabled; // Indica si el fade está activo bool mFinished; // Indica si ha terminado la transición
bool mFinished; // Indica si ha terminado la transición Uint8 mR, mG, mB; // Colores para el fade
Uint8 mR, mG, mB; // Colores para el fade SDL_Rect mRect1; // Rectangulo usado para crear los efectos de transición
SDL_Rect mRect1; // Rectangulo usado para crear los efectos de transición SDL_Rect mRect2; // Rectangulo usado para crear los efectos de transición
SDL_Rect mRect2; // Rectangulo usado para crear los efectos de transición
public: public:
// Constructor // Constructor
Fade(SDL_Renderer *renderer); Fade(SDL_Renderer *renderer);
// Destructor // Destructor
~Fade(); ~Fade();
// Inicializa las variables // Inicializa las variables
void init(Uint8 r, Uint8 g, Uint8 b); void init(Uint8 r, Uint8 g, Uint8 b);
// Pinta una transición en pantalla // Pinta una transición en pantalla
void render(); void render();
// Actualiza las variables internas // Actualiza las variables internas
void update(); void update();
// Activa el fade // Activa el fade
void activateFade(); void activateFade();
// Comprueba si ha terminado la transicion // Comprueba si ha terminado la transicion
bool hasEnded(); bool hasEnded();
// Comprueba si está activo // Comprueba si está activo
bool isEnabled(); bool isEnabled();
// Establece el tipo de fade // Establece el tipo de fade
void setFadeType(Uint8 fadeType); void setFadeType(Uint8 fadeType);
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,11 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string, basic_string
#include <vector> // for vector #include <string> // for string, basic_string
#include "utils.h" // for demoKeys_t, color_t #include <vector> // for vector
#include "utils.h" // for demoKeys_t, color_t
class Asset; class Asset;
class Balloon; class Balloon;
class Bullet; class Bullet;
@@ -50,477 +52,471 @@ constexpr int ITEM_COFFEE_MACHINE_ODDS = 4;
constexpr int TIME_STOPPED_COUNTER = 300; constexpr int TIME_STOPPED_COUNTER = 300;
// Clase Game // Clase Game
class Game class Game {
{ private:
private: struct enemyInits_t {
struct enemyInits_t int x; // Posición en el eje X donde crear al enemigo
{ int y; // Posición en el eje Y donde crear al enemigo
int x; // Posición en el eje X donde crear al enemigo float velX; // Velocidad inicial en el eje X
int y; // Posición en el eje Y donde crear al enemigo Uint8 kind; // Tipo de enemigo
float velX; // Velocidad inicial en el eje X Uint16 creationCounter; // Temporizador para la creación del enemigo
Uint8 kind; // Tipo de enemigo };
Uint16 creationCounter; // Temporizador para la creación del enemigo
};
struct enemyFormation_t // Contiene la información de una formación enemiga struct enemyFormation_t // Contiene la información de una formación enemiga
{ {
Uint8 numberOfEnemies; // Cantidad de enemigos que forman la formación Uint8 numberOfEnemies; // Cantidad de enemigos que forman la formación
enemyInits_t init[MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION]; // Vector con todas las inicializaciones de los enemigos de la formación enemyInits_t init[MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION]; // Vector con todas las inicializaciones de los enemigos de la formación
}; };
struct enemyPool_t struct enemyPool_t {
{ enemyFormation_t *set[10]; // Conjunto de formaciones enemigas
enemyFormation_t *set[10]; // Conjunto de formaciones enemigas };
};
struct stage_t // Contiene todas las variables relacionadas con una fase struct stage_t // Contiene todas las variables relacionadas con una fase
{ {
enemyPool_t *enemyPool; // El conjunto de formaciones enemigas de la fase enemyPool_t *enemyPool; // El conjunto de formaciones enemigas de la fase
Uint16 currentPower; // Cantidad actual de poder Uint16 currentPower; // Cantidad actual de poder
Uint16 powerToComplete; // Cantidad de poder que se necesita para completar la fase Uint16 powerToComplete; // Cantidad de poder que se necesita para completar la fase
Uint8 maxMenace; // Umbral máximo de amenaza de la fase Uint8 maxMenace; // Umbral máximo de amenaza de la fase
Uint8 minMenace; // Umbral mínimo de amenaza de la fase Uint8 minMenace; // Umbral mínimo de amenaza de la fase
Uint8 number; // Numero de fase Uint8 number; // Numero de fase
}; };
struct effect_t struct effect_t {
{ bool flash; // Indica si se ha de pintar la pantalla de blanco
bool flash; // Indica si se ha de pintar la pantalla de blanco bool shake; // Indica si se ha de agitar la pantalla
bool shake; // Indica si se ha de agitar la pantalla Uint8 shakeCounter; // Contador para medir el tiempo que dura el efecto
Uint8 shakeCounter; // Contador para medir el tiempo que dura el efecto };
};
struct helper_t struct helper_t {
{ bool needCoffee; // Indica si se necesitan cafes
bool needCoffee; // Indica si se necesitan cafes bool needCoffeeMachine; // Indica si se necesita PowerUp
bool needCoffeeMachine; // Indica si se necesita PowerUp bool needPowerBall; // Indica si se necesita una PowerBall
bool needPowerBall; // Indica si se necesita una PowerBall int counter; // Contador para no dar ayudas consecutivas
int counter; // Contador para no dar ayudas consecutivas int itemPoints1Odds; // Probabilidad de aparición del objeto
int itemPoints1Odds; // Probabilidad de aparición del objeto int itemPoints2Odds; // Probabilidad de aparición del objeto
int itemPoints2Odds; // Probabilidad de aparición del objeto int itemPoints3Odds; // Probabilidad de aparición del objeto
int itemPoints3Odds; // Probabilidad de aparición del objeto int itemClockOdds; // Probabilidad de aparición del objeto
int itemClockOdds; // Probabilidad de aparición del objeto int itemCoffeeOdds; // Probabilidad de aparición del objeto
int itemCoffeeOdds; // Probabilidad de aparición del objeto int itemCoffeeMachineOdds; // Probabilidad de aparición del objeto
int itemCoffeeMachineOdds; // Probabilidad de aparición del objeto };
};
struct demo_t struct demo_t {
{ bool enabled; // Indica si está activo el modo demo
bool enabled; // Indica si está activo el modo demo bool recording; // Indica si está activado el modo para grabar la demo
bool recording; // Indica si está activado el modo para grabar la demo Uint16 counter; // Contador para el modo demo
Uint16 counter; // Contador para el modo demo demoKeys_t keys; // Variable con las pulsaciones de teclas del modo demo
demoKeys_t keys; // Variable con las pulsaciones de teclas del modo demo demoKeys_t dataFile[TOTAL_DEMO_DATA]; // Datos del fichero con los movimientos para la demo
demoKeys_t dataFile[TOTAL_DEMO_DATA]; // Datos del fichero con los movimientos para la demo };
};
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla Screen *screen; // Objeto encargado de dibujar en pantalla
Asset *asset; // Objeto que gestiona todos los ficheros de recursos Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Lang *lang; // Objeto para gestionar los textos en diferentes idiomas Lang *lang; // Objeto para gestionar los textos en diferentes idiomas
Input *input; // Manejador de entrada Input *input; // Manejador de entrada
section_t *section; // Seccion actual dentro del juego section_t *section; // Seccion actual dentro del juego
std::vector<Player *> players; // Vector con los jugadores std::vector<Player *> players; // Vector con los jugadores
std::vector<Balloon *> balloons; // Vector con los globos std::vector<Balloon *> balloons; // Vector con los globos
std::vector<Bullet *> bullets; // Vector con las balas std::vector<Bullet *> bullets; // Vector con las balas
std::vector<Item *> items; // Vector con los items std::vector<Item *> items; // Vector con los items
std::vector<SmartSprite *> smartSprites; // Vector con los smartsprites std::vector<SmartSprite *> smartSprites; // Vector con los smartsprites
Texture *bulletTexture; // Textura para las balas Texture *bulletTexture; // Textura para las balas
std::vector<Texture *> itemTextures; // Vector con las texturas de los items std::vector<Texture *> itemTextures; // Vector con las texturas de los items
std::vector<Texture *> balloonTextures; // Vector con las texturas de los globos std::vector<Texture *> balloonTextures; // Vector con las texturas de los globos
std::vector<Texture *> player1Textures; // Vector con las texturas del jugador std::vector<Texture *> player1Textures; // Vector con las texturas del jugador
std::vector<Texture *> player2Textures; // Vector con las texturas del jugador std::vector<Texture *> player2Textures; // Vector con las texturas del jugador
std::vector<std::vector<Texture *>> playerTextures; // Vector con todas las texturas de los jugadores; std::vector<std::vector<Texture *>> playerTextures; // Vector con todas las texturas de los jugadores;
Texture *gameBuildingsTexture; // Textura con los edificios de fondo Texture *gameBuildingsTexture; // Textura con los edificios de fondo
Texture *gameCloudsTexture; // Textura con las nubes de fondo Texture *gameCloudsTexture; // Textura con las nubes de fondo
Texture *gameGrassTexture; // Textura con la hierba del suelo Texture *gameGrassTexture; // Textura con la hierba del suelo
Texture *gamePowerMeterTexture; // Textura con el marcador de poder de la fase Texture *gamePowerMeterTexture; // Textura con el marcador de poder de la fase
Texture *gameSkyColorsTexture; // Textura con los diferentes colores de fondo del juego Texture *gameSkyColorsTexture; // Textura con los diferentes colores de fondo del juego
Texture *gameTextTexture; // Textura para los sprites con textos Texture *gameTextTexture; // Textura para los sprites con textos
Texture *gameOverTexture; // Textura para la pantalla de game over Texture *gameOverTexture; // Textura para la pantalla de game over
Texture *gameOverEndTexture; // Textura para la pantalla de game over de acabar el juego Texture *gameOverEndTexture; // Textura para la pantalla de game over de acabar el juego
std::vector<std::vector<std::string> *> itemAnimations; // Vector con las animaciones de los items std::vector<std::vector<std::string> *> itemAnimations; // Vector con las animaciones de los items
std::vector<std::vector<std::string> *> playerAnimations; // Vector con las animaciones del jugador std::vector<std::vector<std::string> *> playerAnimations; // Vector con las animaciones del jugador
std::vector<std::vector<std::string> *> balloonAnimations; // Vector con las animaciones de los globos std::vector<std::vector<std::string> *> balloonAnimations; // Vector con las animaciones de los globos
Text *text; // Fuente para los textos del juego Text *text; // Fuente para los textos del juego
Text *textBig; // Fuente de texto grande Text *textBig; // Fuente de texto grande
Text *textScoreBoard; // Fuente para el marcador del juego Text *textScoreBoard; // Fuente para el marcador del juego
Text *textNokia2; // Otra fuente de texto para mensajes Text *textNokia2; // Otra fuente de texto para mensajes
Text *textNokiaBig2; // Y la versión en grande Text *textNokiaBig2; // Y la versión en grande
Menu *gameOverMenu; // Menú de la pantalla de game over Menu *gameOverMenu; // Menú de la pantalla de game over
Menu *pauseMenu; // Menú de la pantalla de pausa Menu *pauseMenu; // Menú de la pantalla de pausa
Fade *fade; // Objeto para renderizar fades Fade *fade; // Objeto para renderizar fades
SDL_Event *eventHandler; // Manejador de eventos SDL_Event *eventHandler; // Manejador de eventos
MovingSprite *clouds1A; // Sprite para las nubes superiores MovingSprite *clouds1A; // Sprite para las nubes superiores
MovingSprite *clouds1B; // Sprite para las nubes superiores MovingSprite *clouds1B; // Sprite para las nubes superiores
MovingSprite *clouds2A; // Sprite para las nubes inferiores MovingSprite *clouds2A; // Sprite para las nubes inferiores
MovingSprite *clouds2B; // Sprite para las nubes inferiores MovingSprite *clouds2B; // Sprite para las nubes inferiores
SmartSprite *n1000Sprite; // Sprite con el texto 1.000 SmartSprite *n1000Sprite; // Sprite con el texto 1.000
SmartSprite *n2500Sprite; // Sprite con el texto 2.500 SmartSprite *n2500Sprite; // Sprite con el texto 2.500
SmartSprite *n5000Sprite; // Sprite con el texto 5.000 SmartSprite *n5000Sprite; // Sprite con el texto 5.000
Sprite *buildingsSprite; // Sprite con los edificios de fondo Sprite *buildingsSprite; // Sprite con los edificios de fondo
Sprite *skyColorsSprite; // Sprite con los graficos del degradado de color de fondo Sprite *skyColorsSprite; // Sprite con los graficos del degradado de color de fondo
Sprite *grassSprite; // Sprite para la hierba Sprite *grassSprite; // Sprite para la hierba
Sprite *powerMeterSprite; // Sprite para el medidor de poder de la fase Sprite *powerMeterSprite; // Sprite para el medidor de poder de la fase
Sprite *gameOverSprite; // Sprite para dibujar los graficos del game over Sprite *gameOverSprite; // Sprite para dibujar los graficos del game over
Sprite *gameOverEndSprite; // Sprite para dibujar los graficos del game over de acabar el juego Sprite *gameOverEndSprite; // Sprite para dibujar los graficos del game over de acabar el juego
JA_Sound_t *balloonSound; // Sonido para la explosión del globo JA_Sound_t *balloonSound; // Sonido para la explosión del globo
JA_Sound_t *bulletSound; // Sonido para los disparos JA_Sound_t *bulletSound; // Sonido para los disparos
JA_Sound_t *playerCollisionSound; // Sonido para la colisión del jugador con un enemigo JA_Sound_t *playerCollisionSound; // Sonido para la colisión del jugador con un enemigo
JA_Sound_t *hiScoreSound; // Sonido para cuando se alcanza la máxima puntuación JA_Sound_t *hiScoreSound; // Sonido para cuando se alcanza la máxima puntuación
JA_Sound_t *itemDropSound; // Sonido para cuando se genera un item JA_Sound_t *itemDropSound; // Sonido para cuando se genera un item
JA_Sound_t *itemPickUpSound; // Sonido para cuando se recoge un item JA_Sound_t *itemPickUpSound; // Sonido para cuando se recoge un item
JA_Sound_t *coffeeOutSound; // Sonido para cuando el jugador pierde el café al recibir un impacto JA_Sound_t *coffeeOutSound; // Sonido para cuando el jugador pierde el café al recibir un impacto
JA_Sound_t *stageChangeSound; // Sonido para cuando se cambia de fase JA_Sound_t *stageChangeSound; // Sonido para cuando se cambia de fase
JA_Sound_t *bubble1Sound; // Sonido para cuando el jugador muere JA_Sound_t *bubble1Sound; // Sonido para cuando el jugador muere
JA_Sound_t *bubble2Sound; // Sonido para cuando el jugador muere JA_Sound_t *bubble2Sound; // Sonido para cuando el jugador muere
JA_Sound_t *bubble3Sound; // Sonido para cuando el jugador muere JA_Sound_t *bubble3Sound; // Sonido para cuando el jugador muere
JA_Sound_t *bubble4Sound; // Sonido para cuando el jugador muere JA_Sound_t *bubble4Sound; // Sonido para cuando el jugador muere
JA_Sound_t *clockSound; // Sonido para cuando se detiene el tiempo con el item reloj JA_Sound_t *clockSound; // Sonido para cuando se detiene el tiempo con el item reloj
JA_Sound_t *powerBallSound; // Sonido para cuando se explota una Power Ball JA_Sound_t *powerBallSound; // Sonido para cuando se explota una Power Ball
JA_Sound_t *coffeeMachineSound; // Sonido para cuando la máquina de café toca el suelo JA_Sound_t *coffeeMachineSound; // Sonido para cuando la máquina de café toca el suelo
JA_Music_t *gameMusic; // Musica de fondo JA_Music_t *gameMusic; // Musica de fondo
// Variables // Variables
int numPlayers; // Numero de jugadores int numPlayers; // Numero de jugadores
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint8 ticksSpeed; // Velocidad a la que se repiten los bucles del programa Uint8 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
Uint32 hiScore; // Puntuación máxima Uint32 hiScore; // Puntuación máxima
bool hiScoreAchieved; // Indica si se ha superado la puntuación máxima bool hiScoreAchieved; // Indica si se ha superado la puntuación máxima
std::string hiScoreName; // Nombre del jugador que ostenta la máxima puntuación std::string hiScoreName; // Nombre del jugador que ostenta la máxima puntuación
stage_t stage[10]; // Variable con los datos de cada pantalla stage_t stage[10]; // Variable con los datos de cada pantalla
Uint8 currentStage; // Indica la fase actual Uint8 currentStage; // Indica la fase actual
Uint8 stageBitmapCounter; // Contador para el tiempo visible del texto de Stage Uint8 stageBitmapCounter; // Contador para el tiempo visible del texto de Stage
float stageBitmapPath[STAGE_COUNTER]; // Vector con los puntos Y por donde se desplaza el texto float stageBitmapPath[STAGE_COUNTER]; // Vector con los puntos Y por donde se desplaza el texto
float getReadyBitmapPath[STAGE_COUNTER]; // Vector con los puntos X por donde se desplaza el texto float getReadyBitmapPath[STAGE_COUNTER]; // Vector con los puntos X por donde se desplaza el texto
Uint16 deathCounter; // Contador para la animación de muerte del jugador Uint16 deathCounter; // Contador para la animación de muerte del jugador
Uint8 menaceCurrent; // Nivel de amenaza actual Uint8 menaceCurrent; // Nivel de amenaza actual
Uint8 menaceThreshold; // 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 numero de globos Uint8 menaceThreshold; // 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 numero de globos
bool timeStopped; // Indica si el tiempo está detenido bool timeStopped; // Indica si el tiempo está detenido
Uint16 timeStoppedCounter; // Temporizador para llevar la cuenta del tiempo detenido Uint16 timeStoppedCounter; // Temporizador para llevar la cuenta del tiempo detenido
Uint32 counter; // Contador para el juego Uint32 counter; // Contador para el juego
Uint32 scoreDataFile[TOTAL_SCORE_DATA]; // Datos del fichero de puntos Uint32 scoreDataFile[TOTAL_SCORE_DATA]; // Datos del fichero de puntos
SDL_Rect skyColorsRect[4]; // Vector con las coordenadas de los 4 colores de cielo SDL_Rect skyColorsRect[4]; // Vector con las coordenadas de los 4 colores de cielo
Uint16 balloonsPopped; // Lleva la cuenta de los globos explotados Uint16 balloonsPopped; // Lleva la cuenta de los globos explotados
Uint8 lastEnemyDeploy; // Guarda cual ha sido la última formación desplegada para no repetir; Uint8 lastEnemyDeploy; // Guarda cual ha sido la última formación desplegada para no repetir;
int enemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero int enemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero
float enemySpeed; // Velocidad a la que se mueven los enemigos float enemySpeed; // Velocidad a la que se mueven los enemigos
float defaultEnemySpeed; // Velocidad base de los enemigos, sin incrementar float defaultEnemySpeed; // Velocidad base de los enemigos, sin incrementar
effect_t effect; // Variable para gestionar los efectos visuales effect_t effect; // Variable para gestionar los efectos visuales
helper_t helper; // Variable para gestionar las ayudas helper_t helper; // Variable para gestionar las ayudas
bool powerBallEnabled; // Indica si hay una powerball ya activa bool powerBallEnabled; // Indica si hay una powerball ya activa
Uint8 powerBallCounter; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra Uint8 powerBallCounter; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra
bool coffeeMachineEnabled; // Indica si hay una máquina de café en el terreno de juego bool coffeeMachineEnabled; // Indica si hay una máquina de café en el terreno de juego
bool gameCompleted; // Indica si se ha completado la partida, llegando al final de la ultima pantalla bool gameCompleted; // Indica si se ha completado la partida, llegando al final de la ultima pantalla
int gameCompletedCounter; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más enemigos int gameCompletedCounter; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más enemigos
Uint8 difficulty; // Dificultad del juego Uint8 difficulty; // Dificultad del juego
float difficultyScoreMultiplier; // Multiplicador de puntos en función de la dificultad float difficultyScoreMultiplier; // Multiplicador de puntos en función de la dificultad
color_t difficultyColor; // Color asociado a la dificultad color_t difficultyColor; // Color asociado a la dificultad
struct options_t *options; // Variable con todas las variables de las opciones del programa struct options_t *options; // Variable con todas las variables de las opciones del programa
Uint8 onePlayerControl; // Variable para almacenar el valor de las opciones Uint8 onePlayerControl; // Variable para almacenar el valor de las opciones
enemyFormation_t enemyFormation[NUMBER_OF_ENEMY_FORMATIONS]; // Vector con todas las formaciones enemigas enemyFormation_t enemyFormation[NUMBER_OF_ENEMY_FORMATIONS]; // Vector con todas las formaciones enemigas
enemyPool_t enemyPool[10]; // Variable con los diferentes conjuntos de formaciones enemigas enemyPool_t enemyPool[10]; // Variable con los diferentes conjuntos de formaciones enemigas
Uint8 lastStageReached; // Contiene el numero de la última pantalla que se ha alcanzado Uint8 lastStageReached; // Contiene el numero de la última pantalla que se ha alcanzado
demo_t demo; // Variable con todas las variables relacionadas con el modo demo demo_t demo; // Variable con todas las variables relacionadas con el modo demo
int totalPowerToCompleteGame; // La suma del poder necesario para completar todas las fases int totalPowerToCompleteGame; // La suma del poder necesario para completar todas las fases
int cloudsSpeed; // Velocidad a la que se desplazan las nubes int cloudsSpeed; // Velocidad a la que se desplazan las nubes
int pauseCounter; // Contador para salir del menu de pausa y volver al juego int pauseCounter; // Contador para salir del menu de pausa y volver al juego
bool leavingPauseMenu; // Indica si esta saliendo del menu de pausa para volver al juego bool leavingPauseMenu; // Indica si esta saliendo del menu de pausa para volver al juego
#ifdef PAUSE #ifdef PAUSE
bool pause; bool pause;
#endif #endif
// Actualiza el juego // Actualiza el juego
void update(); void update();
// Dibuja el juego // Dibuja el juego
void render(); void render();
// Comprueba los eventos que hay en cola // Comprueba los eventos que hay en cola
void checkEvents(); void checkEvents();
// Inicializa las variables necesarias para la sección 'Game' // Inicializa las variables necesarias para la sección 'Game'
void init(); void init();
// Carga los recursos necesarios para la sección 'Game' // Carga los recursos necesarios para la sección 'Game'
void loadMedia(); void loadMedia();
// Carga el fichero de puntos // Carga el fichero de puntos
bool loadScoreFile(); bool loadScoreFile();
// Carga el fichero de datos para la demo // Carga el fichero de datos para la demo
bool loadDemoFile(); bool loadDemoFile();
// Guarda el fichero de puntos // Guarda el fichero de puntos
bool saveScoreFile(); bool saveScoreFile();
// Guarda el fichero de datos para la demo // Guarda el fichero de datos para la demo
bool saveDemoFile(); bool saveDemoFile();
// Inicializa las formaciones enemigas // Inicializa las formaciones enemigas
void initEnemyFormations(); void initEnemyFormations();
// Inicializa los conjuntos de formaciones // Inicializa los conjuntos de formaciones
void initEnemyPools(); void initEnemyPools();
// Inicializa las fases del juego // Inicializa las fases del juego
void initGameStages(); void initGameStages();
// Crea una formación de enemigos // Crea una formación de enemigos
void deployEnemyFormation(); void deployEnemyFormation();
// Aumenta el poder de la fase // Aumenta el poder de la fase
void increaseStageCurrentPower(Uint8 power); void increaseStageCurrentPower(Uint8 power);
// Establece el valor de la variable // Establece el valor de la variable
void setHiScore(Uint32 score); void setHiScore(Uint32 score);
// Actualiza el valor de HiScore en caso necesario // Actualiza el valor de HiScore en caso necesario
void updateHiScore(); void updateHiScore();
// Transforma un valor numérico en una cadena de 6 cifras // Transforma un valor numérico en una cadena de 6 cifras
std::string updateScoreText(Uint32 num); std::string updateScoreText(Uint32 num);
// Pinta el marcador en pantalla usando un objeto texto // Pinta el marcador en pantalla usando un objeto texto
void renderScoreBoard(); void renderScoreBoard();
// Actualiza las variables del jugador // Actualiza las variables del jugador
void updatePlayers(); void updatePlayers();
// Dibuja a los jugadores // Dibuja a los jugadores
void renderPlayers(); void renderPlayers();
// Actualiza las variables de la fase // Actualiza las variables de la fase
void updateStage(); void updateStage();
// Actualiza el estado de muerte // Actualiza el estado de muerte
void updateDeath(); void updateDeath();
// Renderiza el fade final cuando se acaba la partida // Renderiza el fade final cuando se acaba la partida
void renderDeathFade(int counter); void renderDeathFade(int counter);
// Actualiza los globos // Actualiza los globos
void updateBalloons(); void updateBalloons();
// Pinta en pantalla todos los globos activos // Pinta en pantalla todos los globos activos
void renderBalloons(); void renderBalloons();
// Crea un globo nuevo en el vector de globos // Crea un globo nuevo en el vector de globos
Uint8 createBalloon(float x, int y, Uint8 kind, float velx, float speed, Uint16 stoppedcounter); Uint8 createBalloon(float x, int y, Uint8 kind, float velx, float speed, Uint16 stoppedcounter);
// Crea una PowerBall // Crea una PowerBall
void createPowerBall(); void createPowerBall();
// Establece la velocidad de los globos // Establece la velocidad de los globos
void setBalloonSpeed(float speed); void setBalloonSpeed(float speed);
// Incrementa la velocidad de los globos // Incrementa la velocidad de los globos
void incBalloonSpeed(); void incBalloonSpeed();
// Decrementa la velocidad de los globos // Decrementa la velocidad de los globos
void decBalloonSpeed(); void decBalloonSpeed();
// Actualiza la velocidad de los globos en funcion del poder acumulado de la fase // Actualiza la velocidad de los globos en funcion del poder acumulado de la fase
void updateBalloonSpeed(); void updateBalloonSpeed();
// Explosiona un globo. Lo destruye y crea otros dos si es el caso // Explosiona un globo. Lo destruye y crea otros dos si es el caso
void popBalloon(Balloon *balloon); void popBalloon(Balloon *balloon);
// Explosiona un globo. Lo destruye // Explosiona un globo. Lo destruye
void destroyBalloon(Balloon *balloon); void destroyBalloon(Balloon *balloon);
// Explosiona todos los globos // Explosiona todos los globos
void popAllBalloons(); void popAllBalloons();
// Destruye todos los globos // Destruye todos los globos
void destroyAllBalloons(); void destroyAllBalloons();
// Detiene todos los globos // Detiene todos los globos
void stopAllBalloons(Uint16 time); void stopAllBalloons(Uint16 time);
// Pone en marcha todos los globos // Pone en marcha todos los globos
void startAllBalloons(); void startAllBalloons();
// Obtiene el numero de globos activos // Obtiene el numero de globos activos
Uint8 countBalloons(); Uint8 countBalloons();
// Vacia el vector de globos // Vacia el vector de globos
void freeBalloons(); void freeBalloons();
// Comprueba la colisión entre el jugador y los globos activos // Comprueba la colisión entre el jugador y los globos activos
bool checkPlayerBalloonCollision(Player *player); bool checkPlayerBalloonCollision(Player *player);
// Comprueba la colisión entre el jugador y los items // Comprueba la colisión entre el jugador y los items
void checkPlayerItemCollision(Player *player); void checkPlayerItemCollision(Player *player);
// Comprueba la colisión entre las balas y los globos // Comprueba la colisión entre las balas y los globos
void checkBulletBalloonCollision(); void checkBulletBalloonCollision();
// Mueve las balas activas // Mueve las balas activas
void moveBullets(); void moveBullets();
// Pinta las balas activas // Pinta las balas activas
void renderBullets(); void renderBullets();
// Crea un objeto bala // Crea un objeto bala
void createBullet(int x, int y, Uint8 kind, bool poweredUp, int owner); void createBullet(int x, int y, Uint8 kind, bool poweredUp, int owner);
// Vacia el vector de balas // Vacia el vector de balas
void freeBullets(); void freeBullets();
// Actualiza los items // Actualiza los items
void updateItems(); void updateItems();
// Pinta los items activos // Pinta los items activos
void renderItems(); void renderItems();
// Devuelve un item en función del azar // Devuelve un item en función del azar
Uint8 dropItem(); Uint8 dropItem();
// Crea un objeto item // Crea un objeto item
void createItem(Uint8 kind, float x, float y); void createItem(Uint8 kind, float x, float y);
// Vacia el vector de items // Vacia el vector de items
void freeItems(); void freeItems();
// Crea un objeto SmartSprite // Crea un objeto SmartSprite
void createItemScoreSprite(int x, int y, SmartSprite *sprite); void createItemScoreSprite(int x, int y, SmartSprite *sprite);
// Vacia el vector de smartsprites // Vacia el vector de smartsprites
void freeSmartSprites(); void freeSmartSprites();
// Dibuja el efecto de flash // Dibuja el efecto de flash
void renderFlashEffect(); void renderFlashEffect();
// Actualiza el efecto de agitar la pantalla // Actualiza el efecto de agitar la pantalla
void updateShakeEffect(); void updateShakeEffect();
// Crea un SmartSprite para arrojar el item café al recibir un impacto // Crea un SmartSprite para arrojar el item café al recibir un impacto
void throwCoffee(int x, int y); void throwCoffee(int x, int y);
// Actualiza los SmartSprites // Actualiza los SmartSprites
void updateSmartSprites(); void updateSmartSprites();
// Pinta los SmartSprites activos // Pinta los SmartSprites activos
void renderSmartSprites(); void renderSmartSprites();
// Acciones a realizar cuando el jugador muere // Acciones a realizar cuando el jugador muere
void killPlayer(Player *player); void killPlayer(Player *player);
// Calcula y establece el valor de amenaza en funcion de los globos activos // Calcula y establece el valor de amenaza en funcion de los globos activos
void evaluateAndSetMenace(); void evaluateAndSetMenace();
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint8 getMenace(); Uint8 getMenace();
// Establece el valor de la variable // Establece el valor de la variable
void setTimeStopped(bool value); void setTimeStopped(bool value);
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool isTimeStopped(); bool isTimeStopped();
// Establece el valor de la variable // Establece el valor de la variable
void setTimeStoppedCounter(Uint16 value); void setTimeStoppedCounter(Uint16 value);
// Incrementa el valor de la variable // Incrementa el valor de la variable
void incTimeStoppedCounter(Uint16 value); void incTimeStoppedCounter(Uint16 value);
// Actualiza la variable EnemyDeployCounter // Actualiza la variable EnemyDeployCounter
void updateEnemyDeployCounter(); void updateEnemyDeployCounter();
// Actualiza y comprueba el valor de la variable // Actualiza y comprueba el valor de la variable
void updateTimeStoppedCounter(); void updateTimeStoppedCounter();
// Gestiona el nivel de amenaza // Gestiona el nivel de amenaza
void updateMenace(); void updateMenace();
// Actualiza el fondo // Actualiza el fondo
void updateBackground(); void updateBackground();
// Dibuja el fondo // Dibuja el fondo
void renderBackground(); void renderBackground();
// Gestiona la entrada durante el juego // Gestiona la entrada durante el juego
void checkGameInput(); void checkGameInput();
// Pinta diferentes mensajes en la pantalla // Pinta diferentes mensajes en la pantalla
void renderMessages(); void renderMessages();
// Habilita el efecto del item de detener el tiempo // Habilita el efecto del item de detener el tiempo
void enableTimeStopItem(); void enableTimeStopItem();
// Deshabilita el efecto del item de detener el tiempo // Deshabilita el efecto del item de detener el tiempo
void disableTimeStopItem(); void disableTimeStopItem();
// Agita la pantalla // Agita la pantalla
void shakeScreen(); void shakeScreen();
// Actualiza las variables del menu de pausa del juego // Actualiza las variables del menu de pausa del juego
void updatePausedGame(); void updatePausedGame();
// Dibuja el menu de pausa del juego // Dibuja el menu de pausa del juego
void renderPausedGame(); void renderPausedGame();
// Bucle para el menu de pausa del juego // Bucle para el menu de pausa del juego
void runPausedGame(); void runPausedGame();
// Actualiza los elementos de la pantalla de game over // Actualiza los elementos de la pantalla de game over
void updateGameOverScreen(); void updateGameOverScreen();
// Dibuja los elementos de la pantalla de game over // Dibuja los elementos de la pantalla de game over
void renderGameOverScreen(); void renderGameOverScreen();
// Bucle para la pantalla de game over // Bucle para la pantalla de game over
void runGameOverScreen(); void runGameOverScreen();
// Indica si se puede crear una powerball // Indica si se puede crear una powerball
bool canPowerBallBeCreated(); bool canPowerBallBeCreated();
// Calcula el poder actual de los globos en pantalla // Calcula el poder actual de los globos en pantalla
int calculateScreenPower(); int calculateScreenPower();
// Inicializa las variables que contienen puntos de ruta para mover objetos // Inicializa las variables que contienen puntos de ruta para mover objetos
void initPaths(); void initPaths();
// Actualiza el tramo final de juego, una vez completado // Actualiza el tramo final de juego, una vez completado
void updateGameCompleted(); void updateGameCompleted();
// Actualiza las variables de ayuda // Actualiza las variables de ayuda
void updateHelper(); void updateHelper();
// Comprueba si todos los jugadores han muerto // Comprueba si todos los jugadores han muerto
bool allPlayersAreDead(); bool allPlayersAreDead();
// Carga las animaciones // Carga las animaciones
void loadAnimations(std::string filePath, std::vector<std::string> *buffer); void loadAnimations(std::string filePath, std::vector<std::string> *buffer);
// Elimina todos los objetos contenidos en vectores // Elimina todos los objetos contenidos en vectores
void deleteAllVectorObjects(); void deleteAllVectorObjects();
// Recarga las texturas // Recarga las texturas
void reloadTextures(); void reloadTextures();
// Establece la máxima puntuación desde fichero o desde las puntuaciones online // Establece la máxima puntuación desde fichero o desde las puntuaciones online
void setHiScore(); void setHiScore();
public: public:
// Constructor // Constructor
Game(int numPlayers, int currentStage, SDL_Renderer *renderer, Screen *screen, Asset *asset, Lang *lang, Input *input, bool demo, options_t *options, section_t *section); Game(int numPlayers, int currentStage, SDL_Renderer *renderer, Screen *screen, Asset *asset, Lang *lang, Input *input, bool demo, options_t *options, section_t *section);
// Destructor // Destructor
~Game(); ~Game();
// Bucle para el juego // Bucle para el juego
void run(); void run();
}; };

View File

@@ -1,324 +1,250 @@
#include "input.h" #include "input.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <iostream> // for basic_ostream, operator<<, cout, basi...
#include <iostream> // for basic_ostream, operator<<, cout, basi...
// Constructor // Constructor
Input::Input(std::string file) Input::Input(std::string file) {
{ // Fichero gamecontrollerdb.txt
// Fichero gamecontrollerdb.txt dbPath = file;
dbPath = file;
// Inicializa las variables // Inicializa las variables
keyBindings_t kb; keyBindings_t kb;
kb.scancode = 0; kb.scancode = 0;
kb.active = false; kb.active = false;
keyBindings.resize(input_number_of_inputs, kb); keyBindings.resize(input_number_of_inputs, kb);
GameControllerBindings_t gcb; GameControllerBindings_t gcb;
gcb.button = SDL_GAMEPAD_BUTTON_INVALID; gcb.button = SDL_GAMEPAD_BUTTON_INVALID;
gcb.active = false; gcb.active = false;
gameControllerBindings.resize(input_number_of_inputs, gcb); gameControllerBindings.resize(input_number_of_inputs, gcb);
verbose = true; verbose = true;
enabled = true; enabled = true;
} }
// Actualiza el estado del objeto // Actualiza el estado del objeto
void Input::update() void Input::update() {
{ if (disabledUntil == d_keyPressed && !checkAnyInput()) {
if (disabledUntil == d_keyPressed && !checkAnyInput()) enable();
{ }
enable();
}
} }
// Asigna inputs a teclas // Asigna inputs a teclas
void Input::bindKey(Uint8 input, SDL_Scancode code) void Input::bindKey(Uint8 input, SDL_Scancode code) {
{ keyBindings[input].scancode = code;
keyBindings[input].scancode = code;
} }
// Asigna inputs a botones del mando // Asigna inputs a botones del mando
void Input::bindGameControllerButton(Uint8 input, SDL_GamepadButton button) void Input::bindGameControllerButton(Uint8 input, SDL_GamepadButton button) {
{ gameControllerBindings[input].button = button;
gameControllerBindings[input].button = button;
} }
// Comprueba si un input esta activo // Comprueba si un input esta activo
bool Input::checkInput(Uint8 input, bool repeat, int device, int index) bool Input::checkInput(Uint8 input, bool repeat, int device, int index) {
{ if (!enabled) {
if (!enabled) return false;
{ }
return false;
}
bool successKeyboard = false; bool successKeyboard = false;
bool successGameController = false; bool successGameController = false;
if (device == INPUT_USE_ANY) if (device == INPUT_USE_ANY) {
{ index = 0;
index = 0; }
}
if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) {
{ const bool *keyStates = SDL_GetKeyboardState(nullptr);
const bool *keyStates = SDL_GetKeyboardState(nullptr);
if (repeat) if (repeat) {
{ if (keyStates[keyBindings[input].scancode]) {
if (keyStates[keyBindings[input].scancode]) successKeyboard = true;
{ } else {
successKeyboard = true; successKeyboard = false;
} }
else } else {
{ if (!keyBindings[input].active) {
successKeyboard = false; if (keyStates[keyBindings[input].scancode]) {
} keyBindings[input].active = true;
} successKeyboard = true;
else } else {
{ successKeyboard = false;
if (!keyBindings[input].active) }
{ } else {
if (keyStates[keyBindings[input].scancode]) if (!keyStates[keyBindings[input].scancode]) {
{ keyBindings[input].active = false;
keyBindings[input].active = true; successKeyboard = false;
successKeyboard = true; } else {
} successKeyboard = false;
else }
{ }
successKeyboard = false; }
} }
}
else
{
if (!keyStates[keyBindings[input].scancode])
{
keyBindings[input].active = false;
successKeyboard = false;
}
else
{
successKeyboard = false;
}
}
}
}
if (gameControllerFound()) if (gameControllerFound())
if ((device == INPUT_USE_GAMECONTROLLER) || (device == INPUT_USE_ANY)) if ((device == INPUT_USE_GAMECONTROLLER) || (device == INPUT_USE_ANY)) {
{ if (repeat) {
if (repeat) if (SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button)) {
{ successGameController = true;
if (SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button)) } else {
{ successGameController = false;
successGameController = true; }
} } else {
else if (!gameControllerBindings[input].active) {
{ if (SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button)) {
successGameController = false; gameControllerBindings[input].active = true;
} successGameController = true;
} } else {
else successGameController = false;
{ }
if (!gameControllerBindings[input].active) } else {
{ if (!SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button)) {
if (SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button)) gameControllerBindings[input].active = false;
{ successGameController = false;
gameControllerBindings[input].active = true; } else {
successGameController = true; successGameController = false;
} }
else }
{ }
successGameController = false; }
}
}
else
{
if (!SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[input].button))
{
gameControllerBindings[input].active = false;
successGameController = false;
}
else
{
successGameController = false;
}
}
}
}
return (successKeyboard || successGameController); return (successKeyboard || successGameController);
} }
// Comprueba si hay almenos un input activo // Comprueba si hay almenos un input activo
bool Input::checkAnyInput(int device, int index) bool Input::checkAnyInput(int device, int index) {
{ if (device == INPUT_USE_ANY) {
if (device == INPUT_USE_ANY) index = 0;
{ }
index = 0;
}
if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) {
{ const bool *mKeystates = SDL_GetKeyboardState(nullptr);
const bool *mKeystates = SDL_GetKeyboardState(nullptr);
for (int i = 0; i < (int)keyBindings.size(); ++i) for (int i = 0; i < (int)keyBindings.size(); ++i) {
{ if (mKeystates[keyBindings[i].scancode]) {
if (mKeystates[keyBindings[i].scancode]) return true;
{ }
return true; }
} }
}
}
if (gameControllerFound()) if (gameControllerFound()) {
{ if (device == INPUT_USE_GAMECONTROLLER || device == INPUT_USE_ANY) {
if (device == INPUT_USE_GAMECONTROLLER || device == INPUT_USE_ANY) for (int i = 0; i < (int)gameControllerBindings.size(); ++i) {
{ if (SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[i].button)) {
for (int i = 0; i < (int)gameControllerBindings.size(); ++i) return true;
{ }
if (SDL_GetGamepadButton(connectedControllers[index], gameControllerBindings[i].button)) }
{ }
return true; }
}
}
}
}
return false; return false;
} }
// Busca si hay un mando conectado // Busca si hay un mando conectado
bool Input::discoverGameController() bool Input::discoverGameController() {
{ bool found = false;
bool found = false;
if (SDL_WasInit(SDL_INIT_GAMEPAD) != SDL_INIT_GAMEPAD) if (SDL_WasInit(SDL_INIT_GAMEPAD) != SDL_INIT_GAMEPAD) {
{ SDL_InitSubSystem(SDL_INIT_GAMEPAD);
SDL_InitSubSystem(SDL_INIT_GAMEPAD); }
}
if (SDL_AddGamepadMappingsFromFile(dbPath.c_str()) < 0) if (SDL_AddGamepadMappingsFromFile(dbPath.c_str()) < 0) {
{ if (verbose) {
if (verbose) std::cout << "Error, could not load " << dbPath.c_str() << " file: " << SDL_GetError() << std::endl;
{ }
std::cout << "Error, could not load " << dbPath.c_str() << " file: " << SDL_GetError() << std::endl; }
}
}
int nJoysticks = 0; int nJoysticks = 0;
SDL_JoystickID *joysticks = SDL_GetJoysticks(&nJoysticks); SDL_JoystickID *joysticks = SDL_GetJoysticks(&nJoysticks);
numGamepads = 0; numGamepads = 0;
if (joysticks) if (joysticks) {
{ // Cuenta el numero de mandos
// Cuenta el numero de mandos for (int i = 0; i < nJoysticks; ++i) {
for (int i = 0; i < nJoysticks; ++i) if (SDL_IsGamepad(joysticks[i])) {
{ numGamepads++;
if (SDL_IsGamepad(joysticks[i])) }
{ }
numGamepads++;
}
}
if (verbose) if (verbose) {
{ std::cout << "\nChecking for game controllers...\n";
std::cout << "\nChecking for game controllers...\n"; std::cout << nJoysticks << " joysticks found, " << numGamepads << " are gamepads\n";
std::cout << nJoysticks << " joysticks found, " << numGamepads << " are gamepads\n"; }
}
if (numGamepads > 0) if (numGamepads > 0) {
{ found = true;
found = true; int padIndex = 0;
int padIndex = 0;
for (int i = 0; i < nJoysticks; i++) for (int i = 0; i < nJoysticks; i++) {
{ if (!SDL_IsGamepad(joysticks[i])) continue;
if (!SDL_IsGamepad(joysticks[i])) continue;
// Abre el mando y lo añade a la lista // Abre el mando y lo añade a la lista
SDL_Gamepad *pad = SDL_OpenGamepad(joysticks[i]); SDL_Gamepad *pad = SDL_OpenGamepad(joysticks[i]);
if (pad != nullptr) if (pad != nullptr) {
{ connectedControllers.push_back(pad);
connectedControllers.push_back(pad); const std::string separator(" #");
const std::string separator(" #"); const char *padName = SDL_GetGamepadName(pad);
const char *padName = SDL_GetGamepadName(pad); std::string name = padName ? padName : "Unknown";
std::string name = padName ? padName : "Unknown"; name.resize(25);
name.resize(25); name = name + separator + std::to_string(padIndex);
name = name + separator + std::to_string(padIndex); if (verbose) {
if (verbose) std::cout << name << std::endl;
{ }
std::cout << name << std::endl; controllerNames.push_back(name);
} padIndex++;
controllerNames.push_back(name); } else {
padIndex++; if (verbose) {
} std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
else }
{ }
if (verbose) }
{
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
}
}
}
SDL_SetGamepadEventsEnabled(true); SDL_SetGamepadEventsEnabled(true);
} }
SDL_free(joysticks); SDL_free(joysticks);
} }
return found; return found;
} }
// Comprueba si hay algun mando conectado // Comprueba si hay algun mando conectado
bool Input::gameControllerFound() bool Input::gameControllerFound() {
{ if (numGamepads > 0) {
if (numGamepads > 0) return true;
{ } else {
return true; return false;
} }
else
{
return false;
}
} }
// Obten el nombre de un mando de juego // Obten el nombre de un mando de juego
std::string Input::getControllerName(int index) std::string Input::getControllerName(int index) {
{ if (numGamepads > 0) {
if (numGamepads > 0) return controllerNames[index];
{ } else {
return controllerNames[index]; return "";
} }
else
{
return "";
}
} }
// Obten el numero de mandos conectados // Obten el numero de mandos conectados
int Input::getNumControllers() int Input::getNumControllers() {
{ return numGamepads;
return numGamepads;
} }
// Establece si ha de mostrar mensajes // Establece si ha de mostrar mensajes
void Input::setVerbose(bool value) void Input::setVerbose(bool value) {
{ verbose = value;
verbose = value;
} }
// Deshabilita las entradas durante un periodo de tiempo // Deshabilita las entradas durante un periodo de tiempo
void Input::disableUntil(i_disable_e value) void Input::disableUntil(i_disable_e value) {
{ disabledUntil = value;
disabledUntil = value; enabled = false;
enabled = false;
} }
// Hablita las entradas // Hablita las entradas
void Input::enable() void Input::enable() {
{ enabled = true;
enabled = true; disabledUntil = d_notDisabled;
disabledUntil = d_notDisabled;
} }

View File

@@ -1,8 +1,9 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string, basic_string
#include <vector> // for vector #include <string> // for string, basic_string
#include <vector> // for vector
// Valores de repetición // Valores de repetición
constexpr bool REPEAT_TRUE = true; constexpr bool REPEAT_TRUE = true;
@@ -13,103 +14,98 @@ constexpr int INPUT_USE_KEYBOARD = 0;
constexpr int INPUT_USE_GAMECONTROLLER = 1; constexpr int INPUT_USE_GAMECONTROLLER = 1;
constexpr int INPUT_USE_ANY = 2; constexpr int INPUT_USE_ANY = 2;
enum inputs_e enum inputs_e {
{ // Inputs obligatorios
// Inputs obligatorios input_null,
input_null, input_up,
input_up, input_down,
input_down, input_left,
input_left, input_right,
input_right, input_pause,
input_pause, input_exit,
input_exit, input_accept,
input_accept, input_cancel,
input_cancel,
// Inputs personalizados // Inputs personalizados
input_fire_left, input_fire_left,
input_fire_center, input_fire_center,
input_fire_right, input_fire_right,
input_window_fullscreen, input_window_fullscreen,
input_window_inc_size, input_window_inc_size,
input_window_dec_size, input_window_dec_size,
// Input obligatorio // Input obligatorio
input_number_of_inputs input_number_of_inputs
}; };
enum i_disable_e enum i_disable_e {
{ d_notDisabled,
d_notDisabled, d_forever,
d_forever, d_keyPressed
d_keyPressed
}; };
class Input class Input {
{ private:
private: struct keyBindings_t {
struct keyBindings_t Uint8 scancode; // Scancode asociado
{ bool active; // Indica si está activo
Uint8 scancode; // Scancode asociado };
bool active; // Indica si está activo
};
struct GameControllerBindings_t struct GameControllerBindings_t {
{ SDL_GamepadButton button; // GameControllerButton asociado
SDL_GamepadButton button; // GameControllerButton asociado bool active; // Indica si está activo
bool active; // Indica si está activo };
};
// Objetos y punteros // Objetos y punteros
std::vector<SDL_Gamepad *> connectedControllers; // Vector con todos los mandos conectados std::vector<SDL_Gamepad *> connectedControllers; // Vector con todos los mandos conectados
// Variables // Variables
std::vector<keyBindings_t> keyBindings; // Vector con las teclas asociadas a los inputs predefinidos std::vector<keyBindings_t> keyBindings; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<GameControllerBindings_t> gameControllerBindings; // Vector con las teclas asociadas a los inputs predefinidos std::vector<GameControllerBindings_t> gameControllerBindings; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<std::string> controllerNames; // Vector con los nombres de los mandos std::vector<std::string> controllerNames; // Vector con los nombres de los mandos
int numGamepads; // Numero de mandos conectados int numGamepads; // Numero de mandos conectados
std::string dbPath; // Ruta al archivo gamecontrollerdb.txt std::string dbPath; // Ruta al archivo gamecontrollerdb.txt
bool verbose; // Indica si ha de mostrar mensajes bool verbose; // Indica si ha de mostrar mensajes
i_disable_e disabledUntil; // Tiempo que esta deshabilitado i_disable_e disabledUntil; // Tiempo que esta deshabilitado
bool enabled; // Indica si está habilitado bool enabled; // Indica si está habilitado
public: public:
// Constructor // Constructor
Input(std::string file); Input(std::string file);
// Actualiza el estado del objeto // Actualiza el estado del objeto
void update(); void update();
// Asigna inputs a teclas // Asigna inputs a teclas
void bindKey(Uint8 input, SDL_Scancode code); void bindKey(Uint8 input, SDL_Scancode code);
// Asigna inputs a botones del mando // Asigna inputs a botones del mando
void bindGameControllerButton(Uint8 input, SDL_GamepadButton button); void bindGameControllerButton(Uint8 input, SDL_GamepadButton button);
// Comprueba si un input esta activo // Comprueba si un input esta activo
bool checkInput(Uint8 input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0); bool checkInput(Uint8 input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0);
// Comprueba si hay almenos un input activo // Comprueba si hay almenos un input activo
bool checkAnyInput(int device = INPUT_USE_ANY, int index = 0); bool checkAnyInput(int device = INPUT_USE_ANY, int index = 0);
// Busca si hay un mando conectado // Busca si hay un mando conectado
bool discoverGameController(); bool discoverGameController();
// Comprueba si hay algun mando conectado // Comprueba si hay algun mando conectado
bool gameControllerFound(); bool gameControllerFound();
// Obten el numero de mandos conectados // Obten el numero de mandos conectados
int getNumControllers(); int getNumControllers();
// Obten el nombre de un mando de juego // Obten el nombre de un mando de juego
std::string getControllerName(int index); std::string getControllerName(int index);
// Establece si ha de mostrar mensajes // Establece si ha de mostrar mensajes
void setVerbose(bool value); void setVerbose(bool value);
// Deshabilita las entradas durante un periodo de tiempo // Deshabilita las entradas durante un periodo de tiempo
void disableUntil(i_disable_e value); void disableUntil(i_disable_e value);
// Hablita las entradas // Hablita las entradas
void enable(); void enable();
}; };

View File

@@ -1,294 +1,264 @@
#include "instructions.h" #include "instructions.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <algorithm> // for max
#include <iostream> // for char_traits, basic_ostream, operator<< #include <algorithm> // for max
#include <string> // for basic_string #include <iostream> // for char_traits, basic_ostream, operator<<
#include "asset.h" // for Asset #include <string> // for basic_string
#include "const.h" // for shdwTxtColor, GAMECANVAS_CENTER_X, GAME...
#include "input.h" // for Input, REPEAT_FALSE, inputs_e #include "asset.h" // for Asset
#include "jail_audio.hpp" // for JA_StopMusic #include "const.h" // for shdwTxtColor, GAMECANVAS_CENTER_X, GAME...
#include "lang.h" // for Lang #include "input.h" // for Input, REPEAT_FALSE, inputs_e
#include "screen.h" // for Screen #include "jail_audio.hpp" // for JA_StopMusic
#include "sprite.h" // for Sprite #include "lang.h" // for Lang
#include "text.h" // for Text, TXT_CENTER, TXT_COLOR, TXT_SHADOW #include "screen.h" // for Screen
#include "texture.h" // for Texture #include "sprite.h" // for Sprite
#include "utils.h" // for color_t, section_t #include "text.h" // for Text, TXT_CENTER, TXT_COLOR, TXT_SHADOW
#include "texture.h" // for Texture
#include "utils.h" // for color_t, section_t
const Uint8 SELF = 0; const Uint8 SELF = 0;
// Constructor // Constructor
Instructions::Instructions(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Lang *lang, section_t *section) Instructions::Instructions(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Lang *lang, section_t *section) {
{ // Copia los punteros
// Copia los punteros this->renderer = renderer;
this->renderer = renderer; this->screen = screen;
this->screen = screen; this->asset = asset;
this->asset = asset; this->input = input;
this->input = input; this->lang = lang;
this->lang = lang; this->section = section;
this->section = section;
// Reserva memoria para los punteros // Reserva memoria para los punteros
Texture *item1 = new Texture(renderer, asset->get("item_points1_disk.png")); Texture *item1 = new Texture(renderer, asset->get("item_points1_disk.png"));
itemTextures.push_back(item1); itemTextures.push_back(item1);
Texture *item2 = new Texture(renderer, asset->get("item_points2_gavina.png")); Texture *item2 = new Texture(renderer, asset->get("item_points2_gavina.png"));
itemTextures.push_back(item2); itemTextures.push_back(item2);
Texture *item3 = new Texture(renderer, asset->get("item_points3_pacmar.png")); Texture *item3 = new Texture(renderer, asset->get("item_points3_pacmar.png"));
itemTextures.push_back(item3); itemTextures.push_back(item3);
Texture *item4 = new Texture(renderer, asset->get("item_clock.png")); Texture *item4 = new Texture(renderer, asset->get("item_clock.png"));
itemTextures.push_back(item4); itemTextures.push_back(item4);
Texture *item5 = new Texture(renderer, asset->get("item_coffee.png")); Texture *item5 = new Texture(renderer, asset->get("item_coffee.png"));
itemTextures.push_back(item5); itemTextures.push_back(item5);
Texture *item6 = new Texture(renderer, asset->get("item_coffee_machine.png")); Texture *item6 = new Texture(renderer, asset->get("item_coffee_machine.png"));
itemTextures.push_back(item6); itemTextures.push_back(item6);
eventHandler = new SDL_Event(); eventHandler = new SDL_Event();
sprite = new Sprite(0, 0, 16, 16, itemTextures[0], renderer); sprite = new Sprite(0, 0, 16, 16, itemTextures[0], renderer);
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
// Crea un backbuffer para el renderizador // Crea un backbuffer para el renderizador
backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (backbuffer != nullptr) if (backbuffer != nullptr) {
{ SDL_SetTextureScaleMode(backbuffer, Texture::currentScaleMode);
SDL_SetTextureScaleMode(backbuffer, Texture::currentScaleMode); } else {
} std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
else }
{
std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
// Inicializa variables // Inicializa variables
section->name = SELF; section->name = SELF;
ticks = 0; ticks = 0;
ticksSpeed = 15; ticksSpeed = 15;
manualQuit = false; manualQuit = false;
counter = 0; counter = 0;
counterEnd = 600; counterEnd = 600;
} }
// Destructor // Destructor
Instructions::~Instructions() Instructions::~Instructions() {
{ for (auto texture : itemTextures) {
for (auto texture : itemTextures) texture->unload();
{ delete texture;
texture->unload(); }
delete texture; itemTextures.clear();
}
itemTextures.clear();
delete sprite; delete sprite;
delete eventHandler; delete eventHandler;
delete text; delete text;
SDL_DestroyTexture(backbuffer); SDL_DestroyTexture(backbuffer);
} }
// Actualiza las variables // Actualiza las variables
void Instructions::update() void Instructions::update() {
{ // Comprueba las entradas
// Comprueba las entradas checkInput();
checkInput();
// Actualiza las variables // Actualiza las variables
if (SDL_GetTicks() - ticks > ticksSpeed) if (SDL_GetTicks() - ticks > ticksSpeed) {
{ // Actualiza el contador de ticks
// Actualiza el contador de ticks ticks = SDL_GetTicks();
ticks = SDL_GetTicks();
if (mode == m_auto) if (mode == m_auto) { // Modo automático
{ // Modo automático counter++;
counter++;
if (counter == counterEnd) if (counter == counterEnd) {
{ section->name = SECTION_PROG_TITLE;
section->name = SECTION_PROG_TITLE; section->subsection = SUBSECTION_TITLE_1;
section->subsection = SUBSECTION_TITLE_1; }
} } else { // Modo manual
} ++counter %= 60000;
else
{ // Modo manual
++counter %= 60000;
if (manualQuit) if (manualQuit) {
{ section->name = SECTION_PROG_TITLE;
section->name = SECTION_PROG_TITLE; section->subsection = SUBSECTION_TITLE_3;
section->subsection = SUBSECTION_TITLE_3; }
} }
} }
}
} }
// Pinta en pantalla // Pinta en pantalla
void Instructions::render() void Instructions::render() {
{ // Pinta en pantalla
// Pinta en pantalla SDL_Rect window = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
SDL_Rect window = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; SDL_Rect srcRect = {0, 0, 16, 16};
SDL_Rect srcRect = {0, 0, 16, 16};
const color_t orangeColor = {0xFF, 0x7A, 0x00}; const color_t orangeColor = {0xFF, 0x7A, 0x00};
const SDL_Rect destRect1 = {60, 88 + (16 * 0), 16, 16}; // Disquito const SDL_Rect destRect1 = {60, 88 + (16 * 0), 16, 16}; // Disquito
const SDL_Rect destRect2 = {60, 88 + (16 * 1), 16, 16}; // Gavineixon const SDL_Rect destRect2 = {60, 88 + (16 * 1), 16, 16}; // Gavineixon
const SDL_Rect destRect3 = {60, 88 + (16 * 2), 16, 16}; // Pacmar const SDL_Rect destRect3 = {60, 88 + (16 * 2), 16, 16}; // Pacmar
const SDL_Rect destRect4 = {60, 88 + (16 * 3), 16, 16}; // Time Stopper const SDL_Rect destRect4 = {60, 88 + (16 * 3), 16, 16}; // Time Stopper
const SDL_Rect destRect5 = {60, 88 + (16 * 4), 16, 16}; // Coffee const SDL_Rect destRect5 = {60, 88 + (16 * 4), 16, 16}; // Coffee
// Pinta en el backbuffer el texto y los sprites // Pinta en el backbuffer el texto y los sprites
SDL_SetRenderTarget(renderer, backbuffer); SDL_SetRenderTarget(renderer, backbuffer);
SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255); SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
// Escribe el texto // Escribe el texto
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 8, lang->getText(11), 1, orangeColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 8, lang->getText(11), 1, orangeColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 24, lang->getText(12), 1, noColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 24, lang->getText(12), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 34, lang->getText(13), 1, noColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 34, lang->getText(13), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 48, lang->getText(14), 1, noColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 48, lang->getText(14), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 58, lang->getText(15), 1, noColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 58, lang->getText(15), 1, noColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 75, lang->getText(16), 1, orangeColor, 1, shdwTxtColor); text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 75, lang->getText(16), 1, orangeColor, 1, shdwTxtColor);
text->writeShadowed(84, 92, lang->getText(17), shdwTxtColor); text->writeShadowed(84, 92, lang->getText(17), shdwTxtColor);
text->writeShadowed(84, 108, lang->getText(18), shdwTxtColor); text->writeShadowed(84, 108, lang->getText(18), shdwTxtColor);
text->writeShadowed(84, 124, lang->getText(19), shdwTxtColor); text->writeShadowed(84, 124, lang->getText(19), shdwTxtColor);
text->writeShadowed(84, 140, lang->getText(20), shdwTxtColor); text->writeShadowed(84, 140, lang->getText(20), shdwTxtColor);
text->writeShadowed(84, 156, lang->getText(21), shdwTxtColor); text->writeShadowed(84, 156, lang->getText(21), shdwTxtColor);
if ((mode == m_manual) && (counter % 50 > 14)) if ((mode == m_manual) && (counter % 50 > 14)) {
{ text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, GAMECANVAS_HEIGHT - 12, lang->getText(22), 1, orangeColor, 1, shdwTxtColor);
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, GAMECANVAS_HEIGHT - 12, lang->getText(22), 1, orangeColor, 1, shdwTxtColor); }
}
// Disquito // Disquito
sprite->setTexture(itemTextures[0]); sprite->setTexture(itemTextures[0]);
sprite->setPos(destRect1); sprite->setPos(destRect1);
srcRect.y = 16 * (((counter + 12) / 36) % 2); srcRect.y = 16 * (((counter + 12) / 36) % 2);
sprite->setSpriteClip(srcRect); sprite->setSpriteClip(srcRect);
sprite->render(); sprite->render();
// Gavineixon // Gavineixon
sprite->setTexture(itemTextures[1]); sprite->setTexture(itemTextures[1]);
sprite->setPos(destRect2); sprite->setPos(destRect2);
srcRect.y = 16 * (((counter + 9) / 36) % 2); srcRect.y = 16 * (((counter + 9) / 36) % 2);
sprite->setSpriteClip(srcRect); sprite->setSpriteClip(srcRect);
sprite->render(); sprite->render();
// Pacmar // Pacmar
sprite->setTexture(itemTextures[2]); sprite->setTexture(itemTextures[2]);
sprite->setPos(destRect3); sprite->setPos(destRect3);
srcRect.y = 16 * (((counter + 6) / 36) % 2); srcRect.y = 16 * (((counter + 6) / 36) % 2);
sprite->setSpriteClip(srcRect); sprite->setSpriteClip(srcRect);
sprite->render(); sprite->render();
// Time Stopper // Time Stopper
sprite->setTexture(itemTextures[3]); sprite->setTexture(itemTextures[3]);
sprite->setPos(destRect4); sprite->setPos(destRect4);
srcRect.y = 16 * (((counter + 3) / 36) % 2); srcRect.y = 16 * (((counter + 3) / 36) % 2);
sprite->setSpriteClip(srcRect); sprite->setSpriteClip(srcRect);
sprite->render(); sprite->render();
// Coffee // Coffee
sprite->setTexture(itemTextures[4]); sprite->setTexture(itemTextures[4]);
sprite->setPos(destRect5); sprite->setPos(destRect5);
srcRect.y = 16 * (((counter + 0) / 36) % 2); srcRect.y = 16 * (((counter + 0) / 36) % 2);
sprite->setSpriteClip(srcRect); sprite->setSpriteClip(srcRect);
sprite->render(); sprite->render();
// Cambia el destino de renderizado // Cambia el destino de renderizado
SDL_SetRenderTarget(renderer, nullptr); SDL_SetRenderTarget(renderer, nullptr);
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen->start(); screen->start();
// Limpia la pantalla // Limpia la pantalla
screen->clean(bgColor); screen->clean(bgColor);
// Establece la ventana del backbuffer // Establece la ventana del backbuffer
if (mode == m_auto) if (mode == m_auto) {
{ window.y = std::max(8, GAMECANVAS_HEIGHT - counter + 100);
window.y = std::max(8, GAMECANVAS_HEIGHT - counter + 100); } else {
} window.y = 0;
else }
{
window.y = 0;
}
// Copia el backbuffer al renderizador // Copia el backbuffer al renderizador
SDL_FRect fWindow = {(float)window.x, (float)window.y, (float)window.w, (float)window.h}; SDL_FRect fWindow = {(float)window.x, (float)window.y, (float)window.w, (float)window.h};
SDL_RenderTexture(renderer, backbuffer, nullptr, &fWindow); SDL_RenderTexture(renderer, backbuffer, nullptr, &fWindow);
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->blit(); screen->blit();
} }
// Comprueba los eventos // Comprueba los eventos
void Instructions::checkEvents() void Instructions::checkEvents() {
{ // Comprueba los eventos que hay en la cola
// Comprueba los eventos que hay en la cola while (SDL_PollEvent(eventHandler) != 0) {
while (SDL_PollEvent(eventHandler) != 0) // Evento de salida de la aplicación
{ if (eventHandler->type == SDL_EVENT_QUIT) {
// Evento de salida de la aplicación section->name = SECTION_PROG_QUIT;
if (eventHandler->type == SDL_EVENT_QUIT) break;
{ }
section->name = SECTION_PROG_QUIT; }
break;
}
}
} }
// Comprueba las entradas // Comprueba las entradas
void Instructions::checkInput() void Instructions::checkInput() {
{ if (input->checkInput(input_exit, REPEAT_FALSE)) {
if (input->checkInput(input_exit, REPEAT_FALSE)) section->name = SECTION_PROG_QUIT;
{ }
section->name = SECTION_PROG_QUIT;
}
else if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) else if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) {
{ screen->switchVideoMode();
screen->switchVideoMode(); }
}
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) {
{ screen->decWindowSize();
screen->decWindowSize(); }
}
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) {
{ screen->incWindowSize();
screen->incWindowSize(); }
}
else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) {
{ if (mode == m_auto) {
if (mode == m_auto) JA_StopMusic();
{ section->name = SECTION_PROG_TITLE;
JA_StopMusic(); section->subsection = SUBSECTION_TITLE_1;
section->name = SECTION_PROG_TITLE; } else {
section->subsection = SUBSECTION_TITLE_1; if (counter > 30) {
} manualQuit = true;
else }
{ }
if (counter > 30) }
{
manualQuit = true;
}
}
}
} }
// Bucle para la pantalla de instrucciones // Bucle para la pantalla de instrucciones
void Instructions::run(mode_e mode) void Instructions::run(mode_e mode) {
{ this->mode = mode;
this->mode = mode;
while (section->name == SELF) while (section->name == SELF) {
{ update();
update(); checkEvents();
checkEvents(); render();
render(); }
}
} }

View File

@@ -1,7 +1,8 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <vector> // for vector
#include <vector> // for vector
class Asset; class Asset;
class Input; class Input;
class Lang; class Lang;
@@ -11,56 +12,54 @@ class Text;
class Texture; class Texture;
struct section_t; struct section_t;
enum mode_e enum mode_e {
{ m_manual,
m_manual, m_auto
m_auto
}; };
// Clase Instructions // Clase Instructions
class Instructions class Instructions {
{ private:
private: // Objetos y punteros
// Objetos y punteros SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Renderer *renderer; // El renderizador de la ventana Screen *screen; // Objeto encargado de dibujar en pantalla
Screen *screen; // Objeto encargado de dibujar en pantalla std::vector<Texture *> itemTextures; // Vector con las texturas de los items
std::vector<Texture *> itemTextures; // Vector con las texturas de los items SDL_Event *eventHandler; // Manejador de eventos
SDL_Event *eventHandler; // Manejador de eventos SDL_Texture *backbuffer; // Textura para usar como backbuffer
SDL_Texture *backbuffer; // Textura para usar como backbuffer Sprite *sprite; // Sprite con la textura de las instrucciones
Sprite *sprite; // Sprite con la textura de las instrucciones Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Asset *asset; // Objeto que gestiona todos los ficheros de recursos Input *input; // Objeto pata gestionar la entrada
Input *input; // Objeto pata gestionar la entrada Lang *lang; // Objeto para gestionar los textos en diferentes idiomas
Lang *lang; // Objeto para gestionar los textos en diferentes idiomas Text *text; // Objeto para escribir texto
Text *text; // Objeto para escribir texto section_t *section; // Estado del bucle principal para saber si continua o se sale
section_t *section; // Estado del bucle principal para saber si continua o se sale
// Variables // Variables
Uint16 counter; // Contador Uint16 counter; // Contador
Uint16 counterEnd; // Valor final para el contador Uint16 counterEnd; // 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 ticksSpeed; // Velocidad a la que se repiten los bucles del programa Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
bool manualQuit; // Indica si se quiere salir del modo manual bool manualQuit; // Indica si se quiere salir del modo manual
mode_e mode; // Modo en el que se van a ejecutar las instrucciones mode_e mode; // Modo en el que se van a ejecutar las instrucciones
// Actualiza las variables // Actualiza las variables
void update(); void update();
// Pinta en pantalla // Pinta en pantalla
void render(); void render();
// Comprueba los eventos // Comprueba los eventos
void checkEvents(); void checkEvents();
// Comprueba las entradas // Comprueba las entradas
void checkInput(); void checkInput();
public: public:
// Constructor // Constructor
Instructions(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Lang *lang, section_t *section); Instructions(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Lang *lang, section_t *section);
// Destructor // Destructor
~Instructions(); ~Instructions();
// Bucle principal // Bucle principal
void run(mode_e mode); void run(mode_e mode);
}; };

View File

@@ -1,453 +1,410 @@
#include "intro.h" #include "intro.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for basic_string
#include "asset.h" // for Asset #include <string> // for basic_string
#include "const.h" // for GAMECANVAS_CENTER_X, GAMECANVAS_FIRST_QU...
#include "input.h" // for Input, REPEAT_FALSE, inputs_e #include "asset.h" // for Asset
#include "jail_audio.hpp" // for JA_StopMusic, JA_DeleteMusic, JA_LoadMusic #include "const.h" // for GAMECANVAS_CENTER_X, GAMECANVAS_FIRST_QU...
#include "lang.h" // for Lang #include "input.h" // for Input, REPEAT_FALSE, inputs_e
#include "screen.h" // for Screen #include "jail_audio.hpp" // for JA_StopMusic, JA_DeleteMusic, JA_LoadMusic
#include "smartsprite.h" // for SmartSprite #include "lang.h" // for Lang
#include "text.h" // for Text #include "screen.h" // for Screen
#include "texture.h" // for Texture #include "smartsprite.h" // for SmartSprite
#include "utils.h" // for section_t, color_t #include "text.h" // for Text
#include "writer.h" // for Writer #include "texture.h" // for Texture
#include "utils.h" // for section_t, color_t
#include "writer.h" // for Writer
// Constructor // Constructor
Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Lang *lang, section_t *section) Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Lang *lang, section_t *section) {
{ // Copia los punteros
// Copia los punteros this->renderer = renderer;
this->renderer = renderer; this->screen = screen;
this->screen = screen; this->lang = lang;
this->lang = lang; this->asset = asset;
this->asset = asset; this->input = input;
this->input = input; this->section = section;
this->section = section;
// Reserva memoria para los objetos // Reserva memoria para los objetos
eventHandler = new SDL_Event(); eventHandler = new SDL_Event();
texture = new Texture(renderer, asset->get("intro.png")); texture = new Texture(renderer, asset->get("intro.png"));
text = new Text(asset->get("nokia.png"), asset->get("nokia.txt"), renderer); text = new Text(asset->get("nokia.png"), asset->get("nokia.txt"), renderer);
// Carga los recursos // Carga los recursos
loadMedia(); loadMedia();
// Inicializa variables // Inicializa variables
section->name = SECTION_PROG_INTRO; section->name = SECTION_PROG_INTRO;
section->subsection = 0; section->subsection = 0;
ticks = 0; ticks = 0;
ticksSpeed = 15; ticksSpeed = 15;
scene = 1; scene = 1;
// Inicializa los bitmaps de la intro // Inicializa los bitmaps de la intro
const int totalBitmaps = 6; const int totalBitmaps = 6;
for (int i = 0; i < totalBitmaps; ++i) for (int i = 0; i < totalBitmaps; ++i) {
{ SmartSprite *ss = new SmartSprite(texture, renderer);
SmartSprite *ss = new SmartSprite(texture, renderer); ss->setWidth(128);
ss->setWidth(128); ss->setHeight(96);
ss->setHeight(96); ss->setEnabledCounter(20);
ss->setEnabledCounter(20); ss->setDestX(GAMECANVAS_CENTER_X - 64);
ss->setDestX(GAMECANVAS_CENTER_X - 64); ss->setDestY(GAMECANVAS_FIRST_QUARTER_Y - 24);
ss->setDestY(GAMECANVAS_FIRST_QUARTER_Y - 24); bitmaps.push_back(ss);
bitmaps.push_back(ss); }
}
bitmaps[0]->setPosX(-128); bitmaps[0]->setPosX(-128);
bitmaps[0]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24); bitmaps[0]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps[0]->setVelX(0.0f); bitmaps[0]->setVelX(0.0f);
bitmaps[0]->setVelY(0.0f); bitmaps[0]->setVelY(0.0f);
bitmaps[0]->setAccelX(0.6f); bitmaps[0]->setAccelX(0.6f);
bitmaps[0]->setAccelY(0.0f); bitmaps[0]->setAccelY(0.0f);
bitmaps[0]->setSpriteClip(0, 0, 128, 96); bitmaps[0]->setSpriteClip(0, 0, 128, 96);
bitmaps[1]->setPosX(GAMECANVAS_WIDTH); bitmaps[1]->setPosX(GAMECANVAS_WIDTH);
bitmaps[1]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24); bitmaps[1]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps[1]->setVelX(-1.0f); bitmaps[1]->setVelX(-1.0f);
bitmaps[1]->setVelY(0.0f); bitmaps[1]->setVelY(0.0f);
bitmaps[1]->setAccelX(-0.3f); bitmaps[1]->setAccelX(-0.3f);
bitmaps[1]->setAccelY(0.0f); bitmaps[1]->setAccelY(0.0f);
bitmaps[1]->setSpriteClip(128, 0, 128, 96); bitmaps[1]->setSpriteClip(128, 0, 128, 96);
bitmaps[2]->setPosX(GAMECANVAS_CENTER_X - 64); bitmaps[2]->setPosX(GAMECANVAS_CENTER_X - 64);
bitmaps[2]->setPosY(-96); bitmaps[2]->setPosY(-96);
bitmaps[2]->setVelX(0.0f); bitmaps[2]->setVelX(0.0f);
bitmaps[2]->setVelY(3.0f); bitmaps[2]->setVelY(3.0f);
bitmaps[2]->setAccelX(0.1f); bitmaps[2]->setAccelX(0.1f);
bitmaps[2]->setAccelY(0.3f); bitmaps[2]->setAccelY(0.3f);
bitmaps[2]->setSpriteClip(0, 96, 128, 96); bitmaps[2]->setSpriteClip(0, 96, 128, 96);
bitmaps[2]->setEnabledCounter(250); bitmaps[2]->setEnabledCounter(250);
bitmaps[3]->setPosX(GAMECANVAS_CENTER_X - 64); bitmaps[3]->setPosX(GAMECANVAS_CENTER_X - 64);
bitmaps[3]->setPosY(GAMECANVAS_HEIGHT); bitmaps[3]->setPosY(GAMECANVAS_HEIGHT);
bitmaps[3]->setVelX(0.0f); bitmaps[3]->setVelX(0.0f);
bitmaps[3]->setVelY(-0.7f); bitmaps[3]->setVelY(-0.7f);
bitmaps[3]->setAccelX(0.0f); bitmaps[3]->setAccelX(0.0f);
bitmaps[3]->setAccelY(0.0f); bitmaps[3]->setAccelY(0.0f);
bitmaps[3]->setSpriteClip(128, 96, 128, 96); bitmaps[3]->setSpriteClip(128, 96, 128, 96);
bitmaps[4]->setPosX(GAMECANVAS_CENTER_X - 64); bitmaps[4]->setPosX(GAMECANVAS_CENTER_X - 64);
bitmaps[4]->setPosY(-96); bitmaps[4]->setPosY(-96);
bitmaps[4]->setVelX(0.0f); bitmaps[4]->setVelX(0.0f);
bitmaps[4]->setVelY(3.0f); bitmaps[4]->setVelY(3.0f);
bitmaps[4]->setAccelX(0.1f); bitmaps[4]->setAccelX(0.1f);
bitmaps[4]->setAccelY(0.3f); bitmaps[4]->setAccelY(0.3f);
bitmaps[4]->setSpriteClip(0, 192, 128, 96); bitmaps[4]->setSpriteClip(0, 192, 128, 96);
bitmaps[5]->setPosX(GAMECANVAS_WIDTH); bitmaps[5]->setPosX(GAMECANVAS_WIDTH);
bitmaps[5]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24); bitmaps[5]->setPosY(GAMECANVAS_FIRST_QUARTER_Y - 24);
bitmaps[5]->setVelX(-0.7f); bitmaps[5]->setVelX(-0.7f);
bitmaps[5]->setVelY(0.0f); bitmaps[5]->setVelY(0.0f);
bitmaps[5]->setAccelX(0.0f); bitmaps[5]->setAccelX(0.0f);
bitmaps[5]->setAccelY(0.0f); bitmaps[5]->setAccelY(0.0f);
bitmaps[5]->setSpriteClip(128, 192, 128, 96); bitmaps[5]->setSpriteClip(128, 192, 128, 96);
// Inicializa los textos de la intro // Inicializa los textos de la intro
const int totalTexts = 9; const int totalTexts = 9;
for (int i = 0; i < totalTexts; ++i) for (int i = 0; i < totalTexts; ++i) {
{ Writer *w = new Writer(text);
Writer *w = new Writer(text); w->setPosX(BLOCK * 0);
w->setPosX(BLOCK * 0); w->setPosY(GAMECANVAS_HEIGHT - (BLOCK * 6));
w->setPosY(GAMECANVAS_HEIGHT - (BLOCK * 6)); w->setKerning(-1);
w->setKerning(-1); w->setEnabled(false);
w->setEnabled(false); w->setEnabledCounter(180);
w->setEnabledCounter(180); texts.push_back(w);
texts.push_back(w); }
}
// Un dia qualsevol de l'any 2000 // Un dia qualsevol de l'any 2000
texts[0]->setCaption(lang->getText(27)); texts[0]->setCaption(lang->getText(27));
texts[0]->setSpeed(8); texts[0]->setSpeed(8);
// Tot esta tranquil a la UPV // Tot esta tranquil a la UPV
texts[1]->setCaption(lang->getText(28)); texts[1]->setCaption(lang->getText(28));
texts[1]->setSpeed(8); texts[1]->setSpeed(8);
// Fins que un desaprensiu... // Fins que un desaprensiu...
texts[2]->setCaption(lang->getText(29)); texts[2]->setCaption(lang->getText(29));
texts[2]->setSpeed(12); texts[2]->setSpeed(12);
// HEY! ME ANE A FERME UN CORTAET... // HEY! ME ANE A FERME UN CORTAET...
texts[3]->setCaption(lang->getText(30)); texts[3]->setCaption(lang->getText(30));
texts[3]->setSpeed(8); texts[3]->setSpeed(8);
// UAAAAAAAAAAAAA!!! // UAAAAAAAAAAAAA!!!
texts[4]->setCaption(lang->getText(31)); texts[4]->setCaption(lang->getText(31));
texts[4]->setSpeed(1); texts[4]->setSpeed(1);
// Espera un moment... // Espera un moment...
texts[5]->setCaption(lang->getText(32)); texts[5]->setCaption(lang->getText(32));
texts[5]->setSpeed(16); texts[5]->setSpeed(16);
// Si resulta que no tinc solt! // Si resulta que no tinc solt!
texts[6]->setCaption(lang->getText(33)); texts[6]->setCaption(lang->getText(33));
texts[6]->setSpeed(2); texts[6]->setSpeed(2);
// MERDA DE MAQUINA! // MERDA DE MAQUINA!
texts[7]->setCaption(lang->getText(34)); texts[7]->setCaption(lang->getText(34));
texts[7]->setSpeed(3); texts[7]->setSpeed(3);
// Blop... blop... blop... // Blop... blop... blop...
texts[8]->setCaption(lang->getText(35)); texts[8]->setCaption(lang->getText(35));
texts[8]->setSpeed(16); texts[8]->setSpeed(16);
for (auto text : texts) for (auto text : texts) {
{ text->center(GAMECANVAS_CENTER_X);
text->center(GAMECANVAS_CENTER_X); }
}
} }
// Destructor // Destructor
Intro::~Intro() Intro::~Intro() {
{ delete eventHandler;
delete eventHandler;
texture->unload(); texture->unload();
delete texture; delete texture;
for (auto bitmap : bitmaps) for (auto bitmap : bitmaps) {
{ delete bitmap;
delete bitmap; }
}
for (auto text : texts) for (auto text : texts) {
{ delete text;
delete text; }
}
JA_DeleteMusic(music); JA_DeleteMusic(music);
} }
// Carga los recursos // Carga los recursos
bool Intro::loadMedia() bool Intro::loadMedia() {
{ // Musicas
// Musicas music = JA_LoadMusic(asset->get("intro.ogg").c_str());
music = JA_LoadMusic(asset->get("intro.ogg").c_str());
return true; return true;
} }
// Comprueba los eventos // Comprueba los eventos
void Intro::checkEvents() void Intro::checkEvents() {
{ // Comprueba los eventos que hay en la cola
// Comprueba los eventos que hay en la cola while (SDL_PollEvent(eventHandler) != 0) {
while (SDL_PollEvent(eventHandler) != 0) // Evento de salida de la aplicación
{ if (eventHandler->type == SDL_EVENT_QUIT) {
// Evento de salida de la aplicación section->name = SECTION_PROG_QUIT;
if (eventHandler->type == SDL_EVENT_QUIT) break;
{ }
section->name = SECTION_PROG_QUIT; }
break;
}
}
} }
// Comprueba las entradas // Comprueba las entradas
void Intro::checkInput() void Intro::checkInput() {
{ if (input->checkInput(input_exit, REPEAT_FALSE)) {
if (input->checkInput(input_exit, REPEAT_FALSE)) section->name = SECTION_PROG_QUIT;
{ }
section->name = SECTION_PROG_QUIT;
}
else if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) else if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) {
{ screen->switchVideoMode();
screen->switchVideoMode(); }
}
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) {
{ screen->decWindowSize();
screen->decWindowSize(); }
}
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) {
{ screen->incWindowSize();
screen->incWindowSize(); }
}
else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) {
{ JA_StopMusic();
JA_StopMusic(); section->name = SECTION_PROG_TITLE;
section->name = SECTION_PROG_TITLE; section->subsection = SUBSECTION_TITLE_1;
section->subsection = SUBSECTION_TITLE_1; }
}
} }
// Actualiza las escenas de la intro // Actualiza las escenas de la intro
void Intro::updateScenes() void Intro::updateScenes() {
{ switch (scene) {
switch (scene) case 1:
{ // Primera imagen - UPV
case 1: if (!bitmaps[0]->hasFinished()) {
// Primera imagen - UPV bitmaps[0]->setEnabled(true);
if (!bitmaps[0]->hasFinished()) }
{
bitmaps[0]->setEnabled(true);
}
// Primer texto de la primera imagen // Primer texto de la primera imagen
if (bitmaps[0]->hasFinished() && !texts[0]->hasFinished()) if (bitmaps[0]->hasFinished() && !texts[0]->hasFinished()) {
{ texts[0]->setEnabled(true);
texts[0]->setEnabled(true); }
}
// Segundo texto de la primera imagen // Segundo texto de la primera imagen
if (texts[0]->hasFinished() && !texts[1]->hasFinished()) if (texts[0]->hasFinished() && !texts[1]->hasFinished()) {
{ texts[0]->setEnabled(false);
texts[0]->setEnabled(false); texts[1]->setEnabled(true);
texts[1]->setEnabled(true); }
}
// Tercer texto de la primera imagen // Tercer texto de la primera imagen
if (texts[1]->hasFinished() && !texts[2]->hasFinished()) if (texts[1]->hasFinished() && !texts[2]->hasFinished()) {
{ texts[1]->setEnabled(false);
texts[1]->setEnabled(false); texts[2]->setEnabled(true);
texts[2]->setEnabled(true); }
}
// Fin de la primera escena // Fin de la primera escena
if (texts[2]->hasFinished()) if (texts[2]->hasFinished()) {
{ bitmaps[0]->setEnabled(false);
bitmaps[0]->setEnabled(false); texts[2]->setEnabled(false);
texts[2]->setEnabled(false); scene++;
scene++; }
}
break; break;
case 2: case 2:
// Segunda imagen - Máquina // Segunda imagen - Máquina
if (!bitmaps[1]->hasFinished()) if (!bitmaps[1]->hasFinished()) {
{ bitmaps[1]->setEnabled(true);
bitmaps[1]->setEnabled(true); }
}
// Primer texto de la segunda imagen // Primer texto de la segunda imagen
if (bitmaps[1]->hasFinished() && !texts[3]->hasFinished()) if (bitmaps[1]->hasFinished() && !texts[3]->hasFinished()) {
{ texts[3]->setEnabled(true);
texts[3]->setEnabled(true); }
}
// Fin de la segunda escena // Fin de la segunda escena
if (texts[3]->hasFinished()) if (texts[3]->hasFinished()) {
{ bitmaps[1]->setEnabled(false);
bitmaps[1]->setEnabled(false); texts[3]->setEnabled(false);
texts[3]->setEnabled(false); scene++;
scene++; }
}
break; break;
case 3: case 3:
// Tercera imagen junto con primer texto - GRITO // Tercera imagen junto con primer texto - GRITO
if (!bitmaps[2]->hasFinished() && !texts[4]->hasFinished()) if (!bitmaps[2]->hasFinished() && !texts[4]->hasFinished()) {
{ bitmaps[2]->setEnabled(true);
bitmaps[2]->setEnabled(true); texts[4]->setEnabled(true);
texts[4]->setEnabled(true); }
}
// Fin de la tercera escena // Fin de la tercera escena
if (bitmaps[2]->hasFinished() && texts[4]->hasFinished()) if (bitmaps[2]->hasFinished() && texts[4]->hasFinished()) {
{ bitmaps[2]->setEnabled(false);
bitmaps[2]->setEnabled(false); texts[4]->setEnabled(false);
texts[4]->setEnabled(false); scene++;
scene++; }
}
break; break;
case 4: case 4:
// Cuarta imagen junto con primer texto - Reflexión // Cuarta imagen junto con primer texto - Reflexión
if (!bitmaps[3]->hasFinished() && !texts[5]->hasFinished()) if (!bitmaps[3]->hasFinished() && !texts[5]->hasFinished()) {
{ bitmaps[3]->setEnabled(true);
bitmaps[3]->setEnabled(true); texts[5]->setEnabled(true);
texts[5]->setEnabled(true); }
}
// Segundo texto de la cuarta imagen // Segundo texto de la cuarta imagen
if (texts[5]->hasFinished() && !texts[6]->hasFinished()) if (texts[5]->hasFinished() && !texts[6]->hasFinished()) {
{ texts[5]->setEnabled(false);
texts[5]->setEnabled(false); texts[6]->setEnabled(true);
texts[6]->setEnabled(true); }
}
// Fin de la cuarta escena // Fin de la cuarta escena
if (bitmaps[3]->hasFinished() && texts[6]->hasFinished()) if (bitmaps[3]->hasFinished() && texts[6]->hasFinished()) {
{ bitmaps[3]->setEnabled(false);
bitmaps[3]->setEnabled(false); texts[6]->setEnabled(false);
texts[6]->setEnabled(false); scene++;
scene++; }
}
break; break;
case 5: case 5:
// Quinta imagen - Patada // Quinta imagen - Patada
if (!bitmaps[4]->hasFinished()) if (!bitmaps[4]->hasFinished()) {
{ bitmaps[4]->setEnabled(true);
bitmaps[4]->setEnabled(true); }
}
// Primer texto de la quinta imagen // Primer texto de la quinta imagen
if (bitmaps[4]->hasFinished() && !texts[7]->hasFinished()) if (bitmaps[4]->hasFinished() && !texts[7]->hasFinished()) {
{ texts[7]->setEnabled(true);
texts[7]->setEnabled(true); }
}
// Fin de la quinta escena // Fin de la quinta escena
if (bitmaps[4]->hasFinished() && texts[7]->hasFinished()) if (bitmaps[4]->hasFinished() && texts[7]->hasFinished()) {
{ bitmaps[4]->setEnabled(false);
bitmaps[4]->setEnabled(false); texts[7]->setEnabled(false);
texts[7]->setEnabled(false); scene++;
scene++; }
}
break; break;
case 6: case 6:
// Sexta imagen junto con texto - Globos de café // Sexta imagen junto con texto - Globos de café
if (!bitmaps[5]->hasFinished() && !texts[8]->hasFinished()) if (!bitmaps[5]->hasFinished() && !texts[8]->hasFinished()) {
{ bitmaps[5]->setEnabled(true);
bitmaps[5]->setEnabled(true); texts[8]->setEnabled(true);
texts[8]->setEnabled(true); }
}
// Acaba el último texto // Acaba el último texto
if (bitmaps[5]->hasFinished() && texts[8]->hasFinished()) if (bitmaps[5]->hasFinished() && texts[8]->hasFinished()) {
{ bitmaps[5]->setEnabled(false);
bitmaps[5]->setEnabled(false); texts[8]->setEnabled(false);
texts[8]->setEnabled(false); JA_StopMusic();
JA_StopMusic(); section->name = SECTION_PROG_TITLE;
section->name = SECTION_PROG_TITLE; section->subsection = SUBSECTION_TITLE_1;
section->subsection = SUBSECTION_TITLE_1; }
}
break; break;
default: default:
break; break;
} }
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
void Intro::update() void Intro::update() {
{ JA_Update();
JA_Update(); checkInput();
checkInput();
if (SDL_GetTicks() - ticks > ticksSpeed) if (SDL_GetTicks() - ticks > ticksSpeed) {
{ // Actualiza el contador de ticks
// Actualiza el contador de ticks ticks = SDL_GetTicks();
ticks = SDL_GetTicks();
// Actualiza los objetos // Actualiza los objetos
for (auto bitmap : bitmaps) for (auto bitmap : bitmaps) {
{ bitmap->update();
bitmap->update(); }
}
for (auto text : texts) for (auto text : texts) {
{ text->update();
text->update(); }
}
// Actualiza las escenas de la intro // Actualiza las escenas de la intro
updateScenes(); updateScenes();
} }
} }
// Dibuja el objeto en pantalla // Dibuja el objeto en pantalla
void Intro::render() void Intro::render() {
{ // Prepara para empezar a dibujar en la textura de juego
// Prepara para empezar a dibujar en la textura de juego screen->start();
screen->start();
// Limpia la pantalla // Limpia la pantalla
screen->clean(bgColor); screen->clean(bgColor);
// Dibuja los objetos // Dibuja los objetos
for (auto bitmap : bitmaps) for (auto bitmap : bitmaps) {
{ bitmap->render();
bitmap->render(); }
}
for (auto text : texts) for (auto text : texts) {
{ text->render();
text->render(); }
}
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->blit(); screen->blit();
} }
// Bucle principal // Bucle principal
void Intro::run() void Intro::run() {
{ JA_PlayMusic(music, 0);
JA_PlayMusic(music, 0);
while (section->name == SECTION_PROG_INTRO) while (section->name == SECTION_PROG_INTRO) {
{ update();
update(); checkEvents();
checkEvents(); render();
render(); }
}
} }

View File

@@ -1,7 +1,8 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <vector> // for vector
#include <vector> // for vector
class Asset; class Asset;
class Input; class Input;
class Lang; class Lang;
@@ -14,53 +15,52 @@ struct JA_Music_t;
struct section_t; struct section_t;
// Clase Intro // Clase Intro
class Intro class Intro {
{ private:
private: // Objetos y punteros
// Objetos y punteros SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Renderer *renderer; // El renderizador de la ventana Screen *screen; // Objeto encargado de dibujar en pantalla
Screen *screen; // Objeto encargado de dibujar en pantalla Texture *texture; // Textura con los graficos
Texture *texture; // Textura con los graficos SDL_Event *eventHandler; // Manejador de eventos
SDL_Event *eventHandler; // Manejador de eventos Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Asset *asset; // Objeto que gestiona todos los ficheros de recursos Lang *lang; // Objeto para gestionar los textos en diferentes idiomas
Lang *lang; // Objeto para gestionar los textos en diferentes idiomas Input *input; // Objeto pata gestionar la entrada
Input *input; // Objeto pata gestionar la entrada std::vector<SmartSprite *> bitmaps; // Vector con los sprites inteligentes para los dibujos de la intro
std::vector<SmartSprite *> bitmaps; // Vector con los sprites inteligentes para los dibujos de la intro std::vector<Writer *> texts; // Textos de la intro
std::vector<Writer *> texts; // Textos de la intro Text *text; // Textos de la intro
Text *text; // Textos de la intro section_t *section; // Estado del bucle principal para saber si continua o se sale
section_t *section; // Estado del bucle principal para saber si continua o se sale
// Variables // Variables
Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa
Uint8 ticksSpeed; // Velocidad a la que se repiten los bucles del programa Uint8 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
JA_Music_t *music; // Musica para la intro JA_Music_t *music; // Musica para la intro
int scene; // Indica que escena está activa int scene; // Indica que escena está activa
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update();
// Dibuja el objeto en pantalla // Dibuja el objeto en pantalla
void render(); void render();
// Carga los recursos // Carga los recursos
bool loadMedia(); bool loadMedia();
// Comprueba los eventos // Comprueba los eventos
void checkEvents(); void checkEvents();
// Comprueba las entradas // Comprueba las entradas
void checkInput(); void checkInput();
// Actualiza las escenas de la intro // Actualiza las escenas de la intro
void updateScenes(); void updateScenes();
public: public:
// Constructor // Constructor
Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Lang *lang, section_t *section); Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Lang *lang, section_t *section);
// Destructor // Destructor
~Intro(); ~Intro();
// Bucle principal // Bucle principal
void run(); void run();
}; };

View File

@@ -1,231 +1,200 @@
#include "item.h" #include "item.h"
#include <stdlib.h> // for rand
#include <stdlib.h> // for rand
#include "animatedsprite.h" // for AnimatedSprite #include "animatedsprite.h" // for AnimatedSprite
#include "const.h" // for PLAY_AREA_LEFT, PLAY_AREA_RIGHT, PLAY_AR... #include "const.h" // for PLAY_AREA_LEFT, PLAY_AREA_RIGHT, PLAY_AR...
class Texture; class Texture;
// Constructor // Constructor
Item::Item(Uint8 kind, float x, float y, Texture *texture, std::vector<std::string> *animation, SDL_Renderer *renderer) Item::Item(Uint8 kind, float x, float y, Texture *texture, std::vector<std::string> *animation, SDL_Renderer *renderer) {
{ sprite = new AnimatedSprite(texture, renderer, "", animation);
sprite = new AnimatedSprite(texture, renderer, "", animation);
this->kind = kind; this->kind = kind;
enabled = true; enabled = true;
timeToLive = 600; timeToLive = 600;
accelX = 0.0f; accelX = 0.0f;
floorCollision = false; floorCollision = false;
if (kind == ITEM_COFFEE_MACHINE) if (kind == ITEM_COFFEE_MACHINE) {
{ width = 23;
width = 23; height = 29;
height = 29; posX = (((int)x + (PLAY_AREA_WIDTH / 2)) % (PLAY_AREA_WIDTH - width - 5)) + 2;
posX = (((int)x + (PLAY_AREA_WIDTH / 2)) % (PLAY_AREA_WIDTH - width - 5)) + 2; posY = PLAY_AREA_TOP - height;
posY = PLAY_AREA_TOP - height; velX = 0.0f;
velX = 0.0f; velY = -0.1f;
velY = -0.1f; accelY = 0.1f;
accelY = 0.1f; collider.r = 10;
collider.r = 10; } else {
} width = 16;
else height = 16;
{ posX = x;
width = 16; posY = y;
height = 16; velX = -1.0f + ((rand() % 5) * 0.5f);
posX = x; velY = -4.0f;
posY = y; accelY = 0.2f;
velX = -1.0f + ((rand() % 5) * 0.5f); collider.r = width / 2;
velY = -4.0f; }
accelY = 0.2f;
collider.r = width / 2;
}
sprite->setPosX(posX); sprite->setPosX(posX);
sprite->setPosY(posY); sprite->setPosY(posY);
shiftColliders(); shiftColliders();
} }
// Destructor // Destructor
Item::~Item() Item::~Item() {
{ delete sprite;
delete sprite;
} }
// Centra el objeto en la posición X // Centra el objeto en la posición X
void Item::allignTo(int x) void Item::allignTo(int x) {
{ posX = float(x - (width / 2));
posX = float(x - (width / 2));
if (posX < PLAY_AREA_LEFT) if (posX < PLAY_AREA_LEFT) {
{ posX = PLAY_AREA_LEFT + 1;
posX = PLAY_AREA_LEFT + 1; } else if ((posX + width) > PLAY_AREA_RIGHT) {
} posX = float(PLAY_AREA_RIGHT - width - 1);
else if ((posX + width) > PLAY_AREA_RIGHT) }
{
posX = float(PLAY_AREA_RIGHT - width - 1);
}
// Posición X,Y del sprite // Posición X,Y del sprite
sprite->setPosX(int(posX)); sprite->setPosX(int(posX));
sprite->setPosY(int(posY)); sprite->setPosY(int(posY));
// Alinea el circulo de colisión con el objeto // Alinea el circulo de colisión con el objeto
shiftColliders(); shiftColliders();
} }
// Pinta el objeto en la pantalla // Pinta el objeto en la pantalla
void Item::render() void Item::render() {
{ if (enabled) {
if (enabled) if (timeToLive > 200) {
{ sprite->render();
if (timeToLive > 200) } else if (timeToLive % 20 > 10) {
{ sprite->render();
sprite->render(); }
} }
else if (timeToLive % 20 > 10)
{
sprite->render();
}
}
} }
// Actualiza la posición y estados del objeto // Actualiza la posición y estados del objeto
void Item::move() void Item::move() {
{ floorCollision = false;
floorCollision = false;
// Calcula la nueva posición // Calcula la nueva posición
posX += velX; posX += velX;
posY += velY; posY += velY;
// Aplica las aceleraciones a la velocidad // Aplica las aceleraciones a la velocidad
velX += accelX; velX += accelX;
velY += accelY; velY += accelY;
// Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido // Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido
if ((posX < PLAY_AREA_LEFT) || (posX + width > PLAY_AREA_RIGHT)) if ((posX < PLAY_AREA_LEFT) || (posX + width > PLAY_AREA_RIGHT)) {
{ // Corregir posición
// Corregir posición posX -= velX;
posX -= velX;
// Invertir sentido // Invertir sentido
velX = -velX; velX = -velX;
} }
// Si se sale por arriba rebota (excepto la maquina de café) // Si se sale por arriba rebota (excepto la maquina de café)
if ((posY < PLAY_AREA_TOP) && !(kind == ITEM_COFFEE_MACHINE)) if ((posY < PLAY_AREA_TOP) && !(kind == ITEM_COFFEE_MACHINE)) {
{ // Corrige
// Corrige posY -= velY;
posY -= velY;
// Invierte el sentido // Invierte el sentido
velY = -velY; velY = -velY;
} }
// Si el objeto se sale por la parte inferior // Si el objeto se sale por la parte inferior
if (posY + height > PLAY_AREA_BOTTOM) if (posY + height > PLAY_AREA_BOTTOM) {
{ // Corrige
// Corrige posY -= velY;
posY -= velY;
// Detiene el objeto // Detiene el objeto
velY = 0; velY = 0;
velX = 0; velX = 0;
accelX = 0; accelX = 0;
accelY = 0; accelY = 0;
posY = PLAY_AREA_BOTTOM - height; posY = PLAY_AREA_BOTTOM - height;
if (kind == ITEM_COFFEE_MACHINE) if (kind == ITEM_COFFEE_MACHINE) {
{ floorCollision = true;
floorCollision = true; }
} }
}
// Actualiza la posición del sprite // Actualiza la posición del sprite
sprite->setPosX(int(posX)); sprite->setPosX(int(posX));
sprite->setPosY(int(posY)); sprite->setPosY(int(posY));
shiftColliders(); shiftColliders();
} }
// Pone a cero todos los valores del objeto // Pone a cero todos los valores del objeto
void Item::disable() void Item::disable() {
{ enabled = false;
enabled = false;
} }
// Actualiza el objeto a su posicion, animación y controla los contadores // Actualiza el objeto a su posicion, animación y controla los contadores
void Item::update() void Item::update() {
{ move();
move(); sprite->animate();
sprite->animate(); updateTimeToLive();
updateTimeToLive(); checkTimeToLive();
checkTimeToLive();
} }
// Actualiza el contador // Actualiza el contador
void Item::updateTimeToLive() void Item::updateTimeToLive() {
{ if (timeToLive > 0) {
if (timeToLive > 0) timeToLive--;
{ }
timeToLive--;
}
} }
// Comprueba si el objeto sigue vivo // Comprueba si el objeto sigue vivo
void Item::checkTimeToLive() void Item::checkTimeToLive() {
{ if (timeToLive == 0)
if (timeToLive == 0) disable();
disable();
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
float Item::getPosX() float Item::getPosX() {
{ return posX;
return posX;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
float Item::getPosY() float Item::getPosY() {
{ return posY;
return posY;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
int Item::getWidth() int Item::getWidth() {
{ return width;
return width;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
int Item::getHeight() int Item::getHeight() {
{ return height;
return height;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
int Item::getClass() int Item::getClass() {
{ return kind;
return kind;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool Item::isEnabled() bool Item::isEnabled() {
{ return enabled;
return enabled;
} }
// Obtiene el circulo de colisión // Obtiene el circulo de colisión
circle_t &Item::getCollider() circle_t &Item::getCollider() {
{ return collider;
return collider;
} }
// Alinea el circulo de colisión con la posición del objeto // Alinea el circulo de colisión con la posición del objeto
void Item::shiftColliders() void Item::shiftColliders() {
{ collider.x = int(posX + (width / 2));
collider.x = int(posX + (width / 2)); collider.y = int(posY + (height / 2));
collider.y = int(posY + (height / 2));
} }
// Informa si el objeto ha colisionado con el suelo // Informa si el objeto ha colisionado con el suelo
bool Item::isOnFloor() bool Item::isOnFloor() {
{ return floorCollision;
return floorCollision;
} }

View File

@@ -1,9 +1,11 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string
#include <vector> // for vector #include <string> // for string
#include "utils.h" // for circle_t #include <vector> // for vector
#include "utils.h" // for circle_t
class AnimatedSprite; class AnimatedSprite;
class Texture; class Texture;
@@ -16,25 +18,24 @@ constexpr int ITEM_COFFEE = 5;
constexpr int ITEM_COFFEE_MACHINE = 6; constexpr int ITEM_COFFEE_MACHINE = 6;
// Clase Item // Clase Item
class Item class Item {
{ private:
private:
// Objetos y punteros // Objetos y punteros
AnimatedSprite *sprite; // Sprite con los graficos del objeto AnimatedSprite *sprite; // Sprite con los graficos del objeto
// Variables // Variables
float posX; // Posición X del objeto float posX; // Posición X del objeto
float posY; // Posición Y del objeto float posY; // Posición Y del objeto
Uint8 width; // Ancho del objeto Uint8 width; // Ancho del objeto
Uint8 height; // Alto del objeto Uint8 height; // Alto del objeto
float velX; // Velocidad en el eje X float velX; // Velocidad en el eje X
float velY; // Velocidad en el eje Y float velY; // Velocidad en el eje Y
float accelX; // Aceleración en el eje X float accelX; // Aceleración en el eje X
float accelY; // Aceleración en el eje Y float accelY; // Aceleración en el eje Y
bool floorCollision; // Indica si el objeto colisiona con el suelo bool floorCollision; // Indica si el objeto colisiona con el suelo
Uint8 kind; // Especifica el tipo de objeto que es Uint8 kind; // Especifica el tipo de objeto que es
bool enabled; // Especifica si el objeto está habilitado bool enabled; // Especifica si el objeto está habilitado
circle_t collider; // Circulo de colisión del objeto circle_t collider; // Circulo de colisión del objeto
// Alinea el circulo de colisión con la posición del objeto // Alinea el circulo de colisión con la posición del objeto
void shiftColliders(); void shiftColliders();
@@ -42,8 +43,8 @@ private:
// Actualiza la posición y estados del objeto // Actualiza la posición y estados del objeto
void move(); void move();
public: public:
Uint16 timeToLive; // Temporizador con el tiempo que el objeto está presente Uint16 timeToLive; // Temporizador con el tiempo que el objeto está presente
// Constructor // Constructor
Item(Uint8 kind, float x, float y, Texture *texture, std::vector<std::string> *animation, SDL_Renderer *renderer); Item(Uint8 kind, float x, float y, Texture *texture, std::vector<std::string> *animation, SDL_Renderer *renderer);

View File

@@ -1,40 +1,38 @@
#include "lang.h" #include "lang.h"
#include <fstream> // for basic_ifstream, basic_istream, ifstream #include <fstream> // for basic_ifstream, basic_istream, ifstream
#include "asset.h" // for Asset #include "asset.h" // for Asset
// Constructor // Constructor
Lang::Lang(Asset *mAsset) Lang::Lang(Asset *mAsset) {
{
this->mAsset = mAsset; this->mAsset = mAsset;
} }
// Destructor // Destructor
Lang::~Lang() Lang::~Lang() {
{
} }
// Inicializa los textos del juego en el idioma seleccionado // Inicializa los textos del juego en el idioma seleccionado
bool Lang::setLang(Uint8 lang) bool Lang::setLang(Uint8 lang) {
{
std::string file; std::string file;
switch (lang) switch (lang) {
{ case es_ES:
case es_ES: file = mAsset->get("es_ES.txt");
file = mAsset->get("es_ES.txt"); break;
break;
case en_UK: case en_UK:
file = mAsset->get("en_UK.txt"); file = mAsset->get("en_UK.txt");
break; break;
case ba_BA: case ba_BA:
file = mAsset->get("ba_BA.txt"); file = mAsset->get("ba_BA.txt");
break; break;
default: default:
file = mAsset->get("en_UK.txt"); file = mAsset->get("en_UK.txt");
break; break;
} }
for (int i = 0; i < MAX_TEXT_STRINGS; i++) for (int i = 0; i < MAX_TEXT_STRINGS; i++)
@@ -43,20 +41,17 @@ bool Lang::setLang(Uint8 lang)
bool success = false; bool success = false;
std::ifstream rfile(file); std::ifstream rfile(file);
if (rfile.is_open() && rfile.good()) if (rfile.is_open() && rfile.good()) {
{
success = true; success = true;
std::string line; std::string line;
// lee el resto de datos del fichero // lee el resto de datos del fichero
int index = 0; int index = 0;
while (std::getline(rfile, line)) while (std::getline(rfile, line)) {
{
// Almacena solo las lineas que no empiezan por # o no esten vacias // Almacena solo las lineas que no empiezan por # o no esten vacias
const bool test1 = line.substr(0,1) != "#"; const bool test1 = line.substr(0, 1) != "#";
const bool test2 = !line.empty(); const bool test2 = !line.empty();
if (test1 && test2) if (test1 && test2) {
{
mTextStrings[index] = line; mTextStrings[index] = line;
index++; index++;
} }
@@ -67,7 +62,6 @@ bool Lang::setLang(Uint8 lang)
} }
// Obtiene la cadena de texto del indice // Obtiene la cadena de texto del indice
std::string Lang::getText(int index) std::string Lang::getText(int index) {
{
return mTextStrings[index]; return mTextStrings[index];
} }

View File

@@ -1,7 +1,8 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string, basic_string
#include <string> // for string, basic_string
class Asset; class Asset;
// Códigos de idioma // Códigos de idioma
@@ -14,13 +15,12 @@ constexpr int MAX_LANGUAGES = 3;
constexpr int MAX_TEXT_STRINGS = 100; constexpr int MAX_TEXT_STRINGS = 100;
// Clase Lang // Clase Lang
class Lang class Lang {
{ private:
private: Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos
Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos std::string mTextStrings[MAX_TEXT_STRINGS]; // Vector con los textos
std::string mTextStrings[MAX_TEXT_STRINGS]; // Vector con los textos
public: public:
// Constructor // Constructor
Lang(Asset *mAsset); Lang(Asset *mAsset);

View File

@@ -1,168 +1,151 @@
#include "logo.h" #include "logo.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <algorithm> // for min
#include <string> // for basic_string #include <algorithm> // for min
#include "asset.h" // for Asset #include <string> // for basic_string
#include "const.h" // for bgColor, SECTION_PROG_LOGO, SECTION_PROG...
#include "input.h" // for Input, REPEAT_FALSE, inputs_e #include "asset.h" // for Asset
#include "jail_audio.hpp" // for JA_StopMusic #include "const.h" // for bgColor, SECTION_PROG_LOGO, SECTION_PROG...
#include "screen.h" // for Screen #include "input.h" // for Input, REPEAT_FALSE, inputs_e
#include "sprite.h" // for Sprite #include "jail_audio.hpp" // for JA_StopMusic
#include "texture.h" // for Texture #include "screen.h" // for Screen
#include "utils.h" // for section_t, color_t #include "sprite.h" // for Sprite
#include "texture.h" // for Texture
#include "utils.h" // for section_t, color_t
// Valores de inicialización y fin // Valores de inicialización y fin
constexpr int INIT_FADE = 100; constexpr int INIT_FADE = 100;
constexpr int END_LOGO = 200; constexpr int END_LOGO = 200;
// Constructor // Constructor
Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, section_t *section) Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, section_t *section) {
{ // Copia la dirección de los objetos
// Copia la dirección de los objetos this->renderer = renderer;
this->renderer = renderer; this->screen = screen;
this->screen = screen; this->asset = asset;
this->asset = asset; this->input = input;
this->input = input; this->section = section;
this->section = section;
// Reserva memoria para los punteros // Reserva memoria para los punteros
eventHandler = new SDL_Event(); eventHandler = new SDL_Event();
texture = new Texture(renderer, asset->get("logo.png")); texture = new Texture(renderer, asset->get("logo.png"));
sprite = new Sprite(14, 75, 226, 44, texture, renderer); sprite = new Sprite(14, 75, 226, 44, texture, renderer);
// Inicializa variables // Inicializa variables
counter = 0; counter = 0;
section->name = SECTION_PROG_LOGO; section->name = SECTION_PROG_LOGO;
section->subsection = 0; section->subsection = 0;
ticks = 0; ticks = 0;
ticksSpeed = 15; ticksSpeed = 15;
} }
// Destructor // Destructor
Logo::~Logo() Logo::~Logo() {
{ texture->unload();
texture->unload(); delete texture;
delete texture;
delete sprite; delete sprite;
delete eventHandler; delete eventHandler;
} }
// Comprueba si ha terminado el logo // Comprueba si ha terminado el logo
void Logo::checkLogoEnd() void Logo::checkLogoEnd() {
{ if (counter >= END_LOGO + 20) {
if (counter >= END_LOGO + 20) section->name = SECTION_PROG_INTRO;
{ section->subsection = 0;
section->name = SECTION_PROG_INTRO; }
section->subsection = 0;
}
} }
// Comprueba los eventos // Comprueba los eventos
void Logo::checkEvents() void Logo::checkEvents() {
{ // Comprueba los eventos que hay en la cola
// Comprueba los eventos que hay en la cola while (SDL_PollEvent(eventHandler) != 0) {
while (SDL_PollEvent(eventHandler) != 0) // Evento de salida de la aplicación
{ if (eventHandler->type == SDL_EVENT_QUIT) {
// Evento de salida de la aplicación section->name = SECTION_PROG_QUIT;
if (eventHandler->type == SDL_EVENT_QUIT) break;
{ }
section->name = SECTION_PROG_QUIT; }
break;
}
}
} }
// Comprueba las entradas // Comprueba las entradas
void Logo::checkInput() void Logo::checkInput() {
{ if (input->checkInput(input_exit, REPEAT_FALSE)) {
if (input->checkInput(input_exit, REPEAT_FALSE)) section->name = SECTION_PROG_QUIT;
{ }
section->name = SECTION_PROG_QUIT;
}
else if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) else if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) {
{ screen->switchVideoMode();
screen->switchVideoMode(); }
}
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) else if (input->checkInput(input_window_dec_size, REPEAT_FALSE)) {
{ screen->decWindowSize();
screen->decWindowSize(); }
}
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) else if (input->checkInput(input_window_inc_size, REPEAT_FALSE)) {
{ screen->incWindowSize();
screen->incWindowSize(); }
}
else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) {
{ section->name = SECTION_PROG_TITLE;
section->name = SECTION_PROG_TITLE; section->subsection = SUBSECTION_TITLE_1;
section->subsection = SUBSECTION_TITLE_1; }
}
} }
// Dibuja el fade // Dibuja el fade
void Logo::renderFade() void Logo::renderFade() {
{ // Dibuja el fade
// Dibuja el fade if (counter >= INIT_FADE) {
if (counter >= INIT_FADE) const float step = (float)(counter - INIT_FADE) / (float)(END_LOGO - INIT_FADE);
{ const int alpha = std::min((int)(255 * step), 255);
const float step = (float)(counter - INIT_FADE) / (float)(END_LOGO - INIT_FADE); SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, alpha);
const int alpha = std::min((int)(255 * step), 255); SDL_RenderFillRect(renderer, nullptr);
SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, alpha); }
SDL_RenderFillRect(renderer, nullptr);
}
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
void Logo::update() void Logo::update() {
{ JA_Update();
JA_Update(); checkInput();
checkInput();
if (SDL_GetTicks() - ticks > ticksSpeed) if (SDL_GetTicks() - ticks > ticksSpeed) {
{ // Actualiza el contador de ticks
// Actualiza el contador de ticks ticks = SDL_GetTicks();
ticks = SDL_GetTicks();
// Actualiza el contador // Actualiza el contador
counter++; counter++;
// Comprueba si ha terminado el logo // Comprueba si ha terminado el logo
checkLogoEnd(); checkLogoEnd();
} }
} }
// Dibuja el objeto en pantalla // Dibuja el objeto en pantalla
void Logo::render() void Logo::render() {
{ // Prepara para empezar a dibujar en la textura de juego
// Prepara para empezar a dibujar en la textura de juego screen->start();
screen->start();
// Limpia la pantalla // Limpia la pantalla
screen->clean({238, 238, 238}); screen->clean({238, 238, 238});
// Dibuja los objetos // Dibuja los objetos
sprite->render(); sprite->render();
// Dibuja el fade // Dibuja el fade
renderFade(); renderFade();
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen->blit(); screen->blit();
} }
// Bucle para el logo del juego // Bucle para el logo del juego
void Logo::run() void Logo::run() {
{ JA_StopMusic();
JA_StopMusic();
while (section->name == SECTION_PROG_LOGO) while (section->name == SECTION_PROG_LOGO) {
{ update();
update(); checkEvents();
checkEvents(); render();
render(); }
}
} }

View File

@@ -9,49 +9,48 @@ class Texture;
struct section_t; struct section_t;
// Clase Logo // Clase Logo
class Logo class Logo {
{ private:
private: // Objetos y punteros
// Objetos y punteros SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Renderer *renderer; // El renderizador de la ventana Screen *screen; // Objeto encargado de dibujar en pantalla
Screen *screen; // Objeto encargado de dibujar en pantalla Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Asset *asset; // Objeto que gestiona todos los ficheros de recursos Input *input; // Objeto pata gestionar la entrada
Input *input; // Objeto pata gestionar la entrada Texture *texture; // Textura con los graficos
Texture *texture; // Textura con los graficos SDL_Event *eventHandler; // Manejador de eventos
SDL_Event *eventHandler; // Manejador de eventos Sprite *sprite; // Sprite con la textura del logo
Sprite *sprite; // Sprite con la textura del logo section_t *section; // Estado del bucle principal para saber si continua o se sale
section_t *section; // Estado del bucle principal para saber si continua o se sale
// 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 ticksSpeed; // Velocidad a la que se repiten los bucles del programa Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
int counter; // Contador int counter; // Contador
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update();
// Dibuja el objeto en pantalla // Dibuja el objeto en pantalla
void render(); void render();
// Comprueba si ha terminado el logo // Comprueba si ha terminado el logo
void checkLogoEnd(); void checkLogoEnd();
// Comprueba los eventos // Comprueba los eventos
void checkEvents(); void checkEvents();
// Comprueba las entradas // Comprueba las entradas
void checkInput(); void checkInput();
// Dibuja el fade // Dibuja el fade
void renderFade(); void renderFade();
public: public:
// Constructor // Constructor
Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, section_t *section); Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, section_t *section);
// Destructor // Destructor
~Logo(); ~Logo();
// Bucle principal // Bucle principal
void run(); void run();
}; };

View File

@@ -40,14 +40,14 @@ Reescribiendo el código el 27/09/2022
*/ */
#include <memory> #include <memory>
#include "stb_vorbis.c"
#include "director.h"
int main(int argc, char *argv[]) #include "director.h"
{ #include "stb_vorbis.c"
// Crea el objeto Director
int main(int argc, char *argv[]) {
// Crea el objeto Director
auto director = std::make_unique<Director>(argc, const_cast<const char **>(argv)); auto director = std::make_unique<Director>(argc, const_cast<const char **>(argv));
// Bucle principal // Bucle principal
return director->run(); return director->run();
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,11 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string, basic_string
#include <vector> // for vector #include <string> // for string, basic_string
#include "utils.h" // for color_t #include <vector> // for vector
#include "utils.h" // for color_t
class Asset; class Asset;
class Input; class Input;
class Text; class Text;
@@ -22,208 +24,204 @@ constexpr int SOUND_CANCEL = 2;
constexpr int MENU_NO_OPTION = -1; constexpr int MENU_NO_OPTION = -1;
// Clase Menu // Clase Menu
class Menu class Menu {
{ private:
private: struct rectangle_t {
struct rectangle_t SDL_Rect rect; // Rectangulo
{ color_t color; // Color
SDL_Rect rect; // Rectangulo int a; // Transparencia
color_t color; // Color };
int a; // Transparencia
};
struct item_t struct item_t {
{ std::string label; // Texto
std::string label; // Texto SDL_Rect rect; // Rectangulo que delimita el elemento
SDL_Rect rect; // Rectangulo que delimita el elemento int hPaddingDown; // Espaciado bajo el elemento
int hPaddingDown; // Espaciado bajo el elemento bool selectable; // Indica si se puede seleccionar
bool selectable; // Indica si se puede seleccionar bool greyed; // Indica si ha de aparecer con otro color mas oscuro
bool greyed; // Indica si ha de aparecer con otro color mas oscuro bool linkedDown; // Indica si el elemento actual y el siguiente se tratan como uno solo. Afecta al selector
bool linkedDown; // Indica si el elemento actual y el siguiente se tratan como uno solo. Afecta al selector bool linkedUp; // Indica si el elemento actual y el anterior se tratan como uno solo. Afecta al selector
bool linkedUp; // Indica si el elemento actual y el anterior se tratan como uno solo. Afecta al selector bool visible; // Indica si el elemento es visible
bool visible; // Indica si el elemento es visible bool line; // Indica si el elemento lleva una linea a continuación
bool line; // Indica si el elemento lleva una linea a continuación };
};
struct selector_t struct selector_t {
{ float originY; // Coordenada de origen
float originY; // Coordenada de origen float targetY; // Coordenada de destino
float targetY; // Coordenada de destino float despY; // Cantidad de pixeles que se desplaza el selector en cada salto: (target - origin) / numJumps
float despY; // Cantidad de pixeles que se desplaza el selector en cada salto: (target - origin) / numJumps bool moving; // Indica si el selector está avanzando hacia el destino
bool moving; // Indica si el selector está avanzando hacia el destino float originH; // Altura de origen
float originH; // Altura de origen float targetH; // Altura de destino
float targetH; // Altura de destino float incH; // Cantidad de pixels que debe incrementar o decrementar el selector en cada salto
float incH; // Cantidad de pixels que debe incrementar o decrementar el selector en cada salto bool resizing; // Indica si el selector está cambiando de tamaño
bool resizing; // Indica si el selector está cambiando de tamaño float y; // Coordenada actual, usado para el desplazamiento
float y; // Coordenada actual, usado para el desplazamiento float h; // Altura actual, usado para el cambio de tamaño
float h; // Altura actual, usado para el cambio de tamaño int numJumps; // Numero de pasos preestablecido para llegar al destino
int numJumps; // Numero de pasos preestablecido para llegar al destino int index; // Elemento del menu que tiene el foco
int index; // Elemento del menu que tiene el foco int previousIndex; // Elemento que tenia el foco previamente
int previousIndex; // Elemento que tenia el foco previamente color_t previousItemColor; // Color del item nque tenia el foco previamente
color_t previousItemColor; // Color del item nque tenia el foco previamente SDL_Rect rect; // Rectangulo del selector
SDL_Rect rect; // Rectangulo del selector color_t color; // Color del selector
color_t color; // Color del selector color_t itemColor; // Color del item
color_t itemColor; // Color del item color_t jumpItemColors[8]; // Transición de colores para el item seleccionado
color_t jumpItemColors[8]; // Transición de colores para el item seleccionado int itemColorIndex; // Indice del color de transición para el item seleccionado
int itemColorIndex; // Indice del color de transición para el item seleccionado int a; // Cantidad de transparencia para el rectangulo del selector
int a; // Cantidad de transparencia para el rectangulo del selector };
};
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer; // Puntero al renderizador de la ventana SDL_Renderer *renderer; // Puntero al renderizador de la ventana
Asset *asset; // Objeto para gestionar los ficheros de recursos Asset *asset; // Objeto para gestionar los ficheros de recursos
Text *text; // Texto para poder escribir los items del menu Text *text; // Texto para poder escribir los items del menu
Input *input; // Gestor de eventos de entrada de teclado o gamepad Input *input; // Gestor de eventos de entrada de teclado o gamepad
// Variables // Variables
std::string name; // Nombre del menu std::string name; // Nombre del menu
int x; // Posición en el eje X de la primera letra del primer elemento int x; // Posición en el eje X de la primera letra del primer elemento
int y; // Posición en el eje Y de la primera letra del primer elemento int y; // Posición en el eje Y de la primera letra del primer elemento
int h; // Altura del menu int h; // Altura del menu
int w; // Anchura del menu int w; // Anchura del menu
int itemSelected; // Índice del item del menu que ha sido seleccionado int itemSelected; // Índice del item del menu que ha sido seleccionado
int defaultActionWhenCancel; // Indice del item del menu que se selecciona cuando se cancela el menu int defaultActionWhenCancel; // Indice del item del menu que se selecciona cuando se cancela el menu
int backgroundType; // Tipo de fondo para el menu int backgroundType; // Tipo de fondo para el menu
int centerX; // Centro del menu en el eje X int centerX; // Centro del menu en el eje X
int centerY; // Centro del menu en el eje Y int centerY; // Centro del menu en el eje Y
bool isCenteredOnX; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje X bool isCenteredOnX; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje X
bool isCenteredOnY; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y bool isCenteredOnY; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y
bool areElementsCenteredOnX; // Variable para saber si los elementos van centrados en el eje X bool areElementsCenteredOnX; // Variable para saber si los elementos van centrados en el eje X
int widestItem; // Anchura del elemento más ancho int widestItem; // Anchura del elemento más ancho
JA_Sound_t *soundAccept; // Sonido al aceptar o elegir una opción del menu JA_Sound_t *soundAccept; // Sonido al aceptar o elegir una opción del menu
JA_Sound_t *soundCancel; // Sonido al cancelar el menu JA_Sound_t *soundCancel; // Sonido al cancelar el menu
JA_Sound_t *soundMove; // Sonido al mover el selector JA_Sound_t *soundMove; // Sonido al mover el selector
color_t colorGreyed; // Color para los elementos agrisados color_t colorGreyed; // Color para los elementos agrisados
rectangle_t rectBG; // Rectangulo de fondo del menu rectangle_t rectBG; // Rectangulo de fondo del menu
std::vector<item_t> item; // Estructura para cada elemento del menu std::vector<item_t> item; // Estructura para cada elemento del menu
selector_t selector; // Variables para pintar el selector del menu selector_t selector; // Variables para pintar el selector del menu
std::string font_png; std::string font_png;
std::string font_txt; std::string font_txt;
// Carga la configuración del menu desde un archivo de texto // Carga la configuración del menu desde un archivo de texto
bool load(std::string file_path); bool load(std::string file_path);
// Asigna variables a partir de dos cadenas // Asigna variables a partir de dos cadenas
bool setVars(std::string var, std::string value); bool setVars(std::string var, std::string value);
// Asigna variables a partir de dos cadenas // Asigna variables a partir de dos cadenas
bool setItem(item_t *item, std::string var, std::string value); bool setItem(item_t *item, std::string var, std::string value);
// Actualiza el menu para recolocarlo correctamente y establecer el tamaño // Actualiza el menu para recolocarlo correctamente y establecer el tamaño
void reorganize(); void reorganize();
// Deja el menu apuntando al siguiente elemento // Deja el menu apuntando al siguiente elemento
bool increaseSelectorIndex(); bool increaseSelectorIndex();
// Deja el menu apuntando al elemento anterior // Deja el menu apuntando al elemento anterior
bool decreaseSelectorIndex(); bool decreaseSelectorIndex();
// Actualiza la posicion y el estado del selector // Actualiza la posicion y el estado del selector
void updateSelector(); void updateSelector();
// Obtiene la anchura del elemento más ancho del menu // Obtiene la anchura del elemento más ancho del menu
int getWidestItem(); int getWidestItem();
// Gestiona la entrada de teclado y mando durante el menu // Gestiona la entrada de teclado y mando durante el menu
void checkMenuInput(Menu *menu); void checkMenuInput(Menu *menu);
// Calcula el ancho del menu // Calcula el ancho del menu
int findWidth(); int findWidth();
// Calcula el alto del menu // Calcula el alto del menu
int findHeight(); int findHeight();
// Recoloca los elementos del menu en el eje Y // Recoloca los elementos del menu en el eje Y
void replaceElementsOnY(); void replaceElementsOnY();
// Calcula la altura del selector // Calcula la altura del selector
int getSelectorHeight(int value); int getSelectorHeight(int value);
// Calcula los colores del selector para el degradado // Calcula los colores del selector para el degradado
void setSelectorItemColors(); void setSelectorItemColors();
public: public:
// Constructor // Constructor
Menu(SDL_Renderer *renderer, Asset *asset, Input *input, std::string file = ""); Menu(SDL_Renderer *renderer, Asset *asset, Input *input, std::string file = "");
// Destructor // Destructor
~Menu(); ~Menu();
// Carga los ficheros de audio // Carga los ficheros de audio
void loadAudioFile(std::string file, int sound); void loadAudioFile(std::string file, int sound);
// Obtiene el nombre del menu // Obtiene el nombre del menu
std::string getName(); std::string getName();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getItemSelected(); int getItemSelected();
// Deja el menu apuntando al primer elemento // Deja el menu apuntando al primer elemento
void reset(); void reset();
// Gestiona la entrada de teclado y mando durante el menu // Gestiona la entrada de teclado y mando durante el menu
void checkInput(); void checkInput();
// Actualiza la logica del menu // Actualiza la logica del menu
void update(); void update();
// Pinta el menu en pantalla // Pinta el menu en pantalla
void render(); void render();
// Establece el color del rectangulo de fondo // Establece el color del rectangulo de fondo
void setBackgroundColor(color_t color, int alpha); void setBackgroundColor(color_t color, int alpha);
// Establece el color del rectangulo del selector // Establece el color del rectangulo del selector
void setSelectorColor(color_t color, int alpha); void setSelectorColor(color_t color, int alpha);
// Establece el color del texto del selector // Establece el color del texto del selector
void setSelectorTextColor(color_t color); void setSelectorTextColor(color_t color);
// Centra el menu respecto a un punto en el eje X // Centra el menu respecto a un punto en el eje X
void centerMenuOnX(int value = 0); void centerMenuOnX(int value = 0);
// Centra el menu respecto a un punto en el eje Y // Centra el menu respecto a un punto en el eje Y
void centerMenuOnY(int value); void centerMenuOnY(int value);
// Centra los elementos del menu en el eje X // Centra los elementos del menu en el eje X
void centerMenuElementsOnX(); void centerMenuElementsOnX();
// Añade un item al menu // Añade un item al menu
void addItem(item_t item); void addItem(item_t item);
// Cambia el texto de un item // Cambia el texto de un item
void setItemCaption(int index, std::string text); void setItemCaption(int index, std::string text);
// Establece el indice del item que se usará por defecto al cancelar el menu // Establece el indice del item que se usará por defecto al cancelar el menu
void setDefaultActionWhenCancel(int item); void setDefaultActionWhenCancel(int item);
// Coloca el selector en una posición específica // Coloca el selector en una posición específica
void setSelectorPos(int index); void setSelectorPos(int index);
// Establece el estado seleccionable de un item // Establece el estado seleccionable de un item
void setSelectable(int index, bool value); void setSelectable(int index, bool value);
// Establece el estado agrisado de un item // Establece el estado agrisado de un item
void setGreyed(int index, bool value); void setGreyed(int index, bool value);
// Establece el estado de enlace de un item // Establece el estado de enlace de un item
void setLinkedDown(int index, bool value); void setLinkedDown(int index, bool value);
// Establece el estado de visibilidad de un item // Establece el estado de visibilidad de un item
void setVisible(int index, bool value); void setVisible(int index, bool value);
// Establece el nombre del menu // Establece el nombre del menu
void setName(std::string name); void setName(std::string name);
// Establece la posición del menu // Establece la posición del menu
void setPos(int x, int y); void setPos(int x, int y);
// Establece el tipo de fondo del menu // Establece el tipo de fondo del menu
void setBackgroundType(int value); void setBackgroundType(int value);
// Establece la fuente de texto que se utilizará // Establece la fuente de texto que se utilizará
void setText(std::string font_png, std::string font_txt); void setText(std::string font_png, std::string font_txt);
// Establece el rectangulo de fondo del menu // Establece el rectangulo de fondo del menu
void setRectSize(int w = 0, int h = 0); void setRectSize(int w = 0, int h = 0);
}; };

View File

@@ -1,362 +1,312 @@
#include "movingsprite.h" #include "movingsprite.h"
#include "texture.h" // for Texture #include "texture.h" // for Texture
// Constructor // Constructor
MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, Texture *texture, SDL_Renderer *renderer) MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, Texture *texture, SDL_Renderer *renderer) {
{ // Copia los punteros
// Copia los punteros this->texture = texture;
this->texture = texture; this->renderer = renderer;
this->renderer = renderer;
// Establece el alto y el ancho del sprite // Establece el alto y el ancho del sprite
this->w = w; this->w = w;
this->h = h; this->h = h;
// Establece la posición X,Y del sprite // Establece la posición X,Y del sprite
this->x = x; this->x = x;
this->y = y; this->y = y;
xPrev = x; xPrev = x;
yPrev = y; yPrev = y;
// Establece la velocidad X,Y del sprite // Establece la velocidad X,Y del sprite
vx = velx; vx = velx;
vy = vely; vy = vely;
// Establece la aceleración X,Y del sprite // Establece la aceleración X,Y del sprite
ax = accelx; ax = accelx;
ay = accely; ay = accely;
// Establece el zoom W,H del sprite // Establece el zoom W,H del sprite
zoomW = 1; zoomW = 1;
zoomH = 1; zoomH = 1;
// Establece el angulo con el que se dibujará // Establece el angulo con el que se dibujará
angle = (double)0; angle = (double)0;
// Establece los valores de rotacion // Establece los valores de rotacion
rotateEnabled = false; rotateEnabled = false;
rotateSpeed = 0; rotateSpeed = 0;
rotateAmount = (double)0; rotateAmount = (double)0;
// Contador interno // Contador interno
counter = 0; counter = 0;
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
spriteClip = {0, 0, w, h}; spriteClip = {0, 0, w, h};
// Establece el centro de rotación // Establece el centro de rotación
center = nullptr; center = nullptr;
// Establece el tipo de volteado // Establece el tipo de volteado
currentFlip = SDL_FLIP_NONE; currentFlip = SDL_FLIP_NONE;
}; };
// Reinicia todas las variables // Reinicia todas las variables
void MovingSprite::clear() void MovingSprite::clear() {
{ x = 0.0f; // Posición en el eje X
x = 0.0f; // Posición en el eje X y = 0.0f; // Posición en el eje Y
y = 0.0f; // Posición en el eje Y
vx = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse vx = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
vy = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse vy = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
ax = 0.0f; // Aceleración en el eje X. Variación de la velocidad ax = 0.0f; // Aceleración en el eje X. Variación de la velocidad
ay = 0.0f; // Aceleración en el eje Y. Variación de la velocidad ay = 0.0f; // Aceleración en el eje Y. Variación de la velocidad
zoomW = 1.0f; // Zoom aplicado a la anchura zoomW = 1.0f; // Zoom aplicado a la anchura
zoomH = 1.0f; // Zoom aplicado a la altura zoomH = 1.0f; // Zoom aplicado a la altura
angle = 0.0; // Angulo para dibujarlo angle = 0.0; // Angulo para dibujarlo
rotateEnabled = false; // Indica si ha de rotar rotateEnabled = false; // Indica si ha de rotar
center = nullptr; // Centro de rotación center = nullptr; // Centro de rotación
rotateSpeed = 0; // Velocidad de giro rotateSpeed = 0; // Velocidad de giro
rotateAmount = 0.0; // Cantidad de grados a girar en cada iteración rotateAmount = 0.0; // Cantidad de grados a girar en cada iteración
counter = 0; // Contador interno counter = 0; // Contador interno
currentFlip = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite currentFlip = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
} }
// Mueve el sprite // Mueve el sprite
void MovingSprite::move() void MovingSprite::move() {
{ if (enabled) {
if (enabled) xPrev = x;
{ yPrev = y;
xPrev = x;
yPrev = y;
x += vx; x += vx;
y += vy; y += vy;
vx += ax; vx += ax;
vy += ay; vy += ay;
} }
} }
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void MovingSprite::render() void MovingSprite::render() {
{ if (enabled) {
if (enabled) texture->render(renderer, (int)x, (int)y, &spriteClip, zoomW, zoomH, angle, center, currentFlip);
{ }
texture->render(renderer, (int)x, (int)y, &spriteClip, zoomW, zoomH, angle, center, currentFlip);
}
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getPosX() float MovingSprite::getPosX() {
{ return x;
return x;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getPosY() float MovingSprite::getPosY() {
{ return y;
return y;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getVelX() float MovingSprite::getVelX() {
{ return vx;
return vx;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getVelY() float MovingSprite::getVelY() {
{ return vy;
return vy;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getAccelX() float MovingSprite::getAccelX() {
{ return ax;
return ax;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getAccelY() float MovingSprite::getAccelY() {
{ return ay;
return ay;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getZoomW() float MovingSprite::getZoomW() {
{ return zoomW;
return zoomW;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getZoomH() float MovingSprite::getZoomH() {
{ return zoomH;
return zoomH;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
double MovingSprite::getAngle() double MovingSprite::getAngle() {
{ return angle;
return angle;
} }
// Establece la posición y el tamaño del objeto // Establece la posición y el tamaño del objeto
void MovingSprite::setRect(SDL_Rect rect) void MovingSprite::setRect(SDL_Rect rect) {
{ x = (float)rect.x;
x = (float)rect.x; y = (float)rect.y;
y = (float)rect.y; w = rect.w;
w = rect.w; h = rect.h;
h = rect.h;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setPosX(float value) void MovingSprite::setPosX(float value) {
{ x = value;
x = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setPosY(float value) void MovingSprite::setPosY(float value) {
{ y = value;
y = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setVelX(float value) void MovingSprite::setVelX(float value) {
{ vx = value;
vx = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setVelY(float value) void MovingSprite::setVelY(float value) {
{ vy = value;
vy = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setAccelX(float value) void MovingSprite::setAccelX(float value) {
{ ax = value;
ax = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setAccelY(float value) void MovingSprite::setAccelY(float value) {
{ ay = value;
ay = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setZoomW(float value) void MovingSprite::setZoomW(float value) {
{ zoomW = value;
zoomW = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setZoomH(float value) void MovingSprite::setZoomH(float value) {
{ zoomH = value;
zoomH = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setAngle(double value) void MovingSprite::setAngle(double value) {
{ angle = value;
angle = value;
} }
// Incrementa el valor de la variable // Incrementa el valor de la variable
void MovingSprite::incAngle(double value) void MovingSprite::incAngle(double value) {
{ angle += value;
angle += value;
} }
// Decrementa el valor de la variable // Decrementa el valor de la variable
void MovingSprite::decAngle(double value) void MovingSprite::decAngle(double value) {
{ angle -= value;
angle -= value;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool MovingSprite::getRotate() bool MovingSprite::getRotate() {
{ return rotateEnabled;
return rotateEnabled;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 MovingSprite::getRotateSpeed() Uint16 MovingSprite::getRotateSpeed() {
{ return rotateSpeed;
return rotateSpeed;
} }
// Establece la rotacion // Establece la rotacion
void MovingSprite::rotate() void MovingSprite::rotate() {
{ if (enabled)
if (enabled) if (rotateEnabled) {
if (rotateEnabled) if (counter % rotateSpeed == 0) {
{ incAngle(rotateAmount);
if (counter % rotateSpeed == 0) }
{ }
incAngle(rotateAmount);
}
}
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setRotate(bool value) void MovingSprite::setRotate(bool value) {
{ rotateEnabled = value;
rotateEnabled = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setRotateSpeed(int value) void MovingSprite::setRotateSpeed(int value) {
{ if (value < 1) {
if (value < 1) rotateSpeed = 1;
{ } else {
rotateSpeed = 1; rotateSpeed = value;
} }
else
{
rotateSpeed = value;
}
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setRotateAmount(double value) void MovingSprite::setRotateAmount(double value) {
{ rotateAmount = value;
rotateAmount = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::disableRotate() void MovingSprite::disableRotate() {
{ rotateEnabled = false;
rotateEnabled = false; angle = (double)0;
angle = (double)0;
} }
// Actualiza las variables internas del objeto // Actualiza las variables internas del objeto
void MovingSprite::update() void MovingSprite::update() {
{ move();
move(); rotate();
rotate();
if (enabled) if (enabled) {
{ ++counter %= 60000;
++counter %= 60000; }
}
} }
// Cambia el sentido de la rotación // Cambia el sentido de la rotación
void MovingSprite::switchRotate() void MovingSprite::switchRotate() {
{ rotateAmount *= -1;
rotateAmount *= -1;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setFlip(SDL_FlipMode flip) void MovingSprite::setFlip(SDL_FlipMode flip) {
{ currentFlip = flip;
currentFlip = flip;
} }
// Gira el sprite horizontalmente // Gira el sprite horizontalmente
void MovingSprite::flip() void MovingSprite::flip() {
{ currentFlip = (currentFlip == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL;
currentFlip = (currentFlip == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
SDL_FlipMode MovingSprite::getFlip() SDL_FlipMode MovingSprite::getFlip() {
{ return currentFlip;
return currentFlip;
} }
// Devuelve el rectangulo donde está el sprite // Devuelve el rectangulo donde está el sprite
SDL_Rect MovingSprite::getRect() SDL_Rect MovingSprite::getRect() {
{ const SDL_Rect rect = {(int)x, (int)y, w, h};
const SDL_Rect rect = {(int)x, (int)y, w, h}; return rect;
return rect;
} }
// Deshace el último movimiento // Deshace el último movimiento
void MovingSprite::undoMove() void MovingSprite::undoMove() {
{ x = xPrev;
x = xPrev; y = yPrev;
y = yPrev;
} }
// Deshace el último movimiento en el eje X // Deshace el último movimiento en el eje X
void MovingSprite::undoMoveX() void MovingSprite::undoMoveX() {
{ x = xPrev;
x = xPrev;
} }
// Deshace el último movimiento en el eje Y // Deshace el último movimiento en el eje Y
void MovingSprite::undoMoveY() void MovingSprite::undoMoveY() {
{ y = yPrev;
y = yPrev;
} }
// Pone a cero las velocidades de desplacamiento // Pone a cero las velocidades de desplacamiento
void MovingSprite::clearVel() void MovingSprite::clearVel() {
{ vx = vy = 0.0f;
vx = vy = 0.0f;
} }
// Devuelve el incremento en el eje X en pixels // Devuelve el incremento en el eje X en pixels
int MovingSprite::getIncX() int MovingSprite::getIncX() {
{ return (int)x - (int)xPrev;
return (int)x - (int)xPrev;
} }

View File

@@ -1,37 +1,37 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include "sprite.h" // for Sprite
#include "sprite.h" // for Sprite
class Texture; class Texture;
// Clase MovingSprite. Añade posicion y velocidad en punto flotante // Clase MovingSprite. Añade posicion y velocidad en punto flotante
class MovingSprite : public Sprite class MovingSprite : public Sprite {
{ protected:
protected: float x; // Posición en el eje X
float x; // Posición en el eje X float y; // Posición en el eje Y
float y; // Posición en el eje Y
float xPrev; // Posición anterior en el eje X float xPrev; // Posición anterior en el eje X
float yPrev; // Posición anterior en el eje Y float yPrev; // Posición anterior en el eje Y
float vx; // Velocidad en el eje X. Cantidad de pixeles a desplazarse float vx; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
float vy; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse float vy; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
float ax; // Aceleración en el eje X. Variación de la velocidad float ax; // Aceleración en el eje X. Variación de la velocidad
float ay; // Aceleración en el eje Y. Variación de la velocidad float ay; // Aceleración en el eje Y. Variación de la velocidad
float zoomW; // Zoom aplicado a la anchura float zoomW; // Zoom aplicado a la anchura
float zoomH; // Zoom aplicado a la altura float zoomH; // Zoom aplicado a la altura
double angle; // Angulo para dibujarlo double angle; // Angulo para dibujarlo
bool rotateEnabled; // Indica si ha de rotar bool rotateEnabled; // Indica si ha de rotar
int rotateSpeed; // Velocidad de giro int rotateSpeed; // Velocidad de giro
double rotateAmount; // Cantidad de grados a girar en cada iteración double rotateAmount; // Cantidad de grados a girar en cada iteración
int counter; // Contador interno int counter; // Contador interno
SDL_Point *center; // Centro de rotación SDL_Point *center; // Centro de rotación
SDL_FlipMode currentFlip; // Indica como se voltea el sprite SDL_FlipMode currentFlip; // Indica como se voltea el sprite
public: public:
// Constructor // Constructor
MovingSprite(float x = 0, float y = 0, int w = 0, int h = 0, float velx = 0, float vely = 0, float accelx = 0, float accely = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr); MovingSprite(float x = 0, float y = 0, int w = 0, int h = 0, float velx = 0, float vely = 0, float accelx = 0, float accely = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr);

View File

@@ -1,632 +1,530 @@
#include "player.h" #include "player.h"
#include <stdlib.h> // for rand
#include <stdlib.h> // for rand
#include "animatedsprite.h" // for AnimatedSprite #include "animatedsprite.h" // for AnimatedSprite
#include "const.h" // for PLAY_AREA_LEFT, PLAY_AREA_RIGHT #include "const.h" // for PLAY_AREA_LEFT, PLAY_AREA_RIGHT
#include "input.h" // for inputs_e #include "input.h" // for inputs_e
#include "texture.h" // for Texture #include "texture.h" // for Texture
// Constructor // Constructor
Player::Player(float x, int y, SDL_Renderer *renderer, std::vector<Texture *> texture, std::vector<std::vector<std::string> *> animations) Player::Player(float x, int y, SDL_Renderer *renderer, std::vector<Texture *> texture, std::vector<std::vector<std::string> *> animations) {
{ // Copia los punteros
// Copia los punteros this->renderer = renderer;
this->renderer = renderer;
// Reserva memoria para los objetos // Reserva memoria para los objetos
headSprite = new AnimatedSprite(texture[0], renderer, "", animations[0]); headSprite = new AnimatedSprite(texture[0], renderer, "", animations[0]);
bodySprite = new AnimatedSprite(texture[1], renderer, "", animations[1]); bodySprite = new AnimatedSprite(texture[1], renderer, "", animations[1]);
legsSprite = new AnimatedSprite(texture[2], renderer, "", animations[2]); legsSprite = new AnimatedSprite(texture[2], renderer, "", animations[2]);
deathSprite = new AnimatedSprite(texture[3], renderer, "", animations[3]); deathSprite = new AnimatedSprite(texture[3], renderer, "", animations[3]);
fireSprite = new AnimatedSprite(texture[4], renderer, "", animations[4]); fireSprite = new AnimatedSprite(texture[4], renderer, "", animations[4]);
fireSprite->getTexture()->setAlpha(224); fireSprite->getTexture()->setAlpha(224);
// Establece la posición inicial del jugador // Establece la posición inicial del jugador
posX = x; posX = x;
posY = y; posY = y;
init(); init();
} }
// Destructor // Destructor
Player::~Player() Player::~Player() {
{ delete headSprite;
delete headSprite; delete bodySprite;
delete bodySprite; delete legsSprite;
delete legsSprite; delete deathSprite;
delete deathSprite; delete fireSprite;
delete fireSprite;
} }
// Iniciador // Iniciador
void Player::init() void Player::init() {
{ // Inicializa variables de estado
// Inicializa variables de estado alive = true;
alive = true; deathCounter = DEATH_COUNTER;
deathCounter = DEATH_COUNTER; statusWalking = PLAYER_STATUS_WALKING_STOP;
statusWalking = PLAYER_STATUS_WALKING_STOP; statusFiring = PLAYER_STATUS_FIRING_NO;
statusFiring = PLAYER_STATUS_FIRING_NO; invulnerable = false;
invulnerable = false; invulnerableCounter = PLAYER_INVULNERABLE_COUNTER;
invulnerableCounter = PLAYER_INVULNERABLE_COUNTER; powerUp = false;
powerUp = false; powerUpCounter = PLAYER_POWERUP_COUNTER;
powerUpCounter = PLAYER_POWERUP_COUNTER; extraHit = false;
extraHit = false; coffees = 0;
coffees = 0; input = true;
input = true;
// Establece la altura y el ancho del jugador // Establece la altura y el ancho del jugador
width = 24; width = 24;
height = 24; height = 24;
// Establece el tamaño del circulo de colisión // Establece el tamaño del circulo de colisión
collider.r = 7; collider.r = 7;
// Actualiza la posición del circulo de colisión // Actualiza la posición del circulo de colisión
shiftColliders(); shiftColliders();
// Establece la velocidad inicial // Establece la velocidad inicial
velX = 0; velX = 0;
velY = 0; velY = 0;
// Establece la velocidad base // Establece la velocidad base
baseSpeed = 1.5; baseSpeed = 1.5;
// Establece la puntuación inicial // Establece la puntuación inicial
score = 0; score = 0;
// Establece el multiplicador de puntos inicial // Establece el multiplicador de puntos inicial
scoreMultiplier = 1.0f; scoreMultiplier = 1.0f;
// Inicia el contador para la cadencia de disparo // Inicia el contador para la cadencia de disparo
cooldown = 10; cooldown = 10;
// Establece la posición del sprite // Establece la posición del sprite
legsSprite->setPosX(posX); legsSprite->setPosX(posX);
legsSprite->setPosY(posY); legsSprite->setPosY(posY);
bodySprite->setPosX(posX); bodySprite->setPosX(posX);
bodySprite->setPosY(posY); bodySprite->setPosY(posY);
headSprite->setPosX(posX); headSprite->setPosX(posX);
headSprite->setPosY(posY); headSprite->setPosY(posY);
// Selecciona un frame para pintar // Selecciona un frame para pintar
legsSprite->setCurrentAnimation("stand"); legsSprite->setCurrentAnimation("stand");
bodySprite->setCurrentAnimation("stand"); bodySprite->setCurrentAnimation("stand");
headSprite->setCurrentAnimation("stand"); headSprite->setCurrentAnimation("stand");
} }
// Actua en consecuencia de la entrada recibida // Actua en consecuencia de la entrada recibida
void Player::setInput(Uint8 input) void Player::setInput(Uint8 input) {
{ switch (input) {
switch (input) case input_left:
{ velX = -baseSpeed;
case input_left: setWalkingStatus(PLAYER_STATUS_WALKING_LEFT);
velX = -baseSpeed; break;
setWalkingStatus(PLAYER_STATUS_WALKING_LEFT);
break;
case input_right: case input_right:
velX = baseSpeed; velX = baseSpeed;
setWalkingStatus(PLAYER_STATUS_WALKING_RIGHT); setWalkingStatus(PLAYER_STATUS_WALKING_RIGHT);
break; break;
case input_fire_center: case input_fire_center:
setFiringStatus(PLAYER_STATUS_FIRING_UP); setFiringStatus(PLAYER_STATUS_FIRING_UP);
break; break;
case input_fire_left: case input_fire_left:
setFiringStatus(PLAYER_STATUS_FIRING_LEFT); setFiringStatus(PLAYER_STATUS_FIRING_LEFT);
break; break;
case input_fire_right: case input_fire_right:
setFiringStatus(PLAYER_STATUS_FIRING_RIGHT); setFiringStatus(PLAYER_STATUS_FIRING_RIGHT);
break; break;
default: default:
velX = 0; velX = 0;
setWalkingStatus(PLAYER_STATUS_WALKING_STOP); setWalkingStatus(PLAYER_STATUS_WALKING_STOP);
break; break;
} }
} }
// Mueve el jugador a la posición y animación que le corresponde // Mueve el jugador a la posición y animación que le corresponde
void Player::move() void Player::move() {
{ if (isAlive()) {
if (isAlive()) // Mueve el jugador a derecha o izquierda
{ posX += velX;
// Mueve el jugador a derecha o izquierda
posX += velX;
// Si el jugador abandona el area de juego por los laterales // Si el jugador abandona el area de juego por los laterales
if ((posX < PLAY_AREA_LEFT - 5) || (posX + width > PLAY_AREA_RIGHT + 5)) if ((posX < PLAY_AREA_LEFT - 5) || (posX + width > PLAY_AREA_RIGHT + 5)) { // Restaura su posición
{ // Restaura su posición posX -= velX;
posX -= velX; }
}
// Actualiza la posición del sprite // Actualiza la posición del sprite
legsSprite->setPosX(getPosX()); legsSprite->setPosX(getPosX());
legsSprite->setPosY(posY); legsSprite->setPosY(posY);
bodySprite->setPosX(getPosX()); bodySprite->setPosX(getPosX());
bodySprite->setPosY(posY); bodySprite->setPosY(posY);
headSprite->setPosX(getPosX()); headSprite->setPosX(getPosX());
headSprite->setPosY(posY); headSprite->setPosY(posY);
fireSprite->setPosX(getPosX() - 2); fireSprite->setPosX(getPosX() - 2);
fireSprite->setPosY(posY - 8); fireSprite->setPosY(posY - 8);
} } else {
else deathSprite->update();
{
deathSprite->update();
// Si el cadaver abandona el area de juego por los laterales // Si el cadaver abandona el area de juego por los laterales
if ((deathSprite->getPosX() < PLAY_AREA_LEFT) || (deathSprite->getPosX() + width > PLAY_AREA_RIGHT)) if ((deathSprite->getPosX() < PLAY_AREA_LEFT) || (deathSprite->getPosX() + width > PLAY_AREA_RIGHT)) { // Restaura su posición
{ // Restaura su posición const float vx = deathSprite->getVelX();
const float vx = deathSprite->getVelX(); deathSprite->setPosX(deathSprite->getPosX() - vx);
deathSprite->setPosX(deathSprite->getPosX() - vx);
// Rebota // Rebota
deathSprite->setVelX(-vx); deathSprite->setVelX(-vx);
} }
} }
} }
// Pinta el jugador en pantalla // Pinta el jugador en pantalla
void Player::render() void Player::render() {
{ if (isAlive()) {
if (isAlive()) if (invulnerable) {
{ if ((invulnerableCounter % 10) > 4) {
if (invulnerable) if (powerUp) {
{ fireSprite->render();
if ((invulnerableCounter % 10) > 4) }
{ legsSprite->render();
if (powerUp) bodySprite->render();
{ headSprite->render();
fireSprite->render(); }
} } else {
legsSprite->render(); if (powerUp) {
bodySprite->render(); fireSprite->render();
headSprite->render(); }
} legsSprite->render();
} bodySprite->render();
else headSprite->render();
{ }
if (powerUp) } else {
{ deathSprite->render();
fireSprite->render(); }
}
legsSprite->render();
bodySprite->render();
headSprite->render();
}
}
else
{
deathSprite->render();
}
} }
// Establece el estado del jugador cuando camina // Establece el estado del jugador cuando camina
void Player::setWalkingStatus(Uint8 status) void Player::setWalkingStatus(Uint8 status) {
{ // Si cambiamos de estado, reiniciamos la animación
// Si cambiamos de estado, reiniciamos la animación if (statusWalking != status) {
if (statusWalking != status) statusWalking = status;
{ // legsSprite->setCurrentFrame(0);
statusWalking = status; }
// legsSprite->setCurrentFrame(0);
}
} }
// Establece el estado del jugador cuando dispara // Establece el estado del jugador cuando dispara
void Player::setFiringStatus(Uint8 status) void Player::setFiringStatus(Uint8 status) {
{ // Si cambiamos de estado, reiniciamos la animación
// Si cambiamos de estado, reiniciamos la animación if (statusFiring != status) {
if (statusFiring != status) statusFiring = status;
{ }
statusFiring = status;
}
} }
// Establece la animación correspondiente al estado // Establece la animación correspondiente al estado
void Player::setAnimation() void Player::setAnimation() {
{ // Crea cadenas de texto para componer el nombre de la animación
// Crea cadenas de texto para componer el nombre de la animación std::string aBodyCoffees = "";
std::string aBodyCoffees = ""; std::string aHeadCoffees = "";
std::string aHeadCoffees = ""; if (coffees > 0) {
if (coffees > 0) aBodyCoffees = coffees == 1 ? "_1C" : "_2C";
{ aHeadCoffees = "_1C";
aBodyCoffees = coffees == 1 ? "_1C" : "_2C"; }
aHeadCoffees = "_1C";
}
const std::string aPowerUp = powerUp ? "_pwr" : ""; const std::string aPowerUp = powerUp ? "_pwr" : "";
const std::string aWalking = statusWalking == PLAYER_STATUS_WALKING_STOP ? "stand" : "walk"; const std::string aWalking = statusWalking == PLAYER_STATUS_WALKING_STOP ? "stand" : "walk";
const std::string aFiring = statusFiring == PLAYER_STATUS_FIRING_UP ? "centershoot" : "sideshoot"; const std::string aFiring = statusFiring == PLAYER_STATUS_FIRING_UP ? "centershoot" : "sideshoot";
const SDL_FlipMode flipWalk = statusWalking == PLAYER_STATUS_WALKING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; const SDL_FlipMode flipWalk = statusWalking == PLAYER_STATUS_WALKING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
const SDL_FlipMode flipFire = statusFiring == PLAYER_STATUS_FIRING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; const SDL_FlipMode flipFire = statusFiring == PLAYER_STATUS_FIRING_RIGHT ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
// Establece la animación a partir de las cadenas // Establece la animación a partir de las cadenas
legsSprite->setCurrentAnimation(aWalking); legsSprite->setCurrentAnimation(aWalking);
legsSprite->setFlip(flipWalk); legsSprite->setFlip(flipWalk);
if (statusFiring == PLAYER_STATUS_FIRING_NO) if (statusFiring == PLAYER_STATUS_FIRING_NO) { // No esta disparando
{ // No esta disparando bodySprite->setCurrentAnimation(aWalking + aBodyCoffees + aPowerUp);
bodySprite->setCurrentAnimation(aWalking + aBodyCoffees + aPowerUp); bodySprite->setFlip(flipWalk);
bodySprite->setFlip(flipWalk); headSprite->setCurrentAnimation(aWalking + aHeadCoffees + aPowerUp);
headSprite->setCurrentAnimation(aWalking + aHeadCoffees + aPowerUp); headSprite->setFlip(flipWalk);
headSprite->setFlip(flipWalk); } else { // Está disparando
} bodySprite->setCurrentAnimation(aFiring + aBodyCoffees + aPowerUp);
else bodySprite->setFlip(flipFire);
{ // Está disparando headSprite->setCurrentAnimation(aFiring + aHeadCoffees + aPowerUp);
bodySprite->setCurrentAnimation(aFiring + aBodyCoffees + aPowerUp); headSprite->setFlip(flipFire);
bodySprite->setFlip(flipFire); }
headSprite->setCurrentAnimation(aFiring + aHeadCoffees + aPowerUp);
headSprite->setFlip(flipFire);
}
// Actualiza las animaciones de los sprites // Actualiza las animaciones de los sprites
legsSprite->animate(); legsSprite->animate();
bodySprite->animate(); bodySprite->animate();
headSprite->animate(); headSprite->animate();
fireSprite->animate(); fireSprite->animate();
fireSprite->setFlip(flipWalk); fireSprite->setFlip(flipWalk);
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Player::getPosX() int Player::getPosX() {
{ return int(posX);
return int(posX);
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Player::getPosY() int Player::getPosY() {
{ return posY;
return posY;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Player::getWidth() int Player::getWidth() {
{ return width;
return width;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Player::getHeight() int Player::getHeight() {
{ return height;
return height;
} }
// Indica si el jugador puede disparar // Indica si el jugador puede disparar
bool Player::canFire() bool Player::canFire() {
{ // Si el contador a llegado a cero, podemos disparar. En caso contrario decrementamos el contador
// Si el contador a llegado a cero, podemos disparar. En caso contrario decrementamos el contador if (cooldown > 0) {
if (cooldown > 0) return false;
{ } else {
return false; return true;
} }
else
{
return true;
}
} }
// Establece el valor de la variable // Establece el valor de la variable
void Player::setFireCooldown(int time) void Player::setFireCooldown(int time) {
{ cooldown = time;
cooldown = time;
} }
// Actualiza el valor de la variable // Actualiza el valor de la variable
void Player::updateCooldown() void Player::updateCooldown() {
{ if (cooldown > 0) {
if (cooldown > 0) cooldown--;
{ if (powerUp) {
cooldown--; cooldown--;
if (powerUp) }
{ } else {
cooldown--; setFiringStatus(PLAYER_STATUS_FIRING_NO);
} }
}
else
{
setFiringStatus(PLAYER_STATUS_FIRING_NO);
}
} }
// Actualiza al jugador a su posicion, animación y controla los contadores // Actualiza al jugador a su posicion, animación y controla los contadores
void Player::update() void Player::update() {
{ move();
move(); setAnimation();
setAnimation(); shiftColliders();
shiftColliders(); updateCooldown();
updateCooldown(); updatePowerUpCounter();
updatePowerUpCounter(); updateInvulnerableCounter();
updateInvulnerableCounter(); updateDeathCounter();
updateDeathCounter(); updatePowerUpHeadOffset();
updatePowerUpHeadOffset();
} }
// Obtiene la puntuación del jugador // Obtiene la puntuación del jugador
Uint32 Player::getScore() Uint32 Player::getScore() {
{ return score;
return score;
} }
// Asigna un valor a la puntuación del jugador // Asigna un valor a la puntuación del jugador
void Player::setScore(Uint32 score) void Player::setScore(Uint32 score) {
{ this->score = score;
this->score = score;
} }
// Incrementa la puntuación del jugador // Incrementa la puntuación del jugador
void Player::addScore(Uint32 score) void Player::addScore(Uint32 score) {
{ this->score += score;
this->score += score;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool Player::isAlive() bool Player::isAlive() {
{ return alive;
return alive;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Player::setAlive(bool value) void Player::setAlive(bool value) {
{ alive = value;
alive = value;
if (!value) if (!value) {
{ deathSprite->setPosX(headSprite->getRect().x);
deathSprite->setPosX(headSprite->getRect().x); deathSprite->setPosY(headSprite->getRect().y);
deathSprite->setPosY(headSprite->getRect().y); deathSprite->setAccelY(0.2f);
deathSprite->setAccelY(0.2f); deathSprite->setVelY(-6.6f);
deathSprite->setVelY(-6.6f); deathSprite->setVelX(3.3f);
deathSprite->setVelX(3.3f); if (rand() % 2 == 0) {
if (rand() % 2 == 0) deathSprite->setVelX(-3.3f);
{ }
deathSprite->setVelX(-3.3f); }
}
}
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float Player::getScoreMultiplier() float Player::getScoreMultiplier() {
{ return scoreMultiplier;
return scoreMultiplier;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Player::setScoreMultiplier(float value) void Player::setScoreMultiplier(float value) {
{ scoreMultiplier = value;
scoreMultiplier = value;
} }
// Aumenta el valor de la variable hasta un máximo // Aumenta el valor de la variable hasta un máximo
void Player::incScoreMultiplier() void Player::incScoreMultiplier() {
{ if (scoreMultiplier < 5.0f) {
if (scoreMultiplier < 5.0f) scoreMultiplier += 0.1f;
{ } else {
scoreMultiplier += 0.1f; scoreMultiplier = 5.0f;
} }
else
{
scoreMultiplier = 5.0f;
}
} }
// Decrementa el valor de la variable hasta un mínimo // Decrementa el valor de la variable hasta un mínimo
void Player::decScoreMultiplier() void Player::decScoreMultiplier() {
{ if (scoreMultiplier > 1.0f) {
if (scoreMultiplier > 1.0f) scoreMultiplier -= 0.1f;
{ } else {
scoreMultiplier -= 0.1f; scoreMultiplier = 1.0f;
} }
else
{
scoreMultiplier = 1.0f;
}
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool Player::isInvulnerable() bool Player::isInvulnerable() {
{ return invulnerable;
return invulnerable;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Player::setInvulnerable(bool value) void Player::setInvulnerable(bool value) {
{ invulnerable = value;
invulnerable = value;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 Player::getInvulnerableCounter() Uint16 Player::getInvulnerableCounter() {
{ return invulnerableCounter;
return invulnerableCounter;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Player::setInvulnerableCounter(Uint16 value) void Player::setInvulnerableCounter(Uint16 value) {
{ invulnerableCounter = value;
invulnerableCounter = value;
} }
// Actualiza el valor de la variable // Actualiza el valor de la variable
void Player::updateInvulnerableCounter() void Player::updateInvulnerableCounter() {
{ if (invulnerable) {
if (invulnerable) if (invulnerableCounter > 0) {
{ invulnerableCounter--;
if (invulnerableCounter > 0) } else {
{ invulnerable = false;
invulnerableCounter--; invulnerableCounter = PLAYER_INVULNERABLE_COUNTER;
} }
else }
{
invulnerable = false;
invulnerableCounter = PLAYER_INVULNERABLE_COUNTER;
}
}
} }
// Actualiza el valor de la variable // Actualiza el valor de la variable
void Player::updateDeathCounter() void Player::updateDeathCounter() {
{ if (!alive) {
if (!alive) if (deathCounter > 0) {
{ deathCounter--;
if (deathCounter > 0) }
{ }
deathCounter--;
}
}
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool Player::isPowerUp() bool Player::isPowerUp() {
{ return powerUp;
return powerUp;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Player::setPowerUp(bool value) void Player::setPowerUp(bool value) {
{ powerUp = value;
powerUp = value;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 Player::getPowerUpCounter() Uint16 Player::getPowerUpCounter() {
{ return powerUpCounter;
return powerUpCounter;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Player::setPowerUpCounter(Uint16 value) void Player::setPowerUpCounter(Uint16 value) {
{ powerUpCounter = value;
powerUpCounter = value;
} }
// Actualiza el valor de la variable // Actualiza el valor de la variable
void Player::updatePowerUpCounter() void Player::updatePowerUpCounter() {
{ if ((powerUpCounter > 0) && (powerUp)) {
if ((powerUpCounter > 0) && (powerUp)) powerUpCounter--;
{ } else {
powerUpCounter--; powerUp = false;
} powerUpCounter = PLAYER_POWERUP_COUNTER;
else }
{
powerUp = false;
powerUpCounter = PLAYER_POWERUP_COUNTER;
}
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool Player::hasExtraHit() bool Player::hasExtraHit() {
{ return extraHit;
return extraHit;
} }
// Concede un toque extra al jugador // Concede un toque extra al jugador
void Player::giveExtraHit() void Player::giveExtraHit() {
{ extraHit = true;
extraHit = true; coffees++;
coffees++; if (coffees > 2) {
if (coffees > 2) coffees = 2;
{ }
coffees = 2;
}
} }
// Quita el toque extra al jugador // Quita el toque extra al jugador
void Player::removeExtraHit() void Player::removeExtraHit() {
{ if (coffees > 0) {
if (coffees > 0) coffees--;
{ }
coffees--; if (coffees == 0) {
} extraHit = false;
if (coffees == 0) }
{ invulnerable = true;
extraHit = false; invulnerableCounter = PLAYER_INVULNERABLE_COUNTER;
}
invulnerable = true;
invulnerableCounter = PLAYER_INVULNERABLE_COUNTER;
} }
// Habilita la entrada de ordenes // Habilita la entrada de ordenes
void Player::enableInput() void Player::enableInput() {
{ input = true;
input = true;
} }
// Deshabilita la entrada de ordenes // Deshabilita la entrada de ordenes
void Player::disableInput() void Player::disableInput() {
{ input = false;
input = false;
} }
// Devuelve el numero de cafes actuales // Devuelve el numero de cafes actuales
Uint8 Player::getCoffees() Uint8 Player::getCoffees() {
{ return coffees;
return coffees;
} }
// Obtiene el circulo de colisión // Obtiene el circulo de colisión
circle_t &Player::getCollider() circle_t &Player::getCollider() {
{ return collider;
return collider;
} }
// Actualiza el circulo de colisión a la posición del jugador // Actualiza el circulo de colisión a la posición del jugador
void Player::shiftColliders() void Player::shiftColliders() {
{ collider.x = int(posX + (width / 2));
collider.x = int(posX + (width / 2)); collider.y = int(posY + (height / 2));
collider.y = int(posY + (height / 2));
} }
// Obtiene el puntero a la textura con los gráficos de la animación de morir // Obtiene el puntero a la textura con los gráficos de la animación de morir
Texture *Player::getDeadTexture() Texture *Player::getDeadTexture() {
{ return deathSprite->getTexture();
return deathSprite->getTexture(); ;
;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 Player::getDeathCounter() Uint16 Player::getDeathCounter() {
{ return deathCounter;
return deathCounter;
} }
// Actualiza el valor de la variable // Actualiza el valor de la variable
void Player::updatePowerUpHeadOffset() void Player::updatePowerUpHeadOffset() {
{ if (!powerUp) {
if (!powerUp) // powerUpHeadOffset = 0;
{ } else {
// powerUpHeadOffset = 0; // powerUpHeadOffset = 96;
} if (powerUpCounter < 300) {
else if (powerUpCounter % 10 > 4) {
{ // powerUpHeadOffset = 96;
// powerUpHeadOffset = 96; fireSprite->setEnabled(false);
if (powerUpCounter < 300) } else {
{ // powerUpHeadOffset = 0;
if (powerUpCounter % 10 > 4) fireSprite->setEnabled(true);
{ }
// powerUpHeadOffset = 96; }
fireSprite->setEnabled(false); }
}
else
{
// powerUpHeadOffset = 0;
fireSprite->setEnabled(true);
}
}
}
} }
// Pone las texturas del jugador // Pone las texturas del jugador
void Player::setPlayerTextures(std::vector<Texture *> texture) void Player::setPlayerTextures(std::vector<Texture *> texture) {
{ headSprite->setTexture(texture[0]);
headSprite->setTexture(texture[0]); bodySprite->setTexture(texture[1]);
bodySprite->setTexture(texture[1]); legsSprite->setTexture(texture[2]);
legsSprite->setTexture(texture[2]); deathSprite->setTexture(texture[3]);
deathSprite->setTexture(texture[3]); fireSprite->setTexture(texture[4]);
fireSprite->setTexture(texture[4]);
} }

View File

@@ -1,9 +1,11 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string
#include <vector> // for vector #include <string> // for string
#include "utils.h" // for circle_t #include <vector> // for vector
#include "utils.h" // for circle_t
class AnimatedSprite; class AnimatedSprite;
class Texture; class Texture;
@@ -25,192 +27,191 @@ constexpr int PLAYER_INVULNERABLE_COUNTER = 200;
constexpr int PLAYER_POWERUP_COUNTER = 1500; constexpr int PLAYER_POWERUP_COUNTER = 1500;
// Clase Player // Clase Player
class Player class Player {
{ private:
private: // Objetos y punteros
// Objetos y punteros SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Renderer *renderer; // El renderizador de la ventana AnimatedSprite *headSprite; // Sprite para dibujar la cabeza
AnimatedSprite *headSprite; // Sprite para dibujar la cabeza AnimatedSprite *bodySprite; // Sprite para dibujar el cuerpo
AnimatedSprite *bodySprite; // Sprite para dibujar el cuerpo AnimatedSprite *legsSprite; // Sprite para dibujar las piernas
AnimatedSprite *legsSprite; // Sprite para dibujar las piernas AnimatedSprite *deathSprite; // Sprite para dibujar el jugador derrotado
AnimatedSprite *deathSprite; // Sprite para dibujar el jugador derrotado AnimatedSprite *fireSprite; // Sprite para dibujar el aura del jugador con el poder a tope
AnimatedSprite *fireSprite; // Sprite para dibujar el aura del jugador con el poder a tope
// Variables // Variables
float posX; // Posicion en el eje X float posX; // Posicion en el eje X
int posY; // Posicion en el eje Y int posY; // Posicion en el eje Y
Uint8 width; // Anchura Uint8 width; // Anchura
Uint8 height; // Altura Uint8 height; // Altura
float velX; // Cantidad de pixeles a desplazarse en el eje X float velX; // Cantidad de pixeles a desplazarse en el eje X
int velY; // Cantidad de pixeles a desplazarse en el eje Y int velY; // Cantidad de pixeles a desplazarse en el eje Y
float baseSpeed; // Velocidad base del jugador float baseSpeed; // Velocidad base del jugador
int cooldown; // Contador durante el cual no puede disparar int cooldown; // Contador durante el cual no puede disparar
Uint32 score; // Puntos del jugador Uint32 score; // Puntos del jugador
float scoreMultiplier; // Multiplicador de puntos float scoreMultiplier; // Multiplicador de puntos
Uint8 statusWalking; // Estado del jugador Uint8 statusWalking; // Estado del jugador
Uint8 statusFiring; // Estado del jugador Uint8 statusFiring; // Estado del jugador
bool alive; // Indica si el jugador está vivo bool alive; // Indica si el jugador está vivo
Uint16 deathCounter; // Contador para la animación de morirse Uint16 deathCounter; // Contador para la animación de morirse
bool invulnerable; // Indica si el jugador es invulnerable bool invulnerable; // Indica si el jugador es invulnerable
Uint16 invulnerableCounter; // Contador para la invulnerabilidad Uint16 invulnerableCounter; // Contador para la invulnerabilidad
bool extraHit; // Indica si el jugador tiene un toque extra bool extraHit; // Indica si el jugador tiene un toque extra
Uint8 coffees; // Indica cuantos cafes lleva acumulados Uint8 coffees; // Indica cuantos cafes lleva acumulados
bool powerUp; // Indica si el jugador tiene activo el modo PowerUp bool powerUp; // Indica si el jugador tiene activo el modo PowerUp
Uint16 powerUpCounter; // Temporizador para el modo PowerUp Uint16 powerUpCounter; // Temporizador para el modo PowerUp
bool input; // Indica si puede recibir ordenes de entrada bool input; // Indica si puede recibir ordenes de entrada
circle_t collider; // Circulo de colisión del jugador circle_t collider; // Circulo de colisión del jugador
// Actualiza el circulo de colisión a la posición del jugador // Actualiza el circulo de colisión a la posición del jugador
void shiftColliders(); void shiftColliders();
// Actualiza el valor de la variable // Actualiza el valor de la variable
void updateInvulnerableCounter(); void updateInvulnerableCounter();
// Actualiza el valor de la variable // Actualiza el valor de la variable
void updateDeathCounter(); void updateDeathCounter();
// Actualiza el valor de la variable // Actualiza el valor de la variable
void updatePowerUpHeadOffset(); void updatePowerUpHeadOffset();
public: public:
// Constructor // Constructor
Player(float x, int y, SDL_Renderer *renderer, std::vector<Texture *> texture, std::vector<std::vector<std::string> *> animations); Player(float x, int y, SDL_Renderer *renderer, std::vector<Texture *> texture, std::vector<std::vector<std::string> *> animations);
// Destructor // Destructor
~Player(); ~Player();
// Iniciador // Iniciador
void init(); void init();
// Actualiza al jugador a su posicion, animación y controla los contadores // Actualiza al jugador a su posicion, animación y controla los contadores
void update(); void update();
// Pinta el jugador en pantalla // Pinta el jugador en pantalla
void render(); void render();
// Pone las texturas del jugador // Pone las texturas del jugador
void setPlayerTextures(std::vector<Texture *> texture); void setPlayerTextures(std::vector<Texture *> texture);
// Actua en consecuencia de la entrada recibida // Actua en consecuencia de la entrada recibida
void setInput(Uint8 input); void setInput(Uint8 input);
// Mueve el jugador a la posición y animación que le corresponde // Mueve el jugador a la posición y animación que le corresponde
void move(); void move();
// Establece el estado del jugador // Establece el estado del jugador
void setWalkingStatus(Uint8 status); void setWalkingStatus(Uint8 status);
// Establece el estado del jugador // Establece el estado del jugador
void setFiringStatus(Uint8 status); void setFiringStatus(Uint8 status);
// Establece la animación correspondiente al estado // Establece la animación correspondiente al estado
void setAnimation(); void setAnimation();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getPosX(); int getPosX();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getPosY(); int getPosY();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getWidth(); int getWidth();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getHeight(); int getHeight();
// Indica si el jugador puede disparar // Indica si el jugador puede disparar
bool canFire(); bool canFire();
// Establece el valor de la variable // Establece el valor de la variable
void setFireCooldown(int time); void setFireCooldown(int time);
// Actualiza el valor de la variable // Actualiza el valor de la variable
void updateCooldown(); void updateCooldown();
// Obtiene la puntuación del jugador // Obtiene la puntuación del jugador
Uint32 getScore(); Uint32 getScore();
// Asigna un valor a la puntuación del jugador // Asigna un valor a la puntuación del jugador
void setScore(Uint32 score); void setScore(Uint32 score);
// Incrementa la puntuación del jugador // Incrementa la puntuación del jugador
void addScore(Uint32 score); void addScore(Uint32 score);
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool isAlive(); bool isAlive();
// Establece el valor de la variable // Establece el valor de la variable
void setAlive(bool value); void setAlive(bool value);
// Obtiene el valor de la variable // Obtiene el valor de la variable
float getScoreMultiplier(); float getScoreMultiplier();
// Establece el valor de la variable // Establece el valor de la variable
void setScoreMultiplier(float value); void setScoreMultiplier(float value);
// Aumenta el valor de la variable hasta un máximo // Aumenta el valor de la variable hasta un máximo
void incScoreMultiplier(); void incScoreMultiplier();
// Decrementa el valor de la variable hasta un mínimo // Decrementa el valor de la variable hasta un mínimo
void decScoreMultiplier(); void decScoreMultiplier();
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool isInvulnerable(); bool isInvulnerable();
// Establece el valor de la variable // Establece el valor de la variable
void setInvulnerable(bool value); void setInvulnerable(bool value);
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 getInvulnerableCounter(); Uint16 getInvulnerableCounter();
// Establece el valor de la variable // Establece el valor de la variable
void setInvulnerableCounter(Uint16 value); void setInvulnerableCounter(Uint16 value);
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool isPowerUp(); bool isPowerUp();
// Establece el valor de la variable // Establece el valor de la variable
void setPowerUp(bool value); void setPowerUp(bool value);
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 getPowerUpCounter(); Uint16 getPowerUpCounter();
// Establece el valor de la variable // Establece el valor de la variable
void setPowerUpCounter(Uint16 value); void setPowerUpCounter(Uint16 value);
// Actualiza el valor de la variable // Actualiza el valor de la variable
void updatePowerUpCounter(); void updatePowerUpCounter();
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool hasExtraHit(); bool hasExtraHit();
// Concede un toque extra al jugador // Concede un toque extra al jugador
void giveExtraHit(); void giveExtraHit();
// Quita el toque extra al jugador // Quita el toque extra al jugador
void removeExtraHit(); void removeExtraHit();
// Habilita la entrada de ordenes // Habilita la entrada de ordenes
void enableInput(); void enableInput();
// Deshabilita la entrada de ordenes // Deshabilita la entrada de ordenes
void disableInput(); void disableInput();
// Devuelve el numero de cafes actuales // Devuelve el numero de cafes actuales
Uint8 getCoffees(); Uint8 getCoffees();
// Obtiene el circulo de colisión // Obtiene el circulo de colisión
circle_t &getCollider(); circle_t &getCollider();
// Obtiene el puntero a la textura con los gráficos de la animación de morir // Obtiene el puntero a la textura con los gráficos de la animación de morir
Texture *getDeadTexture(); Texture *getDeadTexture();
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 getDeathCounter(); Uint16 getDeathCounter();
}; };

View File

@@ -1,13 +1,14 @@
#include "screen.h" #include "screen.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <algorithm> // for max, min
#include <iostream> // for basic_ostream, operator<<, cout, endl #include <algorithm> // for max, min
#include <string> // for basic_string, char_traits, string #include <iostream> // for basic_ostream, operator<<, cout, endl
#include <string> // for basic_string, char_traits, string
class Asset; class Asset;
// Constructor // Constructor
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options) Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options) {
{
// Inicializa variables // Inicializa variables
this->window = window; this->window = window;
this->renderer = renderer; this->renderer = renderer;
@@ -29,14 +30,11 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options
// Crea la textura donde se dibujan los graficos del juego // Crea la textura donde se dibujan los graficos del juego
gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight); gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight);
if (gameCanvas != nullptr) if (gameCanvas != nullptr) {
{
SDL_SetTextureScaleMode(gameCanvas, options->filter == FILTER_NEAREST ? SDL_SCALEMODE_NEAREST : SDL_SCALEMODE_LINEAR); SDL_SetTextureScaleMode(gameCanvas, options->filter == FILTER_NEAREST ? SDL_SCALEMODE_NEAREST : SDL_SCALEMODE_LINEAR);
} }
if (gameCanvas == nullptr) if (gameCanvas == nullptr) {
{ if (options->console) {
if (options->console)
{
std::cout << "TitleSurface could not be created!\nSDL Error: " << SDL_GetError() << std::endl; std::cout << "TitleSurface could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
} }
} }
@@ -49,27 +47,23 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options
} }
// Destructor // Destructor
Screen::~Screen() Screen::~Screen() {
{
SDL_DestroyTexture(gameCanvas); SDL_DestroyTexture(gameCanvas);
} }
// Limpia la pantalla // Limpia la pantalla
void Screen::clean(color_t color) void Screen::clean(color_t color) {
{
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
} }
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
void Screen::start() void Screen::start() {
{
SDL_SetRenderTarget(renderer, gameCanvas); SDL_SetRenderTarget(renderer, gameCanvas);
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
void Screen::blit() void Screen::blit() {
{
// Vuelve a dejar el renderizador en modo normal // Vuelve a dejar el renderizador en modo normal
SDL_SetRenderTarget(renderer, nullptr); SDL_SetRenderTarget(renderer, nullptr);
@@ -86,29 +80,25 @@ void Screen::blit()
} }
// Establece el modo de video // Establece el modo de video
void Screen::setVideoMode(int videoMode) void Screen::setVideoMode(int videoMode) {
{
// Aplica el modo de video // Aplica el modo de video
SDL_SetWindowFullscreen(window, videoMode != 0); SDL_SetWindowFullscreen(window, videoMode != 0);
// Si está activo el modo ventana quita el borde // Si está activo el modo ventana quita el borde
if (videoMode == 0) if (videoMode == 0) {
{
// Muestra el puntero // Muestra el puntero
SDL_ShowCursor(); SDL_ShowCursor();
// Esconde la ventana // Esconde la ventana
//SDL_HideWindow(window); // SDL_HideWindow(window);
if (options->borderEnabled) if (options->borderEnabled) {
{
windowWidth = gameCanvasWidth + borderWidth; windowWidth = gameCanvasWidth + borderWidth;
windowHeight = gameCanvasHeight + borderHeight; windowHeight = gameCanvasHeight + borderHeight;
dest = {0 + (borderWidth / 2), 0 + (borderHeight / 2), gameCanvasWidth, gameCanvasHeight}; dest = {0 + (borderWidth / 2), 0 + (borderHeight / 2), gameCanvasWidth, gameCanvasHeight};
} }
else else {
{
windowWidth = gameCanvasWidth; windowWidth = gameCanvasWidth;
windowHeight = gameCanvasHeight; windowHeight = gameCanvasHeight;
dest = {0, 0, gameCanvasWidth, gameCanvasHeight}; dest = {0, 0, gameCanvasWidth, gameCanvasHeight};
@@ -119,12 +109,11 @@ void Screen::setVideoMode(int videoMode)
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
// Muestra la ventana // Muestra la ventana
//SDL_ShowWindow(window); // SDL_ShowWindow(window);
} }
// Si está activo el modo de pantalla completa añade el borde // Si está activo el modo de pantalla completa añade el borde
else if (videoMode == SDL_WINDOW_FULLSCREEN) else if (videoMode == SDL_WINDOW_FULLSCREEN) {
{
// Oculta el puntero // Oculta el puntero
SDL_HideCursor(); SDL_HideCursor();
@@ -132,12 +121,10 @@ void Screen::setVideoMode(int videoMode)
SDL_GetWindowSize(window, &windowWidth, &windowHeight); SDL_GetWindowSize(window, &windowWidth, &windowHeight);
// Aplica el escalado al rectangulo donde se pinta la textura del juego // Aplica el escalado al rectangulo donde se pinta la textura del juego
if (options->integerScale) if (options->integerScale) {
{
// Calcula el tamaño de la escala máxima // Calcula el tamaño de la escala máxima
int scale = 0; int scale = 0;
while (((gameCanvasWidth * (scale + 1)) <= windowWidth) && ((gameCanvasHeight * (scale + 1)) <= windowHeight)) while (((gameCanvasWidth * (scale + 1)) <= windowWidth) && ((gameCanvasHeight * (scale + 1)) <= windowHeight)) {
{
scale++; scale++;
} }
@@ -145,27 +132,20 @@ void Screen::setVideoMode(int videoMode)
dest.h = gameCanvasHeight * scale; dest.h = gameCanvasHeight * scale;
dest.x = (windowWidth - dest.w) / 2; dest.x = (windowWidth - dest.w) / 2;
dest.y = (windowHeight - dest.h) / 2; dest.y = (windowHeight - dest.h) / 2;
} } else if (options->keepAspect) {
else if (options->keepAspect)
{
float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight; float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight;
if ((windowWidth - gameCanvasWidth) >= (windowHeight - gameCanvasHeight)) if ((windowWidth - gameCanvasWidth) >= (windowHeight - gameCanvasHeight)) {
{
dest.h = windowHeight; dest.h = windowHeight;
dest.w = (int)((windowHeight * ratio) + 0.5f); dest.w = (int)((windowHeight * ratio) + 0.5f);
dest.x = (windowWidth - dest.w) / 2; dest.x = (windowWidth - dest.w) / 2;
dest.y = (windowHeight - dest.h) / 2; dest.y = (windowHeight - dest.h) / 2;
} } else {
else
{
dest.w = windowWidth; dest.w = windowWidth;
dest.h = (int)((windowWidth / ratio) + 0.5f); dest.h = (int)((windowWidth / ratio) + 0.5f);
dest.x = (windowWidth - dest.w) / 2; dest.x = (windowWidth - dest.w) / 2;
dest.y = (windowHeight - dest.h) / 2; dest.y = (windowHeight - dest.h) / 2;
} }
} } else {
else
{
dest.w = windowWidth; dest.w = windowWidth;
dest.h = windowHeight; dest.h = windowHeight;
dest.x = dest.y = 0; dest.x = dest.y = 0;
@@ -182,83 +162,70 @@ void Screen::setVideoMode(int videoMode)
} }
// Camibia entre pantalla completa y ventana // Camibia entre pantalla completa y ventana
void Screen::switchVideoMode() void Screen::switchVideoMode() {
{
options->videoMode = (options->videoMode == 0) ? SDL_WINDOW_FULLSCREEN : 0; options->videoMode = (options->videoMode == 0) ? SDL_WINDOW_FULLSCREEN : 0;
setVideoMode(options->videoMode); setVideoMode(options->videoMode);
} }
// Cambia el tamaño de la ventana // Cambia el tamaño de la ventana
void Screen::setWindowSize(int size) void Screen::setWindowSize(int size) {
{
options->windowSize = size; options->windowSize = size;
setVideoMode(0); setVideoMode(0);
} }
// Reduce el tamaño de la ventana // Reduce el tamaño de la ventana
void Screen::decWindowSize() void Screen::decWindowSize() {
{
--options->windowSize; --options->windowSize;
options->windowSize = std::max(options->windowSize, 1); options->windowSize = std::max(options->windowSize, 1);
setVideoMode(0); setVideoMode(0);
} }
// Aumenta el tamaño de la ventana // Aumenta el tamaño de la ventana
void Screen::incWindowSize() void Screen::incWindowSize() {
{
++options->windowSize; ++options->windowSize;
options->windowSize = std::min(options->windowSize, 4); options->windowSize = std::min(options->windowSize, 4);
setVideoMode(0); setVideoMode(0);
} }
// Cambia el color del borde // Cambia el color del borde
void Screen::setBorderColor(color_t color) void Screen::setBorderColor(color_t color) {
{
borderColor = color; borderColor = color;
} }
// Cambia el tipo de mezcla // Cambia el tipo de mezcla
void Screen::setBlendMode(SDL_BlendMode blendMode) void Screen::setBlendMode(SDL_BlendMode blendMode) {
{
SDL_SetRenderDrawBlendMode(renderer, blendMode); SDL_SetRenderDrawBlendMode(renderer, blendMode);
} }
// Establece el tamaño del borde // Establece el tamaño del borde
void Screen::setBorderWidth(int s) void Screen::setBorderWidth(int s) {
{
options->borderWidth = s; options->borderWidth = s;
} }
// Establece el tamaño del borde // Establece el tamaño del borde
void Screen::setBorderHeight(int s) void Screen::setBorderHeight(int s) {
{
options->borderHeight = s; options->borderHeight = s;
} }
// Establece si se ha de ver el borde en el modo ventana // Establece si se ha de ver el borde en el modo ventana
void Screen::setBorderEnabled(bool value) void Screen::setBorderEnabled(bool value) {
{
options->borderEnabled = value; options->borderEnabled = value;
} }
// Cambia entre borde visible y no visible // Cambia entre borde visible y no visible
void Screen::switchBorder() void Screen::switchBorder() {
{
options->borderEnabled = !options->borderEnabled; options->borderEnabled = !options->borderEnabled;
setVideoMode(0); setVideoMode(0);
} }
// Activa el fade // Activa el fade
void Screen::setFade() void Screen::setFade() {
{
fade = true; fade = true;
} }
// Comprueba si ha terminado el fade // Comprueba si ha terminado el fade
bool Screen::fadeEnded() bool Screen::fadeEnded() {
{ if (fade || fadeCounter > 0) {
if (fade || fadeCounter > 0)
{
return false; return false;
} }
@@ -266,16 +233,13 @@ bool Screen::fadeEnded()
} }
// Activa el spectrum fade // Activa el spectrum fade
void Screen::setspectrumFade() void Screen::setspectrumFade() {
{
spectrumFade = true; spectrumFade = true;
} }
// Comprueba si ha terminado el spectrum fade // Comprueba si ha terminado el spectrum fade
bool Screen::spectrumFadeEnded() bool Screen::spectrumFadeEnded() {
{ if (spectrumFade || spectrumFadeCounter > 0) {
if (spectrumFade || spectrumFadeCounter > 0)
{
return false; return false;
} }
@@ -283,33 +247,27 @@ bool Screen::spectrumFadeEnded()
} }
// Inicializa las variables para el fade // Inicializa las variables para el fade
void Screen::iniFade() void Screen::iniFade() {
{
fade = false; fade = false;
fadeCounter = 0; fadeCounter = 0;
fadeLenght = 200; fadeLenght = 200;
} }
// Actualiza el fade // Actualiza el fade
void Screen::updateFade() void Screen::updateFade() {
{ if (!fade) {
if (!fade)
{
return; return;
} }
fadeCounter++; fadeCounter++;
if (fadeCounter > fadeLenght) if (fadeCounter > fadeLenght) {
{
iniFade(); iniFade();
} }
} }
// Dibuja el fade // Dibuja el fade
void Screen::renderFade() void Screen::renderFade() {
{ if (!fade) {
if (!fade)
{
return; return;
} }
@@ -322,8 +280,7 @@ void Screen::renderFade()
} }
// Inicializa las variables para el fade spectrum // Inicializa las variables para el fade spectrum
void Screen::iniSpectrumFade() void Screen::iniSpectrumFade() {
{
spectrumFade = false; spectrumFade = false;
spectrumFadeCounter = 0; spectrumFadeCounter = 0;
spectrumFadeLenght = 50; spectrumFadeLenght = 50;
@@ -332,33 +289,27 @@ void Screen::iniSpectrumFade()
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> vColors = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"}; const std::vector<std::string> vColors = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"};
for (auto v : vColors) for (auto v : vColors) {
{
spectrumColor.push_back(stringToColor(options->palette, v)); spectrumColor.push_back(stringToColor(options->palette, v));
} }
} }
// Actualiza el spectrum fade // Actualiza el spectrum fade
void Screen::updateSpectrumFade() void Screen::updateSpectrumFade() {
{ if (!spectrumFade) {
if (!spectrumFade)
{
return; return;
} }
spectrumFadeCounter++; spectrumFadeCounter++;
if (spectrumFadeCounter > spectrumFadeLenght) if (spectrumFadeCounter > spectrumFadeLenght) {
{
iniSpectrumFade(); iniSpectrumFade();
SDL_SetTextureColorMod(gameCanvas, 255, 255, 255); SDL_SetTextureColorMod(gameCanvas, 255, 255, 255);
} }
} }
// Dibuja el spectrum fade // Dibuja el spectrum fade
void Screen::renderSpectrumFade() void Screen::renderSpectrumFade() {
{ if (!spectrumFade) {
if (!spectrumFade)
{
return; return;
} }
@@ -370,15 +321,13 @@ void Screen::renderSpectrumFade()
} }
// Actualiza los efectos // Actualiza los efectos
void Screen::updateFX() void Screen::updateFX() {
{
updateFade(); updateFade();
updateSpectrumFade(); updateSpectrumFade();
} }
// Dibuja los efectos // Dibuja los efectos
void Screen::renderFX() void Screen::renderFX() {
{
renderFade(); renderFade();
renderSpectrumFade(); renderSpectrumFade();
} }

View File

@@ -1,126 +1,127 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <vector> // for vector
#include "utils.h" // for color_t #include <vector> // for vector
#include "utils.h" // for color_t
class Asset; class Asset;
// Tipos de filtro // Tipos de filtro
constexpr int FILTER_NEAREST = 0; constexpr int FILTER_NEAREST = 0;
constexpr int FILTER_LINEAL = 1; constexpr int FILTER_LINEAL = 1;
class Screen class Screen {
{ private:
private: // Objetos y punteros
// Objetos y punteros SDL_Window *window; // Ventana de la aplicación
SDL_Window *window; // Ventana de la aplicación SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Renderer *renderer; // El renderizador de la ventana Asset *asset; // Objeto con el listado de recursos
Asset *asset; // Objeto con el listado de recursos SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa
SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa options_t *options; // Variable con todas las opciones del programa
options_t *options; // Variable con todas las opciones del programa
// Variables // Variables
int windowWidth; // Ancho de la pantalla o ventana int windowWidth; // Ancho de la pantalla o ventana
int windowHeight; // Alto de la pantalla o ventana int windowHeight; // Alto de la pantalla o ventana
int gameCanvasWidth; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego int gameCanvasWidth; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego
int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego
int borderWidth; // Anchura del borde int borderWidth; // Anchura del borde
int borderHeight; // Anltura del borde int borderHeight; // Anltura del borde
SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
bool notifyActive; // Indica si hay notificaciones activas bool notifyActive; // Indica si hay notificaciones activas
int notificationLogicalWidth; // Ancho lógico de las notificaciones en relación al tamaño de pantalla int notificationLogicalWidth; // Ancho lógico de las notificaciones en relación al tamaño de pantalla
int notificationLogicalHeight; // Alto lógico de las notificaciones en relación al tamaño de pantalla int notificationLogicalHeight; // Alto lógico de las notificaciones en relación al tamaño de pantalla
// Variables - Efectos // Variables - Efectos
bool fade; // Indica si esta activo el efecto de fade bool fade; // Indica si esta activo el efecto de fade
int fadeCounter; // Temporizador para el efecto de fade int fadeCounter; // Temporizador para el efecto de fade
int fadeLenght; // Duración del fade int fadeLenght; // Duración del fade
bool spectrumFade; // Indica si esta activo el efecto de fade spectrum bool spectrumFade; // Indica si esta activo el efecto de fade spectrum
int spectrumFadeCounter; // Temporizador para el efecto de fade spectrum int spectrumFadeCounter; // Temporizador para el efecto de fade spectrum
int spectrumFadeLenght; // Duración del fade spectrum int spectrumFadeLenght; // Duración del fade spectrum
std::vector<color_t> spectrumColor; // Colores para el fade spectrum std::vector<color_t> spectrumColor; // Colores para el fade spectrum
// Inicializa las variables para el fade // Inicializa las variables para el fade
void iniFade(); void iniFade();
// Actualiza el fade // Actualiza el fade
void updateFade(); void updateFade();
// Dibuja el fade // Dibuja el fade
void renderFade(); void renderFade();
// Inicializa las variables para el fade spectrum // Inicializa las variables para el fade spectrum
void iniSpectrumFade(); void iniSpectrumFade();
// Actualiza el spectrum fade // Actualiza el spectrum fade
void updateSpectrumFade(); void updateSpectrumFade();
// Dibuja el spectrum fade // Dibuja el spectrum fade
void renderSpectrumFade(); void renderSpectrumFade();
public: public:
// Constructor // Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options); Screen(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, options_t *options);
// Destructor // Destructor
~Screen(); ~Screen();
// Limpia la pantalla // Limpia la pantalla
void clean(color_t color = {0x00, 0x00, 0x00}); void clean(color_t color = {0x00, 0x00, 0x00});
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
void start(); void start();
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
void blit(); void blit();
// Establece el modo de video // Establece el modo de video
void setVideoMode(int videoMode); void setVideoMode(int videoMode);
// Camibia entre pantalla completa y ventana // Camibia entre pantalla completa y ventana
void switchVideoMode(); void switchVideoMode();
// Cambia el tamaño de la ventana // Cambia el tamaño de la ventana
void setWindowSize(int size); void setWindowSize(int size);
// Reduce el tamaño de la ventana // Reduce el tamaño de la ventana
void decWindowSize(); void decWindowSize();
// Aumenta el tamaño de la ventana // Aumenta el tamaño de la ventana
void incWindowSize(); void incWindowSize();
// Cambia el color del borde // Cambia el color del borde
void setBorderColor(color_t color); void setBorderColor(color_t color);
// Cambia el tipo de mezcla // Cambia el tipo de mezcla
void setBlendMode(SDL_BlendMode blendMode); void setBlendMode(SDL_BlendMode blendMode);
// Establece el tamaño del borde // Establece el tamaño del borde
void setBorderWidth(int s); void setBorderWidth(int s);
void setBorderHeight(int s); void setBorderHeight(int s);
// Establece si se ha de ver el borde en el modo ventana // Establece si se ha de ver el borde en el modo ventana
void setBorderEnabled(bool value); void setBorderEnabled(bool value);
// Cambia entre borde visible y no visible // Cambia entre borde visible y no visible
void switchBorder(); void switchBorder();
// Activa el fade // Activa el fade
void setFade(); void setFade();
// Comprueba si ha terminado el fade // Comprueba si ha terminado el fade
bool fadeEnded(); bool fadeEnded();
// Activa el spectrum fade // Activa el spectrum fade
void setspectrumFade(); void setspectrumFade();
// Comprueba si ha terminado el spectrum fade // Comprueba si ha terminado el spectrum fade
bool spectrumFadeEnded(); bool spectrumFadeEnded();
// Actualiza los efectos // Actualiza los efectos
void updateFX(); void updateFX();
// Dibuja los efectos // Dibuja los efectos
void renderFX(); void renderFX();
}; };

View File

@@ -1,193 +1,164 @@
#include "smartsprite.h" #include "smartsprite.h"
#include "movingsprite.h" // for MovingSprite #include "movingsprite.h" // for MovingSprite
class Texture; class Texture;
// Constructor // Constructor
SmartSprite::SmartSprite(Texture *texture, SDL_Renderer *renderer) SmartSprite::SmartSprite(Texture *texture, SDL_Renderer *renderer) {
{ // Copia punteros
// Copia punteros setTexture(texture);
setTexture(texture); setRenderer(renderer);
setRenderer(renderer);
// Inicializa el objeto // Inicializa el objeto
init(); init();
} }
// Inicializa el objeto // Inicializa el objeto
void SmartSprite::init() void SmartSprite::init() {
{ enabled = false;
enabled = false; enabledCounter = 0;
enabledCounter = 0; onDestination = false;
onDestination = false; destX = 0;
destX = 0; destY = 0;
destY = 0; counter = 0;
counter = 0; finished = false;
finished = false;
} }
// Actualiza la posición y comprueba si ha llegado a su destino // Actualiza la posición y comprueba si ha llegado a su destino
void SmartSprite::update() void SmartSprite::update() {
{ if (enabled) {
if (enabled) // Actualiza las variables internas del objeto
{ MovingSprite::update();
// Actualiza las variables internas del objeto
MovingSprite::update();
// Comprueba el movimiento // Comprueba el movimiento
checkMove(); checkMove();
// Comprueba si ha terminado // Comprueba si ha terminado
checkFinished(); checkFinished();
} }
} }
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void SmartSprite::render() void SmartSprite::render() {
{ if (enabled) {
if (enabled) // Muestra el sprite por pantalla
{ MovingSprite::render();
// Muestra el sprite por pantalla }
MovingSprite::render();
}
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool SmartSprite::isEnabled() bool SmartSprite::isEnabled() {
{ return enabled;
return enabled;
} }
// Establece el valor de la variable // Establece el valor de la variable
void SmartSprite::setEnabled(bool enabled) void SmartSprite::setEnabled(bool enabled) {
{ this->enabled = enabled;
this->enabled = enabled;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int SmartSprite::getEnabledCounter() int SmartSprite::getEnabledCounter() {
{ return enabledCounter;
return enabledCounter;
} }
// Establece el valor de la variable // Establece el valor de la variable
void SmartSprite::setEnabledCounter(int value) void SmartSprite::setEnabledCounter(int value) {
{ enabledCounter = value;
enabledCounter = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void SmartSprite::setDestX(int x) void SmartSprite::setDestX(int x) {
{ destX = x;
destX = x;
} }
// Establece el valor de la variable // Establece el valor de la variable
void SmartSprite::setDestY(int y) void SmartSprite::setDestY(int y) {
{ destY = y;
destY = y;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int SmartSprite::getDestX() int SmartSprite::getDestX() {
{ return destX;
return destX;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int SmartSprite::getDestY() int SmartSprite::getDestY() {
{ return destY;
return destY;
} }
// Comprueba el movimiento // Comprueba el movimiento
void SmartSprite::checkMove() void SmartSprite::checkMove() {
{ // Comprueba si se desplaza en el eje X hacia la derecha
// Comprueba si se desplaza en el eje X hacia la derecha if (getAccelX() > 0 || getVelX() > 0) {
if (getAccelX() > 0 || getVelX() > 0) // Comprueba si ha llegado al destino
{ if (getPosX() > destX) {
// Comprueba si ha llegado al destino // Lo coloca en posición
if (getPosX() > destX) setPosX(destX);
{
// Lo coloca en posición
setPosX(destX);
// Lo detiene // Lo detiene
setVelX(0.0f); setVelX(0.0f);
setAccelX(0.0f); setAccelX(0.0f);
} }
} }
// Comprueba si se desplaza en el eje X hacia la izquierda // Comprueba si se desplaza en el eje X hacia la izquierda
else if (getAccelX() < 0 || getVelX() < 0) else if (getAccelX() < 0 || getVelX() < 0) {
{ // Comprueba si ha llegado al destino
// Comprueba si ha llegado al destino if (getPosX() < destX) {
if (getPosX() < destX) // Lo coloca en posición
{ setPosX(destX);
// Lo coloca en posición
setPosX(destX);
// Lo detiene // Lo detiene
setVelX(0.0f); setVelX(0.0f);
setAccelX(0.0f); setAccelX(0.0f);
} }
} }
// Comprueba si se desplaza en el eje Y hacia abajo // Comprueba si se desplaza en el eje Y hacia abajo
if (getAccelY() > 0 || getVelY() > 0) if (getAccelY() > 0 || getVelY() > 0) {
{ // Comprueba si ha llegado al destino
// Comprueba si ha llegado al destino if (getPosY() > destY) {
if (getPosY() > destY) // Lo coloca en posición
{ setPosY(destY);
// Lo coloca en posición
setPosY(destY);
// Lo detiene // Lo detiene
setVelY(0.0f); setVelY(0.0f);
setAccelY(0.0f); setAccelY(0.0f);
} }
} }
// Comprueba si se desplaza en el eje Y hacia arriba // Comprueba si se desplaza en el eje Y hacia arriba
else if (getAccelY() < 0 || getVelY() < 0) else if (getAccelY() < 0 || getVelY() < 0) {
{ // Comprueba si ha llegado al destino
// Comprueba si ha llegado al destino if (getPosY() < destY) {
if (getPosY() < destY) // Lo coloca en posición
{ setPosY(destY);
// Lo coloca en posición
setPosY(destY);
// Lo detiene // Lo detiene
setVelY(0.0f); setVelY(0.0f);
setAccelY(0.0f); setAccelY(0.0f);
} }
} }
} }
// Comprueba si ha terminado // Comprueba si ha terminado
void SmartSprite::checkFinished() void SmartSprite::checkFinished() {
{ // Comprueba si ha llegado a su destino
// Comprueba si ha llegado a su destino onDestination = (getPosX() == destX && getPosY() == destY) ? true : false;
onDestination = (getPosX() == destX && getPosY() == destY) ? true : false;
if (onDestination) if (onDestination) { // Si esta en el destino comprueba su contador
{ // Si esta en el destino comprueba su contador if (enabledCounter == 0) { // Si ha llegado a cero, deshabilita el objeto y lo marca como finalizado
if (enabledCounter == 0) finished = true;
{ // Si ha llegado a cero, deshabilita el objeto y lo marca como finalizado } else { // Si no ha llegado a cero, decrementa el contador
finished = true; enabledCounter--;
} }
else }
{ // Si no ha llegado a cero, decrementa el contador
enabledCounter--;
}
}
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool SmartSprite::isOnDestination() bool SmartSprite::isOnDestination() {
{ return onDestination;
return onDestination;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool SmartSprite::hasFinished() bool SmartSprite::hasFinished() {
{ return finished;
return finished;
} }

View File

@@ -1,67 +1,67 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include "animatedsprite.h" // for AnimatedSprite
#include "animatedsprite.h" // for AnimatedSprite
class Texture; class Texture;
// Clase SmartSprite // Clase SmartSprite
class SmartSprite : public AnimatedSprite class SmartSprite : public AnimatedSprite {
{ private:
private: // Variables
// Variables bool enabled; // Indica si esta habilitado
bool enabled; // Indica si esta habilitado bool onDestination; // Indica si está en el destino
bool onDestination; // Indica si está en el destino int destX; // Posicion de destino en el eje X
int destX; // Posicion de destino en el eje X int destY; // Posicion de destino en el eje Y
int destY; // Posicion de destino en el eje Y int enabledCounter; // Contador para deshabilitarlo
int enabledCounter; // Contador para deshabilitarlo bool finished; // Indica si ya ha terminado
bool finished; // Indica si ya ha terminado
// Comprueba el movimiento // Comprueba el movimiento
void checkMove(); void checkMove();
// Comprueba si ha terminado // Comprueba si ha terminado
void checkFinished(); void checkFinished();
public: public:
// Constructor // Constructor
SmartSprite(Texture *texture, SDL_Renderer *renderer); SmartSprite(Texture *texture, SDL_Renderer *renderer);
// Inicializa el objeto // Inicializa el objeto
void init(); void init();
// Actualiza la posición y comprueba si ha llegado a su destino // Actualiza la posición y comprueba si ha llegado a su destino
void update(); void update();
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void render(); void render();
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool isEnabled(); bool isEnabled();
// Establece el valor de la variable // Establece el valor de la variable
void setEnabled(bool enabled); void setEnabled(bool enabled);
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getEnabledCounter(); int getEnabledCounter();
// Establece el valor de la variable // Establece el valor de la variable
void setEnabledCounter(int value); void setEnabledCounter(int value);
// Establece el valor de la variable // Establece el valor de la variable
void setDestX(int x); void setDestX(int x);
// Establece el valor de la variable // Establece el valor de la variable
void setDestY(int y); void setDestY(int y);
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getDestX(); int getDestX();
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getDestY(); int getDestY();
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool isOnDestination(); bool isOnDestination();
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool hasFinished(); bool hasFinished();
}; };

View File

@@ -1,190 +1,166 @@
#include "sprite.h" #include "sprite.h"
#include "texture.h" // for Texture #include "texture.h" // for Texture
// Constructor // Constructor
Sprite::Sprite(int x, int y, int w, int h, Texture *texture, SDL_Renderer *renderer) Sprite::Sprite(int x, int y, int w, int h, Texture *texture, SDL_Renderer *renderer) {
{ // Establece la posición X,Y del sprite
// Establece la posición X,Y del sprite this->x = x;
this->x = x; this->y = y;
this->y = y;
// Establece el alto y el ancho del sprite // Establece el alto y el ancho del sprite
this->w = w; this->w = w;
this->h = h; this->h = h;
// Establece el puntero al renderizador de la ventana // Establece el puntero al renderizador de la ventana
this->renderer = renderer; this->renderer = renderer;
// Establece la textura donde están los gráficos para el sprite // Establece la textura donde están los gráficos para el sprite
this->texture = texture; this->texture = texture;
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
spriteClip = {0, 0, w, h}; spriteClip = {0, 0, w, h};
// Inicializa variables // Inicializa variables
enabled = true; enabled = true;
} }
Sprite::Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer) Sprite::Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer) {
{ // Establece la posición X,Y del sprite
// Establece la posición X,Y del sprite x = rect.x;
x = rect.x; y = rect.y;
y = rect.y;
// Establece el alto y el ancho del sprite // Establece el alto y el ancho del sprite
w = rect.w; w = rect.w;
h = rect.h; h = rect.h;
// Establece el puntero al renderizador de la ventana // Establece el puntero al renderizador de la ventana
this->renderer = renderer; this->renderer = renderer;
// Establece la textura donde están los gráficos para el sprite // Establece la textura donde están los gráficos para el sprite
this->texture = texture; this->texture = texture;
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
spriteClip = {0, 0, w, h}; spriteClip = {0, 0, w, h};
// Inicializa variables // Inicializa variables
enabled = true; enabled = true;
} }
// Destructor // Destructor
Sprite::~Sprite() Sprite::~Sprite() {
{ texture = nullptr;
texture = nullptr; renderer = nullptr;
renderer = nullptr;
} }
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void Sprite::render() void Sprite::render() {
{ if (enabled) {
if (enabled) texture->render(renderer, x, y, &spriteClip);
{ }
texture->render(renderer, x, y, &spriteClip);
}
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getPosX() int Sprite::getPosX() {
{ return x;
return x;
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getPosY() int Sprite::getPosY() {
{ return y;
return y;
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getWidth() int Sprite::getWidth() {
{ return w;
return w;
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getHeight() int Sprite::getHeight() {
{ return h;
return h;
} }
// Establece la posición del objeto // Establece la posición del objeto
void Sprite::setPos(SDL_Rect rect) void Sprite::setPos(SDL_Rect rect) {
{ this->x = rect.x;
this->x = rect.x; this->y = rect.y;
this->y = rect.y;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setPosX(int x) void Sprite::setPosX(int x) {
{ this->x = x;
this->x = x;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setPosY(int y) void Sprite::setPosY(int y) {
{ this->y = y;
this->y = y;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setWidth(int w) void Sprite::setWidth(int w) {
{ this->w = w;
this->w = w;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setHeight(int h) void Sprite::setHeight(int h) {
{ this->h = h;
this->h = h;
} }
// Obten el valor de la variable // Obten el valor de la variable
SDL_Rect Sprite::getSpriteClip() SDL_Rect Sprite::getSpriteClip() {
{ return spriteClip;
return spriteClip;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setSpriteClip(SDL_Rect rect) void Sprite::setSpriteClip(SDL_Rect rect) {
{ spriteClip = rect;
spriteClip = rect;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setSpriteClip(int x, int y, int w, int h) void Sprite::setSpriteClip(int x, int y, int w, int h) {
{ spriteClip = {x, y, w, h};
spriteClip = {x, y, w, h};
} }
// Obten el valor de la variable // Obten el valor de la variable
Texture *Sprite::getTexture() Texture *Sprite::getTexture() {
{ return texture;
return texture;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setTexture(Texture *texture) void Sprite::setTexture(Texture *texture) {
{ this->texture = texture;
this->texture = texture;
} }
// Obten el valor de la variable // Obten el valor de la variable
SDL_Renderer *Sprite::getRenderer() SDL_Renderer *Sprite::getRenderer() {
{ return renderer;
return renderer;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setRenderer(SDL_Renderer *renderer) void Sprite::setRenderer(SDL_Renderer *renderer) {
{ this->renderer = renderer;
this->renderer = renderer;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setEnabled(bool value) void Sprite::setEnabled(bool value) {
{ enabled = value;
enabled = value;
} }
// Comprueba si el objeto está habilitado // Comprueba si el objeto está habilitado
bool Sprite::isEnabled() bool Sprite::isEnabled() {
{ return enabled;
return enabled;
} }
// Devuelve el rectangulo donde está el sprite // Devuelve el rectangulo donde está el sprite
SDL_Rect Sprite::getRect() SDL_Rect Sprite::getRect() {
{ SDL_Rect rect = {x, y, w, h};
SDL_Rect rect = {x, y, w, h}; return rect;
return rect;
} }
// Establece los valores de posición y tamaño del sprite // Establece los valores de posición y tamaño del sprite
void Sprite::setRect(SDL_Rect rect) void Sprite::setRect(SDL_Rect rect) {
{ x = rect.x;
x = rect.x; y = rect.y;
y = rect.y; w = rect.w;
w = rect.w; h = rect.h;
h = rect.h;
} }

View File

@@ -4,21 +4,20 @@
class Texture; class Texture;
// Clase sprite // Clase sprite
class Sprite class Sprite {
{ protected:
protected: int x; // Posición en el eje X donde dibujar el sprite
int x; // Posición en el eje X donde dibujar el sprite int y; // Posición en el eje Y donde dibujar el sprite
int y; // Posición en el eje Y donde dibujar el sprite int w; // Ancho del sprite
int w; // Ancho del sprite int h; // Alto del sprite
int h; // Alto del sprite
SDL_Renderer *renderer; // Puntero al renderizador de la ventana SDL_Renderer *renderer; // Puntero al renderizador de la ventana
Texture *texture; // Textura donde estan todos los dibujos del sprite Texture *texture; // Textura donde estan todos los dibujos del sprite
SDL_Rect spriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla SDL_Rect spriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla
bool enabled; // Indica si el sprite esta habilitado bool enabled; // Indica si el sprite esta habilitado
public: public:
// Constructor // Constructor
Sprite(int x = 0, int y = 0, int w = 0, int h = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr); Sprite(int x = 0, int y = 0, int w = 0, int h = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr);
Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer); Sprite(SDL_Rect rect, Texture *texture, SDL_Renderer *renderer);

View File

@@ -1,278 +1,243 @@
#include "text.h" #include "text.h"
#include <fstream> // for char_traits, basic_ostream, basic_ifstream, ope...
#include <iostream> // for cout #include <fstream> // for char_traits, basic_ostream, basic_ifstream, ope...
#include <iostream> // for cout
#include "sprite.h" // for Sprite #include "sprite.h" // for Sprite
#include "texture.h" // for Texture #include "texture.h" // for Texture
#include "utils.h" // for color_t #include "utils.h" // for color_t
// Llena una estructuta textFile_t desde un fichero // Llena una estructuta textFile_t desde un fichero
textFile_t LoadTextFile(std::string file, bool verbose) textFile_t LoadTextFile(std::string file, bool verbose) {
{ textFile_t tf;
textFile_t tf;
// Inicializa a cero el vector con las coordenadas // Inicializa a cero el vector con las coordenadas
for (int i = 0; i < 128; ++i) for (int i = 0; i < 128; ++i) {
{ tf.offset[i].x = 0;
tf.offset[i].x = 0; tf.offset[i].y = 0;
tf.offset[i].y = 0; tf.offset[i].w = 0;
tf.offset[i].w = 0; }
}
// Abre el fichero para leer los valores // Abre el fichero para leer los valores
const std::string filename = file.substr(file.find_last_of("\\/") + 1).c_str(); const std::string filename = file.substr(file.find_last_of("\\/") + 1).c_str();
std::ifstream rfile(file); std::ifstream rfile(file);
if (rfile.is_open() && rfile.good()) if (rfile.is_open() && rfile.good()) {
{ std::string buffer;
std::string buffer;
// Lee los dos primeros valores del fichero // Lee los dos primeros valores del fichero
std::getline(rfile, buffer); std::getline(rfile, buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
tf.boxWidth = std::stoi(buffer); tf.boxWidth = std::stoi(buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
tf.boxHeight = std::stoi(buffer); tf.boxHeight = std::stoi(buffer);
// lee el resto de datos del fichero // lee el resto de datos del fichero
int index = 32; int index = 32;
int line_read = 0; int line_read = 0;
while (std::getline(rfile, buffer)) while (std::getline(rfile, buffer)) {
{ // Almacena solo las lineas impares
// Almacena solo las lineas impares if (line_read % 2 == 1) {
if (line_read % 2 == 1) tf.offset[index++].w = std::stoi(buffer);
{ }
tf.offset[index++].w = std::stoi(buffer);
}
// Limpia el buffer // Limpia el buffer
buffer.clear(); buffer.clear();
line_read++; line_read++;
}; };
// Cierra el fichero // Cierra el fichero
if (verbose) if (verbose) {
{ std::cout << "Text loaded: " << filename.c_str() << std::endl;
std::cout << "Text loaded: " << filename.c_str() << std::endl; }
} rfile.close();
rfile.close(); }
}
// El fichero no se puede abrir // El fichero no se puede abrir
else else {
{ if (verbose) {
if (verbose) std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl;
{ }
std::cout << "Warning: Unable to open " << filename.c_str() << " file" << std::endl; }
}
}
// Establece las coordenadas para cada caracter ascii de la cadena y su ancho // Establece las coordenadas para cada caracter ascii de la cadena y su ancho
for (int i = 32; i < 128; ++i) for (int i = 32; i < 128; ++i) {
{ tf.offset[i].x = ((i - 32) % 15) * tf.boxWidth;
tf.offset[i].x = ((i - 32) % 15) * tf.boxWidth; tf.offset[i].y = ((i - 32) / 15) * tf.boxHeight;
tf.offset[i].y = ((i - 32) / 15) * tf.boxHeight; }
}
return tf; return tf;
} }
// Constructor // Constructor
Text::Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer) Text::Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer) {
{ // Carga los offsets desde el fichero
// Carga los offsets desde el fichero textFile_t tf = LoadTextFile(textFile);
textFile_t tf = LoadTextFile(textFile);
// Inicializa variables desde la estructura // Inicializa variables desde la estructura
boxHeight = tf.boxHeight; boxHeight = tf.boxHeight;
boxWidth = tf.boxWidth; boxWidth = tf.boxWidth;
for (int i = 0; i < 128; ++i) for (int i = 0; i < 128; ++i) {
{ offset[i].x = tf.offset[i].x;
offset[i].x = tf.offset[i].x; offset[i].y = tf.offset[i].y;
offset[i].y = tf.offset[i].y; offset[i].w = tf.offset[i].w;
offset[i].w = tf.offset[i].w; }
}
// Crea los objetos // Crea los objetos
texture = new Texture(renderer, bitmapFile); texture = new Texture(renderer, bitmapFile);
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer); sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
// Inicializa variables // Inicializa variables
fixedWidth = false; fixedWidth = false;
} }
// Constructor // Constructor
Text::Text(std::string textFile, Texture *texture, SDL_Renderer *renderer) Text::Text(std::string textFile, Texture *texture, SDL_Renderer *renderer) {
{ // Carga los offsets desde el fichero
// Carga los offsets desde el fichero textFile_t tf = LoadTextFile(textFile);
textFile_t tf = LoadTextFile(textFile);
// Inicializa variables desde la estructura // Inicializa variables desde la estructura
boxHeight = tf.boxHeight; boxHeight = tf.boxHeight;
boxWidth = tf.boxWidth; boxWidth = tf.boxWidth;
for (int i = 0; i < 128; ++i) for (int i = 0; i < 128; ++i) {
{ offset[i].x = tf.offset[i].x;
offset[i].x = tf.offset[i].x; offset[i].y = tf.offset[i].y;
offset[i].y = tf.offset[i].y; offset[i].w = tf.offset[i].w;
offset[i].w = tf.offset[i].w; }
}
// Crea los objetos // Crea los objetos
this->texture = nullptr; this->texture = nullptr;
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer); sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
// Inicializa variables // Inicializa variables
fixedWidth = false; fixedWidth = false;
} }
// Constructor // Constructor
Text::Text(textFile_t *textFile, Texture *texture, SDL_Renderer *renderer) Text::Text(textFile_t *textFile, Texture *texture, SDL_Renderer *renderer) {
{ // Inicializa variables desde la estructura
// Inicializa variables desde la estructura boxHeight = textFile->boxHeight;
boxHeight = textFile->boxHeight; boxWidth = textFile->boxWidth;
boxWidth = textFile->boxWidth; for (int i = 0; i < 128; ++i) {
for (int i = 0; i < 128; ++i) offset[i].x = textFile->offset[i].x;
{ offset[i].y = textFile->offset[i].y;
offset[i].x = textFile->offset[i].x; offset[i].w = textFile->offset[i].w;
offset[i].y = textFile->offset[i].y; }
offset[i].w = textFile->offset[i].w;
}
// Crea los objetos // Crea los objetos
this->texture = nullptr; this->texture = nullptr;
sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer); sprite = new Sprite({0, 0, boxWidth, boxHeight}, texture, renderer);
// Inicializa variables // Inicializa variables
fixedWidth = false; fixedWidth = false;
} }
// Destructor // Destructor
Text::~Text() Text::~Text() {
{ delete sprite;
delete sprite; if (texture != nullptr) {
if (texture != nullptr) delete texture;
{ }
delete texture;
}
} }
// Escribe texto en pantalla // Escribe texto en pantalla
void Text::write(int x, int y, std::string text, int kerning, int lenght) void Text::write(int x, int y, std::string text, int kerning, int lenght) {
{ int shift = 0;
int shift = 0;
if (lenght == -1) if (lenght == -1) {
{ lenght = text.length();
lenght = text.length(); }
}
sprite->setPosY(y); sprite->setPosY(y);
const int width = sprite->getWidth(); const int width = sprite->getWidth();
const int height = sprite->getHeight(); const int height = sprite->getHeight();
for (int i = 0; i < lenght; ++i) for (int i = 0; i < lenght; ++i) {
{ const int index = text[i];
const int index = text[i]; sprite->setSpriteClip(offset[index].x, offset[index].y, width, height);
sprite->setSpriteClip(offset[index].x, offset[index].y, width, height); sprite->setPosX(x + shift);
sprite->setPosX(x + shift); sprite->render();
sprite->render(); shift += fixedWidth ? boxWidth : (offset[int(text[i])].w + kerning);
shift += fixedWidth ? boxWidth : (offset[int(text[i])].w + kerning); }
}
} }
// Escribe el texto con colores // Escribe el texto con colores
void Text::writeColored(int x, int y, std::string text, color_t color, int kerning, int lenght) void Text::writeColored(int x, int y, std::string text, color_t color, int kerning, int lenght) {
{ sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->getTexture()->setColor(color.r, color.g, color.b); write(x, y, text, kerning, lenght);
write(x, y, text, kerning, lenght); sprite->getTexture()->setColor(255, 255, 255);
sprite->getTexture()->setColor(255, 255, 255);
} }
// Escribe el texto con sombra // Escribe el texto con sombra
void Text::writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance, int kerning, int lenght) void Text::writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance, int kerning, int lenght) {
{ sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->getTexture()->setColor(color.r, color.g, color.b); write(x + shadowDistance, y + shadowDistance, text, kerning, lenght);
write(x + shadowDistance, y + shadowDistance, text, kerning, lenght); sprite->getTexture()->setColor(255, 255, 255);
sprite->getTexture()->setColor(255, 255, 255); write(x, y, text, kerning, lenght);
write(x, y, text, kerning, lenght);
} }
// Escribe el texto centrado en un punto x // Escribe el texto centrado en un punto x
void Text::writeCentered(int x, int y, std::string text, int kerning, int lenght) void Text::writeCentered(int x, int y, std::string text, int kerning, int lenght) {
{ x -= (Text::lenght(text, kerning) / 2);
x -= (Text::lenght(text, kerning) / 2); write(x, y, text, kerning, lenght);
write(x, y, text, kerning, lenght);
} }
// Escribe texto con extras // Escribe texto con extras
void Text::writeDX(Uint8 flags, int x, int y, std::string text, int kerning, color_t textColor, Uint8 shadowDistance, color_t shadowColor, int lenght) void Text::writeDX(Uint8 flags, int x, int y, std::string text, int kerning, color_t textColor, Uint8 shadowDistance, color_t shadowColor, int lenght) {
{ const bool centered = ((flags & TXT_CENTER) == TXT_CENTER);
const bool centered = ((flags & TXT_CENTER) == TXT_CENTER); const bool shadowed = ((flags & TXT_SHADOW) == TXT_SHADOW);
const bool shadowed = ((flags & TXT_SHADOW) == TXT_SHADOW); const bool colored = ((flags & TXT_COLOR) == TXT_COLOR);
const bool colored = ((flags & TXT_COLOR) == TXT_COLOR); const bool stroked = ((flags & TXT_STROKE) == TXT_STROKE);
const bool stroked = ((flags & TXT_STROKE) == TXT_STROKE);
if (centered) if (centered) {
{ x -= (Text::lenght(text, kerning) / 2);
x -= (Text::lenght(text, kerning) / 2); }
}
if (shadowed) if (shadowed) {
{ writeColored(x + shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght);
writeColored(x + shadowDistance, y + shadowDistance, text, shadowColor, kerning, lenght); }
}
if (stroked) if (stroked) {
{ for (int dist = 1; dist <= shadowDistance; ++dist) {
for (int dist = 1; dist <= shadowDistance; ++dist) for (int dy = -dist; dy <= dist; ++dy) {
{ for (int dx = -dist; dx <= dist; ++dx) {
for (int dy = -dist; dy <= dist; ++dy) writeColored(x + dx, y + dy, text, shadowColor, kerning, lenght);
{ }
for (int dx = -dist; dx <= dist; ++dx) }
{ }
writeColored(x + dx, y + dy, text, shadowColor, kerning, lenght); }
}
}
}
}
if (colored) if (colored) {
{ writeColored(x, y, text, textColor, kerning, lenght);
writeColored(x, y, text, textColor, kerning, lenght); } else {
} write(x, y, text, kerning, lenght);
else }
{
write(x, y, text, kerning, lenght);
}
} }
// Obtiene la longitud en pixels de una cadena // Obtiene la longitud en pixels de una cadena
int Text::lenght(std::string text, int kerning) int Text::lenght(std::string text, int kerning) {
{ int shift = 0;
int shift = 0;
for (int i = 0; i < (int)text.length(); ++i) for (int i = 0; i < (int)text.length(); ++i)
shift += (offset[int(text[i])].w + kerning); shift += (offset[int(text[i])].w + kerning);
// Descuenta el kerning del último caracter // Descuenta el kerning del último caracter
return shift - kerning; return shift - kerning;
} }
// Devuelve el valor de la variable // Devuelve el valor de la variable
int Text::getCharacterSize() int Text::getCharacterSize() {
{ return boxWidth;
return boxWidth;
} }
// Recarga la textura // Recarga la textura
void Text::reLoadTexture() void Text::reLoadTexture() {
{ sprite->getTexture()->reLoad();
sprite->getTexture()->reLoad();
} }
// Establece si se usa un tamaño fijo de letra // Establece si se usa un tamaño fijo de letra
void Text::setFixedWidth(bool value) void Text::setFixedWidth(bool value) {
{ fixedWidth = value;
fixedWidth = value;
} }

View File

@@ -1,7 +1,8 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string
#include <string> // for string
class Sprite; class Sprite;
class Texture; class Texture;
#include "utils.h" #include "utils.h"
@@ -12,70 +13,67 @@ constexpr int TXT_SHADOW = 2;
constexpr int TXT_CENTER = 4; constexpr int TXT_CENTER = 4;
constexpr int TXT_STROKE = 8; constexpr int TXT_STROKE = 8;
struct offset_t struct offset_t {
{ int x;
int x; int y;
int y; int w;
int w;
}; };
struct textFile_t struct textFile_t {
{ int boxWidth; // Anchura de la caja de cada caracter en el png
int boxWidth; // Anchura de la caja de cada caracter en el png int boxHeight; // Altura de la caja de cada caracter en el png
int boxHeight; // Altura de la caja de cada caracter en el png offset_t offset[128]; // Vector con las posiciones y ancho de cada letra
offset_t offset[128]; // Vector con las posiciones y ancho de cada letra
}; };
// Llena una estructuta textFile_t desde un fichero // Llena una estructuta textFile_t desde un fichero
textFile_t LoadTextFile(std::string file, bool verbose = false); textFile_t LoadTextFile(std::string file, bool verbose = false);
// Clase texto. Pinta texto en pantalla a partir de un bitmap // Clase texto. Pinta texto en pantalla a partir de un bitmap
class Text class Text {
{ private:
private: // Objetos y punteros
// Objetos y punteros Sprite *sprite; // Objeto con los graficos para el texto
Sprite *sprite; // Objeto con los graficos para el texto Texture *texture; // Textura con los bitmaps del texto
Texture *texture; // Textura con los bitmaps del texto
// Variables // Variables
int boxWidth; // Anchura de la caja de cada caracter en el png int boxWidth; // Anchura de la caja de cada caracter en el png
int boxHeight; // Altura de la caja de cada caracter en el png int boxHeight; // Altura de la caja de cada caracter en el png
bool fixedWidth; // Indica si el texto se ha de escribir con longitud fija en todas las letras bool fixedWidth; // Indica si el texto se ha de escribir con longitud fija en todas las letras
offset_t offset[128]; // Vector con las posiciones y ancho de cada letra offset_t offset[128]; // Vector con las posiciones y ancho de cada letra
public: public:
// Constructor // Constructor
Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer); Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer);
Text(std::string textFile, Texture *texture, SDL_Renderer *renderer); Text(std::string textFile, Texture *texture, SDL_Renderer *renderer);
Text(textFile_t *textFile, Texture *texture, SDL_Renderer *renderer); Text(textFile_t *textFile, Texture *texture, SDL_Renderer *renderer);
// Destructor // Destructor
~Text(); ~Text();
// Escribe el texto en pantalla // Escribe el texto en pantalla
void write(int x, int y, std::string text, int kerning = 1, int lenght = -1); void write(int x, int y, std::string text, int kerning = 1, int lenght = -1);
// Escribe el texto con colores // Escribe el texto con colores
void writeColored(int x, int y, std::string text, color_t color, int kerning = 1, int lenght = -1); void writeColored(int x, int y, std::string text, color_t color, int kerning = 1, int lenght = -1);
// Escribe el texto con sombra // Escribe el texto con sombra
void writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1); void writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1);
// Escribe el texto centrado en un punto x // Escribe el texto centrado en un punto x
void writeCentered(int x, int y, std::string text, int kerning = 1, int lenght = -1); void writeCentered(int x, int y, std::string text, int kerning = 1, int lenght = -1);
// Escribe texto con extras // Escribe texto con extras
void writeDX(Uint8 flags, int x, int y, std::string text, int kerning = 1, color_t textColor = color_t(255, 255, 255), Uint8 shadowDistance = 1, color_t shadowColor = color_t(0, 0, 0), int lenght = -1); void writeDX(Uint8 flags, int x, int y, std::string text, int kerning = 1, color_t textColor = color_t(255, 255, 255), Uint8 shadowDistance = 1, color_t shadowColor = color_t(0, 0, 0), int lenght = -1);
// Obtiene la longitud en pixels de una cadena // Obtiene la longitud en pixels de una cadena
int lenght(std::string text, int kerning = 1); int lenght(std::string text, int kerning = 1);
// Devuelve el valor de la variable // Devuelve el valor de la variable
int getCharacterSize(); int getCharacterSize();
// Recarga la textura // Recarga la textura
void reLoadTexture(); void reLoadTexture();
// 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);
}; };

View File

@@ -1,237 +1,201 @@
#include "texture.h" #include "texture.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <stdlib.h> // for exit #include <stdlib.h> // for exit
#include <iostream> // for basic_ostream, operator<<, cout, endl
#include <iostream> // for basic_ostream, operator<<, cout, endl
#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
SDL_ScaleMode Texture::currentScaleMode = SDL_SCALEMODE_NEAREST; SDL_ScaleMode Texture::currentScaleMode = SDL_SCALEMODE_NEAREST;
void Texture::setGlobalScaleMode(SDL_ScaleMode mode) void Texture::setGlobalScaleMode(SDL_ScaleMode mode) {
{ currentScaleMode = mode;
currentScaleMode = mode;
} }
// Constructor // Constructor
Texture::Texture(SDL_Renderer *renderer, std::string path, bool verbose) Texture::Texture(SDL_Renderer *renderer, std::string path, bool verbose) {
{ // Copia punteros
// Copia punteros this->renderer = renderer;
this->renderer = renderer; this->path = path;
this->path = path;
// Inicializa // Inicializa
texture = nullptr; texture = nullptr;
width = 0; width = 0;
height = 0; height = 0;
// Carga el fichero en la textura // Carga el fichero en la textura
if (path != "") if (path != "") {
{ loadFromFile(path, renderer, verbose);
loadFromFile(path, renderer, verbose); }
}
} }
// Destructor // Destructor
Texture::~Texture() Texture::~Texture() {
{ // Libera memoria
// Libera memoria unload();
unload();
} }
// Carga una imagen desde un fichero // Carga una imagen desde un fichero
bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer, bool verbose) bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer, bool verbose) {
{ const std::string filename = path.substr(path.find_last_of("\\/") + 1);
const std::string filename = path.substr(path.find_last_of("\\/") + 1); int req_format = STBI_rgb_alpha;
int req_format = STBI_rgb_alpha; int width, height, orig_format;
int width, height, orig_format; unsigned char *data = stbi_load(path.c_str(), &width, &height, &orig_format, req_format);
unsigned char *data = stbi_load(path.c_str(), &width, &height, &orig_format, req_format); if (data == nullptr) {
if (data == nullptr) SDL_Log("Loading image failed: %s", stbi_failure_reason());
{ exit(1);
SDL_Log("Loading image failed: %s", stbi_failure_reason()); } else {
exit(1); if (verbose) {
} std::cout << "Image loaded: " << filename.c_str() << std::endl;
else }
{ }
if (verbose)
{
std::cout << "Image loaded: " << filename.c_str() << std::endl;
}
}
int pitch; int pitch;
SDL_PixelFormat pixel_format; SDL_PixelFormat pixel_format;
if (req_format == STBI_rgb) if (req_format == STBI_rgb) {
{ pitch = 3 * width; // 3 bytes por pixel * pixels per linea
pitch = 3 * width; // 3 bytes por pixel * pixels per linea pixel_format = SDL_PIXELFORMAT_RGB24;
pixel_format = SDL_PIXELFORMAT_RGB24; } else { // STBI_rgb_alpha (RGBA)
} pitch = 4 * width;
else pixel_format = SDL_PIXELFORMAT_RGBA32;
{ // STBI_rgb_alpha (RGBA) }
pitch = 4 * width;
pixel_format = SDL_PIXELFORMAT_RGBA32;
}
// Limpia // Limpia
unload(); unload();
// La textura final // La textura final
SDL_Texture *newTexture = nullptr; SDL_Texture *newTexture = nullptr;
// Carga la imagen desde una ruta específica // Carga la imagen desde una ruta específica
SDL_Surface *loadedSurface = SDL_CreateSurfaceFrom(width, height, pixel_format, (void *)data, pitch); SDL_Surface *loadedSurface = SDL_CreateSurfaceFrom(width, height, pixel_format, (void *)data, pitch);
if (loadedSurface == nullptr) if (loadedSurface == nullptr) {
{ if (verbose) {
if (verbose) std::cout << "Unable to load image " << path.c_str() << std::endl;
{ }
std::cout << "Unable to load image " << path.c_str() << std::endl; } else {
} // Crea la textura desde los pixels de la surface
} newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
else if (newTexture == nullptr) {
{ if (verbose) {
// Crea la textura desde los pixels de la surface std::cout << "Unable to create texture from " << path.c_str() << "! SDL Error: " << SDL_GetError() << std::endl;
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); }
if (newTexture == nullptr) } else {
{ // Obtiene las dimensiones de la imagen
if (verbose) this->width = loadedSurface->w;
{ this->height = loadedSurface->h;
std::cout << "Unable to create texture from " << path.c_str() << "! SDL Error: " << SDL_GetError() << std::endl;
}
}
else
{
// Obtiene las dimensiones de la imagen
this->width = loadedSurface->w;
this->height = loadedSurface->h;
// Aplica el modo de escalado // Aplica el modo de escalado
SDL_SetTextureScaleMode(newTexture, currentScaleMode); SDL_SetTextureScaleMode(newTexture, currentScaleMode);
} }
// Elimina la textura cargada // Elimina la textura cargada
SDL_DestroySurface(loadedSurface); SDL_DestroySurface(loadedSurface);
} }
// Return success // Return success
stbi_image_free(data); stbi_image_free(data);
texture = newTexture; texture = newTexture;
return texture != nullptr; return texture != nullptr;
} }
// Crea una textura en blanco // Crea una textura en blanco
bool Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access) bool Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access) {
{ // Crea una textura sin inicializar
// Crea una textura sin inicializar texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height); if (texture == nullptr) {
if (texture == nullptr) std::cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << std::endl;
{ } else {
std::cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << std::endl; this->width = width;
} this->height = height;
else SDL_SetTextureScaleMode(texture, currentScaleMode);
{ }
this->width = width;
this->height = height;
SDL_SetTextureScaleMode(texture, currentScaleMode);
}
return texture != nullptr; return texture != nullptr;
} }
// Libera la memoria de la textura // Libera la memoria de la textura
void Texture::unload() void Texture::unload() {
{ // Libera la textura si existe
// Libera la textura si existe if (texture != nullptr) {
if (texture != nullptr) SDL_DestroyTexture(texture);
{ texture = nullptr;
SDL_DestroyTexture(texture); width = 0;
texture = nullptr; height = 0;
width = 0; }
height = 0;
}
} }
// Establece el color para la modulacion // Establece el color para la modulacion
void Texture::setColor(Uint8 red, Uint8 green, Uint8 blue) void Texture::setColor(Uint8 red, Uint8 green, Uint8 blue) {
{ SDL_SetTextureColorMod(texture, red, green, blue);
SDL_SetTextureColorMod(texture, red, green, blue);
} }
// Establece el blending // Establece el blending
void Texture::setBlendMode(SDL_BlendMode blending) void Texture::setBlendMode(SDL_BlendMode blending) {
{ SDL_SetTextureBlendMode(texture, blending);
SDL_SetTextureBlendMode(texture, blending);
} }
// Establece el alpha para la modulación // Establece el alpha para la modulación
void Texture::setAlpha(Uint8 alpha) void Texture::setAlpha(Uint8 alpha) {
{ SDL_SetTextureAlphaMod(texture, alpha);
SDL_SetTextureAlphaMod(texture, alpha);
} }
// Renderiza la textura en un punto específico // Renderiza la textura en un punto específico
void Texture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, float zoomW, float zoomH, double angle, SDL_Point *center, SDL_FlipMode flip) void Texture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, float zoomW, float zoomH, double angle, SDL_Point *center, SDL_FlipMode flip) {
{ // Establece el destino de renderizado en la pantalla
// Establece el destino de renderizado en la pantalla SDL_FRect renderQuad = {(float)x, (float)y, (float)width, (float)height};
SDL_FRect renderQuad = {(float)x, (float)y, (float)width, (float)height};
// Obtiene las dimesiones del clip de renderizado // Obtiene las dimesiones del clip de renderizado
if (clip != nullptr) if (clip != nullptr) {
{ renderQuad.w = (float)clip->w;
renderQuad.w = (float)clip->w; renderQuad.h = (float)clip->h;
renderQuad.h = (float)clip->h; }
}
renderQuad.w = renderQuad.w * zoomW; renderQuad.w = renderQuad.w * zoomW;
renderQuad.h = renderQuad.h * zoomH; renderQuad.h = renderQuad.h * zoomH;
// Convierte el clip a SDL_FRect // Convierte el clip a SDL_FRect
SDL_FRect srcRect; SDL_FRect srcRect;
SDL_FRect *srcRectPtr = nullptr; SDL_FRect *srcRectPtr = nullptr;
if (clip != nullptr) if (clip != nullptr) {
{ srcRect = {(float)clip->x, (float)clip->y, (float)clip->w, (float)clip->h};
srcRect = {(float)clip->x, (float)clip->y, (float)clip->w, (float)clip->h}; srcRectPtr = &srcRect;
srcRectPtr = &srcRect; }
}
// Convierte el centro a SDL_FPoint // Convierte el centro a SDL_FPoint
SDL_FPoint fCenter; SDL_FPoint fCenter;
SDL_FPoint *fCenterPtr = nullptr; SDL_FPoint *fCenterPtr = nullptr;
if (center != nullptr) if (center != nullptr) {
{ fCenter = {(float)center->x, (float)center->y};
fCenter = {(float)center->x, (float)center->y}; fCenterPtr = &fCenter;
fCenterPtr = &fCenter; }
}
// Renderiza a pantalla // Renderiza a pantalla
SDL_RenderTextureRotated(renderer, texture, srcRectPtr, &renderQuad, angle, fCenterPtr, flip); SDL_RenderTextureRotated(renderer, texture, srcRectPtr, &renderQuad, angle, fCenterPtr, flip);
} }
// Establece la textura como objetivo de renderizado // Establece la textura como objetivo de renderizado
void Texture::setAsRenderTarget(SDL_Renderer *renderer) void Texture::setAsRenderTarget(SDL_Renderer *renderer) {
{ SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderTarget(renderer, texture);
} }
// Obtiene el ancho de la imagen // Obtiene el ancho de la imagen
int Texture::getWidth() int Texture::getWidth() {
{ return width;
return width;
} }
// Obtiene el alto de la imagen // Obtiene el alto de la imagen
int Texture::getHeight() int Texture::getHeight() {
{ return height;
return height;
} }
// Recarga la textura // Recarga la textura
bool Texture::reLoad() bool Texture::reLoad() {
{ return loadFromFile(path, renderer);
return loadFromFile(path, renderer);
} }
// Obtiene la textura // Obtiene la textura
SDL_Texture *Texture::getSDLTexture() SDL_Texture *Texture::getSDLTexture() {
{ return texture;
return texture;
} }

View File

@@ -1,22 +1,22 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for basic_string, string
class Texture #include <string> // for basic_string, string
{
private: class Texture {
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
// 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
public: public:
static SDL_ScaleMode currentScaleMode; // Modo de escalado global para nuevas texturas static SDL_ScaleMode currentScaleMode; // Modo de escalado global para nuevas texturas
// Establece el modo de escalado global para nuevas texturas // Establece el modo de escalado global para nuevas texturas
static void setGlobalScaleMode(SDL_ScaleMode mode); static void setGlobalScaleMode(SDL_ScaleMode mode);

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,11 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <vector> // for vector
#include "instructions.h" // for mode_e #include <vector> // for vector
#include "utils.h" // for input_t, options_t, section_t
#include "instructions.h" // for mode_e
#include "utils.h" // for input_t, options_t, section_t
class AnimatedSprite; class AnimatedSprite;
class Asset; class Asset;
class Fade; class Fade;
@@ -28,120 +30,118 @@ constexpr int TITLE_COUNTER = 800;
// Cantidad de eventos de la pantalla de título // Cantidad de eventos de la pantalla de título
constexpr int TITLE_TOTAL_EVENTS = 2; constexpr int TITLE_TOTAL_EVENTS = 2;
class Title class Title {
{ private:
private: struct menu_t {
struct menu_t Menu *title; // Menu de la pantalla de título
{ Menu *options; // Menú de la pantalla de opciones
Menu *title; // Menu de la pantalla de título Menu *playerSelect; // Menu para elegir jugador
Menu *options; // Menú de la pantalla de opciones Menu *active; // Menu activo (de momento para la pantalla del titulo)
Menu *playerSelect; // Menu para elegir jugador bool keyPressed; // Variable para evitar la repetición de teclas en los menus
Menu *active; // Menu activo (de momento para la pantalla del titulo) };
bool keyPressed; // Variable para evitar la repetición de teclas en los menus
};
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla Screen *screen; // Objeto encargado de dibujar en pantalla
Asset *asset; // Objeto que gestiona todos los ficheros de recursos Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Input *input; // Objeto para leer las entradas de teclado o mando Input *input; // Objeto para leer las entradas de teclado o mando
Lang *lang; // Objeto para gestionar los textos en diferentes idiomas Lang *lang; // Objeto para gestionar los textos en diferentes idiomas
Instructions *instructions; // Objeto para la sección de las instrucciones Instructions *instructions; // Objeto para la sección de las instrucciones
Game *demoGame; // Objeto para lanzar la demo del juego Game *demoGame; // Objeto para lanzar la demo del juego
SDL_Event *eventHandler; // Manejador de eventos SDL_Event *eventHandler; // Manejador de eventos
section_t *section; // Indicador para el bucle del titulo section_t *section; // Indicador para el bucle del titulo
Texture *dustTexture; // Textura con los graficos del polvo Texture *dustTexture; // Textura con los graficos del polvo
Texture *coffeeTexture; // Textura con los graficos de la palabra coffee Texture *coffeeTexture; // Textura con los graficos de la palabra coffee
Texture *crisisTexture; // Textura con los graficos de la plabra crisis Texture *crisisTexture; // Textura con los graficos de la plabra crisis
Texture *gradientTexture; // Textura con los graficos para el degradado del fondo del titulo Texture *gradientTexture; // Textura con los graficos para el degradado del fondo del titulo
SDL_Rect backgroundWindow; // Ventana visible para la textura de fondo del titulo SDL_Rect backgroundWindow; // Ventana visible para la textura de fondo del titulo
SDL_Texture *background; // Textura dibujar el fondo del titulo SDL_Texture *background; // Textura dibujar el fondo del titulo
AnimatedSprite *dustBitmapL; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo AnimatedSprite *dustBitmapL; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo
AnimatedSprite *dustBitmapR; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo AnimatedSprite *dustBitmapR; // Sprite con la el polvo que aparece al colisionar el texto de la pantalla de titulo
SmartSprite *coffeeBitmap; // Sprite con la palabra COFFEE para la pantalla de titulo SmartSprite *coffeeBitmap; // Sprite con la palabra COFFEE para la pantalla de titulo
SmartSprite *crisisBitmap; // Sprite con la palabra CRISIS para la pantalla de titulo SmartSprite *crisisBitmap; // Sprite con la palabra CRISIS para la pantalla de titulo
Sprite *gradient; // Sprite para dibujar el degradado del titulo Sprite *gradient; // Sprite para dibujar el degradado del titulo
Text *text1; // Objeto de texto para poder escribir textos en pantalla Text *text1; // Objeto de texto para poder escribir textos en pantalla
Text *text2; // Objeto de texto para poder escribir textos en pantalla Text *text2; // Objeto de texto para poder escribir textos en pantalla
Fade *fade; // Objeto para realizar fundidos en pantalla Fade *fade; // Objeto para realizar fundidos en pantalla
// Variable // Variable
JA_Music_t *titleMusic; // Musica para el titulo JA_Music_t *titleMusic; // Musica para el titulo
JA_Sound_t *crashSound; // Sonido con el impacto del título JA_Sound_t *crashSound; // Sonido con el impacto del título
int backgroundCounter; // Temporizador para el fondo de tiles de la pantalla de titulo int backgroundCounter; // Temporizador para el fondo de tiles de la pantalla de titulo
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
Uint8 backgroundMode; // Variable para almacenar el tipo de efecto que hará el fondo de la pantalla de titulo Uint8 backgroundMode; // Variable para almacenar el tipo de efecto que hará el fondo de la pantalla de titulo
float sin[360]; // Vector con los valores del seno precalculados float sin[360]; // Vector con los valores del seno precalculados
bool menuVisible; // Indicador para saber si se muestra el menu del titulo o la frase intermitente bool menuVisible; // Indicador para saber si se muestra el menu del titulo o la frase intermitente
bool demo; // Indica si el modo demo estará activo bool demo; // Indica si el modo demo estará activo
section_t nextSection; // Indica cual es la siguiente sección a cargar cuando termine el contador del titulo section_t nextSection; // Indica cual es la siguiente sección a cargar cuando termine el contador del titulo
Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa
Uint8 postFade; // Opción a realizar cuando termina el fundido Uint8 postFade; // Opción a realizar cuando termina el fundido
menu_t menu; // Variable con todos los objetos menus y sus variables menu_t menu; // Variable con todos los objetos menus y sus variables
struct options_t *options; // Variable con todas las variables de las opciones del programa struct options_t *options; // Variable con todas las variables de las opciones del programa
options_t optionsPrevious; // Variable de respaldo para las opciones options_t optionsPrevious; // Variable de respaldo para las opciones
std::vector<input_t> availableInputDevices; // Vector con todos los metodos de control disponibles std::vector<input_t> availableInputDevices; // Vector con todos los metodos de control disponibles
std::vector<int> deviceIndex; // Indice para el jugador [i] del vector de dispositivos de entrada disponibles std::vector<int> deviceIndex; // Indice para el jugador [i] del vector de dispositivos de entrada disponibles
// Inicializa los valores // Inicializa los valores
void init(); void init();
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update();
// Dibuja el objeto en pantalla // Dibuja el objeto en pantalla
void render(); void render();
// Comprueba los eventos // Comprueba los eventos
void checkEvents(); void checkEvents();
// Comprueba las entradas // Comprueba las entradas
void checkInput(); void checkInput();
// Actualiza el tileado de fondo // Actualiza el tileado de fondo
void updateBG(); void updateBG();
// Cambia el valor de la variable de modo de pantalla completa // Cambia el valor de la variable de modo de pantalla completa
void switchFullScreenModeVar(); void switchFullScreenModeVar();
// Actualiza los elementos de los menus // Actualiza los elementos de los menus
void updateMenuLabels(); void updateMenuLabels();
// Aplica las opciones de menu seleccionadas // Aplica las opciones de menu seleccionadas
void applyOptions(); void applyOptions();
// Ejecuta la parte donde se muestran las instrucciones // Ejecuta la parte donde se muestran las instrucciones
void runInstructions(mode_e mode); void runInstructions(mode_e mode);
// Ejecuta el juego en modo demo // Ejecuta el juego en modo demo
void runDemoGame(); void runDemoGame();
// Modifica las opciones para los controles de los jugadores // Modifica las opciones para los controles de los jugadores
bool updatePlayerInputs(int numPlayer); bool updatePlayerInputs(int numPlayer);
// Crea el mosaico de fondo del titulo // Crea el mosaico de fondo del titulo
void createTiledBackground(); void createTiledBackground();
// Comprueba cuantos mandos hay conectados para gestionar el menu de opciones // Comprueba cuantos mandos hay conectados para gestionar el menu de opciones
void checkInputDevices(); void checkInputDevices();
// Recarga las texturas // Recarga las texturas
void reLoadTextures(); void reLoadTextures();
public: public:
// Constructor // Constructor
Title(SDL_Renderer *renderer, Screen *screen, Input *input, Asset *asset, options_t *options, Lang *lang, section_t *section); Title(SDL_Renderer *renderer, Screen *screen, Input *input, Asset *asset, options_t *options, Lang *lang, section_t *section);
// Destructor // Destructor
~Title(); ~Title();
// Bucle para el titulo del juego // Bucle para el titulo del juego
void run(); void run();
}; };

View File

@@ -1,25 +1,24 @@
#include "utils.h" #include "utils.h"
#include <stdlib.h> // for abs, free, malloc #include <stdlib.h> // for abs, free, malloc
#include <cmath> // for round, abs
#include <cmath> // for round, abs
// 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) {
{
const int deltaX = x2 - x1; const int deltaX = x2 - x1;
const int deltaY = y2 - y1; const int deltaY = y2 - y1;
return deltaX * deltaX + deltaY * deltaY; return deltaX * deltaX + deltaY * deltaY;
} }
// Detector de colisiones entre dos circulos // Detector de colisiones entre dos circulos
bool checkCollision(circle_t &a, circle_t &b) bool checkCollision(circle_t &a, circle_t &b) {
{
// Calcula el radio total al cuadrado // Calcula el radio total al cuadrado
int totalRadiusSquared = a.r + b.r; int totalRadiusSquared = a.r + b.r;
totalRadiusSquared = totalRadiusSquared * totalRadiusSquared; totalRadiusSquared = totalRadiusSquared * totalRadiusSquared;
// Si la distancia entre el centro de los circulos es inferior a la suma de sus radios // Si la distancia entre el centro de los circulos es inferior a la suma de sus radios
if (distanceSquared(a.x, a.y, b.x, b.y) < (totalRadiusSquared)) if (distanceSquared(a.x, a.y, b.x, b.y) < (totalRadiusSquared)) {
{
// Los circulos han colisionado // Los circulos han colisionado
return true; return true;
} }
@@ -29,42 +28,30 @@ bool checkCollision(circle_t &a, circle_t &b)
} }
// Detector de colisiones entre un circulo y un rectangulo // Detector de colisiones entre un circulo y un rectangulo
bool checkCollision(circle_t &a, SDL_Rect &b) bool checkCollision(circle_t &a, SDL_Rect &b) {
{
// Closest point on collision box // Closest point on collision box
int cX, cY; int cX, cY;
// Find closest x offset // Find closest x offset
if (a.x < b.x) if (a.x < b.x) {
{
cX = b.x; cX = b.x;
} } else if (a.x > b.x + b.w) {
else if (a.x > b.x + b.w)
{
cX = b.x + b.w; cX = b.x + b.w;
} } else {
else
{
cX = a.x; cX = a.x;
} }
// Find closest y offset // Find closest y offset
if (a.y < b.y) if (a.y < b.y) {
{
cY = b.y; cY = b.y;
} } else if (a.y > b.y + b.h) {
else if (a.y > b.y + b.h)
{
cY = b.y + b.h; cY = b.y + b.h;
} } else {
else
{
cY = a.y; cY = a.y;
} }
// If the closest point is inside the circle_t // If the closest point is inside the circle_t
if (distanceSquared(a.x, a.y, cX, cY) < a.r * a.r) if (distanceSquared(a.x, a.y, cX, cY) < a.r * a.r) {
{
// This box and the circle_t have collided // This box and the circle_t have collided
return true; return true;
} }
@@ -74,8 +61,7 @@ bool checkCollision(circle_t &a, SDL_Rect &b)
} }
// Detector de colisiones entre dos rectangulos // Detector de colisiones entre dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b) bool checkCollision(SDL_Rect &a, SDL_Rect &b) {
{
// Calcula las caras del rectangulo a // Calcula las caras del rectangulo a
const int leftA = a.x; const int leftA = a.x;
const int rightA = a.x + a.w; const int rightA = a.x + a.w;
@@ -89,23 +75,19 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
const int bottomB = b.y + b.h; const int bottomB = b.y + b.h;
// Si cualquiera de las caras de a está fuera de b // Si cualquiera de las caras de a está fuera de b
if (bottomA <= topB) if (bottomA <= topB) {
{
return false; return false;
} }
if (topA >= bottomB) if (topA >= bottomB) {
{
return false; return false;
} }
if (rightA <= leftB) if (rightA <= leftB) {
{
return false; return false;
} }
if (leftA >= rightB) if (leftA >= rightB) {
{
return false; return false;
} }
@@ -114,29 +96,24 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
} }
// Detector de colisiones entre un punto y un rectangulo // Detector de colisiones entre un punto y un rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r) bool checkCollision(SDL_Point &p, SDL_Rect &r) {
{
// Comprueba si el punto está a la izquierda del rectangulo // Comprueba si el punto está a la izquierda del rectangulo
if (p.x < r.x) if (p.x < r.x) {
{
return false; return false;
} }
// Comprueba si el punto está a la derecha del rectangulo // Comprueba si el punto está a la derecha del rectangulo
if (p.x > r.x + r.w) if (p.x > r.x + r.w) {
{
return false; return false;
} }
// Comprueba si el punto está por encima del rectangulo // Comprueba si el punto está por encima del rectangulo
if (p.y < r.y) if (p.y < r.y) {
{
return false; return false;
} }
// Comprueba si el punto está por debajo del rectangulo // Comprueba si el punto está por debajo del rectangulo
if (p.y > r.y + r.h) if (p.y > r.y + r.h) {
{
return false; return false;
} }
@@ -145,29 +122,24 @@ bool checkCollision(SDL_Point &p, SDL_Rect &r)
} }
// Detector de colisiones entre una linea horizontal y un rectangulo // Detector de colisiones entre una linea horizontal y un rectangulo
bool checkCollision(h_line_t &l, SDL_Rect &r) bool checkCollision(h_line_t &l, SDL_Rect &r) {
{
// Comprueba si la linea esta por encima del rectangulo // Comprueba si la linea esta por encima del rectangulo
if (l.y < r.y) if (l.y < r.y) {
{
return false; return false;
} }
// Comprueba si la linea esta por debajo del rectangulo // Comprueba si la linea esta por debajo del rectangulo
if (l.y >= r.y + r.h) if (l.y >= r.y + r.h) {
{
return false; return false;
} }
// Comprueba si el inicio de la linea esta a la derecha del rectangulo // Comprueba si el inicio de la linea esta a la derecha del rectangulo
if (l.x1 >= r.x + r.w) if (l.x1 >= r.x + r.w) {
{
return false; return false;
} }
// Comprueba si el final de la linea esta a la izquierda del rectangulo // Comprueba si el final de la linea esta a la izquierda del rectangulo
if (l.x2 < r.x) if (l.x2 < r.x) {
{
return false; return false;
} }
@@ -176,29 +148,24 @@ bool checkCollision(h_line_t &l, SDL_Rect &r)
} }
// Detector de colisiones entre una linea vertical y un rectangulo // Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(v_line_t &l, SDL_Rect &r) bool checkCollision(v_line_t &l, SDL_Rect &r) {
{
// Comprueba si la linea esta por la izquierda del rectangulo // Comprueba si la linea esta por la izquierda del rectangulo
if (l.x < r.x) if (l.x < r.x) {
{
return false; return false;
} }
// Comprueba si la linea esta por la derecha del rectangulo // Comprueba si la linea esta por la derecha del rectangulo
if (l.x >= r.x + r.w) if (l.x >= r.x + r.w) {
{
return false; return false;
} }
// Comprueba si el inicio de la linea esta debajo del rectangulo // Comprueba si el inicio de la linea esta debajo del rectangulo
if (l.y1 >= r.y + r.h) if (l.y1 >= r.y + r.h) {
{
return false; return false;
} }
// Comprueba si el final de la linea esta encima del rectangulo // Comprueba si el final de la linea esta encima del rectangulo
if (l.y2 < r.y) if (l.y2 < r.y) {
{
return false; return false;
} }
@@ -207,29 +174,24 @@ bool checkCollision(v_line_t &l, SDL_Rect &r)
} }
// Detector de colisiones entre una linea horizontal y un punto // Detector de colisiones entre una linea horizontal y un punto
bool checkCollision(h_line_t &l, SDL_Point &p) bool checkCollision(h_line_t &l, SDL_Point &p) {
{
// Comprueba si el punto esta sobre la linea // Comprueba si el punto esta sobre la linea
if (p.y > l.y) if (p.y > l.y) {
{
return false; return false;
} }
// Comprueba si el punto esta bajo la linea // Comprueba si el punto esta bajo la linea
if (p.y < l.y) if (p.y < l.y) {
{
return false; return false;
} }
// Comprueba si el punto esta a la izquierda de la linea // Comprueba si el punto esta a la izquierda de la linea
if (p.x < l.x1) if (p.x < l.x1) {
{
return false; return false;
} }
// Comprueba si el punto esta a la derecha de la linea // Comprueba si el punto esta a la derecha de la linea
if (p.x > l.x2) if (p.x > l.x2) {
{
return false; return false;
} }
@@ -238,8 +200,7 @@ bool checkCollision(h_line_t &l, SDL_Point &p)
} }
// Detector de colisiones entre dos lineas // Detector de colisiones entre dos lineas
SDL_Point checkCollision(line_t &l1, line_t &l2) SDL_Point checkCollision(line_t &l1, line_t &l2) {
{
const float x1 = l1.x1; const float x1 = l1.x1;
const float y1 = l1.y1; const float y1 = l1.y1;
const float x2 = l1.x2; const float x2 = l1.x2;
@@ -255,8 +216,7 @@ SDL_Point checkCollision(line_t &l1, line_t &l2)
float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)); float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
// if uA and uB are between 0-1, lines are colliding // if uA and uB are between 0-1, lines are colliding
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
{
// Calcula la intersección // Calcula la intersección
const float x = x1 + (uA * (x2 - x1)); const float x = x1 + (uA * (x2 - x1));
const float y = y1 + (uA * (y2 - y1)); const float y = y1 + (uA * (y2 - y1));
@@ -267,8 +227,7 @@ SDL_Point checkCollision(line_t &l1, line_t &l2)
} }
// Detector de colisiones entre dos lineas // Detector de colisiones entre dos lineas
SDL_Point checkCollision(d_line_t &l1, v_line_t &l2) SDL_Point checkCollision(d_line_t &l1, v_line_t &l2) {
{
const float x1 = l1.x1; const float x1 = l1.x1;
const float y1 = l1.y1; const float y1 = l1.y1;
const float x2 = l1.x2; const float x2 = l1.x2;
@@ -284,8 +243,7 @@ SDL_Point checkCollision(d_line_t &l1, v_line_t &l2)
float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)); float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
// if uA and uB are between 0-1, lines are colliding // if uA and uB are between 0-1, lines are colliding
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
{
// Calcula la intersección // Calcula la intersección
const float x = x1 + (uA * (x2 - x1)); const float x = x1 + (uA * (x2 - x1));
const float y = y1 + (uA * (y2 - y1)); const float y = y1 + (uA * (y2 - y1));
@@ -318,12 +276,10 @@ SDL_Point checkCollision(d_line_t &l1, v_line_t &l2)
}*/ }*/
// Normaliza una linea diagonal // Normaliza una linea diagonal
void normalizeLine(d_line_t &l) void normalizeLine(d_line_t &l) {
{
// Las lineas diagonales van de izquierda a derecha // Las lineas diagonales van de izquierda a derecha
// x2 mayor que x1 // x2 mayor que x1
if (l.x2 < l.x1) if (l.x2 < l.x1) {
{
const int x = l.x1; const int x = l.x1;
const int y = l.y1; const int y = l.y1;
l.x1 = l.x2; l.x1 = l.x2;
@@ -334,35 +290,29 @@ void normalizeLine(d_line_t &l)
} }
// Detector de colisiones entre un punto y una linea diagonal // Detector de colisiones entre un punto y una linea diagonal
bool checkCollision(SDL_Point &p, d_line_t &l) bool checkCollision(SDL_Point &p, d_line_t &l) {
{
// Comprueba si el punto está en alineado con la linea // Comprueba si el punto está en alineado con la linea
if (abs(p.x - l.x1) != abs(p.y - l.y1)) if (abs(p.x - l.x1) != abs(p.y - l.y1)) {
{
return false; return false;
} }
// Comprueba si está a la derecha de la linea // Comprueba si está a la derecha de la linea
if (p.x > l.x1 && p.x > l.x2) if (p.x > l.x1 && p.x > l.x2) {
{
return false; return false;
} }
// Comprueba si está a la izquierda de la linea // Comprueba si está a la izquierda de la linea
if (p.x < l.x1 && p.x < l.x2) if (p.x < l.x1 && p.x < l.x2) {
{
return false; return false;
} }
// Comprueba si está por encima de la linea // Comprueba si está por encima de la linea
if (p.y > l.y1 && p.y > l.y2) if (p.y > l.y1 && p.y > l.y2) {
{
return false; return false;
} }
// Comprueba si está por debajo de la linea // Comprueba si está por debajo de la linea
if (p.y < l.y1 && p.y < l.y2) if (p.y < l.y1 && p.y < l.y2) {
{
return false; return false;
} }
@@ -380,170 +330,135 @@ bool checkCollision(SDL_Point &p, d_line_t &l)
} }
// Devuelve un color_t a partir de un string // Devuelve un color_t a partir de un string
color_t stringToColor(palette_e pal, std::string str) color_t stringToColor(palette_e pal, std::string str) {
{ if (pal == p_zxspectrum) {
if (pal == p_zxspectrum) if (str == "black") {
{
if (str == "black")
{
return {0x00, 0x00, 0x00}; return {0x00, 0x00, 0x00};
} }
else if (str == "bright_black") else if (str == "bright_black") {
{
return {0x00, 0x00, 0x00}; return {0x00, 0x00, 0x00};
} }
else if (str == "blue") else if (str == "blue") {
{
return {0x00, 0x00, 0xd8}; return {0x00, 0x00, 0xd8};
} }
else if (str == "bright_blue") else if (str == "bright_blue") {
{
return {0x00, 0x00, 0xFF}; return {0x00, 0x00, 0xFF};
} }
else if (str == "red") else if (str == "red") {
{
return {0xd8, 0x00, 0x00}; return {0xd8, 0x00, 0x00};
} }
else if (str == "bright_red") else if (str == "bright_red") {
{
return {0xFF, 0x00, 0x00}; return {0xFF, 0x00, 0x00};
} }
else if (str == "magenta") else if (str == "magenta") {
{
return {0xd8, 0x00, 0xd8}; return {0xd8, 0x00, 0xd8};
} }
else if (str == "bright_magenta") else if (str == "bright_magenta") {
{
return {0xFF, 0x00, 0xFF}; return {0xFF, 0x00, 0xFF};
} }
else if (str == "green") else if (str == "green") {
{
return {0x00, 0xd8, 0x00}; return {0x00, 0xd8, 0x00};
} }
else if (str == "bright_green") else if (str == "bright_green") {
{
return {0x00, 0xFF, 0x00}; return {0x00, 0xFF, 0x00};
} }
else if (str == "cyan") else if (str == "cyan") {
{
return {0x00, 0xd8, 0xd8}; return {0x00, 0xd8, 0xd8};
} }
else if (str == "bright_cyan") else if (str == "bright_cyan") {
{
return {0x00, 0xFF, 0xFF}; return {0x00, 0xFF, 0xFF};
} }
else if (str == "yellow") else if (str == "yellow") {
{
return {0xd8, 0xd8, 0x00}; return {0xd8, 0xd8, 0x00};
} }
else if (str == "bright_yellow") else if (str == "bright_yellow") {
{
return {0xFF, 0xFF, 0x00}; return {0xFF, 0xFF, 0x00};
} }
else if (str == "white") else if (str == "white") {
{
return {0xd8, 0xd8, 0xd8}; return {0xd8, 0xd8, 0xd8};
} }
else if (str == "bright_white") else if (str == "bright_white") {
{
return {0xFF, 0xFF, 0xFF}; return {0xFF, 0xFF, 0xFF};
} }
} }
else if (pal == p_zxarne) else if (pal == p_zxarne) { // zxarne
{ // zxarne if (str == "black") {
if (str == "black")
{
return {0x00, 0x00, 0x00}; return {0x00, 0x00, 0x00};
} }
else if (str == "bright_black") else if (str == "bright_black") {
{
return {0x3C, 0x35, 0x1F}; return {0x3C, 0x35, 0x1F};
} }
else if (str == "blue") else if (str == "blue") {
{
return {0x31, 0x33, 0x90}; return {0x31, 0x33, 0x90};
} }
else if (str == "bright_blue") else if (str == "bright_blue") {
{
return {0x15, 0x59, 0xDB}; return {0x15, 0x59, 0xDB};
} }
else if (str == "red") else if (str == "red") {
{
return {0xA7, 0x32, 0x11}; return {0xA7, 0x32, 0x11};
} }
else if (str == "bright_red") else if (str == "bright_red") {
{
return {0xD8, 0x55, 0x25}; return {0xD8, 0x55, 0x25};
} }
else if (str == "magenta") else if (str == "magenta") {
{
return {0xA1, 0x55, 0x89}; return {0xA1, 0x55, 0x89};
} }
else if (str == "bright_magenta") else if (str == "bright_magenta") {
{
return {0xCD, 0x7A, 0x50}; return {0xCD, 0x7A, 0x50};
} }
else if (str == "green") else if (str == "green") {
{
return {0x62, 0x9A, 0x31}; return {0x62, 0x9A, 0x31};
} }
else if (str == "bright_green") else if (str == "bright_green") {
{
return {0x9C, 0xD3, 0x3C}; return {0x9C, 0xD3, 0x3C};
} }
else if (str == "cyan") else if (str == "cyan") {
{
return {0x28, 0xA4, 0xCB}; return {0x28, 0xA4, 0xCB};
} }
else if (str == "bright_cyan") else if (str == "bright_cyan") {
{
return {0x65, 0xDC, 0xD6}; return {0x65, 0xDC, 0xD6};
} }
else if (str == "yellow") else if (str == "yellow") {
{
return {0xE8, 0xBC, 0x50}; return {0xE8, 0xBC, 0x50};
} }
else if (str == "bright_yellow") else if (str == "bright_yellow") {
{
return {0xF1, 0xE7, 0x82}; return {0xF1, 0xE7, 0x82};
} }
else if (str == "white") else if (str == "white") {
{
return {0xBF, 0xBF, 0xBD}; return {0xBF, 0xBF, 0xBD};
} }
else if (str == "bright_white") else if (str == "bright_white") {
{
return {0xF2, 0xF1, 0xED}; return {0xF2, 0xF1, 0xED};
} }
} }
@@ -552,38 +467,28 @@ color_t stringToColor(palette_e pal, std::string str)
} }
// Convierte una cadena en un valor booleano // Convierte una cadena en un valor booleano
bool stringToBool(std::string str) bool stringToBool(std::string str) {
{ if (str == "true") {
if (str == "true")
{
return true; return true;
} } else {
else
{
return false; return false;
} }
} }
// Convierte un valor booleano en una cadena // Convierte un valor booleano en una cadena
std::string boolToString(bool value) std::string boolToString(bool value) {
{ if (value) {
if (value)
{
return "true"; return "true";
} } else {
else
{
return "false"; return "false";
} }
} }
// Convierte una cadena a minusculas // Convierte una cadena a minusculas
std::string toLower(std::string str) std::string toLower(std::string str) {
{
const char *original = str.c_str(); const char *original = str.c_str();
char *lower = (char *)malloc(str.size() + 1); char *lower = (char *)malloc(str.size() + 1);
for (int i = 0; i < (int)str.size(); ++i) for (int i = 0; i < (int)str.size(); ++i) {
{
char c = original[i]; char c = original[i];
lower[i] = (c >= 65 && c <= 90) ? c + 32 : c; lower[i] = (c >= 65 && c <= 90) ? c + 32 : c;
} }

View File

@@ -1,8 +1,9 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <string> // for string, basic_string
#include <vector> // for vector #include <string> // for string, basic_string
#include <vector> // for vector
// Dificultad del juego // Dificultad del juego
constexpr int DIFFICULTY_EASY = 0; constexpr int DIFFICULTY_EASY = 0;
@@ -10,111 +11,105 @@ constexpr int DIFFICULTY_NORMAL = 1;
constexpr int DIFFICULTY_HARD = 2; constexpr int DIFFICULTY_HARD = 2;
// Estructura para definir un circulo // Estructura para definir un circulo
struct circle_t struct circle_t {
{ int x;
int x; int y;
int y; int r;
int r;
}; };
// Estructura para definir una linea horizontal // Estructura para definir una linea horizontal
struct h_line_t struct h_line_t {
{ int x1, x2, y;
int x1, x2, y;
}; };
// Estructura para definir una linea vertical // Estructura para definir una linea vertical
struct v_line_t struct v_line_t {
{ int x, y1, y2;
int x, y1, y2;
}; };
// Estructura para definir una linea diagonal // Estructura para definir una linea diagonal
struct d_line_t struct d_line_t {
{ int x1, y1, x2, y2;
int x1, y1, x2, y2;
}; };
// Estructura para definir una linea // Estructura para definir una linea
struct line_t struct line_t {
{ int x1, y1, x2, y2;
int x1, y1, x2, y2;
}; };
// Estructura para definir un color // Estructura para definir un color
struct color_t struct color_t {
{
Uint8 r; Uint8 r;
Uint8 g; Uint8 g;
Uint8 b; Uint8 b;
color_t() : r(0), g(0), b(0) {} // Constructor por defecto color_t()
color_t(Uint8 red, Uint8 green, Uint8 blue) : r(red), g(green), b(blue) {} : r(0),
g(0),
b(0) {} // Constructor por defecto
color_t(Uint8 red, Uint8 green, Uint8 blue)
: r(red),
g(green),
b(blue) {}
}; };
// Tipos de paleta // Tipos de paleta
enum palette_e enum palette_e {
{ p_zxspectrum,
p_zxspectrum, p_zxarne
p_zxarne
}; };
// Estructura para saber la seccion y subseccion del programa // Estructura para saber la seccion y subseccion del programa
struct section_t struct section_t {
{ Uint8 name;
Uint8 name; Uint8 subsection;
Uint8 subsection;
}; };
// Estructura para mapear el teclado usado en la demo // Estructura para mapear el teclado usado en la demo
struct demoKeys_t struct demoKeys_t {
{ Uint8 left;
Uint8 left; Uint8 right;
Uint8 right; Uint8 noInput;
Uint8 noInput; Uint8 fire;
Uint8 fire; Uint8 fireLeft;
Uint8 fireLeft; Uint8 fireRight;
Uint8 fireRight;
}; };
// Estructura para albergar métodos de control // Estructura para albergar métodos de control
struct input_t struct input_t {
{ int id; // Identificador en el vector de mandos
int id; // Identificador en el vector de mandos std::string name; // Nombre del dispositivo
std::string name; // Nombre del dispositivo Uint8 deviceType; // Tipo de dispositivo (teclado o mando)
Uint8 deviceType; // Tipo de dispositivo (teclado o mando)
}; };
// Estructura con opciones de la pantalla // Estructura con opciones de la pantalla
struct op_screen_t struct op_screen_t {
{ int windowWidth; // Ancho de la ventana
int windowWidth; // Ancho de la ventana int windowHeight; // Alto de la ventana
int windowHeight; // Alto de la ventana
}; };
// Estructura con todas las opciones de configuración del programa // Estructura con todas las opciones de configuración del programa
struct options_t struct options_t {
{ Uint8 difficulty; // Dificultad del juego
Uint8 difficulty; // Dificultad del juego Uint8 playerSelected; // Jugador seleccionado para el modo 1P
Uint8 playerSelected; // Jugador seleccionado para el modo 1P std::vector<input_t> input; // Modo de control (teclado o mando)
std::vector<input_t> input; // Modo de control (teclado o mando) Uint8 language; // Idioma usado en el juego
Uint8 language; // Idioma usado en el juego
Uint32 videoMode; // Contiene el valor del modo de pantalla completa Uint32 videoMode; // Contiene el valor del modo de pantalla completa
int windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana int windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana
Uint32 filter; // Filtro usado para el escalado de la imagen Uint32 filter; // Filtro usado para el escalado de la imagen
bool vSync; // Indica si se quiere usar vsync o no bool vSync; // Indica si se quiere usar vsync o no
int gameWidth; // Ancho de la resolucion nativa del juego int gameWidth; // Ancho de la resolucion nativa del juego
int gameHeight; // Alto de la resolucion nativa del juego int gameHeight; // Alto de la resolucion nativa del juego
bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa
bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa
bool borderEnabled; // Indica si ha de mostrar el borde en el modo de ventana bool borderEnabled; // Indica si ha de mostrar el borde en el modo de ventana
int borderWidth; // Cantidad de pixels que se añade en el borde de la ventana int borderWidth; // Cantidad de pixels que se añade en el borde de la ventana
int borderHeight; // Cantidad de pixels que se añade en el borde de la ventana int borderHeight; // Cantidad de pixels que se añade en el borde de la ventana
palette_e palette; // Paleta de colores a usar en el juego palette_e palette; // Paleta de colores a usar en el juego
bool console; // Indica si ha de mostrar información por la consola de texto bool console; // Indica si ha de mostrar información por la consola de texto
op_screen_t screen; // Opciones relativas a la clase screen op_screen_t screen; // Opciones relativas a la clase screen
}; };
// Calcula el cuadrado de la distancia entre dos puntos // Calcula el cuadrado de la distancia entre dos puntos

View File

@@ -1,138 +1,115 @@
#include "writer.h" #include "writer.h"
#include "text.h" // for Text #include "text.h" // for Text
// Constructor // Constructor
Writer::Writer(Text *text) Writer::Writer(Text *text) {
{ // Copia los punteros
// Copia los punteros this->text = text;
this->text = text;
// Inicializa variables // Inicializa variables
posX = 0; posX = 0;
posY = 0; posY = 0;
kerning = 0; kerning = 0;
caption = ""; caption = "";
speed = 0; speed = 0;
writingCounter = 0; writingCounter = 0;
index = 0; index = 0;
lenght = 0; lenght = 0;
completed = false; completed = false;
enabled = false; enabled = false;
enabledCounter = 0; enabledCounter = 0;
finished = false; finished = false;
} }
// Actualiza el objeto // Actualiza el objeto
void Writer::update() void Writer::update() {
{ if (enabled) {
if (enabled) if (!completed) { // No completado
{ if (writingCounter > 0) {
if (!completed) writingCounter--;
{ // No completado }
if (writingCounter > 0)
{
writingCounter--;
}
else if (writingCounter == 0) else if (writingCounter == 0) {
{ index++;
index++; writingCounter = speed;
writingCounter = speed; }
}
if (index == lenght) if (index == lenght) {
{ completed = true;
completed = true; }
} }
}
if (completed) if (completed) { // Completado
{ // Completado if (enabledCounter > 0) {
if (enabledCounter > 0) enabledCounter--;
{ } else if (enabledCounter == 0) {
enabledCounter--; finished = true;
} }
else if (enabledCounter == 0) }
{ }
finished = true;
}
}
}
} }
// Dibuja el objeto en pantalla // Dibuja el objeto en pantalla
void Writer::render() void Writer::render() {
{ if (enabled) {
if (enabled) text->write(posX, posY, caption, kerning, index);
{ }
text->write(posX, posY, caption, kerning, index);
}
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setPosX(int value) void Writer::setPosX(int value) {
{ posX = value;
posX = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setPosY(int value) void Writer::setPosY(int value) {
{ posY = value;
posY = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setKerning(int value) void Writer::setKerning(int value) {
{ kerning = value;
kerning = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setCaption(std::string text) void Writer::setCaption(std::string text) {
{ caption = text;
caption = text; lenght = text.length();
lenght = text.length();
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setSpeed(int value) void Writer::setSpeed(int value) {
{ speed = value;
speed = value; writingCounter = value;
writingCounter = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setEnabled(bool value) void Writer::setEnabled(bool value) {
{ enabled = value;
enabled = value;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool Writer::IsEnabled() bool Writer::IsEnabled() {
{ return enabled;
return enabled;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Writer::setEnabledCounter(int time) void Writer::setEnabledCounter(int time) {
{ enabledCounter = time;
enabledCounter = time;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Writer::getEnabledCounter() int Writer::getEnabledCounter() {
{ return enabledCounter;
return enabledCounter;
} }
// Centra la cadena de texto a un punto X // Centra la cadena de texto a un punto X
void Writer::center(int x) void Writer::center(int x) {
{ setPosX(x - (text->lenght(caption, kerning) / 2));
setPosX(x - (text->lenght(caption, kerning) / 2));
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool Writer::hasFinished() bool Writer::hasFinished() {
{ return finished;
return finished;
} }

View File

@@ -4,66 +4,65 @@
class Text; class Text;
// Clase Writer. Pinta texto en pantalla letra a letra a partir de una cadena y un bitmap // Clase Writer. Pinta texto en pantalla letra a letra a partir de una cadena y un bitmap
class Writer class Writer {
{ private:
private: // Objetos y punteros
// Objetos y punteros Text *text; // Objeto encargado de escribir el texto
Text *text; // Objeto encargado de escribir el texto
// Variables // Variables
int posX; // Posicion en el eje X donde empezar a escribir el texto int posX; // Posicion en el eje X donde empezar a escribir el texto
int posY; // Posicion en el eje Y donde empezar a escribir el texto int posY; // Posicion en el eje Y donde empezar a escribir el texto
int kerning; // Kerning del texto, es decir, espaciado entre caracteres int kerning; // Kerning del texto, es decir, espaciado entre caracteres
std::string caption; // El texto para escribir std::string caption; // El texto para escribir
int speed; // Velocidad de escritura int speed; // Velocidad de escritura
int writingCounter; // Temporizador de escritura para cada caracter int writingCounter; // Temporizador de escritura para cada caracter
int index; // Posición del texto que se está escribiendo int index; // Posición del texto que se está escribiendo
int lenght; // Longitud de la cadena a escribir int lenght; // Longitud de la cadena a escribir
bool completed; // Indica si se ha escrito todo el texto bool completed; // Indica si se ha escrito todo el texto
bool enabled; // Indica si el objeto está habilitado bool enabled; // Indica si el objeto está habilitado
int enabledCounter; // Temporizador para deshabilitar el objeto int enabledCounter; // Temporizador para deshabilitar el objeto
bool finished; // Indica si ya ha terminado bool finished; // Indica si ya ha terminado
public: public:
// Constructor // Constructor
Writer(Text *text); Writer(Text *text);
// Actualiza el objeto // Actualiza el objeto
void update(); void update();
// Dibuja el objeto en pantalla // Dibuja el objeto en pantalla
void render(); void render();
// Establece el valor de la variable // Establece el valor de la variable
void setPosX(int value); void setPosX(int value);
// Establece el valor de la variable // Establece el valor de la variable
void setPosY(int value); void setPosY(int value);
// Establece el valor de la variable // Establece el valor de la variable
void setKerning(int value); void setKerning(int value);
// Establece el valor de la variable // Establece el valor de la variable
void setCaption(std::string text); void setCaption(std::string text);
// Establece el valor de la variable // Establece el valor de la variable
void setSpeed(int value); void setSpeed(int value);
// Establece el valor de la variable // Establece el valor de la variable
void setEnabled(bool value); void setEnabled(bool value);
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool IsEnabled(); bool IsEnabled();
// Establece el valor de la variable // Establece el valor de la variable
void setEnabledCounter(int time); void setEnabledCounter(int time);
// Obtiene el valor de la variable // Obtiene el valor de la variable
int getEnabledCounter(); int getEnabledCounter();
// Centra la cadena de texto a un punto X // Centra la cadena de texto a un punto X
void center(int x); void center(int x);
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool hasFinished(); bool hasFinished();
}; };