55 Commits

Author SHA1 Message Date
e46a346d20 Trabajando con las animaciones del jugador 2022-09-29 14:02:13 +02:00
15b73f1d2c TITULO bastante avanzado, se deja para el final ya que falta ver elmodo demo y demas 2022-09-29 11:22:29 +02:00
fd90a3c66c Corregido el bug de la asignacion de items del menu de la intro 2022-09-28 22:23:26 +02:00
3d75fae393 Error raro en el constructor del menu 2022-09-28 21:12:26 +02:00
6df5d484bc No se pq no funciona al cargar los items del menu 2022-09-28 20:26:35 +02:00
e2298dc2b2 Ya empieza a funcionar la INTRO 2022-09-28 19:41:12 +02:00
c213124193 Trabajando en la INTRO 2022-09-28 18:52:19 +02:00
2209ed5f97 Trabajando en el TITULO 2022-09-28 14:03:45 +02:00
1552f6385c INTRO optimizada y revisada 2022-09-28 11:48:01 +02:00
072a488de6 Ya funciona la INTRO 2022-09-28 09:48:55 +02:00
8b2459dc35 Trabajando en la INTRO 2022-09-27 22:39:27 +02:00
10882780e5 Revisada la clase DIRECTOR 2022-09-27 19:34:13 +02:00
96ee1fdbe5 Eliminado el fichero coffeedrop 2022-09-27 19:04:25 +02:00
50e31a3db3 LOGO funcional 2022-09-27 19:03:24 +02:00
740e495ad0 Ya compila 2022-09-27 14:02:16 +02:00
2528969801 He quitado todos lo errores. No va a funcionar 2022-09-27 13:35:39 +02:00
8d56912765 Actualizando el código 2022-09-27 13:06:04 +02:00
c8bebfd2d9 Me voy a la cama. Sigo con la reescritura de todo el código 2022-09-26 22:25:46 +02:00
35e7abcd3c se va la luz 2022-09-26 18:18:27 +02:00
b092d3f86a Trabajando en la reescritura del código 2022-09-26 14:06:44 +02:00
837bcbd1da menudo berenjenal. sigo con la integracion con las ultimas versiones de mis librerias 2022-09-26 11:18:50 +02:00
26bc47d9f6 Actualizando las librerias a la ultima versión 2022-09-26 10:34:45 +02:00
9e089e9092 Añadiendo la clase asset 2022-09-26 10:17:54 +02:00
25616e1e6c Ya permite continuar 2022-09-25 23:16:20 +02:00
ed67e429d8 Trabajando en poder continuar la partida al morir 2022-09-25 22:45:09 +02:00
4ebd034b59 Cambiado un poco el outline de la fuente nokia_big2 2022-09-25 22:24:41 +02:00
38f3e2e4d3 Limpieza de código no usado 2022-09-25 21:27:12 +02:00
6493b73f4f Cambiados NULL por nullptr 2022-09-25 21:22:59 +02:00
6637ba9f10 Actualizado a la última versión de ltexture 2022-09-25 21:11:17 +02:00
a74c8d5122 Eliminado codigo sin usar 2022-09-25 20:17:06 +02:00
4df0db088f Organización de código 2022-09-25 20:10:31 +02:00
27cb772933 corregido el offset de la m en nokia_big2 2022-09-25 19:40:39 +02:00
778b07cce1 Modificado el texto al cambiar de pantalla. Quitado texto no usado 2022-09-25 19:38:03 +02:00
1fa5c75466 Actualizado README.md 2022-09-25 19:01:13 +02:00
0b00acf31b Cambiado el numero de versión 2022-09-25 18:59:35 +02:00
2979a6752c Limpieza de código. Añadida la última versión de jail_audio 2022-09-25 18:44:58 +02:00
f6494e69c8 Cambiado el idioma por defecto a valenciano 2022-08-21 10:10:09 +02:00
5167a5857d Cambiada la frecuencia a 48000Hz de dos pistas de audio 2022-08-21 10:05:38 +02:00
28fe1130cf Merge branch 'master' of https://gitea.sustancia.synology.me/JailDesigner/coffee_crisis 2022-08-07 12:53:41 +02:00
e92b7eab4e limpieza de archivos 2022-08-07 12:53:14 +02:00
14f7a79927 Actualizar 'README.md' 2022-08-05 23:13:55 +02:00
4f6a6a4918 Actualizar 'Makefile' 2021-09-20 13:48:59 +02:00
f5b35cee6b Trabajando en la versión de opendingux 2021-09-17 20:55:36 +02:00
454791fe96 Añadidos modos en pantalla completa para el escalado entero y mantener la relación de aspecto 2021-09-15 11:48:57 +02:00
3f165be114 Commit para seguir en otro ordenador 2021-09-15 06:37:54 +02:00
778672a6f5 Commit para seguir en otro ordenador 2021-09-14 22:52:25 +02:00
8c919abc9d Trabajando en el escalado entero y el tamaño personalizable de la ventana de renderizado a traves de las opciones 2021-09-14 21:15:52 +02:00
7e37da3999 Restituido ballong.png a los colores originales 2021-09-14 17:03:13 +02:00
842d5dd56b Limpieza de código 2021-09-11 09:06:53 +02:00
ea3f16b8ac Añadida la clase screen al código 2021-09-10 23:52:58 +02:00
3fe0861e4f Trabajando en integrar la clase screen 2021-09-10 23:04:52 +02:00
b28d798545 Actualizado el numero de versión 2021-09-10 20:55:46 +02:00
bdf092d46e Limpieza de código. Modificada la fuente nokiabig2. Puestas ayudas para los dos jugadores. Cambiado el tamaño del mensaje de juego completado 2021-09-10 20:46:24 +02:00
09421a093d Limpieza de código 2021-09-10 14:02:29 +02:00
a7d7cdd047 Modificados los graficos de los globos y del jugador 1. Rebajada la dificultad de las últimas pantallas descendiendo el nivel de amenaza 2021-09-10 10:55:01 +02:00
134 changed files with 6577 additions and 4982 deletions

11
.gitignore vendored
View File

@@ -1,12 +1,5 @@
.vscode
*.DS_Store
bin
data/config.bin
data/score.bin
dll
docs
icon
releases
resources
scripts
*.opk
*.DS_Store
data/score.bin

View File

