Compare commits

45 Commits

Author SHA1 Message Date
59e2865a4a El game_text ara gasta PathSprites en lloc d'SmartSprites
fix: la paleta dels jugadors no s'iniciava correctament
2024-10-28 22:09:28 +01:00
787cb6366f Pasaeta de include-what-you-use
Acabada de perfilar la classe PathSprite
Menjeades declaracions de utils.h als fitxers que toca
2024-10-28 20:45:24 +01:00
0fe371653a commit de me ane cap a casa 2024-10-28 13:51:26 +01:00
2cffe8dfc9 Merge branch 'main' of https://gitea.sustancia.synology.me/JailDesigner/coffee_crisis_arcade_edition 2024-10-27 22:28:47 +01:00
1dd96cfaff Completada la classe PathSprite 2024-10-27 22:28:44 +01:00
d054e188b6 fix: alguns minibugs tontos 2024-10-27 19:04:05 +01:00
ca6ff71a46 Actualitzat README.MD 2024-10-27 18:46:42 +01:00
b90ac65cfc Eliminats warnings que nomes es veuen al compilar en macos/linux 2024-10-27 17:45:49 +01:00
759adbf6fd Actualitzat README.MD 2024-10-27 17:09:40 +01:00
71f76fda05 Redissenyat el time stopper 2024-10-27 13:36:00 +01:00
ddfb3672ea Afegida la funció createTwoBigBalloons() per a que la partida sempre comence igual 2024-10-26 18:16:23 +02:00
6235d0b684 Revisada la classe Balloon 2024-10-26 18:08:04 +02:00
f750997b34 Revisant la classe Balloon 2024-10-26 14:13:08 +02:00
de2a29b669 Ajustado el game_text para que se dibuje siempre en pantalla, sin clipping 2024-10-26 12:23:04 +02:00
f99f908c11 Revisant la classe Balloon 2024-10-26 11:38:08 +02:00
d44bfd51de Balloon: inicialitzades variables en la declaració 2024-10-26 09:09:19 +02:00
4f095ab018 Repasada la classe Bullet 2024-10-26 09:01:32 +02:00
bffd2bdace . 2024-10-26 08:11:30 +02:00
24d09a2e3c Millorada la aparició dels game_text 2024-10-24 22:16:57 +02:00
caf191672e Posat ordre en el constructor de Game 2024-10-24 22:08:53 +02:00
43e7b83403 Continue arreglant cosetes amb cppcheck 2024-10-24 20:36:30 +02:00
a5c72a0f65 Collons, que m'havien stagejat no se que.. ara si, arreglada la carrega d'animacions 2024-10-24 19:58:45 +02:00
ca464b2e81 Arreglada la cárrega d'animacions 2024-10-24 19:58:25 +02:00
f26ecbd969 Canviat el final de linea als scripts de linux 2024-10-24 18:14:33 +02:00
018bb68f9a Canviat el nom de la carpeta a linux_utils 2024-10-24 17:59:50 +02:00
f36ff3d7fe Actualitzats scripts de linux_utils 2024-10-24 17:53:24 +02:00
8f33308f8d . 2024-10-24 14:03:12 +02:00
8c98430b68 . 2024-10-23 22:18:46 +02:00
6e2f80d8ce . 2024-10-23 18:29:52 +02:00
95478134dd Merdetes en la faena, básicament arreglar uns quants iniciadors de variables en les clases 2024-10-23 14:00:19 +02:00
528533fd9b Au, a casa 2024-10-22 13:56:50 +02:00
5df85e1b1a Pasaeta de cppcheck, ale 2024-10-22 09:24:19 +02:00
1d0c2e01a5 Varios arreglos d'estil en el codi i llevar metodes que ja no servien 2024-10-21 22:47:00 +02:00
236d6f58b6 Nous gràfics per al game_text 2024-10-21 19:29:54 +02:00
898b551e06 Paletes noves per al primer café dels jugadors 2024-10-21 18:09:34 +02:00
84238032e0 Afegits uns overrides pa agafar parametres per linea de comandos 2024-10-21 17:46:05 +02:00
2cb22ed013 fix: els globos tenien un parell de setters mal asignats per culpa de buscar y reemplazar
fix: els globos verds s'inicialitzaven amb vy = 0 per gastar abs en lloc de fabs
fix: corregit un bug milenari que de sempre havia creat els balloons verds al popar al pare amb la meitat de velocitat en y. Lo que jo no se es com anava res. Supose que ara el joc serà un poc mes xungo. Quan rebotaven en el piso ja se'ls posava la velocitat bona (crec)
2024-10-20 22:58:15 +02:00
a3a583deb7 Precàrrega dels fitxers amb dades per al mode demostració 2024-10-20 21:23:04 +02:00
b263e0c4be Modificada la estructura on es guarden els datos de la demo 2024-10-20 20:43:03 +02:00
3bf61fc758 fix: no guardar el fitxer de puntuacions en el modo demo 2024-10-20 19:40:09 +02:00
2377815c02 Amb les textures en memoria i compartides ja no puc fer el trick de canvi de paleta per a la flama del segon jugador tal i com està plantejat el codi. Arreglat creant una segona textura 2024-10-20 19:38:28 +02:00
7434869894 Corregit un fallo amagat baix un ifdef ARCADE. Ja he posat que estiga definit per defecte pa que no torne a passar 2024-10-20 15:43:10 +02:00
848d61b5c0 He fet un "manolete" i he pasat a c++ i smartpointers la cárrega de surfaces desde gif. Sembla que no ha petat res
Precárrega i asignació de paletes a les textures
Ara si algú toca una paleta, que siga conscient que la textura es compartida durant tot el joc
2024-10-20 15:36:04 +02:00
cbc9b3f071 Eliminats els últimes defines i passats a enum class 2024-10-20 12:07:55 +02:00
8bca5095da Modificats, estructurats i ben formatats alguns missatges de consola
Canvis en els codis d'eixida del programa
2024-10-20 11:37:26 +02:00
118 changed files with 7537 additions and 6974 deletions

View File

@@ -1,67 +1,39 @@
# Coffee Crisis # Coffee Crisis Arcade Edition
Coffee Crisis es un juego arcade que pondrá a prueba tus reflejos. Empezado durante el verano de 2020 y terminado un año despues, en el verano de 2021. Intenta conseguir todos los puntos que puedas con una sola vida a traves de los 10 niveles de juego y ayuda a Bal1 a defender la UPV de la invasión de la cafeína esférica y saltarina. Coffee Crisis Arcade Edition es la versió ampliada i millorada del aclamat Coffee Crisis. Preparat per a jugar sense parar amn dos jugadors, nous gràfics i moltes sorpreses mes.
![alt text](https://php.sustancia.synology.me/images/cc1.png) <p align="center">
<img src="https://php.sustancia.synology.me/images/ccae_title.png" alt="Titol"
</p>
## Teclado ## Controls
El juego se maneja con teclado, aunque tambien se puede conectar un mando de control. El joc està optimitzat per a ser jugat amb un mando de jocs, encara que un dels jugadors pot utilitzar el teclat.
Las teclas son las siguientes: Les tecles son les següents:
* **Cursores**: Mover al personaje, moverse por los menus * **Fletxes**: Mou al personatge
* **Q, W, E**: Disparar a la izquierda, al centro y a la derecha respectivamente * **Q, W, E**: Disparar a la esquerra, al centre i a la dreta respectivament
* **ESCAPE**: Pone en pausa el juego durante la partida. Sale de los menus. Cierra el juego
* **ENTER**: Acepta las opciones en los menus
![alt text](https://php.sustancia.synology.me/images/cc2.png) <p align="center">
<img src="https://php.sustancia.synology.me/images/ccae1.png" alt="Joc"
</p>
## Compilar ## Altres tecles
- **Tecla ESC**: Tancar el joc
Para compilar el código se necesitan tener las librerías SDL instaladas en el sistema y el compilador g++. - **Tecla F1**: Fa la finestra mes xicoteta
En Linux: - **Tecla F2**: Fa la finestra mes gran
```bash
sudo apt install libsdl2-dev g++
```
En macOS se pueden instalar fácilmente con [brew](https://brew.sh): - **Tecla F3**: Alterna entre el mode de pantalla completa i el de finestra
```bash
brew install sdl2 g++
```
Una vez instaladas las librerías SDL, se puede compilar utilizando el fichero Makefile suministrado. - **Tecla F4**: Activa o desactiva els shaders
En Linux: - **Tecla F10**: Reset
```bash
make linux
```
En macOS: <p align="center">
```bash <img src="https://php.sustancia.synology.me/images/ccae2.png" alt="Joc"
make macos </p>
```
![alt text](https://php.sustancia.synology.me/images/cc3.png)
## Como ejecutar
Para ejecutar el juego hay que escribir en la terminal la orden que se muestra a continuación. ## Agraiments
A chatGPT i sobretot a Copilot. Gracies per estar sempre quan vos he necesitat.
En Linux:
```bash
./coffee_crisis_linux
```
En macOS:
```bash
./coffee_crisis_macos
```
En macOS tambien puedes hacer doble click sobre el archivo coffee_crisis_macos
## Agradecimientos
A los jailers y a la jail. Y entre ellos, a JailDoctor por estar siempre ahí apoyándonos/obligándonos a sacar un Jailgame más.
Y por supuesto a ti por estar aquí.
## Licencia
Usa el código para lo que quieras: aprender, reirte, curiosear... excepto para sacar beneficio económico. Si lo consigues, por favor avísame y vamos a medias.

View File

@@ -7,6 +7,7 @@ game.play_area.rect.y 0 # Rectangulo con la posición de la zona de juego
game.play_area.rect.w 320 # Rectangulo con la posición de la zona de juego game.play_area.rect.w 320 # Rectangulo con la posición de la zona de juego
game.play_area.rect.h 216 # Rectangulo con la posición de la zona de juego game.play_area.rect.h 216 # Rectangulo con la posición de la zona de juego
game.enter_name_seconds 30 # Duración en segundos para introducir el nombre al finalizar la partida game.enter_name_seconds 30 # Duración en segundos para introducir el nombre al finalizar la partida
game.game_text.dest_y
## FADE ## FADE
fade.num_squares_width 160 fade.num_squares_width 160

View File

Before

Width:  |  Height:  |  Size: 84 B

After

Width:  |  Height:  |  Size: 84 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 B

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

After

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 487 B

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 580 B

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View File

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

View File

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 944 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 B

View File

@@ -1,3 +0,0 @@
#!/bin/bash
valgrind --suppressions=valgrind_exceptions --leak-check=full ~/coffee_crisis_arcade_edition/coffee_crisis_arcade_edition_debug > ~/coffee_crisis_arcade_edition/debug.txt 2>&1

View File

View File

@@ -0,0 +1,8 @@
#!/bin/bash
SOURCEPATH=../source/
for i in "$SOURCEPATH"/*.cpp
do
include-what-you-use -D DEBUG -D VERBOSE -std=c++20 -Wall "$i"
done

View File

@@ -5,6 +5,6 @@ SOURCEPATH=../source/
for i in "$SOURCEPATH"/*.cpp for i in "$SOURCEPATH"/*.cpp
do do
include-what-you-use -D DEBUG -D VERBOSE -std=c++20 -Wall "$i" include-what-you-use -D DEBUG -D VERBOSE -std=c++20 -Wall "$i"
read -p "Presiona cualquier tecla para continuar..." read -r -p "Presiona cualquier tecla para continuar..."
clear clear
done done

View File

@@ -0,0 +1,20 @@
#!/bin/bash
# warning,style,performance
#cppcheck --force --enable=warning,style,performance --std=c++20 \
# --suppressions-list=/home/sergio/gitea/coffee_crisis_arcade_edition/linux-utils/cppcheck_suppressions \
# /home/sergio/gitea/coffee_crisis_arcade_edition/source/ \
# 2>/home/sergio/cppcheck-result-warning-style-performance.txt
# all
#cppcheck --force --enable=all -I /usr/include --std=c++20 \
#--suppress=missingIncludeSystem \
#--suppressions-list=/home/sergio/gitea/coffee_crisis_arcade_edition/linux-utils/cppcheck_suppressions \
#/home/sergio/gitea/coffee_crisis_arcade_edition/source/ \
#2>/home/sergio/cppcheck-result-all.txt
# unusedFunction
cppcheck --enable=style --std=c++20 \
--suppressions-list=./cppcheck_suppressions \
../source/ \
2>/home/sergio/cppcheck-result-all.txt

View File

@@ -0,0 +1,8 @@
*:/home/sergio/gitea/coffee_crisis_arcade_edition/source/stb*
*:/home/sergio/gitea/coffee_crisis_arcade_edition/source/gif.c
*:/home/sergio/gitea/coffee_crisis_arcade_edition/source/jail*
*:/usr/include/*
*:../source/stb*
*:../source/gif.c
*:../source/jail*
*:/usr/include/*

View File

View File

@@ -0,0 +1,6 @@
#!/bin/bash
valgrind --suppressions=valgrind_exceptions \
--leak-check=full \
~/coffee_crisis_arcade_edition/coffee_crisis_arcade_edition_debug \
> ~/coffee_crisis_arcade_edition/debug.txt 2>&1

View File

@@ -1,16 +1,15 @@
#include "animated_sprite.h" #include "animated_sprite.h"
#include <algorithm> // for copy #include <stddef.h> // Para size_t
#include <fstream> // for basic_ostream, operator<<, basic_istream, basic... #include <fstream> // Para basic_ostream, basic_istream, operator<<, basic...
#include <iostream> // for cout #include <iostream> // Para cout, cerr
#include <iterator> // for back_insert_iterator, back_inserter #include <sstream> // Para basic_stringstream
#include <sstream> // for basic_stringstream #include <stdexcept> // Para runtime_error
#include "texture.h" // for Texture #include "texture.h" // Para Texture
#include "utils.h" #include "utils.h" // Para printWithDots
// Carga las animaciones en un vector(Animations) desde un fichero // Carga las animaciones en un vector(Animations) desde un fichero
Animations loadAnimationsFromFile(const std::string &file_path) AnimationsFileBuffer loadAnimationsFromFile(const std::string &file_path)
{ {
std::vector<std::string> buffer;
std::ifstream file(file_path); std::ifstream file(file_path);
if (!file) if (!file)
{ {
@@ -18,12 +17,14 @@ Animations loadAnimationsFromFile(const std::string &file_path)
throw std::runtime_error("Fichero no encontrado: " + file_path); throw std::runtime_error("Fichero no encontrado: " + file_path);
} }
std::string line;
printWithDots("Animation : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]"); printWithDots("Animation : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]");
std::vector<std::string> buffer;
std::string line;
while (std::getline(file, line)) while (std::getline(file, line))
{ {
buffer.push_back(line); if (!line.empty())
buffer.push_back(line);
} }
return buffer; return buffer;
@@ -31,35 +32,24 @@ Animations loadAnimationsFromFile(const std::string &file_path)
// Constructor // Constructor
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path) AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path)
: MovingSprite(texture), : MovingSprite(texture)
current_animation_(0)
{ {
// Carga las animaciones // Carga las animaciones
if (!file_path.empty()) if (!file_path.empty())
{ {
animations_ = loadFromFile(file_path); AnimationsFileBuffer v = loadAnimationsFromFile(file_path);
} loadFromAnimationsFileBuffer(v);
}
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const Animations &animations)
: MovingSprite(texture),
current_animation_(0)
{
if (!animations.empty())
{
loadFromVector(animations);
} }
} }
// Constructor // Constructor
AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture) AnimatedSprite::AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer &animations)
: MovingSprite(texture), : MovingSprite(texture)
current_animation_(0) {}
// Destructor
AnimatedSprite::~AnimatedSprite()
{ {
animations_.clear(); if (!animations.empty())
{
loadFromAnimationsFileBuffer(animations);
}
} }
// Obtiene el indice de la animación a partir del nombre // Obtiene el indice de la animación a partir del nombre
@@ -116,89 +106,12 @@ void AnimatedSprite::animate()
} }
} }
// Obtiene el número de frames de la animación actual
int AnimatedSprite::getNumFrames()
{
return (int)animations_[current_animation_].frames.size();
}
// Establece el frame actual de la animación
void AnimatedSprite::setCurrentFrame(int num)
{
// Descarta valores fuera de rango
if (num >= (int)animations_[current_animation_].frames.size())
{
num = 0;
}
// Cambia el valor de la variable
animations_[current_animation_].current_frame = num;
animations_[current_animation_].counter = 0;
// Escoge el frame correspondiente de la animación
setSpriteClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}
// Establece el valor del contador
void AnimatedSprite::setAnimationCounter(const std::string &name, int num)
{
animations_[getIndex(name)].counter = num;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(const std::string &name, int speed)
{
animations_[getIndex(name)].counter = speed;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(int index, int speed)
{
animations_[index].counter = speed;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(const std::string &name, int loop)
{
animations_[getIndex(name)].loop = loop;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(int index, int loop)
{
animations_[index].loop = loop;
}
// Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(const std::string &name, bool value)
{
animations_[getIndex(name)].completed = value;
}
// OLD - Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(int index, bool value)
{
animations_[index].completed = value;
}
// Comprueba si ha terminado la animación // Comprueba si ha terminado la animación
bool AnimatedSprite::animationIsCompleted() bool AnimatedSprite::animationIsCompleted()
{ {
return animations_[current_animation_].completed; return animations_[current_animation_].completed;
} }
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(const std::string &name, Uint8 index)
{
return animations_[getIndex(name)].frames[index];
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(int indexA, Uint8 indexF)
{
return animations_[indexA].frames[indexF];
}
// Establece la animacion actual // Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(const std::string &name) void AnimatedSprite::setCurrentAnimation(const std::string &name)
{ {
@@ -232,21 +145,6 @@ void AnimatedSprite::update()
MovingSprite::update(); 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)
{
animations_[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 : animations_)
{
a.counter = value;
}
}
// Reinicia la animación // Reinicia la animación
void AnimatedSprite::resetAnimation() void AnimatedSprite::resetAnimation()
{ {
@@ -255,268 +153,91 @@ void AnimatedSprite::resetAnimation()
animations_[current_animation_].completed = false; animations_[current_animation_].completed = false;
} }
// Carga la animación desde un fichero // Carga la animación desde un vector de cadenas
std::vector<Animation> AnimatedSprite::loadFromFile(const std::string &file_path) void AnimatedSprite::loadFromAnimationsFileBuffer(const AnimationsFileBuffer &source)
{ {
// Inicializa variables int frame_width = 1;
std::vector<Animation> animations; int frame_height = 1;
auto frames_per_row = 0; int frames_per_row = 1;
auto frame_width = 0; int max_tiles = 1;
auto frame_height = 0;
auto max_tiles = 0;
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1); size_t index = 0;
std::ifstream file(file_path); while (index < source.size())
std::string line;
// El fichero se puede abrir
if (file.good())
{ {
// Procesa el fichero linea a linea std::string line = source.at(index);
std::cout << "Animation loaded: " << file_name << std::endl;
while (std::getline(file, line)) // Parsea el fichero para buscar variables y valores
if (line != "[animation]")
{ {
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación // Encuentra la posición del caracter '='
if (line == "[animation]") size_t pos = line.find("=");
// Procesa las dos subcadenas
if (pos != std::string::npos)
{ {
Animation animation = Animation(); std::string key = line.substr(0, pos);
int value = std::stoi(line.substr(pos + 1));
if (key == "frame_width")
frame_width = value;
else if (key == "frame_height")
frame_height = value;
else
std::cout << "Warning: unknown parameter " << key << std::endl;
do frames_per_row = texture_->getWidth() / frame_width;
{ const int w = texture_->getWidth() / frame_width;
std::getline(file, line); const int h = texture_->getHeight() / frame_height;
max_tiles = w * h;
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != static_cast<int>(line.npos))
{
if (line.substr(0, pos) == "name")
{
animation.name = line.substr(pos + 1, line.length());
}
else if (line.substr(0, pos) == "speed")
{
animation.speed = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "loop")
{
animation.loop = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frames")
{
// Se introducen los valores separados por comas en un vector
std::stringstream ss(line.substr(pos + 1, line.length()));
std::string tmp;
SDL_Rect rect = {0, 0, frame_width, frame_height};
while (getline(ss, tmp, ','))
{
// Comprueba que el tile no sea mayor que el maximo indice permitido
const auto num_tile = std::stoi(tmp) > max_tiles ? 0 : std::stoi(tmp);
rect.x = (num_tile % frames_per_row) * frame_width;
rect.y = (num_tile / frames_per_row) * frame_height;
animation.frames.push_back(rect);
}
}
else
{
std::cout << "Warning: file " << file_name.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
}
}
} while (line != "[/animation]");
// Añade la animación al vector de animaciones
animations.push_back(animation);
}
// En caso contrario se parsea el fichero para buscar las variables y los valores
else
{
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != (int)line.npos)
{
if (line.substr(0, pos) == "frames_per_row")
{
frames_per_row = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frame_width")
{
frame_width = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frame_height")
{
frame_height = std::stoi(line.substr(pos + 1, line.length()));
}
else
{
std::cout << "Warning: file " << file_name.c_str() << "\n, unknown parameter \"" << line.substr(0, pos).c_str() << "\"" << std::endl;
}
// Normaliza valores
if (frames_per_row == 0 && frame_width > 0)
{
frames_per_row = texture_->getWidth() / frame_width;
}
if (max_tiles == 0 && frame_width > 0 && frame_height > 0)
{
const auto w = texture_->getWidth() / frame_width;
const auto h = texture_->getHeight() / frame_height;
max_tiles = w * h;
}
}
} }
} }
// Cierra el fichero
file.close();
}
// El fichero no se puede abrir
else
{
std::cout << "Warning: Unable to open " << file_name.c_str() << " file" << std::endl;
}
// Pone un valor por defecto
setWidth(frame_width);
setHeight(frame_height);
return animations;
}
// Carga la animación desde un vector
bool AnimatedSprite::loadFromVector(const Animations &source)
{
// Inicializa variables
auto frames_per_row = 0;
auto frame_width = 0;
auto frame_height = 0;
auto max_tiles = 0;
// Indicador de éxito en el proceso
auto success = true;
std::string line;
// Recorre todo el vector
auto index = 0;
while (index < (int)source.size())
{
// Lee desde el vector
line = source.at(index);
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación // Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]") if (line == "[animation]")
{ {
Animation animation = Animation(); Animation animation;
do do
{ {
// Aumenta el indice para leer la siguiente linea
index++; index++;
line = source.at(index); line = source.at(index);
size_t pos = line.find("=");
// Encuentra la posición del caracter '=' if (pos != std::string::npos)
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != static_cast<int>(line.npos))
{ {
if (line.substr(0, pos) == "name") std::string key = line.substr(0, pos);
{ std::string value = line.substr(pos + 1);
animation.name = line.substr(pos + 1, line.length());
}
else if (line.substr(0, pos) == "speed") if (key == "name")
{ animation.name = value;
animation.speed = std::stoi(line.substr(pos + 1, line.length())); else if (key == "speed")
} animation.speed = std::stoi(value);
else if (key == "loop")
else if (line.substr(0, pos) == "loop") animation.loop = std::stoi(value);
{ else if (key == "frames")
animation.loop = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frames")
{ {
// Se introducen los valores separados por comas en un vector // Se introducen los valores separados por comas en un vector
std::stringstream ss(line.substr(pos + 1, line.length())); std::stringstream ss(value);
std::string tmp; std::string tmp;
SDL_Rect rect = {0, 0, frame_width, frame_height}; SDL_Rect rect = {0, 0, frame_width, frame_height};
while (getline(ss, tmp, ',')) while (getline(ss, tmp, ','))
{ {
// Comprueba que el tile no sea mayor que el maximo indice permitido // Comprueba que el tile no sea mayor que el maximo indice permitido
const int num_tile = std::stoi(tmp) > max_tiles ? 0 : std::stoi(tmp); const int num_tile = std::stoi(tmp);
rect.x = (num_tile % frames_per_row) * frame_width; if (num_tile <= max_tiles)
rect.y = (num_tile / frames_per_row) * frame_height; {
animation.frames.push_back(rect); rect.x = (num_tile % frames_per_row) * frame_width;
rect.y = (num_tile / frames_per_row) * frame_height;
animation.frames.emplace_back(rect);
}
} }
} }
else else
{ std::cout << "Warning: unknown parameter " << key << std::endl;
std::cout << "Warning: unknown parameter " << line.substr(0, pos).c_str() << std::endl;
success = false;
}
} }
} while (line != "[/animation]"); } while (line != "[/animation]");
// Añade la animación al vector de animaciones // Añade la animación al vector de animaciones
animations_.push_back(animation); animations_.emplace_back(animation);
}
// En caso contrario se parsea el fichero para buscar las variables y los valores
else
{
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != (int)line.npos)
{
if (line.substr(0, pos) == "frames_per_row")
{
frames_per_row = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frame_width")
{
frame_width = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frame_height")
{
frame_height = std::stoi(line.substr(pos + 1, line.length()));
}
else
{
std::cout << "Warning: unknown parameter " << line.substr(0, pos).c_str() << std::endl;
success = false;
}
// Normaliza valores
if (frames_per_row == 0 && frame_width > 0)
{
frames_per_row = texture_->getWidth() / frame_width;
}
if (max_tiles == 0 && frame_width > 0 && frame_height > 0)
{
const int w = texture_->getWidth() / frame_width;
const int h = texture_->getHeight() / frame_height;
max_tiles = w * h;
}
}
} }
// Una vez procesada la linea, aumenta el indice para pasar a la siguiente // Una vez procesada la linea, aumenta el indice para pasar a la siguiente
@@ -526,6 +247,4 @@ bool AnimatedSprite::loadFromVector(const Animations &source)
// Pone un valor por defecto // Pone un valor por defecto
setWidth(frame_width); setWidth(frame_width);
setHeight(frame_height); setHeight(frame_height);
return success;
} }

View File

@@ -1,12 +1,11 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // Para SDL_Rect
#include <SDL2/SDL_stdinc.h> // for Uint8 #include <memory> // Para shared_ptr
#include <memory> // for shared_ptr #include <string> // Para string
#include <string> // for string #include <vector> // Para vector
#include <vector> // for vector #include "moving_sprite.h" // Para MovingSprite
#include "moving_sprite.h" // for MovingSprite class Texture; // lines 9-9
class Texture;
struct Animation struct Animation
{ {
@@ -21,67 +20,40 @@ struct Animation
Animation() : name(std::string()), speed(5), loop(0), completed(false), current_frame(0), counter(0) {} Animation() : name(std::string()), speed(5), loop(0), completed(false), current_frame(0), counter(0) {}
}; };
using Animations = std::vector<std::string>; using AnimationsFileBuffer = std::vector<std::string>;
// Carga las animaciones en un vector(Animations) desde un fichero // Carga las animaciones en un vector(Animations) desde un fichero
Animations loadAnimationsFromFile(const std::string &file_path); AnimationsFileBuffer loadAnimationsFromFile(const std::string &file_path);
class AnimatedSprite : public MovingSprite class AnimatedSprite : public MovingSprite
{ {
protected: protected:
// Variables // Variables
std::vector<Animation> animations_; // Vector con las diferentes animaciones std::vector<Animation> animations_; // Vector con las diferentes animaciones
int current_animation_; // Animacion activa int current_animation_ = 0; // Animacion activa
// Calcula el frame correspondiente a la animación actual // Calcula el frame correspondiente a la animación actual
void animate(); void animate();
// Carga la animación desde un fichero // Carga la animación desde un vector de cadenas
std::vector<Animation> loadFromFile(const std::string &file_path); void loadFromAnimationsFileBuffer(const AnimationsFileBuffer &source);
// Carga la animación desde un vector
bool loadFromVector(const Animations &source);
public: public:
// Constructor // Constructor
AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path); AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path);
AnimatedSprite(std::shared_ptr<Texture> texture, const Animations &animations); AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer &animations);
explicit AnimatedSprite(std::shared_ptr<Texture> texture); explicit AnimatedSprite(std::shared_ptr<Texture> texture)
: MovingSprite(texture) {}
// Destructor // Destructor
virtual ~AnimatedSprite(); virtual ~AnimatedSprite() = default;
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update() override; void update() override;
// Obtiene el número de frames de la animación actual
int getNumFrames();
// Establece el frame actual de la animación
void setCurrentFrame(int num);
// Establece el valor del contador
void setAnimationCounter(const std::string &name, int num);
// Establece la velocidad de una animación
void setAnimationSpeed(const std::string &name, int speed);
void setAnimationSpeed(int index, int speed);
// Establece el frame al que vuelve la animación al finalizar
void setAnimationLoop(const std::string &name, int loop);
void setAnimationLoop(int index, int loop);
// Establece el valor de la variable
void setAnimationCompleted(const std::string &name, bool value);
void setAnimationCompleted(int index, bool value);
// Comprueba si ha terminado la animación // Comprueba si ha terminado la animación
bool animationIsCompleted(); bool animationIsCompleted();
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect getAnimationClip(const std::string &name = "default", Uint8 index = 0);
SDL_Rect getAnimationClip(int indexA = 0, Uint8 indexF = 0);
// Obtiene el indice de la animación a partir del nombre // Obtiene el indice de la animación a partir del nombre
int getIndex(const std::string &name); int getIndex(const std::string &name);
@@ -89,12 +61,6 @@ public:
void setCurrentAnimation(const std::string &name = "default"); void setCurrentAnimation(const std::string &name = "default");
void setCurrentAnimation(int index = 0); void setCurrentAnimation(int index = 0);
// OLD - Establece el rectangulo para un frame de una animación
void setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h);
// OLD - Establece el contador para todas las animaciones
void setAnimationCounter(int value);
// Reinicia la animación // Reinicia la animación
void resetAnimation(); void resetAnimation();
}; };

View File

@@ -1,9 +1,9 @@
#include "asset.h" #include "asset.h"
#include "utils.h" #include <algorithm> // Para find_if, max
#include <SDL2/SDL_rwops.h> // for SDL_RWFromFile, SDL_RWclose, SDL_RWops #include <fstream> // Para basic_ostream, operator<<, basic_ifstream, endl
#include <SDL2/SDL_stdinc.h> // for SDL_max #include <iostream> // Para cout
#include <stddef.h> // for size_t #include <string> // Para allocator, char_traits, string, operator+, oper...
#include <iostream> // for basic_ostream, operator<<, cout, endl #include "utils.h" // Para getFileName, printWithDots
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
Asset *Asset::asset_ = nullptr; Asset *Asset::asset_ = nullptr;
@@ -26,42 +26,31 @@ Asset *Asset::get()
return Asset::asset_; return Asset::asset_;
} }
// Constructor
Asset::Asset(const std::string &executable_path)
: executable_path_(executable_path.substr(0, executable_path.find_last_of("\\/")))
{
longest_name_ = 0;
}
// Añade un elemento a la lista // Añade un elemento a la lista
void Asset::add(const std::string &file, AssetType type, bool required, bool absolute) void Asset::add(const std::string &file, AssetType type, bool required, bool absolute)
{ {
AssetItem ai; file_list_.emplace_back(absolute ? file : executable_path_ + file, type, required);
ai.file = absolute ? file : executable_path_ + file; longest_name_ = std::max(longest_name_, static_cast<int>(file_list_.back().file.size()));
ai.type = type;
ai.required = required;
file_list_.push_back(ai);
const std::string file_name = file.substr(file.find_last_of("\\/") + 1);
longest_name_ = SDL_max(longest_name_, file_name.size());
} }
// Devuelve el fichero de un elemento de la lista a partir de una cadena // Devuelve la ruta completa a un fichero a partir de una cadena
std::string Asset::get(const std::string &text) const std::string Asset::get(const std::string &text) const
{ {
for (const auto &f : file_list_) auto it = std::find_if(file_list_.begin(), file_list_.end(),
[&text](const auto &f)
{
return getFileName(f.file) == text;
});
if (it != file_list_.end())
{ {
const size_t last_index = f.file.find_last_of("/") + 1; return it->file;
const std::string file = f.file.substr(last_index, std::string::npos); }
else
if (file == text) {
{ std::cout << "Warning: file " << text << " not found" << std::endl;
return f.file; return "";
}
} }
std::cout << "Warning: file " << text.c_str() << " not found" << std::endl;
return "";
} }
// Comprueba que existen todos los elementos // Comprueba que existen todos los elementos
@@ -114,20 +103,12 @@ bool Asset::check() const
// Comprueba que existe un fichero // Comprueba que existe un fichero
bool Asset::checkFile(const std::string &path) const bool Asset::checkFile(const std::string &path) const
{ {
auto success = false; std::ifstream file(path);
bool success = file.good();
file.close();
// Comprueba si existe el fichero
auto file = SDL_RWFromFile(path.c_str(), "rb");
if (file)
{
success = true;
SDL_RWclose(file);
}
const std::string file_name = path.substr(path.find_last_of("\\/") + 1);
if (!success) if (!success)
printWithDots("Checking file : ", file_name, (success ? " [ OK ]" : " [ ERROR ]")); printWithDots("Checking file : ", getFileName(path), "[ ERROR ]");
return success; return success;
} }

View File

@@ -1,7 +1,8 @@
#pragma once #pragma once
#include <string> // for string, basic_string #include <string> // para string, basic_string
#include <vector> // for vector #include <vector> // para vector
#include "utils.h"
enum class AssetType : int enum class AssetType : int
{ {
@@ -27,14 +28,17 @@ private:
// Estructura para definir un item // Estructura para definir un item
struct AssetItem struct AssetItem
{ {
std::string file; // Ruta del fichero desde la raiz del directorio std::string file; // Ruta del fichero desde la raíz del directorio
enum AssetType type; // Indica el tipo de recurso AssetType type; // Indica el tipo de recurso
bool required; // Indica si es un fichero que debe de existir 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
// Constructor
AssetItem(const std::string &filePath, AssetType assetType, bool isRequired)
: file(filePath), type(assetType), required(isRequired) {}
}; };
// Variables // Variables
int longest_name_; // Contiene la longitud del nombre de fichero mas largo int longest_name_ = 0; // Contiene la longitud del nombre de fichero mas largo
std::vector<AssetItem> file_list_; // Listado con todas las rutas a los ficheros std::vector<AssetItem> file_list_; // Listado con todas las rutas a los ficheros
std::string executable_path_; // Ruta al ejecutable std::string executable_path_; // Ruta al ejecutable
@@ -45,7 +49,8 @@ private:
std::string getTypeName(AssetType type) const; std::string getTypeName(AssetType type) const;
// Constructor // Constructor
explicit Asset(const std::string &executable_path); explicit Asset(const std::string &executable_path)
: executable_path_(getPath(executable_path)) {}
// Destructor // Destructor
~Asset() = default; ~Asset() = default;
@@ -63,7 +68,7 @@ public:
// Añade un elemento a la lista // Añade un elemento a la lista
void add(const std::string &file, AssetType type, bool required = true, bool absolute = false); void add(const std::string &file, AssetType type, bool required = true, bool absolute = false);
// Devuelve un elemento de la lista a partir de una cadena // Devuelve la ruta completa a un fichero a partir de una cadena
std::string get(const std::string &text) const; std::string get(const std::string &text) const;
// Comprueba que existen todos los elementos // Comprueba que existen todos los elementos

View File

@@ -1,40 +1,35 @@
#include "background.h" #include "background.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
#include <algorithm> // for clamp, max #include <algorithm> // Para clamp, max
#include "asset.h" // for Asset #include "moving_sprite.h" // Para MovingSprite
#include "moving_sprite.h" // for MovingSprite #include "param.h" // Para Param, ParamBackground, param
#include "param.h" // for param #include "resource.h" // Para Resource
#include "resource.h" // for Resource #include "screen.h" // Para Screen
#include "sprite.h" // for Sprite #include "sprite.h" // Para Sprite
#include "texture.h" // for Texture #include "texture.h" // Para Texture
// Constructor // Constructor
Background::Background(SDL_Renderer *renderer) Background::Background()
: renderer_(renderer), : renderer_(Screen::get()->getRenderer()),
buildings_texture_(Resource::get()->getTexture("game_buildings.png")), buildings_texture_(Resource::get()->getTexture("game_buildings.png")),
top_clouds_texture_(Resource::get()->getTexture("game_clouds1.png")), top_clouds_texture_(Resource::get()->getTexture("game_clouds1.png")),
bottom_clouds_texture_(Resource::get()->getTexture("game_clouds2.png")), bottom_clouds_texture_(Resource::get()->getTexture("game_clouds2.png")),
grass_texture_(Resource::get()->getTexture("game_grass.png")), grass_texture_(Resource::get()->getTexture("game_grass.png")),
gradients_texture_(Resource::get()->getTexture("game_sky_colors.png")) gradients_texture_(Resource::get()->getTexture("game_sky_colors.png")),
rect_({0, 0, gradients_texture_->getWidth() / 2, gradients_texture_->getHeight() / 2}),
src_rect_({0, 0, 320, 240}),
dst_rect_({0, 0, 320, 240}),
base_(rect_.h),
color_(Color(param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b)),
alpha_color_text_(param.background.attenuate_alpha),
alpha_color_text_temp_(param.background.attenuate_alpha)
{ {
// Inicializa variables // Inicializa variables
{ {
gradient_number_ = 0;
alpha_ = 0;
clouds_speed_ = 0;
transition_ = 0;
counter_ = 0;
rect_ = {0, 0, gradients_texture_->getWidth() / 2, gradients_texture_->getHeight() / 2};
src_rect_ = {0, 0, 320, 240};
dst_rect_ = {0, 0, 320, 240};
base_ = rect_.h;
color_ = {param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b};
alpha_color_text_ = alpha_color_text_temp_ = param.background.attenuate_alpha;
gradient_rect_[0] = {0, 0, rect_.w, rect_.h}; gradient_rect_[0] = {0, 0, rect_.w, rect_.h};
gradient_rect_[1] = {rect_.w, 0, rect_.w, rect_.h}; gradient_rect_[1] = {rect_.w, 0, rect_.w, rect_.h};
gradient_rect_[2] = {0, rect_.h, rect_.w, rect_.h}; gradient_rect_[2] = {0, rect_.h, rect_.w, rect_.h};
@@ -87,11 +82,11 @@ Background::Background(SDL_Renderer *renderer)
} }
// Crea la textura para componer el fondo // Crea la textura para componer el fondo
canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h); canvas_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
SDL_SetTextureBlendMode(canvas_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(canvas_, SDL_BLENDMODE_BLEND);
// Crea la textura para atenuar el fondo // Crea la textura para atenuar el fondo
color_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h); color_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, rect_.w, rect_.h);
SDL_SetTextureBlendMode(color_texture_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(color_texture_, SDL_BLENDMODE_BLEND);
setColor(color_); setColor(color_);
SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_); SDL_SetTextureAlphaMod(color_texture_, alpha_color_text_);
@@ -120,7 +115,7 @@ void Background::update()
alpha_ = std::max((255 - (int)(255 * transition_)), 0); alpha_ = std::max((255 - (int)(255 * transition_)), 0);
// Incrementa el contador // Incrementa el contador
counter_++; ++counter_;
// Compone todos los elementos del fondo en la textura // Compone todos los elementos del fondo en la textura
fillCanvas(); fillCanvas();
@@ -252,18 +247,6 @@ void Background::setPos(SDL_Rect pos)
src_rect_.h = pos.h; src_rect_.h = pos.h;
} }
// Ajusta el valor de la variable
void Background::setSrcRect(SDL_Rect value)
{
src_rect_ = value;
}
// Ajusta el valor de la variable
void Background::setDstRect(SDL_Rect value)
{
dst_rect_ = value;
}
// Establece el color_ de atenuación // Establece el color_ de atenuación
void Background::setColor(Color color) void Background::setColor(Color color)
{ {

View File

@@ -1,9 +1,9 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // para SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // para SDL_Renderer, SDL_Texture
#include <memory> // for unique_ptr, shared_ptr #include <memory> // para unique_ptr, shared_ptr
#include "utils.h" // for Color #include "utils.h" // para Color
class MovingSprite; class MovingSprite;
class Sprite; class Sprite;
class Texture; class Texture;
@@ -32,12 +32,6 @@ class Texture;
- setTransition(float value) - setTransition(float value)
Porcentaje (entre 0.0f (textura actual) y 1.0f (textura siguiente)) para mostrar entre la textura de fondo actual y la siguiente Porcentaje (entre 0.0f (textura actual) y 1.0f (textura siguiente)) para mostrar entre la textura de fondo actual y la siguiente
- setSrcRect(SDL_Rect value)
Rectangulo de la textura de fondo que se desea mostrar
- setDstRecr(SDL_Rect value)
Rectangulo de destino donde se mostrará el rectángulo antrior. Automaticamente modifica srcRect para coincidor en tamaño con el destino.
- setColor(Color color) - setColor(Color color)
Establece el color de la textura de superposición Establece el color de la textura de superposición
@@ -74,11 +68,11 @@ private:
SDL_Rect gradient_rect_[4]; // Vector con las coordenadas de los 4 degradados para el cielo SDL_Rect gradient_rect_[4]; // Vector con las coordenadas de los 4 degradados para el cielo
SDL_Rect top_clouds_rect_[4]; // Vector con las coordenadas de los 4 nubes de arriba SDL_Rect top_clouds_rect_[4]; // Vector con las coordenadas de los 4 nubes de arriba
SDL_Rect bottom_clouds_rect_[4]; // Vector con las coordenadas de los 4 nubes de abajo SDL_Rect bottom_clouds_rect_[4]; // Vector con las coordenadas de los 4 nubes de abajo
int gradient_number_; // Indica el número de degradado de fondo que se va a dibujar int gradient_number_ = 0; // Indica el número de degradado de fondo que se va a dibujar
int alpha_; // Transparencia entre los dos degradados int alpha_ = 0; // Transparencia entre los dos degradados
float clouds_speed_; // Velocidad a la que se desplazan las nubes float clouds_speed_ = 0; // Velocidad a la que se desplazan las nubes
float transition_; // Nivel de transición del fondo 0..1 float transition_ = 0; // Nivel de transición del fondo 0..1
int counter_; // Contador interno int counter_ = 0; // Contador interno
SDL_Rect rect_; // Tamaño del objeto fondo SDL_Rect rect_; // Tamaño del objeto fondo
SDL_Rect src_rect_; // Parte del objeto fondo que se va a dibujará en pantalla SDL_Rect src_rect_; // Parte del objeto fondo que se va a dibujará en pantalla
SDL_Rect dst_rect_; // Posición donde dibujar la parte del objeto fondo que se dibujará en pantalla SDL_Rect dst_rect_; // Posición donde dibujar la parte del objeto fondo que se dibujará en pantalla
@@ -107,7 +101,7 @@ private:
public: public:
// Constructor // Constructor
explicit Background(SDL_Renderer *renderer); Background();
// Destructor // Destructor
~Background(); ~Background();
@@ -133,12 +127,6 @@ public:
// Ajusta el valor de la variable // Ajusta el valor de la variable
void setTransition(float value); void setTransition(float value);
// Ajusta el valor de la variable
void setSrcRect(SDL_Rect value);
// Ajusta el valor de la variable
void setDstRect(SDL_Rect value);
// Establece el color de atenuación // Establece el color de atenuación
void setColor(Color color); void setColor(Color color);

View File

@@ -1,315 +1,131 @@
#include "balloon.h" #include "balloon.h"
#include <cmath> // for abs #include <algorithm> // Para clamp
#include "animated_sprite.h" // for SpriteAnimated #include <cmath> // Para fabs
#include "moving_sprite.h" // for MovingSprite #include "animated_sprite.h" // Para AnimatedSprite
#include "param.h" // for param #include "param.h" // Para Param, param, ParamBalloon, ParamGame
#include "sprite.h" // for Sprite #include "sprite.h" // Para Sprite
#include "texture.h" // for Texture #include "texture.h" // Para Texture
// Constructor // Constructor
Balloon::Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation) Balloon::Balloon(float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation)
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)), : sprite_(std::make_unique<AnimatedSprite>(texture, animation)),
pos_x_(x), x_(x),
pos_y_(y), y_(y),
vel_x_(vel_x), vx_(vel_x),
being_created_(creation_timer > 0), being_created_(creation_timer > 0),
blinking_(false),
enabled_(true),
invulnerable_(creation_timer > 0), invulnerable_(creation_timer > 0),
stopped_(true), stopped_(creation_timer > 0),
visible_(true),
creation_counter_(creation_timer), creation_counter_(creation_timer),
creation_counter_ini_(creation_timer), creation_counter_ini_(creation_timer),
stopped_counter_(0), type_(type),
kind_(kind), size_(size),
counter_(0),
travel_y_(1.0f),
speed_(speed) speed_(speed)
{ {
switch (type_)
switch (kind_)
{ {
case BALLOON_1: case BalloonType::BALLOON:
// Alto y ancho del objeto {
width_ = BALLOON_WIDTH_1; vy_ = 0;
height_ = BALLOON_WIDTH_1; max_vy_ = 3.0f;
size_ = BALLOON_SIZE_1;
power_ = 1;
// Inicializa los valores de velocidad y gravedad const int size = static_cast<int>(size_);
vel_y_ = 0; gravity_ = param.balloon.at(size).grav;
max_vel_y_ = 3.0f; default_vy_ = param.balloon.at(size).vel;
gravity_ = param.balloon_1.grav; h_ = w_ = BALLOON_SIZE[size];
default_vel_y_ = param.balloon_1.vel; power_ = BALLOON_POWER[size];
menace_ = BALLOON_MENACE[size];
// Puntos que da el globo al ser destruido score_ = BALLOON_SCORE[size];
score_ = BALLOON_SCORE_1;
// Amenaza que genera el globo
menace_ = 1;
break; break;
}
case BALLOON_2: case BalloonType::FLOATER:
// Alto y ancho del objeto {
width_ = BALLOON_WIDTH_2; default_vy_ = max_vy_ = vy_ = fabs(vx_ * 2.0f);
height_ = BALLOON_WIDTH_2;
size_ = BALLOON_SIZE_2;
power_ = 3;
// Inicializa los valores de velocidad y gravedad
vel_y_ = 0;
max_vel_y_ = 3.0f;
gravity_ = param.balloon_2.grav;
default_vel_y_ = param.balloon_2.vel;
// Puntos que da el globo al ser destruido
score_ = BALLOON_SCORE_2;
// Amenaza que genera el globo
menace_ = 2;
break;
case BALLOON_3:
// Alto y ancho del objeto
width_ = BALLOON_WIDTH_3;
height_ = BALLOON_WIDTH_3;
size_ = BALLOON_SIZE_3;
power_ = 7;
// Inicializa los valores de velocidad y gravedad
vel_y_ = 0;
max_vel_y_ = 3.0f;
gravity_ = param.balloon_3.grav;
default_vel_y_ = param.balloon_3.vel;
// Puntos que da el globo al ser destruido
score_ = BALLOON_SCORE_3;
// Amenaza que genera el globo
menace_ = 4;
break;
case BALLOON_4:
// Alto y ancho del objeto
width_ = BALLOON_WIDTH_4;
height_ = BALLOON_WIDTH_4;
size_ = BALLOON_SIZE_4;
power_ = 15;
// Inicializa los valores de velocidad y gravedad
vel_y_ = 0;
max_vel_y_ = 3.0f;
gravity_ = param.balloon_4.grav;
default_vel_y_ = param.balloon_4.vel;
// Puntos que da el globo al ser destruido
score_ = BALLOON_SCORE_4;
// Amenaza que genera el globo
menace_ = 8;
break;
case HEXAGON_1:
// Alto y ancho del objeto
width_ = BALLOON_WIDTH_1;
height_ = BALLOON_WIDTH_1;
size_ = BALLOON_SIZE_1;
power_ = 1;
// Inicializa los valores de velocidad y gravedad
vel_y_ = abs(vel_x) * 2;
max_vel_y_ = abs(vel_x) * 2;
gravity_ = 0.00f; gravity_ = 0.00f;
default_vel_y_ = abs(vel_x) * 2;
// Puntos que da el globo al ser destruido const int size = static_cast<int>(size_);
score_ = BALLOON_SCORE_1; h_ = w_ = BALLOON_SIZE[size];
power_ = BALLOON_POWER[size];
// Amenaza que genera el globo menace_ = BALLOON_MENACE[size];
menace_ = 1; score_ = BALLOON_SCORE[size];
break; break;
}
case HEXAGON_2: case BalloonType::POWERBALL:
// Alto y ancho del objeto {
width_ = BALLOON_WIDTH_2; const int size = 3;
height_ = BALLOON_WIDTH_2; h_ = w_ = BALLOON_SIZE[size];
size_ = BALLOON_SIZE_2; power_ = score_ = menace_ = 0;
power_ = 3;
// Inicializa los valores de velocidad y gravedad vy_ = 0;
vel_y_ = abs(vel_x) * 2; max_vy_ = 3.0f;
max_vel_y_ = abs(vel_x) * 2; gravity_ = param.balloon.at(size).grav;
gravity_ = 0.00f; default_vy_ = param.balloon.at(size).vel;
default_vel_y_ = abs(vel_x) * 2;
// Puntos que da el globo al ser destruido
score_ = BALLOON_SCORE_2;
// Amenaza que genera el globo
menace_ = 2;
break;
case HEXAGON_3:
// Alto y ancho del objeto
width_ = BALLOON_WIDTH_3;
height_ = BALLOON_WIDTH_3;
size_ = BALLOON_SIZE_3;
power_ = 7;
// Inicializa los valores de velocidad y gravedad
vel_y_ = abs(vel_x) * 2;
max_vel_y_ = abs(vel_x) * 2;
gravity_ = 0.00f;
default_vel_y_ = abs(vel_x) * 2;
// Puntos que da el globo al ser destruido
score_ = BALLOON_SCORE_3;
// Amenaza que genera el globo
menace_ = 4;
break;
case HEXAGON_4:
// Alto y ancho del objeto
width_ = BALLOON_WIDTH_4;
height_ = BALLOON_WIDTH_4;
size_ = BALLOON_SIZE_4;
power_ = 15;
// Inicializa los valores de velocidad y gravedad
vel_y_ = abs(vel_x) * 2;
max_vel_y_ = abs(vel_x) * 2;
gravity_ = 0.00f;
default_vel_y_ = abs(vel_x) * 2;
// Puntos que da el globo al ser destruido
score_ = BALLOON_SCORE_4;
// Amenaza que genera el globo
menace_ = 8;
break;
case POWER_BALL:
// Alto y ancho del objeto
width_ = BALLOON_WIDTH_4;
height_ = BALLOON_WIDTH_4;
size_ = 4;
power_ = 0;
// Inicializa los valores de velocidad y gravedad
vel_y_ = 0;
max_vel_y_ = 3.0f;
gravity_ = param.balloon_4.grav;
default_vel_y_ = param.balloon_4.vel;
// Puntos que da el globo al ser destruido
score_ = 0;
// Amenaza que genera el globo
menace_ = 0;
// Añade rotación al sprite_
sprite_->disableRotate(); sprite_->disableRotate();
sprite_->setRotateSpeed(0); sprite_->setRotateSpeed(0);
vel_x_ > 0.0f ? sprite_->setRotateAmount(2.0) : sprite_->setRotateAmount(-2.0); sprite_->setRotateAmount(vx_ > 0.0f ? 2.0 : -2.0);
break; break;
}
default: default:
break; break;
} }
// Valores para el efecto de rebote // Configura el sprite
bouncing_.enabled = false; sprite_->setWidth(w_);
bouncing_.counter = 0; sprite_->setHeight(h_);
bouncing_.speed = 2; shiftSprite();
bouncing_.zoomW = 1.0f;
bouncing_.zoomH = 1.0f;
bouncing_.despX = 0.0f;
bouncing_.despY = 0.0f;
bouncing_.w = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f};
bouncing_.h = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f};
// Alto y ancho del sprite_
sprite_->setWidth(width_);
sprite_->setHeight(height_);
// Posición X,Y del sprite_
sprite_->setPosX((int)pos_x_);
sprite_->setPosY((int)pos_y_);
// Tamaño del circulo de colisión
collider_.r = width_ / 2;
// Alinea el circulo de colisión con el objeto // Alinea el circulo de colisión con el objeto
updateColliders(); collider_.r = w_ / 2;
shiftColliders();
// Establece la animación a usar
setAnimation();
} }
// Centra el globo en la posición X // Centra el globo en la posición X
void Balloon::allignTo(int x) void Balloon::alignTo(int x)
{ {
pos_x_ = float(x - (width_ / 2)); x_ = static_cast<float>(x - (w_ / 2));
const int min_x = param.game.play_area.rect.x;
if (pos_x_ < param.game.play_area.rect.x) const int max_x = param.game.play_area.rect.w - w_;
{ x_ = std::clamp(x_, static_cast<float>(min_x), static_cast<float>(max_x));
pos_x_ = param.game.play_area.rect.x + 1;
}
else if ((pos_x_ + width_) > param.game.play_area.rect.w)
{
pos_x_ = float(param.game.play_area.rect.w - width_ - 1);
}
// Posición X,Y del sprite_
sprite_->setPosX(getPosX());
sprite_->setPosY(getPosY());
// Alinea el circulo de colisión con el objeto
updateColliders();
} }
// Pinta el globo en la pantalla // Pinta el globo en la pantalla
void Balloon::render() void Balloon::render()
{ {
if (visible_ && enabled_) if (isBeingCreated())
{
// Aplica alpha blending
sprite_->getTexture()->setAlpha(255 - (int)((float)creation_counter_ * (255.0f / (float)creation_counter_ini_)));
sprite_->render();
sprite_->getTexture()->setAlpha(255);
}
else
{ {
if (bouncing_.enabled) if (bouncing_.enabled)
{ {
if (kind_ != POWER_BALL) // Aplica efecto de bouncing
{ sprite_->setPos(x_ + bouncing_.despX, y_ + bouncing_.despY);
// Aplica desplazamiento para el zoom
sprite_->setPosX(getPosX() + bouncing_.despX);
sprite_->setPosY(getPosY() + bouncing_.despY);
sprite_->render();
sprite_->setPosX(getPosX() - bouncing_.despX);
sprite_->setPosY(getPosY() - bouncing_.despY);
}
}
else if (isBeingCreated())
{
// Aplica alpha blending
sprite_->getTexture()->setAlpha(255 - (int)((float)creation_counter_ * (255.0f / (float)creation_counter_ini_)));
sprite_->render(); sprite_->render();
sprite_->getTexture()->setAlpha(255); sprite_->setPos(x_ - bouncing_.despX, y_ - bouncing_.despY);
} }
else else
{
sprite_->render(); sprite_->render();
} }
if (kind_ == POWER_BALL && !isBeingCreated()) // Añade la máscara del borde a la PowerBall
{ if (type_ == BalloonType::POWERBALL && !isBeingCreated())
auto sp = std::make_unique<Sprite>(sprite_->getTexture(), sprite_->getPosition()); {
sp->setSpriteClip(BALLOON_WIDTH_4, 0, BALLOON_WIDTH_4, BALLOON_WIDTH_4); auto sp = std::make_unique<Sprite>(sprite_->getTexture(), sprite_->getPosition());
sp->render(); sp->setSpriteClip(BALLOON_SIZE[3], 0, BALLOON_SIZE[3], BALLOON_SIZE[3]);
} sp->render();
} }
} }
@@ -319,61 +135,45 @@ void Balloon::move()
// Comprueba si se puede mover // Comprueba si se puede mover
if (!isStopped()) if (!isStopped())
{ {
// Lo mueve a izquierda o derecha // Mueve el globo en horizontal
pos_x_ += (vel_x_ * speed_); x_ += vx_ * speed_;
// Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido // Colisión en las partes laterales de la zona de juego
if ((pos_x_ < param.game.play_area.rect.x) || (pos_x_ + width_ > param.game.play_area.rect.w)) const int clip = 2;
const float min_x = param.game.play_area.rect.x - clip;
const float max_x = param.game.play_area.rect.w - w_ + clip;
if (x_ < min_x || x_ > max_x)
{ {
// Corrige posición x_ = std::clamp(x_, min_x, max_x);
pos_x_ -= (vel_x_ * speed_); vx_ = -vx_;
// Activa el efecto de rebote o invierte la rotación
// Invierte sentido if (type_ == BalloonType::POWERBALL)
vel_x_ = -vel_x_; sprite_->switchRotate();
else
// Invierte la rotación enableBounce();
sprite_->switchRotate();
// Activa el efecto de rebote
if (kind_ != POWER_BALL)
{
bounceStart();
}
} }
// Mueve el globo hacia arriba o hacia abajo // Mueve el globo en vertical
pos_y_ += (vel_y_ * speed_); y_ += vy_ * speed_;
// Si se sale por arriba // Colisión en la parte superior de la zona de juego
if (pos_y_ < param.game.play_area.rect.y) const int min_y = param.game.play_area.rect.y;
if (y_ < min_y)
{ {
// Corrige y_ = min_y;
pos_y_ = param.game.play_area.rect.y; vy_ = -vy_;
if (type_ != BalloonType::POWERBALL)
// Invierte sentido enableBounce();
vel_y_ = -vel_y_;
// Activa el efecto de rebote
if (kind_ != POWER_BALL)
{
bounceStart();
}
} }
// Si el globo se sale por la parte inferior // Colisión en la parte inferior de la zona de juego
if (pos_y_ + height_ > param.game.play_area.rect.h) const int max_y = param.game.play_area.rect.h - h_;
if (y_ > max_y)
{ {
// Corrige y_ = max_y;
pos_y_ = param.game.play_area.rect.h - height_; vy_ = -default_vy_;
if (type_ != BalloonType::POWERBALL)
// Invierte colocando una velocidad por defecto enableBounce();
vel_y_ = -default_vel_y_;
// Activa el efecto de rebote
if (kind_ != POWER_BALL)
{
bounceStart();
}
} }
/* /*
@@ -395,52 +195,15 @@ void Balloon::move()
travel_y_ -= 1.0f; travel_y_ -= 1.0f;
// Aplica la gravedad al objeto sin pasarse de una velocidad máxima // Aplica la gravedad al objeto sin pasarse de una velocidad máxima
vel_y_ += gravity_; vy_ += gravity_;
// Al parecer esta asignación se quedó sin hacer y ahora el juego no funciona
// correctamente si se aplica, así que se deja sin efecto
// vel_y_ = std::min(vel_y_, max_vel_y_);
} }
// Actualiza la posición del sprite_
sprite_->setPosX(getPosX());
sprite_->setPosY(getPosY());
} }
} }
// Deshabilita el globo y pone a cero todos los valores // Deshabilita el globo y pone a cero todos los valores
void Balloon::disable() void Balloon::disable()
{ {
being_created_ = false;
blinking_ = false;
collider_.r = 0;
collider_.x = 0;
collider_.y = 0;
counter_ = 0;
creation_counter_ = 0;
creation_counter_ini_ = 0;
default_vel_y_ = 0.0f;
enabled_ = false; enabled_ = false;
gravity_ = 0.0f;
height_ = 0;
invulnerable_ = false;
kind_ = 0;
max_vel_y_ = 0.0f;
menace_ = 0;
pos_x_ = 0.0f;
pos_y_ = 0.0f;
power_ = 0;
score_ = 0;
size_ = 0;
speed_ = 0;
stopped_ = false;
stopped_counter_ = 0;
travel_y_ = 0;
vel_x_ = 0.0f;
vel_y_ = 0.0f;
visible_ = false;
width_ = 0;
sprite_->clear();
} }
// Explosiona el globo // Explosiona el globo
@@ -452,16 +215,13 @@ void Balloon::pop()
// Actualiza al globo a su posicion, animación y controla los contadores // Actualiza al globo a su posicion, animación y controla los contadores
void Balloon::update() void Balloon::update()
{ {
if (enabled_) move();
{ updateState();
sprite_->update(); updateBounce();
move(); shiftSprite();
updateAnimation(); shiftColliders();
updateColliders(); sprite_->update();
updateState(); ++counter_;
updateBounce();
counter_++;
}
} }
// Actualiza los estados del globo // Actualiza los estados del globo
@@ -471,105 +231,69 @@ void Balloon::updateState()
if (isBeingCreated()) if (isBeingCreated())
{ {
// Actualiza el valor de las variables // Actualiza el valor de las variables
setStop(true); stop();
setInvulnerable(true); setInvulnerable(true);
// Todavia tiene tiempo en el contador
if (creation_counter_ > 0) if (creation_counter_ > 0)
{ {
// Desplaza lentamente el globo hacia abajo y hacia un lado // Desplaza lentamente el globo hacia abajo y hacia un lado
if (creation_counter_ % 10 == 0) if (creation_counter_ % 10 == 0)
{ {
pos_y_++; y_++;
pos_x_ += vel_x_; x_ += vx_;
// Comprueba no se salga por los laterales // Comprueba no se salga por los laterales
if ((pos_x_ < param.game.play_area.rect.x) || (pos_x_ > (param.game.play_area.rect.w - width_))) const int min_x = param.game.play_area.rect.x;
const int max_x = param.game.play_area.rect.w - w_;
if (x_ < min_x || x_ > max_x)
{ {
// Corrige y cambia el sentido de la velocidad // Corrige y cambia el sentido de la velocidad
pos_x_ -= vel_x_; x_ -= vx_;
vel_x_ = -vel_x_; vx_ = -vx_;
} }
// Actualiza la posición del sprite_
sprite_->setPosX(getPosX());
sprite_->setPosY(getPosY());
// Actualiza la posición del circulo de colisión
updateColliders();
} }
--creation_counter_;
creation_counter_--;
} }
// El contador ha llegado a cero
else else
{ {
setBeingCreated(false); // El contador ha llegado a cero
setStop(false); being_created_ = false;
setVisible(true); start();
setInvulnerable(false); setInvulnerable(false);
if (kind_ == POWER_BALL) setAnimation();
{
sprite_->enableRotate();
}
}
}
// Solo comprueba el estado detenido cuando no se está creando
else if (isStopped())
{
// Si es una powerball deja de rodar
if (kind_ == POWER_BALL)
{
sprite_->disableRotate();
}
// Reduce el contador
if (stopped_counter_ > 0)
{
stopped_counter_--;
}
// Si el contador ha llegado a cero
else
{ // Quitarles el estado "detenido"
setStop(false);
// Si es una powerball vuelve a rodar
if (kind_ == POWER_BALL)
{
sprite_->enableRotate();
}
} }
} }
} }
// Establece la animación correspondiente al estado // Establece la animación correspondiente al estado
void Balloon::updateAnimation() void Balloon::setAnimation()
{ {
std::string creating_animation = "blue"; std::string creating_animation;
std::string normal_animation = "orange"; std::string normal_animation;
if (kind_ == POWER_BALL) switch (type_)
{ {
case BalloonType::POWERBALL:
creating_animation = "powerball"; creating_animation = "powerball";
normal_animation = "powerball"; normal_animation = "powerball";
} break;
else if (getClass() == HEXAGON_CLASS) case BalloonType::FLOATER:
{
creating_animation = "red"; creating_animation = "red";
normal_animation = "green"; normal_animation = "green";
break;
default:
creating_animation = "blue";
normal_animation = "orange";
break;
} }
// Establece el frame de animación // Establece el frame de animación
if (isBeingCreated()) if (use_reversed_colors_)
{
sprite_->setCurrentAnimation(creating_animation); sprite_->setCurrentAnimation(creating_animation);
}
else else
{ sprite_->setCurrentAnimation(isBeingCreated() ? creating_animation : normal_animation);
sprite_->setCurrentAnimation(normal_animation);
}
sprite_->update();
} }
// Comprueba si el globo está habilitado // Comprueba si el globo está habilitado
@@ -581,77 +305,65 @@ bool Balloon::isEnabled() const
// Obtiene del valor de la variable // Obtiene del valor de la variable
float Balloon::getPosX() const float Balloon::getPosX() const
{ {
return pos_x_; return x_;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
float Balloon::getPosY() const float Balloon::getPosY() const
{ {
return pos_y_; return y_;
}
// Obtiene del valor de la variable
float Balloon::getVelY() const
{
return vel_y_;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
int Balloon::getWidth() const int Balloon::getWidth() const
{ {
return width_; return w_;
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
int Balloon::getHeight() const int Balloon::getHeight() const
{ {
return height_; return h_;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Balloon::setVelY(float vel_y_) void Balloon::setVelY(float vel_y)
{ {
this->vel_y_ = vel_y_; vy_ = vel_y;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Balloon::setSpeed(float speed_) void Balloon::setSpeed(float speed)
{ {
this->speed_ = speed_; speed_ = speed;
} }
// Obtiene del valor de la variable // Obtiene el tamaño del globo
int Balloon::getKind() const BalloonSize Balloon::getSize() const
{
return kind_;
}
// Obtiene del valor de la variable
Uint8 Balloon::getSize() const
{ {
return size_; return size_;
} }
// Obtiene la clase a la que pertenece el globo // Obtiene el tipo de globo
Uint8 Balloon::getClass() const BalloonType Balloon::getType() const
{ {
if ((kind_ >= BALLOON_1) && (kind_ <= BALLOON_4)) return type_;
{
return BALLOON_CLASS;
}
else if ((kind_ >= HEXAGON_1) && (kind_ <= HEXAGON_4))
{
return HEXAGON_CLASS;
}
return BALLOON_CLASS;
} }
// Establece el valor de la variable // Detiene el globo
void Balloon::setStop(bool state) void Balloon::stop()
{ {
stopped_ = state; stopped_ = true;
if (type_ == BalloonType::POWERBALL)
sprite_->disableRotate();
}
// Pone el globo en movimiento
void Balloon::start()
{
stopped_ = false;
if (type_ == BalloonType::POWERBALL)
sprite_->enableRotate();
} }
// Obtiene del valor de la variable // Obtiene del valor de la variable
@@ -660,30 +372,6 @@ bool Balloon::isStopped() const
return stopped_; return stopped_;
} }
// Establece el valor de la variable
void Balloon::setBlink(bool value)
{
blinking_ = value;
}
// Obtiene del valor de la variable
bool Balloon::isBlinking() const
{
return blinking_;
}
// Establece el valor de la variable
void Balloon::setVisible(bool value)
{
visible_ = value;
}
// Obtiene del valor de la variable
bool Balloon::isVisible() const
{
return visible_;
}
// Establece el valor de la variable // Establece el valor de la variable
void Balloon::setInvulnerable(bool value) void Balloon::setInvulnerable(bool value)
{ {
@@ -696,30 +384,12 @@ bool Balloon::isInvulnerable() const
return invulnerable_; return invulnerable_;
} }
// Establece el valor de la variable
void Balloon::setBeingCreated(bool value)
{
being_created_ = value;
}
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool Balloon::isBeingCreated() const bool Balloon::isBeingCreated() const
{ {
return being_created_; return being_created_;
} }
// Establece el valor de la variable
void Balloon::setStoppedTimer(Uint16 time)
{
stopped_counter_ = time;
}
// Obtiene del valor de la variable
Uint16 Balloon::getStoppedTimer() const
{
return stopped_counter_;
}
// Obtiene del valor de la variable // Obtiene del valor de la variable
Uint16 Balloon::getScore() const Uint16 Balloon::getScore() const
{ {
@@ -733,10 +403,24 @@ Circle &Balloon::getCollider()
} }
// Alinea el circulo de colisión con la posición del objeto globo // Alinea el circulo de colisión con la posición del objeto globo
void Balloon::updateColliders() void Balloon::shiftColliders()
{ {
collider_.x = Uint16(pos_x_ + collider_.r); collider_.x = static_cast<int>(x_) + collider_.r;
collider_.y = pos_y_ + collider_.r; collider_.y = static_cast<int>(y_) + collider_.r;
}
// Alinea el sprite con la posición del objeto globo
void Balloon::shiftSprite()
{
sprite_->setPosX(x_);
sprite_->setPosY(y_);
}
// Establece el nivel de zoom del sprite
void Balloon::zoomSprite()
{
sprite_->setZoomW(bouncing_.zoomW);
sprite_->setZoomH(bouncing_.zoomH);
} }
// Obtiene le valor de la variable // Obtiene le valor de la variable
@@ -751,44 +435,39 @@ Uint8 Balloon::getPower() const
return power_; return power_;
} }
void Balloon::bounceStart() // Activa el efecto
void Balloon::enableBounce()
{ {
bouncing_.enabled = true; bouncing_.enabled = true;
bouncing_.zoomW = 1; bouncing_.reset();
bouncing_.zoomH = 1; zoomSprite();
sprite_->setZoomW(bouncing_.zoomW);
sprite_->setZoomH(bouncing_.zoomH);
bouncing_.despX = 0;
bouncing_.despY = 0;
} }
void Balloon::bounceStop() // Detiene el efecto
void Balloon::disableBounce()
{ {
bouncing_.enabled = false; bouncing_.enabled = false;
bouncing_.counter = 0; bouncing_.reset();
bouncing_.zoomW = 1.0f; zoomSprite();
bouncing_.zoomH = 1.0f;
sprite_->setZoomW(bouncing_.zoomW);
sprite_->setZoomH(bouncing_.zoomH);
bouncing_.despX = 0.0f;
bouncing_.despY = 0.0f;
} }
// Aplica el efecto
void Balloon::updateBounce() void Balloon::updateBounce()
{ {
if (bouncing_.enabled) if (bouncing_.enabled)
{ {
bouncing_.zoomW = bouncing_.w[bouncing_.counter / bouncing_.speed]; const int index = bouncing_.counter / bouncing_.speed;
bouncing_.zoomH = bouncing_.h[bouncing_.counter / bouncing_.speed]; bouncing_.zoomW = bouncing_.w[index];
sprite_->setZoomW(bouncing_.zoomW); bouncing_.zoomH = bouncing_.h[index];
sprite_->setZoomH(bouncing_.zoomH);
bouncing_.despX = (sprite_->getSpriteClip().w - (sprite_->getSpriteClip().w * bouncing_.zoomW)); zoomSprite();
bouncing_.despY = (sprite_->getSpriteClip().h - (sprite_->getSpriteClip().h * bouncing_.zoomH));
++bouncing_.counter; const auto spriteClip = sprite_->getSpriteClip();
if ((bouncing_.counter / bouncing_.speed) > (MAX_BOUNCE - 1)) bouncing_.despX = spriteClip.w * (1.0f - bouncing_.zoomW);
{ bouncing_.despY = spriteClip.h * (1.0f - bouncing_.zoomH);
bounceStop();
} if (++bouncing_.counter / bouncing_.speed >= MAX_BOUNCE)
disableBounce();
} }
} }
@@ -802,4 +481,27 @@ bool Balloon::canBePopped() const
bool Balloon::canBeDestroyed() const bool Balloon::canBeDestroyed() const
{ {
return isEnabled(); return isEnabled();
}
// Pone el color alternativo en el globo
void Balloon::useReverseColor()
{
if (!isBeingCreated())
{
use_reversed_colors_ = true;
setAnimation();
}
}
// Pone el color normal en el globo
void Balloon::useNormalColor()
{
use_reversed_colors_ = false;
setAnimation();
}
// Indica si está usando el color alternativo
bool Balloon::isUsingReversedColor()
{
return use_reversed_colors_;
} }

View File

@@ -1,42 +1,38 @@
#pragma once #pragma once
#include <SDL2/SDL_stdinc.h> // for Uint8, Uint16, Uint32 #include <SDL2/SDL_stdinc.h> // Para Uint8, Uint16, Uint32
#include <memory> // for shared_ptr, unique_ptr #include <memory> // Para shared_ptr, unique_ptr
#include <string> // for string #include <string> // Para string
#include <vector> // for vector #include <vector> // Para vector
#include "animated_sprite.h" // for SpriteAnimated #include "animated_sprite.h" // Para AnimatedSprite
#include "utils.h" // for Circle #include "utils.h" // Para Circle
class Texture; class Texture; // lines 10-10
// Cantidad de elementos del vector con los valores de la deformación del globo al rebotar // Cantidad de elementos del vector con los valores de la deformación del globo al rebotar
constexpr int MAX_BOUNCE = 10; constexpr int MAX_BOUNCE = 10;
// Tipos de globo
constexpr int BALLOON_1 = 1;
constexpr int BALLOON_2 = 2;
constexpr int BALLOON_3 = 3;
constexpr int BALLOON_4 = 4;
constexpr int HEXAGON_1 = 5;
constexpr int HEXAGON_2 = 6;
constexpr int HEXAGON_3 = 7;
constexpr int HEXAGON_4 = 8;
constexpr int POWER_BALL = 9;
// Puntos de globo // Puntos de globo
constexpr int BALLOON_SCORE_1 = 50; constexpr int BALLOON_SCORE[] = {50, 100, 200, 400};
constexpr int BALLOON_SCORE_2 = 100; constexpr int BALLOON_POWER[] = {1, 3, 7, 15};
constexpr int BALLOON_SCORE_3 = 200; constexpr int BALLOON_MENACE[] = {1, 2, 4, 8};
constexpr int BALLOON_SCORE_4 = 400; constexpr int BALLOON_SIZE[] = {10, 16, 26, 46};
// Tamaños de globo // Tamaños de globo
constexpr int BALLOON_SIZE_1 = 1; enum class BalloonSize : Uint8
constexpr int BALLOON_SIZE_2 = 2; {
constexpr int BALLOON_SIZE_3 = 3; SIZE1 = 0,
constexpr int BALLOON_SIZE_4 = 4; SIZE2 = 1,
SIZE3 = 2,
SIZE4 = 3,
};
// Clases de globo // Clases de globo
constexpr int BALLOON_CLASS = 0; enum class BalloonType : Uint8
constexpr int HEXAGON_CLASS = 1; {
BALLOON = 0,
FLOATER = 1,
POWERBALL = 2,
};
// Velocidad del globo // Velocidad del globo
constexpr float BALLOON_VELX_POSITIVE = 0.7f; constexpr float BALLOON_VELX_POSITIVE = 0.7f;
@@ -47,21 +43,8 @@ constexpr int BALLOON_MOVING_ANIMATION = 0;
constexpr int BALLOON_POP_ANIMATION = 1; constexpr int BALLOON_POP_ANIMATION = 1;
constexpr int BALLOON_BORN_ANIMATION = 2; constexpr int BALLOON_BORN_ANIMATION = 2;
// Cantidad posible de globos
constexpr int MAX_BALLOONS = 100;
// Velocidades a las que se mueven los globos // Velocidades a las que se mueven los globos
constexpr float BALLOON_SPEED_1 = 0.60f; constexpr float BALLOON_SPEED[] = {0.60f, 0.70f, 0.80f, 0.90f, 1.00f};
constexpr float BALLOON_SPEED_2 = 0.70f;
constexpr float BALLOON_SPEED_3 = 0.80f;
constexpr float BALLOON_SPEED_4 = 0.90f;
constexpr float BALLOON_SPEED_5 = 1.00f;
// Tamaño de los globos
constexpr int BALLOON_WIDTH_1 = 10;
constexpr int BALLOON_WIDTH_2 = 16;
constexpr int BALLOON_WIDTH_3 = 26;
constexpr int BALLOON_WIDTH_4 = 46;
// PowerBall // PowerBall
constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10; constexpr int POWERBALL_SCREENPOWER_MINIMUM = 10;
@@ -71,61 +54,78 @@ constexpr int POWERBALL_COUNTER = 8;
class Balloon class Balloon
{ {
private: private:
// Estructura para las variables para el efecto de los rebotes // Estructura para el efecto de los rebotes en los globos
struct Bouncing struct Bouncing
{ {
bool enabled; // Si el efecto está activo bool enabled = false; // Si el efecto está activo
Uint8 counter; // Countador para el efecto Uint8 counter = 0; // Contador para el efecto
Uint8 speed; // Velocidad a la que transcurre el efecto Uint8 speed = 2; // Velocidad a la que transcurre el efecto
float zoomW; // Zoom aplicado a la anchura float zoomW = 1.0f; // Zoom aplicado a la anchura
float zoomH; // Zoom aplicado a la altura float zoomH = 1.0f; // Zoom aplicado a la altura
float despX; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom float despX = 0.0f; // 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 float despY = 0.0f; // 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 float w[MAX_BOUNCE] = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f}; // Vector con los valores de zoom para el ancho del globo
}; float h[MAX_BOUNCE] = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f}; // Vector con los valores de zoom para el alto del globo
// Constructor por defecto
Bouncing() = default;
// Método reset
void reset()
{
counter = 0;
zoomW = 1.0f;
zoomH = 1.0f;
despX = 0.0f;
despY = 0.0f;
}
} bouncing_;
// Objetos y punteros // Objetos y punteros
std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo std::unique_ptr<AnimatedSprite> sprite_; // Sprite del objeto globo
// Variables // Variables
float pos_x_; // Posición en el eje X float x_; // Posición en el eje X
float pos_y_; // Posición en el eje Y float y_; // Posición en el eje Y
Uint8 width_; // Ancho Uint8 w_; // Ancho
Uint8 height_; // Alto Uint8 h_; // Alto
float vel_x_; // Velocidad en el eje X. Cantidad de pixeles a desplazarse float vx_; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
float vel_y_; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse float vy_; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
float gravity_; // Aceleración en el eje Y. Modifica la velocidad float gravity_; // Aceleración en el eje Y. Modifica la velocidad
float default_vel_y_; // Velocidad inicial que tienen al rebotar contra el suelo float default_vy_; // Velocidad inicial que tienen al rebotar contra el suelo
float max_vel_y_; // Máxima velocidad que puede alcanzar el objeto en el eje Y float max_vy_; // Máxima velocidad que puede alcanzar el objeto en el eje Y
bool being_created_; // Indica si el globo se está creando bool being_created_; // Indica si el globo se está creando
bool blinking_; // Indica si el globo está intermitente bool enabled_ = true; // Indica si el globo esta activo
bool enabled_; // Indica si el globo esta activo bool invulnerable_; // Indica si el globo es invulnerable
bool invulnerable_; // Indica si el globo es invulnerable bool stopped_; // Indica si el globo está parado
bool stopped_; // Indica si el globo está parado bool use_reversed_colors_ = false; // Indica si se ha de usar el color secundario del globo como color principal
bool visible_; // Indica si el globo es visible Circle collider_; // Circulo de colisión del objeto
Circle collider_; // Circulo de colisión del objeto Uint16 creation_counter_; // Temporizador para controlar el estado "creandose"
Uint16 creation_counter_; // Temporizador para controlar el estado "creandose" Uint16 creation_counter_ini_; // Valor inicial para el temporizador para controlar el estado "creandose"
Uint16 creation_counter_ini_; // Valor inicial para el temporizador para controlar el estado "creandose" Uint16 score_; // Puntos que da el globo al ser destruido
Uint16 score_; // Puntos que da el globo al ser destruido BalloonType type_; // Clase de globo
Uint16 stopped_counter_; // Contador para controlar el estado "parado" BalloonSize size_; // Tamaño del globo
Uint8 kind_; // Tipo de globo Uint8 menace_; // Cantidad de amenaza que genera el globo
Uint8 menace_; // Cantidad de amenaza que genera el globo Uint32 counter_ = 0; // Contador interno
Uint32 counter_; // Contador interno float travel_y_ = 1.0f; // Distancia que ha de recorrer el globo en el eje Y antes de que se le aplique la gravedad
float travel_y_; // Distancia que ha de recorrer el globo en el eje Y antes de que se le aplique la gravedad float speed_; // Velocidad a la que se mueven los globos
float speed_; // Velocidad a la que se mueven los globos Uint8 power_; // Cantidad de poder que alberga el globo
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 // Alinea el circulo de colisión con la posición del objeto globo
void updateColliders(); void shiftColliders();
// Alinea el sprite con la posición del objeto globo
void shiftSprite();
// Establece el nivel de zoom del sprite
void zoomSprite();
// Activa el efecto // Activa el efecto
void bounceStart(); void enableBounce();
// Detiene el efecto // Detiene el efecto
void bounceStop(); void disableBounce();
// Aplica el efecto // Aplica el efecto
void updateBounce(); void updateBounce();
@@ -134,20 +134,17 @@ private:
void updateState(); void updateState();
// Establece la animación correspondiente // Establece la animación correspondiente
void updateAnimation(); void setAnimation();
// Establece el valor de la variable
void setBeingCreated(bool value);
public: public:
// Constructor // Constructor
Balloon(float x, float y, Uint8 kind, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation); Balloon(float x, float y, BalloonType type, BalloonSize size, float vel_x, float speed, Uint16 creation_timer, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation);
// Destructor // Destructor
~Balloon() = default; ~Balloon() = default;
// Centra el globo en la posición X // Centra el globo en la posición X
void allignTo(int x); void alignTo(int x);
// Pinta el globo en la pantalla // Pinta el globo en la pantalla
void render(); void render();
@@ -173,9 +170,6 @@ public:
// Obtiene del valor de la variable // Obtiene del valor de la variable
float getPosY() const; float getPosY() const;
// Obtiene del valor de la variable
float getVelY() const;
// Obtiene del valor de la variable // Obtiene del valor de la variable
int getWidth() const; int getWidth() const;
@@ -188,33 +182,21 @@ public:
// Establece el valor de la variable // Establece el valor de la variable
void setSpeed(float speed); void setSpeed(float speed);
// Obtiene del valor de la variable // Obtiene el tamaño del globo
int getKind() const; BalloonSize getSize() const;
// Obtiene del valor de la variable // Obtiene el tipo de globo
Uint8 getSize() const; BalloonType getType() const;
// Obtiene la clase a la que pertenece el globo // Detiene el globo
Uint8 getClass() const; void stop();
// Establece el valor de la variable // Pone el globo en movimiento
void setStop(bool value); void start();
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool isStopped() const; bool isStopped() const;
// Establece el valor de la variable
void setBlink(bool value);
// Obtiene del valor de la variable
bool isBlinking() const;
// Establece el valor de la variable
void setVisible(bool value);
// Obtiene del valor de la variable
bool isVisible() const;
// Establece el valor de la variable // Establece el valor de la variable
void setInvulnerable(bool value); void setInvulnerable(bool value);
@@ -224,12 +206,6 @@ public:
// Obtiene del valor de la variable // Obtiene del valor de la variable
bool isBeingCreated() const; bool isBeingCreated() const;
// Establece el valor de la variable
void setStoppedTimer(Uint16 time);
// Obtiene del valor de la variable
Uint16 getStoppedTimer() const;
// Obtiene del valor de la variable // Obtiene del valor de la variable
Uint16 getScore() const; Uint16 getScore() const;
@@ -247,4 +223,13 @@ public:
// Indica si el globo se puede destruir // Indica si el globo se puede destruir
bool canBeDestroyed() const; bool canBeDestroyed() const;
// Pone el color alternativo en el globo
void useReverseColor();
// Pone el color normal en el globo
void useNormalColor();
// Indica si está usando el color alternativo
bool isUsingReversedColor();
}; };

View File

@@ -1,7 +1,7 @@
#include "balloon_formations.h" #include "balloon_formations.h"
#include "balloon.h" // for BALLOON_VELX_NEGATIVE, BALLOON_VELX_POSITIVE #include "balloon.h" // para BALLOON_VELX_NEGATIVE, BALLOON_VELX_POSITIVE
#include "param.h" // for param #include "param.h" // para param
#include "utils.h" // for ParamGame, Param, Zone, BLOCK #include "utils.h" // para ParamGame, Param, Zone, BLOCK
// Constructor // Constructor
BalloonFormations::BalloonFormations() BalloonFormations::BalloonFormations()
@@ -16,36 +16,32 @@ void BalloonFormations::initBalloonFormations()
{ {
constexpr int y4 = -BLOCK; constexpr int y4 = -BLOCK;
const int x4_0 = param.game.play_area.rect.x; const int x4_0 = param.game.play_area.rect.x;
const int x4_100 = param.game.play_area.rect.w - BALLOON_WIDTH_4; const int x4_100 = param.game.play_area.rect.w - BALLOON_SIZE[3];
constexpr int y3 = -BLOCK; constexpr int y3 = -BLOCK;
const int x3_0 = param.game.play_area.rect.x; const int x3_0 = param.game.play_area.rect.x;
const int x3_100 = param.game.play_area.rect.w - BALLOON_WIDTH_3; const int x3_100 = param.game.play_area.rect.w - BALLOON_SIZE[2];
constexpr int y2 = -BLOCK; constexpr int y2 = -BLOCK;
const int x2_0 = param.game.play_area.rect.x; const int x2_0 = param.game.play_area.rect.x;
const int x2_100 = param.game.play_area.rect.w - BALLOON_WIDTH_2; const int x2_100 = param.game.play_area.rect.w - BALLOON_SIZE[1];
constexpr int y1 = -BLOCK; constexpr int y1 = -BLOCK;
const int x1_0 = param.game.play_area.rect.x; const int x1_0 = param.game.play_area.rect.x;
const int x1_50 = param.game.play_area.center_x - (BALLOON_WIDTH_1 / 2); const int x1_50 = param.game.play_area.center_x - (BALLOON_SIZE[0] / 2);
const int x1_100 = param.game.play_area.rect.w - BALLOON_WIDTH_1; const int x1_100 = param.game.play_area.rect.w - BALLOON_SIZE[0];
// Inicializa a cero las variables // Inicializa a cero las variables
for (int i = 0; i < NUMBER_OF_BALLOON_FORMATIONS; i++) for (int j = 0; j < NUMBER_OF_BALLOON_FORMATIONS; ++j)
{ {
balloon_formation_[i].number_of_balloons = 0; balloon_formation_[j].number_of_balloons = 0;
for (int j = 0; j < MAX_NUMBER_OF_BALLOONS_IN_A_FORMATION; j++) for (int i = 0; i < MAX_NUMBER_OF_BALLOONS_IN_A_FORMATION; ++i)
{ {
balloon_formation_[i].init[j].x = 0; balloon_formation_[j].init[i] = BalloonFormationParams();
balloon_formation_[i].init[j].y = 0;
balloon_formation_[i].init[j].vel_x = 0;
balloon_formation_[i].init[j].kind = 0;
balloon_formation_[i].init[j].creation_counter = 0;
} }
} }
const int creation_time = 300; constexpr int CREATION_TIME = 300;
int inc_x = 0; int inc_x = 0;
int inc_time = 0; int inc_time = 0;
int j = 0; int j = 0;
@@ -60,8 +56,8 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].x = x4_0 + (i * inc_x); balloon_formation_[j].init[i].x = x4_0 + (i * inc_x);
balloon_formation_[j].init[i].y = y4; balloon_formation_[j].init[i].y = y4;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1); balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1);
balloon_formation_[j].init[i].kind = BALLOON_4; balloon_formation_[j].init[i].size = BalloonSize::SIZE4;
balloon_formation_[j].init[i].creation_counter = creation_time + (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME + (inc_time * i);
} }
// #01 - Dos enemigos BALLOON4 uno a cada cuarto. Ambos van hacia el centro // #01 - Dos enemigos BALLOON4 uno a cada cuarto. Ambos van hacia el centro
@@ -71,269 +67,269 @@ void BalloonFormations::initBalloonFormations()
inc_time = 0; inc_time = 0;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = param.game.play_area.first_quarter_x - (BALLOON_WIDTH_4 / 2) + (i * inc_x); balloon_formation_[j].init[i].x = param.game.play_area.first_quarter_x - (BALLOON_SIZE[3] / 2) + (i * inc_x);
balloon_formation_[j].init[i].y = y4; balloon_formation_[j].init[i].y = y4;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1); balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE * (((i % 2) * 2) - 1);
balloon_formation_[j].init[i].kind = BALLOON_4; balloon_formation_[j].init[i].size = BalloonSize::SIZE4;
balloon_formation_[j].init[i].creation_counter = creation_time + (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME + (inc_time * i);
} }
// #02 - Cuatro enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro // #02 - Cuatro enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro
j = 2; j = 2;
balloon_formation_[j].number_of_balloons = 4; balloon_formation_[j].number_of_balloons = 4;
inc_x = BALLOON_WIDTH_2 + 1; inc_x = BALLOON_SIZE[1] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x2_0 + (i * inc_x); balloon_formation_[j].init[i].x = x2_0 + (i * inc_x);
balloon_formation_[j].init[i].y = y2; balloon_formation_[j].init[i].y = y2;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_2; balloon_formation_[j].init[i].size = BalloonSize::SIZE2;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #03 - Cuatro enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro // #03 - Cuatro enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro
j = 3; j = 3;
balloon_formation_[j].number_of_balloons = 4; balloon_formation_[j].number_of_balloons = 4;
inc_x = BALLOON_WIDTH_2 + 1; inc_x = BALLOON_SIZE[1] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x2_100 - (i * inc_x); balloon_formation_[j].init[i].x = x2_100 - (i * inc_x);
balloon_formation_[j].init[i].y = y2; balloon_formation_[j].init[i].y = y2;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_2; balloon_formation_[j].init[i].size = BalloonSize::SIZE2;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #04 - Tres enemigos BALLOON3. 0, 25, 50. Hacia la derecha // #04 - Tres enemigos BALLOON3. 0, 25, 50. Hacia la derecha
j = 4; j = 4;
balloon_formation_[j].number_of_balloons = 3; balloon_formation_[j].number_of_balloons = 3;
inc_x = BALLOON_WIDTH_3 * 2; inc_x = BALLOON_SIZE[2] * 2;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x3_0 + (i * inc_x); balloon_formation_[j].init[i].x = x3_0 + (i * inc_x);
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].size = BalloonSize::SIZE3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #05 - Tres enemigos BALLOON3. 50, 75, 100. Hacia la izquierda // #05 - Tres enemigos BALLOON3. 50, 75, 100. Hacia la izquierda
j = 5; j = 5;
balloon_formation_[j].number_of_balloons = 3; balloon_formation_[j].number_of_balloons = 3;
inc_x = BALLOON_WIDTH_3 * 2; inc_x = BALLOON_SIZE[2] * 2;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x3_100 - (i * inc_x); balloon_formation_[j].init[i].x = x3_100 - (i * inc_x);
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].size = BalloonSize::SIZE3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #06 - Tres enemigos BALLOON3. 0, 0, 0. Hacia la derecha // #06 - Tres enemigos BALLOON3. 0, 0, 0. Hacia la derecha
j = 6; j = 6;
balloon_formation_[j].number_of_balloons = 3; balloon_formation_[j].number_of_balloons = 3;
inc_x = BALLOON_WIDTH_3 + 1; inc_x = BALLOON_SIZE[2] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x3_0 + (i * inc_x); balloon_formation_[j].init[i].x = x3_0 + (i * inc_x);
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].size = BalloonSize::SIZE3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #07 - Tres enemigos BALLOON3. 100, 100, 100. Hacia la izquierda // #07 - Tres enemigos BALLOON3. 100, 100, 100. Hacia la izquierda
j = 7; j = 7;
balloon_formation_[j].number_of_balloons = 3; balloon_formation_[j].number_of_balloons = 3;
inc_x = BALLOON_WIDTH_3 + 1; inc_x = BALLOON_SIZE[2] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x3_100 - (i * inc_x); balloon_formation_[j].init[i].x = x3_100 - (i * inc_x);
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].size = BalloonSize::SIZE3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #08 - Seis enemigos BALLOON1. 0, 0, 0, 0, 0, 0. Hacia la derecha // #08 - Seis enemigos BALLOON1. 0, 0, 0, 0, 0, 0. Hacia la derecha
j = 8; j = 8;
balloon_formation_[j].number_of_balloons = 6; balloon_formation_[j].number_of_balloons = 6;
inc_x = BALLOON_WIDTH_1 + 1; inc_x = BALLOON_SIZE[0] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x1_0 + (i * inc_x); balloon_formation_[j].init[i].x = x1_0 + (i * inc_x);
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].size = BalloonSize::SIZE1;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #09 - Seis enemigos BALLOON1. 100, 100, 100, 100, 100, 100. Hacia la izquierda // #09 - Seis enemigos BALLOON1. 100, 100, 100, 100, 100, 100. Hacia la izquierda
j = 9; j = 9;
balloon_formation_[j].number_of_balloons = 6; balloon_formation_[j].number_of_balloons = 6;
inc_x = BALLOON_WIDTH_1 + 1; inc_x = BALLOON_SIZE[0] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x1_100 - (i * inc_x); balloon_formation_[j].init[i].x = x1_100 - (i * inc_x);
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].size = BalloonSize::SIZE1;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #10 - Tres enemigos BALLOON4 seguidos desde la izquierda // #10 - Tres enemigos BALLOON4 seguidos desde la izquierda
j = 10; j = 10;
balloon_formation_[j].number_of_balloons = 3; balloon_formation_[j].number_of_balloons = 3;
inc_x = BALLOON_WIDTH_4 + 1; inc_x = BALLOON_SIZE[3] + 1;
inc_time = 15; inc_time = 15;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x4_0 + (i * inc_x); balloon_formation_[j].init[i].x = x4_0 + (i * inc_x);
balloon_formation_[j].init[i].y = y4; balloon_formation_[j].init[i].y = y4;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_4; balloon_formation_[j].init[i].size = BalloonSize::SIZE4;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #11 - Tres enemigos BALLOON4 seguidos desde la derecha // #11 - Tres enemigos BALLOON4 seguidos desde la derecha
j = 11; j = 11;
balloon_formation_[j].number_of_balloons = 3; balloon_formation_[j].number_of_balloons = 3;
inc_x = BALLOON_WIDTH_4 + 1; inc_x = BALLOON_SIZE[3] + 1;
inc_time = 15; inc_time = 15;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x4_100 - (i * inc_x); balloon_formation_[j].init[i].x = x4_100 - (i * inc_x);
balloon_formation_[j].init[i].y = y4; balloon_formation_[j].init[i].y = y4;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_4; balloon_formation_[j].init[i].size = BalloonSize::SIZE4;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #12 - Seis enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro // #12 - Seis enemigos BALLOON2 uno detras del otro. A la izquierda y hacia el centro
j = 12; j = 12;
balloon_formation_[j].number_of_balloons = 6; balloon_formation_[j].number_of_balloons = 6;
inc_x = BALLOON_WIDTH_2 + 1; inc_x = BALLOON_SIZE[1] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x2_0 + (i * inc_x); balloon_formation_[j].init[i].x = x2_0 + (i * inc_x);
balloon_formation_[j].init[i].y = y2; balloon_formation_[j].init[i].y = y2;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_2; balloon_formation_[j].init[i].size = BalloonSize::SIZE2;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #13 - Seis enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro // #13 - Seis enemigos BALLOON2 uno detras del otro. A la derecha y hacia el centro
j = 13; j = 13;
balloon_formation_[j].number_of_balloons = 6; balloon_formation_[j].number_of_balloons = 6;
inc_x = BALLOON_WIDTH_2 + 1; inc_x = BALLOON_SIZE[1] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x2_100 - (i * inc_x); balloon_formation_[j].init[i].x = x2_100 - (i * inc_x);
balloon_formation_[j].init[i].y = y2; balloon_formation_[j].init[i].y = y2;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_2; balloon_formation_[j].init[i].size = BalloonSize::SIZE2;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #14 - Cinco enemigos BALLOON3. Hacia la derecha. Separados // #14 - Cinco enemigos BALLOON3. Hacia la derecha. Separados
j = 14; j = 14;
balloon_formation_[j].number_of_balloons = 5; balloon_formation_[j].number_of_balloons = 5;
inc_x = BALLOON_WIDTH_3 * 2; inc_x = BALLOON_SIZE[2] * 2;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x3_0 + (i * inc_x); balloon_formation_[j].init[i].x = x3_0 + (i * inc_x);
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].size = BalloonSize::SIZE3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #15 - Cinco enemigos BALLOON3. Hacia la izquierda. Separados // #15 - Cinco enemigos BALLOON3. Hacia la izquierda. Separados
j = 15; j = 15;
balloon_formation_[j].number_of_balloons = 5; balloon_formation_[j].number_of_balloons = 5;
inc_x = BALLOON_WIDTH_3 * 2; inc_x = BALLOON_SIZE[2] * 2;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x3_100 - (i * inc_x); balloon_formation_[j].init[i].x = x3_100 - (i * inc_x);
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].size = BalloonSize::SIZE3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #16 - Cinco enemigos BALLOON3. Hacia la derecha. Juntos // #16 - Cinco enemigos BALLOON3. Hacia la derecha. Juntos
j = 16; j = 16;
balloon_formation_[j].number_of_balloons = 5; balloon_formation_[j].number_of_balloons = 5;
inc_x = BALLOON_WIDTH_3 + 1; inc_x = BALLOON_SIZE[2] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x3_0 + (i * inc_x); balloon_formation_[j].init[i].x = x3_0 + (i * inc_x);
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].size = BalloonSize::SIZE3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #17 - Cinco enemigos BALLOON3. Hacia la izquierda. Juntos // #17 - Cinco enemigos BALLOON3. Hacia la izquierda. Juntos
j = 17; j = 17;
balloon_formation_[j].number_of_balloons = 5; balloon_formation_[j].number_of_balloons = 5;
inc_x = BALLOON_WIDTH_3 + 1; inc_x = BALLOON_SIZE[2] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x3_100 - (i * inc_x); balloon_formation_[j].init[i].x = x3_100 - (i * inc_x);
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].size = BalloonSize::SIZE3;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #18 - Doce enemigos BALLOON1. Hacia la derecha. Juntos // #18 - Doce enemigos BALLOON1. Hacia la derecha. Juntos
j = 18; j = 18;
balloon_formation_[j].number_of_balloons = 12; balloon_formation_[j].number_of_balloons = 12;
inc_x = BALLOON_WIDTH_1 + 1; inc_x = BALLOON_SIZE[0] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x1_0 + (i * inc_x); balloon_formation_[j].init[i].x = x1_0 + (i * inc_x);
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].size = BalloonSize::SIZE1;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #19 - Doce enemigos BALLOON1. Hacia la izquierda. Juntos // #19 - Doce enemigos BALLOON1. Hacia la izquierda. Juntos
j = 19; j = 19;
balloon_formation_[j].number_of_balloons = 12; balloon_formation_[j].number_of_balloons = 12;
inc_x = BALLOON_WIDTH_1 + 1; inc_x = BALLOON_SIZE[0] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
balloon_formation_[j].init[i].x = x1_100 - (i * inc_x); balloon_formation_[j].init[i].x = x1_100 - (i * inc_x);
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].size = BalloonSize::SIZE1;
balloon_formation_[j].init[i].creation_counter = creation_time - (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME - (inc_time * i);
} }
// #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simetricos // #20 - Dos enemigos BALLOON4 seguidos desde la izquierda/derecha. Simetricos
j = 20; j = 20;
balloon_formation_[j].number_of_balloons = 4; balloon_formation_[j].number_of_balloons = 4;
inc_x = BALLOON_WIDTH_4 + 1; inc_x = BALLOON_SIZE[3] + 1;
inc_time = 0; inc_time = 0;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
@@ -349,14 +345,14 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
} }
balloon_formation_[j].init[i].y = y4; balloon_formation_[j].init[i].y = y4;
balloon_formation_[j].init[i].kind = BALLOON_4; balloon_formation_[j].init[i].size = BalloonSize::SIZE4;
balloon_formation_[j].init[i].creation_counter = creation_time + (inc_time * i); balloon_formation_[j].init[i].creation_counter = CREATION_TIME + (inc_time * i);
} }
// #21 - Diez enemigos BALLOON2 uno detras del otro. Izquierda/derecha. Simetricos // #21 - Diez enemigos BALLOON2 uno detras del otro. Izquierda/derecha. Simetricos
j = 21; j = 21;
balloon_formation_[j].number_of_balloons = 10; balloon_formation_[j].number_of_balloons = 10;
inc_x = BALLOON_WIDTH_2 + 1; inc_x = BALLOON_SIZE[1] + 1;
inc_time = 3; inc_time = 3;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
@@ -365,22 +361,22 @@ void BalloonFormations::initBalloonFormations()
{ {
balloon_formation_[j].init[i].x = x2_0 + (i * inc_x); balloon_formation_[j].init[i].x = x2_0 + (i * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * i); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * i);
} }
else else
{ {
balloon_formation_[j].init[i].x = x2_100 - ((i - half) * inc_x); balloon_formation_[j].init[i].x = x2_100 - ((i - half) * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * (i - half)); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * (i - half));
} }
balloon_formation_[j].init[i].y = y2; balloon_formation_[j].init[i].y = y2;
balloon_formation_[j].init[i].kind = BALLOON_2; balloon_formation_[j].init[i].size = BalloonSize::SIZE2;
} }
// #22 - Diez enemigos BALLOON3. Hacia la derecha/izquierda. Separados. Simetricos // #22 - Diez enemigos BALLOON3. Hacia la derecha/izquierda. Separados. Simetricos
j = 22; j = 22;
balloon_formation_[j].number_of_balloons = 10; balloon_formation_[j].number_of_balloons = 10;
inc_x = BALLOON_WIDTH_3 * 2; inc_x = BALLOON_SIZE[2] * 2;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
@@ -389,22 +385,22 @@ void BalloonFormations::initBalloonFormations()
{ {
balloon_formation_[j].init[i].x = x3_0 + (i * inc_x); balloon_formation_[j].init[i].x = x3_0 + (i * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * i); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * i);
} }
else else
{ {
balloon_formation_[j].init[i].x = x3_100 - ((i - half) * inc_x); balloon_formation_[j].init[i].x = x3_100 - ((i - half) * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * (i - half)); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * (i - half));
} }
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].size = BalloonSize::SIZE3;
} }
// #23 - Diez enemigos BALLOON3. Hacia la derecha. Juntos. Simetricos // #23 - Diez enemigos BALLOON3. Hacia la derecha. Juntos. Simetricos
j = 23; j = 23;
balloon_formation_[j].number_of_balloons = 10; balloon_formation_[j].number_of_balloons = 10;
inc_x = BALLOON_WIDTH_3 + 1; inc_x = BALLOON_SIZE[2] + 1;
inc_time = 10; inc_time = 10;
for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++) for (int i = 0; i < balloon_formation_[j].number_of_balloons; i++)
{ {
@@ -413,16 +409,16 @@ void BalloonFormations::initBalloonFormations()
{ {
balloon_formation_[j].init[i].x = x3_0 + (i * inc_x); balloon_formation_[j].init[i].x = x3_0 + (i * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * i); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * i);
} }
else else
{ {
balloon_formation_[j].init[i].x = x3_100 - ((i - half) * inc_x); balloon_formation_[j].init[i].x = x3_100 - ((i - half) * inc_x);
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * (i - half)); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * (i - half));
} }
balloon_formation_[j].init[i].y = y3; balloon_formation_[j].init[i].y = y3;
balloon_formation_[j].init[i].kind = BALLOON_3; balloon_formation_[j].init[i].size = BalloonSize::SIZE3;
} }
// #24 - Treinta enemigos BALLOON1. Del centro hacia los extremos. Juntos. Simetricos // #24 - Treinta enemigos BALLOON1. Del centro hacia los extremos. Juntos. Simetricos
@@ -436,16 +432,16 @@ void BalloonFormations::initBalloonFormations()
{ {
balloon_formation_[j].init[i].x = x1_50; balloon_formation_[j].init[i].x = x1_50;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) + (inc_time * i); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) + (inc_time * i);
} }
else else
{ {
balloon_formation_[j].init[i].x = x1_50; balloon_formation_[j].init[i].x = x1_50;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) + (inc_time * (i - half)); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) + (inc_time * (i - half));
} }
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].size = BalloonSize::SIZE1;
} }
// #25 - Treinta enemigos BALLOON1. Del centro hacia adentro. Juntos. Simetricos // #25 - Treinta enemigos BALLOON1. Del centro hacia adentro. Juntos. Simetricos
@@ -459,16 +455,16 @@ void BalloonFormations::initBalloonFormations()
{ {
balloon_formation_[j].init[i].x = x1_50 + 20; balloon_formation_[j].init[i].x = x1_50 + 20;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_NEGATIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * i); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * i);
} }
else else
{ {
balloon_formation_[j].init[i].x = x1_50 - 20; balloon_formation_[j].init[i].x = x1_50 - 20;
balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE; balloon_formation_[j].init[i].vel_x = BALLOON_VELX_POSITIVE;
balloon_formation_[j].init[i].creation_counter = (creation_time) - (inc_time * (i - half)); balloon_formation_[j].init[i].creation_counter = (CREATION_TIME) - (inc_time * (i - half));
} }
balloon_formation_[j].init[i].y = y1; balloon_formation_[j].init[i].y = y1;
balloon_formation_[j].init[i].kind = BALLOON_1; balloon_formation_[j].init[i].size = BalloonSize::SIZE1;
} }
// Crea las mismas formaciones pero con hexagonos a partir de la posición 50 del vector // Crea las mismas formaciones pero con hexagonos a partir de la posición 50 del vector
@@ -481,7 +477,8 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[k + 50].init[i].y = balloon_formation_[k].init[i].y; balloon_formation_[k + 50].init[i].y = balloon_formation_[k].init[i].y;
balloon_formation_[k + 50].init[i].vel_x = balloon_formation_[k].init[i].vel_x; balloon_formation_[k + 50].init[i].vel_x = balloon_formation_[k].init[i].vel_x;
balloon_formation_[k + 50].init[i].creation_counter = balloon_formation_[k].init[i].creation_counter; balloon_formation_[k + 50].init[i].creation_counter = balloon_formation_[k].init[i].creation_counter;
balloon_formation_[k + 50].init[i].kind = balloon_formation_[k].init[i].kind + 4; balloon_formation_[k + 50].init[i].size = balloon_formation_[k].init[i].size;
balloon_formation_[k + 50].init[i].type = BalloonType::FLOATER;
} }
} }
@@ -491,25 +488,25 @@ void BalloonFormations::initBalloonFormations()
balloon_formation_[99].init[0].x = 10; balloon_formation_[99].init[0].x = 10;
balloon_formation_[99].init[0].y = y1; balloon_formation_[99].init[0].y = y1;
balloon_formation_[99].init[0].vel_x = 0; balloon_formation_[99].init[0].vel_x = 0;
balloon_formation_[99].init[0].kind = BALLOON_1; balloon_formation_[99].init[0].size = BalloonSize::SIZE1;
balloon_formation_[99].init[0].creation_counter = 200; balloon_formation_[99].init[0].creation_counter = 200;
balloon_formation_[99].init[1].x = 50; balloon_formation_[99].init[1].x = 50;
balloon_formation_[99].init[1].y = y1; balloon_formation_[99].init[1].y = y1;
balloon_formation_[99].init[1].vel_x = 0; balloon_formation_[99].init[1].vel_x = 0;
balloon_formation_[99].init[1].kind = BALLOON_2; balloon_formation_[99].init[1].size = BalloonSize::SIZE2;
balloon_formation_[99].init[1].creation_counter = 200; balloon_formation_[99].init[1].creation_counter = 200;
balloon_formation_[99].init[2].x = 90; balloon_formation_[99].init[2].x = 90;
balloon_formation_[99].init[2].y = y1; balloon_formation_[99].init[2].y = y1;
balloon_formation_[99].init[2].vel_x = 0; balloon_formation_[99].init[2].vel_x = 0;
balloon_formation_[99].init[2].kind = BALLOON_3; balloon_formation_[99].init[2].size = BalloonSize::SIZE3;
balloon_formation_[99].init[2].creation_counter = 200; balloon_formation_[99].init[2].creation_counter = 200;
balloon_formation_[99].init[3].x = 140; balloon_formation_[99].init[3].x = 140;
balloon_formation_[99].init[3].y = y1; balloon_formation_[99].init[3].y = y1;
balloon_formation_[99].init[3].vel_x = 0; balloon_formation_[99].init[3].vel_x = 0;
balloon_formation_[99].init[3].kind = BALLOON_4; balloon_formation_[99].init[3].size = BalloonSize::SIZE4;
balloon_formation_[99].init[3].creation_counter = 200; balloon_formation_[99].init[3].creation_counter = 200;
} }
@@ -517,124 +514,124 @@ void BalloonFormations::initBalloonFormations()
void BalloonFormations::initBalloonFormationPools() void BalloonFormations::initBalloonFormationPools()
{ {
// EnemyPool #0 // EnemyPool #0
balloon_formation_pool_[0].set[0] = &balloon_formation_[0]; balloon_formation_pool_[0].set[0] = balloon_formation_[0];
balloon_formation_pool_[0].set[1] = &balloon_formation_[1]; balloon_formation_pool_[0].set[1] = balloon_formation_[1];
balloon_formation_pool_[0].set[2] = &balloon_formation_[2]; balloon_formation_pool_[0].set[2] = balloon_formation_[2];
balloon_formation_pool_[0].set[3] = &balloon_formation_[3]; balloon_formation_pool_[0].set[3] = balloon_formation_[3];
balloon_formation_pool_[0].set[4] = &balloon_formation_[4]; balloon_formation_pool_[0].set[4] = balloon_formation_[4];
balloon_formation_pool_[0].set[5] = &balloon_formation_[5]; balloon_formation_pool_[0].set[5] = balloon_formation_[5];
balloon_formation_pool_[0].set[6] = &balloon_formation_[6]; balloon_formation_pool_[0].set[6] = balloon_formation_[6];
balloon_formation_pool_[0].set[7] = &balloon_formation_[7]; balloon_formation_pool_[0].set[7] = balloon_formation_[7];
balloon_formation_pool_[0].set[8] = &balloon_formation_[8]; balloon_formation_pool_[0].set[8] = balloon_formation_[8];
balloon_formation_pool_[0].set[9] = &balloon_formation_[9]; balloon_formation_pool_[0].set[9] = balloon_formation_[9];
// EnemyPool #1 // EnemyPool #1
balloon_formation_pool_[1].set[0] = &balloon_formation_[10]; balloon_formation_pool_[1].set[0] = balloon_formation_[10];
balloon_formation_pool_[1].set[1] = &balloon_formation_[11]; balloon_formation_pool_[1].set[1] = balloon_formation_[11];
balloon_formation_pool_[1].set[2] = &balloon_formation_[12]; balloon_formation_pool_[1].set[2] = balloon_formation_[12];
balloon_formation_pool_[1].set[3] = &balloon_formation_[13]; balloon_formation_pool_[1].set[3] = balloon_formation_[13];
balloon_formation_pool_[1].set[4] = &balloon_formation_[14]; balloon_formation_pool_[1].set[4] = balloon_formation_[14];
balloon_formation_pool_[1].set[5] = &balloon_formation_[15]; balloon_formation_pool_[1].set[5] = balloon_formation_[15];
balloon_formation_pool_[1].set[6] = &balloon_formation_[16]; balloon_formation_pool_[1].set[6] = balloon_formation_[16];
balloon_formation_pool_[1].set[7] = &balloon_formation_[17]; balloon_formation_pool_[1].set[7] = balloon_formation_[17];
balloon_formation_pool_[1].set[8] = &balloon_formation_[18]; balloon_formation_pool_[1].set[8] = balloon_formation_[18];
balloon_formation_pool_[1].set[9] = &balloon_formation_[19]; balloon_formation_pool_[1].set[9] = balloon_formation_[19];
// EnemyPool #2 // EnemyPool #2
balloon_formation_pool_[2].set[0] = &balloon_formation_[0]; balloon_formation_pool_[2].set[0] = balloon_formation_[0];
balloon_formation_pool_[2].set[1] = &balloon_formation_[1]; balloon_formation_pool_[2].set[1] = balloon_formation_[1];
balloon_formation_pool_[2].set[2] = &balloon_formation_[2]; balloon_formation_pool_[2].set[2] = balloon_formation_[2];
balloon_formation_pool_[2].set[3] = &balloon_formation_[3]; balloon_formation_pool_[2].set[3] = balloon_formation_[3];
balloon_formation_pool_[2].set[4] = &balloon_formation_[4]; balloon_formation_pool_[2].set[4] = balloon_formation_[4];
balloon_formation_pool_[2].set[5] = &balloon_formation_[55]; balloon_formation_pool_[2].set[5] = balloon_formation_[55];
balloon_formation_pool_[2].set[6] = &balloon_formation_[56]; balloon_formation_pool_[2].set[6] = balloon_formation_[56];
balloon_formation_pool_[2].set[7] = &balloon_formation_[57]; balloon_formation_pool_[2].set[7] = balloon_formation_[57];
balloon_formation_pool_[2].set[8] = &balloon_formation_[58]; balloon_formation_pool_[2].set[8] = balloon_formation_[58];
balloon_formation_pool_[2].set[9] = &balloon_formation_[59]; balloon_formation_pool_[2].set[9] = balloon_formation_[59];
// EnemyPool #3 // EnemyPool #3
balloon_formation_pool_[3].set[0] = &balloon_formation_[50]; balloon_formation_pool_[3].set[0] = balloon_formation_[50];
balloon_formation_pool_[3].set[1] = &balloon_formation_[51]; balloon_formation_pool_[3].set[1] = balloon_formation_[51];
balloon_formation_pool_[3].set[2] = &balloon_formation_[52]; balloon_formation_pool_[3].set[2] = balloon_formation_[52];
balloon_formation_pool_[3].set[3] = &balloon_formation_[53]; balloon_formation_pool_[3].set[3] = balloon_formation_[53];
balloon_formation_pool_[3].set[4] = &balloon_formation_[54]; balloon_formation_pool_[3].set[4] = balloon_formation_[54];
balloon_formation_pool_[3].set[5] = &balloon_formation_[5]; balloon_formation_pool_[3].set[5] = balloon_formation_[5];
balloon_formation_pool_[3].set[6] = &balloon_formation_[6]; balloon_formation_pool_[3].set[6] = balloon_formation_[6];
balloon_formation_pool_[3].set[7] = &balloon_formation_[7]; balloon_formation_pool_[3].set[7] = balloon_formation_[7];
balloon_formation_pool_[3].set[8] = &balloon_formation_[8]; balloon_formation_pool_[3].set[8] = balloon_formation_[8];
balloon_formation_pool_[3].set[9] = &balloon_formation_[9]; balloon_formation_pool_[3].set[9] = balloon_formation_[9];
// EnemyPool #4 // EnemyPool #4
balloon_formation_pool_[4].set[0] = &balloon_formation_[60]; balloon_formation_pool_[4].set[0] = balloon_formation_[60];
balloon_formation_pool_[4].set[1] = &balloon_formation_[61]; balloon_formation_pool_[4].set[1] = balloon_formation_[61];
balloon_formation_pool_[4].set[2] = &balloon_formation_[62]; balloon_formation_pool_[4].set[2] = balloon_formation_[62];
balloon_formation_pool_[4].set[3] = &balloon_formation_[63]; balloon_formation_pool_[4].set[3] = balloon_formation_[63];
balloon_formation_pool_[4].set[4] = &balloon_formation_[64]; balloon_formation_pool_[4].set[4] = balloon_formation_[64];
balloon_formation_pool_[4].set[5] = &balloon_formation_[65]; balloon_formation_pool_[4].set[5] = balloon_formation_[65];
balloon_formation_pool_[4].set[6] = &balloon_formation_[66]; balloon_formation_pool_[4].set[6] = balloon_formation_[66];
balloon_formation_pool_[4].set[7] = &balloon_formation_[67]; balloon_formation_pool_[4].set[7] = balloon_formation_[67];
balloon_formation_pool_[4].set[8] = &balloon_formation_[68]; balloon_formation_pool_[4].set[8] = balloon_formation_[68];
balloon_formation_pool_[4].set[9] = &balloon_formation_[69]; balloon_formation_pool_[4].set[9] = balloon_formation_[69];
// EnemyPool #5 // EnemyPool #5
balloon_formation_pool_[5].set[0] = &balloon_formation_[10]; balloon_formation_pool_[5].set[0] = balloon_formation_[10];
balloon_formation_pool_[5].set[1] = &balloon_formation_[61]; balloon_formation_pool_[5].set[1] = balloon_formation_[61];
balloon_formation_pool_[5].set[2] = &balloon_formation_[12]; balloon_formation_pool_[5].set[2] = balloon_formation_[12];
balloon_formation_pool_[5].set[3] = &balloon_formation_[63]; balloon_formation_pool_[5].set[3] = balloon_formation_[63];
balloon_formation_pool_[5].set[4] = &balloon_formation_[14]; balloon_formation_pool_[5].set[4] = balloon_formation_[14];
balloon_formation_pool_[5].set[5] = &balloon_formation_[65]; balloon_formation_pool_[5].set[5] = balloon_formation_[65];
balloon_formation_pool_[5].set[6] = &balloon_formation_[16]; balloon_formation_pool_[5].set[6] = balloon_formation_[16];
balloon_formation_pool_[5].set[7] = &balloon_formation_[67]; balloon_formation_pool_[5].set[7] = balloon_formation_[67];
balloon_formation_pool_[5].set[8] = &balloon_formation_[18]; balloon_formation_pool_[5].set[8] = balloon_formation_[18];
balloon_formation_pool_[5].set[9] = &balloon_formation_[69]; balloon_formation_pool_[5].set[9] = balloon_formation_[69];
// EnemyPool #6 // EnemyPool #6
balloon_formation_pool_[6].set[0] = &balloon_formation_[60]; balloon_formation_pool_[6].set[0] = balloon_formation_[60];
balloon_formation_pool_[6].set[1] = &balloon_formation_[11]; balloon_formation_pool_[6].set[1] = balloon_formation_[11];
balloon_formation_pool_[6].set[2] = &balloon_formation_[62]; balloon_formation_pool_[6].set[2] = balloon_formation_[62];
balloon_formation_pool_[6].set[3] = &balloon_formation_[13]; balloon_formation_pool_[6].set[3] = balloon_formation_[13];
balloon_formation_pool_[6].set[4] = &balloon_formation_[64]; balloon_formation_pool_[6].set[4] = balloon_formation_[64];
balloon_formation_pool_[6].set[5] = &balloon_formation_[15]; balloon_formation_pool_[6].set[5] = balloon_formation_[15];
balloon_formation_pool_[6].set[6] = &balloon_formation_[66]; balloon_formation_pool_[6].set[6] = balloon_formation_[66];
balloon_formation_pool_[6].set[7] = &balloon_formation_[17]; balloon_formation_pool_[6].set[7] = balloon_formation_[17];
balloon_formation_pool_[6].set[8] = &balloon_formation_[68]; balloon_formation_pool_[6].set[8] = balloon_formation_[68];
balloon_formation_pool_[6].set[9] = &balloon_formation_[19]; balloon_formation_pool_[6].set[9] = balloon_formation_[19];
// EnemyPool #7 // EnemyPool #7
balloon_formation_pool_[7].set[0] = &balloon_formation_[20]; balloon_formation_pool_[7].set[0] = balloon_formation_[20];
balloon_formation_pool_[7].set[1] = &balloon_formation_[21]; balloon_formation_pool_[7].set[1] = balloon_formation_[21];
balloon_formation_pool_[7].set[2] = &balloon_formation_[22]; balloon_formation_pool_[7].set[2] = balloon_formation_[22];
balloon_formation_pool_[7].set[3] = &balloon_formation_[23]; balloon_formation_pool_[7].set[3] = balloon_formation_[23];
balloon_formation_pool_[7].set[4] = &balloon_formation_[24]; balloon_formation_pool_[7].set[4] = balloon_formation_[24];
balloon_formation_pool_[7].set[5] = &balloon_formation_[65]; balloon_formation_pool_[7].set[5] = balloon_formation_[65];
balloon_formation_pool_[7].set[6] = &balloon_formation_[66]; balloon_formation_pool_[7].set[6] = balloon_formation_[66];
balloon_formation_pool_[7].set[7] = &balloon_formation_[67]; balloon_formation_pool_[7].set[7] = balloon_formation_[67];
balloon_formation_pool_[7].set[8] = &balloon_formation_[68]; balloon_formation_pool_[7].set[8] = balloon_formation_[68];
balloon_formation_pool_[7].set[9] = &balloon_formation_[69]; balloon_formation_pool_[7].set[9] = balloon_formation_[69];
// EnemyPool #8 // EnemyPool #8
balloon_formation_pool_[8].set[0] = &balloon_formation_[70]; balloon_formation_pool_[8].set[0] = balloon_formation_[70];
balloon_formation_pool_[8].set[1] = &balloon_formation_[71]; balloon_formation_pool_[8].set[1] = balloon_formation_[71];
balloon_formation_pool_[8].set[2] = &balloon_formation_[72]; balloon_formation_pool_[8].set[2] = balloon_formation_[72];
balloon_formation_pool_[8].set[3] = &balloon_formation_[73]; balloon_formation_pool_[8].set[3] = balloon_formation_[73];
balloon_formation_pool_[8].set[4] = &balloon_formation_[74]; balloon_formation_pool_[8].set[4] = balloon_formation_[74];
balloon_formation_pool_[8].set[5] = &balloon_formation_[15]; balloon_formation_pool_[8].set[5] = balloon_formation_[15];
balloon_formation_pool_[8].set[6] = &balloon_formation_[16]; balloon_formation_pool_[8].set[6] = balloon_formation_[16];
balloon_formation_pool_[8].set[7] = &balloon_formation_[17]; balloon_formation_pool_[8].set[7] = balloon_formation_[17];
balloon_formation_pool_[8].set[8] = &balloon_formation_[18]; balloon_formation_pool_[8].set[8] = balloon_formation_[18];
balloon_formation_pool_[8].set[9] = &balloon_formation_[19]; balloon_formation_pool_[8].set[9] = balloon_formation_[19];
// EnemyPool #9 // EnemyPool #9
balloon_formation_pool_[9].set[0] = &balloon_formation_[20]; balloon_formation_pool_[9].set[0] = balloon_formation_[20];
balloon_formation_pool_[9].set[1] = &balloon_formation_[21]; balloon_formation_pool_[9].set[1] = balloon_formation_[21];
balloon_formation_pool_[9].set[2] = &balloon_formation_[22]; balloon_formation_pool_[9].set[2] = balloon_formation_[22];
balloon_formation_pool_[9].set[3] = &balloon_formation_[23]; balloon_formation_pool_[9].set[3] = balloon_formation_[23];
balloon_formation_pool_[9].set[4] = &balloon_formation_[24]; balloon_formation_pool_[9].set[4] = balloon_formation_[24];
balloon_formation_pool_[9].set[5] = &balloon_formation_[70]; balloon_formation_pool_[9].set[5] = balloon_formation_[70];
balloon_formation_pool_[9].set[6] = &balloon_formation_[71]; balloon_formation_pool_[9].set[6] = balloon_formation_[71];
balloon_formation_pool_[9].set[7] = &balloon_formation_[72]; balloon_formation_pool_[9].set[7] = balloon_formation_[72];
balloon_formation_pool_[9].set[8] = &balloon_formation_[73]; balloon_formation_pool_[9].set[8] = balloon_formation_[73];
balloon_formation_pool_[9].set[9] = &balloon_formation_[74]; balloon_formation_pool_[9].set[9] = balloon_formation_[74];
} }
// Inicializa las fases del juego // Inicializa las fases del juego
@@ -645,70 +642,70 @@ void BalloonFormations::initGameStages()
stage_[0].power_to_complete = 200; stage_[0].power_to_complete = 200;
stage_[0].min_menace = 7 + (4 * 1); stage_[0].min_menace = 7 + (4 * 1);
stage_[0].max_menace = 7 + (4 * 3); stage_[0].max_menace = 7 + (4 * 3);
stage_[0].balloon_pool = &balloon_formation_pool_[0]; stage_[0].balloon_pool = balloon_formation_pool_[0];
// STAGE 2 // STAGE 2
stage_[1].number = 2; stage_[1].number = 2;
stage_[1].power_to_complete = 300; stage_[1].power_to_complete = 300;
stage_[1].min_menace = 7 + (4 * 2); stage_[1].min_menace = 7 + (4 * 2);
stage_[1].max_menace = 7 + (4 * 4); stage_[1].max_menace = 7 + (4 * 4);
stage_[1].balloon_pool = &balloon_formation_pool_[1]; stage_[1].balloon_pool = balloon_formation_pool_[1];
// STAGE 3 // STAGE 3
stage_[2].number = 3; stage_[2].number = 3;
stage_[2].power_to_complete = 600; stage_[2].power_to_complete = 600;
stage_[2].min_menace = 7 + (4 * 3); stage_[2].min_menace = 7 + (4 * 3);
stage_[2].max_menace = 7 + (4 * 5); stage_[2].max_menace = 7 + (4 * 5);
stage_[2].balloon_pool = &balloon_formation_pool_[2]; stage_[2].balloon_pool = balloon_formation_pool_[2];
// STAGE 4 // STAGE 4
stage_[3].number = 4; stage_[3].number = 4;
stage_[3].power_to_complete = 600; stage_[3].power_to_complete = 600;
stage_[3].min_menace = 7 + (4 * 3); stage_[3].min_menace = 7 + (4 * 3);
stage_[3].max_menace = 7 + (4 * 5); stage_[3].max_menace = 7 + (4 * 5);
stage_[3].balloon_pool = &balloon_formation_pool_[3]; stage_[3].balloon_pool = balloon_formation_pool_[3];
// STAGE 5 // STAGE 5
stage_[4].number = 5; stage_[4].number = 5;
stage_[4].power_to_complete = 600; stage_[4].power_to_complete = 600;
stage_[4].min_menace = 7 + (4 * 4); stage_[4].min_menace = 7 + (4 * 4);
stage_[4].max_menace = 7 + (4 * 6); stage_[4].max_menace = 7 + (4 * 6);
stage_[4].balloon_pool = &balloon_formation_pool_[4]; stage_[4].balloon_pool = balloon_formation_pool_[4];
// STAGE 6 // STAGE 6
stage_[5].number = 6; stage_[5].number = 6;
stage_[5].power_to_complete = 600; stage_[5].power_to_complete = 600;
stage_[5].min_menace = 7 + (4 * 4); stage_[5].min_menace = 7 + (4 * 4);
stage_[5].max_menace = 7 + (4 * 6); stage_[5].max_menace = 7 + (4 * 6);
stage_[5].balloon_pool = &balloon_formation_pool_[5]; stage_[5].balloon_pool = balloon_formation_pool_[5];
// STAGE 7 // STAGE 7
stage_[6].number = 7; stage_[6].number = 7;
stage_[6].power_to_complete = 650; stage_[6].power_to_complete = 650;
stage_[6].min_menace = 7 + (4 * 5); stage_[6].min_menace = 7 + (4 * 5);
stage_[6].max_menace = 7 + (4 * 7); stage_[6].max_menace = 7 + (4 * 7);
stage_[6].balloon_pool = &balloon_formation_pool_[6]; stage_[6].balloon_pool = balloon_formation_pool_[6];
// STAGE 8 // STAGE 8
stage_[7].number = 8; stage_[7].number = 8;
stage_[7].power_to_complete = 750; stage_[7].power_to_complete = 750;
stage_[7].min_menace = 7 + (4 * 5); stage_[7].min_menace = 7 + (4 * 5);
stage_[7].max_menace = 7 + (4 * 7); stage_[7].max_menace = 7 + (4 * 7);
stage_[7].balloon_pool = &balloon_formation_pool_[7]; stage_[7].balloon_pool = balloon_formation_pool_[7];
// STAGE 9 // STAGE 9
stage_[8].number = 9; stage_[8].number = 9;
stage_[8].power_to_complete = 850; stage_[8].power_to_complete = 850;
stage_[8].min_menace = 7 + (4 * 6); stage_[8].min_menace = 7 + (4 * 6);
stage_[8].max_menace = 7 + (4 * 8); stage_[8].max_menace = 7 + (4 * 8);
stage_[8].balloon_pool = &balloon_formation_pool_[8]; stage_[8].balloon_pool = balloon_formation_pool_[8];
// STAGE 10 // STAGE 10
stage_[9].number = 10; stage_[9].number = 10;
stage_[9].power_to_complete = 950; stage_[9].power_to_complete = 950;
stage_[9].min_menace = 7 + (4 * 7); stage_[9].min_menace = 7 + (4 * 7);
stage_[9].max_menace = 7 + (4 * 10); stage_[9].max_menace = 7 + (4 * 10);
stage_[9].balloon_pool = &balloon_formation_pool_[9]; stage_[9].balloon_pool = balloon_formation_pool_[9];
} }
// Devuelve una fase // Devuelve una fase

View File

@@ -1,36 +1,48 @@
#pragma once #pragma once
#include "balloon.h"
constexpr int NUMBER_OF_BALLOON_FORMATIONS = 100; constexpr int NUMBER_OF_BALLOON_FORMATIONS = 100;
constexpr int MAX_NUMBER_OF_BALLOONS_IN_A_FORMATION = 50; constexpr int MAX_NUMBER_OF_BALLOONS_IN_A_FORMATION = 50;
constexpr int NUMBER_OF_SETS_PER_POOL = 10;
constexpr int NUMBER_OF_STAGES = 10;
// Estructuras // Estructuras
struct BalloonFormationParams struct BalloonFormationParams
{ {
int x; // Posición en el eje X donde crear al enemigo int x = 0; // Posición en el eje X donde crear el globo
int y; // Posición en el eje Y donde crear al enemigo int y = 0; // Posición en el eje Y donde crear el globo
float vel_x; // Velocidad inicial en el eje X float vel_x = 0.0f; // Velocidad inicial en el eje X
int kind; // Tipo de enemigo BalloonType type = BalloonType::BALLOON; // Tipo de globo
int creation_counter; // Temporizador para la creación del enemigo BalloonSize size = BalloonSize::SIZE1; // Tamaño de globo
int creation_counter = 0; // Temporizador para la creación del globo
// Constructor por defecto
BalloonFormationParams() = default;
// Constructor con parámetros
BalloonFormationParams(int x_val, int y_val, float vel_x_val, BalloonType type_val, BalloonSize size_val, int creation_counter_val)
: x(x_val), y(y_val), vel_x(vel_x_val), type(type_val), size(size_val), creation_counter(creation_counter_val) {}
}; };
struct BalloonFormationUnit // Contiene la información de una formación enemiga struct BalloonFormationUnit // Contiene la información de una formación enemiga
{ {
int number_of_balloons; // Cantidad de enemigos que forman la formación int number_of_balloons; // Cantidad de globos que forman la formación
BalloonFormationParams init[MAX_NUMBER_OF_BALLOONS_IN_A_FORMATION]; // Vector con todas las inicializaciones de los enemigos de la formación BalloonFormationParams init[MAX_NUMBER_OF_BALLOONS_IN_A_FORMATION]; // Vector con todas las inicializaciones de los globos de la formación
}; };
struct BalloonFormationPool struct BalloonFormationPool
{ {
BalloonFormationUnit *set[10]; // Conjunto de formaciones de globos BalloonFormationUnit set[NUMBER_OF_SETS_PER_POOL]; // Conjunto de formaciones de globos
}; };
struct Stage // Contiene todas las variables relacionadas con una fase struct Stage // Contiene todas las variables relacionadas con una fase
{ {
BalloonFormationPool *balloon_pool; // El conjunto de formaciones de globos de la fase BalloonFormationPool balloon_pool; // El conjunto de formaciones de globos de la fase
int power_to_complete; // Cantidad de poder que se necesita para completar la fase int power_to_complete; // Cantidad de poder que se necesita para completar la fase
int max_menace; // Umbral máximo de amenaza de la fase int max_menace; // Umbral máximo de amenaza de la fase
int min_menace; // Umbral mínimo de amenaza de la fase int min_menace; // Umbral mínimo de amenaza de la fase
int number; // Número de fase int number; // Número de fase
}; };
// Clase BalloonFormations, para gestionar las formaciones de globos // Clase BalloonFormations, para gestionar las formaciones de globos
@@ -38,9 +50,9 @@ class BalloonFormations
{ {
private: private:
// Variables // Variables
Stage stage_[10]; // Variable con los datos de cada pantalla Stage stage_[NUMBER_OF_STAGES]; // Variable con los datos de cada pantalla
BalloonFormationUnit balloon_formation_[NUMBER_OF_BALLOON_FORMATIONS]; // Vector con todas las formaciones enemigas BalloonFormationUnit balloon_formation_[NUMBER_OF_BALLOON_FORMATIONS]; // Vector con todas las formaciones enemigas
BalloonFormationPool balloon_formation_pool_[10]; // Variable con los diferentes conjuntos de formaciones enemigas BalloonFormationPool balloon_formation_pool_[NUMBER_OF_STAGES]; // Variable con los diferentes conjuntos de formaciones enemigas
// Inicializa las formaciones enemigas // Inicializa las formaciones enemigas
void initBalloonFormations(); void initBalloonFormations();

View File

@@ -1,36 +1,27 @@
#include "bullet.h" #include "bullet.h"
#include <memory> // for unique_ptr, make_unique, shared_ptr #include <SDL2/SDL_rect.h> // Para SDL_Rect
#include "param.h" // for param #include <memory> // Para unique_ptr, make_unique, shared_ptr
#include "sprite.h" // for Sprite #include "param.h" // Para Param, ParamGame, param
class Texture; #include "sprite.h" // Para Sprite
class Texture; // lines 5-5
constexpr int BULLET_WIDTH = 12;
constexpr int BULLET_HEIGHT = 12;
constexpr int BULLET_VELY = -3;
constexpr int BULLET_VELX_LEFT = -2;
constexpr int BULLET_VELX_RIGHT = 2;
// Constructor // Constructor
Bullet::Bullet(int x, int y, BulletType kind, bool powered_up, int owner, SDL_Rect *play_area, std::shared_ptr<Texture> texture) Bullet::Bullet(int x, int y, BulletType bullet_type, bool powered_up, int owner, std::shared_ptr<Texture> texture)
: sprite_(std::make_unique<Sprite>(texture, SDL_Rect{x, y, BULLET_WIDTH, BULLET_HEIGHT})), : sprite_(std::make_unique<Sprite>(texture, SDL_Rect{x, y, BULLET_WIDTH_, BULLET_HEIGHT_})),
pos_x_(x), pos_x_(x),
pos_y_(y), pos_y_(y),
width_(BULLET_WIDTH), bullet_type_(bullet_type),
height_(BULLET_HEIGHT), owner_(owner)
vel_x_(0),
vel_y_(BULLET_VELY),
kind_(kind),
owner_(owner),
play_area_(play_area)
{ {
vel_x_ = (kind_ == BulletType::LEFT) ? BULLET_VELX_LEFT : (kind_ == BulletType::RIGHT) ? BULLET_VELX_RIGHT vel_x_ = (bullet_type_ == BulletType::LEFT) ? BULLET_VEL_X_LEFT_
: 0; : (bullet_type_ == BulletType::RIGHT) ? BULLET_VEL_X_RIGHT_
: 0;
auto sprite_offset = powered_up ? 3 : 0; int sprite_offset = powered_up ? 3 : 0;
auto kind_index = static_cast<int>(kind); int offset = (static_cast<int>(bullet_type) + sprite_offset) * BULLET_WIDTH_;
sprite_->setSpriteClip((kind_index + sprite_offset) * width_, 0, sprite_->getWidth(), sprite_->getHeight()); sprite_->setSpriteClip(offset, 0, BULLET_WIDTH_, BULLET_HEIGHT_);
collider_.r = width_ / 2; collider_.r = BULLET_WIDTH_ / 2;
shiftColliders(); shiftColliders();
} }
@@ -44,21 +35,20 @@ void Bullet::render()
BulletMoveStatus Bullet::move() BulletMoveStatus Bullet::move()
{ {
pos_x_ += vel_x_; pos_x_ += vel_x_;
if (pos_x_ < param.game.play_area.rect.x - width_ || pos_x_ > play_area_->w) if (pos_x_ < param.game.play_area.rect.x - BULLET_WIDTH_ || pos_x_ > param.game.play_area.rect.w)
{ {
disable(); disable();
return BulletMoveStatus::OUT; return BulletMoveStatus::OUT;
} }
pos_y_ += vel_y_; pos_y_ += BULLET_VEL_Y_;
if (pos_y_ < param.game.play_area.rect.y - height_) if (pos_y_ < param.game.play_area.rect.y - BULLET_HEIGHT_)
{ {
disable(); disable();
return BulletMoveStatus::OUT; return BulletMoveStatus::OUT;
} }
sprite_->setX(pos_x_); shiftSprite();
sprite_->setY(pos_y_);
shiftColliders(); shiftColliders();
return BulletMoveStatus::OK; return BulletMoveStatus::OK;
@@ -66,42 +56,12 @@ BulletMoveStatus Bullet::move()
bool Bullet::isEnabled() const bool Bullet::isEnabled() const
{ {
return kind_ != BulletType::NONE; return bullet_type_ != BulletType::NONE;
} }
void Bullet::disable() void Bullet::disable()
{ {
kind_ = BulletType::NONE; bullet_type_ = BulletType::NONE;
}
int Bullet::getPosX() const
{
return pos_x_;
}
int Bullet::getPosY() const
{
return pos_y_;
}
void Bullet::setPosX(int x)
{
pos_x_ = x;
}
void Bullet::setPosY(int y)
{
pos_y_ = y;
}
int Bullet::getVelY() const
{
return vel_y_;
}
BulletType Bullet::getKind() const
{
return kind_;
} }
int Bullet::getOwner() const int Bullet::getOwner() const
@@ -119,3 +79,9 @@ void Bullet::shiftColliders()
collider_.x = pos_x_ + collider_.r; collider_.x = pos_x_ + collider_.r;
collider_.y = pos_y_ + collider_.r; collider_.y = pos_y_ + collider_.r;
} }
void Bullet::shiftSprite()
{
sprite_->setX(pos_x_);
sprite_->setY(pos_y_);
}

View File

@@ -1,14 +1,13 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_stdinc.h> // Para Uint8
#include <SDL2/SDL_stdinc.h> // for Uint8 #include <memory> // Para shared_ptr, unique_ptr
#include <memory> // for shared_ptr, unique_ptr #include "sprite.h" // Para Sprite
#include "sprite.h" // for Sprite #include "utils.h" // Para Circle
#include "utils.h" // for Circle class Texture; // lines 8-8
class Texture;
// Enumeración para los diferentes tipos de balas // Tipos de balas
enum class BulletType enum class BulletType : Uint8
{ {
UP, UP,
LEFT, LEFT,
@@ -16,7 +15,7 @@ enum class BulletType
NONE NONE
}; };
// Enumeración para los resultados del movimiento de la bala // Resultado del movimiento de la bala
enum class BulletMoveStatus : Uint8 enum class BulletMoveStatus : Uint8
{ {
OK = 0, OK = 0,
@@ -27,26 +26,29 @@ enum class BulletMoveStatus : Uint8
class Bullet class Bullet
{ {
private: private:
// Constantes
static constexpr int BULLET_WIDTH_ = 12;
static constexpr int BULLET_HEIGHT_ = 12;
static constexpr int BULLET_VEL_Y_ = -3;
static constexpr int BULLET_VEL_X_LEFT_ = -2;
static constexpr int BULLET_VEL_X_RIGHT_ = 2;
std::unique_ptr<Sprite> sprite_; // Sprite con los gráficos y métodos de pintado std::unique_ptr<Sprite> sprite_; // Sprite con los gráficos y métodos de pintado
int pos_x_; // Posición en el eje X int pos_x_; // Posición en el eje X
int pos_y_; // Posición en el eje Y int pos_y_; // Posición en el eje Y
Uint8 width_; // Ancho del objeto
Uint8 height_; // Alto del objeto
int vel_x_; // Velocidad en el eje X int vel_x_; // Velocidad en el eje X
int vel_y_; // Velocidad en el eje Y
BulletType kind_; // Tipo de objeto BulletType bullet_type_; // Tipo de objeto
int owner_; // Identificador del dueño del objeto int owner_; // Identificador del dueño del objeto
Circle collider_; // Círculo de colisión del objeto Circle collider_; // Círculo de colisión del objeto
SDL_Rect *play_area_; // Rectángulo con la zona de juego
void shiftColliders(); // Alinea el círculo de colisión con el objeto void shiftColliders(); // Alinea el círculo de colisión con el objeto
void shiftSprite(); // Alinea el sprite con el objeto
public: public:
// Constructor // Constructor
Bullet(int x, int y, BulletType kind, bool powered_up, int owner, SDL_Rect *play_area, std::shared_ptr<Texture> texture); Bullet(int x, int y, BulletType bullet_type, bool powered_up, int owner, std::shared_ptr<Texture> texture);
// Destructor // Destructor
~Bullet() = default; ~Bullet() = default;
@@ -63,17 +65,7 @@ public:
// Deshabilita el objeto // Deshabilita el objeto
void disable(); void disable();
// Obtiene la posición
int getPosX() const;
int getPosY() const;
// Establece la posición
void setPosX(int x);
void setPosY(int y);
// Obtiene parámetros // Obtiene parámetros
int getVelY() const;
BulletType getKind() const;
int getOwner() const; int getOwner() const;
Circle &getCollider(); Circle &getCollider();
}; };

View File

@@ -1,7 +1,7 @@
#include "dbgtxt.h" #include "dbgtxt.h"
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // para SDL_Rect
#include <SDL2/SDL_rwops.h> // for SDL_RWFromMem #include <SDL2/SDL_rwops.h> // para SDL_RWFromMem
#include <SDL2/SDL_surface.h> // for SDL_LoadBMP_RW #include <SDL2/SDL_surface.h> // para SDL_LoadBMP_RW
namespace namespace
{ {

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // para SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint8 #include <SDL2/SDL_stdinc.h> // para Uint8
void dbg_init(SDL_Renderer *renderer); void dbg_init(SDL_Renderer *renderer);
void dbg_print(int x, int y, const char *text, Uint8 r, Uint8 g, Uint8 b); void dbg_print(int x, int y, const char *text, Uint8 r, Uint8 g, Uint8 b);

View File

@@ -1,58 +1,30 @@
#include "define_buttons.h" #include "define_buttons.h"
#include <utility> // for move #include <utility> // Para move
#include "input.h" // for Input, InputType #include "input.h" // Para Input, InputType
#include "lang.h" // for getText #include "lang.h" // Para getText
#include "options.h" // for options #include "options.h" // Para OptionsController, Options, options
#include "param.h" // for param #include "param.h" // Para Param, param, ParamGame, ParamTitle
#include "section.h" // for Name, Options, name, options #include "section.h" // Para Name, Options, name, options
#include "text.h" // for Text #include "text.h" // Para Text
#include "utils.h" // for OptionsController, Options, Param, ParamGame
// Constructor // Constructor
DefineButtons::DefineButtons(std::unique_ptr<Text> text_) DefineButtons::DefineButtons(std::unique_ptr<Text> text_)
: text_(std::move(text_)) : input_(Input::get()),
text_(std::move(text_))
{ {
// Copia punteros a los objetos
input_ = Input::get();
// Inicializa variables // Inicializa variables
enabled_ = false;
x_ = param.game.width / 2; x_ = param.game.width / 2;
y_ = param.title.press_start_position; y_ = param.title.press_start_position;
index_controller_ = 0;
index_button_ = 0;
buttons_.clear(); buttons_.emplace_back(lang::getText(95), InputType::FIRE_LEFT, SDL_CONTROLLER_BUTTON_X);
DefineButtonsButton button; buttons_.emplace_back(lang::getText(96), InputType::FIRE_CENTER, SDL_CONTROLLER_BUTTON_Y);
buttons_.emplace_back(lang::getText(97), InputType::FIRE_RIGHT, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
button.label = lang::getText(95); buttons_.emplace_back(lang::getText(98), InputType::START, SDL_CONTROLLER_BUTTON_START);
button.input = InputType::FIRE_LEFT; buttons_.emplace_back(lang::getText(99), InputType::EXIT, SDL_CONTROLLER_BUTTON_BACK);
button.button = SDL_CONTROLLER_BUTTON_X;
buttons_.push_back(button);
button.label = lang::getText(96);
button.input = InputType::FIRE_CENTER;
button.button = SDL_CONTROLLER_BUTTON_Y;
buttons_.push_back(button);
button.label = lang::getText(97);
button.input = InputType::FIRE_RIGHT;
button.button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
buttons_.push_back(button);
button.label = lang::getText(98);
button.input = InputType::START;
button.button = SDL_CONTROLLER_BUTTON_START;
buttons_.push_back(button);
button.label = lang::getText(99);
button.input = InputType::EXIT;
button.button = SDL_CONTROLLER_BUTTON_BACK;
buttons_.push_back(button);
for (int i = 0; i < input_->getNumControllers(); ++i) for (int i = 0; i < input_->getNumControllers(); ++i)
{ {
controller_names_.push_back(input_->getControllerName(i)); controller_names_.emplace_back(input_->getControllerName(i));
} }
} }
@@ -106,7 +78,7 @@ void DefineButtons::checkInput()
case SDL_QUIT: case SDL_QUIT:
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_NORMAL; section::options = section::Options::QUIT_WITH_KEYBOARD;
break; break;
} }
@@ -157,7 +129,7 @@ void DefineButtons::incIndexButton()
// Guarda los cambios en las opciones // Guarda los cambios en las opciones
saveBindingsToOptions(); saveBindingsToOptions();
//input_->allActive(index_controller_); // input_->allActive(index_controller_);
// Reinicia variables // Reinicia variables
index_button_ = 0; index_button_ = 0;

View File

@@ -1,10 +1,10 @@
#pragma once #pragma once
#include <SDL2/SDL_events.h> // for SDL_ControllerButtonEvent #include <SDL2/SDL_events.h> // para SDL_ControllerButtonEvent
#include <SDL2/SDL_gamecontroller.h> // for SDL_GameControllerButton #include <SDL2/SDL_gamecontroller.h> // para SDL_GameControllerButton
#include <memory> // for shared_ptr, unique_ptr #include <memory> // para shared_ptr, unique_ptr
#include <string> // for string #include <string> // para string
#include <vector> // for vector #include <vector> // para vector
class Input; class Input;
class Text; class Text;
enum class InputType : int; enum class InputType : int;
@@ -14,6 +14,10 @@ struct DefineButtonsButton
std::string label; // Texto en pantalla para el botón std::string label; // Texto en pantalla para el botón
InputType input; // Input asociado InputType input; // Input asociado
SDL_GameControllerButton button; // Botón del mando correspondiente SDL_GameControllerButton button; // Botón del mando correspondiente
// Constructor
DefineButtonsButton(const std::string &lbl, InputType inp, SDL_GameControllerButton btn)
: label(lbl), input(inp), button(btn) {}
}; };
// Clase Bullet // Clase Bullet
@@ -25,12 +29,12 @@ private:
std::shared_ptr<Text> text_; // Objeto para escribir texto std::shared_ptr<Text> text_; // Objeto para escribir texto
// Variables // Variables
bool enabled_; // Indica si el objeto está habilitado bool enabled_ = false; // Indica si el objeto está habilitado
int x_; // Posición donde dibujar el texto int x_; // Posición donde dibujar el texto
int y_; // Posición donde dibujar el texto int y_; // Posición donde dibujar el texto
std::vector<DefineButtonsButton> buttons_; // Vector con las nuevas definiciones de botones/acciones std::vector<DefineButtonsButton> buttons_; // Vector con las nuevas definiciones de botones/acciones
int index_controller_; // Indice del controlador a reasignar int index_controller_ = 0; // Indice del controlador a reasignar
int index_button_; // Indice para saber qué bot´çon se está definiendo int index_button_ = 0; // Indice para saber qué bot´çon se está definiendo
std::vector<std::string> controller_names_; // Nombres de los mandos std::vector<std::string> controller_names_; // Nombres de los mandos
// Incrementa el indice de los botones // Incrementa el indice de los botones

View File

@@ -1,47 +1,49 @@
#include "director.h" #include "director.h"
#include <SDL2/SDL.h> // for SDL_Init, SDL_Quit, SDL_INIT_EV... #include <SDL2/SDL.h> // Para SDL_Init, SDL_Quit, SDL_INIT_EV...
#include <SDL2/SDL_audio.h> // for AUDIO_S16 #include <SDL2/SDL_audio.h> // Para AUDIO_S16
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND
#include <SDL2/SDL_error.h> // for SDL_GetError #include <SDL2/SDL_error.h> // Para SDL_GetError
#include <SDL2/SDL_gamecontroller.h> // for SDL_CONTROLLER_BUTTON_B, SDL_CO... #include <SDL2/SDL_gamecontroller.h> // Para SDL_CONTROLLER_BUTTON_B, SDL_CO...
#include <SDL2/SDL_hints.h> // for SDL_SetHint, SDL_HINT_RENDER_DR... #include <SDL2/SDL_hints.h> // Para SDL_SetHint, SDL_HINT_RENDER_DR...
#include <SDL2/SDL_scancode.h> // for SDL_SCANCODE_0, SDL_SCANCODE_DOWN #include <SDL2/SDL_scancode.h> // Para SDL_SCANCODE_0, SDL_SCANCODE_DOWN
#include <SDL2/SDL_stdinc.h> // for SDL_bool, Uint32 #include <SDL2/SDL_stdinc.h> // Para SDL_bool, Uint32
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // Para SDL_GetTicks
#include <cstdlib> // for system #include <errno.h> // Para errno, EEXIST, EACCES, ENAMETOO...
#include <errno.h> // for errno, EEXIST, EACCES, ENAMETOO... #include <stdio.h> // Para printf, perror
#include <stdio.h> // for printf, perror #include <string.h> // Para strcmp
#include <string.h> // for strcmp #include <sys/stat.h> // Para mkdir, stat, S_IRWXU
#include <sys/stat.h> // for mkdir, stat, S_IRWXU #include <unistd.h> // Para getuid
#include <unistd.h> // for getuid #include <cstdlib> // Para exit, EXIT_FAILURE, rand, srand
#include <cstdlib> // for exit, EXIT_FAILURE, rand, srand #include <iostream> // Para basic_ostream, operator<<, cout
#include <iostream> // for basic_ostream, operator<<, cout #include <memory> // Para make_unique, unique_ptr, make_s...
#include <memory> // for make_unique, unique_ptr #include <stdexcept> // Para runtime_error
#include <string> // for operator+, allocator, char_traits #include <string> // Para operator+, allocator, char_traits
#include "asset.h" // for Asset, AssetType #include <vector> // Para vector
#include "dbgtxt.h" // for dbg_init #include "asset.h" // Para Asset, AssetType
#include "game.h" // for Game, GAME_MODE_DEMO_OFF, GAME_... #include "dbgtxt.h" // Para dbg_init
#include "global_inputs.h" // for init #include "game.h" // Para Game, GAME_MODE_DEMO_OFF, GAME_...
#include "hiscore_table.h" // for HiScoreTable #include "global_inputs.h" // Para init
#include "input.h" // for Input, InputType #include "hiscore_table.h" // Para HiScoreTable
#include "instructions.h" // for Instructions #include "input.h" // Para Input, InputType
#include "intro.h" // for Intro #include "instructions.h" // Para Instructions
#include "jail_audio.h" // for JA_LoadMusic, JA_LoadSound, JA_... #include "intro.h" // Para Intro
#include "lang.h" // for Code, loadFromFile #include "jail_audio.h" // Para JA_EnableMusic, JA_EnableSound
#include "logo.h" // for Logo #include "lang.h" // Para Code, loadFromFile
#include "manage_hiscore_table.h" // for ManageHiScoreTable #include "logo.h" // Para Logo
#include "notifier.h" // for Notifier #include "manage_hiscore_table.h" // Para ManageHiScoreTable
#include "on_screen_help.h" // for OnScreenHelp #include "notifier.h" // Para Notifier
#include "options.h" // for options, loadOptionsFile, saveO... #include "on_screen_help.h" // Para OnScreenHelp
#include "param.h" // for param, loadParamsFromFile #include "options.h" // Para Options, options, OptionsContro...
#include "resource.h" //for Resource #include "param.h" // Para Param, ParamGame, param, loadPa...
#include "screen.h" // for Screen #include "resource.h" // Para Resource
#include "section.h" // for Name, name, Options, options #include "screen.h" // Para Screen
#include "title.h" // for Title #include "section.h" // Para Name, Options, name, options
#include "utils.h" // for MusicFile, SoundFile, Options #include "text.h" // Para Text
#include "title.h" // Para Title
#include "utils.h" // Para Overrides, overrides
#ifndef _WIN32 #ifndef _WIN32
#include <pwd.h> // for getpwuid, passwd #include <pwd.h> // para getpwuid, passwd
#endif #endif
// Constructor // Constructor
@@ -84,13 +86,22 @@ Director::Director(int argc, const char *argv[])
#ifdef ANBERNIC #ifdef ANBERNIC
const std::string paramFilePath = asset->get("param_320x240.txt"); const std::string paramFilePath = asset->get("param_320x240.txt");
#else #else
const std::string paramFilePath = param_file_argument_ == "--320x240" ? Asset::get()->get("param_320x240.txt") : Asset::get()->get("param_320x256.txt"); const std::string paramFilePath = overrides.param_file == "--320x240" ? Asset::get()->get("param_320x240.txt") : Asset::get()->get("param_320x256.txt");
#endif #endif
loadParams(paramFilePath); loadParams(paramFilePath);
// Carga el fichero de puntuaciones // Carga el fichero de puntuaciones
auto manager = std::make_unique<ManageHiScoreTable>(&options.game.hi_score_table); {
manager->loadFromFile(Asset::get()->get("score.bin")); auto manager = std::make_unique<ManageHiScoreTable>(options.game.hi_score_table);
if (overrides.clear_hi_score_table)
{
manager->clear();
}
else
{
manager->loadFromFile(Asset::get()->get("score.bin"));
}
}
// Inicializa SDL // Inicializa SDL
initSDL(); initSDL();
@@ -134,6 +145,8 @@ Director::~Director()
SDL_DestroyWindow(window_); SDL_DestroyWindow(window_);
SDL_Quit(); SDL_Quit();
std::cout << "\nBye!" << std::endl;
} }
// Asigna los botones y teclas al objeto Input // Asigna los botones y teclas al objeto Input
@@ -369,85 +382,114 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/shaders/crtpi.glsl", AssetType::DATA); Asset::get()->add(prefix + "/data/shaders/crtpi.glsl", AssetType::DATA);
// Texturas // Texturas
Asset::get()->add(prefix + "/data/gfx/controllers/controllers.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon1.png", AssetType::BITMAP); { // Controllers
Asset::get()->add(prefix + "/data/gfx/balloon/balloon1.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/controllers/controllers.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon2.png", AssetType::BITMAP); }
Asset::get()->add(prefix + "/data/gfx/balloon/balloon2.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon3.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon3.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon4.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon4.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion1.png", AssetType::BITMAP); { // Balloons
Asset::get()->add(prefix + "/data/gfx/balloon/explosion1.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/balloon1.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion2.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/balloon/balloon1.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion2.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/balloon2.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion3.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/balloon/balloon2.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion3.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/balloon3.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion4.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/balloon/balloon3.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion4.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/balloon4.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/balloon4.ani", AssetType::ANIMATION);
}
Asset::get()->add(prefix + "/data/gfx/balloon/powerball.png", AssetType::BITMAP); { // Explosions
Asset::get()->add(prefix + "/data/gfx/balloon/powerball.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/balloon/explosion1.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion1.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion2.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion2.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion3.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion3.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion4.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/explosion4.ani", AssetType::ANIMATION);
}
Asset::get()->add(prefix + "/data/gfx/bullet/bullet.png", AssetType::BITMAP); { // Power Ball
Asset::get()->add(prefix + "/data/gfx/balloon/powerball.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/balloon/powerball.ani", AssetType::ANIMATION);
}
Asset::get()->add(prefix + "/data/gfx/game/game_buildings.png", AssetType::BITMAP); { // Bala
Asset::get()->add(prefix + "/data/gfx/game/game_clouds1.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/bullet/bullet.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game/game_clouds2.png", AssetType::BITMAP); }
Asset::get()->add(prefix + "/data/gfx/game/game_grass.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game/game_power_meter.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game/game_sky_colors.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_1000_points.png", AssetType::BITMAP); { // Juego
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_2500_points.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_buildings.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_5000_points.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_clouds1.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_powerup.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_clouds2.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_one_hit.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/game/game_grass.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game/game_power_meter.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game/game_sky_colors.png", AssetType::BITMAP);
}
Asset::get()->add(prefix + "/data/gfx/intro/intro.png", AssetType::BITMAP); { // Game Text
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_1000_points.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_2500_points.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_5000_points.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_powerup.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_one_hit.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/game_text/game_text_stop.png", AssetType::BITMAP);
}
Asset::get()->add(prefix + "/data/gfx/logo/logo_jailgames.png", AssetType::BITMAP); { // Intro
Asset::get()->add(prefix + "/data/gfx/logo/logo_jailgames_mini.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/intro/intro.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/logo/logo_since_1998.png", AssetType::BITMAP); }
Asset::get()->add(prefix + "/data/gfx/item/item_points1_disk.png", AssetType::BITMAP); { // Logo
Asset::get()->add(prefix + "/data/gfx/item/item_points1_disk.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/logo/logo_jailgames.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_points2_gavina.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/logo/logo_jailgames_mini.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_points2_gavina.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/logo/logo_since_1998.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_points3_pacmar.png", AssetType::BITMAP); }
Asset::get()->add(prefix + "/data/gfx/item/item_points3_pacmar.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_clock.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_clock.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/title/title_bg_tile.png", AssetType::BITMAP); { // Items
Asset::get()->add(prefix + "/data/gfx/title/title_coffee.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_points1_disk.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_crisis.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_points1_disk.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/title/title_arcade_edition.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_points2_gavina.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_dust.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/gfx/item/item_points2_gavina.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/title/title_dust.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/item/item_points3_pacmar.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_points3_pacmar.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_clock.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_clock.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/item/item_coffee_machine.ani", AssetType::ANIMATION);
}
Asset::get()->add(prefix + "/data/gfx/player/player1.gif", AssetType::BITMAP); { // Titulo
Asset::get()->add(prefix + "/data/gfx/player/player1_pal1.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/title/title_bg_tile.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player/player1_pal2.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/title/title_coffee.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player/player1_pal3.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/title/title_crisis.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_arcade_edition.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_dust.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/title/title_dust.ani", AssetType::ANIMATION);
}
Asset::get()->add(prefix + "/data/gfx/player/player2.gif", AssetType::BITMAP); { // Jugador 1
Asset::get()->add(prefix + "/data/gfx/player/player2_pal1.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/player/player1.gif", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player/player2_pal2.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/player/player1_one_coffee_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player2_pal3.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/player/player1_two_coffee_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player1_all_white_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player1_power.png", AssetType::BITMAP);
}
Asset::get()->add(prefix + "/data/gfx/player/player.ani", AssetType::ANIMATION); { // Jugador 2
Asset::get()->add(prefix + "/data/gfx/player/player2.gif", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/gfx/player/player2_one_coffee_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player2_two_coffee_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player2_all_white_palette.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/gfx/player/player2_power.png", AssetType::BITMAP);
}
Asset::get()->add(prefix + "/data/gfx/player/player_power.gif", AssetType::BITMAP); { // Animaciones del jugador
Asset::get()->add(prefix + "/data/gfx/player/player_power_pal.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/gfx/player/player.ani", AssetType::ANIMATION);
Asset::get()->add(prefix + "/data/gfx/player/player_power.ani", AssetType::ANIMATION); Asset::get()->add(prefix + "/data/gfx/player/player_power.ani", AssetType::ANIMATION);
}
// Fuentes de texto // Fuentes de texto
Asset::get()->add(prefix + "/data/font/8bithud.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/8bithud.png", AssetType::BITMAP);
@@ -461,7 +503,7 @@ void Director::setFileList()
Asset::get()->add(prefix + "/data/font/smb2_big.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/smb2_big.png", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/smb2_big.txt", AssetType::FONT); Asset::get()->add(prefix + "/data/font/smb2_big.txt", AssetType::FONT);
Asset::get()->add(prefix + "/data/font/smb2.gif", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/smb2.gif", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/smb2_pal1.gif", AssetType::PALETTE); Asset::get()->add(prefix + "/data/font/smb2_palette1.pal", AssetType::PALETTE);
Asset::get()->add(prefix + "/data/font/smb2.txt", AssetType::FONT); Asset::get()->add(prefix + "/data/font/smb2.txt", AssetType::FONT);
// Textos // Textos
@@ -483,18 +525,33 @@ void Director::loadParams(const std::string &file_path)
// Comprueba los parametros del programa // Comprueba los parametros del programa
void Director::checkProgramArguments(int argc, const char *argv[]) void Director::checkProgramArguments(int argc, const char *argv[])
{ {
const std::vector<std::string> argument_list = {"--h", "--320x240", "--clear_score"};
// Establece la ruta del programa // Establece la ruta del programa
executable_path_ = argv[0]; executable_path_ = argv[0];
// Valores por defecto
param_file_argument_.clear();
// Comprueba el resto de parámetros // Comprueba el resto de parámetros
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
{ {
if (strcmp(argv[i], "--h") == 0)
{
for (const auto &argument : argument_list)
{
std::cout << argument << std::endl;
}
// std::exit(EXIT_SUCCESS);
section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
}
if (strcmp(argv[i], "--320x240") == 0) if (strcmp(argv[i], "--320x240") == 0)
{ {
param_file_argument_ = argv[i]; overrides.param_file = argv[i];
}
if (strcmp(argv[i], "--clear_score") == 0)
{
overrides.clear_hi_score_table = true;
} }
} }
} }
@@ -658,19 +715,20 @@ int Director::run()
#ifdef ARCADE #ifdef ARCADE
// Comprueba si ha de apagar el sistema // Comprueba si ha de apagar el sistema
if (section::options == section::Options::QUIT_SHUTDOWN) if (section::options == section::Options::QUIT_WITH_CONTROLLER)
shutdownSystem(); shutdownSystem();
#endif #endif
const auto return_code = (section::options == section::Options::QUIT_NORMAL) ? "keyboard" : "controller"; const auto return_code = (section::options == section::Options::QUIT_WITH_KEYBOARD) ? "with keyboard" : (section::options == section::Options::QUIT_WITH_CONTROLLER) ? "with controller"
std::cout << "\nGame end with " << return_code << std::endl; : "from event";
std::cout << "\nGame end " << return_code << std::endl;
#ifndef VERBOSE #ifndef VERBOSE
// Habilita de nuevo los std::cout // Habilita de nuevo los std::cout
std::cout.rdbuf(orig_buf); std::cout.rdbuf(orig_buf);
#endif #endif
return (return_code == std::string("keyboard")) ? 0 : 1; return (section::options == section::Options::QUIT_WITH_CONTROLLER) ? 1 : 0;
} }
// Obtiene una fichero a partir de un lang::Code // Obtiene una fichero a partir de un lang::Code
@@ -697,6 +755,7 @@ std::string Director::getLangFile(lang::Code code)
return Asset::get()->get("en_UK.txt"); return Asset::get()->get("en_UK.txt");
} }
#ifdef ARCADE
// Apaga el sistema // Apaga el sistema
void Director::shutdownSystem() void Director::shutdownSystem()
{ {
@@ -713,4 +772,5 @@ void Director::shutdownSystem()
// Sistema operativo no compatible // Sistema operativo no compatible
#error "Sistema operativo no soportado" #error "Sistema operativo no soportado"
#endif #endif
} }
#endif // ARCADE

View File

@@ -1,15 +1,12 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // Para SDL_Renderer
#include <SDL2/SDL_video.h> // for SDL_Window #include <SDL2/SDL_video.h> // Para SDL_Window
#include <string> // for string #include <string> // Para string
#include <vector> // for vector
namespace lang namespace lang
{ {
enum class Code : int; enum class Code : int;
} } // lines 9-9
struct ResourceMusic;
struct ResourceSound;
// Textos // Textos
constexpr char WINDOW_CAPTION[] = "Coffee Crisis Arcade Edition"; constexpr char WINDOW_CAPTION[] = "Coffee Crisis Arcade Edition";
@@ -18,14 +15,15 @@ class Director
{ {
private: private:
// Objetos y punteros // Objetos y punteros
SDL_Window *window_; // La ventana donde dibujamos SDL_Window *window_; // La ventana donde dibujamos
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
#ifndef VERBOSE
std::streambuf *orig_buf; // Puntero al buffer de flujo original para restaurar std::cout std::streambuf *orig_buf; // Puntero al buffer de flujo original para restaurar std::cout
#endif
// Variables // Variables
std::string executable_path_; // Path del ejecutable std::string executable_path_; // Path del ejecutable
std::string system_folder_; // Carpeta del sistema donde guardar datos std::string system_folder_; // Carpeta del sistema donde guardar datos
std::string param_file_argument_; // Argumento para gestionar el fichero con los parametros del programa
// Inicializa jail_audio // Inicializa jail_audio
void initJailAudio(); void initJailAudio();
@@ -71,9 +69,10 @@ private:
// Obtiene una fichero a partir de un lang::Code // Obtiene una fichero a partir de un lang::Code
std::string getLangFile(lang::Code code); std::string getLangFile(lang::Code code);
#ifdef ARCADE
// Apaga el sistema // Apaga el sistema
void shutdownSystem(); void shutdownSystem();
#endif
public: public:
// Constructor // Constructor

View File

@@ -1,5 +1,6 @@
#include "enter_name.h" #include "enter_name.h"
#include <algorithm> // for max, min #include <stddef.h> // Para size_t
#include <algorithm> // Para max, min
// Constructor // Constructor
EnterName::EnterName() EnterName::EnterName()
@@ -16,7 +17,7 @@ void EnterName::init()
// Inicia la lista de caracteres permitidos // Inicia la lista de caracteres permitidos
character_list_ = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-+-*/=?¿<>!\"#$%&/()"; character_list_ = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-+-*/=?¿<>!\"#$%&/()";
position_ = 0; position_ = 0;
num_characters_ = (int)character_list_.size(); num_characters_ = static_cast<int>(character_list_.size());
// Pone la lista de indices para que refleje el nombre // Pone la lista de indices para que refleje el nombre
updateCharacterIndex(); updateCharacterIndex();
@@ -36,7 +37,7 @@ void EnterName::incPosition()
// Decrementa la posición // Decrementa la posición
void EnterName::decPosition() void EnterName::decPosition()
{ {
position_--; --position_;
position_ = std::max(position_, 0); position_ = std::max(position_, 0);
} }
@@ -76,14 +77,14 @@ void EnterName::updateName()
void EnterName::updateCharacterIndex() void EnterName::updateCharacterIndex()
{ {
// Rellena de espacios y marca como no usados // Rellena de espacios y marca como no usados
for (int i = 0; i < NAME_LENGHT; ++i) for (size_t i = 0; i < NAME_LENGHT; ++i)
{ {
character_index_[i] = 0; character_index_[i] = 0;
position_has_been_used_[i] = false; position_has_been_used_[i] = false;
} }
// Coloca los índices en funcion de los caracteres que forman el nombre // Coloca los índices en función de los caracteres que forman el nombre
for (int i = 0; i < (int)name_.size(); ++i) for (size_t i = 0; i < name_.size(); ++i)
{ {
character_index_[i] = findIndex(name_.at(i)); character_index_[i] = findIndex(name_.at(i));
position_has_been_used_[i] = true; position_has_been_used_[i] = true;
@@ -91,15 +92,11 @@ void EnterName::updateCharacterIndex()
} }
// Encuentra el indice de un caracter en "character_list_" // Encuentra el indice de un caracter en "character_list_"
int EnterName::findIndex(char character) int EnterName::findIndex(char character) const
{ {
for (int i = 0; i < (int)character_list_.size(); ++i) for (size_t i = 0; i < character_list_.size(); ++i)
{ if (character == character_list_.at(i))
if (character == character_list_[i])
{
return i; return i;
}
}
return 0; return 0;
} }
@@ -121,9 +118,7 @@ void EnterName::checkIfPositionHasBeenUsed()
auto used = position_has_been_used_[position_]; auto used = position_has_been_used_[position_];
if (!used && position_ > 0) if (!used && position_ > 0)
{
character_index_[position_] = character_index_[position_ - 1]; character_index_[position_] = character_index_[position_ - 1];
}
position_has_been_used_[position_] = true; position_has_been_used_[position_] = true;
updateName(); updateName();

View File

@@ -30,7 +30,7 @@ private:
void updateCharacterIndex(); void updateCharacterIndex();
// Encuentra el indice de un caracter en "characterList" // Encuentra el indice de un caracter en "characterList"
int findIndex(char character); int findIndex(char character) const;
// Comprueba la posición y copia el caracter si es necesario // Comprueba la posición y copia el caracter si es necesario
void checkIfPositionHasBeenUsed(); void checkIfPositionHasBeenUsed();

View File

@@ -1,20 +1,6 @@
#include "explosions.h" #include "explosions.h"
#include <utility> // for move #include "animated_sprite.h" // Para AnimatedSprite
#include "animated_sprite.h" // for SpriteAnimated class Texture; // lines 4-4
class Texture; // lines 3-3
// Constructor
Explosions::Explosions()
{
textures_.clear();
explosions_.clear();
}
// Destructor
Explosions::~Explosions()
{
explosions_.clear();
}
// Actualiza la lógica de la clase // Actualiza la lógica de la clase
void Explosions::update() void Explosions::update()
@@ -38,7 +24,7 @@ void Explosions::render()
} }
// Añade texturas al objeto // Añade texturas al objeto
void Explosions::addTexture(int size, std::shared_ptr<Texture> texture, std::vector<std::string> &animation) void Explosions::addTexture(int size, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation)
{ {
textures_.emplace_back(ExplosionTexture(size, texture, animation)); textures_.emplace_back(ExplosionTexture(size, texture, animation));
} }

View File

@@ -1,10 +1,10 @@
#pragma once #pragma once
#include <memory> // for shared_ptr, unique_ptr #include <memory> // Para unique_ptr, shared_ptr
#include <string> // for string #include <string> // Para string
#include <vector> // for vector #include <vector> // Para vector
class AnimatedSprite; #include "animated_sprite.h" // Para AnimatedSprite
class Texture; class Texture; // lines 7-7
struct ExplosionTexture struct ExplosionTexture
{ {
@@ -13,7 +13,7 @@ struct ExplosionTexture
std::vector<std::string> animation; // Animación para la textura std::vector<std::string> animation; // Animación para la textura
// Constructor // Constructor
ExplosionTexture(int sz, std::shared_ptr<Texture> tex, std::vector<std::string> anim) ExplosionTexture(int sz, std::shared_ptr<Texture> tex, const std::vector<std::string> &anim)
: size(sz), texture(tex), animation(anim) {} : size(sz), texture(tex), animation(anim) {}
}; };
@@ -33,10 +33,10 @@ private:
public: public:
// Constructor // Constructor
Explosions(); Explosions() = default;
// Destructor // Destructor
~Explosions(); ~Explosions() = default;
// Actualiza la lógica de la clase // Actualiza la lógica de la clase
void update(); void update();
@@ -45,7 +45,7 @@ public:
void render(); void render();
// Añade texturas al objeto // Añade texturas al objeto
void addTexture(int size, std::shared_ptr<Texture> texture, std::vector<std::string> &animation); void addTexture(int size, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation);
// Añade una explosión // Añade una explosión
void add(int x, int y, int size); void add(int x, int y, int size);

View File

@@ -1,11 +1,10 @@
#include "fade.h" #include "fade.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND, SDL_BLENDMODE_NONE #include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND, SDL_BLENDMODE_NONE
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
#include <stdlib.h> // for rand #include <stdlib.h> // Para rand
#include <algorithm> // for min, max #include <algorithm> // Para min, max
#include "param.h" // for param #include "param.h" // Para Param, param, ParamGame, ParamFade
#include "screen.h" #include "screen.h" // Para Screen
#include "utils.h" // for Param, ParamGame, ParamFade
// Constructor // Constructor
Fade::Fade() Fade::Fade()

View File

@@ -1,9 +1,9 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // para SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // para SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint8, Uint16 #include <SDL2/SDL_stdinc.h> // para Uint8, Uint16
#include <vector> // for vector #include <vector> // para vector
// Tipos de fundido // Tipos de fundido
enum class FadeType : Uint8 enum class FadeType : Uint8

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,31 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // Para SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // Para Uint32, Uint8
#include <memory> // for shared_ptr, unique_ptr #include <memory> // Para shared_ptr, unique_ptr
#include <string> // for string #include <string> // Para string
#include <vector> // for vector #include <vector> // Para vector
#include "balloon.h" // for Balloon #include "balloon.h" // Para Balloon
#include "player.h" // for Player #include "manage_hiscore_table.h" // Para HiScoreEntry
#include "utils.h" // for DemoKeys, Color, HiScoreEntry #include "options.h" // Para Options, OptionsGame, options
class Asset; #include "player.h" // Para Player
class Background; #include "utils.h" // Para Demo
class BalloonFormations; class Asset; // lines 12-12
class Bullet; class Background; // lines 13-13
class Explosions; class BalloonFormations; // lines 14-14
class Fade; class Bullet; // lines 15-15
class Input; class Explosions; // lines 16-16
class Item; class Fade; // lines 17-17
class Scoreboard; class Input; // lines 18-18
class Screen; class Item; // lines 19-19
class SmartSprite; class PathSprite; // lines 20-20
class Text; class Scoreboard; // lines 21-21
class Texture; class Screen; // lines 22-22
enum class BulletType; // lines 26-26 class SmartSprite; // lines 23-23
struct JA_Music_t; // lines 27-27 class Text; // lines 24-24
struct JA_Sound_t; // lines 28-28 class Texture; // lines 25-25
enum class ItemType; enum class BulletType : Uint8; // lines 26-26
enum class ItemType; // lines 27-27
// Modo demo // Modo demo
constexpr bool GAME_MODE_DEMO_OFF = false; constexpr bool GAME_MODE_DEMO_OFF = false;
@@ -32,26 +33,6 @@ constexpr bool GAME_MODE_DEMO_ON = true;
// Cantidad de elementos a escribir en los ficheros de datos // Cantidad de elementos a escribir en los ficheros de datos
constexpr int TOTAL_SCORE_DATA = 3; constexpr int TOTAL_SCORE_DATA = 3;
constexpr int TOTAL_DEMO_DATA = 2000;
// Contadores
constexpr int STAGE_COUNTER = 200;
constexpr int HELP_COUNTER = 1000;
constexpr int GAME_COMPLETED_START_FADE = 500;
constexpr int GAME_COMPLETED_END = 700;
constexpr int GAME_OVER_COUNTER = 350;
// Porcentaje de aparición de los objetos
constexpr int ITEM_POINTS_1_DISK_ODDS = 10;
constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6;
constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3;
constexpr int ITEM_CLOCK_ODDS = 5;
constexpr int ITEM_COFFEE_ODDS = 5;
constexpr int ITEM_POWER_BALL_ODDS = 0;
constexpr int ITEM_COFFEE_MACHINE_ODDS = 4;
// Valores para las variables asociadas a los objetos
constexpr int TIME_STOPPED_COUNTER = 300;
/* /*
Esta clase gestiona un estado del programa. Se encarga de toda la parte en la Esta clase gestiona un estado del programa. Se encarga de toda la parte en la
@@ -83,6 +64,26 @@ constexpr int TIME_STOPPED_COUNTER = 300;
class Game class Game
{ {
private: private:
// Constantes
// Contadores
static constexpr int STAGE_COUNTER_ = 200;
static constexpr int HELP_COUNTER_ = 1000;
static constexpr int GAME_COMPLETED_START_FADE_ = 500;
static constexpr int GAME_COMPLETED_END_ = 700;
static constexpr int GAME_OVER_COUNTER_ = 350;
static constexpr int TIME_STOPPED_COUNTER_ = 360;
// Porcentaje de aparición de los objetos
static constexpr int ITEM_POINTS_1_DISK_ODDS_ = 10;
static constexpr int ITEM_POINTS_2_GAVINA_ODDS_ = 6;
static constexpr int ITEM_POINTS_3_PACMAR_ODDS_ = 3;
static constexpr int ITEM_CLOCK_ODDS_ = 5;
static constexpr int ITEM_COFFEE_ODDS_ = 5;
static constexpr int ITEM_POWER_BALL_ODDS_ = 0;
static constexpr int ITEM_COFFEE_MACHINE_ODDS_ = 4;
// Estructuras
struct Helper struct Helper
{ {
bool need_coffee; // Indica si se necesitan cafes bool need_coffee; // Indica si se necesitan cafes
@@ -95,15 +96,19 @@ private:
int item_clock_odds; // Probabilidad de aparición del objeto int item_clock_odds; // Probabilidad de aparición del objeto
int item_coffee_odds; // Probabilidad de aparición del objeto int item_coffee_odds; // Probabilidad de aparición del objeto
int item_coffee_machine_odds; // Probabilidad de aparición del objeto int item_coffee_machine_odds; // Probabilidad de aparición del objeto
};
struct Demo // Constructor con valores predeterminados
{ Helper()
bool enabled; // Indica si está activo el modo demo : need_coffee(false),
bool recording; // Indica si está activado el modo para grabar la demo need_coffee_machine(false),
int counter; // Contador para el modo demo need_power_ball(false),
DemoKeys keys; // Variable con las pulsaciones de teclas del modo demo counter(HELP_COUNTER_),
DemoKeys data_file[2][TOTAL_DEMO_DATA]; // Vector con diferentes sets de datos con los movimientos para la demo item_disk_odds(ITEM_POINTS_1_DISK_ODDS_),
item_gavina_odds(ITEM_POINTS_2_GAVINA_ODDS_),
item_pacmar_odds(ITEM_POINTS_3_PACMAR_ODDS_),
item_clock_odds(ITEM_CLOCK_ODDS_),
item_coffee_odds(ITEM_COFFEE_ODDS_),
item_coffee_machine_odds(ITEM_COFFEE_MACHINE_ODDS_) {}
}; };
// Objetos y punteros // Objetos y punteros
@@ -124,6 +129,7 @@ private:
std::vector<std::unique_ptr<Bullet>> bullets_; // Vector con las balas std::vector<std::unique_ptr<Bullet>> bullets_; // Vector con las balas
std::vector<std::unique_ptr<Item>> items_; // Vector con los items std::vector<std::unique_ptr<Item>> items_; // Vector con los items
std::vector<std::unique_ptr<SmartSprite>> smart_sprites_; // Vector con los smartsprites std::vector<std::unique_ptr<SmartSprite>> smart_sprites_; // Vector con los smartsprites
std::vector<std::unique_ptr<PathSprite>> path_sprites_; // Vector con los smartsprites
std::shared_ptr<Texture> bullet_texture_; // Textura para las balas std::shared_ptr<Texture> bullet_texture_; // Textura para las balas
std::vector<std::shared_ptr<Texture>> item_textures_; // Vector con las texturas de los items std::vector<std::shared_ptr<Texture>> item_textures_; // Vector con las texturas de los items
@@ -146,41 +152,41 @@ private:
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
// Variables // Variables
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa HiScoreEntry hi_score_ = HiScoreEntry(
Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa options.game.hi_score_table[0].name,
bool hi_score_achieved_; // Indica si se ha superado la puntuación máxima options.game.hi_score_table[0].score); // Máxima puntuación y nombre de quien la ostenta
HiScoreEntry hi_score_; // Máxima puntuación y nombre de quien la ostenta
int current_stage_; // Indica la fase actual int current_stage_; // Indica la fase actual
int stage_bitmap_counter_; // Contador para el tiempo visible del texto de Stage int last_stage_reached_; // Contiene el número de la última pantalla que se ha alcanzado
float stage_bitmap_path_[STAGE_COUNTER]; // Vector con los puntos Y por donde se desplaza el texto Demo demo_; // Variable con todas las variables relacionadas con el modo demo
float get_ready_bitmap_path_[STAGE_COUNTER]; // Vector con los puntos X por donde se desplaza el texto GameDifficulty difficulty_ = options.game.difficulty; // Dificultad del juego
int game_over_counter_; // Contador para el estado de fin de partida Helper helper_; // Variable para gestionar las ayudas
int menace_current_; // Nivel de amenaza actual Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
int menace_threshold_; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos bool coffee_machine_enabled_ = false; // Indica si hay una máquina de café en el terreno de juego
bool time_stopped_; // Indica si el tiempo está detenido bool game_completed_ = false; // Indica si se ha completado la partida, llegando al final de la ultima pantalla
int time_stopped_counter_; // Temporizador para llevar la cuenta del tiempo detenido bool hi_score_achieved_ = false; // Indica si se ha superado la puntuación máxima
int counter_; // Contador para el juego bool paused_ = false; // Indica si el juego está pausado (no se deberia de poder utilizar en el modo arcade)
int balloons_popped_; // Lleva la cuenta de los globos explotados bool power_ball_enabled_ = false; // Indica si hay una powerball ya activa
int last_ballon_deploy_; // Guarda cual ha sido la última formación desplegada para no repetir; float balloon_speed_; // Velocidad a la que se mueven los enemigos
int balloon_deploy_counter_; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero float default_balloon_speed_; // Velocidad base de los enemigos, sin incrementar
float balloon_speed_; // Velocidad a la que se mueven los enemigos float difficulty_score_multiplier_; // Multiplicador de puntos en función de la dificultad
float default_balloon_speed_; // Velocidad base de los enemigos, sin incrementar float get_ready_bitmap_path_[STAGE_COUNTER_]; // Vector con los puntos X por donde se desplaza el texto
Helper helper_; // Variable para gestionar las ayudas int stage_bitmap_path_[STAGE_COUNTER_]; // Vector con los puntos Y por donde se desplaza el texto
bool power_ball_enabled_; // Indica si hay una powerball ya activa int balloon_deploy_counter_ = 0; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero
int power_ball_counter_; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra int balloons_popped_ = 0; // Lleva la cuenta de los globos explotados
bool coffee_machine_enabled_; // Indica si hay una máquina de café en el terreno de juego int counter_ = 0; // Contador para el juego
bool game_completed_; // Indica si se ha completado la partida, llegando al final de la ultima pantalla int current_power_ = 0; // Poder actual almacenado para completar la fase
int game_completed_counter_; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más enemigos int game_completed_counter_ = 0; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más enemigos
GameDifficulty difficulty_; // Dificultad del juego int game_over_counter_ = GAME_OVER_COUNTER_; // Contador para el estado de fin de partida
float difficulty_score_multiplier_; // Multiplicador de puntos en función de la dificultad int last_balloon_deploy_ = 0; // Guarda cual ha sido la última formación desplegada para no repetir;
Color difficulty_color_; // Color asociado a la dificultad int menace_current_ = 0; // Nivel de amenaza actual
int last_stage_reached_; // Contiene el número de la última pantalla que se ha alcanzado int menace_threshold_ = 0; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos
Demo demo_; // Variable con todas las variables relacionadas con el modo demo int power_ball_counter_ = 0; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra
int total_power_to_complete_game_; // La suma del poder necesario para completar todas las fases int stage_bitmap_counter_ = STAGE_COUNTER_; // Contador para el tiempo visible del texto de Stage
bool paused_; // Indica si el juego está pausado (no se deberia de poder utilizar en el modo arcade) int time_stopped_counter_ = 0; // Temporizador para llevar la cuenta del tiempo detenido
int current_power_; // Poder actual almacenado para completar la fase int total_power_to_complete_game_; // La suma del poder necesario para completar todas las fases
#ifdef DEBUG #ifdef DEBUG
bool auto_pop_balloons_; // Si es true, incrementa automaticamente los globos explotados bool auto_pop_balloons_ = false; // Si es true, incrementa automaticamente los globos explotados
#endif #endif
// Actualiza el juego // Actualiza el juego
@@ -192,21 +198,9 @@ private:
// Comprueba los eventos que hay en cola // Comprueba los eventos que hay en cola
void checkEvents(); void checkEvents();
// Inicializa las variables necesarias para la sección 'Game' // Asigna texturas y animaciones
void init(int player_id); void setResources();
// Carga los recursos necesarios para la sección 'Game'
void loadMedia();
// Libera los recursos previamente cargados
void unloadMedia();
// Carga el fichero de datos para la demo
bool loadDemoFile(const std::string &file_path, DemoKeys (*data_file)[TOTAL_DEMO_DATA]);
#ifdef RECORDING
// Guarda el fichero de datos para la demo
bool saveDemoFile(const std::string &file_path);
#endif
// Crea una formación de enemigos // Crea una formación de enemigos
void deployBalloonFormation(); void deployBalloonFormation();
@@ -235,7 +229,10 @@ private:
void renderBalloons(); void renderBalloons();
// Crea un globo nuevo en el vector de globos // Crea un globo nuevo en el vector de globos
std::shared_ptr<Balloon> createBalloon(float x, int y, int kind, float velx, float speed, int stopped_counter); std::shared_ptr<Balloon> createBalloon(float x, int y, BalloonType type, BalloonSize size, float velx, float speed, int stopped_counter);
// Crea un globo a partir de otro globo
void createChildBalloon(const std::shared_ptr<Balloon> &balloon, const std::string &direction);
// Crea una PowerBall // Crea una PowerBall
void createPowerBall(); void createPowerBall();
@@ -256,11 +253,17 @@ private:
void destroyAllBalloons(); void destroyAllBalloons();
// Detiene todos los globos // Detiene todos los globos
void stopAllBalloons(int time); void stopAllBalloons();
// Pone en marcha todos los globos // Pone en marcha todos los globos
void startAllBalloons(); void startAllBalloons();
// Cambia el color de todos los globos
void reverseColorsToAllBalloons();
// Cambia el color de todos los globos
void normalColorsToAllBalloons();
// Vacia el vector de globos // Vacia el vector de globos
void freeBalloons(); void freeBalloons();
@@ -300,20 +303,29 @@ private:
// Vacia el vector de items // Vacia el vector de items
void freeItems(); void freeItems();
// Crea un objeto SpriteSmart // Crea un objeto PathSprite
void createItemScoreSprite(int x, int y, std::shared_ptr<Texture> texture); void createPathSprite(int x, std::shared_ptr<Texture> texture);
// Vacia el vector de smartsprites // Vacia el vector de smartsprites
void freeSpriteSmarts(); void freeSmartSprites();
// Vacia el vector de pathsprites
void freePathSprites();
// Crea un SpriteSmart para arrojar el item café al recibir un impacto // Crea un SpriteSmart para arrojar el item café al recibir un impacto
void throwCoffee(int x, int y); void throwCoffee(int x, int y);
// Actualiza los SpriteSmarts // Actualiza los SpriteSmarts
void updateSpriteSmarts(); void updateSmartSprites();
// Pinta los SpriteSmarts activos // Pinta los SpriteSmarts activos
void renderSpriteSmarts(); void renderSmartSprites();
// Actualiza los PathSprites
void updatePathSprites();
// Pinta los PathSprites activos
void renderPathSprites();
// Acciones a realizar cuando el jugador muere // Acciones a realizar cuando el jugador muere
void killPlayer(std::shared_ptr<Player> &player); void killPlayer(std::shared_ptr<Player> &player);
@@ -321,26 +333,11 @@ private:
// Calcula y establece el valor de amenaza en funcion de los globos activos // Calcula y establece el valor de amenaza en funcion de los globos activos
void evaluateAndSetMenace(); void evaluateAndSetMenace();
// Obtiene el valor de la variable
int getMenace() const;
// Establece el valor de la variable
void setTimeStopped(bool value);
// Obtiene el valor de la variable
bool isTimeStopped() const;
// Establece el valor de la variable
void setTimeStoppedCounter(int value);
// Incrementa el valor de la variable
void incTimeStoppedCounter(int value);
// Actualiza la variable EnemyDeployCounter // Actualiza la variable EnemyDeployCounter
void updateBalloonDeployCounter(); void updateBalloonDeployCounter();
// Actualiza y comprueba el valor de la variable // Actualiza y comprueba el valor de la variable
void updateTimeStoppedCounter(); void updateTimeStopped();
// Gestiona el nivel de amenaza // Gestiona el nivel de amenaza
void updateMenace(); void updateMenace();
@@ -348,6 +345,9 @@ private:
// Actualiza el fondo // Actualiza el fondo
void updateBackground(); void updateBackground();
// Inicializa las variables que contienen puntos de ruta para mover objetos
void initPaths();
// Pinta diferentes mensajes en la pantalla // Pinta diferentes mensajes en la pantalla
void renderMessages(); void renderMessages();
@@ -363,9 +363,6 @@ private:
// Calcula el poder actual de los globos en pantalla // Calcula el poder actual de los globos en pantalla
int calculateScreenPower(); int calculateScreenPower();
// Inicializa las variables que contienen puntos de ruta para mover objetos
void initPaths();
// Actualiza el tramo final de juego, una vez completado // Actualiza el tramo final de juego, una vez completado
void updateGameCompleted(); void updateGameCompleted();
@@ -381,9 +378,6 @@ private:
// Comprueba si todos los jugadores han terminado de jugar // Comprueba si todos los jugadores han terminado de jugar
bool allPlayersAreNotPlaying(); bool allPlayersAreNotPlaying();
// Elimina todos los objetos contenidos en vectores
void deleteAllVectorObjects();
// Recarga las texturas // Recarga las texturas
void reloadTextures(); void reloadTextures();
@@ -424,7 +418,6 @@ private:
void handleDemoMode(); void handleDemoMode();
// Procesa las entradas para un jugador específico durante el modo demo. // Procesa las entradas para un jugador específico durante el modo demo.
// Incluye movimientos (izquierda, derecha, sin movimiento) y disparos automáticos.
void handleDemoPlayerInput(const std::shared_ptr<Player> &player, int index); void handleDemoPlayerInput(const std::shared_ptr<Player> &player, int index);
// Maneja el disparo de un jugador, incluyendo la creación de balas y la gestión del tiempo de espera entre disparos. // Maneja el disparo de un jugador, incluyendo la creación de balas y la gestión del tiempo de espera entre disparos.
@@ -445,6 +438,33 @@ private:
// Procesa las entradas para la introducción del nombre del jugador. // Procesa las entradas para la introducción del nombre del jugador.
void handleNameInput(const std::shared_ptr<Player> &player); void handleNameInput(const std::shared_ptr<Player> &player);
// Inicializa las variables para el modo DEMO
void initDemo(int player_id);
// Calcula el poder total necesario para completar el juego
void setTotalPower();
// Inicializa el marcador
void initScoreboard();
// Inicializa las opciones relacionadas con la dificultad
void initDifficultyVars();
// Inicializa los jugadores
void initPlayers(int player_id);
// Crea dos globos gordos
void createTwoBigBalloons();
// Pausa la música
void pauseMusic();
// Reanuda la música
void resumeMusic();
// Detiene la música
void stopMusic();
public: public:
// Constructor // Constructor
Game(int playerID, int current_stage, bool demo); Game(int playerID, int current_stage, bool demo);

View File

@@ -1,16 +1,13 @@
#include "game_logo.h" #include "game_logo.h"
#include <SDL2/SDL_render.h> // for SDL_FLIP_HORIZONTAL #include <SDL2/SDL_render.h> // Para SDL_FLIP_HORIZONTAL
#include <algorithm> // for max #include <algorithm> // Para max
#include "animated_sprite.h" // for SpriteAnimated #include "animated_sprite.h" // Para AnimatedSprite
#include "asset.h" // for Asset #include "jail_audio.h" // Para JA_PlaySound
#include "jail_audio.h" // JA_PlaySound #include "param.h" // Para Param, param, ParamGame, ParamTitle
#include "param.h" // for param #include "resource.h" // Para Resource
#include "resource.h" // for Resource #include "smart_sprite.h" // Para SmartSprite
#include "screen.h" // for Screen #include "sprite.h" // Para Sprite
#include "smart_sprite.h" // for SpriteSmart #include "texture.h" // Para Texture
#include "sprite.h" // for Sprite
#include "texture.h" // for Texture
#include "utils.h" // for Param, ParamGame, ParamTitle
// Constructor // Constructor
GameLogo::GameLogo(int x, int y) GameLogo::GameLogo(int x, int y)
@@ -27,7 +24,6 @@ GameLogo::GameLogo(int x, int y)
arcade_edition_sprite_(std::make_unique<Sprite>(arcade_edition_texture_, (param.game.width - arcade_edition_texture_->getWidth()) / 2, param.title.arcade_edition_position, arcade_edition_texture_->getWidth(), arcade_edition_texture_->getHeight())), arcade_edition_sprite_(std::make_unique<Sprite>(arcade_edition_texture_, (param.game.width - arcade_edition_texture_->getWidth()) / 2, param.title.arcade_edition_position, arcade_edition_texture_->getWidth(), arcade_edition_texture_->getHeight())),
x_(x), x_(x),
y_(y) y_(y)
{ {
@@ -51,7 +47,6 @@ void GameLogo::init()
shake_.origin = xp; shake_.origin = xp;
// Inicializa el bitmap de 'Coffee' // Inicializa el bitmap de 'Coffee'
coffee_sprite_->init();
coffee_sprite_->setPosX(xp); coffee_sprite_->setPosX(xp);
coffee_sprite_->setPosY(y_ - coffee_texture_->getHeight() - desp); coffee_sprite_->setPosY(y_ - coffee_texture_->getHeight() - desp);
coffee_sprite_->setWidth(coffee_texture_->getWidth()); coffee_sprite_->setWidth(coffee_texture_->getWidth());
@@ -67,7 +62,6 @@ void GameLogo::init()
coffee_sprite_->setDestY(y_ - coffee_texture_->getHeight()); coffee_sprite_->setDestY(y_ - coffee_texture_->getHeight());
// Inicializa el bitmap de 'Crisis' // Inicializa el bitmap de 'Crisis'
crisis_sprite_->init();
crisis_sprite_->setPosX(xp + 15); crisis_sprite_->setPosX(xp + 15);
crisis_sprite_->setPosY(y_ + desp); crisis_sprite_->setPosY(y_ + desp);
crisis_sprite_->setWidth(crisis_texture_->getWidth()); crisis_sprite_->setWidth(crisis_texture_->getWidth());

View File

@@ -1,11 +1,10 @@
#pragma once #pragma once
#include <memory> // for unique_ptr, shared_ptr #include <memory> // Para unique_ptr, shared_ptr
#include "animated_sprite.h" #include "animated_sprite.h" // Para AnimatedSprite
#include "smart_sprite.h" #include "smart_sprite.h" // Para SmartSprite
class Sprite; #include "sprite.h" // Para Sprite
class Texture; class Texture; // lines 7-7
struct JA_Sound_t; // lines 10-10
// Clase GameLogo // Clase GameLogo
class GameLogo class GameLogo

View File

@@ -1,14 +1,13 @@
#include "global_inputs.h" #include "global_inputs.h"
#include <string> // for basic_string, operator+ #include <string> // Para operator+, string
#include "input.h" // for Input, inputs_e, INPUT_DO_NOT_ALLOW_REPEAT #include "input.h" // Para Input, InputType, INPUT_DO_NOT_ALLOW_REPEAT
#include "jail_audio.h" // for JA_EnableMusic, JA_EnableSound #include "jail_audio.h" // Para JA_EnableMusic, JA_EnableSound
#include "lang.h" // for getText #include "lang.h" // Para getText
#include "notifier.h" // for Notifier #include "notifier.h" // Para Notifier
#include "options.h" // for options #include "on_screen_help.h" // Para OnScreenHelp
#include "on_screen_help.h" #include "options.h" // Para Options, OptionsAudio, options, OptionsM...
#include "screen.h" // for Screen #include "section.h" // Para Name, Options, name, options
#include "section.h" // for SectionOptions, name, SectionName, options #include "utils.h" // Para boolToOnOff, stringInVector
#include "utils.h" // for OptionsAudio, Options, OptionsMusic, boolToOnOff
namespace globalInputs namespace globalInputs
{ {
@@ -39,7 +38,7 @@ namespace globalInputs
else else
{ {
#ifdef ARCADE #ifdef ARCADE
const int index = code == section::Options::QUIT_NORMAL ? 94 : 116; const int index = code == section::Options::QUIT_WITH_CONTROLLER ? 116 : 94;
Notifier::get()->showText(lang::getText(index), std::string(), -1, exit_code); Notifier::get()->showText(lang::getText(index), std::string(), -1, exit_code);
#else #else
Notifier::get()->showText(lang::getText(94), std::string(), -1, exit_code); Notifier::get()->showText(lang::getText(94), std::string(), -1, exit_code);
@@ -69,7 +68,7 @@ namespace globalInputs
// Comprueba si se sale con el teclado // Comprueba si se sale con el teclado
if (Input::get()->checkInput(InputType::EXIT, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_KEYBOARD)) if (Input::get()->checkInput(InputType::EXIT, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_KEYBOARD))
{ {
quit(section::Options::QUIT_NORMAL); quit(section::Options::QUIT_WITH_KEYBOARD);
return; return;
} }
@@ -107,7 +106,7 @@ namespace globalInputs
// Comprueba si se sale con el mando // Comprueba si se sale con el mando
if (Input::get()->checkModInput(InputType::SERVICE, InputType::EXIT, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i)) if (Input::get()->checkModInput(InputType::SERVICE, InputType::EXIT, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i))
{ {
quit(section::Options::QUIT_SHUTDOWN); quit(section::Options::QUIT_WITH_CONTROLLER);
return; return;
} }

View File

@@ -1,51 +1,43 @@
#include "hiscore_table.h" #include "hiscore_table.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_QUIT #include <SDL2/SDL_events.h> // Para SDL_PollEvent, SDL_Event, SDL_QUIT
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // Para SDL_GetTicks
#include <SDL2/SDL_video.h> // for SDL_WINDOWEVENT_SIZE_CHANGED #include <SDL2/SDL_video.h> // Para SDL_WINDOWEVENT_SIZE_CHANGED
#include <algorithm> // for max #include <algorithm> // Para max
#include <vector> // for vector #include <vector> // Para vector
#include "asset.h" // for Asset #include "background.h" // Para Background
#include "background.h" // for Background #include "fade.h" // Para Fade, FadeMode, FadeType
#include "fade.h" // for Fade, FadeMode, FadeType #include "global_inputs.h" // Para check
#include "global_inputs.h" // for check #include "input.h" // Para Input
#include "input.h" // for Input #include "jail_audio.h" // Para JA_GetMusicState, JA_Music_state
#include "jail_audio.h" // for JA_GetMusicState, JA_Music_state #include "lang.h" // Para getText
#include "lang.h" // for getText #include "manage_hiscore_table.h" // Para HiScoreEntry
#include "options.h" // for options #include "options.h" // Para Options, OptionsGame, options
#include "param.h" // for param #include "param.h" // Para Param, param, ParamGame, ParamFade
#include "resource.h" // for Resource #include "resource.h" // Para Resource
#include "screen.h" // for Screen #include "screen.h" // Para Screen
#include "section.h" // for Name, name, Options, options #include "section.h" // Para Name, name, Options, options
#include "text.h" // for Text, TEXT_CENTER, TEXT_SHADOW, TEXT... #include "text.h" // Para Text, TEXT_CENTER, TEXT_SHADOW
#include "utils.h" // for Param, ParamGame, Color, HiScoreEntry #include "utils.h" // Para Color, Zone, fade_color, orange_color
// Constructor // Constructor
HiScoreTable::HiScoreTable() HiScoreTable::HiScoreTable()
: renderer_(Screen::get()->getRenderer()),
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
fade_(std::make_unique<Fade>()),
background_(std::make_unique<Background>()),
text_(std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"))),
counter_(0),
ticks_(0),
view_area_({0, 0, param.game.width, param.game.height}),
fade_mode_(FadeMode::IN)
{ {
// Copia punteros // Inicializa el resto de variables
renderer_ = Screen::get()->getRenderer();
// Objetos
fade_ = std::make_unique<Fade>();
background_ = std::make_unique<Background>(renderer_);
text_ = std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"));
// Crea un backbuffer para el renderizador
backbuffer_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height);
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
// Inicializa variables
section::name = section::Name::HI_SCORE_TABLE; section::name = section::Name::HI_SCORE_TABLE;
ticks_ = 0;
ticks_speed_ = 15;
counter_ = 0;
counter_end_ = 800;
view_area_ = {0, 0, param.game.width, param.game.height};
fade_mode_ = FadeMode::IN;
// Inicializa objetos // Inicializa objetos
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
background_->setPos(param.game.game_area.rect); background_->setPos(param.game.game_area.rect);
background_->setCloudsSpeed(-0.1f); background_->setCloudsSpeed(-0.1f);
background_->setGradientNumber(1); background_->setGradientNumber(1);
@@ -69,8 +61,9 @@ HiScoreTable::~HiScoreTable()
// Actualiza las variables // Actualiza las variables
void HiScoreTable::update() void HiScoreTable::update()
{ {
// Actualiza las variables constexpr int TICKS_SPEED = 15;
if (SDL_GetTicks() - ticks_ > ticks_speed_)
if (SDL_GetTicks() - ticks_ > TICKS_SPEED)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
@@ -95,11 +88,11 @@ void HiScoreTable::update()
if (counter_ == 150) if (counter_ == 150)
{ {
background_->setColor({0, 0, 0}); background_->setColor(Color(0, 0, 0));
background_->setAlpha(96); background_->setAlpha(96);
} }
if (counter_ == counter_end_) if (counter_ == COUNTER_END_)
{ {
fade_->activate(); fade_->activate();
} }
@@ -188,6 +181,7 @@ void HiScoreTable::checkEvents()
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
break; break;
} }

View File

@@ -1,10 +1,10 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // para SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // para SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint16, Uint32, Uint8 #include <SDL2/SDL_stdinc.h> // para Uint16, Uint32, Uint8
#include <memory> // for unique_ptr #include <memory> // para unique_ptr
#include <string> // for string #include <string> // para string
class Background; // lines 8-8 class Background; // lines 8-8
class Fade; // lines 9-9 class Fade; // lines 9-9
class Text; // lines 10-10 class Text; // lines 10-10
@@ -24,6 +24,9 @@ enum class FadeMode : Uint8; // lines 11-11
class HiScoreTable class HiScoreTable
{ {
private: private:
// Constantes
static constexpr Uint16 COUNTER_END_ = 800; // Valor final para el contador
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *backbuffer_; // Textura para usar como backbuffer SDL_Texture *backbuffer_; // Textura para usar como backbuffer
@@ -34,9 +37,7 @@ private:
// Variables // Variables
Uint16 counter_; // Contador Uint16 counter_; // Contador
Uint16 counter_end_; // Valor final para el contador
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa
SDL_Rect view_area_; // Parte de la textura que se muestra en pantalla SDL_Rect view_area_; // Parte de la textura que se muestra en pantalla
FadeMode fade_mode_; // Modo de fade a utilizar FadeMode fade_mode_; // Modo de fade a utilizar

View File

@@ -1,9 +1,9 @@
#include "input.h" #include "input.h"
#include <SDL2/SDL.h> // for SDL_INIT_GAMECONTROLLER, SDL_InitSubS... #include <SDL2/SDL.h> // para SDL_INIT_GAMECONTROLLER, SDL_InitSubS...
#include <SDL2/SDL_error.h> // for SDL_GetError #include <SDL2/SDL_error.h> // para SDL_GetError
#include <SDL2/SDL_events.h> // for SDL_ENABLE #include <SDL2/SDL_events.h> // para SDL_ENABLE
#include <SDL2/SDL_keyboard.h> // for SDL_GetKeyboardState #include <SDL2/SDL_keyboard.h> // para SDL_GetKeyboardState
#include <iostream> // for basic_ostream, operator<<, cout, basi... #include <iostream> // para basic_ostream, operator<<, cout, basi...
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
Input *Input::input_ = nullptr; Input *Input::input_ = nullptr;
@@ -416,10 +416,9 @@ bool Input::discoverGameControllers()
} }
} }
{ std::cout << "\n** LOOKING FOR GAME CONTROLLERS" << std::endl;
std::cout << "\nChecking for game controllers...\n"; // std::cout << " " << num_joysticks_ << " joysticks found" << std::endl;
std::cout << num_joysticks_ << " joysticks found, " << num_gamepads_ << " are gamepads\n"; std::cout << "Gamepads found: " << num_gamepads_ << std::endl;
}
if (num_gamepads_ > 0) if (num_gamepads_ > 0)
{ {
@@ -434,7 +433,7 @@ bool Input::discoverGameControllers()
connected_controllers_.push_back(pad); connected_controllers_.push_back(pad);
const std::string name = SDL_GameControllerNameForIndex(i); const std::string name = SDL_GameControllerNameForIndex(i);
{ {
std::cout << name << std::endl; std::cout << "#" << i << ": " << name << std::endl;
} }
controller_names_.push_back(name); controller_names_.push_back(name);
} }
@@ -449,6 +448,8 @@ bool Input::discoverGameControllers()
SDL_GameControllerEventState(SDL_ENABLE); SDL_GameControllerEventState(SDL_ENABLE);
} }
std::cout << "\n** FINISHED LOOKING FOR GAME CONTROLLERS" << std::endl;
return found; return found;
} }

View File

@@ -1,11 +1,11 @@
#pragma once #pragma once
#include <SDL2/SDL_gamecontroller.h> // for SDL_GameControllerButton, SDL_G... #include <SDL2/SDL_gamecontroller.h> // para SDL_GameControllerButton, SDL_G...
#include <SDL2/SDL_joystick.h> // for SDL_Joystick #include <SDL2/SDL_joystick.h> // para SDL_Joystick
#include <SDL2/SDL_scancode.h> // for SDL_Scancode #include <SDL2/SDL_scancode.h> // para SDL_Scancode
#include <SDL2/SDL_stdinc.h> // for Uint8 #include <SDL2/SDL_stdinc.h> // para Uint8
#include <string> // for string, basic_string #include <string> // para string, basic_string
#include <vector> // for vector #include <vector> // para vector
/* /*
connectedControllers es un vector donde estan todos los mandos encontrados [0 .. n] connectedControllers es un vector donde estan todos los mandos encontrados [0 .. n]

View File

@@ -1,56 +1,44 @@
#include "instructions.h" #include "instructions.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_QUIT #include <SDL2/SDL_events.h> // Para SDL_PollEvent, SDL_Event, SDL_QUIT
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // Para SDL_GetTicks
#include <SDL2/SDL_video.h> // for SDL_WINDOWEVENT_SIZE_CHANGED #include <SDL2/SDL_video.h> // Para SDL_WINDOWEVENT_SIZE_CHANGED
#include <algorithm> // for max #include <algorithm> // Para max
#include <utility> // for move #include <utility> // Para move
#include "asset.h" // for Asset #include "fade.h" // Para Fade, FadeMode, FadeType
#include "fade.h" // for Fade, FadeMode, FadeType #include "global_inputs.h" // Para check
#include "global_inputs.h" // for check #include "input.h" // Para Input
#include "input.h" // for Input #include "jail_audio.h" // Para JA_GetMusicState, JA_Music_state
#include "jail_audio.h" // for JA_GetMusicState, JA_Music_state #include "lang.h" // Para getText
#include "lang.h" // for getText #include "param.h" // Para Param, param, ParamGame, ParamFade
#include "param.h" // for param #include "resource.h" // Para Resource
#include "resource.h" // for Resource #include "screen.h" // Para Screen
#include "screen.h" // for Screen #include "section.h" // Para Name, name, Options, options
#include "section.h" // for Name, name, Options, options #include "sprite.h" // Para Sprite
#include "sprite.h" // for Sprite #include "text.h" // Para Text, TEXT_CENTER, TEXT_COLOR, TEXT_...
#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR, TEXT_... #include "texture.h" // Para Texture
#include "texture.h" // for Texture #include "tiled_bg.h" // Para TiledBG, TiledBGMode
#include "tiled_bg.h" // for TiledBG, TILED_MODE_STATIC #include "utils.h" // Para Color, shdw_txt_color, Zone, no_color
#include "utils.h" // for Param, ParamGame, Color, shdw_txt_color
struct JA_Music_t; // lines 22-22
// Constructor // Constructor
Instructions::Instructions() Instructions::Instructions()
: renderer_(Screen::get()->getRenderer()),
texture_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
text_(std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"))),
tiled_bg_(std::make_unique<TiledBG>((SDL_Rect){0, 0, param.game.width, param.game.height}, TiledBGMode::STATIC)),
fade_(std::make_unique<Fade>())
{ {
// Copia los punteros
renderer_ = Screen::get()->getRenderer();
// Crea objetos
text_ = std::make_unique<Text>(Resource::get()->getTexture("smb2.gif"), Resource::get()->getTextFile("smb2.txt"));
tiled_bg_ = std::make_unique<TiledBG>((SDL_Rect){0, 0, param.game.width, param.game.height}, TILED_MODE_STATIC);
fade_ = std::make_unique<Fade>();
// Crea un backbuffer para el renderizador // Crea un backbuffer para el renderizador
backbuffer_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height);
SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(backbuffer_, SDL_BLENDMODE_BLEND);
// Crea una textura para el texto fijo // Crea una textura para el texto fijo
texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height);
SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
// Inicializa variables // Inicializa variables
section::name = section::Name::INSTRUCTIONS; section::name = section::Name::INSTRUCTIONS;
ticks_ = 0;
ticks_speed_ = 15;
counter_ = 0;
counter_end_ = 700;
view_ = {0, 0, param.game.width, param.game.height}; view_ = {0, 0, param.game.width, param.game.height};
sprite_pos_ = {0, 0};
item_space_ = 2;
// Inicializa objetos // Inicializa objetos
fade_->setColor(fade_color.r, fade_color.g, fade_color.b); fade_->setColor(fade_color.r, fade_color.g, fade_color.b);
@@ -214,8 +202,9 @@ void Instructions::fillBackbuffer()
// Actualiza las variables // Actualiza las variables
void Instructions::update() void Instructions::update()
{ {
// Actualiza las variables constexpr int TICKS_SPEED = 15;
if (SDL_GetTicks() - ticks_ > ticks_speed_)
if (SDL_GetTicks() - ticks_ > TICKS_SPEED)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
@@ -297,6 +286,7 @@ void Instructions::checkEvents()
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
break; break;
} }

View File

@@ -1,16 +1,15 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Point, SDL_Rect #include <SDL2/SDL_rect.h> // Para SDL_Point, SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Texture, SDL_Renderer #include <SDL2/SDL_render.h> // Para SDL_Texture, SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // Para Uint32
#include <memory> // for unique_ptr, shared_ptr #include <memory> // Para unique_ptr, shared_ptr
#include <vector> // for vector #include <vector> // Para vector
class Fade; class Fade; // lines 8-8
class Sprite; class Sprite; // lines 9-9
class Text; class Text; // lines 10-10
class Texture; class Texture; // lines 11-11
class TiledBG; class TiledBG; // lines 12-12
struct JA_Music_t; // lines 14-14
/* /*
Esta clase gestiona un estado del programa. Se encarga de poner en pantalla Esta clase gestiona un estado del programa. Se encarga de poner en pantalla
@@ -30,24 +29,23 @@ class Instructions
{ {
private: private:
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *texture_; // Textura fija con el texto
SDL_Texture *backbuffer_; // Textura para usar como backbuffer
std::vector<std::shared_ptr<Texture>> item_textures_; // Vector con las texturas de los items std::vector<std::shared_ptr<Texture>> item_textures_; // Vector con las texturas de los items
std::vector<std::unique_ptr<Sprite>> sprites_; // Vector con los sprites de los items std::vector<std::unique_ptr<Sprite>> sprites_; // Vector con los sprites de los items
std::unique_ptr<Text> text_; // Objeto para escribir texto std::unique_ptr<Text> text_; // Objeto para escribir texto
std::unique_ptr<TiledBG> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo std::unique_ptr<TiledBG> tiled_bg_; // Objeto para dibujar el mosaico animado de fondo
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *texture_; // Textura fija con el texto
SDL_Texture *backbuffer_; // Textura para usar como backbuffer
// Variables // Variables
int counter_; // Contador int counter_ = 0; // Contador
int counter_end_; // Valor final para el contador int counter_end_ = 700; // Valor final para el contador
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
Uint32 ticks_speed_; // Velocidad a la que se repiten los bucles del programa SDL_Rect view_; // Vista del backbuffer que se va amostrar por pantalla
SDL_Rect view_; // Vista del backbuffer que se va amostrar por pantalla SDL_Point sprite_pos_ = {0, 0}; // Posición del primer sprite
SDL_Point sprite_pos_; // Posición del primer sprite int item_space_ = 2; // Espacio entre los items
int item_space_; // Espacio entre los items
// Actualiza las variables // Actualiza las variables
void update(); void update();

View File

@@ -1,37 +1,31 @@
#include "intro.h" #include "intro.h"
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_QUIT, SDL... #include <SDL2/SDL_events.h> // Para SDL_PollEvent, SDL_Event, SDL_QUIT, SDL...
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // Para SDL_GetTicks
#include <SDL2/SDL_video.h> // for SDL_WINDOWEVENT_SIZE_CHANGED #include <SDL2/SDL_video.h> // Para SDL_WINDOWEVENT_SIZE_CHANGED
#include <utility> // for move #include <utility> // Para move
#include "asset.h" // for Asset #include "global_inputs.h" // Para check
#include "global_inputs.h" // for check #include "input.h" // Para Input
#include "input.h" // for Input #include "jail_audio.h" // Para JA_StopMusic, JA_PlayMusic
#include "jail_audio.h" // for JA_StopMusic, JA_PlayMusic #include "lang.h" // Para getText
#include "lang.h" // for getText #include "param.h" // Para Param, ParamGame, param
#include "param.h" // for param #include "resource.h" // Para Resource
#include "resource.h" // for Resource #include "screen.h" // Para Screen
#include "screen.h" // for Screen #include "section.h" // Para Name, name, Options, options
#include "section.h" // for Name, name, Options, options #include "smart_sprite.h" // Para SmartSprite
#include "smart_sprite.h" // for SpriteSmart #include "text.h" // Para Text
#include "text.h" // for Text #include "texture.h" // Para Texture
#include "texture.h" // for Texture #include "utils.h" // Para Zone, BLOCK, Color, bg_color
#include "utils.h" // for Param, ParamGame, Zone, BLOCK, Color #include "writer.h" // Para Writer
#include "writer.h" // for Writer
struct JA_Music_t; // lines 19-19
// Constructor // Constructor
Intro::Intro() Intro::Intro()
: texture_(Resource::get()->getTexture("intro.png")),
text_(std::make_shared<Text>(Resource::get()->getTexture("nokia.png"), Resource::get()->getTextFile("nokia.txt")))
{ {
// Reserva memoria para los objetos
texture_ = Resource::get()->getTexture("intro.png");
text_ = std::make_shared<Text>(Resource::get()->getTexture("nokia.png"), Resource::get()->getTextFile("nokia.txt"));
// Inicializa variables // Inicializa variables
section::name = section::Name::INTRO; section::name = section::Name::INTRO;
section::options = section::Options::NONE; section::options = section::Options::NONE;
ticks_ = 0;
ticks_speed_ = 15;
scene_ = 1;
// Inicializa los bitmaps de la intro // Inicializa los bitmaps de la intro
constexpr int totalBitmaps = 6; constexpr int totalBitmaps = 6;
@@ -170,6 +164,7 @@ void Intro::checkEvents()
case SDL_QUIT: case SDL_QUIT:
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
break; break;
} }
@@ -371,7 +366,9 @@ void Intro::updateScenes()
// Actualiza las variables del objeto // Actualiza las variables del objeto
void Intro::update() void Intro::update()
{ {
if (SDL_GetTicks() - ticks_ > ticks_speed_) constexpr int TICKS_SPEED = 15;
if (SDL_GetTicks() - ticks_ > TICKS_SPEED)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();

View File

@@ -1,13 +1,12 @@
#pragma once #pragma once
#include <SDL2/SDL_stdinc.h> // for Uint32, Uint8 #include <SDL2/SDL_stdinc.h> // Para Uint32
#include <memory> // for unique_ptr, shared_ptr #include <memory> // Para unique_ptr, shared_ptr
#include <vector> // for vector #include <vector> // Para vector
#include "smart_sprite.h" // for SpriteSmart #include "smart_sprite.h" // Para SmartSprite
#include "writer.h" // for Writer #include "writer.h" // Para Writer
class Text; class Text; // lines 8-8
class Texture; class Texture; // lines 9-9
struct JA_Music_t; // lines 11-11
/* /*
Esta clase gestiona un estado del programa. Se encarga de mostrar la secuencia Esta clase gestiona un estado del programa. Se encarga de mostrar la secuencia
@@ -26,9 +25,8 @@ private:
std::vector<std::unique_ptr<Writer>> texts_; // Textos de la intro std::vector<std::unique_ptr<Writer>> texts_; // Textos de la intro
// Variables // Variables
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
Uint8 ticks_speed_; // Velocidad a la que se repiten los bucles del programa int scene_ = 1; // Indica que escena está activa
int scene_; // Indica que escena está activa
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update();

View File

@@ -1,31 +1,30 @@
#include "item.h" #include "item.h"
#include <stdlib.h> // for rand #include <stdlib.h> // para rand
#include "animated_sprite.h" // for SpriteAnimated #include "animated_sprite.h" // para SpriteAnimated
#include "param.h" // for param #include "param.h" // para param
class Texture; class Texture;
// Constructor // Constructor
Item::Item(ItemType type, float x, float y, SDL_Rect *play_area, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation) Item::Item(ItemType type, float x, float y, SDL_Rect &play_area, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation)
: sprite_(std::make_unique<AnimatedSprite>(texture, animation)), : sprite_(std::make_unique<AnimatedSprite>(texture, animation)),
accel_x_(0.0f),
floor_collision_(false),
type_(type), type_(type),
enabled_(true), play_area_(play_area)
play_area_(play_area),
time_to_live_(600)
{ {
if (type == ItemType::COFFEE_MACHINE) switch (type)
{
case ItemType::COFFEE_MACHINE:
{ {
width_ = 28; width_ = 28;
height_ = 37; height_ = 37;
pos_x_ = (((int)x + (play_area->w / 2)) % (play_area->w - width_ - 5)) + 2; pos_x_ = ((static_cast<int>(x) + (play_area.w / 2)) % (play_area.w - width_ - 5)) + 2;
pos_y_ = -height_; pos_y_ = -height_;
vel_x_ = 0.0f; vel_x_ = 0.0f;
vel_y_ = -0.1f; vel_y_ = -0.1f;
accel_y_ = 0.1f; accel_y_ = 0.1f;
collider_.r = 10; collider_.r = 10;
break;
} }
else default:
{ {
width_ = 20; width_ = 20;
height_ = 20; height_ = 20;
@@ -35,6 +34,8 @@ Item::Item(ItemType type, float x, float y, SDL_Rect *play_area, std::shared_ptr
vel_y_ = -4.0f; vel_y_ = -4.0f;
accel_y_ = 0.2f; accel_y_ = 0.2f;
collider_.r = width_ / 2; collider_.r = width_ / 2;
break;
}
} }
sprite_->setPosX(pos_x_); sprite_->setPosX(pos_x_);
@@ -43,22 +44,22 @@ Item::Item(ItemType type, float x, float y, SDL_Rect *play_area, std::shared_ptr
} }
// Centra el objeto en la posición X // Centra el objeto en la posición X
void Item::allignTo(int x) void Item::alignTo(int x)
{ {
pos_x_ = float(x - (width_ / 2)); pos_x_ = static_cast<float>(x - (width_ / 2));
if (pos_x_ < param.game.play_area.rect.x) if (pos_x_ < param.game.play_area.rect.x)
{ {
pos_x_ = param.game.play_area.rect.x + 1; pos_x_ = param.game.play_area.rect.x + 1;
} }
else if ((pos_x_ + width_) > play_area_->w) else if (pos_x_ + width_ > play_area_.w)
{ {
pos_x_ = float(play_area_->w - width_ - 1); pos_x_ = static_cast<float>(play_area_.w - width_ - 1);
} }
// Posición X,Y del sprite // Posición X,Y del sprite
sprite_->setPosX(int(pos_x_)); sprite_->setPosX(pos_x_);
sprite_->setPosY(int(pos_y_)); sprite_->setPosY(pos_y_);
// Alinea el circulo de colisión con el objeto // Alinea el circulo de colisión con el objeto
shiftColliders(); shiftColliders();
@@ -94,7 +95,7 @@ void Item::move()
vel_y_ += accel_y_; vel_y_ += accel_y_;
// Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido // Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido
if ((pos_x_ < param.game.play_area.rect.x) || (pos_x_ + width_ > play_area_->w)) if ((pos_x_ < param.game.play_area.rect.x) || (pos_x_ + width_ > play_area_.w))
{ {
// Corregir posición // Corregir posición
pos_x_ -= vel_x_; pos_x_ -= vel_x_;
@@ -114,14 +115,14 @@ void Item::move()
} }
// Si el objeto se sale por la parte inferior // Si el objeto se sale por la parte inferior
if (pos_y_ + height_ > play_area_->h) if (pos_y_ + height_ > play_area_.h)
{ {
// Detiene el objeto // Detiene el objeto
vel_y_ = 0; vel_y_ = 0;
vel_x_ = 0; vel_x_ = 0;
accel_x_ = 0; accel_x_ = 0;
accel_y_ = 0; accel_y_ = 0;
pos_y_ = play_area_->h - height_; pos_y_ = play_area_.h - height_;
if (type_ == ItemType::COFFEE_MACHINE) if (type_ == ItemType::COFFEE_MACHINE)
{ {
floor_collision_ = true; floor_collision_ = true;

View File

@@ -1,12 +1,12 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // para SDL_Rect
#include <SDL2/SDL_stdinc.h> // for Uint16 #include <SDL2/SDL_stdinc.h> // para Uint16
#include <memory> // for shared_ptr, unique_ptr #include <memory> // para shared_ptr, unique_ptr
#include <string> // for string #include <string> // para string
#include <vector> // for vector #include <vector> // para vector
#include "animated_sprite.h" // for SpriteAnimated #include "animated_sprite.h" // para SpriteAnimated
#include "utils.h" // for Circle #include "utils.h" // para Circle
class Texture; class Texture;
// Tipos de objetos // Tipos de objetos
@@ -29,20 +29,20 @@ private:
std::unique_ptr<AnimatedSprite> sprite_; // Sprite con los graficos del objeto std::unique_ptr<AnimatedSprite> sprite_; // Sprite con los graficos del objeto
// Variables // Variables
float pos_x_; // Posición X del objeto float pos_x_; // Posición X del objeto
float pos_y_; // Posición Y del objeto float pos_y_; // Posición Y del objeto
int width_; // Ancho del objeto int width_; // Ancho del objeto
int height_; // Alto del objeto int height_; // Alto del objeto
float vel_x_; // Velocidad en el eje X float vel_x_; // Velocidad en el eje X
float vel_y_; // Velocidad en el eje Y float vel_y_; // Velocidad en el eje Y
float accel_x_; // Aceleración en el eje X float accel_x_ = 0.0f; // Aceleración en el eje X
float accel_y_; // Aceleración en el eje Y float accel_y_; // Aceleración en el eje Y
bool floor_collision_; // Indica si el objeto colisiona con el suelo bool floor_collision_ = false; // Indica si el objeto colisiona con el suelo
ItemType type_; // Especifica el tipo de objeto que es ItemType type_; // Especifica el tipo de objeto que es
bool enabled_; // Especifica si el objeto está habilitado bool enabled_ = true; // Especifica si el objeto está habilitado
Circle collider_; // Circulo de colisión del objeto Circle collider_; // Circulo de colisión del objeto
SDL_Rect *play_area_; // Rectangulo con la zona de juego SDL_Rect play_area_; // Rectangulo con la zona de juego
Uint16 time_to_live_; // Temporizador con el tiempo que el objeto está presente Uint16 time_to_live_ = 600; // Temporizador con el tiempo que el objeto está presente
// Alinea el circulo de colisión con la posición del objeto // Alinea el circulo de colisión con la posición del objeto
void shiftColliders(); void shiftColliders();
@@ -58,13 +58,13 @@ private:
public: public:
// Constructor // Constructor
Item(ItemType type, float x, float y, SDL_Rect *play_area, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation); Item(ItemType type, float x, float y, SDL_Rect &play_area, std::shared_ptr<Texture> texture, const std::vector<std::string> &animation);
// Destructor // Destructor
~Item() = default; ~Item() = default;
// Centra el objeto en la posición X // Centra el objeto en la posición X
void allignTo(int x); void alignTo(int x);
// Pinta el objeto en la pantalla // Pinta el objeto en la pantalla
void render(); void render();

View File

@@ -1,74 +1,91 @@
#ifndef JA_USESDLMIXER #ifndef JA_USESDLMIXER
#include "jail_audio.h" #include "jail_audio.h"
#include <stdint.h> // for uint8_t #include <stdint.h> // para uint8_t
#include <stdio.h> // for NULL, fseek, fclose, fopen, fread, ftell, FILE #include <stdio.h> // para NULL, fseek, fclose, fopen, fread, ftell, FILE
#include <stdlib.h> // for free, malloc #include <stdlib.h> // para free, malloc
#include "stb_vorbis.c" // for stb_vorbis_decode_memory #include "stb_vorbis.c" // para stb_vorbis_decode_memory
#define JA_MAX_SIMULTANEOUS_CHANNELS 5 #define JA_MAX_SIMULTANEOUS_CHANNELS 5
struct JA_Sound_t { struct JA_Sound_t
Uint32 length {0}; {
Uint8* buffer {NULL}; Uint32 length{0};
Uint8 *buffer{NULL};
}; };
struct JA_Channel_t { struct JA_Channel_t
JA_Sound_t *sound; {
int pos {0}; JA_Sound_t *sound;
int times {0}; int pos{0};
JA_Channel_state state { JA_CHANNEL_FREE }; int times{0};
JA_Channel_state state{JA_CHANNEL_FREE};
}; };
struct JA_Music_t { struct JA_Music_t
int samples {0}; {
int pos {0}; int samples{0};
int times {0}; int pos{0};
short* output {NULL}; int times{0};
JA_Music_state state {JA_MUSIC_INVALID}; short *output{NULL};
JA_Music_state state{JA_MUSIC_INVALID};
}; };
JA_Music_t *current_music{NULL}; JA_Music_t *current_music{NULL};
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
int JA_freq {48000}; int JA_freq{48000};
SDL_AudioFormat JA_format {AUDIO_S16}; SDL_AudioFormat JA_format{AUDIO_S16};
Uint8 JA_channels {2}; Uint8 JA_channels{2};
int JA_musicVolume = 128; int JA_musicVolume = 128;
int JA_soundVolume = 64; int JA_soundVolume = 64;
bool JA_musicEnabled = true; bool JA_musicEnabled = true;
bool JA_soundEnabled = true; bool JA_soundEnabled = true;
SDL_AudioDeviceID sdlAudioDevice = 0; SDL_AudioDeviceID sdlAudioDevice = 0;
void audioCallback(void * userdata, uint8_t * stream, int len) { void audioCallback(void *userdata, uint8_t *stream, int len)
{
SDL_memset(stream, 0, len); SDL_memset(stream, 0, len);
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) { if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING)
const int size = SDL_min(len, current_music->samples*2-current_music->pos); {
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_musicVolume); const int size = SDL_min(len, current_music->samples * 2 - current_music->pos);
current_music->pos += size/2; SDL_MixAudioFormat(stream, (Uint8 *)(current_music->output + current_music->pos), AUDIO_S16, size, JA_musicVolume);
if (size < len) { current_music->pos += size / 2;
if (current_music->times != 0) { if (size < len)
SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, JA_musicVolume); {
current_music->pos = (len-size)/2; if (current_music->times != 0)
if (current_music->times > 0) current_music->times--; {
} else { SDL_MixAudioFormat(stream + size, (Uint8 *)current_music->output, AUDIO_S16, len - size, JA_musicVolume);
current_music->pos = (len - size) / 2;
if (current_music->times > 0)
current_music->times--;
}
else
{
current_music->pos = 0; current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED; current_music->state = JA_MUSIC_STOPPED;
} }
} }
} }
// Mixar els channels mi amol // Mixar els channels mi amol
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
if (channels[i].state == JA_CHANNEL_PLAYING) { {
if (channels[i].state == JA_CHANNEL_PLAYING)
{
const int size = SDL_min(len, channels[i].sound->length - channels[i].pos); const int size = SDL_min(len, channels[i].sound->length - channels[i].pos);
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundVolume); SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundVolume);
channels[i].pos += size; channels[i].pos += size;
if (size < len) { if (size < len)
if (channels[i].times != 0) { {
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_soundVolume); if (channels[i].times != 0)
channels[i].pos = len-size; {
if (channels[i].times > 0) channels[i].times--; SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len - size, JA_soundVolume);
} else { channels[i].pos = len - size;
if (channels[i].times > 0)
channels[i].times--;
}
else
{
JA_StopChannel(i); JA_StopChannel(i);
} }
} }
@@ -76,23 +93,28 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
} }
} }
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) { void JA_Init(const int freq, const SDL_AudioFormat format, const int channels)
{
JA_freq = freq; JA_freq = freq;
JA_format = format; JA_format = format;
JA_channels = channels; JA_channels = channels;
SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL}; SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL};
if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice); if (sdlAudioDevice != 0)
SDL_CloseAudioDevice(sdlAudioDevice);
sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0); sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
SDL_PauseAudioDevice(sdlAudioDevice, 0); SDL_PauseAudioDevice(sdlAudioDevice, 0);
} }
void JA_Quit() { void JA_Quit()
{
SDL_PauseAudioDevice(sdlAudioDevice, 1); SDL_PauseAudioDevice(sdlAudioDevice, 1);
if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice); if (sdlAudioDevice != 0)
SDL_CloseAudioDevice(sdlAudioDevice);
sdlAudioDevice = 0; sdlAudioDevice = 0;
} }
JA_Music_t *JA_LoadMusic(const char* filename) { JA_Music_t *JA_LoadMusic(const char *filename)
{
int chan, samplerate; int chan, samplerate;
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid. // [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
@@ -100,8 +122,9 @@ JA_Music_t *JA_LoadMusic(const char* filename) {
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
long fsize = ftell(f); long fsize = ftell(f);
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
Uint8 *buffer = (Uint8*)malloc(fsize + 1); Uint8 *buffer = (Uint8 *)malloc(fsize + 1);
if (fread(buffer, fsize, 1, f)!=1) return NULL; if (fread(buffer, fsize, 1, f) != 1)
return NULL;
fclose(f); fclose(f);
JA_Music_t *music = new JA_Music_t(); JA_Music_t *music = new JA_Music_t();
@@ -109,17 +132,18 @@ JA_Music_t *JA_LoadMusic(const char* filename) {
music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output); music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output);
free(buffer); free(buffer);
// [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert // [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert
// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output); // music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
SDL_AudioCVT cvt; SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq); SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
if (cvt.needed) { if (cvt.needed)
{
cvt.len = music->samples * chan * 2; cvt.len = music->samples * chan * 2;
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult); cvt.buf = (Uint8 *)SDL_malloc(cvt.len * cvt.len_mult);
SDL_memcpy(cvt.buf, music->output, cvt.len); SDL_memcpy(cvt.buf, music->output, cvt.len);
SDL_ConvertAudio(&cvt); SDL_ConvertAudio(&cvt);
free(music->output); free(music->output);
music->output = (short*)cvt.buf; music->output = (short *)cvt.buf;
} }
music->pos = 0; music->pos = 0;
music->state = JA_MUSIC_STOPPED; music->state = JA_MUSIC_STOPPED;
@@ -129,9 +153,11 @@ JA_Music_t *JA_LoadMusic(const char* filename) {
void JA_PlayMusic(JA_Music_t *music, const int loop) void JA_PlayMusic(JA_Music_t *music, const int loop)
{ {
if (!JA_musicEnabled || !music) return; if (!JA_musicEnabled || !music)
return;
if (current_music != NULL) { if (current_music != NULL)
{
current_music->pos = 0; current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED; current_music->state = JA_MUSIC_STOPPED;
} }
@@ -143,67 +169,78 @@ void JA_PlayMusic(JA_Music_t *music, const int loop)
void JA_PauseMusic() void JA_PauseMusic()
{ {
if (!JA_musicEnabled) return; if (!JA_musicEnabled)
return;
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; if (current_music == NULL || current_music->state == JA_MUSIC_INVALID)
return;
current_music->state = JA_MUSIC_PAUSED; current_music->state = JA_MUSIC_PAUSED;
} }
void JA_ResumeMusic() void JA_ResumeMusic()
{ {
if (!JA_musicEnabled) return; if (!JA_musicEnabled)
return;
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; if (current_music == NULL || current_music->state == JA_MUSIC_INVALID)
return;
current_music->state = JA_MUSIC_PLAYING; current_music->state = JA_MUSIC_PLAYING;
} }
void JA_StopMusic() void JA_StopMusic()
{ {
if (!JA_musicEnabled) return; if (!JA_musicEnabled)
return;
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return; if (current_music == NULL || current_music->state == JA_MUSIC_INVALID)
return;
current_music->pos = 0; current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED; current_music->state = JA_MUSIC_STOPPED;
} }
JA_Music_state JA_GetMusicState() { JA_Music_state JA_GetMusicState()
if (!JA_musicEnabled) return JA_MUSIC_DISABLED; {
if (!JA_musicEnabled)
return JA_MUSIC_DISABLED;
if (current_music == NULL) return JA_MUSIC_INVALID; if (current_music == NULL)
return JA_MUSIC_INVALID;
return current_music->state; return current_music->state;
} }
void JA_DeleteMusic(JA_Music_t *music) { void JA_DeleteMusic(JA_Music_t *music)
if (current_music == music) current_music = NULL; {
if (current_music == music)
current_music = NULL;
free(music->output); free(music->output);
delete music; delete music;
} }
int JA_SetMusicVolume(int volume) int JA_SetMusicVolume(int volume)
{ {
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0
: volume;
return JA_musicVolume; return JA_musicVolume;
} }
void JA_EnableMusic(const bool value) void JA_EnableMusic(const bool value)
{ {
if (!value && current_music != NULL && current_music->state==JA_MUSIC_PLAYING) JA_StopMusic(); if (!value && current_music != NULL && current_music->state == JA_MUSIC_PLAYING)
JA_StopMusic();
JA_musicEnabled = value; JA_musicEnabled = value;
} }
JA_Sound_t *JA_NewSound(Uint8 *buffer, Uint32 length)
{
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length) {
JA_Sound_t *sound = new JA_Sound_t(); JA_Sound_t *sound = new JA_Sound_t();
sound->buffer = buffer; sound->buffer = buffer;
sound->length = length; sound->length = length;
return sound; return sound;
} }
JA_Sound_t *JA_LoadSound(const char* filename) { JA_Sound_t *JA_LoadSound(const char *filename)
{
JA_Sound_t *sound = new JA_Sound_t(); JA_Sound_t *sound = new JA_Sound_t();
SDL_AudioSpec wavSpec; SDL_AudioSpec wavSpec;
SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length); SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
@@ -211,7 +248,7 @@ JA_Sound_t *JA_LoadSound(const char* filename) {
SDL_AudioCVT cvt; SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq); SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);
cvt.len = sound->length; cvt.len = sound->length;
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult); cvt.buf = (Uint8 *)SDL_malloc(cvt.len * cvt.len_mult);
SDL_memcpy(cvt.buf, sound->buffer, sound->length); SDL_memcpy(cvt.buf, sound->buffer, sound->length);
SDL_ConvertAudio(&cvt); SDL_ConvertAudio(&cvt);
SDL_FreeWAV(sound->buffer); SDL_FreeWAV(sound->buffer);
@@ -223,11 +260,16 @@ JA_Sound_t *JA_LoadSound(const char* filename) {
int JA_PlaySound(JA_Sound_t *sound, const int loop) int JA_PlaySound(JA_Sound_t *sound, const int loop)
{ {
if (!JA_soundEnabled || !sound) return 0; if (!JA_soundEnabled || !sound)
return 0;
int channel = 0; int channel = 0;
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; } while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE)
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0; {
channel++;
}
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS)
channel = 0;
channels[channel].sound = sound; channels[channel].sound = sound;
channels[channel].times = loop; channels[channel].times = loop;
@@ -238,8 +280,10 @@ int JA_PlaySound(JA_Sound_t *sound, const int loop)
void JA_DeleteSound(JA_Sound_t *sound) void JA_DeleteSound(JA_Sound_t *sound)
{ {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
if (channels[i].sound == sound) JA_StopChannel(i); {
if (channels[i].sound == sound)
JA_StopChannel(i);
} }
SDL_free(sound->buffer); SDL_free(sound->buffer);
delete sound; delete sound;
@@ -247,41 +291,60 @@ void JA_DeleteSound(JA_Sound_t *sound)
void JA_PauseChannel(const int channel) void JA_PauseChannel(const int channel)
{ {
if (!JA_soundEnabled) return; if (!JA_soundEnabled)
return;
if (channel == -1) { if (channel == -1)
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { {
if (channels[i].state == JA_CHANNEL_PLAYING) channels[i].state = JA_CHANNEL_PAUSED; for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
{
if (channels[i].state == JA_CHANNEL_PLAYING)
channels[i].state = JA_CHANNEL_PAUSED;
} }
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { }
if (channels[channel].state == JA_CHANNEL_PLAYING) channels[channel].state = JA_CHANNEL_PAUSED; else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
{
if (channels[channel].state == JA_CHANNEL_PLAYING)
channels[channel].state = JA_CHANNEL_PAUSED;
} }
} }
void JA_ResumeChannel(const int channel) void JA_ResumeChannel(const int channel)
{ {
if (!JA_soundEnabled) return; if (!JA_soundEnabled)
return;
if (channel == -1) { if (channel == -1)
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { {
if (channels[i].state == JA_CHANNEL_PAUSED) channels[i].state = JA_CHANNEL_PLAYING; for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
{
if (channels[i].state == JA_CHANNEL_PAUSED)
channels[i].state = JA_CHANNEL_PLAYING;
} }
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { }
if (channels[channel].state == JA_CHANNEL_PAUSED) channels[channel].state = JA_CHANNEL_PLAYING; else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
{
if (channels[channel].state == JA_CHANNEL_PAUSED)
channels[channel].state = JA_CHANNEL_PLAYING;
} }
} }
void JA_StopChannel(const int channel) void JA_StopChannel(const int channel)
{ {
if (!JA_soundEnabled) return; if (!JA_soundEnabled)
return;
if (channel == -1) { if (channel == -1)
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
{
channels[i].state = JA_CHANNEL_FREE; channels[i].state = JA_CHANNEL_FREE;
channels[i].pos = 0; channels[i].pos = 0;
channels[i].sound = NULL; channels[i].sound = NULL;
} }
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { }
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
{
channels[channel].state = JA_CHANNEL_FREE; channels[channel].state = JA_CHANNEL_FREE;
channels[channel].pos = 0; channels[channel].pos = 0;
channels[channel].sound = NULL; channels[channel].sound = NULL;
@@ -290,15 +353,18 @@ void JA_StopChannel(const int channel)
JA_Channel_state JA_GetChannelState(const int channel) JA_Channel_state JA_GetChannelState(const int channel)
{ {
if (!JA_soundEnabled) return JA_SOUND_DISABLED; if (!JA_soundEnabled)
return JA_SOUND_DISABLED;
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID; if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS)
return JA_CHANNEL_INVALID;
return channels[channel].state; return channels[channel].state;
} }
int JA_SetSoundVolume(int volume) int JA_SetSoundVolume(int volume)
{ {
JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0
: volume;
return JA_soundVolume; return JA_soundVolume;
} }
@@ -306,15 +372,17 @@ void JA_EnableSound(const bool value)
{ {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
{ {
if (channels[i].state == JA_CHANNEL_PLAYING) JA_StopChannel(i); if (channels[i].state == JA_CHANNEL_PLAYING)
JA_StopChannel(i);
} }
JA_soundEnabled = value; JA_soundEnabled = value;
} }
int JA_SetVolume(int volume) int JA_SetVolume(int volume)
{ {
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0
JA_soundVolume = JA_musicVolume/2; : volume;
JA_soundVolume = JA_musicVolume / 2;
return JA_musicVolume; return JA_musicVolume;
} }

View File

@@ -1,17 +1,31 @@
#pragma once #pragma once
#include <SDL2/SDL_audio.h> // for SDL_AudioFormat #include <SDL2/SDL_audio.h> // para SDL_AudioFormat
#include <SDL2/SDL_stdinc.h> // for Uint32, Uint8 #include <SDL2/SDL_stdinc.h> // para Uint32, Uint8
struct JA_Music_t; // lines 5-5 struct JA_Music_t; // lines 5-5
struct JA_Sound_t; // lines 6-6 struct JA_Sound_t; // lines 6-6
enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED, JA_SOUND_DISABLED }; enum JA_Channel_state
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED, JA_MUSIC_DISABLED }; {
JA_CHANNEL_INVALID,
JA_CHANNEL_FREE,
JA_CHANNEL_PLAYING,
JA_CHANNEL_PAUSED,
JA_SOUND_DISABLED
};
enum JA_Music_state
{
JA_MUSIC_INVALID,
JA_MUSIC_PLAYING,
JA_MUSIC_PAUSED,
JA_MUSIC_STOPPED,
JA_MUSIC_DISABLED
};
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels); void JA_Init(const int freq, const SDL_AudioFormat format, const int channels);
void JA_Quit(); void JA_Quit();
JA_Music_t *JA_LoadMusic(const char* filename); JA_Music_t *JA_LoadMusic(const char *filename);
void JA_PlayMusic(JA_Music_t *music, const int loop = -1); void JA_PlayMusic(JA_Music_t *music, const int loop = -1);
void JA_PauseMusic(); void JA_PauseMusic();
void JA_ResumeMusic(); void JA_ResumeMusic();
@@ -21,8 +35,8 @@ void JA_DeleteMusic(JA_Music_t *music);
int JA_SetMusicVolume(int volume); int JA_SetMusicVolume(int volume);
void JA_EnableMusic(const bool value); void JA_EnableMusic(const bool value);
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length); JA_Sound_t *JA_NewSound(Uint8 *buffer, Uint32 length);
JA_Sound_t *JA_LoadSound(const char* filename); JA_Sound_t *JA_LoadSound(const char *filename);
int JA_PlaySound(JA_Sound_t *sound, const int loop = 0); int JA_PlaySound(JA_Sound_t *sound, const int loop = 0);
void JA_PauseChannel(const int channel); void JA_PauseChannel(const int channel);
void JA_ResumeChannel(const int channel); void JA_ResumeChannel(const int channel);

View File

@@ -1,10 +1,10 @@
#ifndef NO_SHADERS #ifndef NO_SHADERS
#include "jail_shader.h" #include "jail_shader.h"
#include <SDL2/SDL_rect.h> // for SDL_Point #include <SDL2/SDL_rect.h> // para SDL_Point
#include <stdlib.h> // for NULL, free, malloc, exit #include <stdlib.h> // para NULL, free, malloc, exit
#include <string.h> // for strncmp #include <string.h> // para strncmp
#include <iostream> // for basic_ostream, char_traits, operator<< #include <iostream> // para basic_ostream, char_traits, operator<<
#ifdef __APPLE__ #ifdef __APPLE__
#include "CoreFoundation/CoreFoundation.h" #include "CoreFoundation/CoreFoundation.h"
@@ -14,7 +14,7 @@
#include <OpenGL/gl3.h> #include <OpenGL/gl3.h>
#else #else
#include <OpenGL/gl.h> #include <OpenGL/gl.h>
#endif //!ESSENTIAL_GL_PRACTICES_SUPPORT_GL3 #endif //! ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
#else #else
#include <SDL2/SDL_opengl.h> #include <SDL2/SDL_opengl.h>
#endif #endif
@@ -24,14 +24,14 @@ namespace shader
SDL_Window *win = nullptr; SDL_Window *win = nullptr;
SDL_Renderer *renderer = nullptr; SDL_Renderer *renderer = nullptr;
GLuint programId = 0; GLuint programId = 0;
SDL_Texture* backBuffer = nullptr; SDL_Texture *backBuffer = nullptr;
SDL_Point win_size = {320*4, 256*4}; SDL_Point win_size = {320 * 4, 256 * 4};
SDL_Point tex_size = {320, 256}; SDL_Point tex_size = {320, 256};
bool usingOpenGL; bool usingOpenGL;
#ifndef __APPLE__ #ifndef __APPLE__
// I'm avoiding the use of GLEW or some extensions handler, but that // I'm avoiding the use of GLEW or some extensions handler, but that
// doesn't mean you should... // doesn't mean you should...
PFNGLCREATESHADERPROC glCreateShader; PFNGLCREATESHADERPROC glCreateShader;
PFNGLSHADERSOURCEPROC glShaderSource; PFNGLSHADERSOURCEPROC glShaderSource;
@@ -47,7 +47,8 @@ namespace shader
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
PFNGLUSEPROGRAMPROC glUseProgram; PFNGLUSEPROGRAMPROC glUseProgram;
bool initGLExtensions() { bool initGLExtensions()
{
glCreateShader = (PFNGLCREATESHADERPROC)SDL_GL_GetProcAddress("glCreateShader"); glCreateShader = (PFNGLCREATESHADERPROC)SDL_GL_GetProcAddress("glCreateShader");
glShaderSource = (PFNGLSHADERSOURCEPROC)SDL_GL_GetProcAddress("glShaderSource"); glShaderSource = (PFNGLSHADERSOURCEPROC)SDL_GL_GetProcAddress("glShaderSource");
glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader"); glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader");
@@ -62,56 +63,60 @@ namespace shader
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)SDL_GL_GetProcAddress("glGetProgramInfoLog"); glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)SDL_GL_GetProcAddress("glGetProgramInfoLog");
glUseProgram = (PFNGLUSEPROGRAMPROC)SDL_GL_GetProcAddress("glUseProgram"); glUseProgram = (PFNGLUSEPROGRAMPROC)SDL_GL_GetProcAddress("glUseProgram");
return glCreateShader && glShaderSource && glCompileShader && glGetShaderiv && return glCreateShader && glShaderSource && glCompileShader && glGetShaderiv &&
glGetShaderInfoLog && glDeleteShader && glAttachShader && glCreateProgram && glGetShaderInfoLog && glDeleteShader && glAttachShader && glCreateProgram &&
glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog && glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog &&
glUseProgram; glUseProgram;
} }
#endif #endif
GLuint compileShader(const char* source, GLuint shaderType) { GLuint compileShader(const char *source, GLuint shaderType)
{
// Create ID for shader // Create ID for shader
GLuint result = glCreateShader(shaderType); GLuint result = glCreateShader(shaderType);
// Add define depending on shader type // Add define depending on shader type
const char *sources[2] = { shaderType==GL_VERTEX_SHADER?"#define VERTEX\n":"#define FRAGMENT\n", source }; const char *sources[2] = {shaderType == GL_VERTEX_SHADER ? "#define VERTEX\n" : "#define FRAGMENT\n", source};
// Define shader text // Define shader text
glShaderSource(result, 2, sources, NULL); glShaderSource(result, 2, sources, NULL);
// Compile shader // Compile shader
glCompileShader(result); glCompileShader(result);
//Check vertex shader for errors // Check vertex shader for errors
GLint shaderCompiled = GL_FALSE; GLint shaderCompiled = GL_FALSE;
glGetShaderiv( result, GL_COMPILE_STATUS, &shaderCompiled ); glGetShaderiv(result, GL_COMPILE_STATUS, &shaderCompiled);
if( shaderCompiled != GL_TRUE ) { if (shaderCompiled != GL_TRUE)
{
std::cout << "Error en la compilación: " << result << "!" << std::endl; std::cout << "Error en la compilación: " << result << "!" << std::endl;
GLint logLength; GLint logLength;
glGetShaderiv(result, GL_INFO_LOG_LENGTH, &logLength); glGetShaderiv(result, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) if (logLength > 0)
{ {
GLchar *log = (GLchar*)malloc(logLength); GLchar *log = (GLchar *)malloc(logLength);
glGetShaderInfoLog(result, logLength, &logLength, log); glGetShaderInfoLog(result, logLength, &logLength, log);
std::cout << "Shader compile log:" << log << std::endl; std::cout << "Shader compile log:" << log << std::endl;
free(log); free(log);
} }
glDeleteShader(result); glDeleteShader(result);
result = 0; result = 0;
// } else { // } else {
// std::cout << "Shader compilado correctamente. Id = " << result << std::endl; // std::cout << "Shader compilado correctamente. Id = " << result << std::endl;
} }
return result; return result;
} }
GLuint compileProgram(const char* vertexShaderSource, const char* fragmentShaderSource) { GLuint compileProgram(const char *vertexShaderSource, const char *fragmentShaderSource)
{
GLuint programId = 0; GLuint programId = 0;
GLuint vtxShaderId, fragShaderId; GLuint vtxShaderId, fragShaderId;
programId = glCreateProgram(); programId = glCreateProgram();
vtxShaderId = compileShader(vertexShaderSource, GL_VERTEX_SHADER); vtxShaderId = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
fragShaderId = compileShader(fragmentShaderSource?fragmentShaderSource:vertexShaderSource, GL_FRAGMENT_SHADER); fragShaderId = compileShader(fragmentShaderSource ? fragmentShaderSource : vertexShaderSource, GL_FRAGMENT_SHADER);
if(vtxShaderId && fragShaderId) { if (vtxShaderId && fragShaderId)
{
// Associate shader with program // Associate shader with program
glAttachShader(programId, vtxShaderId); glAttachShader(programId, vtxShaderId);
glAttachShader(programId, fragShaderId); glAttachShader(programId, fragShaderId);
@@ -121,24 +126,28 @@ namespace shader
// Check the status of the compile/link // Check the status of the compile/link
GLint logLen; GLint logLen;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen); glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen);
if(logLen > 0) { if (logLen > 0)
char* log = (char*) malloc(logLen * sizeof(char)); {
char *log = (char *)malloc(logLen * sizeof(char));
// Show any errors as appropriate // Show any errors as appropriate
glGetProgramInfoLog(programId, logLen, &logLen, log); glGetProgramInfoLog(programId, logLen, &logLen, log);
std::cout << "Prog Info Log: " << std::endl << log << std::endl; std::cout << "Prog Info Log: " << std::endl
<< log << std::endl;
free(log); free(log);
} }
} }
if(vtxShaderId) { if (vtxShaderId)
{
glDeleteShader(vtxShaderId); glDeleteShader(vtxShaderId);
} }
if(fragShaderId) { if (fragShaderId)
{
glDeleteShader(fragShaderId); glDeleteShader(fragShaderId);
} }
return programId; return programId;
} }
const bool init(SDL_Window* win, SDL_Texture* backBuffer, const char* vertexShader, const char* fragmentShader) const bool init(SDL_Window *win, SDL_Texture *backBuffer, const char *vertexShader, const char *fragmentShader)
{ {
shader::win = win; shader::win = win;
shader::renderer = SDL_GetRenderer(win); shader::renderer = SDL_GetRenderer(win);
@@ -155,19 +164,23 @@ namespace shader
SDL_RendererInfo rendererInfo; SDL_RendererInfo rendererInfo;
SDL_GetRendererInfo(renderer, &rendererInfo); SDL_GetRendererInfo(renderer, &rendererInfo);
if(!strncmp(rendererInfo.name, "opengl", 6)) { if (!strncmp(rendererInfo.name, "opengl", 6))
//std::cout << "Es OpenGL!" << std::endl; {
#ifndef __APPLE__ // std::cout << "Es OpenGL!" << std::endl;
if (!initGLExtensions()) { #ifndef __APPLE__
if (!initGLExtensions())
{
std::cout << "WARNING: No s'han pogut inicialitzar les extensions d'OpenGL!" << std::endl; std::cout << "WARNING: No s'han pogut inicialitzar les extensions d'OpenGL!" << std::endl;
usingOpenGL = false; usingOpenGL = false;
return false; return false;
} }
#endif #endif
// Compilar el shader y dejarlo listo para usar. // Compilar el shader y dejarlo listo para usar.
programId = compileProgram(vertexShader, fragmentShader); programId = compileProgram(vertexShader, fragmentShader);
//std::cout << "programId = " << programId << std::endl; // std::cout << "programId = " << programId << std::endl;
} else { }
else
{
std::cout << "WARNING: El driver del renderer no es OpenGL." << std::endl; std::cout << "WARNING: El driver del renderer no es OpenGL." << std::endl;
usingOpenGL = false; usingOpenGL = false;
return false; return false;
@@ -180,19 +193,21 @@ namespace shader
{ {
GLint oldProgramId; GLint oldProgramId;
// Guarrada para obtener el textureid (en driverdata->texture) // Guarrada para obtener el textureid (en driverdata->texture)
//Detach the texture // Detach the texture
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_SetRenderTarget(renderer, NULL); SDL_SetRenderTarget(renderer, NULL);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
if (usingOpenGL) { if (usingOpenGL)
{
SDL_GL_BindTexture(backBuffer, NULL, NULL); SDL_GL_BindTexture(backBuffer, NULL, NULL);
if(programId != 0) { if (programId != 0)
glGetIntegerv(GL_CURRENT_PROGRAM,&oldProgramId); {
glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgramId);
glUseProgram(programId); glUseProgram(programId);
} }
GLfloat minx, miny, maxx, maxy; GLfloat minx, miny, maxx, maxy;
GLfloat minu, maxu, minv, maxv; GLfloat minu, maxu, minv, maxv;
@@ -210,21 +225,24 @@ namespace shader
glViewport(0, 0, win_size.x, win_size.y); glViewport(0, 0, win_size.x, win_size.y);
glBegin(GL_TRIANGLE_STRIP); glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(minu, minv); glTexCoord2f(minu, minv);
glVertex2f(minx, miny); glVertex2f(minx, miny);
glTexCoord2f(maxu, minv); glTexCoord2f(maxu, minv);
glVertex2f(maxx, miny); glVertex2f(maxx, miny);
glTexCoord2f(minu, maxv); glTexCoord2f(minu, maxv);
glVertex2f(minx, maxy); glVertex2f(minx, maxy);
glTexCoord2f(maxu, maxv); glTexCoord2f(maxu, maxv);
glVertex2f(maxx, maxy); glVertex2f(maxx, maxy);
glEnd(); glEnd();
SDL_GL_SwapWindow(win); SDL_GL_SwapWindow(win);
if(programId != 0) { if (programId != 0)
{
glUseProgram(oldProgramId); glUseProgram(oldProgramId);
} }
} else { }
else
{
SDL_RenderCopy(renderer, backBuffer, NULL, NULL); SDL_RenderCopy(renderer, backBuffer, NULL, NULL);
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }

View File

@@ -2,8 +2,8 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Texture #include <SDL2/SDL_render.h> // para SDL_Texture
#include <SDL2/SDL_video.h> // for SDL_Window #include <SDL2/SDL_video.h> // para SDL_Window
// TIPS: // TIPS:
// ======================================================================= // =======================================================================
@@ -27,7 +27,7 @@
// Els shaders li'ls passem com una cadena, som nosaltres els que s'encarreguem // Els shaders li'ls passem com una cadena, som nosaltres els que s'encarreguem
// de carregarlos de disc, amb fopen, ifstream, jfile o el que vullgues. // de carregarlos de disc, amb fopen, ifstream, jfile o el que vullgues.
// Si els tens en un std::string, passa-li-la com "cadena.c_str()". // Si els tens en un std::string, passa-li-la com "cadena.c_str()".
// //
// Poden ser els dos el mateix arxiu, com fa libRetro, jo desde dins ja fique // Poden ser els dos el mateix arxiu, com fa libRetro, jo desde dins ja fique
// els defines necessaris. Si es el mateix arxiu, pots no ficar el quart paràmetre. // els defines necessaris. Si es el mateix arxiu, pots no ficar el quart paràmetre.
// //
@@ -40,8 +40,8 @@
namespace shader namespace shader
{ {
const bool init(SDL_Window* win, SDL_Texture* backBuffer, const bool init(SDL_Window *win, SDL_Texture *backBuffer,
const char* vertexShader, const char* fragmentShader=nullptr); const char *vertexShader, const char *fragmentShader = nullptr);
void render(); void render();
} }

View File

@@ -1,11 +1,11 @@
#include "lang.h" #include "lang.h"
#include <fstream> // for basic_ifstream, basic_istream, ifstream #include <fstream> // para basic_ifstream, basic_istream, ifstream
#include <vector> // for vector #include <vector> // para vector
namespace lang namespace lang
{ {
std::vector<std::string> texts; // Vector con los textos std::vector<std::string> texts; // Vector con los textos
// Inicializa los textos del juego en el idioma seleccionado // Inicializa los textos del juego en el idioma seleccionado
bool loadFromFile(std::string file_path) bool loadFromFile(std::string file_path)
{ {

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <string> // for string #include <string> // para string
namespace lang namespace lang
{ {

View File

@@ -1,31 +1,29 @@
#include "logo.h" #include "logo.h"
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_QUIT, SDL... #include <SDL2/SDL_events.h> // Para SDL_PollEvent, SDL_Event, SDL_QUIT, SDL...
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_timer.h> // Para SDL_GetTicks
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_video.h> // Para SDL_WINDOWEVENT_SIZE_CHANGED
#include <SDL2/SDL_video.h> // for SDL_WINDOWEVENT_SIZE_CHANGED #include <utility> // Para move
#include <utility> // for move #include "global_inputs.h" // Para check
#include "asset.h" // for Asset #include "input.h" // Para Input
#include "global_inputs.h" // for check #include "jail_audio.h" // Para JA_StopMusic
#include "input.h" // for Input #include "param.h" // Para Param, ParamGame, param
#include "jail_audio.h" // for JA_StopMusic #include "resource.h" // Para Resource
#include "param.h" // for param #include "screen.h" // Para Screen
#include "resource.h" // for Resource #include "section.h" // Para Name, name, Options, options
#include "screen.h" // for Screen #include "sprite.h" // Para Sprite
#include "section.h" // for Name, name, Options, options #include "texture.h" // Para Texture
#include "sprite.h" // for Sprite
#include "texture.h" // for Texture
// Constructor // Constructor
Logo::Logo() Logo::Logo()
: since_texture_(Resource::get()->getTexture("logo_since_1998.png")), : since_texture_(Resource::get()->getTexture("logo_since_1998.png")),
since_sprite_(std::make_unique<Sprite>(since_texture_)), since_sprite_(std::make_unique<Sprite>(since_texture_)),
jail_texture_(Resource::get()->getTexture("logo_jailgames.png")) jail_texture_(Resource::get()->getTexture("logo_jailgames.png")),
ticks_(0)
{ {
// Inicializa variables // Inicializa variables
counter_ = 0; counter_ = 0;
section::name = section::Name::LOGO; section::name = section::Name::LOGO;
ticks_ = 0;
dest_.x = param.game.game_area.center_x - jail_texture_->getWidth() / 2; dest_.x = param.game.game_area.center_x - jail_texture_->getWidth() / 2;
dest_.y = param.game.game_area.center_y - jail_texture_->getHeight() / 2; dest_.y = param.game.game_area.center_y - jail_texture_->getHeight() / 2;
since_sprite_->setPosition({(param.game.width - since_texture_->getWidth()) / 2, 83 + jail_texture_->getHeight() + 5, since_texture_->getWidth(), since_texture_->getHeight()}); since_sprite_->setPosition({(param.game.width - since_texture_->getWidth()) / 2, 83 + jail_texture_->getHeight() + 5, since_texture_->getWidth(), since_texture_->getHeight()});
@@ -45,14 +43,14 @@ Logo::Logo()
} }
// Inicializa el vector de colores // Inicializa el vector de colores
color_.push_back({0x00, 0x00, 0x00}); // Black color_.push_back(Color(0x00, 0x00, 0x00)); // Black
color_.push_back({0x00, 0x00, 0xd8}); // Blue color_.push_back(Color(0x00, 0x00, 0xd8)); // Blue
color_.push_back({0xd8, 0x00, 0x00}); // Red color_.push_back(Color(0xd8, 0x00, 0x00)); // Red
color_.push_back({0xd8, 0x00, 0xd8}); // Magenta color_.push_back(Color(0xd8, 0x00, 0xd8)); // Magenta
color_.push_back({0x00, 0xd8, 0x00}); // Green color_.push_back(Color(0x00, 0xd8, 0x00)); // Green
color_.push_back({0x00, 0xd8, 0xd8}); // Cyan color_.push_back(Color(0x00, 0xd8, 0xd8)); // Cyan
color_.push_back({0xd8, 0xd8, 0x00}); // Yellow color_.push_back(Color(0xd8, 0xd8, 0x00)); // Yellow
color_.push_back({0xFF, 0xFF, 0xFF}); // Bright white color_.push_back(Color(0xFF, 0xFF, 0xFF)); // Bright white
} }
// Recarga todas las texturas // Recarga todas las texturas
@@ -73,6 +71,7 @@ void Logo::checkEvents()
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
section::name = section::Name::QUIT; section::name = section::Name::QUIT;
section::options = section::Options::QUIT_FROM_EVENT;
break; break;
} }
@@ -164,7 +163,8 @@ void Logo::updateTextureColors()
// Actualiza las variables // Actualiza las variables
void Logo::update() void Logo::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego constexpr int TICKS_SPEED = 15;
if (SDL_GetTicks() - ticks_ > TICKS_SPEED) if (SDL_GetTicks() - ticks_ > TICKS_SPEED)
{ {
// Actualiza el contador de ticks // Actualiza el contador de ticks

View File

@@ -1,11 +1,11 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Point #include <SDL2/SDL_rect.h> // para SDL_Point
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // para Uint32
#include <memory> // for unique_ptr, shared_ptr #include <memory> // para unique_ptr, shared_ptr
#include <vector> // for vector #include <vector> // para vector
#include "sprite.h" // for Sprite #include "sprite.h" // para Sprite
#include "utils.h" // for Color #include "utils.h" // para Color
class Texture; class Texture;
/* /*
@@ -21,13 +21,12 @@ class Logo
{ {
private: private:
// Constantes // Constantes
static constexpr Uint32 TICKS_SPEED = 15; // Velocidad a la que se repiten los bucles del programa
static constexpr int SHOW_SINCE_SPRITE_COUNTER_MARK = 70; // Tiempo del contador en el que empieza a verse el sprite de "SINCE 1998" static constexpr int SHOW_SINCE_SPRITE_COUNTER_MARK = 70; // Tiempo del contador en el que empieza a verse el sprite de "SINCE 1998"
static constexpr int INIT_FADE_COUNTER_MARK = 300; // Tiempo del contador cuando inicia el fade a negro static constexpr int INIT_FADE_COUNTER_MARK = 300; // Tiempo del contador cuando inicia el fade a negro
static constexpr int END_LOGO_COUNTER_MARK = 400; // Tiempo del contador para terminar el logo static constexpr int END_LOGO_COUNTER_MARK = 400; // Tiempo del contador para terminar el logo
static constexpr int POST_LOGO_DURATION = 20; // Tiempo que dura el logo con el fade al maximo static constexpr int POST_LOGO_DURATION = 20; // Tiempo que dura el logo con el fade al maximo
static constexpr int SPEED = 8; // Velocidad de desplazamiento de cada linea static constexpr int SPEED = 8; // Velocidad de desplazamiento de cada linea
// Objetos y punteros // Objetos y punteros
std::shared_ptr<Texture> since_texture_; // Textura con los graficos "Since 1998" std::shared_ptr<Texture> since_texture_; // Textura con los graficos "Since 1998"
std::unique_ptr<Sprite> since_sprite_; // Sprite para manejar la sinceTexture std::unique_ptr<Sprite> since_sprite_; // Sprite para manejar la sinceTexture

View File

@@ -7,9 +7,8 @@ Actualizando a la versión "Arcade Edition" en 08/05/2024
*/ */
#include <iostream> // for char_traits, basic_ostream, operator<<, cout #include <memory> // Para make_unique, unique_ptr
#include <memory> // for make_unique, unique_ptr #include "director.h" // Para Director
#include "director.h" // for Director
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {

View File

@@ -1,48 +1,40 @@
#include "manage_hiscore_table.h" #include "manage_hiscore_table.h"
#include <SDL2/SDL_error.h> // for SDL_GetError #include <SDL2/SDL_error.h> // Para SDL_GetError
#include <SDL2/SDL_rwops.h> // for SDL_RWread, SDL_RWwrite, SDL_RWFromFile #include <SDL2/SDL_rwops.h> // Para SDL_RWread, SDL_RWwrite, SDL_RWFromFile
#include <stdlib.h> // for free, malloc #include <algorithm> // Para sort
#include <algorithm> // for sort #include <iostream> // Para basic_ostream, operator<<, cout, endl
#include <iostream> // for basic_ostream, char_traits, operator<< #include "utils.h" // Para HiScoreEntry, getFileName
#include "utils.h" // for HiScoreEntry
// Constructor
ManageHiScoreTable::ManageHiScoreTable(std::vector<HiScoreEntry> *table)
: table_(table) {}
// Resetea la tabla a los valores por defecto // Resetea la tabla a los valores por defecto
void ManageHiScoreTable::clear() void ManageHiScoreTable::clear()
{ {
// Limpia la tabla // Limpia la tabla
table_->clear(); table_.clear();
// Añade 10 entradas predefinidas // Añade 10 entradas predefinidas
table_->push_back({"Bry", 1000000}); table_.push_back(HiScoreEntry("Bry", 1000000));
table_->push_back({"Usufondo", 500000}); table_.push_back(HiScoreEntry("Usufondo", 500000));
table_->push_back({"G.Lucas", 100000}); table_.push_back(HiScoreEntry("G.Lucas", 100000));
table_->push_back({"P.Delgat", 50000}); table_.push_back(HiScoreEntry("P.Delgat", 50000));
table_->push_back({"P.Arrabalera", 10000}); table_.push_back(HiScoreEntry("P.Arrabalera", 10000));
table_->push_back({"Pelechano", 5000}); table_.push_back(HiScoreEntry("Pelechano", 5000));
table_->push_back({"Sahuquillo", 1000}); table_.push_back(HiScoreEntry("Sahuquillo", 1000));
table_->push_back({"Bacteriol", 500}); table_.push_back(HiScoreEntry("Bacteriol", 500));
table_->push_back({"Pepe", 200}); table_.push_back(HiScoreEntry("Pepe", 200));
table_->push_back({"Rosita", 100}); table_.push_back(HiScoreEntry("Rosita", 100));
} }
// Añade un elemento a la tabla // Añade un elemento a la tabla
void ManageHiScoreTable::add(HiScoreEntry entry) void ManageHiScoreTable::add(HiScoreEntry entry)
{ {
// Añade la entrada a la tabla // Añade la entrada a la tabla
table_->push_back(entry); table_.push_back(entry);
// Ordena la tabla // Ordena la tabla
sort(); sort();
// Deja solo las 10 primeras entradas // Deja solo las 10 primeras entradas
if (static_cast<int>(table_->size()) > 10) table_.resize(10);
{
table_->resize(10);
}
} }
// Ordena la tabla // Ordena la tabla
@@ -51,28 +43,27 @@ void ManageHiScoreTable::sort()
struct struct
{ {
bool operator()(const HiScoreEntry &a, const HiScoreEntry &b) const { return a.score > b.score; } bool operator()(const HiScoreEntry &a, const HiScoreEntry &b) const { return a.score > b.score; }
} custom_less; } scoreDescendingComparator;
std::sort(table_->begin(), table_->end(), custom_less); std::sort(table_.begin(), table_.end(), scoreDescendingComparator);
} }
// Carga la tabla con los datos de un fichero // Carga la tabla con los datos de un fichero
bool ManageHiScoreTable::loadFromFile(const std::string &file_path) bool ManageHiScoreTable::loadFromFile(const std::string &file_path)
{ {
clear(); clear();
auto success = true; auto success = true;
auto file = SDL_RWFromFile(file_path.c_str(), "r+b"); auto file = SDL_RWFromFile(file_path.c_str(), "r+b");
if (file) if (file)
{ {
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1); std::cout << "Reading file: " << getFileName(file_path) << std::endl;
std::cout << "Reading file: " << file_name.c_str() << std::endl;
for (int i = 0; i < (int)table_->size(); ++i) for (auto &entry : table_)
{ {
int nameSize = 0; int nameSize = 0;
if (SDL_RWread(file, &table_->at(i).score, sizeof(int), 1) == 0) if (SDL_RWread(file, &entry.score, sizeof(int), 1) == 0)
{ {
success = false; success = false;
break; break;
@@ -84,19 +75,15 @@ bool ManageHiScoreTable::loadFromFile(const std::string &file_path)
break; break;
} }
char *name = static_cast<char *>(malloc(nameSize + 1)); std::vector<char> nameBuffer(nameSize + 1);
if (SDL_RWread(file, name, sizeof(char) * nameSize, 1) == 0) if (SDL_RWread(file, nameBuffer.data(), sizeof(char) * nameSize, 1) == 0)
{ {
success = false; success = false;
free(name);
break; break;
} }
else
{ nameBuffer[nameSize] = '\0';
name[nameSize] = 0; entry.name = std::string(nameBuffer.data());
table_->at(i).name = name;
free(name);
}
} }
SDL_RWclose(file); SDL_RWclose(file);
@@ -113,28 +100,26 @@ bool ManageHiScoreTable::loadFromFile(const std::string &file_path)
// Guarda la tabla en un fichero // Guarda la tabla en un fichero
bool ManageHiScoreTable::saveToFile(const std::string &file_path) bool ManageHiScoreTable::saveToFile(const std::string &file_path)
{ {
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1);
auto success = true; auto success = true;
auto file = SDL_RWFromFile(file_path.c_str(), "w+b"); auto file = SDL_RWFromFile(file_path.c_str(), "w+b");
if (file) if (file)
{ {
// Guarda los datos // Guarda los datos
for (int i = 0; i < (int)table_->size(); ++i) for (int i = 0; i < (int)table_.size(); ++i)
{ {
SDL_RWwrite(file, &table_->at(i).score, sizeof(int), 1); SDL_RWwrite(file, &table_.at(i).score, sizeof(int), 1);
const int nameSize = (int)table_->at(i).name.size(); const int nameSize = (int)table_.at(i).name.size();
SDL_RWwrite(file, &nameSize, sizeof(int), 1); SDL_RWwrite(file, &nameSize, sizeof(int), 1);
SDL_RWwrite(file, table_->at(i).name.c_str(), nameSize, 1); SDL_RWwrite(file, table_.at(i).name.c_str(), nameSize, 1);
} }
std::cout << "Writing file: " << file_name.c_str() << std::endl; std::cout << "Writing file: " << getFileName(file_path).c_str() << std::endl;
// Cierra el fichero
SDL_RWclose(file); SDL_RWclose(file);
} }
else else
{ {
std::cout << "Error: Unable to save " << file_name.c_str() << " file! " << SDL_GetError() << std::endl; std::cout << "Error: Unable to save " << getFileName(file_path).c_str() << " file! " << SDL_GetError() << std::endl;
} }
return success; return success;
} }

View File

@@ -1,8 +1,7 @@
#pragma once #pragma once
#include <string> // for string #include <string> // para string
#include <vector> // for vector #include <vector> // para vector
struct HiScoreEntry;
/* /*
Esta clase sirve para añadir elementos hiScoreEntry_r a un vector (tabla), de manera Esta clase sirve para añadir elementos hiScoreEntry_r a un vector (tabla), de manera
@@ -12,19 +11,31 @@ struct HiScoreEntry;
leer y escribir la tabla a un fichero leer y escribir la tabla a un fichero
*/ */
// Estructura para las entradas de la tabla de recirds
struct HiScoreEntry
{
std::string name; // Nombre
int score; // Puntuación
// Constructor
explicit HiScoreEntry(const std::string &n = "", int s = 0)
: name(n), score(s) {}
};
// Clase ManageHiScoreTable // Clase ManageHiScoreTable
class ManageHiScoreTable class ManageHiScoreTable
{ {
private: private:
// Variables // Variables
std::vector<HiScoreEntry> *table_; // Tabla con los records std::vector<HiScoreEntry> &table_; // Tabla con los records
// Ordena la tabla // Ordena la tabla
void sort(); void sort();
public: public:
// Constructor // Constructor
explicit ManageHiScoreTable(std::vector<HiScoreEntry> *table); explicit ManageHiScoreTable(std::vector<HiScoreEntry> &table)
: table_(table) {}
// Destructor // Destructor
~ManageHiScoreTable() = default; ~ManageHiScoreTable() = default;

View File

@@ -1,15 +1,12 @@
#include "moving_sprite.h" #include "moving_sprite.h"
#include "texture.h" // for Texture #include <algorithm> // Para max
#include "texture.h" // Para Texture
// Constructor // Constructor
MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_Rect pos, Rotate rotate, float zoom_w, float zoom_h, SDL_RendererFlip flip) MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_Rect pos, Rotate rotate, float zoom_w, float zoom_h, SDL_RendererFlip flip)
: Sprite(texture, pos), : Sprite(texture, pos),
x_(pos.x), x_(pos.x),
y_(pos.y), y_(pos.y),
vx_(0.0f),
vy_(0.0f),
ax_(0.0f),
ay_(0.0f),
rotate_(rotate), rotate_(rotate),
zoom_w_(zoom_w), zoom_w_(zoom_w),
zoom_h_(zoom_h), zoom_h_(zoom_h),
@@ -19,10 +16,6 @@ MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_Rect pos)
: Sprite(texture, pos), : Sprite(texture, pos),
x_(pos.x), x_(pos.x),
y_(pos.y), y_(pos.y),
vx_(0.0f),
vy_(0.0f),
ax_(0.0f),
ay_(0.0f),
rotate_(Rotate()), rotate_(Rotate()),
zoom_w_(1.0f), zoom_w_(1.0f),
zoom_h_(1.0f), zoom_h_(1.0f),
@@ -32,10 +25,6 @@ MovingSprite::MovingSprite(std::shared_ptr<Texture> texture)
: Sprite(texture), : Sprite(texture),
x_(0.0f), x_(0.0f),
y_(0.0f), y_(0.0f),
vx_(0.0f),
vy_(0.0f),
ax_(0.0f),
ay_(0.0f),
rotate_(Rotate()), rotate_(Rotate()),
zoom_w_(1.0f), zoom_w_(1.0f),
zoom_h_(1.0f), zoom_h_(1.0f),
@@ -89,24 +78,6 @@ void MovingSprite::render()
texture_->render(pos_.x, pos_.y, &sprite_clip_, zoom_w_, zoom_h_, rotate_.angle, rotate_.center, flip_); texture_->render(pos_.x, pos_.y, &sprite_clip_, zoom_w_, zoom_h_, rotate_.angle, rotate_.center, flip_);
} }
// Obtiene el valor de la variable
float MovingSprite::getZoomW() const
{
return zoom_w_;
}
// Obtiene el valor de la variable
float MovingSprite::getZoomH() const
{
return zoom_h_;
}
// Obtiene el valor de la variable
double MovingSprite::getAngle() const
{
return rotate_.angle;
}
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setZoomW(float value) void MovingSprite::setZoomW(float value)
{ {
@@ -137,12 +108,6 @@ bool MovingSprite::isRotating() const
return rotate_.enabled; return rotate_.enabled;
} }
// Obtiene el valor de la variable
int MovingSprite::getRotateSpeed() const
{
return rotate_.speed;
}
// Establece la rotacion // Establece la rotacion
void MovingSprite::rotate() void MovingSprite::rotate()
{ {

View File

@@ -1,11 +1,10 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point #include <SDL2/SDL_rect.h> // Para SDL_Rect, SDL_Point
#include <SDL2/SDL_render.h> // for SDL_RendererFlip #include <SDL2/SDL_render.h> // Para SDL_RendererFlip
#include <SDL2/SDL_stdinc.h> // for Uint16 #include <memory> // Para shared_ptr
#include <memory> // for shared_ptr #include "sprite.h" // Para Sprite
#include "sprite.h" // for Sprite class Texture; // lines 8-8
class Texture;
// Clase MovingSprite. Añade movimiento y efectos de rotación, zoom y flip al sprite // Clase MovingSprite. Añade movimiento y efectos de rotación, zoom y flip al sprite
class MovingSprite : public Sprite class MovingSprite : public Sprite
@@ -27,11 +26,11 @@ protected:
float x_; // Posición en el eje X float x_; // Posición en el eje X
float y_; // Posición en el eje Y float y_; // Posición en el eje Y
float vx_; // Velocidad en el eje X. Cantidad de pixeles a desplazarse float vx_ = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
float vy_; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse float vy_ = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
float ax_; // Aceleración en el eje X. Variación de la velocidad float ax_ = 0.0f; // Aceleración en el eje X. Variación de la velocidad
float ay_; // Aceleración en el eje Y. Variación de la velocidad float ay_ = 0.0f; // Aceleración en el eje Y. Variación de la velocidad
Rotate rotate_; // Variables usada para controlar la rotación del sprite Rotate rotate_; // Variables usada para controlar la rotación del sprite
float zoom_w_; // Zoom aplicado a la anchura float zoom_w_; // Zoom aplicado a la anchura
@@ -54,7 +53,7 @@ public:
explicit MovingSprite(std::shared_ptr<Texture> texture); explicit MovingSprite(std::shared_ptr<Texture> texture);
// Destructor // Destructor
~MovingSprite() = default; virtual ~MovingSprite() = default;
// Actualiza las variables internas del objeto // Actualiza las variables internas del objeto
virtual void update(); virtual void update();
@@ -79,14 +78,8 @@ public:
void setAccelX(float value); void setAccelX(float value);
void setAccelY(float value); void setAccelY(float value);
// Obten el valor de la variable
float getZoomW() const;
float getZoomH() const;
// Obten el valor de la variable // Obten el valor de la variable
bool isRotating() const; bool isRotating() const;
double getAngle() const;
int getRotateSpeed() const;
// Establece el valor de la variable // Establece el valor de la variable
void setZoomW(float value); void setZoomW(float value);

View File

@@ -1,20 +1,19 @@
#include "notifier.h" #include "notifier.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
#include <string> // for string #include <string> // Para string
#include "jail_audio.h" // for JA_DeleteSound, JA_LoadSound, JA_Pla... #include "jail_audio.h" // Para JA_DeleteSound, JA_LoadSound, JA_Pla...
#include "param.h" // for param #include "param.h" // Para Param, param, ParamNotification, Par...
#include "resource.h" // for Resource #include "screen.h" // Para Screen
#include "screen.h" // for Screen #include "sprite.h" // Para Sprite
#include "sprite.h" // for Sprite #include "text.h" // Para Text
#include "text.h" // for Text #include "texture.h" // Para Texture
#include "texture.h" // for Texture
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
Notifier *Notifier::notifier_ = nullptr; Notifier *Notifier::notifier_ = nullptr;
// [SINGLETON] Crearemos el objeto screen con esta función estática // [SINGLETON] Crearemos el objeto screen con esta función estática
void Notifier::init(std::string icon_file, std::shared_ptr<Text> text, const std::string &sound_file) void Notifier::init(const std::string &icon_file, std::shared_ptr<Text> text, const std::string &sound_file)
{ {
Notifier::notifier_ = new Notifier(icon_file, text, sound_file); Notifier::notifier_ = new Notifier(icon_file, text, sound_file);
} }
@@ -34,35 +33,25 @@ Notifier *Notifier::get()
// Constructor // Constructor
Notifier::Notifier(std::string icon_file, std::shared_ptr<Text> text, const std::string &sound_file) Notifier::Notifier(std::string icon_file, std::shared_ptr<Text> text, const std::string &sound_file)
: renderer_(Screen::get()->getRenderer()), : renderer_(Screen::get()->getRenderer()),
icon_texture_(!icon_file.empty() ? std::make_unique<Texture>(renderer_, icon_file) : nullptr),
text_(text), text_(text),
bg_color_(param.notification.color), bg_color_(param.notification.color),
wait_time_(150), wait_time_(150),
stack_(false), stack_(false),
sound_(JA_LoadSound(sound_file.c_str())) has_icons_(!icon_file.empty()),
{ sound_(JA_LoadSound(sound_file.c_str())) {}
// Inicializa variables
has_icons_ = !icon_file.empty();
// Crea objetos
icon_texture_ = has_icons_ ? std::make_unique<Texture>(renderer_, icon_file) : nullptr;
}
// Destructor // Destructor
Notifier::~Notifier() Notifier::~Notifier()
{ {
// Libera la memoria de los objetos
JA_DeleteSound(sound_); JA_DeleteSound(sound_);
notifications_.clear();
} }
// Dibuja las notificaciones por pantalla // Dibuja las notificaciones por pantalla
void Notifier::render() void Notifier::render()
{ {
for (int i = (int)notifications_.size() - 1; i >= 0; --i) for (int i = (int)notifications_.size() - 1; i >= 0; --i)
{
notifications_[i].sprite->render(); notifications_[i].sprite->render();
}
} }
// Actualiza el estado de las notificaiones // Actualiza el estado de las notificaiones
@@ -165,7 +154,7 @@ void Notifier::clearFinishedNotifications()
} }
} }
void Notifier::showText(std::string text1, std::string text2, int icon, std::string code) void Notifier::showText(std::string text1, std::string text2, int icon, const std::string &code)
{ {
// Cuenta el número de textos a mostrar // Cuenta el número de textos a mostrar
const int num_texts = !text1.empty() + !text2.empty(); const int num_texts = !text1.empty() + !text2.empty();
@@ -237,8 +226,6 @@ void Notifier::showText(std::string text1, std::string text2, int icon, std::str
n.code = code; n.code = code;
n.y = offset; n.y = offset;
n.travel_dist = travel_dist; n.travel_dist = travel_dist;
n.counter = 0;
n.status = NotificationStatus::RISING;
n.text1 = text1; n.text1 = text1;
n.text2 = text2; n.text2 = text2;
n.shape = shape; n.shape = shape;
@@ -286,7 +273,7 @@ void Notifier::showText(std::string text1, std::string text2, int icon, std::str
} }
// Escribe el texto de la notificación // Escribe el texto de la notificación
Color color = {255, 255, 255}; Color color{255, 255, 255};
if (num_texts == 2) if (num_texts == 2)
{ // Dos lineas de texto { // Dos lineas de texto
text_->writeColored(padding_in_h + icon_space, padding_in_v, text1, color); text_->writeColored(padding_in_h + icon_space, padding_in_v, text1, color);

View File

@@ -1,11 +1,11 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // para SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // para SDL_Renderer
#include <memory> // for shared_ptr, unique_ptr #include <memory> // para shared_ptr, unique_ptr
#include <string> // for string, basic_string #include <string> // para string, basic_string
#include <vector> // for vector #include <vector> // para vector
#include "utils.h" // for Color #include "utils.h" // para Color
class Sprite; class Sprite;
class Text; class Text;
class Texture; class Texture;
@@ -25,18 +25,6 @@ private:
FINISHED, FINISHED,
}; };
enum class NotificationPosition
{
UPPER_LEFT,
UPPER_CENTER,
UPPER_RIGHT,
MIDDLE_LEFT,
MIDDLE_RIGHT,
BOTTOM_LEFT,
BOTTOM_CENTER,
BOTTOM_RIGHT,
};
enum class NotificationShape enum class NotificationShape
{ {
ROUNDED, ROUNDED,
@@ -51,12 +39,16 @@ private:
std::string text2; std::string text2;
int counter; int counter;
NotificationStatus status; NotificationStatus status;
NotificationPosition position;
NotificationShape shape; NotificationShape shape;
SDL_Rect rect; SDL_Rect rect;
int y; int y;
int travel_dist; int travel_dist;
std::string code; // Permite asignar un código a la notificación std::string code; // Permite asignar un código a la notificación
// Constructor
explicit Notification()
: texture(nullptr), sprite(nullptr), text1(""), text2(""), counter(0), status(NotificationStatus::RISING),
shape(NotificationShape::SQUARED), rect{0, 0, 0, 0}, y(0), travel_dist(0), code("") {}
}; };
// Objetos y punteros // Objetos y punteros
@@ -89,7 +81,7 @@ private:
public: public:
// [SINGLETON] Crearemos el objeto notifier con esta función estática // [SINGLETON] Crearemos el objeto notifier con esta función estática
static void init(std::string icon_file, std::shared_ptr<Text> text, const std::string &sound_file); static void init(const std::string &icon_file, std::shared_ptr<Text> text, const std::string &sound_file);
// [SINGLETON] Destruiremos el objeto notifier con esta función estática // [SINGLETON] Destruiremos el objeto notifier con esta función estática
static void destroy(); static void destroy();
@@ -111,7 +103,7 @@ public:
* @param icon Icono opcional para mostrar (valor predeterminado: -1). * @param icon Icono opcional para mostrar (valor predeterminado: -1).
* @param code Permite asignar un código a la notificación (valor predeterminado: cadena vacía). * @param code Permite asignar un código a la notificación (valor predeterminado: cadena vacía).
*/ */
void showText(std::string text1 = std::string(), std::string text2 = std::string(), int icon = -1, std::string code = std::string()); void showText(std::string text1 = std::string(), std::string text2 = std::string(), int icon = -1, const std::string &code = std::string());
// Indica si hay notificaciones activas // Indica si hay notificaciones activas
bool isActive(); bool isActive();

View File

@@ -1,16 +1,14 @@
#include "on_screen_help.h" #include "on_screen_help.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
#include <memory> // for make_unique, make_shared, unique_ptr #include <memory> // Para make_unique, unique_ptr
#include "asset.h" // for Asset #include "lang.h" // Para getText
#include "lang.h" // for getText #include "param.h" // Para Param, ParamGame, param
#include "param.h" // for param #include "resource.h" // Para Resource
#include "resource.h" // for Resource #include "screen.h" // Para Screen
#include "screen.h" // for Screen #include "sprite.h" // Para Sprite
#include "sprite.h" // for Sprite #include "text.h" // Para Text
#include "text.h" // for Text #include "utils.h" // Para easeInOutSine
#include "texture.h" // for Texture
#include "utils.h" // for easeInOutSine, Param, ParamGame
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
OnScreenHelp *OnScreenHelp::onScreenHelp = nullptr; OnScreenHelp *OnScreenHelp::onScreenHelp = nullptr;

View File

@@ -1,8 +1,8 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // para SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Texture #include <SDL2/SDL_render.h> // para SDL_Texture
#include <vector> // for vector #include <vector> // para vector
class Sprite; class Sprite;
class Text; class Text;

View File

@@ -1,13 +1,13 @@
#include "options.h" #include "options.h"
#include <SDL2/SDL_gamecontroller.h> // for SDL_GameControllerButton, SDL_C... #include <SDL2/SDL_gamecontroller.h> // para SDL_GameControllerButton, SDL_C...
#include <algorithm> // for max, min #include <algorithm> // para max, min
#include <fstream> // for basic_ostream, operator<<, basi... #include <fstream> // para basic_ostream, operator<<, basi...
#include <iostream> // for cout #include <iostream> // para cout
#include <vector> // for vector #include <vector> // para vector
#include "input.h" // for inputs_e, INPUT_USE_ANY, INPUT_... #include "input.h" // para inputs_e, INPUT_USE_ANY, INPUT_...
#include "lang.h" // for lang_e #include "lang.h" // para lang_e
#include "screen.h" // for ScreenVideoMode, ScreenFilter #include "screen.h" // para ScreenVideoMode, ScreenFilter
#include "utils.h" // for OptionsController, Options, op_... #include "utils.h" // para OptionsController, Options, op_...
// Variables // Variables
Options options; Options options;
@@ -86,14 +86,13 @@ bool loadOptionsFile(std::string file_path)
bool success = true; bool success = true;
// Variables para manejar el fichero // Variables para manejar el fichero
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1);
std::ifstream file(file_path); std::ifstream file(file_path);
// Si el fichero se puede abrir // Si el fichero se puede abrir
if (file.good()) if (file.good())
{ {
// Procesa el fichero linea a linea // Procesa el fichero linea a linea
std::cout << "Reading file: " << file_name << std::endl; std::cout << "Reading file: " << getFileName(file_path) << std::endl;
std::string line; std::string line;
while (std::getline(file, line)) while (std::getline(file, line))
{ {
@@ -105,14 +104,12 @@ bool loadOptionsFile(std::string file_path)
// Procesa las dos subcadenas // Procesa las dos subcadenas
if (!setOptions(line.substr(0, pos), line.substr(pos + 1, line.length()))) if (!setOptions(line.substr(0, pos), line.substr(pos + 1, line.length())))
{ {
std::cout << "Warning: file " << file_name << std::endl; std::cout << "Warning: file " << getFileName(file_path) << std::endl;
std::cout << "Unknown parameter " << line.substr(0, pos).c_str() << std::endl; std::cout << "Unknown parameter " << line.substr(0, pos).c_str() << std::endl;
success = false; success = false;
} }
} }
} }
// Cierra el fichero
file.close(); file.close();
} }
@@ -146,16 +143,15 @@ bool loadOptionsFile(std::string file_path)
// Guarda el fichero de configuración // Guarda el fichero de configuración
bool saveOptionsFile(std::string file_path) bool saveOptionsFile(std::string file_path)
{ {
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1);
std::ofstream file(file_path); std::ofstream file(file_path);
if (!file.good()) if (!file.good())
{ {
std::cout << file_name << " can't be opened" << std::endl; std::cout << getFileName(file_path) << " can't be opened" << std::endl;
return false; return false;
} }
std::cout << "Writing file: " << file_name << std::endl; std::cout << "Writing file: " << getFileName(file_path) << std::endl;
// Opciones de video // Opciones de video
const auto value_video_mode_winow = std::to_string(static_cast<int>(ScreenVideoMode::WINDOW)); const auto value_video_mode_winow = std::to_string(static_cast<int>(ScreenVideoMode::WINDOW));

View File

@@ -1,7 +1,93 @@
#pragma once #pragma once
#include <string> // for string #include <SDL2/SDL_gamecontroller.h> // Para SDL_GameControllerButton
struct Options; #include <SDL2/SDL_stdinc.h> // Para Uint8
#include "manage_hiscore_table.h"
#include <vector> // Para vector
#include <string>
enum class InputType : int;
enum class ScreenFilter : int;
enum class ScreenVideoMode : int;
namespace lang
{
enum class Code : int;
}
// Dificultad del juego
enum class GameDifficulty
{
EASY = 0,
NORMAL = 1,
HARD = 2,
};
// Estructura para las opciones de la ventana
struct OptionsWindow
{
int size; // Contiene el valor por el que se multiplica el tamaño de la ventana
};
// Estructura con opciones para el video
struct OptionsVideo
{
OptionsWindow window; // Opciones para la ventana del programa
ScreenVideoMode mode; // Contiene el valor del modo de pantalla completa
ScreenFilter filter; // Filtro usado para el escalado de la imagen
bool v_sync; // Indica si se quiere usar vsync o no
bool integer_scale; // Indica si se va a usar el escalado entero
bool shaders; // Indica si se van a usar shaders para los filtros de video
};
// Estructura para las opciones de musica
struct OptionsMusic
{
bool enabled; // Indica si la musica suena o no
int volume; // Volumen al que suena la música
};
// Estructura para las opciones de sonido
struct OptionsSound
{
bool enabled; // Indica si los sonidos suenan o no
int volume; // Volumen al que suenan los sonidos
};
// Estructura para las opciones de audio
struct OptionsAudio
{
OptionsMusic music; // Opciones para la música
OptionsSound sound; // Opciones para los efectos de sonido
};
// Estructura para las opciones del juego
struct OptionsGame
{
GameDifficulty difficulty; // Dificultad del juego
lang::Code language; // Idioma usado en el juego
bool autofire; // Indica si el jugador ha de pulsar repetidamente para disparar o basta con mantener pulsado
std::vector<HiScoreEntry> hi_score_table; // Tabla con las mejores puntuaciones
};
// Estructura para los controles del juego
struct OptionsController
{
int index; // Indice en el vector de mandos
int player_id; // Jugador asociado al mando
Uint8 device_type; // Indica si se utilizará teclado o mando o ambos
std::string name; // Nombre del dispositivo
bool plugged; // Indica si el mando se encuentra conectado
std::vector<InputType> inputs; // Listado de inputs
std::vector<SDL_GameControllerButton> buttons; // Listado de botones asignados a cada input
};
// Estructura con todas las opciones de configuración del programa
struct Options
{
OptionsGame game; // Opciones para el propio juego
OptionsVideo video; // Opciones relativas a la clase screen
OptionsAudio audio; // Opciones para el audio
std::vector<OptionsController> controller; // Opciones con las asignaciones del mando para cada jugador
};
// Variables // Variables
extern Options options; extern Options options;

View File

@@ -1,10 +1,10 @@
#include "param.h" #include "param.h"
#include <fstream> // for char_traits, basic_ostream, basic_ifstream, basi... #include <fstream> // para char_traits, basic_ostream, basic_ifstream, basi...
#include <iostream> // for cout #include <iostream> // para cout
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <stdexcept> #include <stdexcept>
#include "utils.h" // for Param, ParamGame, Zone, ParamBalloon #include "utils.h" // para Param, ParamGame, Zone, ParamBalloon
Param param; Param param;
@@ -43,18 +43,14 @@ void initParam()
param.title.title_c_c_position = 11; param.title.title_c_c_position = 11;
// BACKGROUND // BACKGROUND
param.background.attenuate_color = (Color){255, 255, 255}; param.background.attenuate_color = Color(255, 255, 255);
param.background.attenuate_alpha = 32; param.background.attenuate_alpha = 32;
// BALLOONS // BALLOONS
param.balloon_1.vel = 2.60f; param.balloon.emplace_back(0.09f, 2.60f);
param.balloon_1.grav = 0.09f; param.balloon.emplace_back(0.10f, 3.50f);
param.balloon_2.vel = 3.50f; param.balloon.emplace_back(0.10f, 4.50f);
param.balloon_2.grav = 0.10f; param.balloon.emplace_back(0.10f, 4.95f);
param.balloon_3.vel = 4.50f;
param.balloon_3.grav = 0.10f;
param.balloon_4.vel = 4.95f;
param.balloon_4.grav = 0.10f;
// NOTIFICATION // NOTIFICATION
param.notification.pos_v = NotifyPosition::TOP; param.notification.pos_v = NotifyPosition::TOP;
@@ -78,8 +74,7 @@ void loadParamsFromFile(const std::string &file_path)
throw std::runtime_error("No se pudo abrir el archivo: " + file_path); throw std::runtime_error("No se pudo abrir el archivo: " + file_path);
} }
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1); std::cout << "Reading file: " << getFileName(file_path) << std::endl;
std::cout << "Reading file: " << file_name << std::endl;
std::string line, param1, param2; std::string line, param1, param2;
while (std::getline(file, line)) while (std::getline(file, line))
@@ -250,42 +245,42 @@ bool setParams(const std::string &var, const std::string &value)
// BALLOON // BALLOON
else if (var == "balloon_1.vel") else if (var == "balloon_1.vel")
{ {
param.balloon_1.vel = std::stof(value); param.balloon.at(0).vel = std::stof(value);
} }
else if (var == "balloon_1.grav") else if (var == "balloon_1.grav")
{ {
param.balloon_1.grav = std::stof(value); param.balloon.at(0).grav = std::stof(value);
} }
else if (var == "balloon_2.vel") else if (var == "balloon_2.vel")
{ {
param.balloon_2.vel = std::stof(value); param.balloon.at(1).vel = std::stof(value);
} }
else if (var == "balloon_2.grav") else if (var == "balloon_2.grav")
{ {
param.balloon_2.grav = std::stof(value); param.balloon.at(1).grav = std::stof(value);
} }
else if (var == "balloon_3.vel") else if (var == "balloon_3.vel")
{ {
param.balloon_3.vel = std::stof(value); param.balloon.at(2).vel = std::stof(value);
} }
else if (var == "balloon_3.grav") else if (var == "balloon_3.grav")
{ {
param.balloon_3.grav = std::stof(value); param.balloon.at(2).grav = std::stof(value);
} }
else if (var == "balloon_4.vel") else if (var == "balloon_4.vel")
{ {
param.balloon_4.vel = std::stof(value); param.balloon.at(3).vel = std::stof(value);
} }
else if (var == "balloon_4.grav") else if (var == "balloon_4.grav")
{ {
param.balloon_4.grav = std::stof(value); param.balloon.at(3).grav = std::stof(value);
} }
// NOTIFICACIONES // NOTIFICACIONES

View File

@@ -1,7 +1,80 @@
#pragma once #pragma once
#include <string> // for string #include <SDL2/SDL_rect.h> // Para SDL_Rect
struct Param; #include <string> // Para string
#include <vector> // Para vector
#include "utils.h" // Para Color, Zone
// param.game
struct ParamGame
{
int width; // Ancho de la resolucion nativa del juego
int height; // Alto de la resolucion nativa del juego
int item_size; // Tamaño de los items del juego
Zone play_area; // Rectangulo con la posición de la zona de juego
Zone game_area; // Rectangulo con las dimensiones del juego
int enter_name_seconds; // Duración en segundos para introducir el nombre al finalizar la partida
};
// param.fade
struct ParamFade
{
int num_squares_width; // Cantidad total de cuadraditos en horizontal para el FadeType::RANDOM_SQUARE
int num_squares_height; // Cantidad total de cuadraditos en vertical para el FadeType::RANDOM_SQUARE
int random_squares_delay; // Duración entre cada pintado de cuadrados
int random_squares_mult; // Cantidad de cuadrados que se pintaran cada vez
int post_duration; // Duración final del fade
int venetian_size; // Altura de los rectangulos para FadeType::VENETIAN
};
// param.title
struct ParamTitle
{
int press_start_position; // Posición del texto para empezar a jugar
int title_duration; // Tiempo de inactividad del titulo
int arcade_edition_position; // Posición del bitmap
int title_c_c_position; // Posición del bitmap
};
// param.background
struct ParamBackground
{
Color attenuate_color;
int attenuate_alpha;
};
struct ParamBalloon
{
float grav; // Aceleración en el eje Y. Modifica la velocidad
float vel; // Velocidad inicial que tienen al rebotar contra el suelo
// Constructor
explicit ParamBalloon(float grav_val = 0.0f, float vel_val = 0.0f)
: grav(grav_val), vel(vel_val) {}
};
// Estructura para las opciones de las notificaciones
struct ParamNotification
{
NotifyPosition pos_h; // Ubicación de las notificaciones en pantalla
NotifyPosition pos_v; // Ubicación de las notificaciones en pantalla
bool sound; // Indica si las notificaciones suenan
Color color; // Color de las notificaciones
};
// Estructura para almacenar todos los parámetros del juego
struct Param
{
ParamGame game; // Parametros relacionados con el juego
ParamFade fade; // Parametros para ajustar el fade
SDL_Rect scoreboard; // Posición y tamaño del marcador
ParamTitle title; // Parametros con ajustes para la sección Title
ParamBackground background; // Parametros que afectan a la clase Background
std::vector<ParamBalloon> balloon; // Parametros de velocidad y gravedad de cada tipo de globo
ParamNotification notification; // Opciones para las notificaciones
Param() { balloon.reserve(4); }
};
extern Param param; extern Param param;

124
source/path_sprite.cpp Normal file
View File

@@ -0,0 +1,124 @@
#include "path_sprite.h"
#include <bits/std_abs.h> // Para abs
#include <stdlib.h> // Para abs
#include <utility> // Para move
#include "moving_sprite.h" // Para MovingSprite
#include "utils.h" // Para easeOutQuint
#include <functional>
class Texture; // lines 3-3
// Constructor
PathSprite::PathSprite(std::shared_ptr<Texture> texture)
: AnimatedSprite(texture) {}
// Actualiza la posición y comprueba si ha llegado a su destino
void PathSprite::update()
{
if (enabled_)
{
moveThroughCurrentPath();
goToNextPathOrDie();
}
}
// Añade un recorrido
void PathSprite::addPath(int start, int end, PathType type, int fixed_pos, int steps, const std::function<double(double)> &easingFunction, int waiting_counter)
{
paths_.emplace_back(createPath(start, end, type, fixed_pos, steps, easingFunction), waiting_counter);
}
// Añade un recorrido
void PathSprite::addPath(std::vector<SDL_Point> spots, int waiting_counter)
{
paths_.emplace_back(std::move(spots), waiting_counter);
}
// Devuelve un vector con los puntos que conforman la ruta
std::vector<SDL_Point> PathSprite::createPath(int start, int end, PathType type, int fixed_pos, int steps, const std::function<double(double)> &easingFunction)
{
std::vector<SDL_Point> v;
v.reserve(steps);
for (int i = 0; i < steps; ++i)
{
double t = static_cast<double>(i) / (steps - 1);
double value = start + (end - start) * easingFunction(t);
if (start > 0 && end < 0)
{
value = start - std::abs(end - start) * easingFunction(t);
}
else if (start < 0 && end > 0)
{
value = start + std::abs(end - start) * easingFunction(t);
}
switch (type)
{
case PathType::HORIZONTAL:
v.emplace_back(SDL_Point{static_cast<int>(value), fixed_pos});
break;
case PathType::VERTICAL:
v.emplace_back(SDL_Point{fixed_pos, static_cast<int>(value)});
break;
default:
break;
}
}
return v;
}
// Habilita el objeto
void PathSprite::enable()
{
enabled_ = true;
}
// Coloca el sprite en los diferentes puntos del recorrido
void PathSprite::moveThroughCurrentPath()
{
auto &path = paths_.at(current_path_);
// Establece la posición
const auto &p = path.spots.at(path.counter);
MovingSprite::setPos(p.x, p.y);
// Comprobar si ha terminado el recorrido
if (!path.on_destination)
{
++path.counter;
if (path.counter >= static_cast<int>(path.spots.size()))
{
path.on_destination = true;
path.counter = static_cast<int>(path.spots.size()) - 1;
}
}
// Comprobar si ha terminado la espera
if (path.on_destination)
{
if (path.waiting_counter == 0)
path.finished = true;
else
--path.waiting_counter;
}
}
// Cambia de recorrido o finaliza
void PathSprite::goToNextPathOrDie()
{
// Comprueba si ha terminado el recorrdo actual
if (paths_.at(current_path_).finished)
++current_path_;
// Comprueba si quedan mas recorridos
if (current_path_ >= static_cast<int>(paths_.size()))
enabled_ = false;
}
// Indica si ha terminado todos los recorridos
bool PathSprite::hasFinished()
{
return !enabled_;
}

68
source/path_sprite.h Normal file
View File

@@ -0,0 +1,68 @@
#pragma once
#include <SDL2/SDL_rect.h> // Para SDL_Point
#include <memory> // Para shared_ptr
#include <functional>
#include <vector> // Para vector
#include "animated_sprite.h" // Para AnimatedSprite
class Texture; // lines 5-5
enum class PathType
{
VERTICAL,
HORIZONTAL,
};
// Clase PathSprite
class PathSprite : public AnimatedSprite
{
private:
// Estructuras
struct Path
{
std::vector<SDL_Point> spots; // Puntos por los que se desplazará el sprite
int waiting_counter; // Tiempo de espera una vez en el destino
bool on_destination = false; // Indica si ha llegado al destino
bool finished = false; // Indica si ha terminado de esperarse
int counter = 0; // Contador interno
// Constructor
Path(const std::vector<SDL_Point> &spots_init, int waiting_counter_init)
: spots(spots_init), waiting_counter(waiting_counter_init) {}
};
// Variables
bool finished_ = false; // Indica si ya ha terminado
bool enabled_ = false; // Indica si el objeto está habilitado
int current_path_ = 0; // Path que se está recorriendo actualmente
std::vector<Path> paths_; // Caminos a recorrer por el sprite
// Coloca el sprite en los diferentes puntos del recorrido
void moveThroughCurrentPath();
// Cambia de recorrido o finaliza
void goToNextPathOrDie();
public:
// Constructor
explicit PathSprite(std::shared_ptr<Texture> texture);
// Destructor
~PathSprite() = default;
// Actualiza la posición del sprite
void update() override;
// Añade un recorrido
void addPath(std::vector<SDL_Point> spots, int waiting_counter);
void addPath(int start, int end, PathType type, int fixed_pos, int steps, const std::function<double(double)> &easingFunction, int waiting_counter);
// Devuelve un vector con los puntos que conforman la ruta
std::vector<SDL_Point> createPath(int start, int end, PathType type, int fixed_pos, int steps, const std::function<double(double)> &easingFunction);
// Habilita el objeto
void enable();
// Indica si ha terminado todos los recorridos
bool hasFinished();
};

View File

@@ -1,36 +1,30 @@
#include "player.h" #include "player.h"
#include <SDL2/SDL_render.h> // for SDL_FLIP_HORIZONTAL, SDL_FLIP_NONE, SDL... #include <SDL2/SDL_render.h> // Para SDL_FLIP_HORIZONTAL, SDL_FLIP_NONE
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // Para SDL_GetTicks
#include <stdlib.h> // for rand #include <stdlib.h> // Para rand
#include <algorithm> // for max, min #include <algorithm> // Para max, min
#include "animated_sprite.h" // for SpriteAnimated #include "animated_sprite.h" // Para AnimatedSprite
#include "input.h" // for inputs_e #include "input.h" // Para InputType
#include "param.h" // for param #include "manage_hiscore_table.h" // Para HiScoreEntry
#include "texture.h" // for Texture #include "options.h" // Para Options, OptionsGame, options
#include "scoreboard.h" // for Texture #include "param.h" // Para Param, ParamGame, param
#include "options.h" #include "scoreboard.h" // Para Scoreboard, ScoreboardMode
#include "texture.h" // Para Texture
// Constructor // Constructor
Player::Player(int id, float x, int y, bool demo, SDL_Rect *play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations) Player::Player(int id, float x, int y, bool demo, SDL_Rect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations)
: player_sprite_(std::make_unique<AnimatedSprite>(texture[0], animations[0])), : player_sprite_(std::make_unique<AnimatedSprite>(texture[0], animations[0])),
power_sprite_(std::make_unique<AnimatedSprite>(texture[1], animations[1])), power_sprite_(std::make_unique<AnimatedSprite>(texture[1], animations[1])),
enter_name_(std::make_unique<EnterName>()), enter_name_(std::make_unique<EnterName>()),
play_area_(play_area),
id_(id), id_(id),
pos_x_(x), play_area_(play_area),
pos_y_(y),
default_pos_x_(x), default_pos_x_(x),
default_pos_y_(y), default_pos_y_(y),
status_playing_(PlayerStatus::WAITING),
scoreboard_panel_(0),
name_(std::string()),
controller_index_(0),
demo_(demo) demo_(demo)
{ {
// Reserva memoria para los objetos // Configura objetos
player_sprite_->getTexture()->setPalette(coffees_);
power_sprite_->getTexture()->setAlpha(224); power_sprite_->getTexture()->setAlpha(224);
// Establece los offsets para el sprite de PowerUp
power_up_desp_x_ = (power_sprite_->getWidth() - player_sprite_->getWidth()) / 2; power_up_desp_x_ = (power_sprite_->getWidth() - player_sprite_->getWidth()) / 2;
power_sprite_->setPosY(y - (power_sprite_->getHeight() - player_sprite_->getHeight())); power_sprite_->setPosY(y - (power_sprite_->getHeight() - player_sprite_->getHeight()));
@@ -46,25 +40,21 @@ void Player::init()
pos_x_ = default_pos_x_; pos_x_ = default_pos_x_;
pos_y_ = default_pos_y_; pos_y_ = default_pos_y_;
status_walking_ = PlayerStatus::WALKING_STOP; status_walking_ = PlayerStatus::WALKING_STOP;
status_firing_ = PlayerStatus::FIRING_NO; status_firing_ = PlayerStatus::FIRING_NONE;
status_playing_ = PlayerStatus::WAITING;
invulnerable_ = true; invulnerable_ = true;
invulnerable_counter_ = PLAYER_INVULNERABLE_COUNTER; invulnerable_counter_ = INVULNERABLE_COUNTER_;
power_up_ = false; power_up_ = false;
power_up_counter_ = PLAYER_POWERUP_COUNTER; power_up_counter_ = POWERUP_COUNTER_;
extra_hit_ = false; extra_hit_ = false;
coffees_ = 0; coffees_ = 0;
input_ = true;
continue_ticks_ = 0; continue_ticks_ = 0;
continue_counter_ = 10; continue_counter_ = 10;
enter_name_ticks_ = 0; enter_name_ticks_ = 0;
enter_name_counter_ = param.game.enter_name_seconds; enter_name_counter_ = param.game.enter_name_seconds;
width_ = 30;
height_ = 30;
collider_.r = 9;
shiftColliders(); shiftColliders();
vel_x_ = 0; vel_x_ = 0;
vel_y_ = 0; vel_y_ = 0;
base_speed_ = 1.5;
score_ = 0; score_ = 0;
score_multiplier_ = 1.0f; score_multiplier_ = 1.0f;
cooldown_ = 10; cooldown_ = 10;
@@ -107,14 +97,14 @@ void Player::setInputPlaying(InputType input)
{ {
case InputType::LEFT: case InputType::LEFT:
{ {
vel_x_ = -base_speed_; vel_x_ = -BASE_SPEED_;
setWalkingStatus(PlayerStatus::WALKING_LEFT); setWalkingStatus(PlayerStatus::WALKING_LEFT);
break; break;
} }
case InputType::RIGHT: case InputType::RIGHT:
{ {
vel_x_ = base_speed_; vel_x_ = BASE_SPEED_;
setWalkingStatus(PlayerStatus::WALKING_RIGHT); setWalkingStatus(PlayerStatus::WALKING_RIGHT);
break; break;
} }
@@ -186,7 +176,7 @@ void Player::move()
pos_x_ += vel_x_; pos_x_ += vel_x_;
// Si el jugador abandona el area de juego por los laterales // Si el jugador abandona el area de juego por los laterales
if ((pos_x_ < param.game.play_area.rect.x - 5) || (pos_x_ + width_ > play_area_->w + 5)) if ((pos_x_ < param.game.play_area.rect.x - 5) || (pos_x_ + WIDTH_ > play_area_.w + 5))
{ {
// Restaura su posición // Restaura su posición
pos_x_ -= vel_x_; pos_x_ -= vel_x_;
@@ -203,7 +193,7 @@ void Player::move()
player_sprite_->update(); player_sprite_->update();
// Si el cadaver abandona el area de juego por los laterales // Si el cadaver abandona el area de juego por los laterales
if ((player_sprite_->getPosX() < param.game.play_area.rect.x) || (player_sprite_->getPosX() + width_ > play_area_->w)) if ((player_sprite_->getPosX() < param.game.play_area.rect.x) || (player_sprite_->getPosX() + WIDTH_ > play_area_.w))
{ {
// Restaura su posición // Restaura su posición
const float vx = player_sprite_->getVelX(); const float vx = player_sprite_->getVelX();
@@ -226,7 +216,7 @@ void Player::render()
{ {
if (power_up_ && isPlaying()) if (power_up_ && isPlaying())
{ {
if (power_up_counter_ > (PLAYER_POWERUP_COUNTER / 4) || power_up_counter_ % 20 > 4) if (power_up_counter_ > (POWERUP_COUNTER_ / 4) || power_up_counter_ % 20 > 4)
{ {
power_sprite_->render(); power_sprite_->render();
} }
@@ -261,7 +251,7 @@ void Player::setAnimation()
// Establece la animación a partir de las cadenas // Establece la animación a partir de las cadenas
if (isPlaying()) if (isPlaying())
{ {
if (status_firing_ == PlayerStatus::FIRING_NO) if (status_firing_ == PlayerStatus::FIRING_NONE)
{ // No esta disparando { // No esta disparando
player_sprite_->setCurrentAnimation(a_walking); player_sprite_->setCurrentAnimation(a_walking);
player_sprite_->setFlip(flip_walk); player_sprite_->setFlip(flip_walk);
@@ -301,13 +291,13 @@ int Player::getPosY() const
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Player::getWidth() const int Player::getWidth() const
{ {
return width_; return WIDTH_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
int Player::getHeight() const int Player::getHeight() const
{ {
return height_; return HEIGHT_;
} }
// Indica si el jugador puede disparar // Indica si el jugador puede disparar
@@ -336,7 +326,7 @@ void Player::updateCooldown()
} }
else else
{ {
setFiringStatus(PlayerStatus::FIRING_NO); setFiringStatus(PlayerStatus::FIRING_NONE);
} }
} }
@@ -347,7 +337,7 @@ void Player::update()
setAnimation(); setAnimation();
shiftColliders(); shiftColliders();
updateCooldown(); updateCooldown();
updatePowerUpCounter(); updatePowerUp();
updateInvulnerable(); updateInvulnerable();
updateContinueCounter(); updateContinueCounter();
updateEnterNameCounter(); updateEnterNameCounter();
@@ -459,8 +449,8 @@ void Player::setStatusPlaying(PlayerStatus value)
{ {
case PlayerStatus::PLAYING: case PlayerStatus::PLAYING:
{ {
status_playing_ = PlayerStatus::PLAYING;
init(); init();
status_playing_ = PlayerStatus::PLAYING;
setScoreboardMode(ScoreboardMode::SCORE); setScoreboardMode(ScoreboardMode::SCORE);
break; break;
} }
@@ -556,7 +546,7 @@ bool Player::isInvulnerable() const
void Player::setInvulnerable(bool value) void Player::setInvulnerable(bool value)
{ {
invulnerable_ = value; invulnerable_ = value;
invulnerable_counter_ = invulnerable_ ? PLAYER_INVULNERABLE_COUNTER : 0; invulnerable_counter_ = invulnerable_ ? INVULNERABLE_COUNTER_ : 0;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
@@ -578,7 +568,7 @@ void Player::updateInvulnerable()
{ {
if (invulnerable_counter_ > 0) if (invulnerable_counter_ > 0)
{ {
invulnerable_counter_--; --invulnerable_counter_;
invulnerable_counter_ % 8 > 3 ? player_sprite_->getTexture()->setPalette(coffees_) : player_sprite_->getTexture()->setPalette(3); invulnerable_counter_ % 8 > 3 ? player_sprite_->getTexture()->setPalette(coffees_) : player_sprite_->getTexture()->setPalette(3);
} }
else else
@@ -599,7 +589,7 @@ bool Player::isPowerUp() const
void Player::setPowerUp() void Player::setPowerUp()
{ {
power_up_ = true; power_up_ = true;
power_up_counter_ = PLAYER_POWERUP_COUNTER; power_up_counter_ = POWERUP_COUNTER_;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
@@ -615,15 +605,12 @@ void Player::setPowerUpCounter(int value)
} }
// Actualiza el valor de la variable // Actualiza el valor de la variable
void Player::updatePowerUpCounter() void Player::updatePowerUp()
{ {
if ((power_up_counter_ > 0) && (power_up_)) if (power_up_)
{ {
power_up_counter_--; --power_up_counter_;
} power_up_ = power_up_counter_ > 0;
else
{
power_up_ = false;
} }
} }
@@ -657,18 +644,6 @@ void Player::removeExtraHit()
extra_hit_ = coffees_ == 0 ? false : true; extra_hit_ = coffees_ == 0 ? false : true;
} }
// Habilita la entrada de ordenes
void Player::enableInput()
{
input_ = true;
}
// Deshabilita la entrada de ordenes
void Player::disableInput()
{
input_ = false;
}
// Devuelve el número de cafes actuales // Devuelve el número de cafes actuales
int Player::getCoffees() const int Player::getCoffees() const
{ {
@@ -684,8 +659,8 @@ Circle &Player::getCollider()
// Actualiza el circulo de colisión a la posición del jugador // Actualiza el circulo de colisión a la posición del jugador
void Player::shiftColliders() void Player::shiftColliders()
{ {
collider_.x = int(pos_x_ + (width_ / 2)); collider_.x = static_cast<int>(pos_x_ + (WIDTH_ / 2));
collider_.y = int(pos_y_ + (height_ / 2)); collider_.y = static_cast<int>(pos_y_ + (HEIGHT_ / 2));
} }
// Pone las texturas del jugador // Pone las texturas del jugador
@@ -706,9 +681,8 @@ void Player::updateContinueCounter()
{ {
if (status_playing_ == PlayerStatus::CONTINUE) if (status_playing_ == PlayerStatus::CONTINUE)
{ {
constexpr Uint32 ticks_speed = 1000; constexpr int TICKS_SPEED = 1000;
if (SDL_GetTicks() - continue_ticks_ > TICKS_SPEED)
if (SDL_GetTicks() - continue_ticks_ > ticks_speed)
{ {
decContinueCounter(); decContinueCounter();
} }
@@ -720,9 +694,8 @@ void Player::updateEnterNameCounter()
{ {
if (status_playing_ == PlayerStatus::ENTERING_NAME) if (status_playing_ == PlayerStatus::ENTERING_NAME)
{ {
constexpr Uint32 ticks_speed = 1000; constexpr int TICKS_SPEED = 1000;
if (SDL_GetTicks() - enter_name_ticks_ > TICKS_SPEED)
if (SDL_GetTicks() - enter_name_ticks_ > ticks_speed)
{ {
decEnterNameCounter(); decEnterNameCounter();
} }

View File

@@ -1,17 +1,16 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // Para SDL_Rect
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // Para Uint32
#include <memory> // for unique_ptr, shared_ptr #include <memory> // Para unique_ptr, shared_ptr
#include <string> // for string #include <string> // Para string
#include <vector> // for vector #include <vector> // Para vector
#include "animated_sprite.h" // for SpriteAnimated #include "animated_sprite.h" // Para AnimatedSprite
#include "smart_sprite.h" // for SpriteAnimated #include "enter_name.h" // Para EnterName
#include "enter_name.h" // for EnterName #include "utils.h" // Para Circle
#include "utils.h" // for Circle class Texture; // lines 12-12
class Texture; enum class InputType : int; // lines 13-13
enum class InputType : int; enum class ScoreboardMode; // lines 14-14
enum class ScoreboardMode; // lines 12-12
// Estados del jugador // Estados del jugador
enum class PlayerStatus enum class PlayerStatus
@@ -23,7 +22,7 @@ enum class PlayerStatus
FIRING_UP, FIRING_UP,
FIRING_LEFT, FIRING_LEFT,
FIRING_RIGHT, FIRING_RIGHT,
FIRING_NO, FIRING_NONE,
PLAYING, PLAYING,
CONTINUE, CONTINUE,
@@ -35,54 +34,55 @@ enum class PlayerStatus
}; };
// Variables del jugador // Variables del jugador
constexpr int PLAYER_INVULNERABLE_COUNTER = 200;
constexpr int PLAYER_POWERUP_COUNTER = 1500;
// Clase Player // Clase Player
class Player class Player
{ {
private: private:
// Constantes
static constexpr int POWERUP_COUNTER_ = 1500; // Duración del estado PowerUp
static constexpr int INVULNERABLE_COUNTER_ = 200; // Duración del estado invulnerable
static constexpr int WIDTH_ = 30; // Anchura
static constexpr int HEIGHT_ = 30; // Altura
static constexpr float BASE_SPEED_ = 1.5f; // Velocidad base del jugador
// Objetos y punteros // Objetos y punteros
std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador
std::unique_ptr<AnimatedSprite> power_sprite_; // Sprite para dibujar el aura del jugador con el poder a tope std::unique_ptr<AnimatedSprite> power_sprite_; // Sprite para dibujar el aura del jugador con el poder a tope
std::unique_ptr<EnterName> enter_name_; // Clase utilizada para introducir el nombre std::unique_ptr<EnterName> enter_name_; // Clase utilizada para introducir el nombre
SDL_Rect *play_area_; // Rectangulo con la zona de juego
// Variables // Variables
int id_; // Numero de identificación para el jugador int id_; // Numero de identificación para el jugador. Player1 = 1, Player2 = 2
float pos_x_; // Posicion en el eje X SDL_Rect play_area_; // Rectangulo con la zona de juego
int pos_y_; // Posicion en el eje Y float pos_x_ = 0.0f; // Posicion en el eje X
float default_pos_x_; // Posición inicial para el jugador int pos_y_ = 0; // Posicion en el eje Y
int default_pos_y_; // Posición inicial para el jugador float default_pos_x_; // Posición inicial para el jugador
int width_; // Anchura int default_pos_y_; // Posición inicial para el jugador
int height_; // Altura float vel_x_ = 0.0f; // Cantidad de pixeles a desplazarse en el eje X
float vel_x_; // Cantidad de pixeles a desplazarse en el eje X int vel_y_ = 0.0f; // Cantidad de pixeles a desplazarse en el eje Y
int vel_y_; // Cantidad de pixeles a desplazarse en el eje Y int cooldown_ = 10; // Contador durante el cual no puede disparar
float base_speed_; // Velocidad base del jugador int score_ = 0; // Puntos del jugador
int cooldown_; // Contador durante el cual no puede disparar float score_multiplier_ = 1.0f; // Multiplicador de puntos
int score_; // Puntos del jugador PlayerStatus status_walking_ = PlayerStatus::WALKING_STOP; // Estado del jugador al moverse
float score_multiplier_; // Multiplicador de puntos PlayerStatus status_firing_ = PlayerStatus::FIRING_NONE; // Estado del jugador al disparar
PlayerStatus status_walking_; // Estado del jugador al moverse PlayerStatus status_playing_ = PlayerStatus::WAITING; // Estado del jugador en el juego
PlayerStatus status_firing_; // Estado del jugador al disparar bool invulnerable_ = true; // Indica si el jugador es invulnerable
PlayerStatus status_playing_; // Estado del jugador en el juego int invulnerable_counter_ = INVULNERABLE_COUNTER_; // Contador para la invulnerabilidad
bool invulnerable_; // Indica si el jugador es invulnerable bool extra_hit_ = false; // Indica si el jugador tiene un toque extra
int invulnerable_counter_; // Contador para la invulnerabilidad int coffees_ = 0; // Indica cuantos cafes lleva acumulados
bool extra_hit_; // Indica si el jugador tiene un toque extra bool power_up_ = false; // Indica si el jugador tiene activo el modo PowerUp
int coffees_; // Indica cuantos cafes lleva acumulados int power_up_counter_ = POWERUP_COUNTER_; // Temporizador para el modo PowerUp
bool power_up_; // Indica si el jugador tiene activo el modo PowerUp int power_up_desp_x_ = 0; // Desplazamiento del sprite de PowerUp respecto al sprite del jugador
int power_up_counter_; // Temporizador para el modo PowerUp Circle collider_ = Circle(0, 0, 9); // Circulo de colisión del jugador
int power_up_desp_x_; // Desplazamiento del sprite de PowerUp respecto al sprite del jugador int continue_counter_ = 10; // Contador para poder continuar
bool input_; // Indica si puede recibir ordenes de entrada Uint32 continue_ticks_ = 0; // Variable para poder cambiar el contador de continue en función del tiempo
Circle collider_; // Circulo de colisión del jugador int scoreboard_panel_ = 0; // Panel del marcador asociado al jugador
int continue_counter_; // Contador para poder continuar std::string name_; // Nombre del jugador
Uint32 continue_ticks_; // Variable para poder cambiar el contador de continue en función del tiempo std::string record_name_; // Nombre del jugador para la tabla de mejores puntuaciones
int scoreboard_panel_; // Panel del marcador asociado al jugador int controller_index_ = 0; // Indice del array de mandos que utilizará para moverse
std::string name_; // Nombre del jugador bool demo_; // Para que el jugador sepa si está en el modo demostración
std::string record_name_; // Nombre del jugador para la tabla de mejores puntuaciones int enter_name_counter_; // Contador para poner nombre
int controller_index_; // Indice del array de mandos que utilizará para moverse Uint32 enter_name_ticks_ = 0; // Variable para poder cambiar el contador de poner nombre en función del tiempo
bool demo_; // Para que el jugador sepa si está en el modo demostración
int enter_name_counter_; // Contador para poner nombre
Uint32 enter_name_ticks_; // Variable para poder cambiar el contador de poner nombre en función del tiempo
// Actualiza el circulo de colisión a la posición del jugador // Actualiza el circulo de colisión a la posición del jugador
void shiftColliders(); void shiftColliders();
@@ -113,7 +113,7 @@ private:
public: public:
// Constructor // Constructor
Player(int id, float x, int y, bool demo, SDL_Rect *play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations); Player(int id, float x, int y, bool demo, SDL_Rect &play_area, std::vector<std::shared_ptr<Texture>> texture, const std::vector<std::vector<std::string>> &animations);
// Destructor // Destructor
~Player() = default; ~Player() = default;
@@ -245,7 +245,7 @@ public:
void setPowerUpCounter(int value); void setPowerUpCounter(int value);
// Actualiza el valor de la variable // Actualiza el valor de la variable
void updatePowerUpCounter(); void updatePowerUp();
// Obtiene el valor de la variable // Obtiene el valor de la variable
bool hasExtraHit() const; bool hasExtraHit() const;
@@ -256,12 +256,6 @@ public:
// Quita el toque extra al jugador // Quita el toque extra al jugador
void removeExtraHit(); void removeExtraHit();
// Habilita la entrada de ordenes
void enableInput();
// Deshabilita la entrada de ordenes
void disableInput();
// Devuelve el número de cafes actuales // Devuelve el número de cafes actuales
int getCoffees() const; int getCoffees() const;

View File

@@ -1,7 +1,12 @@
#include <iostream>
#include "resource.h" #include "resource.h"
#include "asset.h" #include <algorithm> // Para find_if
#include "screen.h" #include <iostream> // Para basic_ostream, operator<<, endl, cout, cerr
#include <stdexcept> // Para runtime_error
#include "asset.h" // Para Asset, AssetType
#include "jail_audio.h" // Para JA_LoadMusic, JA_LoadSound
#include "screen.h" // Para Screen
struct JA_Music_t;
struct JA_Sound_t;
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
Resource *Resource::resource_ = nullptr; Resource *Resource::resource_ = nullptr;
@@ -33,6 +38,8 @@ Resource::Resource()
loadTextures(); loadTextures();
loadTextFiles(); loadTextFiles();
loadAnimations(); loadAnimations();
loadDemoData();
addPalettes();
std::cout << "\n** RESOURCES LOADED" << std::endl; std::cout << "\n** RESOURCES LOADED" << std::endl;
} }
@@ -49,13 +56,14 @@ Resource::~Resource()
// Obtiene el sonido a partir de un nombre // Obtiene el sonido a partir de un nombre
JA_Sound_t *Resource::getSound(const std::string &name) JA_Sound_t *Resource::getSound(const std::string &name)
{ {
for (const auto &s : sounds_) auto it = std::find_if(sounds_.begin(), sounds_.end(), [&name](const auto &s)
{ return s.name == name; });
if (it != sounds_.end())
{ {
if (s.name == name) return it->sound;
{
return s.sound;
}
} }
std::cerr << "Error: Sonido no encontrado " << name << std::endl; std::cerr << "Error: Sonido no encontrado " << name << std::endl;
throw std::runtime_error("Sonido no encontrado: " + name); throw std::runtime_error("Sonido no encontrado: " + name);
} }
@@ -63,13 +71,14 @@ JA_Sound_t *Resource::getSound(const std::string &name)
// Obtiene la música a partir de un nombre // Obtiene la música a partir de un nombre
JA_Music_t *Resource::getMusic(const std::string &name) JA_Music_t *Resource::getMusic(const std::string &name)
{ {
for (const auto &m : musics_) auto it = std::find_if(musics_.begin(), musics_.end(), [&name](const auto &m)
{ return m.name == name; });
if (it != musics_.end())
{ {
if (m.name == name) return it->music;
{
return m.music;
}
} }
std::cerr << "Error: Música no encontrada " << name << std::endl; std::cerr << "Error: Música no encontrada " << name << std::endl;
throw std::runtime_error("Música no encontrada: " + name); throw std::runtime_error("Música no encontrada: " + name);
} }
@@ -77,13 +86,14 @@ JA_Music_t *Resource::getMusic(const std::string &name)
// Obtiene la textura a partir de un nombre // Obtiene la textura a partir de un nombre
std::shared_ptr<Texture> Resource::getTexture(const std::string &name) std::shared_ptr<Texture> Resource::getTexture(const std::string &name)
{ {
for (const auto &t : textures_) auto it = std::find_if(textures_.begin(), textures_.end(), [&name](const auto &t)
{ return t.name == name; });
if (it != textures_.end())
{ {
if (t.name == name) return it->texture;
{
return t.texture;
}
} }
std::cerr << "Error: Imagen no encontrada " << name << std::endl; std::cerr << "Error: Imagen no encontrada " << name << std::endl;
throw std::runtime_error("Imagen no encontrada: " + name); throw std::runtime_error("Imagen no encontrada: " + name);
} }
@@ -91,48 +101,49 @@ std::shared_ptr<Texture> Resource::getTexture(const std::string &name)
// Obtiene el fichero de texto a partir de un nombre // Obtiene el fichero de texto a partir de un nombre
std::shared_ptr<TextFile> Resource::getTextFile(const std::string &name) std::shared_ptr<TextFile> Resource::getTextFile(const std::string &name)
{ {
for (const auto &t : text_files_) auto it = std::find_if(text_files_.begin(), text_files_.end(), [&name](const auto &t)
{ return t.name == name; });
if (it != text_files_.end())
{ {
if (t.name == name) return it->text_file;
{
return t.text_file;
}
} }
std::cerr << "Error: TextFile no encontrado " << name << std::endl; std::cerr << "Error: TextFile no encontrado " << name << std::endl;
throw std::runtime_error("TextFile no encontrado: " + name); throw std::runtime_error("TextFile no encontrado: " + name);
} }
// Obtiene la animación a partir de un nombre // Obtiene la animación a partir de un nombre
Animations &Resource::getAnimation(const std::string &name) AnimationsFileBuffer &Resource::getAnimation(const std::string &name)
{ {
for (auto &a : animations_) auto it = std::find_if(animations_.begin(), animations_.end(), [&name](const auto &a)
{ return a.name == name; });
if (it != animations_.end())
{ {
if (a.name == name) return it->animation;
{
return a.animation;
}
} }
std::cerr << "Error: Animación no encontrada " << name << std::endl; std::cerr << "Error: Animación no encontrada " << name << std::endl;
throw std::runtime_error("Animación no encontrada: " + name); throw std::runtime_error("Animación no encontrada: " + name);
} }
// Obtiene el fichero con los datos para el modo demostración a partir de un çindice
DemoData &Resource::getDemoData(int index)
{
return demos_.at(index);
}
// Carga los sonidos // Carga los sonidos
void Resource::loadSounds() void Resource::loadSounds()
{ {
std::cout << "\n>> SOUND FILES" << std::endl; std::cout << "\n>> SOUND FILES" << std::endl;
// Obtiene la lista con las rutas a los ficheros de sonidos
auto list = Asset::get()->getListByType(AssetType::SOUND); auto list = Asset::get()->getListByType(AssetType::SOUND);
sounds_.clear(); sounds_.clear();
for (const auto &l : list) for (const auto &l : list)
{ {
// Encuentra el último índice de '/' auto name = getFileName(l);
auto last_index = l.find_last_of('/') + 1;
// Obtiene la subcadena desde el último '/'
auto name = l.substr(last_index);
sounds_.emplace_back(ResourceSound(name, JA_LoadSound(l.c_str()))); sounds_.emplace_back(ResourceSound(name, JA_LoadSound(l.c_str())));
printWithDots("Sound : ", name, "[ LOADED ]"); printWithDots("Sound : ", name, "[ LOADED ]");
} }
@@ -142,19 +153,12 @@ void Resource::loadSounds()
void Resource::loadMusics() void Resource::loadMusics()
{ {
std::cout << "\n>> MUSIC FILES" << std::endl; std::cout << "\n>> MUSIC FILES" << std::endl;
// Obtiene la lista con las rutas a los ficheros musicales
auto list = Asset::get()->getListByType(AssetType::MUSIC); auto list = Asset::get()->getListByType(AssetType::MUSIC);
musics_.clear(); musics_.clear();
for (const auto &l : list) for (const auto &l : list)
{ {
// Encuentra el último índice de '/' auto name = getFileName(l);
auto last_index = l.find_last_of('/') + 1;
// Obtiene la subcadena desde el último '/'
auto name = l.substr(last_index);
musics_.emplace_back(ResourceMusic(name, JA_LoadMusic(l.c_str()))); musics_.emplace_back(ResourceMusic(name, JA_LoadMusic(l.c_str())));
printWithDots("Music : ", name, "[ LOADED ]"); printWithDots("Music : ", name, "[ LOADED ]");
} }
@@ -164,19 +168,12 @@ void Resource::loadMusics()
void Resource::loadTextures() void Resource::loadTextures()
{ {
std::cout << "\n>> TEXTURES" << std::endl; std::cout << "\n>> TEXTURES" << std::endl;
// Obtiene la lista con las rutas a los ficheros png
auto list = Asset::get()->getListByType(AssetType::BITMAP); auto list = Asset::get()->getListByType(AssetType::BITMAP);
textures_.clear(); textures_.clear();
for (const auto &l : list) for (const auto &l : list)
{ {
// Encuentra el último índice de '/' auto name = getFileName(l);
auto last_index = l.find_last_of('/') + 1;
// Obtiene la subcadena desde el último '/'
auto name = l.substr(last_index);
textures_.emplace_back(ResourceTexture(name, std::make_shared<Texture>(Screen::get()->getRenderer(), l))); textures_.emplace_back(ResourceTexture(name, std::make_shared<Texture>(Screen::get()->getRenderer(), l)));
} }
} }
@@ -185,18 +182,12 @@ void Resource::loadTextures()
void Resource::loadTextFiles() void Resource::loadTextFiles()
{ {
std::cout << "\n>> TEXT FILES" << std::endl; std::cout << "\n>> TEXT FILES" << std::endl;
// Obtiene la lista con las rutas a los ficheros png
auto list = Asset::get()->getListByType(AssetType::FONT); auto list = Asset::get()->getListByType(AssetType::FONT);
text_files_.clear(); text_files_.clear();
for (const auto &l : list) for (const auto &l : list)
{ {
// Encuentra el último índice de '/' auto name = getFileName(l);
auto last_index = l.find_last_of('/') + 1;
// Obtiene la subcadena desde el último '/'
auto name = l.substr(last_index);
text_files_.emplace_back(ResourceTextFile(name, loadTextFile(l))); text_files_.emplace_back(ResourceTextFile(name, loadTextFile(l)));
} }
} }
@@ -205,18 +196,38 @@ void Resource::loadTextFiles()
void Resource::loadAnimations() void Resource::loadAnimations()
{ {
std::cout << "\n>> ANIMATIONS" << std::endl; std::cout << "\n>> ANIMATIONS" << std::endl;
// Obtiene la lista con las rutas a los ficheros ani
auto list = Asset::get()->getListByType(AssetType::ANIMATION); auto list = Asset::get()->getListByType(AssetType::ANIMATION);
animations_.clear(); animations_.clear();
for (const auto &l : list) for (const auto &l : list)
{ {
// Encuentra el último índice de '/' auto name = getFileName(l);
auto last_index = l.find_last_of('/') + 1;
// Obtiene la subcadena desde el último '/'
auto name = l.substr(last_index);
animations_.emplace_back(ResourceAnimation(name, loadAnimationsFromFile(l))); animations_.emplace_back(ResourceAnimation(name, loadAnimationsFromFile(l)));
} }
}
// Carga los datos para el modo demostración
void Resource::loadDemoData()
{
std::cout << "\n>> DEMO_FILES" << std::endl;
demos_.emplace_back(loadDemoDataFromFile(Asset::get()->get("demo1.bin")));
demos_.emplace_back(loadDemoDataFromFile(Asset::get()->get("demo2.bin")));
}
// Añade paletas a las texturas
void Resource::addPalettes()
{
// Jugador 1
std::cout << "\n>> PALETTES" << std::endl;
getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_one_coffee_palette.pal"));
getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_two_coffee_palette.pal"));
getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_all_white_palette.pal"));
// Jugador 2
getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_one_coffee_palette.pal"));
getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_two_coffee_palette.pal"));
getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_all_white_palette.pal"));
// Fuentes
getTexture("smb2.gif")->addPaletteFromFile(Asset::get()->get("smb2_palette1.pal"));
} }

View File

@@ -1,13 +1,14 @@
#pragma once #pragma once
#include <SDL2/SDL.h> #include <memory> // Para shared_ptr
#include <vector> #include <string> // Para string
#include <memory> #include <vector> // Para vector
#include <string> #include "animated_sprite.h" // Para AnimationsFileBuffer
#include "jail_audio.h" #include "text.h" // Para TextFile
#include "texture.h" #include "texture.h" // Para Texture
#include "text.h" #include "utils.h" // Para DemoData
#include "animated_sprite.h" struct JA_Music_t;
struct JA_Sound_t;
// Estructura para almacenar ficheros de sonido y su nombre // Estructura para almacenar ficheros de sonido y su nombre
struct ResourceSound struct ResourceSound
@@ -56,11 +57,11 @@ struct ResourceTextFile
// Estructura para almacenar ficheros animaciones y su nombre // Estructura para almacenar ficheros animaciones y su nombre
struct ResourceAnimation struct ResourceAnimation
{ {
std::string name; // Nombre del fichero std::string name; // Nombre del fichero
Animations animation; // Objeto con las animaciones AnimationsFileBuffer animation; // Objeto con las animaciones
// Constructor // Constructor
ResourceAnimation(const std::string &name, Animations animation) ResourceAnimation(const std::string &name, const AnimationsFileBuffer &animation)
: name(name), animation(animation) {} : name(name), animation(animation) {}
}; };
@@ -75,6 +76,7 @@ private:
std::vector<ResourceTexture> textures_; // Vector con las musicas std::vector<ResourceTexture> textures_; // Vector con las musicas
std::vector<ResourceTextFile> text_files_; // Vector con los ficheros de texto std::vector<ResourceTextFile> text_files_; // Vector con los ficheros de texto
std::vector<ResourceAnimation> animations_; // Vector con las animaciones std::vector<ResourceAnimation> animations_; // Vector con las animaciones
std::vector<DemoData> demos_; // Vector con los ficheros de datos para el modo demostración
// Carga los sonidos // Carga los sonidos
void loadSounds(); void loadSounds();
@@ -91,6 +93,12 @@ private:
// Carga las animaciones // Carga las animaciones
void loadAnimations(); void loadAnimations();
// Carga los datos para el modo demostración
void loadDemoData();
// Añade paletas a las texturas
void addPalettes();
// [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos resource desde fuera // [SINGLETON] Ahora el constructor y el destructor son privados, para no poder crear objetos resource desde fuera
// Constructor // Constructor
@@ -122,5 +130,8 @@ public:
std::shared_ptr<TextFile> getTextFile(const std::string &name); std::shared_ptr<TextFile> getTextFile(const std::string &name);
// Obtiene la animación a partir de un nombre // Obtiene la animación a partir de un nombre
Animations &getAnimation(const std::string &name); AnimationsFileBuffer &getAnimation(const std::string &name);
// Obtiene el fichero con los datos para el modo demostración a partir de un çindice
DemoData &getDemoData(int index);
}; };

View File

@@ -1,24 +1,23 @@
#include "scoreboard.h" #include "scoreboard.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // Para SDL_GetTicks
#include <math.h> // for roundf #include <math.h> // Para roundf
#include <iomanip> #include <iomanip> // Para operator<<, setfill, setw
#include <sstream> #include <sstream> // Para basic_ostream, basic_ostringstream
#include "asset.h" // for Asset #include "lang.h" // Para getText
#include "lang.h" // for getText #include "resource.h" // Para Resource
#include "resource.h" // for Resource #include "screen.h" // Para Screen
#include "sprite.h" // for Sprite #include "sprite.h" // Para Sprite
#include "text.h" // for Text #include "text.h" // Para Text
#include "texture.h" // for Texture
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
Scoreboard *Scoreboard::scoreboard_ = nullptr; Scoreboard *Scoreboard::scoreboard_ = nullptr;
// [SINGLETON] Crearemos el objeto score_board con esta función estática // [SINGLETON] Crearemos el objeto score_board con esta función estática
void Scoreboard::init(SDL_Renderer *renderer) void Scoreboard::init()
{ {
Scoreboard::scoreboard_ = new Scoreboard(renderer); Scoreboard::scoreboard_ = new Scoreboard();
} }
// [SINGLETON] Destruiremos el objeto score_board con esta función estática // [SINGLETON] Destruiremos el objeto score_board con esta función estática
@@ -34,21 +33,11 @@ Scoreboard *Scoreboard::get()
} }
// Constructor // Constructor
Scoreboard::Scoreboard(SDL_Renderer *renderer) Scoreboard::Scoreboard()
: renderer_(renderer), : renderer_(Screen::get()->getRenderer()),
game_power_meter_texture_(Resource::get()->getTexture("game_power_meter.png")), game_power_meter_texture_(Resource::get()->getTexture("game_power_meter.png")),
power_meter_sprite_(std::make_unique<Sprite>(game_power_meter_texture_)), power_meter_sprite_(std::make_unique<Sprite>(game_power_meter_texture_)),
text_scoreboard_(std::make_unique<Text>(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt"))), text_scoreboard_(std::make_unique<Text>(Resource::get()->getTexture("8bithud.png"), Resource::get()->getTextFile("8bithud.txt")))
stage_(1),
hi_score_(0),
power_(0),
hi_score_name_(std::string()),
color_({0, 0, 0}),
rect_({0, 0, 320, 40}),
ticks_(SDL_GetTicks()),
counter_(0)
{ {
// Inicializa variables // Inicializa variables
for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i) for (int i = 0; i < SCOREBOARD_MAX_PANELS; ++i)
@@ -107,7 +96,9 @@ std::string Scoreboard::updateScoreText(int num)
// Actualiza el contador // Actualiza el contador
void Scoreboard::updateCounter() void Scoreboard::updateCounter()
{ {
if (SDL_GetTicks() - ticks_ > SCOREBOARD_TICK_SPEED) constexpr int TICKS_SPEED = 100;
if (SDL_GetTicks() - ticks_ > TICKS_SPEED)
{ {
ticks_ = SDL_GetTicks(); ticks_ = SDL_GetTicks();
counter_++; counter_++;

View File

@@ -1,12 +1,13 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Point, SDL_Rect #include <SDL2/SDL_rect.h> // para SDL_Point, SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // para SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // para Uint32
#include <memory> // for unique_ptr, shared_ptr #include <SDL2/SDL_timer.h> // para SDL_GetTicks
#include <string> // for string #include <memory> // para unique_ptr, shared_ptr
#include <vector> // for vector #include <string> // para string
#include "utils.h" // for Color #include <vector> // para vector
#include "utils.h" // para Color
class Sprite; class Sprite;
class Text; class Text;
class Texture; class Texture;
@@ -16,7 +17,6 @@ constexpr int SCOREBOARD_LEFT_PANEL = 0;
constexpr int SCOREBOARD_CENTER_PANEL = 1; constexpr int SCOREBOARD_CENTER_PANEL = 1;
constexpr int SCOREBOARD_RIGHT_PANEL = 2; constexpr int SCOREBOARD_RIGHT_PANEL = 2;
constexpr int SCOREBOARD_MAX_PANELS = 3; constexpr int SCOREBOARD_MAX_PANELS = 3;
constexpr int SCOREBOARD_TICK_SPEED = 100;
// Enums // Enums
enum class ScoreboardMode : int enum class ScoreboardMode : int
@@ -52,25 +52,25 @@ private:
std::unique_ptr<Sprite> power_meter_sprite_; // Sprite para el medidor de poder de la fase std::unique_ptr<Sprite> power_meter_sprite_; // Sprite para el medidor de poder de la fase
std::unique_ptr<Text> text_scoreboard_; // Fuente para el marcador del juego std::unique_ptr<Text> text_scoreboard_; // Fuente para el marcador del juego
SDL_Texture *background_; // Textura para dibujar el marcador SDL_Texture *background_ = nullptr; // Textura para dibujar el marcador
std::vector<SDL_Texture *> panel_texture_; // Texturas para dibujar cada panel std::vector<SDL_Texture *> panel_texture_; // Texturas para dibujar cada panel
// Variables // Variables
std::string name_[SCOREBOARD_MAX_PANELS]; // Nom de cada jugador std::string name_[SCOREBOARD_MAX_PANELS] = {}; // Nom de cada jugador
std::string record_name_[SCOREBOARD_MAX_PANELS]; // Nombre introducido para la tabla de records std::string record_name_[SCOREBOARD_MAX_PANELS] = {}; // Nombre introducido para la tabla de records
int selector_pos_[SCOREBOARD_MAX_PANELS]; // Posición del selector de letra para introducir el nombre int selector_pos_[SCOREBOARD_MAX_PANELS] = {}; // Posición del selector de letra para introducir el nombre
int score_[SCOREBOARD_MAX_PANELS]; // Puntuación de los jugadores int score_[SCOREBOARD_MAX_PANELS] = {}; // Puntuación de los jugadores
float mult_[SCOREBOARD_MAX_PANELS]; // Multiplicador de los jugadores float mult_[SCOREBOARD_MAX_PANELS] = {}; // Multiplicador de los jugadores
int continue_counter_[SCOREBOARD_MAX_PANELS]; // Tiempo para continuar de los jugadores int continue_counter_[SCOREBOARD_MAX_PANELS] = {}; // Tiempo para continuar de los jugadores
Panel panel_[SCOREBOARD_MAX_PANELS]; // Lista con todos los paneles del marcador Panel panel_[SCOREBOARD_MAX_PANELS] = {}; // Lista con todos los paneles del marcador
int stage_; // Número de fase actual int stage_ = 1; // Número de fase actual
int hi_score_; // Máxima puntuación int hi_score_ = 0; // Máxima puntuación
float power_; // Poder actual de la fase float power_ = 0; // Poder actual de la fase
std::string hi_score_name_; // Nombre del jugador con la máxima puntuación std::string hi_score_name_ = std::string(); // Nombre del jugador con la máxima puntuación
Color color_; // Color del marcador Color color_ = Color(); // Color del marcador
SDL_Rect rect_; // Posición y dimensiones del marcador SDL_Rect rect_ = {0, 0, 320, 40}; // Posición y dimensiones del marcador
Uint32 ticks_; // Variable donde almacenar el valor de SDL_GetTiks() Uint32 ticks_ = SDL_GetTicks(); // Variable donde almacenar el valor de SDL_GetTiks()
int counter_; // Contador int counter_ = 0; // Contador
// Puntos predefinidos para colocar elementos en los paneles // Puntos predefinidos para colocar elementos en los paneles
SDL_Point slot4_1_, slot4_2_, slot4_3_, slot4_4_; SDL_Point slot4_1_, slot4_2_, slot4_3_, slot4_4_;
@@ -103,14 +103,14 @@ private:
// [SINGLETON] Ahora el constructor y el destructor son privados // [SINGLETON] Ahora el constructor y el destructor son privados
// Constructor // Constructor
explicit Scoreboard(SDL_Renderer *renderer); Scoreboard();
// Destructor // Destructor
~Scoreboard(); ~Scoreboard();
public: public:
// [SINGLETON] Crearemos el objeto scoreboard con esta función estática // [SINGLETON] Crearemos el objeto scoreboard con esta función estática
static void init(SDL_Renderer *renderer); static void init();
// [SINGLETON] Destruiremos el objeto scoreboard con esta función estática // [SINGLETON] Destruiremos el objeto scoreboard con esta función estática
static void destroy(); static void destroy();

View File

@@ -1,24 +1,23 @@
#include "screen.h" #include "screen.h"
#include <SDL2/SDL_events.h> // for SDL_DISABLE, SDL_ENABLE #include <SDL2/SDL_events.h> // Para SDL_DISABLE, SDL_ENABLE
#include <SDL2/SDL_mouse.h> // for SDL_ShowCursor #include <SDL2/SDL_mouse.h> // Para SDL_ShowCursor
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // Para SDL_GetTicks
#include <algorithm> // for max, min #include <algorithm> // Para clamp, max, min
#include <fstream> // for basic_ifstream, ifstream #include <fstream> // Para basic_ifstream, ifstream
#include <iterator> // for istreambuf_iterator, operator!= #include <iterator> // Para istreambuf_iterator, operator==
#include <string> // for basic_string, operator+, to_string, cha... #include <string> // Para allocator, operator+, to_string, char_t...
#include <vector> // for vector #include <vector> // Para vector
#include "asset.h" // for Asset #include "asset.h" // Para Asset
#include "dbgtxt.h" // for dbg_print #include "dbgtxt.h" // Para dbg_print
#include "global_inputs.h" // for servicePressedCounter #include "global_inputs.h" // Para service_pressed_counter
#include "input.h" // for Input, inputs_e, INPUT_DO_NOT_ALLOW_REPEAT #include "input.h" // Para Input, InputType, INPUT_DO_NOT_ALLOW_RE...
#include "notifier.h" // for Notify #include "notifier.h" // Para Notifier
#include "on_screen_help.h" // for OnScreenHelp #include "on_screen_help.h" // Para OnScreenHelp
#include "options.h" // for options #include "options.h" // Para Options, OptionsVideo, options, Options...
#include "param.h" // for param
#ifndef NO_SHADERS #ifndef NO_SHADERS
#include "jail_shader.h" // for init, render #include "jail_shader.h" // para init, render
#endif #endif
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
@@ -46,36 +45,12 @@ Screen *Screen::get()
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
: window_(window), : window_(window),
renderer_(renderer), renderer_(renderer),
game_canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), game_canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
shader_canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)), shader_canvas_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
src_rect_({0, 0, param.game.width, param.game.height}), src_rect_({0, 0, param.game.width, param.game.height}),
dst_rect_({0, 0, param.game.width, param.game.height}), dst_rect_({0, 0, param.game.width, param.game.height})
border_color_({0x00, 0x00, 0x00}),
attenuate_effect_(false),
fps_ticks_(0),
fps_counter_(0),
fps_(0),
#ifdef DEBUG
show_info_(true)
#else
show_info_(false)
#endif
{ {
// Inicializa variables // Inicializa variables
flash_effect_.enabled = false;
flash_effect_.counter = 0;
flash_effect_.lenght = 0;
flash_effect_.color = {0xFF, 0xFF, 0xFF};
shake_effect_.enabled = false;
shake_effect_.desp = 2;
shake_effect_.delay = 3;
shake_effect_.counter = 0;
shake_effect_.lenght = 8;
shake_effect_.remaining = 0;
shake_effect_.originalPos = 0;
shake_effect_.originalWidth = param.game.width;
SDL_DisplayMode DM; SDL_DisplayMode DM;
SDL_GetCurrentDisplayMode(0, &DM); SDL_GetCurrentDisplayMode(0, &DM);
info_resolution_ = std::to_string(DM.w) + " X " + std::to_string(DM.h) + " AT " + std::to_string(DM.refresh_rate) + " HZ"; info_resolution_ = std::to_string(DM.w) + " X " + std::to_string(DM.h) + " AT " + std::to_string(DM.refresh_rate) + " HZ";
@@ -480,7 +455,9 @@ void Screen::displayInfo()
// Resolution // Resolution
dbg_print(0, 0, info_resolution_.c_str(), 255, 255, 0); dbg_print(0, 0, info_resolution_.c_str(), 255, 255, 0);
dbg_print(0, 8, std::to_string(globalInputs::service_pressed_counter[0]).c_str(), 255, 255, 0); // Contador de service_pressed_counter
if (const int counter = globalInputs::service_pressed_counter[0]; counter > 0)
dbg_print(0, 8, std::to_string(counter).c_str(), 255, 0, 255);
} }
} }

Some files were not shown because too many files have changed in this diff Show More