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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,9 +1,11 @@
#pragma once
#include <SDL3/SDL.h>
#include <string> // for string
#include <vector> // for vector
#include "utils.h" // for circle_t
#include <SDL3/SDL.h>
#include <string> // for string
#include <vector> // for vector
#include "utils.h" // for circle_t
class AnimatedSprite;
class Texture;
@@ -16,25 +18,24 @@ constexpr int ITEM_COFFEE = 5;
constexpr int ITEM_COFFEE_MACHINE = 6;
// Clase Item
class Item
{
private:
class Item {
private:
// Objetos y punteros
AnimatedSprite *sprite; // Sprite con los graficos del objeto
AnimatedSprite *sprite; // Sprite con los graficos del objeto
// Variables
float posX; // Posición X del objeto
float posY; // Posición Y del objeto
Uint8 width; // Ancho del objeto
Uint8 height; // Alto del objeto
float velX; // Velocidad en el eje X
float velY; // Velocidad en el eje Y
float accelX; // Aceleración en el eje X
float accelY; // Aceleración en el eje Y
bool floorCollision; // Indica si el objeto colisiona con el suelo
Uint8 kind; // Especifica el tipo de objeto que es
bool enabled; // Especifica si el objeto está habilitado
circle_t collider; // Circulo de colisión del objeto
float posX; // Posición X del objeto
float posY; // Posición Y del objeto
Uint8 width; // Ancho del objeto
Uint8 height; // Alto del objeto
float velX; // Velocidad en el eje X
float velY; // Velocidad en el eje Y
float accelX; // Aceleración en el eje X
float accelY; // Aceleración en el eje Y
bool floorCollision; // Indica si el objeto colisiona con el suelo
Uint8 kind; // Especifica el tipo de objeto que es
bool enabled; // Especifica si el objeto está habilitado
circle_t collider; // Circulo de colisión del objeto
// Alinea el circulo de colisión con la posición del objeto
void shiftColliders();
@@ -42,8 +43,8 @@ private:
// Actualiza la posición y estados del objeto
void move();
public:
Uint16 timeToLive; // Temporizador con el tiempo que el objeto está presente
public:
Uint16 timeToLive; // Temporizador con el tiempo que el objeto está presente
// Constructor
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 <fstream> // for basic_ifstream, basic_istream, ifstream
#include "asset.h" // for Asset
// Constructor
Lang::Lang(Asset *mAsset)
{
Lang::Lang(Asset *mAsset) {
this->mAsset = mAsset;
}
// Destructor
Lang::~Lang()
{
Lang::~Lang() {
}
// Inicializa los textos del juego en el idioma seleccionado
bool Lang::setLang(Uint8 lang)
{
bool Lang::setLang(Uint8 lang) {
std::string file;
switch (lang)
{
case es_ES:
file = mAsset->get("es_ES.txt");
break;
switch (lang) {
case es_ES:
file = mAsset->get("es_ES.txt");
break;
case en_UK:
file = mAsset->get("en_UK.txt");
break;
case en_UK:
file = mAsset->get("en_UK.txt");
break;
case ba_BA:
file = mAsset->get("ba_BA.txt");
break;
case ba_BA:
file = mAsset->get("ba_BA.txt");
break;
default:
file = mAsset->get("en_UK.txt");
break;
default:
file = mAsset->get("en_UK.txt");
break;
}
for (int i = 0; i < MAX_TEXT_STRINGS; i++)
@@ -43,20 +41,17 @@ bool Lang::setLang(Uint8 lang)
bool success = false;
std::ifstream rfile(file);
if (rfile.is_open() && rfile.good())
{
if (rfile.is_open() && rfile.good()) {
success = true;
std::string line;
// lee el resto de datos del fichero
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
const bool test1 = line.substr(0,1) != "#";
const bool test1 = line.substr(0, 1) != "#";
const bool test2 = !line.empty();
if (test1 && test2)
{
if (test1 && test2) {
mTextStrings[index] = line;
index++;
}
@@ -67,7 +62,6 @@ bool Lang::setLang(Uint8 lang)
}
// Obtiene la cadena de texto del indice
std::string Lang::getText(int index)
{
std::string Lang::getText(int index) {
return mTextStrings[index];
}

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,13 +1,14 @@
#include "screen.h"
#include <SDL3/SDL.h>
#include <algorithm> // for max, min
#include <iostream> // for basic_ostream, operator<<, cout, endl
#include <string> // for basic_string, char_traits, string
#include <algorithm> // for max, min
#include <iostream> // for basic_ostream, operator<<, cout, endl
#include <string> // for basic_string, char_traits, string
class Asset;
// 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
this->window = window;
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
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);
}
if (gameCanvas == nullptr)
{
if (options->console)
{
if (gameCanvas == nullptr) {
if (options->console) {
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
Screen::~Screen()
{
Screen::~Screen() {
SDL_DestroyTexture(gameCanvas);
}
// 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_RenderClear(renderer);
}
// Prepara para empezar a dibujar en la textura de juego
void Screen::start()
{
void Screen::start() {
SDL_SetRenderTarget(renderer, gameCanvas);
}
// Vuelca el contenido del renderizador en pantalla
void Screen::blit()
{
void Screen::blit() {
// Vuelve a dejar el renderizador en modo normal
SDL_SetRenderTarget(renderer, nullptr);
@@ -86,29 +80,25 @@ void Screen::blit()
}
// Establece el modo de video
void Screen::setVideoMode(int videoMode)
{
void Screen::setVideoMode(int videoMode) {
// Aplica el modo de video
SDL_SetWindowFullscreen(window, videoMode != 0);
// Si está activo el modo ventana quita el borde
if (videoMode == 0)
{
if (videoMode == 0) {
// Muestra el puntero
SDL_ShowCursor();
// Esconde la ventana
//SDL_HideWindow(window);
// SDL_HideWindow(window);
if (options->borderEnabled)
{
if (options->borderEnabled) {
windowWidth = gameCanvasWidth + borderWidth;
windowHeight = gameCanvasHeight + borderHeight;
dest = {0 + (borderWidth / 2), 0 + (borderHeight / 2), gameCanvasWidth, gameCanvasHeight};
}
else
{
else {
windowWidth = gameCanvasWidth;
windowHeight = gameCanvasHeight;
dest = {0, 0, gameCanvasWidth, gameCanvasHeight};
@@ -119,12 +109,11 @@ void Screen::setVideoMode(int videoMode)
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
// Muestra la ventana
//SDL_ShowWindow(window);
// SDL_ShowWindow(window);
}
// 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
SDL_HideCursor();
@@ -132,12 +121,10 @@ void Screen::setVideoMode(int videoMode)
SDL_GetWindowSize(window, &windowWidth, &windowHeight);
// 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
int scale = 0;
while (((gameCanvasWidth * (scale + 1)) <= windowWidth) && ((gameCanvasHeight * (scale + 1)) <= windowHeight))
{
while (((gameCanvasWidth * (scale + 1)) <= windowWidth) && ((gameCanvasHeight * (scale + 1)) <= windowHeight)) {
scale++;
}
@@ -145,27 +132,20 @@ void Screen::setVideoMode(int videoMode)
dest.h = gameCanvasHeight * scale;
dest.x = (windowWidth - dest.w) / 2;
dest.y = (windowHeight - dest.h) / 2;
}
else if (options->keepAspect)
{
} else if (options->keepAspect) {
float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight;
if ((windowWidth - gameCanvasWidth) >= (windowHeight - gameCanvasHeight))
{
if ((windowWidth - gameCanvasWidth) >= (windowHeight - gameCanvasHeight)) {
dest.h = windowHeight;
dest.w = (int)((windowHeight * ratio) + 0.5f);
dest.x = (windowWidth - dest.w) / 2;
dest.y = (windowHeight - dest.h) / 2;
}
else
{
} else {
dest.w = windowWidth;
dest.h = (int)((windowWidth / ratio) + 0.5f);
dest.x = (windowWidth - dest.w) / 2;
dest.y = (windowHeight - dest.h) / 2;
}
}
else
{
} else {
dest.w = windowWidth;
dest.h = windowHeight;
dest.x = dest.y = 0;
@@ -182,83 +162,70 @@ void Screen::setVideoMode(int videoMode)
}
// Camibia entre pantalla completa y ventana
void Screen::switchVideoMode()
{
void Screen::switchVideoMode() {
options->videoMode = (options->videoMode == 0) ? SDL_WINDOW_FULLSCREEN : 0;
setVideoMode(options->videoMode);
}
// Cambia el tamaño de la ventana
void Screen::setWindowSize(int size)
{
void Screen::setWindowSize(int size) {
options->windowSize = size;
setVideoMode(0);
}
// Reduce el tamaño de la ventana
void Screen::decWindowSize()
{
void Screen::decWindowSize() {
--options->windowSize;
options->windowSize = std::max(options->windowSize, 1);
setVideoMode(0);
}
// Aumenta el tamaño de la ventana
void Screen::incWindowSize()
{
void Screen::incWindowSize() {
++options->windowSize;
options->windowSize = std::min(options->windowSize, 4);
setVideoMode(0);
}
// Cambia el color del borde
void Screen::setBorderColor(color_t color)
{
void Screen::setBorderColor(color_t color) {
borderColor = color;
}
// Cambia el tipo de mezcla
void Screen::setBlendMode(SDL_BlendMode blendMode)
{
void Screen::setBlendMode(SDL_BlendMode blendMode) {
SDL_SetRenderDrawBlendMode(renderer, blendMode);
}
// Establece el tamaño del borde
void Screen::setBorderWidth(int s)
{
void Screen::setBorderWidth(int s) {
options->borderWidth = s;
}
// Establece el tamaño del borde
void Screen::setBorderHeight(int s)
{
void Screen::setBorderHeight(int s) {
options->borderHeight = s;
}
// 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;
}
// Cambia entre borde visible y no visible
void Screen::switchBorder()
{
void Screen::switchBorder() {
options->borderEnabled = !options->borderEnabled;
setVideoMode(0);
}
// Activa el fade
void Screen::setFade()
{
void Screen::setFade() {
fade = true;
}
// Comprueba si ha terminado el fade
bool Screen::fadeEnded()
{
if (fade || fadeCounter > 0)
{
bool Screen::fadeEnded() {
if (fade || fadeCounter > 0) {
return false;
}
@@ -266,16 +233,13 @@ bool Screen::fadeEnded()
}
// Activa el spectrum fade
void Screen::setspectrumFade()
{
void Screen::setspectrumFade() {
spectrumFade = true;
}
// Comprueba si ha terminado el spectrum fade
bool Screen::spectrumFadeEnded()
{
if (spectrumFade || spectrumFadeCounter > 0)
{
bool Screen::spectrumFadeEnded() {
if (spectrumFade || spectrumFadeCounter > 0) {
return false;
}
@@ -283,33 +247,27 @@ bool Screen::spectrumFadeEnded()
}
// Inicializa las variables para el fade
void Screen::iniFade()
{
void Screen::iniFade() {
fade = false;
fadeCounter = 0;
fadeLenght = 200;
}
// Actualiza el fade
void Screen::updateFade()
{
if (!fade)
{
void Screen::updateFade() {
if (!fade) {
return;
}
fadeCounter++;
if (fadeCounter > fadeLenght)
{
if (fadeCounter > fadeLenght) {
iniFade();
}
}
// Dibuja el fade
void Screen::renderFade()
{
if (!fade)
{
void Screen::renderFade() {
if (!fade) {
return;
}
@@ -322,8 +280,7 @@ void Screen::renderFade()
}
// Inicializa las variables para el fade spectrum
void Screen::iniSpectrumFade()
{
void Screen::iniSpectrumFade() {
spectrumFade = false;
spectrumFadeCounter = 0;
spectrumFadeLenght = 50;
@@ -332,33 +289,27 @@ void Screen::iniSpectrumFade()
// Inicializa el vector de colores
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));
}
}
// Actualiza el spectrum fade
void Screen::updateSpectrumFade()
{
if (!spectrumFade)
{
void Screen::updateSpectrumFade() {
if (!spectrumFade) {
return;
}
spectrumFadeCounter++;
if (spectrumFadeCounter > spectrumFadeLenght)
{
if (spectrumFadeCounter > spectrumFadeLenght) {
iniSpectrumFade();
SDL_SetTextureColorMod(gameCanvas, 255, 255, 255);
}
}
// Dibuja el spectrum fade
void Screen::renderSpectrumFade()
{
if (!spectrumFade)
{
void Screen::renderSpectrumFade() {
if (!spectrumFade) {
return;
}
@@ -370,15 +321,13 @@ void Screen::renderSpectrumFade()
}
// Actualiza los efectos
void Screen::updateFX()
{
void Screen::updateFX() {
updateFade();
updateSpectrumFade();
}
// Dibuja los efectos
void Screen::renderFX()
{
void Screen::renderFX() {
renderFade();
renderSpectrumFade();
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,21 +4,20 @@
class Texture;
// Clase sprite
class Sprite
{
protected:
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 w; // Ancho del sprite
int h; // Alto del sprite
class Sprite {
protected:
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 w; // Ancho del sprite
int h; // Alto del sprite
SDL_Renderer *renderer; // Puntero al renderizador de la ventana
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_Renderer *renderer; // Puntero al renderizador de la ventana
Texture *texture; // Textura donde estan todos los dibujos del sprite
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
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);

View File

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

View File

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

View File

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

View File

@@ -1,22 +1,22 @@
#pragma once
#include <SDL3/SDL.h>
#include <string> // for basic_string, string
class Texture
{
private:
#include <string> // for basic_string, string
class Texture {
private:
// Objetos y punteros
SDL_Texture *texture; // La textura
SDL_Renderer *renderer; // Renderizador donde dibujar la textura
SDL_Texture *texture; // La textura
SDL_Renderer *renderer; // Renderizador donde dibujar la textura
// Variables
int width; // Ancho de la imagen
int height; // Alto de la imagen
std::string path; // Ruta de la imagen de la textura
int width; // Ancho de la imagen
int height; // Alto de la imagen
std::string path; // Ruta de la imagen de la textura
public:
static SDL_ScaleMode currentScaleMode; // Modo de escalado global para nuevas texturas
public:
static SDL_ScaleMode currentScaleMode; // Modo de escalado global para nuevas texturas
// Establece el modo de escalado global para nuevas texturas
static void setGlobalScaleMode(SDL_ScaleMode mode);

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,25 +1,24 @@
#include "utils.h"
#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
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 deltaY = y2 - y1;
return deltaX * deltaX + deltaY * deltaY;
}
// 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
int totalRadiusSquared = a.r + b.r;
totalRadiusSquared = totalRadiusSquared * totalRadiusSquared;
// 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
return true;
}
@@ -29,42 +28,30 @@ bool checkCollision(circle_t &a, circle_t &b)
}
// 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
int cX, cY;
// Find closest x offset
if (a.x < b.x)
{
if (a.x < 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;
}
else
{
} else {
cX = a.x;
}
// Find closest y offset
if (a.y < b.y)
{
if (a.y < 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;
}
else
{
} else {
cY = a.y;
}
// 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
return true;
}
@@ -74,8 +61,7 @@ bool checkCollision(circle_t &a, SDL_Rect &b)
}
// 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
const int leftA = a.x;
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;
// Si cualquiera de las caras de a está fuera de b
if (bottomA <= topB)
{
if (bottomA <= topB) {
return false;
}
if (topA >= bottomB)
{
if (topA >= bottomB) {
return false;
}
if (rightA <= leftB)
{
if (rightA <= leftB) {
return false;
}
if (leftA >= rightB)
{
if (leftA >= rightB) {
return false;
}
@@ -114,29 +96,24 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
}
// 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
if (p.x < r.x)
{
if (p.x < r.x) {
return false;
}
// 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;
}
// Comprueba si el punto está por encima del rectangulo
if (p.y < r.y)
{
if (p.y < r.y) {
return false;
}
// 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;
}
@@ -145,29 +122,24 @@ bool checkCollision(SDL_Point &p, SDL_Rect &r)
}
// 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
if (l.y < r.y)
{
if (l.y < r.y) {
return false;
}
// 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;
}
// 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;
}
// 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;
}
@@ -176,29 +148,24 @@ bool checkCollision(h_line_t &l, SDL_Rect &r)
}
// 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
if (l.x < r.x)
{
if (l.x < r.x) {
return false;
}
// 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;
}
// 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;
}
// Comprueba si el final de la linea esta encima del rectangulo
if (l.y2 < r.y)
{
if (l.y2 < r.y) {
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
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
if (p.y > l.y)
{
if (p.y > l.y) {
return false;
}
// Comprueba si el punto esta bajo la linea
if (p.y < l.y)
{
if (p.y < l.y) {
return false;
}
// Comprueba si el punto esta a la izquierda de la linea
if (p.x < l.x1)
{
if (p.x < l.x1) {
return false;
}
// Comprueba si el punto esta a la derecha de la linea
if (p.x > l.x2)
{
if (p.x > l.x2) {
return false;
}
@@ -238,8 +200,7 @@ bool checkCollision(h_line_t &l, SDL_Point &p)
}
// 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 y1 = l1.y1;
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));
// 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
const float x = x1 + (uA * (x2 - x1));
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
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 y1 = l1.y1;
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));
// 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
const float x = x1 + (uA * (x2 - x1));
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
void normalizeLine(d_line_t &l)
{
void normalizeLine(d_line_t &l) {
// Las lineas diagonales van de izquierda a derecha
// x2 mayor que x1
if (l.x2 < l.x1)
{
if (l.x2 < l.x1) {
const int x = l.x1;
const int y = l.y1;
l.x1 = l.x2;
@@ -334,35 +290,29 @@ void normalizeLine(d_line_t &l)
}
// 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
if (abs(p.x - l.x1) != abs(p.y - l.y1))
{
if (abs(p.x - l.x1) != abs(p.y - l.y1)) {
return false;
}
// 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;
}
// 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;
}
// 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;
}
// 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;
}
@@ -380,170 +330,135 @@ bool checkCollision(SDL_Point &p, d_line_t &l)
}
// Devuelve un color_t a partir de un string
color_t stringToColor(palette_e pal, std::string str)
{
if (pal == p_zxspectrum)
{
if (str == "black")
{
color_t stringToColor(palette_e pal, std::string str) {
if (pal == p_zxspectrum) {
if (str == "black") {
return {0x00, 0x00, 0x00};
}
else if (str == "bright_black")
{
else if (str == "bright_black") {
return {0x00, 0x00, 0x00};
}
else if (str == "blue")
{
else if (str == "blue") {
return {0x00, 0x00, 0xd8};
}
else if (str == "bright_blue")
{
else if (str == "bright_blue") {
return {0x00, 0x00, 0xFF};
}
else if (str == "red")
{
else if (str == "red") {
return {0xd8, 0x00, 0x00};
}
else if (str == "bright_red")
{
else if (str == "bright_red") {
return {0xFF, 0x00, 0x00};
}
else if (str == "magenta")
{
else if (str == "magenta") {
return {0xd8, 0x00, 0xd8};
}
else if (str == "bright_magenta")
{
else if (str == "bright_magenta") {
return {0xFF, 0x00, 0xFF};
}
else if (str == "green")
{
else if (str == "green") {
return {0x00, 0xd8, 0x00};
}
else if (str == "bright_green")
{
else if (str == "bright_green") {
return {0x00, 0xFF, 0x00};
}
else if (str == "cyan")
{
else if (str == "cyan") {
return {0x00, 0xd8, 0xd8};
}
else if (str == "bright_cyan")
{
else if (str == "bright_cyan") {
return {0x00, 0xFF, 0xFF};
}
else if (str == "yellow")
{
else if (str == "yellow") {
return {0xd8, 0xd8, 0x00};
}
else if (str == "bright_yellow")
{
else if (str == "bright_yellow") {
return {0xFF, 0xFF, 0x00};
}
else if (str == "white")
{
else if (str == "white") {
return {0xd8, 0xd8, 0xd8};
}
else if (str == "bright_white")
{
else if (str == "bright_white") {
return {0xFF, 0xFF, 0xFF};
}
}
else if (pal == p_zxarne)
{ // zxarne
if (str == "black")
{
else if (pal == p_zxarne) { // zxarne
if (str == "black") {
return {0x00, 0x00, 0x00};
}
else if (str == "bright_black")
{
else if (str == "bright_black") {
return {0x3C, 0x35, 0x1F};
}
else if (str == "blue")
{
else if (str == "blue") {
return {0x31, 0x33, 0x90};
}
else if (str == "bright_blue")
{
else if (str == "bright_blue") {
return {0x15, 0x59, 0xDB};
}
else if (str == "red")
{
else if (str == "red") {
return {0xA7, 0x32, 0x11};
}
else if (str == "bright_red")
{
else if (str == "bright_red") {
return {0xD8, 0x55, 0x25};
}
else if (str == "magenta")
{
else if (str == "magenta") {
return {0xA1, 0x55, 0x89};
}
else if (str == "bright_magenta")
{
else if (str == "bright_magenta") {
return {0xCD, 0x7A, 0x50};
}
else if (str == "green")
{
else if (str == "green") {
return {0x62, 0x9A, 0x31};
}
else if (str == "bright_green")
{
else if (str == "bright_green") {
return {0x9C, 0xD3, 0x3C};
}
else if (str == "cyan")
{
else if (str == "cyan") {
return {0x28, 0xA4, 0xCB};
}
else if (str == "bright_cyan")
{
else if (str == "bright_cyan") {
return {0x65, 0xDC, 0xD6};
}
else if (str == "yellow")
{
else if (str == "yellow") {
return {0xE8, 0xBC, 0x50};
}
else if (str == "bright_yellow")
{
else if (str == "bright_yellow") {
return {0xF1, 0xE7, 0x82};
}
else if (str == "white")
{
else if (str == "white") {
return {0xBF, 0xBF, 0xBD};
}
else if (str == "bright_white")
{
else if (str == "bright_white") {
return {0xF2, 0xF1, 0xED};
}
}
@@ -552,38 +467,28 @@ color_t stringToColor(palette_e pal, std::string str)
}
// Convierte una cadena en un valor booleano
bool stringToBool(std::string str)
{
if (str == "true")
{
bool stringToBool(std::string str) {
if (str == "true") {
return true;
}
else
{
} else {
return false;
}
}
// Convierte un valor booleano en una cadena
std::string boolToString(bool value)
{
if (value)
{
std::string boolToString(bool value) {
if (value) {
return "true";
}
else
{
} else {
return "false";
}
}
// Convierte una cadena a minusculas
std::string toLower(std::string str)
{
std::string toLower(std::string str) {
const char *original = str.c_str();
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];
lower[i] = (c >= 65 && c <= 90) ? c + 32 : c;
}

View File

@@ -1,8 +1,9 @@
#pragma once
#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
constexpr int DIFFICULTY_EASY = 0;
@@ -10,111 +11,105 @@ constexpr int DIFFICULTY_NORMAL = 1;
constexpr int DIFFICULTY_HARD = 2;
// Estructura para definir un circulo
struct circle_t
{
int x;
int y;
int r;
struct circle_t {
int x;
int y;
int r;
};
// Estructura para definir una linea horizontal
struct h_line_t
{
int x1, x2, y;
struct h_line_t {
int x1, x2, y;
};
// Estructura para definir una linea vertical
struct v_line_t
{
int x, y1, y2;
struct v_line_t {
int x, y1, y2;
};
// Estructura para definir una linea diagonal
struct d_line_t
{
int x1, y1, x2, y2;
struct d_line_t {
int x1, y1, x2, y2;
};
// Estructura para definir una linea
struct line_t
{
int x1, y1, x2, y2;
struct line_t {
int x1, y1, x2, y2;
};
// Estructura para definir un color
struct color_t
{
struct color_t {
Uint8 r;
Uint8 g;
Uint8 b;
color_t() : r(0), g(0), b(0) {} // Constructor por defecto
color_t(Uint8 red, Uint8 green, Uint8 blue) : r(red), g(green), b(blue) {}
color_t()
: 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
enum palette_e
{
p_zxspectrum,
p_zxarne
enum palette_e {
p_zxspectrum,
p_zxarne
};
// Estructura para saber la seccion y subseccion del programa
struct section_t
{
Uint8 name;
Uint8 subsection;
struct section_t {
Uint8 name;
Uint8 subsection;
};
// Estructura para mapear el teclado usado en la demo
struct demoKeys_t
{
Uint8 left;
Uint8 right;
Uint8 noInput;
Uint8 fire;
Uint8 fireLeft;
Uint8 fireRight;
struct demoKeys_t {
Uint8 left;
Uint8 right;
Uint8 noInput;
Uint8 fire;
Uint8 fireLeft;
Uint8 fireRight;
};
// Estructura para albergar métodos de control
struct input_t
{
int id; // Identificador en el vector de mandos
std::string name; // Nombre del dispositivo
Uint8 deviceType; // Tipo de dispositivo (teclado o mando)
struct input_t {
int id; // Identificador en el vector de mandos
std::string name; // Nombre del dispositivo
Uint8 deviceType; // Tipo de dispositivo (teclado o mando)
};
// Estructura con opciones de la pantalla
struct op_screen_t
{
int windowWidth; // Ancho de la ventana
int windowHeight; // Alto de la ventana
struct op_screen_t {
int windowWidth; // Ancho de la ventana
int windowHeight; // Alto de la ventana
};
// Estructura con todas las opciones de configuración del programa
struct options_t
{
Uint8 difficulty; // Dificultad del juego
Uint8 playerSelected; // Jugador seleccionado para el modo 1P
std::vector<input_t> input; // Modo de control (teclado o mando)
Uint8 language; // Idioma usado en el juego
struct options_t {
Uint8 difficulty; // Dificultad del juego
Uint8 playerSelected; // Jugador seleccionado para el modo 1P
std::vector<input_t> input; // Modo de control (teclado o mando)
Uint8 language; // Idioma usado en el juego
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
Uint32 filter; // Filtro usado para el escalado de la imagen
bool vSync; // Indica si se quiere usar vsync o no
int gameWidth; // Ancho 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 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
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
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
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
Uint32 filter; // Filtro usado para el escalado de la imagen
bool vSync; // Indica si se quiere usar vsync o no
int gameWidth; // Ancho 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 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
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
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
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

View File

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

View File

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