@@ -6,4 +6,8 @@ macos:
linux:
mkdir -p bin
g++ source/*.cpp -std=c++11 -Os -lSDL2 -ffunction-sections -fdata-sections -Wl,--gc-sections -o bin/$(executable)_linux
strip -s -R .comment -R .gnu.version bin/$(executable)_linux --strip-unneeded
strip -s -R .comment -R .gnu.version bin/$(executable)_linux --strip-unneeded
opendingux:
mkdir -p bin
/opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc -D GCWZERO -O2 -std=c++11 -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include/SDL2 -D_GNU_SOURCE=1 -D_REENTRANT -lSDL2 -lSDL2_mixer -lstdc++ source/*.cpp -o bin/$(executable)_opendingux
/opt/gcw0-toolchain/usr/bin/mksquashfs ./default.gcw0.desktop ./icon.png ./bin ./data ./media coffee_crisis.opk -all-root -noappend -no-exports -no-xattrs

View File

@@ -1,6 +1,6 @@
# Coffee Crisis
Coffe Crisis es un juego arcade que pondrá a prueba tus reflejos. Empezado el verano de 2020 y terminado el verano de 2021. Intenta conseguir todos los puntos que puedas con una sola vida y ayuda a Bal1 a defender la UPV ante la invasión de la cafeína durante 10 estresantes oleadas.
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.
## Compilar

BIN
data/config/config.bin Normal file

Binary file not shown.

BIN
data/config/score.bin Normal file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
data/font/nokia_big2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -157,7 +157,7 @@
# 108 l
8
# 109 m
10
20
# 110 n
14
# 111 o

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

Before

Width:  |  Height:  |  Size: 644 B

After

Width:  |  Height:  |  Size: 644 B

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 795 B

After

Width:  |  Height:  |  Size: 795 B

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,9 @@
frameWidth=16
frameHeight=16
[animation]
name=default
speed=8
loop=-1
frames=0,1,2,3,4,5,6
[/animation]

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1,9 @@
frameWidth=16
frameHeight=16
[animation]
name=default
speed=8
loop=-1
frames=0,1,2,3,4,5,6
[/animation]

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,9 @@
frameWidth=16
frameHeight=16
[animation]
name=default
speed=8
loop=-1
frames=0,1,2,3,4,5,6
[/animation]

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,9 @@
frameWidth=16
frameHeight=16
[animation]
name=default
speed=8
loop=-1
frames=0,1,2,3,4,5,6
[/animation]

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

View File

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Before

Width:  |  Height:  |  Size: 654 B

After

Width:  |  Height:  |  Size: 654 B

BIN
data/gfx/title_bg_tile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

BIN
data/gfx/title_coffee.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
data/gfx/title_crisis.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

9
data/gfx/title_dust.ani Normal file
View File

@@ -0,0 +1,9 @@
frameWidth=16
frameHeight=16
[animation]
name=default
speed=8
loop=-1
frames=0,1,2,3,4,5,6
[/animation]

BIN
data/gfx/title_dust.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

BIN
data/gfx/title_gradient.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@@ -75,21 +75,21 @@ Temps detes:
## 37 - TEXTOS DEL JUEGO
D E M O
## 38 - TEXTOS DEL JUEGO
Pantalla
## 39 - MARCADOR
PUNTS
## 40 - MARCADOR
MAX.PUNT.
## 41 - MARCADOR
MULT
## 42 - MARCADOR
PANTALLA
fases mes!
## 39 -
## 40 -
## 41 -
## 42 -
## 43 - PANTALLA DE GAME OVER
FI DEL JOC
## 44 - PANTALLA DE GAME OVER
ELS TEUS PUNTS:
## 45 - PANTALLA DE GAME OVER
REINTENTAR?
CONTINUAR?
## 46 - MENU DE PAUSA
CONTINUAR
## 47 - MENU DE PAUSA
@@ -113,7 +113,7 @@ mult
## 56 MARCADOR
max. puntuacio
## 57 MARCADOR
pantalla
fase
## 58 - MENU DE OPCIONES
MODE DE VISUALITZACIO
## 59 - MENU DE OPCIONES
@@ -126,10 +126,10 @@ SINC. VERTICAL
CONTROLS DEL JUGADOR 1
## 63 - MENU DE OPCIONES
CONTROLS DEL JUGADOR 2
## 64 - MENU DE OPCIONES
TECLAT
## 65 - MENU DE OPCIONES
MANDO
## 64 -
## 65 -
## 66 - MENU DE OPCIONES
FACIL
## 67 - MENU DE OPCIONES
@@ -155,4 +155,6 @@ Endavant!
## 77 - PANTALLA DE GAME OVER
PUNTS J1:
## 78 - PANTALLA DE GAME OVER
PUNTS J2:
PUNTS J2:
## 79 - TEXTOS DEL JUEGO
Ultima fase!

View File

@@ -75,21 +75,21 @@ Time stopped:
## 37 - TEXTOS DEL JUEGO
D E M O
## 38 - TEXTOS DEL JUEGO
Stage
## 39 - MARCADOR
SCORE
## 40 - MARCADOR
HI-SCORE
## 41 - MARCADOR
MULT
## 42 - MARCADOR
STAGE
stages left!
## 39 -
## 40 -
## 41 -
## 42 -
## 43 - PANTALLA DE GAME OVER
GAME OVER
## 44 - PANTALLA DE GAME OVER
YOUR SCORE:
## 45 - PANTALLA DE GAME OVER
RETRY?
CONTINUE?
## 46 - MENU DE PAUSA
CONTINUE
## 47 - MENU DE PAUSA
@@ -126,10 +126,10 @@ VSYNC
PLAYER 1 CONTROLS
## 63 - MENU DE OPCIONES
PLAYER 2 CONTROLS
## 64 - MENU DE OPCIONES
KEYBOARD
## 65 - MENU DE OPCIONES
GAME CONTROLLER
## 64 -
## 65 -
## 66 - MENU DE OPCIONES
EASY
## 67 - MENU DE OPCIONES
@@ -155,4 +155,6 @@ Get Ready!
## 77 - PANTALLA DE GAME OVER
PLAYER1 SCORE:
## 78 - PANTALLA DE GAME OVER
PLAYER2 SCORE:
PLAYER2 SCORE:
## 79 - TEXTOS DEL JUEGO
Last stage!

View File

@@ -75,21 +75,21 @@ Tiempo:
## 37 - TEXTOS DEL JUEGO
D E M O
## 38 - TEXTOS DEL JUEGO
Fase
## 39 - MARCADOR
PUNTOS
## 40 - MARCADOR
MAX.PUNT.
## 41 - MARCADOR
MULT
## 42 - MARCADOR
FASE
fases mas!
## 39 -
## 40 -
## 41 -
## 42 -
## 43 - PANTALLA DE GAME OVER
FIN DE JUEGO
## 44 - PANTALLA DE GAME OVER
TU PUNTUACION:
## 45 - PANTALLA DE GAME OVER
REINTENTAR?
CONTINUAR?
## 46 - MENU DE PAUSA
CONTINUAR
## 47 - MENU DE PAUSA
@@ -113,7 +113,7 @@ mult
## 56 - MARCADOR
max. puntuacion
## 57 - MARCADOR
fase
FASE
## 58 - MENU DE OPCIONES
MODO DE VISUALIZACION
## 59 - MENU DE OPCIONES
@@ -126,10 +126,10 @@ SINC. VERTICAL
CONTROLES DEL JUGADOR 1
## 63 - MENU DE OPCIONES
CONTROLES DEL JUGADOR 2
## 64 - MENU DE OPCIONES
TECLADO
## 65 - MENU DE OPCIONES
MANDO
## 64 -
## 65 -
## 66 - MENU DE OPCIONES
FACIL
## 67 - MENU DE OPCIONES
@@ -155,4 +155,6 @@ Adelante!
## 77 - PANTALLA DE GAME OVER
PUNTUACION J1:
## 78 - PANTALLA DE GAME OVER
PUNTUACION J2:
PUNTUACION J2:
## 79 - TEXTOS DEL JUEGO
Ultima fase!

109
data/menu/options.men Normal file
View File

@@ -0,0 +1,109 @@
font_png=smb2.png
font_txt=smb2.txt
sound_cancel=menu_cancel.wav
sound_accept=menu_select.wav
sound_move=menu_move.wav
name=OPTIONS
x=0
y=116
backgroundType=0
backgroundColor=48,48,64,192
areElementsCenteredOnX=true
isCenteredOnX=true
centerX=128
isCenteredOnY=true
centerY=96
selector_color=229,28,35,255
selector_text_color=255,180,0
defaultActionWhenCancel=13
[item]
text=DIFFICULTY
hPaddingDown=7
[/item]
[item]
text=PLAYER 1 CONTROLS
hPaddingDown=2
selectable=true
greyed=false
linkedDown=true
[/item]
[item]
text=KEYBOARD
hPaddingDown=7
selectable=false
greyed=false
[/item]
[item]
text=PLAYER 2 CONTROLS
hPaddingDown=2
selectable=true
greyed=false
linkedDown=true
[/item]
[item]
text=GAME CONTROLLER
hPaddingDown=7
selectable=false
greyed=false
[/item]
[item]
text=LANGUAGE
hPaddingDown=7
[/item]
[item]
text=DISPLAY MODE
hPaddingDown=2
selectable=true
greyed=false
linkedDown=true
[/item]
[item]
text=WINDOW
hPaddingDown=7
selectable=false
greyed=false
[/item]
[item]
text=WINDOW SIZE
hPaddingDown=2
[/item]
[item]
text=FILTER
hPaddingDown=2
[/item]
[item]
text=VSYNC
hPaddingDown=7
[/item]
[item]
text=HOW TO PLAY
hPaddingDown=7
[/item]
[item]
text=ACCEPT
hPaddingDown=2
[/item]
[item]
text=CANCEL
[/item]

40
data/menu/title.men Normal file
View File

@@ -0,0 +1,40 @@
font_png=smb2.png
font_txt=smb2.txt
sound_cancel=menu_cancel.wav
sound_accept=menu_select.wav
sound_move=menu_move.wav
name=TITLE
x=0
y=116
backgroundType=0
backgroundColor=48,48,64,192
areElementsCenteredOnX=true
isCenteredOnX=true
centerX=128
selector_color=229,28,35,0
selector_text_color=255,180,0
defaultActionWhenCancel=3
[item]
text=1 PLAYER
hPaddingDown=2
[/item]
[item]
text=2 PLAYERS
hPaddingDown=7
[/item]
[item]
text=OPTIONS
hPaddingDown=7
[/item]
[item]
text=QUIT
[/item]

BIN
data/music/playing.ogg Normal file

Binary file not shown.

BIN
data/music/title.ogg Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -1,123 +1,351 @@
#include "const.h"
#include "animatedsprite.h"
// Constructor
AnimatedSprite::AnimatedSprite()
AnimatedSprite::AnimatedSprite(LTexture *texture, SDL_Renderer *renderer, std::string file)
{
//init(nullptr, nullptr);
// Copia los punteros
setTexture(texture);
setRenderer(renderer);
// Carga las animaciones
if (file != "")
{
load(file);
}
// Inicializa variables
currentAnimation = 0;
}
// Destructor
AnimatedSprite::~AnimatedSprite()
{
//init(nullptr, nullptr);
for (auto &a : animation)
{
a.frames.clear();
}
animation.clear();
}
// Iniciador
void AnimatedSprite::init(LTexture *texture, SDL_Renderer *renderer)
// Obtiene el indice de la animación a partir del nombre
int AnimatedSprite::getIndex(std::string name)
{
mRenderer = renderer;
mTexture = texture;
for (int i = 0; i < 20; i++)
int index = -1;
for (auto a : animation)
{
mAnimation[i].numFrames = 0;
mAnimation[i].speed = 0;
mAnimation[i].loop = true;
mAnimation[i].completed = false;
for (int j = 0; i < 20; i++)
index++;
if (a.name == name)
{
mAnimation[i].frames[j].x = 0;
mAnimation[i].frames[j].y = 0;
mAnimation[i].frames[j].w = 0;
mAnimation[i].frames[j].h = 0;
return index;
}
}
mCurrentFrame = 0;
mAnimationCounter = 0;
printf("** Warning: could not find \"%s\" animation\n", name.c_str());
return -1;
}
// Calcula el frame correspondiente a la animación
void AnimatedSprite::animate(int index)
void AnimatedSprite::animate()
{
if (mEnabled)
if (!enabled || animation.at(currentAnimation).speed == 0)
{
// Calculamos el frame actual a partir del contador
mCurrentFrame = mAnimationCounter / mAnimation[index].speed;
return;
}
// Si alcanzamos el final de la animación, reiniciamos el contador de la animación
// en función de la variable loop
if (mCurrentFrame >= mAnimation[index].numFrames)
{
if (mAnimation[index].loop)
mAnimationCounter = 0;
else
mCurrentFrame = mAnimation[index].numFrames;
// Calcula el frame actual a partir del contador
animation.at(currentAnimation).currentFrame = animation.at(currentAnimation).counter / animation.at(currentAnimation).speed;
// Si alcanza el final de la animación, reinicia el contador de la animación
// en función de la variable loop y coloca el nuevo frame
if (animation.at(currentAnimation).currentFrame >= (int)animation.at(currentAnimation).frames.size())
{
if (animation.at(currentAnimation).loop == -1)
{ // Si no hay loop, deja el último frame
animation.at(currentAnimation).currentFrame = animation.at(currentAnimation).frames.size();
animation.at(currentAnimation).completed = true;
}
// En caso contrario
else
{
// Escogemos el frame correspondiente de la animación
setSpriteClip(mAnimation[index].frames[mCurrentFrame]);
// Incrementamos el contador de la animacion
mAnimationCounter++;
{ // Si hay loop, vuelve al frame indicado
animation.at(currentAnimation).counter = 0;
animation.at(currentAnimation).currentFrame = animation.at(currentAnimation).loop;
}
}
// En caso contrario
else
{
// Escoge el frame correspondiente de la animación
setSpriteClip(animation.at(currentAnimation).frames.at(animation.at(currentAnimation).currentFrame));
// Incrementa el contador de la animacion
animation.at(currentAnimation).counter++;
}
}
// Establece el frame actual de la animación
void AnimatedSprite::setCurrentFrame(Uint8 num)
void AnimatedSprite::setCurrentFrame(int num)
{
mCurrentFrame = num;
// Descarta valores fuera de rango
if (num >= (int)animation.at(currentAnimation).frames.size())
{
num = 0;
}
// Cambia el valor de la variable
animation.at(currentAnimation).counter = animation.at(currentAnimation).speed * num;
// Escoge el frame correspondiente de la animación
setSpriteClip(animation.at(currentAnimation).frames.at(animation.at(currentAnimation).currentFrame));
}
// Establece el valor del contador
void AnimatedSprite::setAnimationCounter(Uint16 num)
void AnimatedSprite::setAnimationCounter(std::string name, int num)
{
mAnimationCounter = num;
animation.at(getIndex(name)).counter = num;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(std::string name, int speed)
{
animation.at(getIndex(name)).counter = speed;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(int index, int speed)
{
animation.at(index).counter = speed;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(std::string name, int loop)
{
animation.at(getIndex(name)).loop = loop;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(int index, int loop)
{
animation.at(index).loop = loop;
}
// Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(std::string name, bool value)
{
animation.at(getIndex(name)).completed = value;
}
// OLD - Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(int index, bool value)
{
animation.at(index).completed = value;
}
// Comprueba si ha terminado la animación
bool AnimatedSprite::animationIsCompleted()
{
return animation.at(currentAnimation).completed;
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(std::string name, Uint8 index)
{
return animation.at(getIndex(name)).frames.at(index);
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(int indexA, Uint8 indexF)
{
return animation.at(indexA).frames.at(indexF);
}
// Carga la animación desde un fichero
bool AnimatedSprite::load(std::string filePath)
{
int framesPerRow = 0;
int frameWidth = 0;
int frameHeight = 0;
int maxTiles = 0;
// Indicador de éxito en la carga
bool success = true;
const std::string filename = filePath.substr(filePath.find_last_of("\\/") + 1);
std::ifstream file(filePath);
std::string line;
// El fichero se puede abrir
if (file.good())
{
// Procesa el fichero linea a linea
printf("Reading file %s\n", filename.c_str());
while (std::getline(file, line))
{
// Si la linea contiene el texto [animation] se realiza el proceso de carga de una animación
if (line == "[animation]")
{
t_animation buffer;
buffer.counter = 0;
buffer.currentFrame = 0;
buffer.completed = false;
do
{
std::getline(file, line);
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != (int)line.npos)
{
if (line.substr(0, pos) == "name")
{
buffer.name = line.substr(pos + 1, line.length());
}
else if (line.substr(0, pos) == "speed")
{
buffer.speed = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "loop")
{
buffer.loop = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frames")
{
// Se introducen los valores separados por comas en un vector
std::stringstream ss(line.substr(pos + 1, line.length()));
std::string tmp;
SDL_Rect rect = {0, 0, frameWidth, frameHeight};
while (getline(ss, tmp, ','))
{
// Comprueba que el tile no sea mayor que el maximo indice permitido
const int numTile = std::stoi(tmp) > maxTiles ? 0 : std::stoi(tmp);
rect.x = (numTile % framesPerRow) * frameWidth;
rect.y = (numTile / framesPerRow) * frameHeight;
buffer.frames.push_back(rect);
}
}
else
{
printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
}
} while (line != "[/animation]");
// Añade la animación al vector de animaciones
animation.push_back(buffer);
}
// En caso contrario se parsea el fichero para buscar las variables y los valores
else
{
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (pos != (int)line.npos)
{
if (line.substr(0, pos) == "framesPerRow")
{
framesPerRow = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frameWidth")
{
frameWidth = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frameHeight")
{
frameHeight = std::stoi(line.substr(pos + 1, line.length()));
}
else
{
printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
// Normaliza valores
if (framesPerRow == 0 && frameWidth > 0)
{
framesPerRow = texture->getWidth() / frameWidth;
}
if (maxTiles == 0 && frameWidth > 0 && frameHeight > 0)
{
const int w = texture->getWidth() / frameWidth;
const int h = texture->getHeight() / frameHeight;
maxTiles = w * h;
}
}
}
}
// Cierra el fichero
printf("Closing file %s\n\n", filename.c_str());
file.close();
}
// El fichero no se puede abrir
else
{
printf("Warning: Unable to open %s file\n", filename.c_str());
success = false;
}
// Pone un valor por defecto
setPos({0, 0, frameWidth, frameHeight});
return success;
}
// Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(std::string name)
{
const int newAnimation = getIndex(name);
if (currentAnimation != newAnimation)
{
currentAnimation = newAnimation;
animation.at(currentAnimation).currentFrame = 0;
animation.at(currentAnimation).counter = 0;
animation.at(currentAnimation).completed = false;
}
}
// Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(int index)
{
const int newAnimation = index;
if (currentAnimation != newAnimation)
{
currentAnimation = newAnimation;
animation.at(currentAnimation).currentFrame = 0;
animation.at(currentAnimation).counter = 0;
animation.at(currentAnimation).completed = false;
}
}
// Actualiza las variables del objeto
void AnimatedSprite::update()
{
animate();
MovingSprite::update();
}
// Establece el rectangulo para un frame de una animación
void AnimatedSprite::setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h)
{
mAnimation[index_animation].frames[index_frame].x = x;
mAnimation[index_animation].frames[index_frame].y = y;
mAnimation[index_animation].frames[index_frame].w = w;
mAnimation[index_animation].frames[index_frame].h = h;
animation.at(index_animation).frames.push_back({x, y, w, h});
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(Uint8 index, Uint8 speed)
// OLD - Establece el contador para todas las animaciones
void AnimatedSprite::setAnimationCounter(int value)
{
mAnimation[index].speed = speed;
}
// Establece el numero de frames de una animación
void AnimatedSprite::setAnimationNumFrames(Uint8 index, Uint8 num)
{
mAnimation[index].numFrames = num;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(Uint8 index, bool loop)
{
mAnimation[index].loop = loop;
}
// Establece el valor de la variable
void AnimatedSprite::setCompleted(Uint8 index, bool value)
{
mAnimation[index].completed = value;
}
// Comprueba si ha terminado la animación
bool AnimatedSprite::isCompleted(Uint8 index)
{
return mAnimation[index].completed;
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(Uint8 index_animation, Uint8 index_frame)
{
return mAnimation[index_animation].frames[index_frame];
for (auto &a : animation)
{
a.counter = value;
}
}

View File

@@ -1,69 +1,85 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "movingsprite.h"
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#ifndef ANIMATEDSPRITE_H
#define ANIMATEDSPRITE_H
#define MAX_FRAMES 30
#define MAX_ANIMATIONS 20
// Clase AnimatedSprite
class AnimatedSprite : public MovingSprite
{
private:
struct sAnimation
struct t_animation
{
SDL_Rect frames[MAX_FRAMES]; // Cada uno de los frames que componen la animación
Uint8 numFrames; // Numero de frames que componen la animación
Uint8 speed; // Velocidad de la animación
bool loop; // Indica si la animación se reproduce en bucle
bool completed; // Indica si ha finalizado la animación
std::string name; // Nombre de la animacion
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
int speed; // Velocidad de la animación
int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
bool completed; // Indica si ha finalizado la animación
int currentFrame; // Frame actual
int counter; // Contador para las animaciones
};
sAnimation mAnimation[MAX_ANIMATIONS]; // Vector con las diferentes animaciones
Uint8 mCurrentFrame; // Frame actual
Uint16 mAnimationCounter; // Contador para las animaciones
std::vector<t_animation> animation; // Vector con las diferentes animaciones
int currentAnimation; // Animacion activa
public:
// Constructor
AnimatedSprite();
AnimatedSprite(LTexture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "");
// Destructor
~AnimatedSprite();
// Iniciador
void init(LTexture *texture, SDL_Renderer *renderer);
// Calcula el frame correspondiente a la animación
void animate(int index);
// Calcula el frame correspondiente a la animación actual
void animate();
// Establece el frame actual de la animación
void setCurrentFrame(Uint8 num);
void setCurrentFrame(int num);
// Establece el valor del contador
void setAnimationCounter(Uint16 num);
// 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);
void setAnimationCounter(std::string name, int num);
// Establece la velocidad de una animación
void setAnimationSpeed(Uint8 index, Uint8 speed);
void setAnimationSpeed(std::string name, int speed);
void setAnimationSpeed(int index, int speed);
// Establece el numero de frames de una animación
void setAnimationNumFrames(Uint8 index, Uint8 num);
// Establece si la animación se reproduce en bucle
void setAnimationLoop(Uint8 index, bool loop);
// Establece el frame al que vuelve la animación al finalizar
void setAnimationLoop(std::string name, int loop);
void setAnimationLoop(int index, int loop);
// Establece el valor de la variable
void setCompleted(Uint8 index, bool value);
void setAnimationCompleted(std::string name, bool value);
void setAnimationCompleted(int index, bool value);
// Comprueba si ha terminado la animación
bool isCompleted(Uint8 index);
bool animationIsCompleted();
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect getAnimationClip(Uint8 index_animation, Uint8 index_frame);
SDL_Rect getAnimationClip(std::string name, Uint8 index);
SDL_Rect getAnimationClip(int indexA, Uint8 indexF);
// Obtiene el indice de la animación a partir del nombre
int getIndex(std::string name);
// Carga la animación desde un fichero
bool load(std::string filePath);
// Establece la animacion actual
void setCurrentAnimation(std::string name = "default");
void setCurrentAnimation(int index = 0);
// Actualiza las variables del objeto
void update();
// 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);
};
#endif

160
source/asset.cpp Normal file
View File

@@ -0,0 +1,160 @@
#include "asset.h"
// Constructor
Asset::Asset(std::string path)
{
executablePath = path;
longest_name = 0;
}
// Destructor
Asset::~Asset()
{
}
// Añade un elemento a la lista
void Asset::add(std::string file, enum assetType_e type, bool required)
{
item_t temp;
temp.file = executablePath + file;
temp.type = type;
temp.required = required;
fileList.push_back(temp);
const std::string filename = file.substr(file.find_last_of("\\/") + 1);
longest_name = SDL_max(longest_name, filename.size());
}
// Devuelve el fichero de un elemento de la lista a partir de una cadena
std::string Asset::get(std::string text)
{
for (auto f : fileList)
{
if (f.file.find(text) != std::string::npos)
{
return f.file;
}
}
printf("Warning: file %s not found\n", text.c_str());
return "";
}
// Comprueba que existen todos los elementos
bool Asset::check()
{
bool success = true;
printf("\n** Checking files.\n");
// Comprueba la lista de ficheros clasificandolos por tipo
for (int type = 0; type < t_maxAssetType; ++type)
{
// Comprueba si hay ficheros de ese tipo
bool any = false;
for (auto f : fileList)
{
if ((f.required) && (f.type == type))
{
any = true;
}
}
// Si hay ficheros de ese tipo, comprueba si existen
if (any)
{
printf("\n>> %s FILES\n", getTypeName(type).c_str());
for (auto f : fileList)
{
if ((f.required) && (f.type == type))
{
success &= checkFile(f.file);
}
}
}
}
// Resultado
if (success)
{
printf("\n** All files OK.\n\n");
}
else
{
printf("\n** A file is missing. Exiting.\n\n");
}
return success;
}
// Comprueba que existe un fichero
bool Asset::checkFile(std::string path)
{
bool success = false;
std::string result = "ERROR";
// Comprueba si existe el fichero
const std::string filename = path.substr(path.find_last_of("\\/") + 1);
SDL_RWops *file = SDL_RWFromFile(path.c_str(), "r+b");
if (file != nullptr)
{
result = "OK";
success = true;
SDL_RWclose(file);
}
const std::string s = "Checking file %-" + std::to_string(longest_name) + "s [" + result + "]\n";
printf(s.c_str(), filename.c_str());
return success;
}
// Devuelve el nombre del tipo de recurso
std::string Asset::getTypeName(int type)
{
switch (type)
{
case t_bitmap:
return "BITMAP";
break;
case t_music:
return "MUSIC";
break;
case t_sound:
return "SOUND";
break;
case t_font:
return "FONT";
break;
case t_lang:
return "LANG";
break;
case t_data:
return "DATA";
break;
case t_room:
return "ROOM";
break;
case t_enemy:
return "ENEMY";
break;
case t_item:
return "ITEM";
break;
default:
return "ERROR";
break;
}
}

64
source/asset.h Normal file
View File

@@ -0,0 +1,64 @@
#pragma once
#include <SDL2/SDL.h>
#include <string>
#include <vector>
#ifndef ASSET_H
#define ASSET_H
enum assetType_e
{
t_bitmap,
t_music,
t_sound,
t_font,
t_lang,
t_data,
t_room,
t_enemy,
t_item,
t_maxAssetType
};
// Clase Asset
class Asset
{
private:
// Estructura para definir un item
struct item_t
{
std::string file; // Ruta del fichero desde la raiz del directorio
enum assetType_e type; // Indica el tipo de recurso
bool required; // Indica si es un fichero que debe de existir
};
int longest_name; // Contiene la longitud del nombre de fichero mas largo
std::vector<item_t> fileList;
std::string executablePath;
// Comprueba que existe un fichero
bool checkFile(std::string path);
// Devuelve el nombre del tipo de recurso
std::string getTypeName(int type);
public:
// Constructor
Asset(std::string path);
// Destructor
~Asset();
// Añade un elemento a la lista
void add(std::string file, enum assetType_e type, bool required = true);
// Devuelve un elemento de la lista a partir de una cadena
std::string get(std::string text);
// Comprueba que existen todos los elementos
bool check();
};
#endif

View File

@@ -2,22 +2,11 @@
#include "balloon.h"
// Constructor
Balloon::Balloon()
Balloon::Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 creationtimer, LTexture *texture, SDL_Renderer *renderer)
{
mSprite = new AnimatedSprite();
disable();
}
// Destructor
Balloon::~Balloon()
{
delete mSprite;
mSprite = nullptr;
}
// Inicializador
void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16 creationtimer, LTexture *texture, SDL_Renderer *renderer)
{
const Uint8 NUM_FRAMES_BALLON = 10;
const Uint8 NUM_FRAMES_BALLON_POP = 12;
const Uint8 NUM_FRAMES_BALLON_BORN = 10;
@@ -55,13 +44,19 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
// Establece los frames de cada animación
for (int i = 0; i < NUM_FRAMES_BALLON; i++)
{
mSprite->setAnimationFrames(BALLOON_MOVING_ANIMATION, i, 50 + OFFSET_ORANGE_BALLOONS, 21 + (37 * i), getWidth(), getHeight());
}
for (int i = 0; i < NUM_FRAMES_BALLON_BORN; i++)
{
mSprite->setAnimationFrames(BALLOON_BORN_ANIMATION, i, 50 + OFFSET_BLUE_BALLOONS, 21 + (37 * i), getWidth(), getHeight());
}
for (int i = 0; i < NUM_FRAMES_BALLON_POP; i++)
{
mSprite->setAnimationFrames(BALLOON_POP_ANIMATION, i, 50 + OFFSET_EXPLOSIONS, 21 + (37 * i), getWidth(), getHeight());
}
break;
@@ -351,13 +346,16 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mPosX = x;
mPosY = y;
mBouncing.enabled = false; // Si el efecto está activo
mBouncing.counter = 0; // Countador para el efecto
mBouncing.speed = 0; // Velocidad a la que transcurre el efecto
mBouncing.zoomW = 1.0f; // Zoom aplicado a la anchura
mBouncing.zoomH = 1.0f; // Zoom aplicado a la altura
mBouncing.despX = 0.0f; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom
// Valores para el efecto de rebote
mBouncing.enabled = false;
mBouncing.counter = 0;
mBouncing.speed = 0;
mBouncing.zoomW = 1.0f;
mBouncing.zoomH = 1.0f;
mBouncing.despX = 0.0f;
mBouncing.despY = 0.0f;
mBouncing.w = {1.10f, 1.05f, 1.00f, 0.95f, 0.90f, 0.95f, 1.00f, 1.02f, 1.05f, 1.02f};
mBouncing.h = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f};
// Textura con los gráficos del sprite
mSprite->setTexture(texture);
@@ -404,13 +402,13 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mKind = kind;
// Inicializa las variables para la animación
mSprite->setCurrentFrame(0);
mSprite->setAnimationCounter(0);
// mSprite->setCurrentFrame(0);
// mSprite->setAnimationCounter(0);
// Establece el numero de frames de cada animacion
mSprite->setAnimationNumFrames(BALLOON_MOVING_ANIMATION, NUM_FRAMES_BALLON);
mSprite->setAnimationNumFrames(BALLOON_POP_ANIMATION, NUM_FRAMES_BALLON_POP);
mSprite->setAnimationNumFrames(BALLOON_BORN_ANIMATION, NUM_FRAMES_BALLON_BORN);
// mSprite->setAnimationNumFrames(BALLOON_MOVING_ANIMATION, NUM_FRAMES_BALLON);
// mSprite->setAnimationNumFrames(BALLOON_POP_ANIMATION, NUM_FRAMES_BALLON_POP);
// mSprite->setAnimationNumFrames(BALLOON_BORN_ANIMATION, NUM_FRAMES_BALLON_BORN);
// Establece la velocidad de cada animación
mSprite->setAnimationSpeed(BALLOON_MOVING_ANIMATION, 10);
@@ -426,19 +424,22 @@ void Balloon::init(float x, float y, Uint8 kind, float velx, float speed, Uint16
mSprite->setSpriteClip(mSprite->getAnimationClip(0, 0));
}
// Destructor
Balloon::~Balloon()
{
delete mSprite;
mSprite = nullptr;
}
// Centra el globo en la posición X
void Balloon::allignTo(int x)
{
mPosX = float(x - (mWidth / 2));
if (mPosX < PLAY_AREA_LEFT)
{
mPosX = PLAY_AREA_LEFT + 1;
}
else if ((mPosX + mWidth) > PLAY_AREA_RIGHT)
{
mPosX = float(PLAY_AREA_RIGHT - mWidth - 1);
}
// Posición X,Y del sprite
mSprite->setPosX(getPosX());
@@ -531,10 +532,12 @@ void Balloon::move()
}
/*
Para aplicar la gravedad, el diseño original la aplicaba en cada iteración del bucle
Al añadir el modificador de velocidad se reduce la distancia que recorre el objeto y por
tanto recibe mas gravedad. Para solucionarlo se va a aplicar la gravedad cuando se haya
recorrido una distancia igual a la velocidad en Y, que era el cálculo inicial
*/
// Incrementa la variable que calcula la distancia acumulada en Y
@@ -550,11 +553,6 @@ void Balloon::move()
mVelY += mGravity;
std::min(mVelY, mMaxVelY);
}
// Aplica la gravedad al objeto
//if (mVelY > mMaxVelY)
// mVelY = mMaxVelY;
//else if (mCounter % 1 == 0)
// mVelY += mGravity;
// Actualiza la posición del sprite
mSprite->setPosX(getPosX());
@@ -603,7 +601,7 @@ void Balloon::disable()
void Balloon::pop()
{
setPopping(true);
mSprite->setAnimationCounter(0);
mSprite->setAnimationCounter(0);
mSprite->disableRotate();
setTimeToLive(120);
setStop(true);
@@ -635,9 +633,9 @@ void Balloon::updateState()
{
setInvulnerable(true);
setStop(true);
if (mSprite->isCompleted(BALLOON_POP_ANIMATION))
if (mSprite->animationIsCompleted())
{
mSprite->setCompleted(BALLOON_POP_ANIMATION, false);
mSprite->setAnimationCompleted(BALLOON_POP_ANIMATION, false);
mTimeToLive = 0;
disable();
}
@@ -679,12 +677,6 @@ void Balloon::updateState()
updateColliders();
}
// Hace visible el globo de forma intermitente
//if (mCreationCounter > 100)
// setVisible(mCreationCounter / 10 % 2 == 0);
//else
// setVisible(mCreationCounter / 5 % 2 == 0);
mCreationCounter--;
}
// El contador ha llegado a cero
@@ -709,10 +701,14 @@ void Balloon::updateState()
{
// Si está detenido, reduce el contador
if (mStoppedCounter > 0)
{
mStoppedCounter--;
}
// Si el contador ha llegado a cero, ya no está detenido
else if (!isPopping()) // Quitarles el estado "detenido" si no estan explosionandoxq
else if (!isPopping())
{ // Quitarles el estado "detenido" si no estan explosionando
setStop(false);
}
}
}
@@ -721,11 +717,19 @@ void Balloon::updateAnimation()
{
// Establece el frame de animación
if (isPopping())
mSprite->animate(BALLOON_POP_ANIMATION);
{
mSprite->setCurrentAnimation(BALLOON_POP_ANIMATION);
}
else if (isBeingCreated())
mSprite->animate(BALLOON_BORN_ANIMATION);
{
mSprite->setCurrentAnimation(BALLOON_BORN_ANIMATION);
}
else
mSprite->animate(BALLOON_MOVING_ANIMATION);
{
mSprite->setCurrentAnimation(BALLOON_MOVING_ANIMATION);
}
mSprite->animate();
}
// Comprueba si el globo está habilitado
@@ -910,7 +914,6 @@ circle_t &Balloon::getCollider()
// Alinea el circulo de colisión con la posición del objeto globo
void Balloon::updateColliders()
{
// Align collider to center of balloon
mCollider.x = Uint16(mPosX + mCollider.r);
mCollider.y = mPosY + mCollider.r;
}
@@ -940,6 +943,7 @@ void Balloon::bounceStart()
mBouncing.despX = 0;
mBouncing.despY = 0;
}
void Balloon::bounceStop()
{
mBouncing.enabled = false;
@@ -951,12 +955,13 @@ void Balloon::bounceStop()
mBouncing.despX = 0.0f;
mBouncing.despY = 0.0f;
}
void Balloon::updateBounce()
{
if (mBouncing.enabled)
{
mBouncing.zoomW = mBouncing.w[mBouncing.counter / mBouncing.speed];
mBouncing.zoomH = mBouncing.h[mBouncing.counter / mBouncing.speed];
mBouncing.zoomW = mBouncing.w.at(mBouncing.counter / mBouncing.speed);
mBouncing.zoomH = mBouncing.h.at(mBouncing.counter / mBouncing.speed);
mSprite->setZoomW(mBouncing.zoomW);
mSprite->setZoomH(mBouncing.zoomH);
mBouncing.despX = (mSprite->getSpriteClip().w - (mSprite->getSpriteClip().w * mBouncing.zoomW));

View File

@@ -1,16 +1,90 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include "animatedsprite.h"
#include <vector>
#ifndef BALLOON_H
#define BALLOON_H
// Cantidad de elementos del vector con los valores de la deformación del globo al rebotar
#define MAX_BOUNCE 10
// Clase globo
// Tipos de globo
#define BALLOON_1 1
#define BALLOON_2 2
#define BALLOON_3 3
#define BALLOON_4 4
#define HEXAGON_1 5
#define HEXAGON_2 6
#define HEXAGON_3 7
#define HEXAGON_4 8
#define POWER_BALL 9
// Puntos de globo
#define BALLOON_SCORE_1 50
#define BALLOON_SCORE_2 100
#define BALLOON_SCORE_3 200
#define BALLOON_SCORE_4 400
// Tamaños de globo
#define BALLOON_SIZE_1 1
#define BALLOON_SIZE_2 2
#define BALLOON_SIZE_3 3
#define BALLOON_SIZE_4 4
// Clases de globo
#define BALLOON_CLASS 0
#define HEXAGON_CLASS 1
// Velocidad del globo
#define BALLOON_VELX_POSITIVE 0.7f
#define BALLOON_VELX_NEGATIVE -0.7f
// Indice para las animaciones de los globos
#define BALLOON_MOVING_ANIMATION 0
#define BALLOON_POP_ANIMATION 1
#define BALLOON_BORN_ANIMATION 2
// Cantidad posible de globos
#define MAX_BALLOONS 100
// Velocidades a las que se mueven los globos
#define BALLOON_SPEED_1 0.60f
#define BALLOON_SPEED_2 0.70f
#define BALLOON_SPEED_3 0.80f
#define BALLOON_SPEED_4 0.90f
#define BALLOON_SPEED_5 1.00f
// Tamaño de los globos
#define BALLOON_WIDTH_1 8
#define BALLOON_WIDTH_2 13
#define BALLOON_WIDTH_3 21
#define BALLOON_WIDTH_4 37
// PowerBall
#define POWERBALL_SCREENPOWER_MINIMUM 10
#define POWERBALL_COUNTER 8
// Clase Balloon
class Balloon
{
private:
// Estructura para las variables para el efecto de los rebotes
struct bouncing
{
bool enabled; // Si el efecto está activo
Uint8 counter; // Countador para el efecto
Uint8 speed; // Velocidad a la que transcurre el efecto
float zoomW; // Zoom aplicado a la anchura
float zoomH; // Zoom aplicado a la altura
float despX; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom
float despY; // Desplazamiento de pixeles en el eje Y antes de pintar el objeto con zoom
std::vector<float> w; // Vector con los valores de zoom para el ancho del globo
std::vector<float> h; // Vector con los valores de zoom para el alto del globo
};
float mPosX; // Posición en el eje X
float mPosY; // Posición en el eje Y
Uint8 mWidth; // Ancho
@@ -41,43 +115,42 @@ private:
float mSpeed; // Velocidad a la que se mueven los globos
Uint8 mSize; // Tamaño del globo
Uint8 mPower; // Cantidad de poder que alberga el globo
bouncing mBouncing; // Contiene las variables para el efecto de rebote
struct bouncing // Estructura para las variables para el efecto de los rebotes
{
bool enabled; // Si el efecto está activo
Uint8 counter; // Countador para el efecto
Uint8 speed; // Velocidad a la que transcurre el efecto
float zoomW; // Zoom aplicado a la anchura
float zoomH; // Zoom aplicado a la altura
float despX; // Desplazamiento de pixeles en el eje X antes de pintar el objeto con zoom
float despY; // Desplazamiento de pixeles en el eje Y antes de pintar el objeto con zoom
// Alinea el circulo de colisión con la posición del objeto globo
void updateColliders();
// Vector con los valores de zoom para el ancho y 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};
float h[MAX_BOUNCE] = {0.90f, 0.95f, 1.00f, 1.05f, 1.10f, 1.05f, 1.00f, 0.98f, 0.95f, 0.98f};
};
bouncing mBouncing;
// Activa el efecto
void bounceStart();
void updateColliders(); // Alinea el circulo de colisión con la posición del objeto globo
void bounceStart(); // Activa el efecto
void bounceStop(); // Detiene el efecto
void updateBounce(); // Aplica el efecto
void updateState(); // Actualiza los estados del globo
void updateAnimation(); // Establece la animación correspondiente
void setBeingCreated(bool state); // Establece el valor de la variable
void setTimeToLive(Uint16 time); // Establece el valor de la variable
Uint16 getTimeToLive(); // Obtiene del valor de la variable
// Detiene el efecto
void bounceStop();
// Aplica el efecto
void updateBounce();
// Actualiza los estados del globo
void updateState();
// Establece la animación correspondiente
void updateAnimation();
// Establece el valor de la variable
void setBeingCreated(bool state);
// Establece el valor de la variable
void setTimeToLive(Uint16 time);
// Obtiene del valor de la variable
Uint16 getTimeToLive();
public:
// Constructor
Balloon();
Balloon(float x, float y, Uint8 kind, float velx, float speed, Uint16 creationtimer, LTexture *texture, SDL_Renderer *renderer);
// Destructor
~Balloon();
// Inicializador
void init(float x, float y, Uint8 kind, float velx, float speed, Uint16 creationtimer, LTexture *texture, SDL_Renderer *renderer);
// Centra el globo en la posición X
void allignTo(int x);

View File

@@ -2,23 +2,10 @@
#include "bullet.h"
// Constructor
Bullet::Bullet()
Bullet::Bullet(int x, int y, int kind, bool poweredUp, int owner, LTexture *texture, SDL_Renderer *renderer)
{
mSprite = new Sprite();
mKind = NO_KIND;
}
mSprite = new Sprite({x,y,10,10},texture, renderer);
// Destructor
Bullet::~Bullet()
{
//init(0, 0, NO_KIND, nullptr, nullptr);
delete mSprite;
mSprite = nullptr;
}
// Iniciador
void Bullet::init(int x, int y, int kind, bool poweredUp, int owner, LTexture *texture, SDL_Renderer *renderer)
{
// Posición inicial del objeto
mPosX = x;
mPosY = y;
@@ -36,20 +23,6 @@ void Bullet::init(int x, int y, int kind, bool poweredUp, int owner, LTexture *t
// Identificador del dueño del objeto
mOwner = owner;
// Textura con los gráficos del objeto
mSprite->setTexture(texture);
// Renderizador
mSprite->setRenderer(renderer);
// Alto y ancho del sprite
mSprite->setWidth(mWidth);
mSprite->setHeight(mHeight);
// Posición inicial del sprite
mSprite->setPosX(mPosX);
mSprite->setPosY(mPosY);
// Valores especificos según el tipo
switch (kind)
{
@@ -97,6 +70,13 @@ void Bullet::init(int x, int y, int kind, bool poweredUp, int owner, LTexture *t
shiftColliders();
}
// Destructor
Bullet::~Bullet()
{
delete mSprite;
mSprite = nullptr;
}
// Pinta el objeto en pantalla
void Bullet::render()
{
@@ -107,7 +87,7 @@ void Bullet::render()
Uint8 Bullet::move()
{
// Variable con el valor de retorno
Uint8 msg = MSG_OK;
Uint8 msg = BULLET_MOVE_OK;
// Mueve el objeto a su nueva posición
mPosX += mVelX;
@@ -119,7 +99,7 @@ Uint8 Bullet::move()
mKind = NO_KIND;
// Mensaje de salida
msg = MSG_BULLET_OUT;
msg = BULLET_MOVE_OUT;
}
// Mueve el objeto a su nueva posición en vertical
@@ -132,7 +112,7 @@ Uint8 Bullet::move()
mKind = NO_KIND;
// Mensaje de salida
msg = MSG_BULLET_OUT;
msg = BULLET_MOVE_OUT;
}
// Actualiza la posición del sprite
@@ -145,35 +125,13 @@ Uint8 Bullet::move()
return msg;
}
#ifdef TEST
void Bullet::testMove()
{
// Update sprite position
mSprite->setPosX(mPosX);
mSprite->setPosY(mPosY);
// Update circle colliders
shiftColliders();
}
#endif
// Deshabilita el objeto
void Bullet::erase()
{
init(0, 0, 0, false, -1, nullptr, nullptr);
}
// Comprueba si el objeto está activo
bool Bullet::isActive()
{
if (mKind == NO_KIND)
{
return false;
}
else
{
return true;
}
}
// Obtiene el valor de la variable

View File

@@ -1,11 +1,22 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include "sprite.h"
#ifndef BULLET_H
#define BULLET_H
// Clase bala
// Tipos de bala
#define BULLET_UP 1
#define BULLET_LEFT 2
#define BULLET_RIGHT 3
// Tipos de retorno de la funcion move de la bala
#define BULLET_MOVE_OK 0
#define BULLET_MOVE_OUT 1
// Clase Bullet
class Bullet
{
private:
@@ -25,23 +36,17 @@ private:
public:
// Constructor
Bullet();
Bullet(int x, int y, int kind, bool poweredUp, int owner, LTexture *texture, SDL_Renderer *renderer);
// Destructor
~Bullet();
// Iniciador
void init(int x, int y, int kind, bool poweredUp, int owner, LTexture *texture, SDL_Renderer *renderer);
// Pinta el objeto en pantalla
void render();
// Actualiza la posición y estado del objeto
Uint8 move();
// Deshabilita el objeto
void erase();
// Comprueba si el objeto está activo
bool isActive();

View File

@@ -1,89 +0,0 @@
#include "const.h"
#include "coffeedrop.h"
#ifndef UNUSED
// Constructor
CoffeeDrop::CoffeeDrop()
{
mPosX = 0;
mPosY = 0;
mWidth = 8;
mHeight = 8;
mVelX = 0;
mVelY = 0;
mGravity = 0.1f;
mFloor = 0;
mEnabled = false;
mSprite = new Sprite();
mAlpha = 128;
}
// Destructor
CoffeeDrop::~CoffeeDrop()
{
delete mSprite;
}
// Inicializador
void CoffeeDrop::init(LTexture *texture, SDL_Renderer *renderer, float x, float y, float velX, float velY, int floor)
{
mEnabled = true;
mPosX = x;
mPosY = y;
mVelX = velX;
mVelY = velY;
mFloor = floor;
mSprite->setRenderer(renderer);
mSprite->setTexture(texture);
mSprite->setSpriteClip(256, 97, mWidth, mHeight);
mSprite->setPosX(x);
mSprite->setPosY(y);
}
// Actualiza las variables del objeto
void CoffeeDrop::update()
{
if (mEnabled)
{
mVelY += mGravity;
mPosX += mVelX;
mPosY += mVelY;
mSprite->setPosX((int)mPosX);
mSprite->setPosY((int)mPosY);
if ((mPosY > mFloor) || (mPosX > PLAY_AREA_RIGHT) || ((mPosX - mWidth) < PLAY_AREA_LEFT))
mEnabled = false;
mAlpha -= 2;
if (mAlpha == 0)
mEnabled = false;
}
}
// Pinta el objeto
void CoffeeDrop::render()
{
if (mEnabled)
{
mSprite->getTexture()->setAlpha(mAlpha);
mSprite->render();
mSprite->getTexture()->setAlpha(255);
}
}
// Deshabilita el objeto
void CoffeeDrop::disable()
{
mEnabled = false;
}
// Comprueba si està habilitado
bool CoffeeDrop::isEnabled()
{
return mEnabled;
}
#endif

View File

@@ -1,50 +0,0 @@
#pragma once
#include "sprite.h"
#ifndef COFFEEDROP_H
#define COFFEEDROP_H
#ifndef UNUSED
// Clase CoffeeDrop. Gotas de café que aparecen al explotar un globo
class CoffeeDrop
{
private:
float mPosX; // Posicion en el eje X del objeto
float mPosY; // Posicion en el eje Y del objeto
Uint8 mWidth; // Ancho del sprite
Uint8 mHeight; // Alto del sprite
float mVelX; // Velocidad en el eje X
float mVelY; // Velocidad en el eje Y
float mGravity; // Aceleración en el eje Y
int mFloor; // Punto donde se encuentra el suelo y desaparecen
bool mEnabled; // Si esta habilitado. Sirve para saber si se pinta, se actualiza o se puede usar
Sprite *mSprite; // Puntero al sprite con los graficos
Uint8 mAlpha;
public:
// Constructor
CoffeeDrop();
// Destructor
~CoffeeDrop();
// Inicializador
void init(LTexture *texture, SDL_Renderer *renderer, float x, float y, float velX, float velY, int floor);
// Actualiza las variables del objeto
void update();
// Pinta el objeto
void render();
// Deshabilita el objeto
void disable();
// Comprueba si està habilitado
bool isEnabled();
};
#endif
#endif

View File

@@ -1,91 +1,25 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "utils.h"
#include "lang.h"
#include <string>
#ifndef CONST_H
#define CONST_H
// Textos
#define WINDOW_CAPTION "Coffee Crisis"
#define TEXT_COPYRIGHT "@2020,2021 JailDesigner (v2.0.1)"
// Recursos
#define BINFILE_SCORE 0
#define BINFILE_DEMO 1
#define BINFILE_CONFIG 2
#define TOTAL_BINFILE 3
#define MUSIC_INTRO 0
#define MUSIC_PLAYING 1
#define MUSIC_TITLE 2
#define TOTAL_MUSIC 3
#define SOUND_BALLOON 0
#define SOUND_BUBBLE1 1
#define SOUND_BUBBLE2 2
#define SOUND_BUBBLE3 3
#define SOUND_BUBBLE4 4
#define SOUND_BULLET 5
#define SOUND_COFFEE_OUT 6
#define SOUND_HISCORE 7
#define SOUND_ITEM_DROP 8
#define SOUND_ITEM_PICKUP 9
#define SOUND_MENU_CANCEL 10
#define SOUND_MENU_MOVE 11
#define SOUND_MENU_SELECT 12
#define SOUND_PLAYER_COLLISION 13
#define SOUND_STAGE_CHANGE 14
#define SOUND_TITLE 15
#define SOUND_CLOCK 16
#define SOUND_POWERBALL 17
#define TOTAL_SOUND 18
#define TEXTURE_BALLOON 0
#define TEXTURE_BULLET 1
#define TEXTURE_FONT_BLACK 2
#define TEXTURE_FONT_BLACK_X2 3
#define TEXTURE_FONT_NOKIA 4
#define TEXTURE_FONT_WHITE 5
#define TEXTURE_FONT_WHITE_X2 6
#define TEXTURE_GAME_BG 7
#define TEXTURE_GAME_TEXT 8
#define TEXTURE_INTRO 9
#define TEXTURE_ITEMS 10
#define TEXTURE_LOGO 11
#define TEXTURE_MENU 12
#define TEXTURE_PLAYER_BODY 13
#define TEXTURE_PLAYER_DEATH 14
#define TEXTURE_PLAYER_LEGS 15
#define TEXTURE_TITLE 16
#define TOTAL_TEXTURE 17
// Tamaño de bloque
#define BLOCK 8
#define HALF_BLOCK BLOCK / 2
// Tamaño de la pantalla real
#define SCREEN_WIDTH 256
const int SCREEN_HEIGHT = SCREEN_WIDTH * 3 / 4;
// Tamaño de la pantalla que se muestra
const int VIEW_WIDTH = SCREEN_WIDTH * 3;
const int VIEW_HEIGHT = SCREEN_HEIGHT * 3;
// Cantidad de enteros a escribir en los ficheros de datos
#define TOTAL_SCORE_DATA 3
#define TOTAL_DEMO_DATA 2000
// Tamaño de la pantalla de juego
#define GAME_WIDTH 256
#define GAME_HEIGHT 192
// Zona de juego
const int PLAY_AREA_TOP = (0 * BLOCK);
const int PLAY_AREA_BOTTOM = SCREEN_HEIGHT - (4 * BLOCK);
const int PLAY_AREA_BOTTOM = GAME_HEIGHT - (4 * BLOCK);
const int PLAY_AREA_LEFT = (0 * BLOCK);
const int PLAY_AREA_RIGHT = SCREEN_WIDTH - (0 * BLOCK);
const int PLAY_AREA_RIGHT = GAME_WIDTH - (0 * BLOCK);
const int PLAY_AREA_WIDTH = PLAY_AREA_RIGHT - PLAY_AREA_LEFT;
const int PLAY_AREA_HEIGHT = PLAY_AREA_BOTTOM - PLAY_AREA_TOP;
const int PLAY_AREA_CENTER_X = PLAY_AREA_LEFT + (PLAY_AREA_WIDTH / 2);
@@ -96,54 +30,12 @@ const int PLAY_AREA_FIRST_QUARTER_Y = PLAY_AREA_HEIGHT / 4;
const int PLAY_AREA_THIRD_QUARTER_Y = (PLAY_AREA_HEIGHT / 4) * 3;
// Anclajes de pantalla
const int SCREEN_CENTER_X = SCREEN_WIDTH / 2;
const int SCREEN_FIRST_QUARTER_X = SCREEN_WIDTH / 4;
const int SCREEN_THIRD_QUARTER_X = (SCREEN_WIDTH / 4) * 3;
const int SCREEN_CENTER_Y = SCREEN_HEIGHT / 2;
const int SCREEN_FIRST_QUARTER_Y = SCREEN_HEIGHT / 4;
const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3;
// Opciones de menu
#define MENU_NO_OPTION -1
#define MENU_OPTION_START 0
#define MENU_OPTION_QUIT 1
#define MENU_OPTION_TOTAL 2
// Tipos de fondos para el menu
#define MENU_BACKGROUND_TRANSPARENT 0
#define MENU_BACKGROUND_SOLID 1
// Estados del jugador
#define PLAYER_STATUS_WALKING_LEFT 0
#define PLAYER_STATUS_WALKING_RIGHT 1
#define PLAYER_STATUS_WALKING_STOP 2
#define PLAYER_STATUS_FIRING_UP 0
#define PLAYER_STATUS_FIRING_LEFT 1
#define PLAYER_STATUS_FIRING_RIGHT 2
#define PLAYER_STATUS_FIRING_NO 3
#define PLAYER_ANIMATION_LEGS_WALKING_LEFT 0
#define PLAYER_ANIMATION_LEGS_WALKING_RIGHT 1
#define PLAYER_ANIMATION_LEGS_WALKING_STOP 2
#define PLAYER_ANIMATION_BODY_WALKING_LEFT 0
#define PLAYER_ANIMATION_BODY_FIRING_LEFT 1
#define PLAYER_ANIMATION_BODY_WALKING_RIGHT 2
#define PLAYER_ANIMATION_BODY_FIRING_RIGHT 3
#define PLAYER_ANIMATION_BODY_WALKING_STOP 4
#define PLAYER_ANIMATION_BODY_FIRING_UP 5
#define PLAYER_ANIMATION_HEAD_WALKING_LEFT 0
#define PLAYER_ANIMATION_HEAD_FIRING_LEFT 1
#define PLAYER_ANIMATION_HEAD_WALKING_RIGHT 2
#define PLAYER_ANIMATION_HEAD_FIRING_RIGHT 3
#define PLAYER_ANIMATION_HEAD_WALKING_STOP 4
#define PLAYER_ANIMATION_HEAD_FIRING_UP 5
// Variables del jugador
#define PLAYER_INVULNERABLE_COUNTER 200
#define PLAYER_POWERUP_COUNTER 1500
const int SCREEN_CENTER_X = GAME_WIDTH / 2;
const int SCREEN_FIRST_QUARTER_X = GAME_WIDTH / 4;
const int SCREEN_THIRD_QUARTER_X = (GAME_WIDTH / 4) * 3;
const int SCREEN_CENTER_Y = GAME_HEIGHT / 2;
const int SCREEN_FIRST_QUARTER_Y = GAME_HEIGHT / 4;
const int SCREEN_THIRD_QUARTER_Y = (GAME_HEIGHT / 4) * 3;
// Secciones del programa
#define PROG_SECTION_LOGO 0
@@ -162,197 +54,12 @@ const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3;
#define TITLE_SECTION_3 5
#define TITLE_SECTION_INSTRUCTIONS 6
// Modo para las instrucciones
#define INSTRUCTIONS_MODE_MANUAL 0
#define INSTRUCTIONS_MODE_AUTO 1
// Estados de cada elemento que pertenece a un evento
#define EVENT_WAITING 1
#define EVENT_RUNNING 2
#define EVENT_COMPLETED 3
// Cantidad de eventos de la intro
#define INTRO_TOTAL_BITMAPS 6
#define INTRO_TOTAL_TEXTS 9
const int INTRO_TOTAL_EVENTS = INTRO_TOTAL_BITMAPS + INTRO_TOTAL_TEXTS;
// Cantidad de eventos de la pantalla de titulo
#define TITLE_TOTAL_EVENTS 2
// Relaciones de Id con nomnbres
#define BITMAP0 0
#define BITMAP1 1
#define BITMAP2 2
#define BITMAP3 3
#define BITMAP4 4
#define BITMAP5 5
#define TEXT0 6
#define TEXT1 7
#define TEXT2 8
#define TEXT3 9
#define TEXT4 10
#define TEXT5 11
#define TEXT6 12
#define TEXT7 13
#define TEXT8 14
// Anclajes para el marcador de puntos
const int SCORE_WORD_X = (SCREEN_WIDTH / 4) - ((5 * BLOCK) / 2);
const int SCORE_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int SCORE_NUMBER_X = (SCREEN_WIDTH / 4) - ((6 * BLOCK) / 2);
const int SCORE_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
const int HISCORE_WORD_X = ((SCREEN_WIDTH / 4) * 3) - ((8 * BLOCK) / 2);
const int HISCORE_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int HISCORE_NUMBER_X = ((SCREEN_WIDTH / 4) * 3) - ((6 * BLOCK) / 2);
const int HISCORE_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
const int MULTIPLIER_WORD_X = (SCREEN_WIDTH / 2) - ((4 * BLOCK) / 2);
const int MULTIPLIER_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int MULTIPLIER_NUMBER_X = (SCREEN_WIDTH / 2) - ((3 * BLOCK) / 2);
const int MULTIPLIER_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
// Ningun tipo
#define NO_KIND 0
// Tipos de globo
#define BALLOON_1 1
#define BALLOON_2 2
#define BALLOON_3 3
#define BALLOON_4 4
#define HEXAGON_1 5
#define HEXAGON_2 6
#define HEXAGON_3 7
#define HEXAGON_4 8
#define POWER_BALL 9
// Puntos de globo
#define BALLOON_SCORE_1 50
#define BALLOON_SCORE_2 100
#define BALLOON_SCORE_3 200
#define BALLOON_SCORE_4 400
// Tamaños de globo
#define BALLOON_SIZE_1 1
#define BALLOON_SIZE_2 2
#define BALLOON_SIZE_3 3
#define BALLOON_SIZE_4 4
// Clases de globo
#define BALLOON_CLASS 0
#define HEXAGON_CLASS 1
// Velocidad del globo
#define BALLOON_VELX_POSITIVE 0.7f
#define BALLOON_VELX_NEGATIVE -0.7f
// Indice para las animaciones de los globos
#define BALLOON_MOVING_ANIMATION 0
#define BALLOON_POP_ANIMATION 1
#define BALLOON_BORN_ANIMATION 2
// Cantidad posible de globos
#define MAX_BALLOONS 100
// Velocidades a las que se mueven los enemigos
#define BALLOON_SPEED_1 0.60f
#define BALLOON_SPEED_2 0.70f
#define BALLOON_SPEED_3 0.80f
#define BALLOON_SPEED_4 0.90f
#define BALLOON_SPEED_5 1.00f
// Tamaño de los globos
#define BALLOON_WIDTH_1 8
#define BALLOON_WIDTH_2 13
#define BALLOON_WIDTH_3 21
#define BALLOON_WIDTH_4 37
// PowerBall
#define POWERBALL_SCREENPOWER_MINIMUM 10
#define POWERBALL_COUNTER 8
// Tipos de bala
#define BULLET_UP 1
#define BULLET_LEFT 2
#define BULLET_RIGHT 3
// Cantidad posible de globos
#define MAX_BULLETS 50
// Tipos de objetos
#define ITEM_POINTS_1_DISK 1
#define ITEM_POINTS_2_GAVINA 2
#define ITEM_POINTS_3_PACMAR 3
#define ITEM_CLOCK 4
#define ITEM_COFFEE 5
#define ITEM_POWER_BALL 6
#define ITEM_COFFEE_MACHINE 7
// Porcentaje de aparición de los objetos
#define ITEM_POINTS_1_DISK_ODDS 10
#define ITEM_POINTS_2_GAVINA_ODDS 6
#define ITEM_POINTS_3_PACMAR_ODDS 3
#define ITEM_CLOCK_ODDS 5
#define ITEM_COFFEE_ODDS 5
#define ITEM_POWER_BALL_ODDS 0
#define ITEM_COFFEE_MACHINE_ODDS 4
// Cantidad de objetos simultaneos
#define MAX_ITEMS 10
// Valores para las variables asociadas a los objetos
#define REMAINING_EXPLOSIONS 3
#define REMAINING_EXPLOSIONS_COUNTER 50
#define TIME_STOPPED_COUNTER 300
// Estados de entrada
#define NO_INPUT 0
#define INPUT_FIRE_LEFT 7
#define INPUT_FIRE_UP 8
#define INPUT_FIRE_RIGHT 9
#define INPUT_PAUSE 10
// Zona muerta del mando analógico
#define JOYSTICK_DEAD_ZONE 8000
// Tipos de mensajes para el retorno de las funciones
#define MSG_OK 0
#define MSG_BULLET_OUT 1
// Tipos de texto
#define TEXT_FIXED 0
#define TEXT_VARIABLE 1
// Cantidad de elementos del vector de SmartSprites
#define MAX_SMART_SPRITES 10
// Cantidad máxima de gotas de café
#define MAX_COFFEE_DROPS 100
// Contadores
#define TITLE_COUNTER 800
#define STAGE_COUNTER 200
#define INSTRUCTIONS_COUNTER 600
#define DEATH_COUNTER 350
#define SHAKE_COUNTER 10
#define HELP_COUNTER 1000
// Colores
const color_t bgColor = {0x27, 0x27, 0x36};
const color_t noColor = {0xFF, 0xFF, 0xFF};
const color_t shdwTxtColor = {0x43, 0x43, 0x4F};
// Formaciones enemigas
#define NUMBER_OF_ENEMY_FORMATIONS 100
#define MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION 50
// Dificultad del juego
#define DIFFICULTY_EASY 0
#define DIFFICULTY_NORMAL 1
#define DIFFICULTY_HARD 2
// Tipo de filtro
#define FILTER_NEAREST 0
#define FILTER_LINEAL 1
#endif

View File

@@ -1,46 +1,29 @@
#include "const.h"
#include "utils.h"
#include "director.h"
#include "utils.h"
#include <iostream>
#include <string>
#ifdef __MIPSEL__
#include <sys/stat.h>
#include <dirent.h>
#endif
// Constructor
Director::Director(std::string path)
{
// Inicializa la ruta
setExecutablePath(path);
// Inicializa variables
section.name = PROG_SECTION_GAME;
section.subsection = GAME_SECTION_PLAY_1P;
// Crea el objeto que controla los ficheros de recursos
asset = new Asset(path.substr(0, path.find_last_of("\\/")) + "/../");
// Establece la lista de ficheros
setFileList();
// Si falta algún fichero no inicies el programa
Uint8 section = PROG_SECTION_LOGO;
if (!checkFileList())
section = PROG_SECTION_QUIT;
// Inicializa el objeto de idioma
mLang = new Lang(mFileList);
// Crea el puntero a la estructura y carga el fichero de configuración
mOptions = new options_t;
if (!loadConfigFile())
{
mOptions->fullScreenMode = 0;
mOptions->windowSize = 3;
mOptions->language = en_UK;
mOptions->difficulty = DIFFICULTY_NORMAL;
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
mOptions->filter = FILTER_NEAREST;
mOptions->vSync = true;
if (!setFileList())
{ // Si falta algún fichero no inicia el programa
section.name = PROG_SECTION_QUIT;
}
// Crea los objetos
mInput = new Input(mFileList[53]);
// Crea el puntero a la estructura y carga el fichero de configuración
options = new options_t;
loadConfigFile();
// Inicializa SDL
initSDL();
@@ -48,88 +31,60 @@ Director::Director(std::string path)
// Inicializa JailAudio
initJailAudio();
// Aplica las opciones
SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode);
SDL_SetWindowSize(mWindow, SCREEN_WIDTH * mOptions->windowSize, SCREEN_HEIGHT * mOptions->windowSize);
mLang->setLang(mOptions->language);
// Crea los objetos
lang = new Lang(asset);
lang->setLang(options->language);
#ifdef __MIPSEL__
DIR *dir = opendir("/media/data/local/home/.coffee_crisis");
if (dir)
{
closedir(dir);
}
else if (ENOENT == errno)
{
int status = mkdir("/media/data/local/home/.coffee_crisis", 755);
}
#endif
input = new Input(asset->get("controllerdb.txt"));
initInput();
// Inicializa el resto de variables
init(section);
screen = new Screen(window, renderer, options, GAME_WIDTH, GAME_HEIGHT);
}
Director::~Director()
{
saveConfigFile();
delete mInput;
mInput = nullptr;
delete asset;
delete input;
delete screen;
delete lang;
delete options;
delete mLang;
mLang = nullptr;
delete mOptions;
mOptions = nullptr;
SDL_DestroyRenderer(mRenderer);
SDL_DestroyWindow(mWindow);
mRenderer = nullptr;
mWindow = nullptr;
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
// Inicia las variables necesarias para arrancar el programa
void Director::init(Uint8 name)
// Inicializa el objeto input
void Director::initInput()
{
// Sección
mSection.name = name;
mSection.subsection = 0;
// Teclado
input->bindKey(INPUT_UP, SDL_SCANCODE_UP);
input->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN);
input->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT);
input->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT);
input->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN);
input->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE);
input->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_Q);
input->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_W);
input->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_E);
input->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE); // PAUSE
input->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_ESCAPE); // ESCAPE
// Textos
mLang->setLang(mOptions->language);
// Controles
mInput->bindKey(INPUT_UP, SDL_SCANCODE_UP);
mInput->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN);
mInput->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT);
mInput->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT);
mInput->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN);
mInput->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE);
#ifdef __MIPSEL__
mInput->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_LSHIFT);
mInput->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_SPACE);
mInput->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_LCTRL);
#else
mInput->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_Q);
mInput->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_W);
mInput->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_E);
#endif
mInput->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE); // PAUSE
mInput->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_ESCAPE); // ESCAPE
mInput->bindGameControllerButton(INPUT_UP, SDL_CONTROLLER_BUTTON_DPAD_UP);
mInput->bindGameControllerButton(INPUT_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
mInput->bindGameControllerButton(INPUT_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
mInput->bindGameControllerButton(INPUT_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
mInput->bindGameControllerButton(INPUT_ACCEPT, SDL_CONTROLLER_BUTTON_B);
mInput->bindGameControllerButton(INPUT_CANCEL, SDL_CONTROLLER_BUTTON_A);
mInput->bindGameControllerButton(INPUT_BUTTON_1, SDL_CONTROLLER_BUTTON_X);
mInput->bindGameControllerButton(INPUT_BUTTON_2, SDL_CONTROLLER_BUTTON_Y);
mInput->bindGameControllerButton(INPUT_BUTTON_3, SDL_CONTROLLER_BUTTON_B);
mInput->bindGameControllerButton(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE); // PAUSE
mInput->bindGameControllerButton(INPUT_BUTTON_ESCAPE, SDL_CONTROLLER_BUTTON_GUIDE); // ESCAPE
// Mando
input->bindGameControllerButton(INPUT_UP, SDL_CONTROLLER_BUTTON_DPAD_UP);
input->bindGameControllerButton(INPUT_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
input->bindGameControllerButton(INPUT_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
input->bindGameControllerButton(INPUT_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
input->bindGameControllerButton(INPUT_ACCEPT, SDL_CONTROLLER_BUTTON_B);
input->bindGameControllerButton(INPUT_CANCEL, SDL_CONTROLLER_BUTTON_A);
input->bindGameControllerButton(INPUT_BUTTON_1, SDL_CONTROLLER_BUTTON_X);
input->bindGameControllerButton(INPUT_BUTTON_2, SDL_CONTROLLER_BUTTON_Y);
input->bindGameControllerButton(INPUT_BUTTON_3, SDL_CONTROLLER_BUTTON_B);
input->bindGameControllerButton(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE); // PAUSE
input->bindGameControllerButton(INPUT_BUTTON_ESCAPE, SDL_CONTROLLER_BUTTON_GUIDE); // ESCAPE
}
// Inicializa JailAudio
@@ -145,8 +100,7 @@ bool Director::initSDL()
bool success = true;
// Inicializa SDL
//if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0)
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0)
{
printf("SDL could not initialize!\nSDL Error: %s\n", SDL_GetError());
success = false;
@@ -156,15 +110,15 @@ bool Director::initSDL()
// Inicia el generador de numeros aleatorios
std::srand(static_cast<unsigned int>(SDL_GetTicks()));
// Establece el filtro de la textura a nearest
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(mOptions->filter).c_str()))
// Establece el filtro de la textura
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(options->filter).c_str()))
{
printf("Warning: Nearest texture filtering not enabled!\n");
}
// Crea la ventana
mWindow = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, VIEW_WIDTH, VIEW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (mWindow == NULL)
window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, options->screenWidth * options->windowSize, options->screenHeight * options->windowSize, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (window == nullptr)
{
printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false;
@@ -172,12 +126,12 @@ bool Director::initSDL()
else
{
// Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones
if (mOptions->vSync)
mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (options->vSync)
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
else
mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (mRenderer == NULL)
if (renderer == nullptr)
{
printf("Renderer could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false;
@@ -185,13 +139,13 @@ bool Director::initSDL()
else
{
// Inicializa el color de renderizado
SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF);
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
// Establece el tamaño del buffer de renderizado
SDL_RenderSetLogicalSize(mRenderer, SCREEN_WIDTH, SCREEN_HEIGHT);
SDL_RenderSetLogicalSize(renderer, options->screenWidth, options->screenHeight);
// Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(mRenderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
}
}
}
@@ -201,198 +155,158 @@ bool Director::initSDL()
}
// Crea el indice de ficheros
void Director::setFileList()
bool Director::setFileList()
{
// Inicializa el vector
for (int i = 0; i < MAX_FILE_LIST; i++)
mFileList[i] = "";
// Ficheros binarios
#ifdef __MIPSEL__
mFileList[0] = "/media/data/local/home/.coffee_crisis/score.bin";
mFileList[1] = "/media/data/local/home/.coffee_crisis/demo.bin";
mFileList[2] = "/media/data/local/home/.coffee_crisis/config.bin";
#else
mFileList[0] = mExecutablePath + "/" + "../data/score.bin";
mFileList[1] = mExecutablePath + "/" + "../data/demo.bin";
mFileList[2] = mExecutablePath + "/" + "../data/config.bin";
#endif
// Ficheros de configuración
asset->add("data/config/score.bin", t_data, false);
asset->add("data/config/demo.bin", t_data);
asset->add("data/config/config.bin", t_data, false);
asset->add("data/config/gamecontrollerdb.txt", t_data);
// Musicas
mFileList[3] = mExecutablePath + "/" + "../media/music/intro.ogg";
mFileList[4] = mExecutablePath + "/" + "../media/music/playing.ogg";
mFileList[5] = mExecutablePath + "/" + "../media/music/title.ogg";
asset->add("data/music/intro.ogg", t_music);
asset->add("data/music/playing.ogg", t_music);
asset->add("data/music/title.ogg", t_music);
// Sonidos
mFileList[6] = mExecutablePath + "/" + "../media/sound/balloon.wav";
mFileList[7] = mExecutablePath + "/" + "../media/sound/bubble1.wav";
mFileList[8] = mExecutablePath + "/" + "../media/sound/bubble2.wav";
mFileList[9] = mExecutablePath + "/" + "../media/sound/bubble3.wav";
mFileList[10] = mExecutablePath + "/" + "../media/sound/bubble4.wav";
mFileList[11] = mExecutablePath + "/" + "../media/sound/bullet.wav";
mFileList[12] = mExecutablePath + "/" + "../media/sound/coffeeout.wav";
mFileList[13] = mExecutablePath + "/" + "../media/sound/hiscore.wav";
mFileList[14] = mExecutablePath + "/" + "../media/sound/itemdrop.wav";
mFileList[15] = mExecutablePath + "/" + "../media/sound/itempickup.wav";
mFileList[16] = mExecutablePath + "/" + "../media/sound/menu_cancel.wav";
mFileList[17] = mExecutablePath + "/" + "../media/sound/menu_move.wav";
mFileList[18] = mExecutablePath + "/" + "../media/sound/menu_select.wav";
mFileList[19] = mExecutablePath + "/" + "../media/sound/player_collision.wav";
mFileList[20] = mExecutablePath + "/" + "../media/sound/stage_change.wav";
mFileList[21] = mExecutablePath + "/" + "../media/sound/title.wav";
mFileList[22] = mExecutablePath + "/" + "../media/sound/clock.wav";
mFileList[23] = mExecutablePath + "/" + "../media/sound/powerball.wav";
asset->add("data/sound/balloon.wav", t_sound);
asset->add("data/sound/bubble1.wav", t_sound);
asset->add("data/sound/bubble2.wav", t_sound);
asset->add("data/sound/bubble3.wav", t_sound);
asset->add("data/sound/bubble4.wav", t_sound);
asset->add("data/sound/bullet.wav", t_sound);
asset->add("data/sound/coffeeout.wav", t_sound);
asset->add("data/sound/hiscore.wav", t_sound);
asset->add("data/sound/itemdrop.wav", t_sound);
asset->add("data/sound/itempickup.wav", t_sound);
asset->add("data/sound/menu_cancel.wav", t_sound);
asset->add("data/sound/menu_move.wav", t_sound);
asset->add("data/sound/menu_select.wav", t_sound);
asset->add("data/sound/player_collision.wav", t_sound);
asset->add("data/sound/stage_change.wav", t_sound);
asset->add("data/sound/title.wav", t_sound);
asset->add("data/sound/clock.wav", t_sound);
asset->add("data/sound/powerball.wav", t_sound);
// Texturas
mFileList[24] = mExecutablePath + "/" + "../media/gfx/balloon.png";
mFileList[25] = mExecutablePath + "/" + "../media/gfx/bullet.png";
mFileList[31] = mExecutablePath + "/" + "../media/gfx/game_bg.png";
mFileList[32] = mExecutablePath + "/" + "../media/gfx/game_text.png";
mFileList[33] = mExecutablePath + "/" + "../media/gfx/intro.png";
mFileList[34] = mExecutablePath + "/" + "../media/gfx/items.png";
mFileList[35] = mExecutablePath + "/" + "../media/gfx/logo.png";
mFileList[37] = mExecutablePath + "/" + "../media/gfx/player1_body.png";
mFileList[38] = mExecutablePath + "/" + "../media/gfx/player1_death.png";
mFileList[39] = mExecutablePath + "/" + "../media/gfx/player1_legs.png";
mFileList[40] = mExecutablePath + "/" + "../media/gfx/title.png";
mFileList[41] = mExecutablePath + "/" + "../media/gfx/player1_head.png";
mFileList[42] = mExecutablePath + "/" + "../media/gfx/player2_body.png";
mFileList[43] = mExecutablePath + "/" + "../media/gfx/player2_death.png";
mFileList[44] = mExecutablePath + "/" + "../media/gfx/player2_legs.png";
mFileList[45] = mExecutablePath + "/" + "../media/gfx/player2_head.png";
asset->add("data/gfx/balloon.png", t_bitmap);
asset->add("data/gfx/bullet.png", t_bitmap);
asset->add("data/gfx/game_bg.png", t_bitmap);
asset->add("data/gfx/game_text.png", t_bitmap);
asset->add("data/gfx/intro.png", t_bitmap);
asset->add("data/gfx/items.png", t_bitmap);
asset->add("data/gfx/logo.png", t_bitmap);
asset->add("data/gfx/title_bg_tile.png", t_bitmap);
asset->add("data/gfx/title_coffee.png", t_bitmap);
asset->add("data/gfx/title_crisis.png", t_bitmap);
asset->add("data/gfx/title_dust.png", t_bitmap);
asset->add("data/gfx/title_dust.ani", t_data);
asset->add("data/gfx/title_gradient.png", t_bitmap);
asset->add("data/gfx/player1_head.png", t_bitmap);
asset->add("data/gfx/player1_body.png", t_bitmap);
asset->add("data/gfx/player1_legs.png", t_bitmap);
asset->add("data/gfx/player1_death.png", t_bitmap);
asset->add("data/gfx/player2_head.png", t_bitmap);
asset->add("data/gfx/player2_body.png", t_bitmap);
asset->add("data/gfx/player2_legs.png", t_bitmap);
asset->add("data/gfx/player2_death.png", t_bitmap);
// Fuentes
mFileList[27] = mExecutablePath + "/" + "../media/font/8bithud.png";
mFileList[46] = mExecutablePath + "/" + "../media/font/8bithud.txt";
mFileList[28] = mExecutablePath + "/" + "../media/font/nokia.png";
mFileList[54] = mExecutablePath + "/" + "../media/font/nokia_big2.png";
mFileList[52] = mExecutablePath + "/" + "../media/font/nokia.txt";
mFileList[56] = mExecutablePath + "/" + "../media/font/nokia2.png";
mFileList[57] = mExecutablePath + "/" + "../media/font/nokia2.txt";
mFileList[55] = mExecutablePath + "/" + "../media/font/nokia_big2.txt";
mFileList[29] = mExecutablePath + "/" + "../media/font/smb2_big.png";
mFileList[47] = mExecutablePath + "/" + "../media/font/smb2_big.txt";
mFileList[30] = mExecutablePath + "/" + "../media/font/smb2.png";
mFileList[48] = mExecutablePath + "/" + "../media/font/smb2.txt";
asset->add("data/font/8bithud.png", t_font);
asset->add("data/font/8bithud.txt", t_font);
asset->add("data/font/nokia.png", t_font);
asset->add("data/font/nokia_big2.png", t_font);
asset->add("data/font/nokia.txt", t_font);
asset->add("data/font/nokia2.png", t_font);
asset->add("data/font/nokia2.txt", t_font);
asset->add("data/font/nokia_big2.txt", t_font);
asset->add("data/font/smb2_big.png", t_font);
asset->add("data/font/smb2_big.txt", t_font);
asset->add("data/font/smb2.png", t_font);
asset->add("data/font/smb2.txt", t_font);
// Textos
mFileList[49] = mExecutablePath + "/" + "../media/lang/es_ES.txt";
mFileList[50] = mExecutablePath + "/" + "../media/lang/en_UK.txt";
mFileList[51] = mExecutablePath + "/" + "../media/lang/ba_BA.txt";
asset->add("data/lang/es_ES.txt", t_lang);
asset->add("data/lang/en_UK.txt", t_lang);
asset->add("data/lang/ba_BA.txt", t_lang);
// DATA
mFileList[53] = mExecutablePath + "/" + "../data/gamecontrollerdb.txt";
}
// Menus
asset->add("data/menu/title.men", t_data);
asset->add("data/menu/options.men", t_data);
// Comprueba los ficheros del vector de ficheros que coinciden con una ruta dada
bool Director::checkFolder(std::string name, std::string path)
{
bool success = true;
std::string p;
std::string filename;
SDL_RWops *file;
// Comprueba los ficheros de la carpeta
printf("\n>> %s FILES\n", name.c_str());
for (int i = 3; i < MAX_FILE_LIST; i++)
{
if (mFileList[i].find(path.c_str()) != std::string::npos)
{
p = mFileList[i].c_str();
filename = p.substr(p.find_last_of("\\/") + 1);
file = SDL_RWFromFile(p.c_str(), "r+b");
if (file != NULL)
{
printf("Checking file %-20s [OK]\n", filename.c_str());
}
else
{
printf("Checking file %-20s [ERROR]\n", filename.c_str());
success = false;
break;
}
SDL_RWclose(file);
}
}
return success;
}
// Comprueba que todos los ficheros existen
bool Director::checkFileList()
{
bool success = true;
printf("Checking files...\n");
if (success)
success &= checkFolder("MUSIC", "/media/music/");
if (success)
success &= checkFolder("SOUND", "/media/sound/");
if (success)
success &= checkFolder("BITMAP", "/media/gfx/");
if (success)
success &= checkFolder("FONT", "/media/font/");
if (success)
success &= checkFolder("LANG", "/media/lang/");
// Resultado
if (success)
printf("\n** All files OK.\n\n");
else
printf("\n** A file is missing. Exiting.\n\n");
return success;
return asset->check();
}
// Carga el fichero de configuración
bool Director::loadConfigFile()
{
// Pone unos valores por defecto
mOptions->fullScreenMode = 0;
mOptions->windowSize = 3;
mOptions->language = en_UK;
mOptions->difficulty = DIFFICULTY_NORMAL;
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
mOptions->filter = FILTER_NEAREST;
mOptions->vSync = true;
options->input.clear();
input_t inp;
inp.id = 0;
inp.name = "KEYBOARD";
inp.deviceType = INPUT_USE_KEYBOARD;
options->input.push_back(inp);
inp.id = 0;
inp.name = "GAME CONTROLLER";
inp.deviceType = INPUT_USE_GAMECONTROLLER;
options->input.push_back(inp);
options->fullScreenMode = 0;
options->windowSize = 3;
options->language = ba_BA;
options->difficulty = DIFFICULTY_NORMAL;
options->filter = FILTER_NEAREST;
options->vSync = true;
options->screenWidth = GAME_WIDTH;
options->screenHeight = GAME_HEIGHT;
options->integerScale = true;
options->keepAspect = true;
options->borderSize = 0.0f;
options->borderEnabled = false;
// Indicador de éxito en la carga
bool success = true;
const std::string p = mFileList[2];
const std::string p = asset->get("config.bin");
std::string filename = p.substr(p.find_last_of("\\/") + 1);
SDL_RWops *file = SDL_RWFromFile(p.c_str(), "r+b");
// El fichero no existe
if (file == NULL)
if (file == nullptr)
{
printf("Warning: Unable to open %s file\n", filename.c_str());
// Crea el fichero para escritura
file = SDL_RWFromFile(p.c_str(), "w+b");
if (file != NULL)
{
if (file != nullptr)
{ // Ha podido crear el fichero
printf("New file (%s) created!\n", filename.c_str());
// Escribe los datos
SDL_RWwrite(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1);
SDL_RWwrite(file, &mOptions->windowSize, sizeof(mOptions->windowSize), 1);
SDL_RWwrite(file, &mOptions->language, sizeof(mOptions->language), 1);
SDL_RWwrite(file, &mOptions->difficulty, sizeof(mOptions->difficulty), 1);
SDL_RWwrite(file, &mOptions->input[0].deviceType, sizeof(mOptions->input[0].deviceType), 1);
SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1);
SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1);
SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1);
SDL_RWwrite(file, &options->fullScreenMode, sizeof(options->fullScreenMode), 1);
SDL_RWwrite(file, &options->windowSize, sizeof(options->windowSize), 1);
SDL_RWwrite(file, &options->language, sizeof(options->language), 1);
SDL_RWwrite(file, &options->difficulty, sizeof(options->difficulty), 1);
SDL_RWwrite(file, &options->input.at(0).deviceType, sizeof(options->input.at(0).deviceType), 1);
SDL_RWwrite(file, &options->input.at(1).deviceType, sizeof(options->input.at(1).deviceType), 1);
SDL_RWwrite(file, &options->filter, sizeof(options->filter), 1);
SDL_RWwrite(file, &options->vSync, sizeof(options->vSync), 1);
SDL_RWwrite(file, &options->screenWidth, sizeof(options->screenWidth), 1);
SDL_RWwrite(file, &options->screenHeight, sizeof(options->screenHeight), 1);
SDL_RWwrite(file, &options->integerScale, sizeof(options->integerScale), 1);
SDL_RWwrite(file, &options->keepAspect, sizeof(options->keepAspect), 1);
// Cierra el fichero
SDL_RWclose(file);
}
else
{
{ // No ha podido crear el fichero
printf("Error: Unable to create file %s\n", filename.c_str());
success = false;
}
@@ -402,24 +316,37 @@ bool Director::loadConfigFile()
{
// Carga los datos
printf("Reading file %s\n", filename.c_str());
SDL_RWread(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1);
SDL_RWread(file, &mOptions->windowSize, sizeof(mOptions->windowSize), 1);
SDL_RWread(file, &mOptions->language, sizeof(mOptions->language), 1);
SDL_RWread(file, &mOptions->difficulty, sizeof(mOptions->difficulty), 1);
SDL_RWread(file, &mOptions->input[0].deviceType, sizeof(mOptions->input[0].deviceType), 1);
SDL_RWread(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1);
SDL_RWread(file, &mOptions->filter, sizeof(mOptions->filter), 1);
SDL_RWread(file, &mOptions->vSync, sizeof(mOptions->vSync), 1);
SDL_RWread(file, &options->fullScreenMode, sizeof(options->fullScreenMode), 1);
SDL_RWread(file, &options->windowSize, sizeof(options->windowSize), 1);
SDL_RWread(file, &options->language, sizeof(options->language), 1);
SDL_RWread(file, &options->difficulty, sizeof(options->difficulty), 1);
SDL_RWread(file, &options->input.at(0).deviceType, sizeof(options->input.at(0).deviceType), 1);
SDL_RWread(file, &options->input.at(1).deviceType, sizeof(options->input.at(1).deviceType), 1);
SDL_RWread(file, &options->filter, sizeof(options->filter), 1);
SDL_RWread(file, &options->vSync, sizeof(options->vSync), 1);
SDL_RWread(file, &options->screenWidth, sizeof(options->screenWidth), 1);
SDL_RWread(file, &options->screenHeight, sizeof(options->screenHeight), 1);
SDL_RWread(file, &options->integerScale, sizeof(options->integerScale), 1);
SDL_RWread(file, &options->keepAspect, sizeof(options->keepAspect), 1);
// Normaliza los valores
if (!((mOptions->fullScreenMode == 0) ||
(mOptions->fullScreenMode == SDL_WINDOW_FULLSCREEN) ||
(mOptions->fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP)))
mOptions->fullScreenMode = 0;
if ((mOptions->windowSize < 1) || (mOptions->windowSize > 4))
mOptions->windowSize = 3;
if ((mOptions->language < 0) || (mOptions->language > MAX_LANGUAGES))
mOptions->language = en_UK;
const bool a = options->fullScreenMode == 0;
const bool b = options->fullScreenMode == SDL_WINDOW_FULLSCREEN;
const bool c = options->fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP;
if (!(a || b || c))
{
options->fullScreenMode = 0;
}
if (options->windowSize < 1 || options->windowSize > 4)
{
options->windowSize = 3;
}
if (options->language < 0 || options->language > MAX_LANGUAGES)
{
options->language = en_UK;
}
// Cierra el fichero
SDL_RWclose(file);
@@ -432,20 +359,24 @@ bool Director::loadConfigFile()
bool Director::saveConfigFile()
{
bool success = true;
const std::string p = mFileList[2];
const std::string p = asset->get("config.bin");
std::string filename = p.substr(p.find_last_of("\\/") + 1);
SDL_RWops *file = SDL_RWFromFile(p.c_str(), "w+b");
if (file != NULL)
if (file != nullptr)
{
// Guarda los datos
SDL_RWwrite(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1);
SDL_RWwrite(file, &mOptions->windowSize, sizeof(mOptions->windowSize), 1);
SDL_RWwrite(file, &mOptions->language, sizeof(mOptions->language), 1);
SDL_RWwrite(file, &mOptions->difficulty, sizeof(mOptions->difficulty), 1);
SDL_RWwrite(file, &mOptions->input[0].deviceType, sizeof(mOptions->input[0].deviceType), 1);
SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1);
SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1);
SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1);
SDL_RWwrite(file, &options->fullScreenMode, sizeof(options->fullScreenMode), 1);
SDL_RWwrite(file, &options->windowSize, sizeof(options->windowSize), 1);
SDL_RWwrite(file, &options->language, sizeof(options->language), 1);
SDL_RWwrite(file, &options->difficulty, sizeof(options->difficulty), 1);
SDL_RWwrite(file, &options->input.at(0).deviceType, sizeof(options->input.at(0).deviceType), 1);
SDL_RWwrite(file, &options->input.at(1).deviceType, sizeof(options->input.at(1).deviceType), 1);
SDL_RWwrite(file, &options->filter, sizeof(options->filter), 1);
SDL_RWwrite(file, &options->vSync, sizeof(options->vSync), 1);
SDL_RWwrite(file, &options->screenWidth, sizeof(options->screenWidth), 1);
SDL_RWwrite(file, &options->screenHeight, sizeof(options->screenHeight), 1);
SDL_RWwrite(file, &options->integerScale, sizeof(options->integerScale), 1);
SDL_RWwrite(file, &options->keepAspect, sizeof(options->keepAspect), 1);
printf("Writing file %s\n", filename.c_str());
@@ -455,81 +386,66 @@ bool Director::saveConfigFile()
else
{
printf("Error: Unable to save %s file! %s\n", filename.c_str(), SDL_GetError());
success = false;
}
return success;
}
// Establece el valor de la variable
void Director::setExecutablePath(std::string path)
{
mExecutablePath = path.substr(0, path.find_last_of("\\/"));
}
// Obtiene el valor de la variable
Uint8 Director::getSubsection()
{
return mSection.subsection;
}
// Obtiene el valor de la variable
Uint8 Director::getSection()
{
return mSection.name;
}
// Establece el valor de la variable
void Director::setSection(section_t section)
{
mSection = section;
this->section = section;
}
void Director::runLogo()
{
mLogo = new Logo(mRenderer, mFileList);
setSection(mLogo->run());
delete mLogo;
logo = new Logo(renderer, screen, asset);
setSection(logo->run());
delete logo;
}
void Director::runIntro()
{
mIntro = new Intro(mRenderer, mFileList, mLang);
setSection(mIntro->run());
delete mIntro;
intro = new Intro(renderer, screen, asset, lang);
setSection(intro->run());
delete intro;
}
void Director::runTitle()
{
mTitle = new Title(mWindow, mRenderer, mInput, mFileList, mOptions, mLang);
setSection(mTitle->run(mSection.subsection));
delete mTitle;
title = new Title(renderer, screen, input, asset, options, lang, section);
setSection(title->run());
delete title;
}
void Director::runGame()
{
if (mSection.subsection == GAME_SECTION_PLAY_1P)
mGame = new Game(1, mRenderer, mFileList, mLang, mInput, false, mOptions);
if (mSection.subsection == GAME_SECTION_PLAY_2P)
mGame = new Game(2, mRenderer, mFileList, mLang, mInput, false, mOptions);
setSection(mGame->run());
delete mGame;
const int numPlayers = section.subsection == GAME_SECTION_PLAY_1P ? 1 : 2;
game = new Game(numPlayers, 0, renderer, screen, asset, lang, input, false, options);
setSection(game->run());
delete game;
}
void Director::run()
{
// Bucle principal
while (!(getSection() == PROG_SECTION_QUIT))
while (section.name != PROG_SECTION_QUIT)
{
switch (getSection())
switch (section.name)
{
case PROG_SECTION_LOGO:
runLogo();
break;
case PROG_SECTION_INTRO:
runIntro();
break;
case PROG_SECTION_TITLE:
runTitle();
break;
case PROG_SECTION_GAME:
runGame();
break;

View File

@@ -1,51 +1,53 @@
#pragma once
#include "ifdefs.h"
#include "sprite.h"
#include "movingsprite.h"
#include "smartsprite.h"
#include "player.h"
#include <SDL2/SDL.h>
#include "asset.h"
#include "balloon.h"
#include "bullet.h"
#include "coffeedrop.h"
#include "item.h"
#include "text.h"
#include "writer.h"
#include "menu.h"
#include "const.h"
#include "jail_audio.h"
#include "utils.h"
#include "logo.h"
#include "intro.h"
#include "title.h"
#include "fade.h"
#include "game.h"
#include "input.h"
#include "fade.h"
//#include <math.h>
#include "intro.h"
#include "item.h"
#include "jail_audio.h"
#include "logo.h"
#include "menu.h"
#include "movingsprite.h"
#include "player.h"
#include "screen.h"
#include "smartsprite.h"
#include "sprite.h"
#include "text.h"
#include "title.h"
#include "utils.h"
#include "writer.h"
#ifndef DIRECTOR_H
#define DIRECTOR_H
#define MAX_FILE_LIST 100
// Textos
#define WINDOW_CAPTION "Coffee Crisis"
// Director
// Clase Director
class Director
{
private:
SDL_Window *mWindow; // La ventana donde dibujamos
SDL_Renderer *mRenderer; // El renderizador de la ventana
// Objetos
SDL_Window *window; // La ventana donde dibujamos
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
Logo *logo; // Objeto para la sección del logo
Intro *intro; // Objeto para la sección de la intro
Title *title; // Objeto para la sección del titulo y el menu de opciones
Game *game; // Objeto para la sección del juego
Input *input; // Objeto Input para gestionar las entradas
Lang *lang; // Objeto para gestionar los textos en diferentes idiomas
Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Logo *mLogo; // Objeto para la sección del logo
Intro *mIntro; // Objeto para la sección de la intro
Title *mTitle; // Objeto para la sección del titulo y el menu de opciones
Game *mGame; // Objeto para la sección del juego
Input *mInput; // Objeto Input para gestionar las entradas
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
std::string mFileList[MAX_FILE_LIST]; // Vector con las rutas a los ficheros de recursos
struct options_t *mOptions; // Variable con todas las opciones del programa
std::string mExecutablePath; // Path del ejecutable
section_t mSection; // Sección y subsección actual del programa;
// Variables
struct options_t *options; // Variable con todas las opciones del programa
section_t section; // Sección y subsección actual del programa;
// Inicializa jail_audio
void initJailAudio();
@@ -53,11 +55,11 @@ private:
// Arranca SDL y crea la ventana
bool initSDL();
// Crea el indice de ficheros
void setFileList();
// Inicializa el objeto input
void initInput();
// Comprueba que todos los ficheros existen
bool checkFileList();
// Crea el indice de ficheros
bool setFileList();
// Carga el fichero de configuración
bool loadConfigFile();
@@ -65,15 +67,6 @@ private:
// Guarda el fichero de configuración
bool saveConfigFile();
// Establece el valor de la variable
void setExecutablePath(std::string path);
// Obtiene el valor de la variable
Uint8 getSubsection();
// Obtiene el valor de la variable
Uint8 getSection();
// Establece el valor de la variable
void setSection(section_t section);
@@ -89,9 +82,6 @@ private:
// Ejecuta la seccion de juego donde se juega
void runGame();
// Comprueba los ficheros del vector de ficheros que coinciden con una ruta dada
bool checkFolder(std::string name, std::string path);
public:
// Constructor
Director(std::string path);
@@ -99,9 +89,6 @@ public:
// Destructor
~Director();
// Inicia las variables necesarias para arrancar el programa
void init(Uint8 name);
// Bucle principal
void run();
};

View File

@@ -6,8 +6,8 @@ Fade::Fade(SDL_Renderer *renderer)
{
mRenderer = renderer;
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT);
if (mBackbuffer == NULL)
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAME_WIDTH, GAME_HEIGHT);
if (mBackbuffer == nullptr)
printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError());
}
@@ -25,9 +25,6 @@ void Fade::init(Uint8 r, Uint8 g, Uint8 b)
mEnabled = false;
mFinished = false;
mCounter = 0;
//mR = 0x27;
//mG = 0x27;
//mB = 0x36;
mR = r;
mG = g;
mB = b;
@@ -41,15 +38,15 @@ void Fade::render()
switch (mFadeType)
{
case FADE_FULLSCREEN:
mRect1 = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
mRect1 = {0, 0, GAME_WIDTH, GAME_HEIGHT};
for (int i = 0; i < 256; i += 4)
{
// Dibujamos sobre el renderizador
SDL_SetRenderTarget(mRenderer, NULL);
SDL_SetRenderTarget(mRenderer, nullptr);
// Copia el backbuffer con la imagen que había al renderizador
SDL_RenderCopy(mRenderer, mBackbuffer, NULL, NULL);
SDL_RenderCopy(mRenderer, mBackbuffer, nullptr, nullptr);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, i);
SDL_RenderFillRect(mRenderer, &mRect1);
@@ -63,27 +60,27 @@ void Fade::render()
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
SDL_RenderClear(mRenderer);
SDL_SetRenderTarget(mRenderer, NULL);
SDL_SetRenderTarget(mRenderer, nullptr);
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
SDL_RenderClear(mRenderer);
break;
case FADE_CENTER:
mRect1 = {0, 0, SCREEN_WIDTH, 0};
mRect2 = {0, 0, SCREEN_WIDTH, 0};
mRect1 = {0, 0, GAME_WIDTH, 0};
mRect2 = {0, 0, GAME_WIDTH, 0};
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 64);
for (int i = 0; i < mCounter; i++)
{
mRect1.h = mRect2.h = i * 4;
mRect2.y = SCREEN_HEIGHT - (i * 4);
mRect2.y = GAME_HEIGHT - (i * 4);
SDL_RenderFillRect(mRenderer, &mRect1);
SDL_RenderFillRect(mRenderer, &mRect2);
}
if ((mCounter * 4) > SCREEN_HEIGHT)
if ((mCounter * 4) > GAME_HEIGHT)
mFinished = true;
break;
@@ -101,15 +98,15 @@ void Fade::render()
// Dibujamos sobre el backbuffer
SDL_SetRenderTarget(mRenderer, mBackbuffer);
mRect1.x = rand() % (SCREEN_WIDTH - mRect1.w);
mRect1.y = rand() % (SCREEN_HEIGHT - mRect1.h);
mRect1.x = rand() % (GAME_WIDTH - mRect1.w);
mRect1.y = rand() % (GAME_HEIGHT - mRect1.h);
SDL_RenderFillRect(mRenderer, &mRect1);
// Volvemos a usar el renderizador de forma normal
SDL_SetRenderTarget(mRenderer, NULL);
SDL_SetRenderTarget(mRenderer, nullptr);
// Copiamos el backbuffer al renderizador
SDL_RenderCopy(mRenderer, mBackbuffer, NULL, NULL);
SDL_RenderCopy(mRenderer, mBackbuffer, nullptr, nullptr);
// Volcamos el renderizador en pantalla
SDL_RenderPresent(mRenderer);
@@ -121,7 +118,7 @@ void Fade::render()
break;
}
}
if (mFinished)
{
SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
@@ -153,16 +150,7 @@ bool Fade::isEnabled()
// Comprueba si ha terminado la transicion
bool Fade::hasEnded()
{
if (mFinished)
{
//mEnabled = false;
//mFinished = false;
return true;
}
else
{
return false;
}
return mFinished;
}
// Establece el tipo de fade

View File

@@ -1,15 +1,17 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "ltexture.h"
#ifndef FADE_H
#define FADE_H
// Tipos de fundido
#define FADE_FULLSCREEN 0
#define FADE_CENTER 1
#define FADE_RANDOM_SQUARE 2
// Fade
// Clase Fade
class Fade
{
private:

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +1,62 @@
#pragma once
#include "ifdefs.h"
#include "const.h"
#include "utils.h"
#include "sprite.h"
#include "movingsprite.h"
#include "smartsprite.h"
#include "player.h"
#include <SDL2/SDL.h>
#include "asset.h"
#include "balloon.h"
#include "bullet.h"
#include "item.h"
#include "text.h"
#include "writer.h"
#include "menu.h"
#include "input.h"
#include "const.h"
#include "fade.h"
#include "input.h"
#include "item.h"
#include "jail_audio.h"
#include "menu.h"
#include "movingsprite.h"
#include "player.h"
#include "screen.h"
#include "smartsprite.h"
#include "sprite.h"
#include "text.h"
#include "utils.h"
#include "writer.h"
#ifndef GAME_H
#define GAME_H
// Game
// Cantidad de elementos a escribir en los ficheros de datos
#define TOTAL_SCORE_DATA 3
#define TOTAL_DEMO_DATA 2000
// Contadores
#define STAGE_COUNTER 200
#define SHAKE_COUNTER 10
#define HELP_COUNTER 1000
// Formaciones enemigas
#define NUMBER_OF_ENEMY_FORMATIONS 100
#define MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION 50
// Cantidad de elementos del vector de SmartSprites
#define MAX_SMART_SPRITES 10
// Cantidad máxima posible de balas
#define MAX_BULLETS 50
// Porcentaje de aparición de los objetos
#define ITEM_POINTS_1_DISK_ODDS 10
#define ITEM_POINTS_2_GAVINA_ODDS 6
#define ITEM_POINTS_3_PACMAR_ODDS 3
#define ITEM_CLOCK_ODDS 5
#define ITEM_COFFEE_ODDS 5
#define ITEM_POWER_BALL_ODDS 0
#define ITEM_COFFEE_MACHINE_ODDS 4
// Cantidad de objetos simultaneos
#define MAX_ITEMS 10
// Valores para las variables asociadas a los objetos
#define TIME_STOPPED_COUNTER 300
// Clase Game
class Game
{
private:
@@ -40,13 +74,11 @@ private:
Uint8 numberOfEnemies; // Cantidad de enemigos que forman la formación
enemyInits_t init[MAX_NUMBER_OF_ENEMIES_IN_A_FORMATION]; // Vector con todas las inicializaciones de los enemigos de la formación
};
enemyFormation_t mEnemyFormation[NUMBER_OF_ENEMY_FORMATIONS]; // Vector con todas las formaciones enemigas
struct enemyPool_t
{
enemyFormation_t *set[10]; // Conjunto de formaciones enemigas
};
enemyPool_t mEnemyPool[10]; // Variable con los diferentes conjuntos de formaciones enemigas
struct stage_t // Contiene todas las variables relacionadas con una fase
{
@@ -79,43 +111,55 @@ private:
int itemCoffeeMachineOdds; // Probabilidad de aparición del objeto
};
struct demo_t
{
bool enabled; // Indica si está activo el modo demo
bool recording; // Indica si está activado el modo para grabar la demo
Uint16 counter; // Contador para el modo demo
demoKeys_t keys; // Variable con las pulsaciones de teclas del modo demo
demoKeys_t dataFile[TOTAL_DEMO_DATA]; // Datos del fichero con los movimientos para la demo
};
struct debug_t
{
bool enabled; // Indica si se va a mostrar la información de debug
Uint8 enemySet; // Escoge el set enemigo a generar
Uint8 gradR, gradG, gradB; // Colores RGB para modificar el color del gradiente de fondo
float hudW, hudH; // Multiplica el tamaño del hud de debug;
};
SDL_Renderer *mRenderer; // El renderizador de la ventana
std::string *mFileList; // Lista de ficheros con los recursos
Screen *mScreen; // Objeto encargado de dibujar en pantalla
Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
Input *mInput; // Manejador de entrada
int mNumPlayers; // Numero de jugadores
Player *mPlayer[2]; // Vector con los jugadores jugador
Input *mInput; // Manejador de entrada
int mNumPlayers; // Numero de jugadores
std::vector<Player *> players; // Vector con los jugadores
std::vector<Balloon *> balloons; // Vector con los globos
std::vector<Bullet *> bullets; // Vector con las balas
std::vector<Item *> items; // Vector con los items
std::vector<SmartSprite *> smartSprites; // Vector con los smartsprites
Balloon *mBalloon[MAX_BALLOONS]; // Vector con los objetos globo
Bullet *mBullet[MAX_BULLETS]; // Vector con los objetos bala
Item *mItem[MAX_ITEMS]; // Vector con los objetos item
SmartSprite *mSmartSprite[MAX_SMART_SPRITES]; // Vector para almacenar y gestionar SmartSprites
LTexture *mTextureBalloon; // Textura para los enemigos
LTexture *mTextureBullet; // Textura para las balas
LTexture *mTextureGameBG; // Textura para el fondo del juego
LTexture *mTextureGameText; // Textura para los sprites con textos
LTexture *mTextureItems; // Textura para los items
LTexture *mTexturePlayer1Head; // Textura para la cabeza del jugador1
LTexture *mTexturePlayer1Body; // Textura para el cuerpo del jugador1
LTexture *mTexturePlayer1Death; // Textura para la animación de muerte del jugador1
LTexture *mTexturePlayer1Legs; // Textura para las piernas del jugador
LTexture *mTexturePlayer2Head; // Textura para la cabeza del jugador2
LTexture *mTexturePlayer2Body; // Textura para el cuerpo del jugador2
LTexture *mTexturePlayer2Death; // Textura para la animación de muerte del jugador2
LTexture *mTexturePlayer2Legs; // Textura para las piernas del jugador
LTexture *mTextureText; // Textura para el texto del juego
LTexture *mTextureTextScoreBoard; // Textura para el texto del marcador
LTexture *mTextureTextBig; // Textura para el texto grande
LTexture *mTextureTextNokia2; // Textura para la fuente de texto Nokia
LTexture *mTextureTextNokiaBig2; // Textura para la fuente de texto Nokia grande
LTexture *mTextureBalloon; // Textura para los enemigos
LTexture *mTextureBullet; // Textura para las balas
LTexture *mTextureGameBG; // Textura para el fondo del juego
LTexture *mTextureGameText; // Textura para los sprites con textos
LTexture *mTextureItems; // Textura para los items
LTexture *mTexturePlayer1Head; // Textura para la cabeza del jugador1
LTexture *mTexturePlayer1Body; // Textura para el cuerpo del jugador1
LTexture *mTexturePlayer1Death; // Textura para la animación de muerte del jugador1
LTexture *mTexturePlayer1Legs; // Textura para las piernas del jugador
LTexture *mTexturePlayer2Head; // Textura para la cabeza del jugador2
LTexture *mTexturePlayer2Body; // Textura para el cuerpo del jugador2
LTexture *mTexturePlayer2Death; // Textura para la animación de muerte del jugador2
LTexture *mTexturePlayer2Legs; // Textura para las piernas del jugador
Text *mText; // Fuente para los textos del juego
Text *mTextBig; // Fuente de texto grande
Text *mTextScoreBoard; // Fuente para el marcador del juego
Text *mTextNokia2; // Otra fuente de texto para mesajes
Text *mTextNokiaBig2; // Y la versión en grande
Text *mTextNokiaBig2; // Y la versión en grande
Menu *mMenuGameOver; // Menú de la pantalla de game over
Menu *mMenuPause; // Menú de la pantalla de pausa
@@ -158,63 +202,47 @@ private:
Uint32 mTicks; // Contador de ticks para ajustar la velocidad del programa
Uint8 mTicksSpeed; // Velocidad a la que se repiten los bucles del programa
Uint32 mHiScore; // Puntuación máxima
bool mHiScoreAchieved; // Indica si se ha superado la puntuación máxima
section_t mSection; // Seccion actual dentro del juego
stage_t mStage[10]; // Variable con los datos de cada pantalla
Uint8 mCurrentStage; // Indica la fase actual
Uint8 mStageBitmapCounter; // Contador para el tiempo visible del texto de Stage
float mStageBitmapPath[STAGE_COUNTER]; // Vector con los puntos Y por donde se desplaza el texto
float mGetReadyBitmapPath[STAGE_COUNTER]; // Vector con los puntos X por donde se desplaza el texto
Uint16 mDeathCounter; // Contador para la animación de muerte del jugador
Uint8 mDeathIndex; // Indice del vector de smartsprites que contiene el sprite del jugador
Uint8 mMenaceCurrent; // Nivel de amenaza actual
Uint8 mMenaceThreshold; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el numero de globos
bool mTimeStopped; // Indica si el tiempo está detenido
Uint16 mTimeStoppedCounter; // Temporizador para llevar la cuenta del tiempo detenido
Uint8 mRemainingExplosions; // Cantidad de explosiones restantes
Uint16 mRemainingExplosionsCounter; // Temporizador para la cantidad de explosiones restantes
bool mExplosionTime; // Indica si las explosiones estan en marcha
Uint32 mCounter; // Contador para el juego
Uint32 mScoreDataFile[TOTAL_SCORE_DATA]; // Datos del fichero de puntos
SDL_Rect mGradientRect[4]; // Vector con las coordenadas de los 4 gradientes
Uint16 mBalloonsPopped; // Lleva la cuenta de los globos explotados
Uint8 mLastEnemyDeploy; // Guarda cual ha sido la última formación desplegada para no repetir;
Uint8 mEnemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero
float mEnemySpeed; // Velocidad a la que se mueven los enemigos
float mDefaultEnemySpeed; // Velocidad base de los enemigos, sin incrementar
effect_t mEffect; // Variable para gestionar los efectos visuales
helper_t mHelper; // Variable para gestionar las ayudas
bool mPowerBallEnabled; // Indica si hay una powerball ya activa
Uint8 mPowerBallCounter; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra
bool mCoffeeMachineEnabled; // Indica si hay una máquina de café en el terreno de juego
Uint8 mPostFade; // Qué hacer al acabar el fade
float mSin[360]; // Vector con los valores del seno para 360 grados
bool mGameCompleted; // Indica si se ha completado la partida, llegando al final de la ultima pantalla
int mGameCompletedCounter; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más enemigos
Uint8 mDifficulty; // Dificultad del juego
float mDifficultyScoreMultiplier; // Multiplicador de puntos en función de la dificultad
struct options_t *mOptions; // Variable con todas las variables de las opciones del programa
Uint8 mOnePlayerControl; // Variable para almacenar el valor de las opciones
Uint32 mHiScore; // Puntuación máxima
bool mHiScoreAchieved; // Indica si se ha superado la puntuación máxima
section_t mSection; // Seccion actual dentro del juego
stage_t mStage[10]; // Variable con los datos de cada pantalla
Uint8 mCurrentStage; // Indica la fase actual
Uint8 mStageBitmapCounter; // Contador para el tiempo visible del texto de Stage
float mStageBitmapPath[STAGE_COUNTER]; // Vector con los puntos Y por donde se desplaza el texto
float mGetReadyBitmapPath[STAGE_COUNTER]; // Vector con los puntos X por donde se desplaza el texto
Uint16 mDeathCounter; // Contador para la animación de muerte del jugador
Uint8 mDeathIndex; // Indice del vector de smartsprites que contiene el sprite del jugador
Uint8 mMenaceCurrent; // Nivel de amenaza actual
Uint8 mMenaceThreshold; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el numero de globos
bool mTimeStopped; // Indica si el tiempo está detenido
Uint16 mTimeStoppedCounter; // Temporizador para llevar la cuenta del tiempo detenido
Uint32 mCounter; // Contador para el juego
Uint32 mScoreDataFile[TOTAL_SCORE_DATA]; // Datos del fichero de puntos
SDL_Rect mGradientRect[4]; // Vector con las coordenadas de los 4 gradientes
Uint16 mBalloonsPopped; // Lleva la cuenta de los globos explotados
Uint8 mLastEnemyDeploy; // Guarda cual ha sido la última formación desplegada para no repetir;
int mEnemyDeployCounter; // Cuando se lanza una formación, se le da un valor y no sale otra hasta que llegue a cero
float mEnemySpeed; // Velocidad a la que se mueven los enemigos
float mDefaultEnemySpeed; // Velocidad base de los enemigos, sin incrementar
effect_t mEffect; // Variable para gestionar los efectos visuales
helper_t mHelper; // Variable para gestionar las ayudas
bool mPowerBallEnabled; // Indica si hay una powerball ya activa
Uint8 mPowerBallCounter; // Contador de formaciones enemigas entre la aparicion de una PowerBall y otra
bool mCoffeeMachineEnabled; // Indica si hay una máquina de café en el terreno de juego
Uint8 mPostFade; // Qué hacer al acabar el fade
float mSin[360]; // Vector con los valores del seno para 360 grados
bool mGameCompleted; // Indica si se ha completado la partida, llegando al final de la ultima pantalla
int mGameCompletedCounter; // Contador para el tramo final, cuando se ha completado la partida y ya no aparecen más enemigos
Uint8 mDifficulty; // Dificultad del juego
float mDifficultyScoreMultiplier; // Multiplicador de puntos en función de la dificultad
struct options_t *mOptions; // Variable con todas las variables de las opciones del programa
Uint8 mOnePlayerControl; // Variable para almacenar el valor de las opciones
enemyFormation_t mEnemyFormation[NUMBER_OF_ENEMY_FORMATIONS]; // Vector con todas las formaciones enemigas
enemyPool_t mEnemyPool[10]; // Variable con los diferentes conjuntos de formaciones enemigas
Uint8 mLastStageReached; // Contiene el numero de la última pantalla que se ha alcanzado
struct demo_t
{
bool enabled; // Indica si está activo el modo demo
bool recording; // Indica si está activado el modo para grabar la demo
Uint16 counter; // Contador para el modo demo
demoKeys_t keys; // Variable con las pulsaciones de teclas del modo demo
demoKeys_t dataFile[TOTAL_DEMO_DATA]; // Datos del fichero con los movimientos para la demo
};
demo_t mDemo; // Variable con todas las variables relacionadas con el modo demo
struct debug_t
{
bool enabled; // Indica si se va a mostrar la información de debug
Uint8 enemySet; // Escoge el set enemigo a generar
Uint8 gradR, gradG, gradB; // Colores RGB para modificar el color del gradiente de fondo
float hudW, hudH; // Multiplica el tamaño del hud de debug;
};
debug_t mDebug;
demo_t mDemo; // Variable con todas las variables relacionadas con el modo demo
debug_t mDebug; // Variable con las opciones de debug
// Inicializa el vector con los valores del seno
void initSin();
@@ -282,18 +310,12 @@ private:
// Pinta en pantalla todos los globos activos
void renderBalloons();
// Devuelve el primer indice no activo del vector de globos
Uint8 getBalloonFreeIndex();
// Crea un globo nuevo en el vector de globos
Uint8 createNewBalloon(float x, int y, Uint8 kind, float velx, float speed, Uint16 stoppedcounter, LTexture *texture);
// Crea una PowerBall
void createPowerBall();
// Establece a cero todos los valores del vector de objetos globo
void resetBalloons();
// Establece la velocidad de los globos
void setBalloonSpeed(float speed);
@@ -307,10 +329,10 @@ private:
void updateBalloonSpeed();
// Explosiona un globo. Lo destruye y crea otros dos si es el caso
void popBalloon(Uint8 index);
void popBalloon(Balloon *balloon);
// Explosiona un globo. Lo destruye
void destroyBalloon(Uint8 index);
void destroyBalloon(Balloon *balloon);
// Explosiona todos los globos
void popAllBalloons();
@@ -328,10 +350,10 @@ private:
Uint8 countBalloons();
// Comprueba la colisión entre el jugador y los globos activos
bool checkPlayerBalloonCollision(int index);
bool checkPlayerBalloonCollision(Player *player);
// Comprueba la colisión entre el jugador y los items
void checkPlayerItemCollision(int index);
void checkPlayerItemCollision(Player *player);
// Comprueba la colisión entre las balas y los globos
void checkBulletBalloonCollision();
@@ -342,12 +364,6 @@ private:
// Pinta las balas activas
void renderBullets();
// Devuelve el primer indice no activo del vector de balas
Uint8 getBulletFreeIndex();
// Establece a cero todos los valores del vector de objetos bala
void resetBullets();
// Crea un objeto bala
void createBullet(int x, int y, Uint8 kind, bool poweredUp, int owner);
@@ -357,17 +373,11 @@ private:
// Pinta los items activos
void renderItems();
// Devuelve el primer indice no activo del vector de items
Uint8 getItemFreeIndex();
// Establece a cero todos los valores del vector de objetos item
void resetItems();
// Devuelve un item en función del azar
Uint8 dropItem();
// Crea un objeto item
void createItem(int x, int y, Uint8 kind);
void createItem(LTexture *texture, SDL_Renderer *renderer, Uint8 type, float x, float y);
// Crea un objeto SmartSprite
void createItemScoreSprite(int x, int y, SmartSprite *sprite);
@@ -382,7 +392,7 @@ private:
void throwCoffee(int x, int y);
// Crea un SmartSprite para arrojar al jugador al morir
void throwPlayer(int x, int y, int index);
void throwPlayer(int x, int y, Player *player);
// Actualiza los SmartSprites
void updateSmartSprites();
@@ -390,14 +400,8 @@ private:
// Pinta los SmartSprites activos
void renderSmartSprites();
// Devuelve el primer indice no activo del vector de SmartSprites
Uint8 getSmartSpriteFreeIndex();
// Establece a cero todos los valores del vector de objetos SmafrtSprite
void resetSmartSprites();
// Acciones a realizar cuando el jugador muere
void killPlayer(int index);
void killPlayer(Player *player);
// Obtiene el valor de la variable
Uint8 getSubsection();
@@ -426,18 +430,6 @@ private:
// Actualiza y comprueba el valor de la variable
void updateTimeStoppedCounter();
// Establece el valor de la variable
void setExplosionTime(bool value);
// Obtiene el valor de la variable
bool isExplosionTime();
// Establece el valor de la variable
void setRemainingExplosions(Uint8 value);
// Actualiza y comprueba el valor de la variable
void updateRemainingExplosionsCounter();
// Gestiona el nivel de amenaza
void updateMenace();
@@ -453,9 +445,6 @@ private:
// Dibuja el campo de juego
void renderPlayField();
// Gestiona las entradas desde el mando de juego
bool checkGameController(Uint8 state);
// Gestiona la entrada durante el juego
void checkGameInput();
@@ -500,7 +489,7 @@ private:
public:
// Constructor
Game(int numPlayers, SDL_Renderer *renderer, std::string *filelist, Lang *lang, Input *input, bool demo, options_t *options);
Game(int numPlayers, int currentStage, SDL_Renderer *renderer, Screen *screen, Asset *mAsset, Lang *lang, Input *input, bool demo, options_t *options);
// Destructor
~Game();

View File

@@ -1,22 +0,0 @@
#ifdef _WIN64
#include "C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include\c++\SDL2\SDL.h"
#endif
#ifdef _WIN32
#include "C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include\c++\SDL2\SDL.h"
#endif
#ifdef __APPLE__
//#include "/Library/Frameworks/SDL2.framework/Versions/A/Headers/SDL.h"
#include <SDL2/SDL.h>
#endif
#ifdef __linux__
#ifdef __MIPSEL__
#include "SDL.h"
#else
#include <SDL2/SDL.h>
#endif
#endif
#define UNUSED

View File

@@ -1,45 +1,42 @@
#include "input.h"
#include <iostream>
// Contestar cuantos joystics ha detectado
// Preguntarlepor los joystics que ha encontrado para ir poniendolos en la variable de opciones
// Constructor
Input::Input(std::string file)
{
// Fichero gamecontrollerdb.txt
mDBpath = file;
dbPath = file;
// Inicializa las variables
for (int i = 0; i < 17; i++)
{
mKeyBindings[i].scancode = 0;
mKeyBindings[i].active = false;
keyBindings_t kb;
kb.scancode = 0;
kb.active = false;
keyBindings.resize(17, kb);
mGameControllerBindings[i].button = SDL_CONTROLLER_BUTTON_INVALID;
mGameControllerBindings[i].active = false;
}
GameControllerBindings_t gcb;
gcb.button = SDL_CONTROLLER_BUTTON_INVALID;
gcb.active = false;
gameControllerBindings.resize(17, gcb);
// Comprueba si hay un mando conectado
discoverGameController();
}
// Destructor
Input::~Input()
{
for (int i = 0; i < mNumGamepads; i++)
mConnectedControllers[i] = nullptr;
}
// Asigna uno de los posibles inputs a una tecla del teclado
void Input::bindKey(Uint8 input, SDL_Scancode code)
{
mKeyBindings[input].scancode = code;
keyBindings.at(input).scancode = code;
}
// Asigna uno de los posibles inputs a un botón del mando
void Input::bindGameControllerButton(Uint8 input, SDL_GameControllerButton button)
{
mGameControllerBindings[input].button = button;
gameControllerBindings.at(input).button = button;
}
// Comprueba si un input esta activo
@@ -51,24 +48,28 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
if (device == INPUT_USE_ANY)
index = 0;
if ((device == INPUT_USE_KEYBOARD) || (device == INPUT_USE_ANY))
if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY)
{
const Uint8 *mKeystates = SDL_GetKeyboardState(NULL);
const Uint8 *keyStates = SDL_GetKeyboardState(nullptr);
if (repeat)
{
if (mKeystates[mKeyBindings[input].scancode] != 0)
if (keyStates[keyBindings.at(input).scancode] != 0)
{
successKeyboard = true;
}
else
{
successKeyboard = false;
}
}
else
{
if (!mKeyBindings[input].active)
if (!keyBindings.at(input).active)
{
if (mKeystates[mKeyBindings[input].scancode] != 0)
if (keyStates[keyBindings.at(input).scancode] != 0)
{
mKeyBindings[input].active = true;
keyBindings.at(input).active = true;
successKeyboard = true;
}
else
@@ -78,9 +79,9 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
}
else
{
if (mKeystates[mKeyBindings[input].scancode] == 0)
if (keyStates[keyBindings.at(input).scancode] == 0)
{
mKeyBindings[input].active = false;
keyBindings.at(input).active = false;
successKeyboard = false;
}
else
@@ -96,18 +97,22 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
{
if (repeat)
{
if (SDL_GameControllerGetButton(mConnectedControllers[index], mGameControllerBindings[input].button) != 0)
if (SDL_GameControllerGetButton(connectedControllers.at(index), gameControllerBindings[input].button) != 0)
{
successGameController = true;
}
else
{
successGameController = false;
}
}
else
{
if (!mGameControllerBindings[input].active)
if (!gameControllerBindings[input].active)
{
if (SDL_GameControllerGetButton(mConnectedControllers[index], mGameControllerBindings[input].button) != 0)
if (SDL_GameControllerGetButton(connectedControllers.at(index), gameControllerBindings[input].button) != 0)
{
mGameControllerBindings[input].active = true;
gameControllerBindings[input].active = true;
successGameController = true;
}
else
@@ -117,9 +122,9 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
}
else
{
if (SDL_GameControllerGetButton(mConnectedControllers[index], mGameControllerBindings[input].button) == 0)
if (SDL_GameControllerGetButton(connectedControllers.at(index), gameControllerBindings[input].button) == 0)
{
mGameControllerBindings[input].active = false;
gameControllerBindings[input].active = false;
successGameController = false;
}
else
@@ -139,45 +144,54 @@ bool Input::discoverGameController()
bool found = false;
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) != 1)
{
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
}
if (SDL_GameControllerAddMappingsFromFile(mDBpath.c_str()) < 0)
printf("Error, could not load %s file: %s\n", mDBpath.c_str(), SDL_GetError());
if (SDL_GameControllerAddMappingsFromFile(dbPath.c_str()) < 0)
{
printf("Error, could not load %s file: %s\n", dbPath.c_str(), SDL_GetError());
}
int nJoysticks = SDL_NumJoysticks();
mNumGamepads = 0;
const int nJoysticks = SDL_NumJoysticks();
numGamepads = 0;
// Cuenta el numero de mandos
for (int i = 0; i < nJoysticks; i++)
for (int i = 0; i < nJoysticks; ++i)
{
if (SDL_IsGameController(i))
mNumGamepads++;
{
numGamepads++;
}
}
printf("\nChecking for game controllers...\n");
printf("%i joysticks found, %i are gamepads\n", nJoysticks, mNumGamepads);
printf("%i joysticks found, %i are gamepads\n", nJoysticks, numGamepads);
if (mNumGamepads > 0)
if (numGamepads > 0)
{
found = true;
for (int i = 0; i < mNumGamepads; i++)
for (int i = 0; i < numGamepads; i++)
{
// Abre el mando y lo añade a la lista
SDL_GameController *pad = SDL_GameControllerOpen(i);
if (SDL_GameControllerGetAttached(pad) == 1)
{
mConnectedControllers.push_back(pad);
std::string separator(" #");
connectedControllers.push_back(pad);
const std::string separator(" #");
std::string name = SDL_GameControllerNameForIndex(i);
name.resize(25);
name = name + separator + std::to_string(i);
std::cout << name << std::endl;
mControllerNames.push_back(name);
controllerNames.push_back(name);
}
else
{
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
}
}
//mGameController = mConnectedControllers[0];
SDL_GameControllerEventState(SDL_ENABLE);
}
@@ -187,23 +201,31 @@ bool Input::discoverGameController()
// Comprueba si hay algun mando conectado
bool Input::gameControllerFound()
{
if (mNumGamepads > 0)
if (numGamepads > 0)
{
return true;
}
else
{
return false;
}
}
// Obten el nombre de un mando de juego
std::string Input::getControllerName(int index)
{
if (mNumGamepads > 0)
return mControllerNames[index];
if (numGamepads > 0)
{
return controllerNames.at(index);
}
else
{
return "";
}
}
// Obten el numero de mandos conectados
int Input::getNumControllers()
{
return mNumGamepads;
return numGamepads;
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include <string>
#include <vector>
@@ -40,20 +41,19 @@ private:
Uint8 scancode; // Scancode asociado
bool active; // Indica si está activo
};
keyBindings_t mKeyBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos
struct GameControllerBindings_t
{
SDL_GameControllerButton button; // GameControllerButton asociado
bool active; // Indica si está activo
};
GameControllerBindings_t mGameControllerBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos
//SDL_GameController *mGameController; // Manejador para el mando
std::vector<SDL_GameController*> mConnectedControllers;
std::vector<std::string> mControllerNames;
int mNumGamepads;
std::string mDBpath; // Ruta al archivo gamecontrollerdb.txt
std::vector<keyBindings_t> keyBindings; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<GameControllerBindings_t> gameControllerBindings; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<SDL_GameController *> connectedControllers; // Vector con todos los mandos conectados
std::vector<std::string> controllerNames; // Vector con los nombres de los mandos
int numGamepads; // Numero de mandos conectados
std::string dbPath; // Ruta al archivo gamecontrollerdb.txt
// Comprueba si hay un mando conectado
bool discoverGameController();
@@ -72,7 +72,7 @@ public:
void bindGameControllerButton(Uint8 input, SDL_GameControllerButton button);
// Comprueba si un input esta activo
bool checkInput(Uint8 input, bool repeat, int device=INPUT_USE_ANY, int index=0);
bool checkInput(Uint8 input, bool repeat, int device = INPUT_USE_ANY, int index = 0);
// Comprueba si hay algun mando conectado
bool gameControllerFound();

View File

@@ -1,43 +1,42 @@
#include "instructions.h"
#ifdef __MIPSEL__
#include <sys/stat.h>
#include <dirent.h>
#endif
const Uint8 SELF = 0;
// Constructor
Instructions::Instructions(SDL_Renderer *renderer, std::string *fileList, Lang *lang)
Instructions::Instructions(SDL_Renderer *renderer, Screen *screen, Asset *mAsset, Lang *lang)
{
// Copia los punteros
mRenderer = renderer;
mFileList = fileList;
mScreen = screen;
this->mAsset = mAsset;
mLang = lang;
// Reserva memoria para los punteros
mEventHandler = new SDL_Event();
mItemTexture = new LTexture();
mTextTexture = new LTexture();
mSprite = new Sprite();
mText = new Text(mFileList[48], mTextTexture, mRenderer);
mItemTexture = new LTexture(mRenderer,mAsset->get("items.png"));
mSprite = new Sprite(0, 0, GAME_WIDTH, GAME_HEIGHT, mItemTexture, mRenderer);
mText = new Text(mAsset->get("smb2.png"), mAsset->get("smb2.txt"), mRenderer);
// Crea un backbuffer para el renderizador
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT);
if (mBackbuffer == NULL)
mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAME_WIDTH, GAME_HEIGHT);
if (mBackbuffer == nullptr)
{
printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError());
}
}
// Destructor
Instructions::~Instructions()
{
mRenderer = nullptr;
mScreen = nullptr;
mAsset = nullptr;
mLang = nullptr;
mItemTexture->unload();
delete mItemTexture;
mItemTexture = nullptr;
mTextTexture->unload();
delete mTextTexture;
mTextTexture = nullptr;
delete mSprite;
mSprite = nullptr;
@@ -51,26 +50,11 @@ Instructions::~Instructions()
mBackbuffer = nullptr;
}
// Carga los recursos necesarios para la sección 'Instructions'
bool Instructions::loadMedia()
{
bool success = true;
success &= loadTextureFromFile(mItemTexture, mFileList[34], mRenderer);
success &= loadTextureFromFile(mTextTexture, mFileList[30], mRenderer);
return success;
}
// Inicializa las variables necesarias para la sección 'Instructions'
void Instructions::init()
{
// Carga los recursos
loadMedia();
// Inicializa variables
mSection.name = SELF;
mSprite->init(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, mItemTexture, mRenderer);
mTicks = 0;
mTicksSpeed = 15;
mManualQuit = false;
@@ -138,7 +122,7 @@ void Instructions::run(Uint8 mode)
}
// Pinta en pantalla
SDL_Rect window = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
SDL_Rect window = {0, 0, GAME_WIDTH, GAME_HEIGHT};
SDL_Rect srcRect = {0, 0, 16, 16};
const color_t orangeColor = {0xFF, 0x7A, 0x00};
@@ -169,38 +153,38 @@ void Instructions::run(Uint8 mode)
mText->writeShadowed(84, 156, mLang->getText(21), shdwTxtColor);
if ((mode == INSTRUCTIONS_MODE_MANUAL) && (mCounter % 50 > 14))
mText->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, SCREEN_HEIGHT - 12, mLang->getText(22), 1, orangeColor, 1, shdwTxtColor);
mText->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, GAME_HEIGHT - 12, mLang->getText(22), 1, orangeColor, 1, shdwTxtColor);
// Disquito
mSprite->init(destRect1, mItemTexture, mRenderer);
mSprite->setPos(destRect1);
srcRect.x = 0;
srcRect.y = 16 * (((mCounter + 12) / 36) % 2);
mSprite->setSpriteClip(srcRect);
mSprite->render();
// Gavineixon
mSprite->init(destRect2, mItemTexture, mRenderer);
mSprite->setPos(destRect2);
srcRect.x += srcRect.w;
srcRect.y = 16 * (((mCounter + 9) / 36) % 2);
mSprite->setSpriteClip(srcRect);
mSprite->render();
// Pacmar
mSprite->init(destRect3, mItemTexture, mRenderer);
mSprite->setPos(destRect3);
srcRect.x += srcRect.w;
srcRect.y = 16 * (((mCounter + 6) / 36) % 2);
mSprite->setSpriteClip(srcRect);
mSprite->render();
// Time Stopper
mSprite->init(destRect4, mItemTexture, mRenderer);
mSprite->setPos(destRect4);
srcRect.x += srcRect.w;
srcRect.y = 16 * (((mCounter + 3) / 36) % 2);
mSprite->setSpriteClip(srcRect);
mSprite->render();
// Coffee
mSprite->init(destRect5, mItemTexture, mRenderer);
mSprite->setPos(destRect5);
srcRect.x += (srcRect.w * 2); // Se salta el icono del TNT
srcRect.y = 16 * (((mCounter + 0) / 36) % 2);
mSprite->setSpriteClip(srcRect);
@@ -209,20 +193,22 @@ void Instructions::run(Uint8 mode)
// Cambia el destino de renderizado
SDL_SetRenderTarget(mRenderer, nullptr);
// Limpia el renderizador
SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255);
SDL_RenderClear(mRenderer);
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
mScreen->clean(bgColor);
// Establece la ventana del backbuffer
if (mode == INSTRUCTIONS_MODE_AUTO)
window.y = std::max(8, SCREEN_HEIGHT - mCounter + 100);
window.y = std::max(8, GAME_HEIGHT - mCounter + 100);
else
window.y = 0;
// Copia el backbuffer al renderizador
SDL_RenderCopy(mRenderer, mBackbuffer, NULL, &window);
SDL_RenderCopy(mRenderer, mBackbuffer, nullptr, &window);
// Dibuja el renderizador en pantalla
SDL_RenderPresent(mRenderer);
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
}
}

View File

@@ -1,37 +1,43 @@
#pragma once
#include "ifdefs.h"
#include "utils.h"
#include "const.h"
#include <SDL2/SDL.h>
#include "asset.h"
#include "const.h"
#include "jail_audio.h"
#include "screen.h"
#include "sprite.h"
#include "text.h"
#include "jail_audio.h"
#include "utils.h"
#ifndef INSTRUCTIONS_H
#define INSTRUCTIONS_H
// Instructions
// Contadores
#define INSTRUCTIONS_COUNTER 600
// Modo para las instrucciones
#define INSTRUCTIONS_MODE_MANUAL 0
#define INSTRUCTIONS_MODE_AUTO 1
// Clase Instructions
class Instructions
{
private:
LTexture *mItemTexture; // Textura con los graficos
LTexture *mTextTexture; // Textura con los graficos
SDL_Event *mEventHandler; // Manejador de eventos
SDL_Renderer *mRenderer; // El renderizador de la ventana
Screen *mScreen; // Objeto encargado de dibujar en pantalla
LTexture *mItemTexture; // Textura con los graficos
SDL_Event *mEventHandler; // Manejador de eventos
SDL_Texture *mBackbuffer; // Textura para usar como backbuffer
Sprite *mSprite; // Sprite con la textura de las instrucciones
std::string *mFileList; // Lista de ficheros
Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
Text *mText; // Objeto para escribir texto
Uint16 mCounter; // Contador
section_t mSection; // Estado del bucle principal para saber si continua o se sale
Uint32 mTicks; // Contador de ticks para ajustar la velocidad del programa
Uint8 mTicksSpeed; // Velocidad a la que se repiten los bucles del programa
Uint32 mTicksSpeed; // Velocidad a la que se repiten los bucles del programa
bool mManualQuit; // Indica si se quiere salir del modo manual
// Carga los recursos
bool loadMedia();
// Actualiza las variables
void update();
@@ -43,7 +49,7 @@ private:
public:
// Constructor
Instructions(SDL_Renderer *renderer, std::string *fileList, Lang *lang);
Instructions(SDL_Renderer *renderer, Screen *screen, Asset *mAsset, Lang *lang);
// Destructor
~Instructions();

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