Compare commits

...

74 Commits
v0.1 ... v0.6

Author SHA1 Message Date
62183d745a Corregido el texto de la marquesina 2022-09-03 18:28:26 +02:00
57c51676a4 Terminada la marquesina del titulo 2022-09-03 18:16:22 +02:00
1571b73c84 Añadida musica al titulo 2022-09-03 17:25:47 +02:00
3c26c98dd5 Trabajando en el titulo 2022-09-03 15:08:57 +02:00
643129b850 Actualizado Makefile 2022-09-03 14:36:53 +02:00
13fa289b42 Trabajando en el titulo 2022-09-03 14:33:16 +02:00
fce356e306 Empezando a trabajar en el titulo 2022-09-03 14:22:05 +02:00
d881220c7e Terminado (mas o menos) lo que quería hacer con el logo 2022-09-03 11:24:51 +02:00
9a9751bfdd Trabajando en el logo. Version con vector de completados 2022-09-03 10:17:02 +02:00
603aa4d653 Merge branch 'master' of https://gitea.sustancia.synology.me/JailDesigner/jaildoctors_dilemma 2022-09-03 07:40:26 +02:00
04d39c579a Empezando a trabajar en el logo 2022-09-03 07:40:11 +02:00
3e79bcb62d Pequeñas optimizaciones 2022-09-02 14:00:08 +02:00
a620d512c2 Añadida habitación sigmasua 2022-09-01 22:53:06 +02:00
3e94633f56 Quitados tres warnings 2022-09-01 21:22:13 +02:00
877b1e56e4 Modificado el todo.txt 2022-09-01 20:35:33 +02:00
31dea2aeea Añadido el procedimiento reLoadTexture a todos los objetos que lo necesitaban 2022-09-01 20:25:25 +02:00
4e219c47f6 Modificadas las llamadas para crear texturas 2022-09-01 19:49:03 +02:00
8f2e04b120 Modificada la clase LTexture 2022-09-01 19:30:56 +02:00
114da1e381 Renombradas variables en la clase text 2022-09-01 19:00:13 +02:00
203391da2d Eliminado el procedimiento loadTextureFromFile() de utils.h 2022-09-01 18:59:18 +02:00
4433cc6943 Invertido el separador del reloj 2022-09-01 13:14:15 +02:00
6a84d114e8 Implementado el temporizador del marcador 2022-09-01 12:50:17 +02:00
62e9a2ad2a Trabajando en el marcador 2022-08-31 22:40:22 +02:00
0087815ced Añadido el sonido de coger objetos 2022-08-31 20:59:52 +02:00
c18a13ec83 Añadida música 2022-08-31 19:51:00 +02:00
f1047a8b07 Trabajando en el marcador 2022-08-31 18:10:34 +02:00
c57fbf7bc3 Trabajando en el marcador 2022-08-31 13:56:17 +02:00
fff400be8f Probando stage changes 2022-08-30 22:53:16 +02:00
7b492b6942 Cambiado a todo.txt 2022-08-30 22:33:15 +02:00
1458658f4d Arreglado el nuevo bug que animaba a los enemigos dos veces 2022-08-30 21:57:01 +02:00
93febf3127 Los items ya brillan a distinto ritmo 2022-08-30 21:44:07 +02:00
38c41193ec Mejorada la información de debug 2022-08-30 20:35:53 +02:00
8616c3e165 Actualizada la clase screen con nuevos procedimientos 2022-08-30 17:31:33 +02:00
cbdc7d9fc3 Clase screen actualizada a la última versión 2022-08-30 16:45:26 +02:00
c5728d0849 Retocando las constantes 2022-08-30 14:01:44 +02:00
add7e5201a Sustituyendo todos los defines de const.h 2022-08-29 21:07:52 +02:00
0d27774c74 Eliminado el fichero const.h 2022-08-29 20:57:28 +02:00
75317a8b46 Modificada la fecha de inicio de programación en el codigo fuente 2022-08-29 20:16:21 +02:00
a1dad5d841 Actualizado jail_adudio y Menu 2022-08-29 20:11:46 +02:00
2af7b66a99 Borrado el fichero ifdefs.h 2022-08-29 20:06:50 +02:00
05311f7a00 Actualizada la clase asset 2022-08-29 20:04:53 +02:00
9c2140b274 Actualizadas las clases sprite, movingsprite y animatedsprite 2022-08-29 20:02:46 +02:00
47c57a9f44 Borradas clases que no se utilizaban 2022-08-29 18:29:39 +02:00
9a20d5fc1b Renombrado de variables 2022-08-29 18:16:14 +02:00
822386c269 Actualizada la clase Text 2022-08-29 17:47:06 +02:00
21c844a925 modificado director.h. El método init se ha hecho privado 2022-08-08 19:59:25 +02:00
04068466b1 modificados los archivos de tiled 2022-08-07 15:49:52 +02:00
446f130f3e cambios en los ficheros de las habitaciones 2022-08-07 15:42:03 +02:00
c0b24b9cc7 renombrats alguns fitxers de recursos 2022-08-07 15:18:32 +02:00
01d96ec1ce Arreglado un fallo en el salto al cambiar de pantalla hacia arriba 2022-07-14 19:17:31 +02:00
446dc9941f Añadidos nuevos tamaños para los enemigos 2022-07-14 18:09:06 +02:00
d95645e930 Creados tiles que matan 2022-07-14 16:37:58 +02:00
8f3fc5b52a Ya lleva la cuenta de los objetos recogidos 2022-07-14 11:03:35 +02:00
e752e90630 Añadida la clase item_tracker 2022-07-14 10:36:24 +02:00
6152dc4255 Ya se pueden pillar los items. Falta llevar el control de los iterms conseguidos 2022-07-12 19:33:09 +02:00
f8db0e3a90 Clase item creada. Ya dibuja items en pantalla 2022-07-12 18:39:00 +02:00
ae841a45ee Retocadas las clases Sprite e hijas 2022-07-12 17:32:12 +02:00
834d3a09a4 Rehaciendo las clases Sprite y sus hijas 2022-07-12 14:47:25 +02:00
6d7f8035bb Creación de nuevos tiles 2022-07-11 19:29:29 +02:00
8101c33526 Muerte y reaparición del jugador 2022-07-11 18:08:48 +02:00
4f6a99f670 Creadas las colisiones con los enemigos 2022-07-11 14:18:30 +02:00
4d41ef53f1 Ya realiza bien las colisiones con todos los tiles 2022-07-11 12:31:04 +02:00
38f95d9724 El salto ya hace el arco y luego cae 2022-07-11 10:52:20 +02:00
783689c368 Modificado el metodo de carga de habitaciones 2022-07-11 09:37:58 +02:00
6059a3b894 Arco de salto mejorado 2022-07-10 21:36:48 +02:00
8d49c78519 Ya funcionan los tiles atravesables 2022-07-10 21:10:45 +02:00
bade27edc4 Calibrando el salto. Aun no está perfeccionado del todo 2022-07-10 19:05:30 +02:00
64ebf24408 Ya no cambia de borde el jugador si tampoco puede cambiar de habitación 2022-07-10 18:51:59 +02:00
f931890e95 Ya realiza bien las colisiones en el salto 2022-07-10 18:49:26 +02:00
216fc1e19c Depurando los saltos con colisiones 2022-07-07 20:07:29 +02:00
9ecab3ea59 Trabajando en las colisiones con el mapeado 2022-07-07 17:44:22 +02:00
90bbe77f39 Colision con el suelo terminada 2022-07-06 21:04:45 +02:00
edba97cfc7 Preparandose para añadir gravedad y colisiones y pasarle el mapa al jugador 2022-07-06 09:10:11 +02:00
4243f89dc0 El jugador ya cambia de pantalla 2022-07-05 20:44:35 +02:00
94 changed files with 4289 additions and 3595 deletions

View File

@@ -1,5 +1,8 @@
executable = jaildoctors_dilemma
windows:
mkdir bin
g++ -std=c++11 -Wall -O2 -lSDL2 -lmingw32 -lSDL2main -mwindows source/*.cpp -o bin/$(executable).exe
macos:
mkdir -p bin
g++ -std=c++11 -Wall -O2 source/*.cpp -o bin/$(executable)_macos -lSDL2

View File

@@ -1,10 +0,0 @@
tileset=enemy01.png
x=8
y=8
vx=0.1
vy=0
x1=8
x2=200
y1=8
y2=8
color=red

View File

@@ -1,37 +1,101 @@
id=1
name=Test Room
bg_color=black
tileset=room1.png
room_up=0
room_down=0
room_left=0
room_right=02.room
tilemap=41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,41,41,41,41,41,41,41,41,41,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,41,41,41,41,41,0,0,0,0,0,0,0,0,0,81,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,41,41,41,41,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,0,0,0,0,0,41,41,0,0,0,0,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,0,0,0,0,0,41,0,0,0,0,0,0,0,0,0,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41
name=void main
bgColor=black
tileset=standard.png
roomUp=0
roomDown=0
roomLeft=0
roomRight=02.room
[tilemap]
01.tmx
[/tilemap]
[enemy]
tileset=enemy01.png
x=8
tileset=paco.png
animation=paco.ani
width=16
height=16
x=1
y=0
vx=0
vy=0.3
x1=8
x2=8
x1=1
y1=0
y2=48
x2=1
y2=6
color=red
[enemy-end]
[/enemy]
[enemy]
tileset=enemy01.png
x=40
y=72
vx=0.3
tileset=paco.png
animation=paco.ani
width=16
height=16
x=5
y=9
vx=0.6
vy=0
x1=40
x2=184
y1=72
y2=72
x1=5
y1=9
x2=22
y2=9
color=yellow
[enemy-end]
[/enemy]
item=1,10,10
[item]
tileset=items.png
tile=0
x=1
y=7
counter=6
[/item]
[item]
tileset=items.png
tile=0
x=17
y=8
counter=7
[/item]
[item]
tileset=items.png
tile=0
x=12
y=12
counter=1
[/item]
[item]
tileset=items.png
tile=0
x=13
y=12
counter=2
[/item]
[item]
tileset=items.png
tile=0
x=14
y=12
counter=3
[/item]
[item]
tileset=items.png
tile=0
x=15
y=12
counter=4
[/item]
[item]
tileset=items.png
tile=0
x=16
y=12
counter=5
[/item]

24
data/room/01.tmx Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv">
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,0,0,21,21,21,21,21,21,21,21,21,21,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,21,21,21,0,0,0,0,0,0,0,0,0,0,0,211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,21,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,21,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,21,21,21,0,0,0,0,0,21,21,21,21,21,
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,211,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,0,0,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21
</data>
</layer>
</map>

View File

@@ -1,12 +1,34 @@
id=2
name=Test Room 2
bg_color=black
tileset=room1.png
room_up=0
room_down=0
room_left=01.room
room_right=0
tilemap=43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,43,43,43,43,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43,0,0,0,0,0,0,0,83,83,83,83,83,83,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,83,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63
enemy=1,0,0,0,1
enemy=2,10,0,0,1
item=1,10,10
name=case switch
bgColor=black
tileset=standard.png
roomUp=0
roomDown=04.room
roomLeft=01.room
roomRight=03.room
[tilemap]
02.tmx
[/tilemap]
[enemy]
tileset=paco.png
animation=paco.ani
width=16
height=16
x=14
y=0
vx=0
vy=1
x1=14
y1=0
x2=14
y2=12
color=purple
[/enemy]
[item]
tileset=items.png
tile=1
x=19
y=6
[/item]

24
data/room/02.tmx Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv">
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,
0,0,0,0,0,0,0,0,0,0,0,203,203,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,0,0,0,0,0,0,0,0,0,23,
23,23,23,23,23,23,0,0,0,203,0,0,0,0,0,0,0,0,0,23,0,0,0,0,203,203,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,203,0,0,0,0,0,0,0,0,0,23,0,0,0,0,203,203,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,203,203,23,
0,0,0,0,0,0,0,203,203,203,203,203,203,0,0,0,0,0,0,23,0,0,0,0,203,203,0,0,0,0,0,23,
0,0,0,0,0,203,0,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,23,
43,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,83,83,83,83,83,83,83,83,83,83,83,83,
43,43,43,43,43,43,43,43,43,43,43,43,43,43,223,0,0,223,43,43,43,43,43,43,43,43,43,43,43,43,43,43
</data>
</layer>
</map>

66
data/room/03.room Normal file
View File

@@ -0,0 +1,66 @@
name=the edge
bgColor=light_black
tileset=standard.png
roomUp=0
roomDown=05.room
roomLeft=02.room
roomRight=0
[tilemap]
03.tmx
[/tilemap]
[enemy]
tileset=chip.png
animation=chip.ani
width=8
height=16
x=4
y=5
vx=0
vy=1
x1=4
y1=2
x2=4
y2=13
color=green
[/enemy]
[enemy]
tileset=chip.png
animation=chip.ani
width=8
height=16
x=10
y=4
vx=0
vy=1
x1=10
y1=2
x2=10
y2=13
color=light_blue
[/enemy]
[enemy]
tileset=chip.png
animation=chip.ani
width=8
height=16
x=16
y=3
vx=0
vy=1
x1=16
y1=2
x2=16
y2=13
color=purple
[/enemy]
[item]
tileset=items.png
tile=5
x=12
y=2
[/item]

24
data/room/03.tmx Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv">
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,271,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,0,232,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,232,0,0,0,0,0,0,0,0,0,
26,26,26,0,0,0,26,26,26,0,0,0,26,26,26,0,0,0,26,26,26,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
</map>

81
data/room/04.room Normal file
View File

@@ -0,0 +1,81 @@
name=The Fridge
bgColor=blue
tileset=standard.png
roomUp=02.room
roomDown=0
roomLeft=0
roomRight=05.room
[tilemap]
04.tmx
[/tilemap]
[enemy]
tileset=chip.png
animation=chip.ani
width=8
height=16
x=1
y=3
vx=1
vy=0
x1=1
y1=3
x2=14
y2=3
color=purple
[/enemy]
[enemy]
tileset=chip.png
animation=chip.ani
width=8
height=16
x=30
y=7
vx=-0.8
vy=0
x1=10
y1=7
x2=30
y2=7
color=light_white
[/enemy]
[enemy]
tileset=wave.png
animation=wave.ani
width=8
height=8
x=15
y=12
vx=0.5
vy=0
x1=15
y1=12
x2=30
y2=12
color=light_purple
[/enemy]
[item]
tileset=items.png
tile=6
x=2
y=2
[/item]
[item]
tileset=items.png
tile=6
x=29
y=5
[/item]
[item]
tileset=items.png
tile=6
x=21
y=12
[/item]

24
data/room/04.tmx Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv">
25,249,249,249,249,249,249,249,249,249,249,249,249,249,0,0,0,0,249,249,249,249,249,249,249,249,249,249,249,249,249,25,
25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,
25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,
25,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,
25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,
25,25,25,25,0,25,25,25,25,25,0,25,25,25,25,0,0,230,0,0,0,0,0,0,0,0,0,0,0,0,0,25,
25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,270,270,270,270,270,270,270,0,0,270,0,25,
25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,290,0,0,0,0,0,0,0,25,
25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,290,0,0,0,0,0,0,0,25,
25,0,0,0,0,0,0,0,0,0,0,25,25,25,25,0,0,25,25,25,25,25,25,25,0,0,0,0,0,0,0,25,
25,0,0,0,0,229,229,229,229,229,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,
25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,
25,249,249,249,249,249,249,249,249,249,249,249,249,249,249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,
22,0,0,0,0,0,289,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
22,0,0,0,0,0,289,0,0,0,0,0,0,0,0,0,0,0,381,0,0,0,0,0,0,381,0,0,0,0,0,0,
25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25
</data>
</layer>
</map>

107
data/room/05.room Normal file
View File

@@ -0,0 +1,107 @@
name=sigmasua
bgColor=black
tileset=standard.png
roomUp=03.room
roomDown=0
roomLeft=04.room
roomRight=0
[tilemap]
05.tmx
[/tilemap]
[enemy]
tileset=sigmasua.png
animation=sigmasua.ani
width=16
height=16
x=15
y=7
vx=0.8
vy=0
x1=9
y1=7
x2=25
y2=7
color=red
[/enemy]
[enemy]
tileset=sigmasua.png
animation=sigmasua.ani
width=16
height=16
x=3
y=8
vx=0
vy=0.4
x1=3
y1=5
x2=3
y2=12
color=red
[/enemy]
[enemy]
tileset=sigmasua.png
animation=sigmasua.ani
width=16
height=16
x=10
y=10
vx=0
vy=0.3
x1=10
y1=10
x2=10
y2=13
color=light_red
[/enemy]
[enemy]
tileset=sigmasua.png
animation=sigmasua.ani
width=16
height=16
x=23
y=13
vx=0
vy=-0.3
x1=23
y1=10
x2=23
y2=13
color=light_red
[/enemy]
[item]
tileset=items.png
tile=9
counter=1
x=21
y=3
[/item]
[item]
tileset=items.png
tile=9
counter=2
x=1
y=8
[/item]
[item]
tileset=items.png
tile=9
counter=3
x=26
y=14
[/item]
[item]
tileset=items.png
tile=9
counter=4
x=18
y=5
[/item]

24
data/room/05.tmx Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.1" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv">
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,68,0,0,68,0,0,0,0,0,0,0,
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62,222,0,0,0,0,0,222,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,222,0,0,0,
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,0,0,
62,0,0,0,0,0,0,222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,222,0,0,0,
62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,0,0,
0,0,0,0,0,0,0,222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,222,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,0,0,
68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68
</data>
</layer>
</map>

10
media/enemies/chip.ani Normal file
View File

@@ -0,0 +1,10 @@
frames_per_row=4
frame_width=8
frame_height=16
[animation]
name=default
speed=8
loop=0
frames=0,1,2,3
[/animation]

BIN
media/enemies/chip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

10
media/enemies/paco.ani Normal file
View File

@@ -0,0 +1,10 @@
frames_per_row=4
frame_width=16
frame_height=16
[animation]
name=default
speed=8
loop=0
frames=0,1,2,3
[/animation]

View File

Before

Width:  |  Height:  |  Size: 239 B

After

Width:  |  Height:  |  Size: 239 B

View File

@@ -0,0 +1,10 @@
frames_per_row=4
frame_width=16
frame_height=16
[animation]
name=default
speed=8
loop=0
frames=0,1,2,3
[/animation]

BIN
media/enemies/sigmasua.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

10
media/enemies/wave.ani Normal file
View File

@@ -0,0 +1,10 @@
frames_per_row=4
frame_width=8
frame_height=8
[animation]
name=default
speed=8
loop=0
frames=0,1,2,3
[/animation]

BIN
media/enemies/wave.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

BIN
media/font/debug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

View File

@@ -1,194 +1,194 @@
# box width
8
# box height
8
# 32 espacio ( )
2
# 33 !
2
# 34 "
5
# box height
5
# 32 espacio ( )
3
# 33 !
1
# 34 "
3
# 35 #
6
3
# 36 $
6
3
# 37 %
6
3
# 38 &
6
3
# 39 '
2
1
# 40 (
3
2
# 41 )
3
2
# 42 *
4
3
# 43 +
3
# 44 ,
2
1
# 45 -
3
# 46 .
2
1
# 47 /
4
3
# 48 0
6
3
# 49 1
6
3
# 50 2
6
3
# 51 3
6
3
# 52 4
6
3
# 53 5
6
3
# 54 6
6
3
# 55 7
6
3
# 56 8
6
3
# 57 9
6
3
# 58 :
2
1
# 59 ;
2
1
# 60 <
4
3
# 61 =
3
# 62 >
4
3
# 63 ?
6
3
# 64 @
8
3
# 65 A
6
3
# 66 B
6
3
# 67 C
6
3
# 68 D
6
3
# 69 E
6
3
# 70 F
6
3
# 71 G
6
3
# 72 H
6
3
# 73 I
6
3
# 74 J
6
3
# 75 K
6
3
# 76 L
6
3
# 77 M
6
3
# 78 N
6
3
# 79 O
6
3
# 80 P
6
3
# 81 Q
6
3
# 82 R
6
3
# 83 S
6
3
# 84 T
6
3
# 85 U
6
3
# 86 V
5
3
# 87 W
6
3
# 88 X
6
3
# 89 Y
6
3
# 90 Z
6
3
# 91 [
3
2
# 92 \
5
# 93 ]
3
# 93 ]
2
# 94 ^
4
3
# 95 _
6
3
# 96 `
2
# 97 a
5
3
# 98 b
5
3
# 99 c
5
3
# 100 d
5
3
# 101 e
5
3
# 102 f
5
3
# 103 g
5
3
# 104 h
5
3
# 105 i
4
3
# 106 j
5
3
# 107 k
5
3
# 108 l
5
3
# 109 m
6
3
# 110 n
5
3
# 111 o
5
3
# 112 p
5
3
# 113 q
5
3
# 114 r
5
3
# 115 s
5
3
# 116 t
4
3
# 117 u
5
3
# 118 v
5
3
# 119 w
6
3
# 120 x
4
3
# 121 y
4
3
# 122 z
5
3
# 123 {
3
# 124 |
2
3
# 125 }
3
# 126 ~
3
5

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,194 +0,0 @@
# box width
10
# box height
10
# 32 espacio ( )
5
# 33 !
4
# 34 "
5
# 35 #
7
# 36 $
7
# 37 %
8
# 38 &
8
# 39 '
3
# 40 (
5
# 41 )
5
# 42 *
7
# 43 +
7
# 44 ,
4
# 45 -
6
# 46 .
4
# 47 /
5
# 48 0
7
# 49 1
5
# 50 2
7
# 51 3
7
# 52 4
7
# 53 5
7
# 54 6
7
# 55 7
7
# 56 8
7
# 57 9
7
# 58 :
4
# 59 ;
4
# 60 <
6
# 61 =
6
# 62 >
6
# 63 ?
7
# 64 @
8
# 65 A
7
# 66 B
7
# 67 C
7
# 68 D
7
# 69 E
7
# 70 F
7
# 71 G
7
# 72 H
7
# 73 I
4
# 74 J
6
# 75 K
8
# 76 L
6
# 77 M
9
# 78 N
8
# 79 O
8
# 80 P
7
# 81 Q
8
# 82 R
7
# 83 S
6
# 84 T
8
# 85 U
7
# 86 V
8
# 87 W
9
# 88 X
8
# 89 Y
8
# 90 Z
7
# 91 [
4
# 92 \
5
# 93 ]
4
# 94 ^
5
# 95 _
8
# 96 `
4
# 97 a
7
# 98 b
7
# 99 c
6
# 100 d
7
# 101 e
7
# 102 f
5
# 103 g
7
# 104 h
7
# 105 i
4
# 106 j
5
# 107 k
7
# 108 l
4
# 109 m
10
# 110 n
7
# 111 o
7
# 112 p
7
# 113 q
7
# 114 r
6
# 115 s
6
# 116 t
5
# 117 u
7
# 118 v
7
# 119 w
9
# 120 x
7
# 121 y
7
# 122 z
7
# 123 { -> ñ
7
# 124 | -> ç
7
# 125 }
0
# 126 ~
0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,194 +0,0 @@
# box width
10
# box height
10
# 32 espacio ( )
5
# 33 !
4
# 34 "
5
# 35 #
7
# 36 $
7
# 37 %
8
# 38 &
8
# 39 '
3
# 40 (
5
# 41 )
5
# 42 *
7
# 43 +
7
# 44 ,
4
# 45 -
6
# 46 .
4
# 47 /
5
# 48 0
7
# 49 1
5
# 50 2
7
# 51 3
7
# 52 4
7
# 53 5
7
# 54 6
7
# 55 7
7
# 56 8
7
# 57 9
7
# 58 :
4
# 59 ;
4
# 60 <
6
# 61 =
6
# 62 >
6
# 63 ?
7
# 64 @
8
# 65 A
7
# 66 B
7
# 67 C
7
# 68 D
7
# 69 E
7
# 70 F
7
# 71 G
7
# 72 H
7
# 73 I
4
# 74 J
6
# 75 K
8
# 76 L
6
# 77 M
9
# 78 N
8
# 79 O
8
# 80 P
7
# 81 Q
8
# 82 R
7
# 83 S
6
# 84 T
8
# 85 U
7
# 86 V
8
# 87 W
9
# 88 X
8
# 89 Y
8
# 90 Z
7
# 91 [
4
# 92 \
5
# 93 ]
4
# 94 ^
5
# 95 _
8
# 96 `
4
# 97 a
7
# 98 b
7
# 99 c
6
# 100 d
7
# 101 e
7
# 102 f
5
# 103 g
7
# 104 h
7
# 105 i
4
# 106 j
5
# 107 k
7
# 108 l
4
# 109 m
10
# 110 n
7
# 111 o
7
# 112 p
7
# 113 q
7
# 114 r
6
# 115 s
6
# 116 t
5
# 117 u
7
# 118 v
7
# 119 w
9
# 120 x
7
# 121 y
7
# 122 z
7
# 123 { -> ñ
7
# 124 | -> ç
7
# 125 }
0
# 126 ~
0

BIN
media/items/items.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

View File

@@ -1,158 +0,0 @@
## 0 - MENU DEL TITULO
JUGAR
## 1 - MENU DEL TITULO
OPCIONS
## 2 - MENU DEL TITULO
INSTRUCCIONS
## 3 - MENU DEL TITULO
EIXIR
## 4 - MENU DE OPCIONES
FINESTRA
## 5 - MENU DE OPCIONES
PANTALLA COMPLETA
## 6 - MENU DE OPCIONES
PANTALLA COMPLETA FALSA
## 7 - MENU DE OPCIONES
TAMANY DE FINESTRA
## 8 - MENU DE OPCIONES
IDIOMA
## 9 - MENU DE OPCIONES
[ ACEPTAR ]
## 10 - MENU DE OPCIONES
[ CANCELAR ]
## 11 - INSTRUCCIONES
OBJECTIU
## 12 - INSTRUCCIONES
HAS D'EXPLOTAR
## 13 - INSTRUCCIONES
TANTS GLOBUS COM PUGUES
## 14 - INSTRUCCIONES
LA DIFICULTAT AUGMENTA
## 15 - INSTRUCCIONES
A MESURA QUE VAS PUNTUANT
## 16 - INSTRUCCIONES
OBJECTES
## 17 - INSTRUCCIONES
1.000 PUNTS
## 18 - INSTRUCCIONES
2.500 PUNTS
## 19 - INSTRUCCIONES
5.000 PUNTS
## 20 - INSTRUCCIONES
PARA EL TEMPS
## 21 - INSTRUCCIONES
VIDA EXTRA
## 22 - INSTRUCCIONES
PREM UNA TECLA PER A TORNAR
## 23 - TITULO
PREM QUALSEVOL TECLA
## 24 - MENU SELECCION DE IDIOMA
ESPA{OL (ESPANYOL)
## 25 - MENU SELECCION DE IDIOMA
BALOONCIA
## 26 - MENU SELECCION DE IDIOMA
ENGLISH (ANGLES)
## 27 - INTRO
Un dia qualsevol de l'any 2000
## 28 - INTRO
Tot esta tranquil a la UPV
## 29 - INTRO
Fins que un desaprensiu...
## 30 - INTRO
HEY! ME ANE A FERME UN CORTAET...
## 31 - INTRO
UAAAAAAAAAAAAA!!!
## 32 - INTRO
Espera un moment...
## 33 - INTRO
Si resulta que no tinc solt!
## 34 - INTRO
MERDA DE MAQUINA!
## 35 - INTRO
Blop... blop... blop...
## 36 - TEXTOS DEL JUEGO
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
## 43 - PANTALLA DE GAME OVER
FI DEL JOC
## 44 - PANTALLA DE GAME OVER
ELS TEUS PUNTS:
## 45 - PANTALLA DE GAME OVER
REINTENTAR?
## 46 - MENU DE PAUSA
CONTINUAR
## 47 - MENU DE PAUSA
EIXIR DEL JOC
## 48 - MENU GAME OVER
SI
## 49 - MENU GAME OVER
NO
## 50 - TEXTO DE COMPLETAR EL JUEGO
Felicitats!!
## 51 - MENU DEL TITULO
1 JUGADOR
## 52 - MENU DEL TITULO
2 JUGADORS
## 53 MARCADOR
jugador 1
## 54 MARCADOR
jugador 2
## 55 MARCADOR
mult
## 56 MARCADOR
max. puntuacio
## 57 MARCADOR
pantalla
## 58 - MENU DE OPCIONES
MODE DE VISUALITZACIO
## 59 - MENU DE OPCIONES
DIFICULTAT
## 60 - MENU DE OPCIONES
FILTRE
## 61 - MENU DE OPCIONES
SINC. VERTICAL
## 62 - MENU DE OPCIONES
CONTROLS DEL JUGADOR 1
## 63 - MENU DE OPCIONES
CONTROLS DEL JUGADOR 2
## 64 - MENU DE OPCIONES
TECLAT
## 65 - MENU DE OPCIONES
MANDO
## 66 - MENU DE OPCIONES
FACIL
## 67 - MENU DE OPCIONES
NORMAL
## 68 - MENU DE OPCIONES
DIFICIL
## 69 - MENU DE OPCIONES
TECLAT
## 70 - MENU DE OPCIONES
MANDO
## 71 - MENU DE OPCIONES
LINEAL
## 72 - MENU DE OPCIONES
NEAREST
## 73 - MENU DE OPCIONES
ACTIVADA
## 74 - MENU DE OPCIONES
DESACTIVADA
## 75 - JUEGO
Endavant!
## 76 - JUEGO
1.000.000 de punts!
## 77 - PANTALLA DE GAME OVER
PUNTS J1:
## 78 - PANTALLA DE GAME OVER
PUNTS J2:

View File

@@ -1,158 +0,0 @@
## 0 - MENU DEL TITULO
PLAY
## 1 - MENU DEL TITULO
OPTIONS
## 2 - MENU DEL TITULO
HOW TO PLAY
## 3 - MENU DEL TITULO
QUIT
## 4 - MENU DE OPCIONES
WINDOW
## 5 - MENU DE OPCIONES
FULLSCREEN
## 6 - MENU DE OPCIONES
FAKE FULLSCREEN
## 7 - MENU DE OPCIONES
WINDOW SIZE
## 8 - MENU DE OPCIONES
LANGUAGE
## 9 - MENU DE OPCIONES
[ ACCEPT ]
## 10 - MENU DE OPCIONES
[ CANCEL ]
## 11 - INSTRUCCIONES
OBJECTIVE
## 12 - INSTRUCCIONES
YOU HAVE TO POP AS MANY
## 13 - INSTRUCCIONES
BALLOONS AS YOU CAN
## 14 - INSTRUCCIONES
DIFFICULTY WILL BE INCREASED
## 15 - INSTRUCCIONES
AS YOU SCORE POINTS
## 16 - INSTRUCCIONES
ITEMS
## 17 - INSTRUCCIONES
1.000 POINTS
## 18 - INSTRUCCIONES
2.500 POINTS
## 19 - INSTRUCCIONES
5.000 POINTS
## 20 - INSTRUCCIONES
TIME STOPPER
## 21 - INSTRUCCIONES
EXTRA HIT
## 22 - INSTRUCCIONES
PRESS ANY KEY TO RETURN
## 23 - TITULO
PRESS ANY KEY
## 24 - MENU SELECCION DE IDIOMA
ESPA{OL (SPANISH)
## 25 - MENU SELECCION DE IDIOMA
BALOONCIA (VALENCIAN)
## 26 - MENU SELECCION DE IDIOMA
ENGLISH
## 27 - INTRO
Any day of the year 2000
## 28 - INTRO
Everything is quiet at the UPV
## 29 - INTRO
Until a bastard arrives...
## 30 - INTRO
YO! GONNA TAKE A CAFELITO...
## 31 - INTRO
AAAAAAAARGHHHH!!!
## 32 - INTRO
Wait a moment...
## 33 - INTRO
I don't have any loose!
## 34 - INTRO
FUCKING MACHINE!
## 35 - INTRO
Blop... blop... blop...
## 36 - TEXTOS DEL JUEGO
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
## 43 - PANTALLA DE GAME OVER
GAME OVER
## 44 - PANTALLA DE GAME OVER
YOUR SCORE:
## 45 - PANTALLA DE GAME OVER
RETRY?
## 46 - MENU DE PAUSA
CONTINUE
## 47 - MENU DE PAUSA
LEAVE GAME
## 48 - MENU GAME OVER
YES
## 49 - MENU GAME OVER
NO
## 50 - TEXTO DE COMPLETAR EL JUEGO
Congratulations!!
## 51 - MENU DEL TITULO
1 PLAYER
## 52 - MENU DEL TITULO
2 PLAYERS
## 53 - MARCADOR
player 1
## 54 - MARCADOR
player 2
## 55 - MARCADOR
mult
## 56 - MARCADOR
high score
## 57 - MARCADOR
stage
## 58 - MENU DE OPCIONES
DISPLAY MODE
## 59 - MENU DE OPCIONES
DIFFICULTY
## 60 - MENU DE OPCIONES
FILTER
## 61 - MENU DE OPCIONES
VSYNC
## 62 - MENU DE OPCIONES
PLAYER 1 CONTROLS
## 63 - MENU DE OPCIONES
PLAYER 2 CONTROLS
## 64 - MENU DE OPCIONES
KEYBOARD
## 65 - MENU DE OPCIONES
GAME CONTROLLER
## 66 - MENU DE OPCIONES
EASY
## 67 - MENU DE OPCIONES
NORMAL
## 68 - MENU DE OPCIONES
HARD
## 69 - MENU DE OPCIONES
KEYBOARD
## 70 - MENU DE OPCIONES
GAME CONTROLLER
## 71 - MENU DE OPCIONES
LINEAL
## 72 - MENU DE OPCIONES
NEAREST
## 73 - MENU DE OPCIONES
ON
## 74 - MENU DE OPCIONES
OFF
## 75 - JUEGO
Get Ready!
## 76 - JUEGO
1.000.000 points!
## 77 - PANTALLA DE GAME OVER
PLAYER1 SCORE:
## 78 - PANTALLA DE GAME OVER
PLAYER2 SCORE:

View File

@@ -1,158 +0,0 @@
## 0 - MENU DEL TITULO
JUGAR
## 1 - MENU DEL TITULO
OPCIONES
## 2 - MENU DEL TITULO
INSTRUCCIONES
## 3 - MENU DEL TITULO
SALIR
## 4 - MENU DE OPCIONES
VENTANA
## 5 - MENU DE OPCIONES
PANTALLA COMPLETA
## 6 - MENU DE OPCIONES
PANTALLA COMPLETA FALSA
## 7 - MENU DE OPCIONES
TAMA{O DE VENTANA
## 8 - MENU DE OPCIONES
IDIOMA
## 9 - MENU DE OPCIONES
[ ACEPTAR ]
## 10 - MENU DE OPCIONES
[ CANCELAR ]
## 11 - INSTRUCCIONES
OBJETIVO
## 12 - INSTRUCCIONES
TIENES QUE EXPLOTAR
## 13 - INSTRUCCIONES
TANTOS GLOBOS COMO PUEDAS
## 14 - INSTRUCCIONES
LA DIFICULTAD SE INCREMENTA
## 15 - INSTRUCCIONES
A MEDIDA QUE VAS PUNTUANDO
## 16 - INSTRUCCIONES
OBJETOS
## 17 - INSTRUCCIONES
1.000 PUNTOS
## 18 - INSTRUCCIONES
2.500 PUNTOS
## 19 - INSTRUCCIONES
5.000 PUNTOS
## 20 - INSTRUCCIONES
DETIENE EL TIEMPO
## 21 - INSTRUCCIONES
VIDA EXTRA
## 22 - INSTRUCCIONES
PULSA UNA TECLA PARA VOLVER
## 23 - TITULO
PULSA CUALQUIER TECLA
## 24 - MENU SELECCION DE IDIOMA
ESPA{OL
## 25 - MENU SELECCION DE IDIOMA
BALOONCIA (VALENCIANO)
## 26 - MENU SELECCION DE IDIOMA
ENGLISH (INGLES)
## 27 - INTRO
Un dia cualquiera del a{o 2000
## 28 - INTRO
Todo esta tranquilo en la UPV
## 29 - INTRO
Hasta que un desaprensivo...
## 30 - INTRO
HEY! VOY A SACARME UN TALLADET...
## 31 - INTRO
UAAAAAAAAAAAAA!!!
## 32 - INTRO
Espera un momento...
## 33 - INTRO
Si no llevo suelto encima!
## 34 - INTRO
MIERDA DE MAQUINA!
## 35 - INTRO
Blop... blop... blop...
## 36 - TEXTOS DEL JUEGO
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
## 43 - PANTALLA DE GAME OVER
FIN DE JUEGO
## 44 - PANTALLA DE GAME OVER
TU PUNTUACION:
## 45 - PANTALLA DE GAME OVER
REINTENTAR?
## 46 - MENU DE PAUSA
CONTINUAR
## 47 - MENU DE PAUSA
SALIR DEL JUEGO
## 48 - MENU GAME OVER
SI
## 49 - MENU GAME OVER
NO
## 50 - TEXTO DE COMPLETAR EL JUEGO
Felicidades!!
## 51 - MENU DEL TITULO
1 JUGADOR
## 52 - MENU DEL TITULO
2 JUGADORES
## 53 - MARCADOR
jugador 1
## 54 - MARCADOR
jugador 2
## 55 - MARCADOR
mult
## 56 - MARCADOR
max. puntuacion
## 57 - MARCADOR
fase
## 58 - MENU DE OPCIONES
MODO DE VISUALIZACION
## 59 - MENU DE OPCIONES
DIFICULTAD
## 60 - MENU DE OPCIONES
FILTRO
## 61 - MENU DE OPCIONES
SINC. VERTICAL
## 62 - MENU DE OPCIONES
CONTROLES DEL JUGADOR 1
## 63 - MENU DE OPCIONES
CONTROLES DEL JUGADOR 2
## 64 - MENU DE OPCIONES
TECLADO
## 65 - MENU DE OPCIONES
MANDO
## 66 - MENU DE OPCIONES
FACIL
## 67 - MENU DE OPCIONES
NORMAL
## 68 - MENU DE OPCIONES
DIFICIL
## 69 - MENU DE OPCIONES
TECLADO
## 70 - MENU DE OPCIONES
MANDO
## 71 - MENU DE OPCIONES
LINEAL
## 72 - MENU DE OPCIONES
NEAREST
## 73 - MENU DE OPCIONES
ACTIVADA
## 74 - MENU DE OPCIONES
DESACTIVADA
## 75 - JUEGO
Adelante!
## 76 - JUEGO
1.000.000 de puntos!
## 77 - PANTALLA DE GAME OVER
PUNTUACION J1:
## 78 - PANTALLA DE GAME OVER
PUNTUACION J2:

BIN
media/logo/jailgames.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

BIN
media/logo/seagull.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

BIN
media/logo/since_1998.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

BIN
media/music/game.ogg Normal file

Binary file not shown.

BIN
media/music/title.ogg Normal file

Binary file not shown.

24
media/player/player01.ani Normal file
View File

@@ -0,0 +1,24 @@
frames_per_row=4
frame_width=8
frame_height=16
[animation]
name=stand
speed=8
loop=0
frames=0
[/animation]
[animation]
name=walk
speed=8
loop=0
frames=0,1,2,3
[/animation]
[animation]
name=walk_menu
speed=0
loop=0
frames=0,1,2,3
[/animation]

BIN
media/player/player01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

BIN
media/sound/item.wav Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 B

BIN
media/tilesets/standard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -1,121 +1,278 @@
#include "const.h"
#include "animatedsprite.h"
// Constructor
AnimatedSprite::AnimatedSprite(LTexture *texture, SDL_Renderer *renderer)
AnimatedSprite::AnimatedSprite(LTexture *texture, SDL_Renderer *renderer, std::string file)
{
mRenderer = renderer;
mTexture = texture;
// Copia los punteros
setTexture(texture);
setRenderer(renderer);
// Carga las animaciones
load(file);
// Inicializa variables
currentAnimation = 0;
}
// Destructor
AnimatedSprite::~AnimatedSprite()
{
for (auto &a : animation)
{
a.frames.clear();
}
animation.clear();
}
// Iniciador
void AnimatedSprite::init()
// Obtiene el indice de la animación a partir del nombre
int AnimatedSprite::getIndex(std::string name)
{
for (int i = 0; i < 20; i++)
int index = -1;
/*for (int i = 0; i < (int)animation.size(); i++)
{
mAnimation[i].numFrames = 0;
mAnimation[i].speed = 0;
mAnimation[i].loop = true;
mAnimation[i].completed = false;
for (int j = 0; i < 20; i++)
if (animation[i].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;
index = i;
}
}*/
for (auto a : animation)
{
index++;
if (a.name == name)
{
return index;
}
}
mCurrentFrame = 0;
mAnimationCounter = 0;
printf("** Warning: could not find \"%s\" animation\n", name.c_str());
index = 0;
return -1;
}
// Calcula el frame correspondiente a la animación
void AnimatedSprite::animate(int index)
void AnimatedSprite::animate()
{
if (mEnabled)
if (!enabled || animation[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)
// Calcula el frame actual a partir del contador
animation[currentAnimation].currentFrame = animation[currentAnimation].counter / animation[currentAnimation].speed;
// Si alcanza el final de la animación, reinicia el contador de la animación
// en función de la variable loop y coloca el nuevo frame
if (animation[currentAnimation].currentFrame >= animation[currentAnimation].frames.size())
{
if (mAnimation[index].loop)
mAnimationCounter = 0;
if (animation[currentAnimation].loop == -1)
{ // Si no hay loop, deja el último frame
animation[currentAnimation].currentFrame = animation[currentAnimation].frames.size();
animation[currentAnimation].completed = true;
}
else
mCurrentFrame = mAnimation[index].numFrames;
{ // Si hay loop, vuelve al frame indicado
animation[currentAnimation].counter = 0;
animation[currentAnimation].currentFrame = animation[currentAnimation].loop;
}
}
// En caso contrario
else
{
// Escogemos el frame correspondiente de la animación
setSpriteClip(mAnimation[index].frames[mCurrentFrame]);
// Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
// Incrementamos el contador de la animacion
mAnimationCounter++;
}
// Incrementa el contador de la animacion
animation[currentAnimation].counter++;
}
}
// Establece el frame actual de la animación
void AnimatedSprite::setCurrentFrame(Uint8 num)
void AnimatedSprite::setCurrentFrame(int num)
{
mCurrentFrame = num;
animation[currentAnimation].currentFrame = num;
// Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
}
// Establece el valor del contador
void AnimatedSprite::setAnimationCounter(Uint16 num)
void AnimatedSprite::setAnimationCounter(std::string name, int num)
{
mAnimationCounter = num;
}
// 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[getIndex(name)].counter = num;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(Uint8 index, Uint8 speed)
void AnimatedSprite::setAnimationSpeed(std::string name, int speed)
{
mAnimation[index].speed = speed;
}
// Establece el numero de frames de una animación
void AnimatedSprite::setAnimationNumFrames(Uint8 index, Uint8 num)
{
mAnimation[index].numFrames = num;
animation[getIndex(name)].counter = speed;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(Uint8 index, bool loop)
void AnimatedSprite::setAnimationLoop(std::string name, int loop)
{
mAnimation[index].loop = loop;
animation[getIndex(name)].loop = loop;
}
// Establece el valor de la variable
void AnimatedSprite::setCompleted(Uint8 index, bool value)
void AnimatedSprite::setAnimationCompleted(std::string name, bool value)
{
mAnimation[index].completed = value;
animation[getIndex(name)].completed = value;
}
// Comprueba si ha terminado la animación
bool AnimatedSprite::isCompleted(Uint8 index)
bool AnimatedSprite::animationIsCompleted()
{
return mAnimation[index].completed;
return animation[currentAnimation].completed;
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(Uint8 index_animation, Uint8 index_frame)
SDL_Rect AnimatedSprite::getAnimationClip(std::string name, Uint8 index)
{
return mAnimation[index_animation].frames[index_frame];
return animation[getIndex(name)].frames[index];
}
// Carga la animación desde un fichero
bool AnimatedSprite::load(std::string filePath)
{
int frames_per_row = 0;
int frame_width = 0;
int frame_height = 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 [enemy] se realiza el proceso de carga de un enemigo
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 != 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, frame_width, frame_height};
while (getline(ss, tmp, ','))
{
int num_tile = std::stoi(tmp);
rect.x = (num_tile % frames_per_row) * frame_width;
rect.y = (num_tile / frames_per_row) * frame_height;
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 el enemigo al vector de enemigos
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 != line.npos)
{
if (line.substr(0, pos) == "frames_per_row")
{
frames_per_row = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frame_width")
{
frame_width = std::stoi(line.substr(pos + 1, line.length()));
}
else if (line.substr(0, pos) == "frame_height")
{
frame_height = std::stoi(line.substr(pos + 1, line.length()));
}
else
{
printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
}
}
}
// 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, frame_width, frame_height});
return success;
}
// Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(std::string name)
{
const int newAnimation = getIndex(name);
if (currentAnimation != newAnimation)
{
currentAnimation = newAnimation;
animation[currentAnimation].currentFrame = 0;
animation[currentAnimation].counter = 0;
animation[currentAnimation].completed = false;
}
}
// Actualiza las variables del objeto
void AnimatedSprite::update()
{
animate();
MovingSprite::update();
}

View File

@@ -1,69 +1,74 @@
#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
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(LTexture *texture, SDL_Renderer *renderer);
AnimatedSprite(LTexture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "");
// Destructor
~AnimatedSprite();
// Iniciador
void init();
// 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);
// 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);
// Establece el valor de la variable
void setCompleted(Uint8 index, bool value);
void setAnimationCompleted(std::string name, 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);
// 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");
// Actualiza las variables del objeto
void update();
};
#endif

View File

@@ -4,6 +4,7 @@
Asset::Asset(std::string path)
{
mExecutablePath = path;
longest_name = 0;
}
// Destructor
@@ -19,6 +20,9 @@ void Asset::add(std::string file, enum assetType type, bool required)
temp.type = type;
temp.required = required;
mFileList.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
@@ -37,8 +41,20 @@ bool Asset::check()
{
bool success = true;
printf("\n** Checking files.\n");
// Comprueba la lista de ficheros clasificandolos por tipo
for (int type = 0; type < maxAssetType; type++)
{
// Comprueba si hay ficheros de ese tipo
bool any = false;
for (int i = 0; i < mFileList.size(); i++)
if ((mFileList[i].required) && (mFileList[i].type == type))
any = true;
// Si hay ficheros de ese tipo, comprueba si existen
if (any)
{
printf("\n>> %s FILES\n", getTypeName(type).c_str());
@@ -46,6 +62,7 @@ bool Asset::check()
if ((mFileList[i].required) && (mFileList[i].type == type))
success &= checkFile(mFileList[i].file);
}
}
// Resultado
if (success)
@@ -59,7 +76,8 @@ bool Asset::check()
// Comprueba que existe un fichero
bool Asset::checkFile(std::string path)
{
bool success = true;
bool success = false;
std::string result = "ERROR";
// Comprueba si existe el fichero
const std::string filename = path.substr(path.find_last_of("\\/") + 1);
@@ -67,14 +85,13 @@ bool Asset::checkFile(std::string path)
if (file != NULL)
{
printf("Checking file %-20s [OK]\n", filename.c_str());
result = "OK";
success = true;
SDL_RWclose(file);
}
else
{
printf("Checking file %-20s [ERROR]\n", filename.c_str());
success = false;
}
const std::string s = "Checking file %-" + std::to_string(longest_name) + "s [" + result + "]\n";
printf(s.c_str(), filename.c_str());
return success;
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include <string>
#include <vector>
@@ -32,6 +33,8 @@ private:
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> mFileList;
std::string mExecutablePath;

View File

@@ -1,4 +1,5 @@
#pragma once
#include <SDL2/SDL.h>
#include <string>
#include "utils.h"
@@ -15,23 +16,15 @@
#define BLOCK 8
#define HALF_BLOCK 4
// Tamaño de la pantalla real
#define SCREEN_WIDTH 256
#define SCREEN_HEIGHT 192
// Tamaño de la pantalla virtual
#define GAMECANVAS_WIDTH 256
#define GAMECANVAS_HEIGHT 192
// Tamaño de la pantalla que se muestra
const int VIEW_WIDTH = SCREEN_WIDTH * 3;
const int VIEW_HEIGHT = SCREEN_HEIGHT * 3;
// Zona de juego
const int PLAY_AREA_TOP = (0 * BLOCK);
const int PLAY_AREA_BOTTOM = GAMECANVAS_HEIGHT - (4 * BLOCK);
const int PLAY_AREA_BOTTOM = (16 * BLOCK);
const int PLAY_AREA_LEFT = (0 * BLOCK);
const int PLAY_AREA_RIGHT = GAMECANVAS_WIDTH - (0 * BLOCK);
const int PLAY_AREA_RIGHT = (32 * 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);
@@ -41,6 +34,11 @@ const int PLAY_AREA_CENTER_Y = PLAY_AREA_TOP + (PLAY_AREA_HEIGHT / 2);
const int PLAY_AREA_FIRST_QUARTER_Y = PLAY_AREA_HEIGHT / 4;
const int PLAY_AREA_THIRD_QUARTER_Y = (PLAY_AREA_HEIGHT / 4) * 3;
#define BORDER_TOP 0
#define BORDER_RIGHT 1
#define BORDER_BOTTOM 2
#define BORDER_LEFT 3
// Anclajes de pantalla
const int GAMECANVAS_CENTER_X = GAMECANVAS_WIDTH / 2;
const int GAMECANVAS_FIRST_QUARTER_X = GAMECANVAS_WIDTH / 4;
@@ -56,37 +54,8 @@ const int GAMECANVAS_THIRD_QUARTER_Y = (GAMECANVAS_HEIGHT / 4) * 3;
#define SECTION_PROG_GAME 3
#define SECTION_PROG_QUIT 4
// Subsecciones
#define SECTION_GAME_PLAY 0
#define SECTION_GAME_PAUSE 1
#define SECTION_GAME_GAMEOVER 2
#define SECTION_TITLE_1 3
#define SECTION_TITLE_2 4
#define SECTION_TITLE_3 5
#define SECTION_TITLE_INSTRUCTIONS 6
// Estados de cada elemento que pertenece a un evento
#define EVENT_WAITING 1
#define EVENT_RUNNING 2
#define EVENT_COMPLETED 3
// Estados de entrada
#define INPUT_NULL 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
// Colores
const color_t bgColor = {0x27, 0x27, 0x36};
const color_t noColor = {0xFF, 0xFF, 0xFF};
const color_t shdwTxtColor = {0x43, 0x43, 0x4F};
// Tipo de filtro
#define FILTER_NEAREST 0
#define FILTER_LINEAL 1
const color_t borderColor = {0x27, 0x27, 0x36};
const color_t black = {0xFF, 0xFF, 0xFF};
#endif

View File

@@ -1,4 +1,4 @@
#include "const.h"
#include "utils.h"
#include "director.h"
#include <iostream>
@@ -7,39 +7,30 @@
// Constructor
Director::Director(std::string path)
{
// Inicializa la ruta
setExecutablePath(path);
// Crea el objeto que controla los ficheros de recursos
mAsset = new Asset(mExecutablePath);
// Establece la lista de ficheros
setFileList();
asset = new Asset(path.substr(0, path.find_last_of("\\/")));
// Si falta algún fichero no inicia el programa
Uint8 section = SECTION_PROG_GAME;
if (!mAsset->check())
section = SECTION_PROG_QUIT;
// Inicializa el objeto de idioma
mLang = new Lang(mAsset);
// Crea el puntero a la estructura y carga el fichero de configuración
mOptions = new options_t;
if (!loadConfigFile())
if (!setFileList())
{
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;
section.name = SECTION_PROG_QUIT;
}
else
{
section.name = SECTION_PROG_LOGO;
section.subsection = 0;
}
// Crea los objetos
mInput = new Input(mAsset->get("gamecontrollerdb.txt"));
// Crea el puntero a la estructura y carga el fichero de configuración
options = new options_t;
options->fullScreenMode = 0;
options->windowSize = 3;
options->filter = FILTER_NEAREST;
options->vSync = true;
options->screenWidth = GAMECANVAS_WIDTH * options->windowSize;
options->screenHeight = GAMECANVAS_HEIGHT * options->windowSize;
options->integerScale = true;
options->keepAspect = true;
// Inicializa SDL
initSDL();
@@ -47,69 +38,48 @@ 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);
// Inicializa el resto de variables
init(section);
// Crea los objetos
input = new Input(asset->get("gamecontrollerdb.txt"));
initInput();
screen = new Screen(window, renderer, options, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
screen->setBorderColor(borderColor);
}
Director::~Director()
{
saveConfigFile();
delete mInput;
mInput = nullptr;
delete mLang;
mLang = nullptr;
delete mOptions;
mOptions = nullptr;
delete mAsset;
mAsset = nullptr;
SDL_DestroyRenderer(mRenderer);
SDL_DestroyWindow(mWindow);
mRenderer = nullptr;
mWindow = nullptr;
delete options;
delete asset;
delete input;
delete screen;
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
// Inicia las variables necesarias para arrancar el programa
void Director::init(Uint8 name)
void Director::initInput()
{
// Sección
mSection.name = name;
mSection.subsection = 0;
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_SPACE);
input->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_D);
input->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE);
input->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_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);
mInput->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_SPACE);
mInput->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE);
mInput->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_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_B);
mInput->bindGameControllerButton(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE);
mInput->bindGameControllerButton(INPUT_BUTTON_ESCAPE, SDL_CONTROLLER_BUTTON_GUIDE);
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_B);
input->bindGameControllerButton(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE);
input->bindGameControllerButton(INPUT_BUTTON_ESCAPE, SDL_CONTROLLER_BUTTON_GUIDE);
}
// Inicializa JailAudio
@@ -126,7 +96,6 @@ bool Director::initSDL()
// Inicializa SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0)
//if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
printf("SDL could not initialize!\nSDL Error: %s\n", SDL_GetError());
success = false;
@@ -137,14 +106,14 @@ bool Director::initSDL()
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()))
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->screenHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (window == NULL)
{
printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false;
@@ -152,12 +121,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 == NULL)
{
printf("Renderer could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false;
@@ -165,13 +134,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);
}
}
}
@@ -181,186 +150,108 @@ bool Director::initSDL()
}
// Crea el indice de ficheros
void Director::setFileList()
bool Director::setFileList()
{
mAsset->add("/media/font/8bithud.png", font);
mAsset->add("/media/font/8bithud.txt", font);
mAsset->add("/media/font/nokia.png", font);
mAsset->add("/media/font/nokia.txt", font);
mAsset->add("/media/font/nokia2.png", font);
mAsset->add("/media/font/nokia2.txt", font);
mAsset->add("/media/font/smb2.png", font);
mAsset->add("/media/font/smb2.txt", font);
mAsset->add("/media/lang/es_ES.txt", lang);
mAsset->add("/media/lang/en_UK.txt", lang);
mAsset->add("/media/lang/ba_BA.txt", lang);
mAsset->add("/data/gamecontrollerdb.txt", data);
mAsset->add("/data/config.bin", data, false);
mAsset->add("/data/room/01.room", room);
mAsset->add("/data/room/02.room", room);
mAsset->add("/media/tilesets/room1.png", bitmap);
mAsset->add("/media/enemies/enemy01.png", bitmap);
}
asset->add("/media/font/smb2.png", font);
asset->add("/media/font/smb2.txt", font);
asset->add("/media/font/debug.png", font);
asset->add("/media/font/debug.txt", font);
// 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;
asset->add("/data/gamecontrollerdb.txt", data);
// Indicador de éxito en la carga
bool success = true;
asset->add("/data/room/01.room", room);
asset->add("/data/room/02.room", room);
asset->add("/data/room/03.room", room);
asset->add("/data/room/04.room", room);
asset->add("/data/room/05.room", room);
asset->add("/data/room/01.tmx", room);
asset->add("/data/room/02.tmx", room);
asset->add("/data/room/03.tmx", room);
asset->add("/data/room/04.tmx", room);
asset->add("/data/room/05.tmx", room);
const std::string p = mAsset->get("config.bin");
std::string filename = p.substr(p.find_last_of("\\/") + 1);
SDL_RWops *file = SDL_RWFromFile(p.c_str(), "r+b");
asset->add("/media/tilesets/standard.png", bitmap);
// El fichero no existe
if (file == NULL)
{
printf("Warning: Unable to open %s file\n", filename.c_str());
asset->add("/media/enemies/paco.png", bitmap);
asset->add("/media/enemies/paco.ani", data);
asset->add("/media/enemies/chip.png", bitmap);
asset->add("/media/enemies/chip.ani", data);
asset->add("/media/enemies/wave.png", bitmap);
asset->add("/media/enemies/wave.ani", data);
asset->add("/media/enemies/sigmasua.png", bitmap);
asset->add("/media/enemies/sigmasua.ani", data);
// Crea el fichero para escritura
file = SDL_RWFromFile(p.c_str(), "w+b");
if (file != NULL)
{
printf("New file (%s) created!\n", filename.c_str());
asset->add("/media/player/player01.png", bitmap);
asset->add("/media/player/player01.ani", data);
// 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);
asset->add("/media/items/items.png", bitmap);
// Cierra el fichero
SDL_RWclose(file);
}
else
{
printf("Error: Unable to create file %s\n", filename.c_str());
success = false;
}
}
// El fichero existe
else
{
// 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);
asset->add("/media/music/title.ogg", music);
asset->add("/media/music/game.ogg", music);
// 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;
asset->add("/media/sound/item.wav", sound);
// Cierra el fichero
SDL_RWclose(file);
}
asset->add("/media/logo/jailgames.png", bitmap);
asset->add("/media/logo/since_1998.png", bitmap);
asset->add("/media/logo/seagull.png", bitmap);
return success;
}
asset->add("/media/title/loading_screen1.png", bitmap);
asset->add("/media/title/loading_screen2.png", bitmap);
// Guarda el fichero de configuración
bool Director::saveConfigFile()
{
bool success = true;
const std::string p = mAsset->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)
{
// 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);
printf("Writing file %s\n", filename.c_str());
// Cierra el fichero
SDL_RWclose(file);
}
else
{
printf("Error: Unable to save %s file! %s\n", filename.c_str(), SDL_GetError());
}
return success;
}
// Establece el valor de la variable
void Director::setExecutablePath(std::string path)
{
mExecutablePath = path.substr(0, path.find_last_of("\\/"));
return asset->check();
}
// Obtiene el valor de la variable
Uint8 Director::getSubsection()
{
return mSection.subsection;
return section.subsection;
}
// Obtiene el valor de la variable
Uint8 Director::getSection()
{
return mSection.name;
return section.name;
}
// Establece el valor de la variable
void Director::setSection(section_t section)
{
mSection = section;
this->section = section;
}
// Ejecuta la seccion de juego con el logo
void Director::runLogo()
{
logo = new Logo(renderer, screen, asset);
setSection(logo->run());
delete logo;
}
// Ejecuta la seccion de juego de la introducción
void Director::runIntro()
{
}
// Ejecuta la seccion de juego con el titulo y los menus
void Director::runTitle()
{
title = new Title(renderer, screen, asset);
setSection(title->run());
delete title;
}
// Ejecuta la seccion de juego donde se juega
void Director::runGame()
{
mGame = new Game(mWindow, mRenderer, mAsset, mLang, mInput);
setSection(mGame->run());
delete mGame;
game = new Game(renderer, screen, asset, input);
setSection(game->run());
delete game;
}
void Director::run()
{
// Bucle principal
while (!(getSection() == SECTION_PROG_QUIT))
while (getSection() != SECTION_PROG_QUIT)
{
switch (getSection())
{

View File

@@ -1,40 +1,37 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "sprite.h"
#include "movingsprite.h"
#include "text.h"
#include "writer.h"
#include "menu.h"
#include "const.h"
#include "jail_audio.h"
#include "utils.h"
#include "input.h"
#include "fade.h"
#include "game.h"
#include "logo.h"
#include "title.h"
#include "asset.h"
#include "lang.h"
#include "const.h"
#ifndef DIRECTOR_H
#define DIRECTOR_H
#define MAX_FILE_LIST 100
// Director
class Director
{
private:
SDL_Window *mWindow; // La ventana donde dibujamos
SDL_Renderer *mRenderer; // El renderizador de la ventana
SDL_Window *window; // La ventana donde dibujamos
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
Input *input; // Objeto Input para gestionar las entradas
Game *game; // Objeto para gestionar la sección del juego
Logo *logo; // Objeto para gestionar la sección del logo del programa
Title *title; // Objeto para gestionar la pantalla de título
Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Input *mInput; // Objeto Input para gestionar las entradas
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
Game *mGame; // Objeto para la sección del juego
Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos
struct options_t *options; // Variable con todas las opciones del programa
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;
std::string executablePath; // Path del ejecutable
section_t section; // Sección y subsección actual del programa;
// Inicializa jail_audio
void initJailAudio();
@@ -42,20 +39,11 @@ private:
// Arranca SDL y crea la ventana
bool initSDL();
// Inicializa el objeto Input
void initInput();
// Crea el indice de ficheros
void setFileList();
// Comprueba que todos los ficheros existen
bool checkFileList();
// Carga el fichero de configuración
bool loadConfigFile();
// Guarda el fichero de configuración
bool saveConfigFile();
// Establece el valor de la variable
void setExecutablePath(std::string path);
bool setFileList();
// Obtiene el valor de la variable
Uint8 getSubsection();
@@ -78,9 +66,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);
@@ -88,9 +73,6 @@ public:
// Destructor
~Director();
// Inicia las variables necesarias para arrancar el programa
void init(Uint8 name);
// Bucle principal
void run();
};

View File

@@ -10,11 +10,8 @@ Enemy::Enemy(enemy_t enemy)
renderer = enemy.renderer;
// Crea objetos
texture = new LTexture();
sprite = new AnimatedSprite(texture, renderer);
// Carga la textura
loadTextureFromFile(texture, asset->get(enemy.tileset), renderer);
texture = new LTexture(renderer, asset->get(enemy.tileset));
sprite = new AnimatedSprite(texture, renderer, asset->get(enemy.animation));
// Obten el resto de valores
x1 = enemy.x1;
@@ -26,35 +23,21 @@ Enemy::Enemy(enemy_t enemy)
sprite->setPosY(enemy.y);
sprite->setVelX(enemy.vx);
sprite->setVelY(enemy.vy);
sprite->setWidth(enemy.w);
sprite->setHeight(enemy.h);
// Inicializa el sprite con el resto de parametros comunes
sprite->setWidth(16);
sprite->setHeight(16);
sprite->setCurrentFrame(0);
sprite->setAnimationCounter(0);
sprite->setAnimationNumFrames(0, 4);
sprite->setAnimationSpeed(0, 5);
sprite->setAnimationLoop(0, true);
sprite->setAnimationFrames(0, 0, 16 * 0, 0, 16, 16);
sprite->setAnimationFrames(0, 1, 16 * 1, 0, 16, 16);
sprite->setAnimationFrames(0, 2, 16 * 2, 0, 16, 16);
sprite->setAnimationFrames(0, 3, 16 * 3, 0, 16, 16);
sprite->setSpriteClip(sprite->getAnimationClip(0, 0));
collider = getRect();
}
// Destructor
Enemy::~Enemy()
{
texture->unload();
delete texture;
texture = nullptr;
delete sprite;
sprite = nullptr;
}
// Pinta el enemigo en pantalla
void Enemy::draw()
void Enemy::render()
{
sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->render();
@@ -65,8 +48,9 @@ void Enemy::draw()
void Enemy::update()
{
sprite->update();
sprite->animate(0);
// sprite->animate();
checkPath();
collider = getRect();
}
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
@@ -74,13 +58,29 @@ void Enemy::checkPath()
{
if (sprite->getPosX() > x2 || sprite->getPosX() < x1)
{
//sprite->setPosX(sprite->getPosX() - sprite->getVelX());
sprite->setVelX(sprite->getVelX() * (-1));
}
if (sprite->getPosY() > y2 || sprite->getPosY() < y1)
{
//sprite->setPosY(sprite->getPosY() - sprite->getVelY());
sprite->setVelY(sprite->getVelY() * (-1));
}
}
// Devuelve el rectangulo que contiene al enemigo
SDL_Rect Enemy::getRect()
{
return sprite->getRect();
}
// Obtiene el rectangulo de colision del enemigo
SDL_Rect &Enemy::getCollider()
{
return collider;
}
// Recarga la textura
void Enemy::reLoadTexture()
{
texture->reLoad();
}

View File

@@ -1,5 +1,5 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "utils.h"
#include "asset.h"
#include "animatedsprite.h"
@@ -29,6 +29,9 @@ struct enemy_t
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
std::string tileset; // Fichero con los graficos del enemigo
std::string animation; // Fichero con las animaciones del enemigo
int w; // Anchura del enemigo
int h; // Altura del enemigo
float x; // Posición inicial en el eje X
float y; // Posición inicial en el eje Y
float vx; // Velocidad en el eje X
@@ -54,6 +57,7 @@ private:
int x2; // Limite derecho de la ruta en el eje X
int y1; // Limite superior de la ruta en el eje Y
int y2; // Limite inferior de la ruta en el eje Y
SDL_Rect collider; // Caja de colisión
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void checkPath();
@@ -66,10 +70,19 @@ public:
~Enemy();
// Pinta el enemigo en pantalla
void draw();
void render();
// Actualiza las variables del objeto
void update();
// Devuelve el rectangulo que contiene al enemigo
SDL_Rect getRect();
// Obtiene el rectangulo de colision del enemigo
SDL_Rect &getCollider();
// Recarga la textura
void reLoadTexture();
};
#endif

View File

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

View File

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

View File

@@ -1,149 +1,247 @@
#include "game.h"
// Constructor
Game::Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Lang *lang, Input *input)
Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input)
{
// Copia los punteros
mRenderer = renderer;
mAsset = asset;
mLang = lang;
mInput = input;
// Inicia variables
clock = SDL_GetTicks();
currentRoom = "01.room";
spawnPoint = {2 * 8, 12 * 8, 0, 0, 0, STATUS_STANDING, SDL_FLIP_NONE};
debug = false;
mScreen = new Screen(window, renderer);
mRoom = new Room(mAsset->get("01.room"), mRenderer, mAsset);
mEventHandler = new SDL_Event();
mTextureText = new LTexture();
mText = new Text(mAsset->get("smb2.txt"), mTextureText, renderer);
mFade = new Fade(renderer);
// Copia los punteros
this->renderer = renderer;
this->asset = asset;
this->screen = screen;
this->input = input;
// Crea los objetos
scoreboard = new ScoreBoard(renderer, asset, &playerLives, &itemsPicked, &clock);
itemTracker = new ItemTracker();
room = new Room(asset->get(currentRoom), renderer, asset, itemTracker, &itemsPicked);
player = new Player(spawnPoint, asset->get("player01.png"), asset->get("player01.ani"), renderer, asset, input, room);
eventHandler = new SDL_Event();
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
debugText = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer);
music = JA_LoadMusic(asset->get("game.ogg").c_str());
// Inicializa variables
ticks = 0;
ticksSpeed = 15;
playerLives = 9;
itemsPicked = 0;
section.name = SECTION_PROG_GAME;
section.subsection = SUBSECTION_GAME_PLAY;
}
Game::~Game()
{
mRenderer = nullptr;
mAsset = nullptr;
mLang = nullptr;
mInput = nullptr;
// Borra las referencias a los punteros
renderer = nullptr;
asset = nullptr;
input = nullptr;
delete mEventHandler;
mEventHandler = nullptr;
// Libera la memoria de los objetos
delete scoreboard;
scoreboard = nullptr;
mTextureText->unload();
delete mTextureText;
mTextureText = nullptr;
delete itemTracker;
itemTracker = nullptr;
delete mScreen;
mScreen = nullptr;
delete room;
room = nullptr;
delete mRoom;
mRoom = nullptr;
delete player;
player = nullptr;
delete mText;
mText = nullptr;
delete eventHandler;
eventHandler = nullptr;
delete mFade;
mFade = nullptr;
delete text;
text = nullptr;
delete debugText;
debugText = nullptr;
}
// Inicializa las variables necesarias para la sección 'Game'
void Game::init()
// Comprueba los eventos de la cola
void Game::checkEventHandler()
{
// Carga los recursos
loadMedia();
mTicks = 0;
mTicksSpeed = 15;
mSection.name = SECTION_PROG_GAME;
mSection.subsection = SECTION_GAME_PLAY;
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(eventHandler) != 0)
{
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
break;
}
// Carga los recursos necesarios para la sección 'Game'
bool Game::loadMedia()
else if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0))
{
bool success = true;
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_TITLE;
break;
// Texturas
success &= loadTextureFromFile(mTextureText, mAsset->get("smb2.png"), mRenderer);
case SDL_SCANCODE_D:
debug = !debug;
break;
return success;
case SDL_SCANCODE_M:
(JA_GetMusicState() == JA_MUSIC_PLAYING) ? JA_PauseMusic() : JA_ResumeMusic();
break;
case SDL_SCANCODE_F:
screen->switchVideoMode();
reLoadTextures();
break;
case SDL_SCANCODE_F1:
screen->setWindowSize(1);
reLoadTextures();
break;
case SDL_SCANCODE_F2:
screen->setWindowSize(2);
reLoadTextures();
break;
case SDL_SCANCODE_F3:
screen->setWindowSize(3);
reLoadTextures();
break;
case SDL_SCANCODE_F4:
screen->setWindowSize(4);
reLoadTextures();
break;
default:
break;
}
}
}
}
// Bucle para el juego
section_t Game::run()
{
init();
JA_PlayMusic(music);
while (mSection.name == SECTION_PROG_GAME)
while (section.name == SECTION_PROG_GAME)
{
// Sección juego jugando
if (mSection.subsection == SECTION_GAME_PLAY)
if (section.subsection == SUBSECTION_GAME_PLAY)
{
update();
draw();
render();
}
}
return mSection;
JA_StopMusic();
return section;
}
// Actualiza el juego, las variables, comprueba la entrada, etc.
void Game::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - mTicks > mTicksSpeed)
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
mTicks = SDL_GetTicks();
ticks = SDL_GetTicks();
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(mEventHandler) != 0)
{
// Evento de salida de la aplicación
if (mEventHandler->type == SDL_QUIT)
{
mSection.name = SECTION_PROG_QUIT;
break;
}
}
// Comprueba los eventos de la cola
checkEventHandler();
checkInput();
mRoom->update();
// Actualiza los objetos
room->update();
{
player->update();
checkPlayerAndWalls(); // Debe ir detras del player update, por si se ha metido en algun muro
}
checkPlayerOnBorder();
checkPlayerOnFloor();
checkPlayerAndItems();
checkPlayerAndEnemies();
scoreboard->update();
}
}
// Pinta los objetos en pantalla
void Game::draw()
void Game::render()
{
// Prepara para dibujar el frame
const color_t color = {0xAA, 0x55, 0x55};
mScreen->start();
mScreen->clean(color);
mScreen->clean(mRoom->getBGColor());
screen->start();
screen->clean(room->getBGColor());
mRoom->drawMap();
mRoom->drawEnemies();
room->renderMap();
room->renderEnemies();
room->renderItems();
player->render();
renderRoomName();
scoreboard->render();
// Texto en el centro de la pantalla
mText->writeCentered(GAMECANVAS_CENTER_X, 18 * 8, mRoom->getName());
// Debug info
renderDebugInfo();
// Actualiza la pantalla
mScreen->blit();
screen->blit();
}
// Comprueba la entrada
void Game::checkInput()
// Pone la información de debug en pantalla
void Game::renderDebugInfo()
{
if (mInput->checkInput(INPUT_UP, REPEAT_FALSE))
changeRoom(mRoom->getRoomUp());
if (!debug)
{
return;
}
if (mInput->checkInput(INPUT_DOWN, REPEAT_FALSE))
changeRoom(mRoom->getRoomDown());
// Pinta la rejilla
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 64);
for (int i = 0; i < PLAY_AREA_BOTTOM; i += 8)
{ // Lineas horizontales
SDL_RenderDrawLine(renderer, 0, i, PLAY_AREA_RIGHT, i);
}
for (int i = 0; i < PLAY_AREA_RIGHT; i += 8)
{ // Lineas verticales
SDL_RenderDrawLine(renderer, i, 0, i, PLAY_AREA_BOTTOM - 1);
}
if (mInput->checkInput(INPUT_LEFT, REPEAT_FALSE))
changeRoom(mRoom->getRoomLeft());
// Pinta el texto
std::string text;
const int inc = debugText->getCharacterWidth() + 1;
int line = 131;
if (mInput->checkInput(INPUT_RIGHT, REPEAT_FALSE))
changeRoom(mRoom->getRoomRight());
text = "status: " + std::to_string(player->status);
debugText->write(0, line += inc, text);
text = "foot: " + std::to_string((int)player->getLeftFoot().y);
debugText->write(0, line += inc, text);
const int a = (player->lastPosition.y + 16) / 8;
const int b = player->getLeftFoot().y / 8;
text = "tile: " + std::to_string(a) + " - " + std::to_string(b);
debugText->write(0, line += inc, text);
const bool collision = checkPlayerAndEnemies();
text = "collision: " + std::to_string(collision);
debugText->write(0, line += inc, text);
}
// Escribe el nombre de la pantalla
void Game::renderRoomName()
{
// Texto en el centro de la pantalla
SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK};
color_t color = stringToColor("light_black");
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(renderer, &rect);
text->writeCentered(GAMECANVAS_CENTER_X, 16 * 8, room->getName());
}
// Cambia de habitación
@@ -154,17 +252,171 @@ bool Game::changeRoom(std::string file)
// En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada
if (file != "0")
// Verifica que exista el fichero que se va a cargar
if (mAsset->get(file) != "")
if (asset->get(file) != "")
{
// Elimina la habitación actual
delete mRoom;
mRoom = nullptr;
delete room;
room = nullptr;
// Crea un objeto habitación nuevo a partir del fichero
mRoom = new Room(mAsset->get(file), mRenderer, mAsset);
room = new Room(asset->get(file), renderer, asset, itemTracker, &itemsPicked);
success = true;
}
return success;
}
// Comprueba si el jugador esta en el borde de la pantalla
void Game::checkPlayerOnBorder()
{
if (player->getOnBorder())
{
const std::string room_name = room->getRoom(player->getBorder());
if (changeRoom(room_name))
{
player->switchBorders();
currentRoom = room_name;
spawnPoint = player->getSpawnParams();
}
}
}
// Comprueba si el jugador esta sobre el suelo
void Game::checkPlayerOnFloor()
{
// Comprueba si tiene suelo bajo los pies solo cuando no hay velocidad de subida
// y solo cuando el pie este encima de un bloque, es decir, en multiplos de 8
// *** HAY UN POSIBLE PROBLEMA y es que caiga muy rapido y viaje a mas de un pixel de velocidad,
// con lo que se saltaria la comprobación
// *** POSIBLE SOLUCION. Comprobar si el tile actual del pie es diferente al tile del pie previo.
// Esto indica que se ha saltado la comprobacion cada 8 pixeles.
// En este caso habría que recolocar al jugador en el sitio
// *** PARECE RESUELTO
const int a = (player->lastPosition.y + 16) / 8;
const int b = player->getLeftFoot().y / 8;
const bool tile_change = a != b;
const bool is_not_going_up = player->getVelY() >= 0;
const bool is_tile_aligned = player->getLeftFoot().y % 8 == 0;
if (((is_not_going_up) && (is_tile_aligned)) || ((is_not_going_up) && (tile_change)))
{
bool test = false;
test |= (room->getTile(player->getLeftFoot()) == TILE_SOLID);
test |= (room->getTile(player->getRightFoot()) == TILE_SOLID);
test |= (room->getTile(player->getLeftFoot()) == TILE_TRAVESSABLE);
test |= (room->getTile(player->getRightFoot()) == TILE_TRAVESSABLE);
// Tiene uno de los pies sobre una superficie
if (test)
{
player->setStatus(STATUS_STANDING);
// Si ha habido un cambio de tile, hay que recolocarlo
if (tile_change)
{
int offset = (int)player->sprite->getPosY() % 8;
player->sprite->setPosY((int)player->sprite->getPosY() - offset);
}
}
// Tiene ambos pies sobre el vacío
else if (player->getStatus() != STATUS_JUMPING)
{
player->setStatus(STATUS_FALLING);
}
}
}
// Comprueba que el jugador no atraviese ninguna pared
void Game::checkPlayerAndWalls()
{
// Obtiene los ocho puntos de colisión del jugador
const SDL_Rect rect = player->getRect();
const SDL_Point p1 = {rect.x, rect.y};
const SDL_Point p2 = {rect.x + 7, rect.y};
const SDL_Point p3 = {rect.x + 7, rect.y + 7};
const SDL_Point p4 = {rect.x, rect.y + 7};
const SDL_Point p5 = {rect.x, rect.y + 8};
const SDL_Point p6 = {rect.x + 7, rect.y + 8};
const SDL_Point p7 = {rect.x + 7, rect.y + 15};
const SDL_Point p8 = {rect.x, rect.y + 15};
// Comprueba si ha colisionado con un muro
bool wall = false;
wall |= (room->getTile(p1) == TILE_SOLID);
wall |= (room->getTile(p2) == TILE_SOLID);
wall |= (room->getTile(p3) == TILE_SOLID);
wall |= (room->getTile(p4) == TILE_SOLID);
wall |= (room->getTile(p5) == TILE_SOLID);
wall |= (room->getTile(p6) == TILE_SOLID);
wall |= (room->getTile(p7) == TILE_SOLID);
wall |= (room->getTile(p8) == TILE_SOLID);
if (wall)
{
// Si hay colisión, deshace el movimiento y lo pone en modo caída
player->undoLastMove();
player->setStatus(STATUS_FALLING);
}
// Comprueba si ha colisionado con un tile de los que matan al jugador
bool death = false;
death |= (room->getTile(p1) == TILE_KILL);
death |= (room->getTile(p2) == TILE_KILL);
death |= (room->getTile(p3) == TILE_KILL);
death |= (room->getTile(p4) == TILE_KILL);
death |= (room->getTile(p5) == TILE_KILL);
death |= (room->getTile(p6) == TILE_KILL);
death |= (room->getTile(p7) == TILE_KILL);
death |= (room->getTile(p8) == TILE_KILL);
if (death)
{
killPlayer();
}
}
// Comprueba las colisiones del jugador con los enemigos
bool Game::checkPlayerAndEnemies()
{
const bool death = room->enemyCollision(player->getCollider());
if (death)
{
killPlayer();
}
return death;
}
// Comprueba las colisiones del jugador con los objetos
void Game::checkPlayerAndItems()
{
room->itemCollision(player->getCollider());
}
// Mata al jugador
void Game::killPlayer()
{
playerLives--;
// Destruye la habitacion y el jugador
delete room;
delete player;
// Crea la nueva habitación y el nuevo jugador
room = new Room(asset->get(currentRoom), renderer, asset, itemTracker, &itemsPicked);
player = new Player(spawnPoint, asset->get("player01.png"), asset->get("player01.ani"), renderer, asset, input, room);
}
// Recarga todas las texturas
void Game::reLoadTextures()
{
player->reLoadTexture();
room->reLoadTexture();
scoreboard->reLoadTexture();
text->reLoadTexture();
}

View File

@@ -1,20 +1,18 @@
#pragma once
#include "ifdefs.h"
#include "const.h"
#include "utils.h"
#include <SDL2/SDL.h>
#include "utils.h"
#include "sprite.h"
#include "movingsprite.h"
#include "animatedsprite.h"
#include "text.h"
#include "writer.h"
#include "menu.h"
#include "input.h"
#include "fade.h"
#include "lang.h"
#include "screen.h"
#include "asset.h"
#include "room.h"
#include "item_tracker.h"
#include "player.h"
#include "jail_audio.h"
#include "scoreboard.h"
#ifndef GAME_H
#define GAME_H
@@ -23,41 +21,70 @@
class Game
{
private:
SDL_Renderer *mRenderer; // El renderizador de la ventana
SDL_Event *mEventHandler; // Manejador de eventos
Screen *mScreen; // Objeto encargado de manejar el renderizador
Room *mRoom; // Objeto encargado de gestionar cada habitación del juego
Asset *mAsset; // Objeto con la ruta a todos los ficheros de recursos
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas
Input *mInput; // Objeto pata gestionar la entrada
Text *mText; // Objeto para los textos del juego
Fade *mFade; // Objeto para renderizar fades
LTexture *mTextureText; // Textura para la fuente de texto
Uint32 mTicks; // Contador de ticks para ajustar la velocidad del programa
Uint8 mTicksSpeed; // Velocidad a la que se repiten los bucles del programa
section_t mSection; // Seccion actual dentro del juego
// Inicializa las variables
void init();
// Carga los recursos
bool loadMedia();
SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Event *eventHandler; // Manejador de eventos
Screen *screen; // Objeto encargado de manejar el renderizador
Room *room; // Objeto encargado de gestionar cada habitación del juego
Player *player; // Objeto con el jugador
ItemTracker *itemTracker; // Lleva el control de los objetos recogidos
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada
Text *text; // Objeto para los textos del juego
Text *debugText; // Objeto para los textos de debug del juego
ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador
JA_Music music; // Musica que suena durante el juego
int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
section_t section; // Seccion actual dentro del juego
std::string currentRoom; // Fichero de la habitación actual
player_t spawnPoint; // Lugar de la habitación donde aparece el jugador
bool debug; // Indica si el modo debug está activo
int playerLives; // Lleva la cuenta de ls vidas restantes del jugador
int itemsPicked; // Lleva la cuenta de los objetos recogidos
Uint32 clock; // Cuenta el tiempo que dura la partida
// Actualiza el juego, las variables, comprueba la entrada, etc.
void update();
// Pinta los objetos en pantalla
void draw();
void render();
// Comprueba la entrada
void checkInput();
// Comprueba los eventos de la cola
void checkEventHandler();
// Pone la información de debug en pantalla
void renderDebugInfo();
// Escribe el nombre de la pantalla
void renderRoomName();
// Cambia de habitación
bool changeRoom(std::string file);
// Comprueba si el jugador esta en el borde de la pantalla y actua
void checkPlayerOnBorder();
// Comprueba si el jugador esta sobre el suelo
void checkPlayerOnFloor();
// Comprueba que el jugador no atraviese ninguna pared
void checkPlayerAndWalls();
// Comprueba las colisiones del jugador con los enemigos
bool checkPlayerAndEnemies();
// Comprueba las colisiones del jugador con los objetos
void checkPlayerAndItems();
// Mata al jugador
void killPlayer();
// Recarga todas las texturas
void reLoadTextures();
public:
// Constructor
Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Lang *lang, Input *input);
Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input);
// Destructor
~Game();

View File

@@ -1,13 +0,0 @@
#include <SDL2/SDL.h>
#ifdef __APPLE__
#include "/Library/Frameworks/SDL2.framework/Versions/A/Headers/SDL.h"
#endif
#ifdef __linux__
#ifdef __MIPSEL__
#include "SDL.h"
#else
#include <SDL2/SDL.h>
#endif
#endif

View File

@@ -1,5 +1,5 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include <string>
#include <vector>

87
source/item.cpp Normal file
View File

@@ -0,0 +1,87 @@
#include "item.h"
#include <fstream>
#include <sstream>
// Constructor
Item::Item(item_t item)
{
// Obten punteros a objetos
asset = item.asset;
renderer = item.renderer;
// Crea objetos
texture = new LTexture(renderer,asset->get(item.tileset));
sprite = new Sprite(item.x, item.y, 8, 8, texture, renderer);
// Inicia variables
sprite->setSpriteClip(item.tile * 8, 0, 8, 8);
collider = sprite->getRect();
colorChangeSpeed = 4;
counter = item.counter * colorChangeSpeed;
// Inicializa los colores
color_t c = stringToColor("blue");
color.push_back(c);
c = stringToColor("red");
color.push_back(c);
c = stringToColor("purple");
color.push_back(c);
c = stringToColor("green");
color.push_back(c);
c = stringToColor("cyan");
color.push_back(c);
c = stringToColor("yellow");
color.push_back(c);
}
// Destructor
Item::~Item()
{
delete texture;
delete sprite;
}
// Pinta el objeto en pantalla
void Item::render()
{
const int index = (counter / colorChangeSpeed) % color.size();
sprite->getTexture()->setColor(color[index].r, color[index].g, color[index].b);
sprite->render();
sprite->getTexture()->setColor(255, 255, 255);
}
// Actualiza las variables del objeto
void Item::update()
{
counter++;
}
// Coge el objeto
void Item::pick()
{
sprite->setEnabled(false);
}
// Obtiene el rectangulo de colision del objeto
SDL_Rect &Item::getCollider()
{
return collider;
}
// Obtiene su ubicación
SDL_Point Item::getPos()
{
const SDL_Point p = {sprite->getPosX(), sprite->getPosY()};
return p;
}
// Recarga la textura
void Item::reLoadTexture()
{
texture->reLoad();
}

67
source/item.h Normal file
View File

@@ -0,0 +1,67 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include "asset.h"
#include "sprite.h"
#include <string>
#ifndef ITEM_H
#define ITEM_H
/*
Un item deberia tener la siguiente informacion:
POSICION INICIAL
PNG ASOCIADO
*/
struct item_t
{
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
std::string tileset; // Fichero con los graficos del item
int x; // Posicion del item en pantalla
int y; // Posicion del item en pantalla
int tile; // Numero de tile dentro de la textura
int counter; // Contador inicial. Es el que lo hace cambiar de color
};
// Clase Item
class Item
{
private:
LTexture *texture; // Textura con los graficos del objeto
Sprite *sprite; // Sprite del objeto
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
std::vector<color_t> color; // Vector con los colores del objeto
int counter; // Contador interno
SDL_Rect collider; // Rectangulo de colisión
int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color
public:
// Constructor
Item(item_t item);
// Destructor
~Item();
// Pinta el objeto en pantalla
void render();
// Actualiza las variables del objeto
void update();
// Coge el item
void pick();
// Obtiene el rectangulo de colision del objeto
SDL_Rect &getCollider();
// Obtiene su ubicación
SDL_Point getPos();
// Recarga la textura
void reLoadTexture();
};
#endif

87
source/item_tracker.cpp Normal file
View File

@@ -0,0 +1,87 @@
#include "item_tracker.h"
// Constructor
ItemTracker::ItemTracker()
{
}
// Destructor
ItemTracker::~ItemTracker()
{
list.clear();
}
// Comprueba si el objeto ya ha sido cogido
bool ItemTracker::hasBeenPicked(std::string name, SDL_Point pos)
{
bool success = false;
// Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name);
if (index != -1)
{
// Luego busca si existe ya una entrada con esa posición
if (findByPos(index, pos) != -1)
{
success = true;
}
}
return success;
}
// Añade el objeto a la lista de objetos cogidos
void ItemTracker::addItem(std::string name, SDL_Point pos)
{
// Comprueba si el objeto no ha sido recogido con anterioridad
if (!hasBeenPicked(name, pos))
{
// Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name);
if (index != -1)
{
list[index].pos.push_back(pos);
}
// En caso contrario crea la entrada
else
{
item_tracker_t item;
item.name = name;
item.pos.push_back(pos);
list.push_back(item);
}
}
}
// Busca una entrada en la lista por nombre
int ItemTracker::findByName(std::string name)
{
const int c = -1;
for (int i = 0; i < list.size(); i++)
{
if (list[i].name == name)
{
return i;
}
}
return c;
}
// Busca una entrada en la lista por posición
int ItemTracker::findByPos(int index, SDL_Point pos)
{
const int c = -1;
for (int i = 0; i < list[index].pos.size(); i++)
{
if ((list[index].pos[i].x == pos.x) && (list[index].pos[i].y == pos.y))
{
return i;
}
}
return c;
}

42
source/item_tracker.h Normal file
View File

@@ -0,0 +1,42 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include <string>
#include <vector>
#ifndef ITEM_TRACKER_H
#define ITEM_TRACKER_H
struct item_tracker_t
{
std::string name; // Nombre de la habitación donde se encuentra el objeto
std::vector<SDL_Point> pos; // Lista de objetos cogidos de la habitación
};
// Clase ItemTracker
class ItemTracker
{
private:
std::vector<item_tracker_t> list; // Lista con todos los objetos recogidos
// Busca una entrada en la lista por nombre
int findByName(std::string name);
// Busca una entrada en la lista por posición
int findByPos(int index, SDL_Point pos);
public:
// Constructor
ItemTracker();
// Destructor
~ItemTracker();
// Comprueba si el objeto ya ha sido cogido
bool hasBeenPicked(std::string name, SDL_Point pos);
// Añade el objeto a la lista de objetos cogidos
void addItem(std::string name, SDL_Point pos);
};
#endif

View File

@@ -1,6 +1,7 @@
#ifndef __MIPSEL__
#include "jail_audio.h"
#include "stb_vorbis.c"
#include <SDL2/SDL.h>
#include <stdio.h>
#define JA_MAX_SIMULTANEOUS_CHANNELS 5
@@ -30,16 +31,17 @@ JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
int JA_freq {48000};
SDL_AudioFormat JA_format {AUDIO_S16};
Uint8 JA_channels {2};
int JA_volume = 128;
void audioCallback(void * userdata, uint8_t * stream, int len) {
SDL_memset(stream, 0, len);
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
const int size = SDL_min(len, current_music->samples*2-current_music->pos);
SDL_memcpy(stream, current_music->output+current_music->pos, size);
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_volume);
current_music->pos += size/2;
if (size < len) {
if (current_music->times != 0) {
SDL_memcpy(stream+size, current_music->output, len-size);
SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, JA_volume);
current_music->pos = (len-size)/2;
if (current_music->times > 0) current_music->times--;
} else {
@@ -52,11 +54,11 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].state == JA_CHANNEL_PLAYING) {
const int size = SDL_min(len, channels[i].sound->length - channels[i].pos);
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, 64);
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_volume/2);
channels[i].pos += size;
if (size < len) {
if (channels[i].times != 0) {
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, 64);
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_volume/2);
channels[i].pos = len-size;
if (channels[i].times > 0) channels[i].times--;
} else {
@@ -79,7 +81,19 @@ void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) {
JA_Music JA_LoadMusic(const char* filename) {
int chan, samplerate;
JA_Music music = new JA_Music_t();
music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
// [RZC 28/08/22] Carreguem primer el arxiu en memòria i després el descomprimim. Es algo més rapid.
FILE *f = fopen(filename, "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
Uint8 *buffer = (Uint8*)malloc(fsize + 1);
fread(buffer, fsize, 1, f);
fclose(f);
music->samples = stb_vorbis_decode_memory(buffer, fsize, &chan, &samplerate, &music->output);
free(buffer);
// [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert
// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
@@ -134,6 +148,13 @@ void JA_DeleteMusic(JA_Music music) {
delete music;
}
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length) {
JA_Sound sound = new JA_Sound_t();
sound->buffer = buffer;
sound->length = length;
return sound;
}
JA_Sound JA_LoadSound(const char* filename) {
JA_Sound sound = new JA_Sound_t();
SDL_AudioSpec wavSpec;
@@ -210,4 +231,8 @@ JA_Channel_state JA_GetChannelState(const int channel) {
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
return channels[channel].state;
}
#endif
int JA_SetVolume(int volume) {
JA_volume = volume > 128 ? 128 : volume < 0 ? 0 : volume;
return JA_volume;
}

View File

@@ -1,5 +1,5 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED };
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED };
@@ -17,6 +17,7 @@ void JA_StopMusic();
JA_Music_state JA_GetMusicState();
void JA_DeleteMusic(JA_Music music);
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length);
JA_Sound JA_LoadSound(const char* filename);
int JA_PlaySound(JA_Sound sound, const int loop = 0);
void JA_PauseChannel(const int channel);
@@ -24,3 +25,5 @@ void JA_ResumeChannel(const int channel);
void JA_StopChannel(const int channel);
JA_Channel_state JA_GetChannelState(const int channel);
void JA_DeleteSound(JA_Sound sound);
int JA_SetVolume(int volume);

View File

@@ -1,74 +0,0 @@
#include "lang.h"
#include <iostream>
#include <fstream>
// Constructor
Lang::Lang(Asset *asset)
{
mAsset = asset;
}
// Destructor
Lang::~Lang()
{
mAsset = nullptr;
}
// Inicializa los textos del juego en el idioma seleccionado
bool Lang::setLang(Uint8 lang)
{
std::string file;
switch (lang)
{
case es_ES:
file = mAsset->get("es_ES.txt");
break;
case en_UK:
file = mAsset->get("en_UK.txt");
break;
case ba_BA:
file = mAsset->get("ba_BA.txt");
break;
default:
file = mAsset->get("en_UK.txt");
break;
}
for (int i = 0; i < MAX_TEXT_STRINGS; i++)
mTextStrings[i] = "";
bool success = false;
std::ifstream rfile(file);
if (rfile.is_open() && rfile.good())
{
success = true;
std::string buffer;
// lee el resto de datos del fichero
int index = 0;
int line_read = 0;
while (std::getline(rfile, buffer))
{
// Almacena solo las lineas impares
if (line_read % 2 == 1)
mTextStrings[index++] = buffer;
// Limpia el buffer
buffer.clear();
line_read++;
};
}
return success;
}
// Obtiene la cadena de texto del indice
std::string Lang::getText(int index)
{
return mTextStrings[index];
}

View File

@@ -1,38 +0,0 @@
#pragma once
#include "ifdefs.h"
#include "asset.h"
#include <string>
#ifndef LANG_H
#define LANG_H
// Lang codes
#define es_ES 0
#define ba_BA 1
#define en_UK 2
#define MAX_LANGUAGES 3
// Textos
#define MAX_TEXT_STRINGS 100
// Clase Lang
class Lang
{
private:
Asset *mAsset;
std::string mTextStrings[MAX_TEXT_STRINGS];
public:
// Constructor
Lang(Asset *asset);
// Destructor
~Lang();
// Inicializa los textos del juego en el idioma seleccionado
bool setLang(Uint8 lang);
// Obtiene la cadena de texto del indice
std::string getText(int index);
};
#endif

267
source/logo.cpp Normal file
View File

@@ -0,0 +1,267 @@
#include "logo.h"
// Constructor
Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset)
{
// Copia la dirección de los objetos
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
texture = new LTexture(renderer, asset->get("jailgames.png"));
texture2 = new LTexture(renderer, asset->get("since_1998.png"));
sprite2 = new Sprite((256 - texture2->getWidth()) / 2, 83 + texture->getHeight() + 5, texture2->getWidth(), texture2->getHeight(), texture2, renderer);
sprite2->setSpriteClip(0, 0, texture2->getWidth(), texture2->getHeight());
texture2->setColor(0, 0, 0);
for (int i = 0; i < texture->getHeight(); i++)
{
sprite.push_back(new Sprite(0, i, texture->getWidth(), 1, texture, renderer));
if (i % 2 == 0)
{
sprite[i]->setPosX(256 + (i * 3));
}
else
{
sprite[i]->setPosX(-181 - (i * 3));
}
sprite[i]->setPosY(83 + i);
}
// Inicializa variables
counter = 0;
section.name = SECTION_PROG_LOGO;
section.subsection = 0;
ticks = 0;
ticksSpeed = 15;
initFade = 300;
endLogo = 400;
postLogo = 20;
color_t c = stringToColor("black");
color.push_back(c);
c = stringToColor("blue");
color.push_back(c);
c = stringToColor("red");
color.push_back(c);
c = stringToColor("purple");
color.push_back(c);
c = stringToColor("green");
color.push_back(c);
c = stringToColor("cyan");
color.push_back(c);
c = stringToColor("yellow");
color.push_back(c);
c = stringToColor("light_white");
color.push_back(c);
}
// Destructor
Logo::~Logo()
{
delete texture;
delete texture2;
for (auto s : sprite)
{
delete s;
}
delete sprite2;
delete eventHandler;
}
// Comprueba el manejador de eventos
void Logo::checkEventHandler()
{
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(eventHandler) != 0)
{
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
break;
}
// Cualquier tecla pulsada
if ((eventHandler->type == SDL_KEYDOWN) || (eventHandler->type == SDL_JOYBUTTONDOWN))
{
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
}
}
}
// Actualiza las variables
void Logo::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Comprueba el manejador de eventos
checkEventHandler();
// Incrementa el contador
counter++;
// update de JAILGAMES
if (counter > 30)
{
for (int i = 1; i < sprite.size(); i++)
{
const int speed = 8;
const int dest = 37;
if (sprite[i]->getPosX() != 37)
{
if (i % 2 == 0)
{
sprite[i]->incPosX(-speed);
if (sprite[i]->getPosX() < dest)
{
sprite[i]->setPosX(dest);
}
}
else
{
sprite[i]->incPosX(speed);
if (sprite[i]->getPosX() > dest)
{
sprite[i]->setPosX(dest);
}
}
}
}
}
// update de fade
{
const int ini = 70;
const int inc = 4;
if (counter == ini + inc * 0)
{
texture2->setColor(color[0].r, color[0].g, color[0].b);
}
else if (counter == ini + inc * 1)
{
texture2->setColor(color[1].r, color[1].g, color[1].b);
}
else if (counter == ini + inc * 2)
{
texture2->setColor(color[2].r, color[2].g, color[2].b);
}
else if (counter == ini + inc * 3)
{
texture2->setColor(color[3].r, color[3].g, color[3].b);
}
else if (counter == ini + inc * 4)
{
texture2->setColor(color[4].r, color[4].g, color[4].b);
}
else if (counter == ini + inc * 5)
{
texture2->setColor(color[5].r, color[5].g, color[5].b);
}
else if (counter == ini + inc * 6)
{
texture2->setColor(color[6].r, color[6].g, color[6].b);
}
else if (counter == ini + inc * 7)
{
texture2->setColor(color[7].r, color[7].g, color[7].b);
}
else if (counter == initFade + inc * 0)
{
texture->setColor(color[6].r, color[6].g, color[6].b);
texture2->setColor(color[6].r, color[6].g, color[6].b);
}
else if (counter == initFade + inc * 1)
{
texture->setColor(color[5].r, color[5].g, color[5].b);
texture2->setColor(color[5].r, color[5].g, color[5].b);
}
else if (counter == initFade + inc * 2)
{
texture->setColor(color[4].r, color[4].g, color[4].b);
texture2->setColor(color[4].r, color[4].g, color[4].b);
}
else if (counter == initFade + inc * 3)
{
texture->setColor(color[3].r, color[3].g, color[3].b);
texture2->setColor(color[3].r, color[3].g, color[3].b);
}
else if (counter == initFade + inc * 4)
{
texture->setColor(color[2].r, color[2].g, color[2].b);
texture2->setColor(color[2].r, color[2].g, color[2].b);
}
else if (counter == initFade + inc * 5)
{
texture->setColor(color[1].r, color[1].g, color[1].b);
texture2->setColor(color[1].r, color[1].g, color[1].b);
}
else if (counter == initFade + inc * 6)
{
texture->setColor(color[0].r, color[0].g, color[0].b);
texture2->setColor(color[0].r, color[0].g, color[0].b);
}
}
// Comprueba si ha terminado el logo
if (counter == endLogo + postLogo)
{
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
}
}
}
// Dibuja en pantalla
void Logo::render()
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean();
// Dibuja los objetos
for (auto s : sprite)
{
s->render();
}
sprite2->render();
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
// Bucle para el logo del juego
section_t Logo::run()
{
// Detiene la música
JA_StopMusic();
while (section.name == SECTION_PROG_LOGO)
{
update();
render();
}
return section;
}

56
source/logo.h Normal file
View File

@@ -0,0 +1,56 @@
#pragma once
#include <SDL2/SDL.h>
#include "const.h"
#include "utils.h"
#include "sprite.h"
#include "screen.h"
#include "asset.h"
#include "jail_audio.h"
#include <vector>
#ifndef LOGO_H
#define LOGO_H
// Clase Logo
class Logo
{
private:
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
Asset *asset; // Objeto con los ficheros de recursos
LTexture *texture; // Textura con los graficos "JAILGAMES"
LTexture *texture2; // Textura con los graficos "Since 1998"
SDL_Event *eventHandler; // Manejador de eventos
std::vector<Sprite *> sprite; // Vector con los sprites de cada linea que forman el bitmap JAILGAMES
Sprite *sprite2; // Sprite para manejar la textura2
std::vector<color_t> color; // Vector con los colores para el fade
int counter; // Contador
section_t section; // Estado del bucle principal para saber si continua o se sale
int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
int initFade; // Tiempo del contador cuando inicia el fade a negro
int endLogo; // Tiempo del contador para terminar el logo
int postLogo; // Tiempo que dura el logo con el fade al maximo
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
// Comprueba el manejador de eventos
void checkEventHandler();
public:
// Constructor
Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset);
// Destructor
~Logo();
// Bucle principal
section_t run();
};
#endif

View File

@@ -1,22 +1,35 @@
#include "const.h"
#include "ltexture.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
LTexture::LTexture()
// Constructor
LTexture::LTexture(SDL_Renderer *renderer, std::string path)
{
// Initialize
mTexture = NULL;
mWidth = 0;
mHeight = 0;
// Copia punteros
this->renderer = renderer;
this->path = path;
// Inicializa
texture = NULL;
width = 0;
height = 0;
// Carga el fichero en la textura
if (path != "")
{
loadFromFile(path, renderer);
}
}
// Destructor
LTexture::~LTexture()
{
// Deallocate
// Libera memoria
unload();
}
// Carga una imagen desde un fichero
bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
{
int req_format = STBI_rgb_alpha;
@@ -33,7 +46,7 @@ bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
if (req_format == STBI_rgb)
{
depth = 24;
pitch = 3 * width; // 3 bytes per pixel * pixels per row
pitch = 3 * width; // 3 bytes por pixel * pixels per linea
pixel_format = SDL_PIXELFORMAT_RGB24;
}
else
@@ -43,14 +56,13 @@ bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
pixel_format = SDL_PIXELFORMAT_RGBA32;
}
// Get rid of preexisting texture
// Limpia
unload();
// The final texture
// La textura final
SDL_Texture *newTexture = NULL;
// Load image at specified path
//SDL_Surface *loadedSurface = IMG_Load(path.c_str());
// Carga la imagen desde una ruta específica
SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void *)data, width, height, depth, pitch, pixel_format);
if (loadedSurface == NULL)
{
@@ -58,10 +70,7 @@ bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
}
else
{
// Color key image
//SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, COLOR_KEY_R, COLOR_KEY_G, COLOR_KEY_B));
// Create texture from surface pixels
// Crea la textura desde los pixels de la surface
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if (newTexture == NULL)
{
@@ -69,73 +78,76 @@ bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
}
else
{
// Get image dimensions
mWidth = loadedSurface->w;
mHeight = loadedSurface->h;
// Obtiene las dimensiones de la imagen
this->width = loadedSurface->w;
this->height = loadedSurface->h;
}
// Get rid of old loaded surface
// Elimina la textura cargada
SDL_FreeSurface(loadedSurface);
}
// Return success
mTexture = newTexture;
return mTexture != NULL;
texture = newTexture;
return texture != NULL;
}
// Crea una textura en blanco
bool LTexture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access)
{
// Create uninitialized texture
mTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
if (mTexture == NULL)
// Crea una textura sin inicializar
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
if (texture == NULL)
{
printf("Unable to create blank texture! SDL Error: %s\n", SDL_GetError());
}
else
{
mWidth = width;
mHeight = height;
this->width = width;
this->height = height;
}
return mTexture != NULL;
return texture != NULL;
}
// Libera la memoria de la textura
void LTexture::unload()
{
// Free texture if it exists
if (mTexture != NULL)
// Libera la textura si existe
if (texture != NULL)
{
SDL_DestroyTexture(mTexture);
mTexture = NULL;
mWidth = 0;
mHeight = 0;
SDL_DestroyTexture(texture);
texture = NULL;
width = 0;
height = 0;
}
}
// Establece el color para la modulacion
void LTexture::setColor(Uint8 red, Uint8 green, Uint8 blue)
{
// Modulate texture rgb
SDL_SetTextureColorMod(mTexture, red, green, blue);
SDL_SetTextureColorMod(texture, red, green, blue);
}
// Establece el blending
void LTexture::setBlendMode(SDL_BlendMode blending)
{
// Set blending function
SDL_SetTextureBlendMode(mTexture, blending);
SDL_SetTextureBlendMode(texture, blending);
}
// Establece el alpha para la modulación
void LTexture::setAlpha(Uint8 alpha)
{
// Modulate texture alpha
SDL_SetTextureAlphaMod(mTexture, alpha);
SDL_SetTextureAlphaMod(texture, alpha);
}
// Renderiza la textura en un punto específico
void LTexture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, float zoomW, float zoomH, double angle, SDL_Point *center, SDL_RendererFlip flip)
{
// Set rendering space and render to screen
SDL_Rect renderQuad = {x, y, mWidth, mHeight};
// Establece el destini de renderizado en la pantalla
SDL_Rect renderQuad = {x, y, width, height};
// Set clip rendering dimensions
// Obtiene las dimesiones del clip de renderizado
if (clip != NULL)
{
renderQuad.w = clip->w;
@@ -145,22 +157,30 @@ void LTexture::render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip, floa
renderQuad.w = renderQuad.w * zoomW;
renderQuad.h = renderQuad.h * zoomH;
// Render to screen
SDL_RenderCopyEx(renderer, mTexture, clip, &renderQuad, angle, center, flip);
// Renderiza a pantalla
SDL_RenderCopyEx(renderer, texture, clip, &renderQuad, angle, center, flip);
}
// Establece la textura como objetivo de renderizado
void LTexture::setAsRenderTarget(SDL_Renderer *renderer)
{
// Make self render target
SDL_SetRenderTarget(renderer, mTexture);
SDL_SetRenderTarget(renderer, texture);
}
// Obtiene el ancho de la imagen
int LTexture::getWidth()
{
return mWidth;
return width;
}
// Obtiene el alto de la imagen
int LTexture::getHeight()
{
return mHeight;
return height;
}
// Recarga la textura
bool LTexture::reLoad()
{
return loadFromFile(path, renderer);
}

View File

@@ -1,66 +1,61 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include <stdio.h>
#include <string>
#ifndef LTEXTURE_H
#define LTEXTURE_H
// Texture wrapper class
// Clase LTexture
class LTexture
{
public:
// Initializes variables
LTexture();
private:
SDL_Texture *texture; // La textura
SDL_Renderer *renderer; // Renderizador donde dibujar la textura
int width; // Ancho de la imagen
int height; // Alto de la imagen
std::string path; // Ruta de la imagen de la textura
// Deallocates memory
public:
// Constructor
LTexture(SDL_Renderer *renderer, std::string path = "");
// Destructor
~LTexture();
// Loads image at specified path
// Carga una imagen desde un fichero
bool loadFromFile(std::string path, SDL_Renderer *renderer);
// Creates blank texture
// Crea una textura en blanco
bool createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING);
// Deallocates texture
// Libera la memoria de la textura
void unload();
// Set color modulation
// Establece el color para la modulacion
void setColor(Uint8 red, Uint8 green, Uint8 blue);
// Set blending
// Establece el blending
void setBlendMode(SDL_BlendMode blending);
// Set alpha modulation
// Establece el alpha para la modulación
void setAlpha(Uint8 alpha);
// Renders texture at given point
// Renderiza la textura en un punto específico
void render(SDL_Renderer *renderer, int x, int y, SDL_Rect *clip = NULL, float zoomW = 1, float zoomH = 1, double angle = 0.0, SDL_Point *center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE);
// Set self as render target
// Establece la textura como objetivo de renderizado
void setAsRenderTarget(SDL_Renderer *renderer);
// Gets image dimensions
// Obtiene el ancho de la imagen
int getWidth();
// Obtiene el alto de la imagen
int getHeight();
// Pixel manipulators
bool lockTexture();
bool unlockTexture();
void *getPixels();
void copyPixels(void *pixels);
int getPitch();
Uint32 getPixel32(unsigned int x, unsigned int y);
private:
// The actual hardware texture
SDL_Texture *mTexture;
void *mPixels;
int mPitch;
// Image dimensions
int mWidth;
int mHeight;
// Recarga la textura
bool reLoad();
};
#endif

View File

@@ -1,7 +1,7 @@
/*
Código fuente creado por JailDesigner
Empezado en Castalla el 06/09/2021.
Empezado en Castalla el 01/07/2022.
*/

View File

@@ -1,599 +0,0 @@
#include "const.h"
#include "menu.h"
// Constructor
Menu::Menu(SDL_Renderer *renderer, Text *text, Input *input, std::string *fileList)
{
mRenderer = renderer;
mText = text;
mInput = input;
mFileList = fileList;
}
Menu::~Menu()
{
mRenderer = nullptr;
mText = nullptr;
mInput = nullptr;
mFileList = nullptr;
}
// Inicializador
void Menu::init(std::string name, int x, int y, int backgroundType)
{
loadMedia();
// Inicia variables
mName = name;
mSelector.index = 0;
mTotalItems = 0;
mItemSelected = MENU_NO_OPTION;
mPosX = x;
mPosY = y;
mRectBG.rect.x = 0;
mRectBG.rect.y = 0;
mRectBG.rect.w = 0;
mRectBG.rect.h = 0;
mRectBG.r = 0;
mRectBG.g = 0;
mRectBG.b = 0;
mBackgroundType = backgroundType;
mIsCenteredOnX = false;
mIsCenteredOnY = false;
mAreElementsCenteredOnX = false;
mCenterX = 0;
mCenterY = 0;
mWidestItem = 0;
mColorGreyed = {128, 128, 128};
// Selector
mSelector.originY = 0;
mSelector.targetY = 0;
mSelector.despY = 0;
mSelector.originH = 0;
mSelector.targetH = 0;
mSelector.incH = 0;
mSelector.y = 0.0f;
mSelector.h = 0.0f;
mSelector.numJumps = 8;
mSelector.moving = false;
mSelector.resizing = false;
mSelector.rect = {0, 0, 0, 0};
mSelector.r = 0;
mSelector.g = 0;
mSelector.b = 0;
mSelector.a = 255;
// Elementos del menu
for (int i = 0; i < MENU_MAX_ITEMS; i++)
{
mItem[i].label = "";
mItem[i].rect = {0, 0, 0, 0};
mItem[i].hPaddingDown = 0;
mItem[i].selectable = false;
mItem[i].greyed = false;
mItem[i].linkedDown = false;
mItem[i].linkedUp = false;
}
}
// Carga los recursos necesarios para la sección 'Title'
bool Menu::loadMedia()
{
// Indicador de éxito en la carga
bool success = true;
// Sonidos
mSoundMove = JA_LoadSound(mFileList[17].c_str());
mSoundAccept = JA_LoadSound(mFileList[18].c_str());
mSoundCancel = JA_LoadSound(mFileList[16].c_str());
return success;
}
// Obtiene el nombre del menu
std::string Menu::getName()
{
return mName;
}
// Obtiene el valor de la variable
Uint8 Menu::getItemSelected()
{
// Al llamar a esta funcion, se obtiene el valor y se borra
const int temp = mItemSelected;
mItemSelected = MENU_NO_OPTION;
return temp;
}
// Actualiza la posicion y el estado del selector
void Menu::updateSelector()
{
if (mSelector.moving)
{
// Calcula el desplazamiento en Y
mSelector.y += mSelector.despY;
if (mSelector.despY > 0) // Va hacia abajo
{
if (mSelector.y > mSelector.targetY) // Ha llegado al destino
{
mSelector.originY = mSelector.y = mSelector.targetY;
mSelector.moving = false;
}
}
if (mSelector.despY < 0) // Va hacia arriba
{
if (mSelector.y < mSelector.targetY) // Ha llegado al destino
{
mSelector.originY = mSelector.y = mSelector.targetY;
mSelector.moving = false;
}
}
mSelector.rect.y = int(mSelector.y);
}
else
{
mSelector.rect.y = int(mSelector.y);
}
if (mSelector.resizing)
{
// Calcula el incremento en H
mSelector.h += mSelector.incH;
if (mSelector.incH > 0) // Crece
{
if (mSelector.h > mSelector.targetH) // Ha llegado al destino
{
//mSelector.originH = mSelector.targetH = mSelector.rect.h = getSelectorHeight(mSelector.index);
mSelector.originH = mSelector.h = mSelector.targetH;
mSelector.resizing = false;
}
}
if (mSelector.incH < 0) // Decrece
{
if (mSelector.h < mSelector.targetH) // Ha llegado al destino
{
//mSelector.originH = mSelector.targetH = mSelector.rect.h = getSelectorHeight(mSelector.index);
mSelector.originH = mSelector.h = mSelector.targetH;
mSelector.resizing = false;
}
}
mSelector.rect.h = int(mSelector.h);
}
else
{
mSelector.rect.h = getSelectorHeight(mSelector.index);
}
}
// Coloca el selector en una posición específica
void Menu::setSelectorPos(Uint8 index)
{
if (index < mTotalItems)
{
mSelector.index = index;
mSelector.rect.y = mSelector.y = mSelector.originY = mSelector.targetY = mItem[mSelector.index].rect.y;
mSelector.rect.w = mRectBG.rect.w;
mSelector.rect.x = mRectBG.rect.x;
mSelector.originH = mSelector.targetH = mSelector.rect.h = getSelectorHeight(mSelector.index);
mSelector.moving = false;
mSelector.resizing = false;
}
}
// Obtiene la anchura del elemento más ancho del menu
Uint16 Menu::getWidestItem()
{
Uint16 result = 0;
// Obtenemos la anchura del item mas ancho
for (int i = 0; i < mTotalItems; i++)
if (mItem[i].rect.w > result)
result = mItem[i].rect.w;
return result;
}
// Deja el menu apuntando al primer elemento
void Menu::reset()
{
mItemSelected = MENU_NO_OPTION;
mSelector.index = 0;
mSelector.originY = mSelector.targetY = mSelector.y = mItem[0].rect.y;
mSelector.originH = mSelector.targetH = mItem[0].rect.h;
mSelector.moving = false;
mSelector.resizing = false;
}
// Actualiza el menu para recolocarlo correctamente y establecer el tamaño
void Menu::reorganize()
{
setRectSize();
if (mIsCenteredOnX)
centerMenuOnX(mCenterX);
if (mIsCenteredOnY)
centerMenuOnY(mCenterY);
if (mAreElementsCenteredOnX)
centerMenuElementsOnX();
}
// Deja el menu apuntando al siguiente elemento
bool Menu::increaseSelectorIndex()
{
bool success = false;
// Obten las coordenadas del elemento actual
mSelector.y = mSelector.originY = mItem[mSelector.index].rect.y;
mSelector.h = mSelector.originH = getSelectorHeight(mSelector.index);
// Calcula cual es el siguiente elemento
//if (mSelector.index < (mTotalItems - 1))
//{
// mSelector.index++;
// while ((!mItem[mSelector.index].selectable) && (mSelector.index < (mTotalItems - 1)))
// mSelector.index++;
// success = true;
//}
// Calcula cual es el siguiente elemento (versión con loop)
//if (mSelector.index < (mTotalItems - 1))
{
++mSelector.index %= mTotalItems;
while (!mItem[mSelector.index].selectable)
//mSelector.index++;
++mSelector.index %= mTotalItems;
success = true;
}
if (success)
{ // Establece las coordenadas y altura de destino
mSelector.targetY = mItem[mSelector.index].rect.y;
mSelector.despY = (mSelector.targetY - mSelector.originY) / mSelector.numJumps;
mSelector.targetH = getSelectorHeight(mSelector.index);
mSelector.incH = (mSelector.targetH - mSelector.originH) / mSelector.numJumps;
mSelector.moving = true;
if (mSelector.incH != 0)
mSelector.resizing = true;
}
return success;
}
// Deja el menu apuntando al elemento anterior
bool Menu::decreaseSelectorIndex()
{
bool success = false;
// Obten las coordenadas del elemento actual
mSelector.y = mSelector.originY = mItem[mSelector.index].rect.y;
mSelector.h = mSelector.originH = getSelectorHeight(mSelector.index);
// Calcula cual es el siguiente elemento
//if (mSelector.index > 0)
//{
// mSelector.index--;
// while ((!mItem[mSelector.index].selectable) && (mSelector.index > 0))
// mSelector.index--;
// success = true;
//}
// Calcula cual es el siguiente elemento (versión con loop)
//if (mSelector.index > 0)
{
if (mSelector.index == 0)
mSelector.index = mTotalItems;
else
mSelector.index--;
while (!mItem[mSelector.index].selectable)
{
if (mSelector.index == 0)
mSelector.index = mTotalItems;
else
mSelector.index--;
}
success = true;
}
if (success)
{ // Establece las coordenadas y altura de destino
mSelector.targetY = mItem[mSelector.index].rect.y;
mSelector.despY = (mSelector.targetY - mSelector.originY) / mSelector.numJumps;
mSelector.targetH = getSelectorHeight(mSelector.index);
mSelector.incH = (mSelector.targetH - mSelector.originH) / mSelector.numJumps;
mSelector.moving = true;
if (mSelector.incH != 0)
mSelector.resizing = true;
}
return success;
}
// Actualiza la logica del menu
void Menu::update()
{
updateSelector();
}
// Pinta el menu en pantalla
void Menu::render()
{
// Rendereritza el fondo del menu
if (mBackgroundType == MENU_BACKGROUND_SOLID)
{
SDL_SetRenderDrawColor(mRenderer, mRectBG.r, mRectBG.g, mRectBG.b, mRectBG.a);
SDL_RenderFillRect(mRenderer, &mRectBG.rect);
}
// Renderiza el rectangulo del selector
SDL_Rect temp = mSelector.rect;
temp.y--;
temp.h++;
SDL_SetRenderDrawColor(mRenderer, mSelector.r, mSelector.g, mSelector.b, mSelector.a);
SDL_RenderFillRect(mRenderer, &temp);
// Renderiza el borde del fondo
if (mBackgroundType == MENU_BACKGROUND_SOLID)
{
SDL_SetRenderDrawColor(mRenderer, mRectBG.r, mRectBG.g, mRectBG.b, 255);
SDL_RenderDrawRect(mRenderer, &mRectBG.rect);
}
// Renderitza el texto
for (int i = 0; i < mTotalItems; i++)
{
if (i == mSelector.index)
{
const color_t color = {mSelector.itemR, mSelector.itemG, mSelector.itemB};
mText->writeColored(mItem[i].rect.x, mItem[i].rect.y, mItem[i].label, color);
}
else if (mItem[i].selectable)
{
mText->write(mItem[i].rect.x, mItem[i].rect.y, mItem[i].label);
}
else if (mItem[i].greyed)
{
mText->writeColored(mItem[i].rect.x, mItem[i].rect.y, mItem[i].label, mColorGreyed);
}
else // No seleccionable
{
if ((mItem[i].linkedUp) && (i == mSelector.index + 1))
{
const color_t color = {mSelector.itemR, mSelector.itemG, mSelector.itemB};
mText->writeColored(mItem[i].rect.x, mItem[i].rect.y, mItem[i].label, color);
}
else // No enlazado con el de arriba
{
mText->write(mItem[i].rect.x, mItem[i].rect.y, mItem[i].label);
}
}
//borrar
//mText->write(0, 0, std::to_string(mSelector.h) + " " + std::to_string(mSelector.incH) + " " + std::to_string(mSelector.resizing));
//mText->write(0, 8, std::to_string(mSelector.y) + " " + std::to_string(mSelector.despY) + " " + std::to_string(mSelector.moving));
}
}
// Establece el rectangulo de fondo del menu y el selector
void Menu::setRectSize()
{
mRectBG.rect.w = findWidth() + mText->getCharacterWidth();
mRectBG.rect.h = findHeight() + mText->getCharacterWidth();
// La posición X es la del menú menos medio caracter
mRectBG.rect.x = mPosX - (mText->getCharacterWidth() / 2);
// La posición Y es la del menu menos la altura de medio caracter
mRectBG.rect.y = mPosY - (mText->getCharacterWidth() / 2);
// Establecemos los valores del rectangulo del selector a partir de los valores del rectangulo de fondo
setSelectorPos(mSelector.index);
}
// Establece el valor de la variable
void Menu::setTotalItems(int num)
{
mTotalItems = num;
if (mTotalItems > MENU_MAX_ITEMS)
mTotalItems = MENU_MAX_ITEMS;
}
// Establece el color del rectangulo de fondo
void Menu::setBackgroundColor(int r, int g, int b, int alpha)
{
mRectBG.r = r;
mRectBG.g = g;
mRectBG.b = b;
mRectBG.a = alpha;
}
// Establece el color del rectangulo del selector
void Menu::setSelectorColor(int r, int g, int b, int alpha)
{
mSelector.r = r;
mSelector.g = g;
mSelector.b = b;
mSelector.a = alpha;
}
// Establece el color del texto del selector
void Menu::setSelectorTextColor(int r, int g, int b)
{
mSelector.itemR = r;
mSelector.itemG = g;
mSelector.itemB = b;
}
// Centra el menu respecto un punto en el eje X
void Menu::centerMenuOnX(int value)
{
mIsCenteredOnX = true;
mCenterX = value;
// Actualiza el rectangulo de fondo para recalcular las dimensiones
//setRectSize();
// Establece la nueva posición centrada en funcion del elemento más ancho
mPosX = (value) - (findWidth() / 2);
// Reposiciona los elementos del menu
for (int i = 0; i < MENU_MAX_ITEMS; i++)
mItem[i].rect.x = mPosX;
// Recalcula el rectangulo de fondo
setRectSize();
}
// Centra el menu respecto un punto en el eje Y
void Menu::centerMenuOnY(int value)
{
mIsCenteredOnY = true;
mCenterY = value;
// Actualiza el rectangulo de fondo para recalcular las dimensiones
//setRectSize();
// Establece la nueva posición centrada en funcion del elemento más ancho
mPosY = (value) - (findHeight() / 2);
// Reposiciona los elementos del menu
replaceElementsOnY();
// Recalcula el rectangulo de fondo
setRectSize();
}
// Centra los elementos del menu en el eje X
void Menu::centerMenuElementsOnX()
{
mAreElementsCenteredOnX = true;
for (int i = 0; i < mTotalItems; i++)
mItem[i].rect.x = (mCenterX - (mItem[i].rect.w / 2));
}
// Añade un item al menu
void Menu::addItem(std::string text, Uint8 hPaddingDown, bool selectable, bool greyed, bool linkedDown)
{
// Si es el primer item coge la posición en el eje Y del propio menu
if (mTotalItems == 0)
mItem[mTotalItems].rect.y = mPosY;
else
// En caso contrario, coge la posición en el eje Y a partir del elemento anterior
mItem[mTotalItems].rect.y = mItem[mTotalItems - 1].rect.y + mItem[mTotalItems - 1].rect.h + mItem[mTotalItems - 1].hPaddingDown;
setItemCaption(mTotalItems, text);
mItem[mTotalItems].rect.x = mPosX;
mItem[mTotalItems].hPaddingDown = hPaddingDown;
mItem[mTotalItems].selectable = selectable;
mItem[mTotalItems].greyed = greyed;
mItem[mTotalItems].linkedDown = linkedDown;
if (mTotalItems > 0)
if (mItem[mTotalItems - 1].linkedDown)
mItem[mTotalItems].linkedUp = true;
setTotalItems(mTotalItems + 1);
mCenterX = mPosX + (findWidth() / 2);
//setSelectorPos(0);
reorganize();
}
// Cambia el texto de un item
void Menu::setItemCaption(Uint8 index, std::string text)
{
mItem[index].label = text;
mItem[index].rect.w = mText->lenght(mItem[index].label);
mItem[index].rect.h = mText->getCharacterWidth();
reorganize();
}
// Establece el indice del itemm que se usará por defecto al cancelar el menu
void Menu::setDefaultActionWhenCancel(Uint8 item)
{
mDefaultActionWhenCancel = item;
}
// Gestiona la entrada de teclado y mando durante el menu
void Menu::checkInput()
{
if (mInput->checkInput(INPUT_UP, REPEAT_FALSE))
{
if (decreaseSelectorIndex())
JA_PlaySound(mSoundMove);
}
if (mInput->checkInput(INPUT_DOWN, REPEAT_FALSE))
{
if (increaseSelectorIndex())
JA_PlaySound(mSoundMove);
}
if (mInput->checkInput(INPUT_ACCEPT, REPEAT_FALSE))
{
mItemSelected = mSelector.index;
JA_PlaySound(mSoundAccept);
}
if (mInput->checkInput(INPUT_CANCEL, REPEAT_FALSE))
{
mItemSelected = mDefaultActionWhenCancel;
JA_PlaySound(mSoundCancel);
}
}
// Calcula el ancho del menu
Uint16 Menu::findWidth()
{
return getWidestItem();
}
// Calcula el alto del menu
Uint16 Menu::findHeight()
{
Uint16 height = 0;
// Obtenemos la altura de la suma de alturas de los items
for (int i = 0; i < mTotalItems; i++)
height += mItem[i].rect.h + mItem[i].hPaddingDown;
return height - mItem[mTotalItems - 1].hPaddingDown;
}
// Recoloca los elementos del menu en el eje Y
void Menu::replaceElementsOnY()
{
mItem[0].rect.y = mPosY;
for (int i = 1; i < mTotalItems; i++)
mItem[i].rect.y = mItem[i - 1].rect.y + mItem[i - 1].rect.h + mItem[i - 1].hPaddingDown;
}
// Establece el estado seleccionable de un item
void Menu::setSelectable(Uint8 index, bool value)
{
mItem[index].selectable = value;
}
// Establece el estado agrisado de un item
void Menu::setGreyed(Uint8 index, bool value)
{
mItem[index].greyed = value;
}
// Establece el estado de enlace de un item
void Menu::setLinkedDown(Uint8 index, bool value)
{
mItem[index].linkedDown = value;
}
// Calcula la altura del selector
int Menu::getSelectorHeight(int value)
{
if (mItem[value].linkedDown)
return mItem[value].rect.h + mItem[value].hPaddingDown + mItem[value + 1].rect.h;
else
return mItem[value].rect.h;
}

View File

@@ -1,200 +0,0 @@
#pragma once
#include "ifdefs.h"
#include "sprite.h"
#include "text.h"
#include "input.h"
#include "jail_audio.h"
#ifndef MENU_H
#define MENU_H
#define MENU_MAX_ITEMS 50
#define MENU_NO_OPTION -1
#define MENU_BACKGROUND_TRANSPARENT 0
#define MENU_BACKGROUND_SOLID 1
// Clase menu
class Menu
{
private:
std::string mName; // Nombre del menu
int mPosX; // Posición en el eje X de la primera letra del primer elemento
int mPosY; // Posición en el eje Y de la primera letra del primer elemento
Uint16 mHeight; // Altura del menu
Uint16 mWidth; // Anchura del menu
Uint8 mTotalItems; // Numero total de items del menu
int mItemSelected; // Índice del item del menu que ha sido seleccionado
Uint8 mDefaultActionWhenCancel; // Indice del item del menu que se selecciona cuando se cancela el menu
Uint8 mBackgroundType; // Tipo de fondo para el menu
bool mIsCenteredOnX; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje X
bool mIsCenteredOnY; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y
int mCenterX; // Centro del menu en el eje X
int mCenterY; // Centro del menu en el eje Y
bool mAreElementsCenteredOnX; // Variable para saber si los elementos van centrados en el eje X
Uint16 mWidestItem; // Anchura del elemento más ancho
JA_Sound mSoundAccept; // Sonido al aceptar o elegir una opción del menu
JA_Sound mSoundCancel; // Sonido al cancelar el menu
JA_Sound mSoundMove; // Sonido al mover el selector
SDL_Renderer *mRenderer; // Puntero al renderizador de la ventana
std::string *mFileList; // Lista de ficheros
Text *mText; // Texto para poder escribir los items del menu
Input *mInput; // Gestor de eventos de entrada de teclado o gamepad
color_t mColorGreyed; // Color para los elementos agrisados
struct rectangle
{
SDL_Rect rect; // Rectangulo
Uint8 r; // Rojo
Uint8 g; // Verde
Uint8 b; // Azul
Uint8 a; // Transparencia
};
rectangle mRectBG; // Rectangulo de fondo del menu
struct item
{
std::string label; // Texto
SDL_Rect rect; // Rectangulo que delimita el elemento
Uint8 hPaddingDown; // Espaciado bajo el elemento
bool selectable; // Indica si se puede seleccionar
bool greyed; // Indica si ha de aparecer con otro color mas oscuro
bool linkedDown; // Indica si el elemento actual y el siguiente se tratan como uno solo. Afecta al selector
bool linkedUp; // Indica si el elemento actual y el anterior se tratan como uno solo. Afecta al selector
};
item mItem[MENU_MAX_ITEMS]; // Estructura para cada elemento del menu
struct selector
{
float originY; // Coordenada de origen
float targetY; // Coordenada de destino
float despY; // Cantidad de pixeles que se desplaza el selector en cada salto: (target - origin) / numJumps
bool moving; // Indica si el selector está avanzando hacia el destino
float originH; // Altura de origen
float targetH; // Altura de destino
float incH; // Cantidad de pixels que debe incrementar o decrementar el selector en cada salto
bool resizing; // Indica si el selector está cambiando de tamaño
float y; // Coordenada actual, usado para el desplazamiento
float h; // Altura actual, usado para el cambio de tamaño
Uint8 numJumps; // Numero de pasos preestablecido para llegar al destino
Uint8 index; // Elemento del menu que tiene el foco
SDL_Rect rect; // Rectangulo del selector
Uint8 r; // Cantidad de color rojo para el rectangulo del selector
Uint8 g; // Cantidad de color verde para el rectangulo del selector
Uint8 b; // Cantidad de color azul para el rectangulo del selector
Uint8 a; // Cantidad de transparencia para el rectangulo del selector
Uint8 itemR; // Cantidad de color rojo para el texto del elemento seleccionado
Uint8 itemG; // Cantidad de color verde para el texto del elemento seleccionado
Uint8 itemB; // Cantidad de color azul para el texto del elemento seleccionado
};
selector mSelector; // Variables para pintar el selector del menu
// Carga los recursos necesarios para la sección 'Title'
bool loadMedia();
// Establece el valor de la variable
void setTotalItems(int num);
// Establece el rectangulo de fondo del menu
void setRectSize();
// Actualiza el menu para recolocarlo correctamente y establecer el tamaño
void reorganize();
// Deja el menu apuntando al siguiente elemento
bool increaseSelectorIndex();
// Deja el menu apuntando al elemento anterior
bool decreaseSelectorIndex();
// Actualiza la posicion y el estado del selector
void updateSelector();
// Obtiene la anchura del elemento más ancho del menu
Uint16 getWidestItem();
// Gestiona la entrada de teclado y mando durante el menu
void checkMenuInput(Menu *menu);
// Calcula el ancho del menu
Uint16 findWidth();
// Calcula el alto del menu
Uint16 findHeight();
// Recoloca los elementos del menu en el eje Y
void replaceElementsOnY();
// Calcula la altura del selector
int getSelectorHeight(int value);
public:
// Constructor
Menu(SDL_Renderer *renderer, Text *text, Input *input, std::string *fileList);
// Destructor
~Menu();
// Inicializador
void init(std::string name, int x, int y, int backgroundType);
// Obtiene el nombre del menu
std::string getName();
// Obtiene el valor de la variable
Uint8 getItemSelected();
// Deja el menu apuntando al primer elemento
void reset();
// Gestiona la entrada de teclado y mando durante el menu
void checkInput();
// Actualiza la logica del menu
void update();
// Pinta el menu en pantalla
void render();
// Establece el color del rectangulo de fondo
void setBackgroundColor(int r, int g, int b, int alpha);
// Establece el color del rectangulo del selector
void setSelectorColor(int r, int g, int b, int alpha);
// Establece el color del texto del selector
void setSelectorTextColor(int r, int g, int b);
// Centra el menu respecto a un punto en el eje X
void centerMenuOnX(int value);
// Centra el menu respecto a un punto en el eje Y
void centerMenuOnY(int value);
// Centra los elementos del menu en el eje X
void centerMenuElementsOnX();
// Añade un item al menu
void addItem(std::string text, Uint8 hPaddingDown = 1, bool selectable = true, bool greyed = false, bool linkedDown = false);
// Cambia el texto de un item
void setItemCaption(Uint8 index, std::string text);
// Establece el indice del item que se usará por defecto al cancelar el menu
void setDefaultActionWhenCancel(Uint8 item);
// Coloca el selector en una posición específica
void setSelectorPos(Uint8 index);
// Establece el estado seleccionable de un item
void setSelectable(Uint8 index, bool value);
// Establece el estado agrisado de un item
void setGreyed(Uint8 index, bool value);
// Establece el estado de enlace de un item
void setLinkedDown(Uint8 index, bool value);
};
#endif

View File

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

View File

@@ -1,5 +1,6 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "sprite.h"
#ifndef MOVINGSPRITE_H
@@ -9,34 +10,36 @@
class MovingSprite : public Sprite
{
protected:
float mPosX; // Posición en el eje X
float mPosY; // Posición en el eje Y
float x; // Posición en el eje X
float y; // Posición en el eje Y
float mVelX; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
float mVelY; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
float xPrev; // Posición anterior en el eje X
float yPrev; // Posición anterior en el eje Y
float mAccelX; // Aceleración en el eje X. Variación de la velocidad
float mAccelY; // Aceleración en el eje Y. Variación de la velocidad
float vx; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
float vy; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
float mZoomW; // Zoom aplicado a la anchura
float mZoomH; // Zoom aplicado a la altura
float ax; // Aceleración en el eje X. Variación de la velocidad
float ay; // Aceleración en el eje Y. Variación de la velocidad
double mAngle; // Angulo para dibujarlo
bool mRotate; // Indica si ha de rotar
Uint16 mRotateSpeed; // Velocidad de giro
double mRotateAmount; // Cantidad de grados a girar en cada iteración
Uint16 mCounter; // Contador interno
float zoomW; // Zoom aplicado a la anchura
float zoomH; // Zoom aplicado a la altura
double angle; // Angulo para dibujarlo
bool rotateEnabled; // Indica si ha de rotar
int rotateSpeed; // Velocidad de giro
double rotateAmount; // Cantidad de grados a girar en cada iteración
int counter; // Contador interno
SDL_Point center; // Centro de rotación
SDL_RendererFlip currentFlip; // Indica como se voltea el sprite
public:
// Constructor
MovingSprite();
MovingSprite(float x = 0, float y = 0, int w = 0, int h = 0, float velx = 0, float vely = 0, float accelx = 0, float accely = 0, LTexture *texture = nullptr, SDL_Renderer *renderer = nullptr);
// Destructor
~MovingSprite();
// Iniciador
void init(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, LTexture *texture, SDL_Renderer *renderer);
// Mueve el sprite
void move();
@@ -85,44 +88,47 @@ public:
// Obtiene el valor de la variable
Uint16 getRotateSpeed();
// Establece el valor de la variable
void setPosX(float x);
// Establece la posición del objeto
void setPos(SDL_Rect rect);
// Establece el valor de la variable
void setPosY(float y);
void setPosX(float value);
// Establece el valor de la variable
void setVelX(float x);
void setPosY(float value);
// Establece el valor de la variable
void setVelY(float y);
void setVelX(float value);
// Establece el valor de la variable
void setAccelX(float x);
void setVelY(float value);
// Establece el valor de la variable
void setAccelY(float y);
void setAccelX(float value);
// Establece el valor de la variable
void setZoomW(float w);
void setAccelY(float value);
// Establece el valor de la variable
void setZoomH(float h);
void setZoomW(float value);
// Establece el valor de la variable
void setAngle(double a);
void setZoomH(float value);
// Establece el valor de la variable
void setAngle(double vaue);
// Incrementa el valor de la variable
void incAngle(double inc);
void incAngle(double value);
// Decrementa el valor de la variable
void decAngle(double dec);
void decAngle(double value);
// Establece el valor de la variable
void setRotate(bool value);
// Establece el valor de la variable
void setRotateSpeed(Uint16 value);
void setRotateSpeed(int value);
// Establece el valor de la variable
void setRotateAmount(double value);
@@ -132,6 +138,36 @@ public:
// Cambia el sentido de la rotación
void switchRotate();
// Establece el valor de la variable
void setFlip(SDL_RendererFlip flip);
// Gira el sprite horizontalmente
void flip();
// Obtiene el valor de la variable
SDL_RendererFlip getFlip();
// Devuelve el rectangulo donde está el sprite
SDL_Rect getRect();
// Establece los valores de posición y tamaño del sprite
void setRect(SDL_Rect rect);
// Deshace el último movimiento
void undoMove();
// Deshace el último movimiento en el eje X
void undoMoveX();
// Deshace el último movimiento en el eje Y
void undoMoveY();
// Pone a cero las velocidades de desplacamiento
void clearVel();
// Devuelve el incremento en el eje X en pixels
int getIncX();
};
#endif

View File

@@ -2,46 +2,292 @@
#include <fstream>
#include <sstream>
// CAUTION!!!!! si no se gasta al final, quitar la referencia a la habitación
// Constructor
Player::Player(std::string _tileset, SDL_Renderer *_renderer, Asset *_asset)
Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room)
{
// Obten punteros a objetos
asset = _asset;
renderer = _renderer;
this->asset = asset;
this->renderer = renderer;
this->input = input;
// Crea objetos
texture = new LTexture();
sprite = new AnimatedSprite(texture, renderer);
// Carga la textura
loadTextureFromFile(texture, asset->get(_tileset), renderer);
texture = new LTexture(renderer, asset->get(tileset));
sprite = new AnimatedSprite(texture, renderer, animation);
// Inicializa variables
color = stringToColor("white");
onBorder = false;
border = BORDER_TOP;
jump_ini = ini.jump_ini;
status = ini.status;
sprite->setPosX(ini.x);
sprite->setPosY(ini.y);
sprite->setVelX(ini.vx);
sprite->setVelY(ini.vy);
sprite->setWidth(8);
sprite->setHeight(16);
sprite->setFlip(ini.flip);
lastPosition = getRect();
collider = getRect();
}
// Destructor
Player::~Player()
{
texture->unload();
delete texture;
texture = nullptr;
delete sprite;
sprite = nullptr;
}
// Pinta el enemigo en pantalla
void Player::draw()
// Pinta el jugador en pantalla
void Player::render()
{
sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->render();
sprite->getTexture()->setColor(255, 255, 255);
}
// Actualiza las variables del objeto
void Player::update()
{
sprite->update();
sprite->animate(0);
setLastPosition(); // Guarda la posición actual en la variable lastPosition
checkInput(); // Comprueba las entradas y modifica variables
move(); // Recalcula la posición del jugador y su animación
checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación
applyGravity(); // Aplica gravedad al jugador
checkJump(); // Comprueba si ha finalizado el salto
collider = getRect(); // Obtiene el rectangulo que delimita al jugador
}
// Comprueba las entradas y modifica variables
void Player::checkInput()
{
// Solo comprueba las entradas de dirección cuando está de pie
if ((input->checkInput(INPUT_LEFT, REPEAT_TRUE)) && (status == STATUS_STANDING))
{
sprite->setVelX(-0.6f);
sprite->setFlip(SDL_FLIP_HORIZONTAL);
}
else if ((input->checkInput(INPUT_RIGHT, REPEAT_TRUE)) && (status == STATUS_STANDING))
{
sprite->setVelX(0.6f);
sprite->setFlip(SDL_FLIP_NONE);
}
else if (status == STATUS_STANDING)
{
sprite->setVelX(0);
}
if (input->checkInput(INPUT_UP, REPEAT_TRUE))
{
setStatus(STATUS_JUMPING);
}
}
// Indica si el jugador esta en uno de los cuatro bordes de la pantalla
bool Player::getOnBorder()
{
return onBorder;
}
// Indica en cual de los cuatro bordes se encuentra
int Player::getBorder()
{
return border;
}
// Comprueba si está situado en alguno de los cuatro bordes de la habitación
void Player::checkBorders()
{
if (sprite->getPosX() < PLAY_AREA_LEFT)
{
border = BORDER_LEFT;
onBorder = true;
}
else if (sprite->getPosX() > PLAY_AREA_RIGHT - sprite->getWidth())
{
border = BORDER_RIGHT;
onBorder = true;
}
else if (sprite->getPosY() < PLAY_AREA_TOP)
{
border = BORDER_TOP;
onBorder = true;
}
else if (sprite->getPosY() > PLAY_AREA_BOTTOM - sprite->getHeight())
{
border = BORDER_BOTTOM;
onBorder = true;
}
else
{
onBorder = false;
}
}
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
void Player::switchBorders()
{
if (border == BORDER_TOP)
{
sprite->setPosY(PLAY_AREA_BOTTOM - sprite->getHeight() - 1);
jump_ini += 128;
}
else if (border == BORDER_BOTTOM)
{
sprite->setPosY(PLAY_AREA_TOP + 1);
}
else if (border == BORDER_RIGHT)
{
sprite->setPosX(PLAY_AREA_LEFT + 1);
}
if (border == BORDER_LEFT)
{
sprite->setPosX(PLAY_AREA_RIGHT - sprite->getWidth() - 1);
}
onBorder = false;
}
// Obtiene el valor del pixel inferior izquierdo del jugador
SDL_Point Player::getLeftFoot()
{
SDL_Point point = {(int)sprite->getPosX(), (int)sprite->getPosY() + sprite->getHeight()};
return point;
}
// Obtiene el valor del pixel inferior derecho del jugador
SDL_Point Player::getRightFoot()
{
SDL_Point point = {(int)sprite->getPosX() + sprite->getWidth() - 1, (int)sprite->getPosY() + sprite->getHeight()};
return point;
}
// Cambia el estado del jugador
void Player::setStatus(int value)
{
// Si quiere cambiar a saltando, ha de ser desde quieto
if ((value == STATUS_JUMPING) && (status == STATUS_STANDING))
{
status = STATUS_JUMPING;
sprite->setVelY(-MAX_VY);
jump_ini = sprite->getPosY();
}
// Modifica el estado a 'cayendo'
if (value == STATUS_FALLING)
{
status = STATUS_FALLING;
sprite->setVelY(MAX_VY);
sprite->setVelX(0);
}
// Modifica el estado a 'de pie'
if (value == STATUS_STANDING)
{
status = STATUS_STANDING;
sprite->setVelY(0.0f);
}
}
// Obtiene el estado del jugador
int Player::getStatus()
{
return status;
}
// Obtiene la velocidad en el eje Y del jugador
float Player::getVelY()
{
return sprite->getVelY();
}
// Aplica gravedad al jugador
void Player::applyGravity()
{
if (status == STATUS_JUMPING)
{
sprite->setVelY(sprite->getVelY() + GRAVITY);
if (sprite->getVelY() > MAX_VY)
{
sprite->setVelY(MAX_VY);
}
}
}
// Obtiene el rectangulo que delimita al jugador
SDL_Rect Player::getRect()
{
return sprite->getRect();
}
// Obtiene el rectangulo de colision del jugador
SDL_Rect &Player::getCollider()
{
return collider;
}
// Guarda la posición actual en la variable lastPosition
void Player::setLastPosition()
{
lastPosition = getRect();
}
// Deshace el ultimo movimiento
void Player::undoLastMove()
{
sprite->setPosX(lastPosition.x);
sprite->setPosY(lastPosition.y);
}
// Recalcula la posición del jugador y su animación
void Player::move()
{
sprite->update();
if (sprite->getVelX() != 0)
{
sprite->setCurrentAnimation("walk");
}
else
{
sprite->setCurrentAnimation("stand");
}
}
// Comprueba si ha finalizado el salto
void Player::checkJump()
{
if (status == STATUS_JUMPING)
if (sprite->getVelY() > 0)
if (sprite->getPosY() > jump_ini)
{
setStatus(STATUS_FALLING);
}
}
// Obtiene algunos parametros del jugador
player_t Player::getSpawnParams()
{
player_t params;
params.x = sprite->getPosX();
params.y = sprite->getPosY();
params.vx = sprite->getVelX();
params.vy = sprite->getVelY();
params.jump_ini = jump_ini;
params.status = status;
params.flip = sprite->getFlip();
return params;
}
// Recarga la textura
void Player::reLoadTexture()
{
texture->reLoad();
}

View File

@@ -1,37 +1,128 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "utils.h"
#include "asset.h"
#include "room.h"
#include "animatedsprite.h"
#include "input.h"
#include "const.h"
#include <string>
#ifndef PLAYER_H
#define PLAYER_H
//#define VX 0.6
#define STATUS_STANDING 0
#define STATUS_JUMPING 1
#define STATUS_FALLING 2
#define GRAVITY 0.035f
#define MAX_VY 1.2f
struct player_t
{
float x;
float y;
float vx;
float vy;
int jump_ini;
int status;
SDL_RendererFlip flip;
};
// Clase Player
class Player
{
private:
LTexture *texture; // Textura con los graficos del enemigo
AnimatedSprite *sprite; // Sprite del enemigo
Input *input; // Objeto para gestionar la entrada
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
color_t color; // Color del jugador
SDL_Rect collider; // Caja de colisión
bool onBorder; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla
int border; // Indica en cual de los cuatro bordes se encuentra
// Comprueba las entradas y modifica variables
void checkInput();
// Comprueba si se halla en alguno de los cuatro bordes
void checkBorders();
// Asigna velocidad negativa en el eje Y al jugador
void jump();
// Aplica gravedad al jugador
void applyGravity();
// Guarda la posición actual en la variable lastPosition
void setLastPosition();
// Recalcula la posición del jugador y su animación
void move();
// Comprueba si ha finalizado el salto
void checkJump();
public:
AnimatedSprite *sprite; // Sprite del enemigo
SDL_Rect lastPosition; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento
int jump_ini; // Valor del eje Y en el que se inicia el salto
int status; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
// Constructor
Player(std::string _tileset, SDL_Renderer *_renderer, Asset *_asset);
Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room);
// Destructor
~Player();
// Pinta el enemigo en pantalla
void draw();
void render();
// Actualiza las variables del objeto
void update();
// Indica si el jugador esta en uno de los cuatro bordes de la pantalla
bool getOnBorder();
// Indica en cual de los cuatro bordes se encuentra
int getBorder();
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
void switchBorders();
// Obtiene el valor del pixel inferior izquierdo del jugador
SDL_Point getLeftFoot();
// Obtiene el valor del pixel inferior derecho del jugador
SDL_Point getRightFoot();
// Cambia el estado del jugador
void setStatus(int value);
// Obtiene el estado del jugador
int getStatus();
// Obtiene la velocidad en el eje Y del jugador
float getVelY();
// Obtiene el rectangulo que delimita al jugador
SDL_Rect getRect();
// Obtiene el rectangulo de colision del jugador
SDL_Rect &getCollider();
// Deshace el ultimo movimiento
void undoLastMove();
// Obtiene algunos parametros del jugador
player_t getSpawnParams();
// Recarga la textura
void reLoadTexture();
};
#endif

View File

@@ -4,18 +4,23 @@
#include <sstream>
// Constructor
Room::Room(std::string _file_path, SDL_Renderer *_renderer, Asset *_asset)
Room::Room(std::string file_path, SDL_Renderer *renderer, Asset *asset, ItemTracker *itemTracker, int *items)
{
texture = new LTexture();
asset = _asset;
renderer = _renderer;
load(_file_path);
loadTextureFromFile(texture, asset->get(tileset), renderer);
// Copia los punteros a objetos
this->asset = asset;
this->renderer = renderer;
this->itemTracker = itemTracker;
this->itemsPicked = items;
// Crea los objetos
load(file_path);
texture = new LTexture(renderer, asset->get(tileset));
itemSound = JA_LoadSound(asset->get("item.wav").c_str());
// Crea la textura para el mapa de tiles de la habitación
map_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (map_texture == NULL)
printf("Error: map_texture could not be created!\nSDL Error: %s\n", SDL_GetError());
mapTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (mapTexture == NULL)
printf("Error: mapTexture could not be created!\nSDL Error: %s\n", SDL_GetError());
// Pinta el mapa de la habitación en la textura
fillMapTexture();
@@ -25,18 +30,19 @@ Room::Room(std::string _file_path, SDL_Renderer *_renderer, Asset *_asset)
Room::~Room()
{
// Reclama la memoria utilizada por los objetos
texture->unload();
delete texture;
texture = nullptr;
JA_DeleteSound(itemSound);
SDL_DestroyTexture(mapTexture);
SDL_DestroyTexture(map_texture);
map_texture = nullptr;
for (auto enemy : enemy_list)
for (auto enemy : enemies)
{
delete enemy;
}
enemy_list.clear();
for (auto item : items)
{
delete item;
}
}
// Carga las variables desde un fichero
@@ -56,7 +62,7 @@ bool Room::load(std::string _file_path)
printf("Reading file %s\n", filename.c_str());
while (std::getline(file, line))
{
// Si la linea contiene el texto [enemy] se realiza un proceso distinto
// Si la linea contiene el texto [enemy] se realiza el proceso de carga de un enemigo
if (line == "[enemy]")
{
enemy_t enemy;
@@ -75,11 +81,94 @@ bool Room::load(std::string _file_path)
printf("Warning: file %s\n, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
} while (line != "[enemy-end]");
} while (line != "[/enemy]");
// Añade el enemigo al vector de enemigos
enemy_list.push_back(new Enemy(enemy));
enemies.push_back(new Enemy(enemy));
}
// Si la linea contiene el texto [tilemap] se realiza el proceso de carga del fichero tmx
else if (line == "[tilemap]")
{
// printf("Loading tilemap...\n");
do
{
std::getline(file, line);
if (line.find(".tmx") != std::string::npos)
{
// printf("Reading file %s\n", asset->get(line).c_str());
std::ifstream file2(asset->get(line)); // Abre el fichero tmx
if (file2.good())
{
bool data_read = false;
while (std::getline(file2, line)) // Lee el fichero linea a linea
{
if (!data_read)
{ // Lee lineas hasta que encuentre donde empiezan los datos del mapa
int pos = 0;
do
{
std::getline(file2, line);
// printf("parsing: %s\n", line.c_str());
pos = line.find("data encoding");
// printf("pos: %i\n", pos);
} while (pos == std::string::npos);
do
{ // Se introducen los valores separados por comas en un vector
data_read = true;
std::getline(file2, line);
if (line != "</data>")
{
// printf("data: %s\n", line.c_str());
std::stringstream ss(line);
std::string tmp;
while (getline(ss, tmp, ','))
{
// printf("tile: %s\n", tmp.c_str());
tilemap.push_back(std::stoi(tmp));
}
}
} while (line != "</data>");
}
}
}
}
} while (line != "[/tilemap]");
}
// Si la linea contiene el texto [item] se realiza el proceso de carga de un item
else if (line == "[item]")
{
item_t item;
item.asset = asset;
item.renderer = renderer;
item.counter = 0;
do
{
std::getline(file, line);
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (!setItem(&item, line.substr(0, pos), line.substr(pos + 1, line.length())))
{
printf("Warning: file %s\n, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
} while (line != "[/item]");
// Añade el item al vector de items
const SDL_Point itemPos = {item.x, item.y};
if (!itemTracker->hasBeenPicked(name, itemPos))
{
items.push_back(new Item(item));
}
}
// En caso contrario se parsea el fichero para buscar las variables y los valores
else
{
@@ -109,53 +198,61 @@ bool Room::load(std::string _file_path)
}
// Asigna variables a partir de dos cadenas
bool Room::setVars(std::string _var, std::string _value)
bool Room::setVars(std::string var, std::string value)
{
// Indicador de éxito en la asignación
bool success = true;
if (_var == "id")
if (var == "name")
{
id = _value;
name = value;
}
else if (_var == "name")
else if (var == "bgColor")
{
name = _value;
bgColor = stringToColor(value);
}
else if (_var == "bg_color")
else if (var == "tileset")
{
bg_color = stringToColor(_value);
tileset = value;
}
else if (_var == "tileset")
else if (var == "roomUp")
{
tileset = _value;
roomUp = value;
}
else if (_var == "room_up")
else if (var == "roomDown")
{
room_up = _value;
roomDown = value;
}
else if (_var == "room_down")
else if (var == "roomLeft")
{
room_down = _value;
roomLeft = value;
}
else if (_var == "room_left")
else if (var == "roomRight")
{
room_left = _value;
roomRight = value;
}
else if (_var == "room_right")
{
room_right = _value;
}
else if (_var == "tilemap")
else if (var == "tilemap")
{
// Se introducen los valores separados por comas en un vector
std::stringstream ss(_value);
std::stringstream ss(value);
std::string tmp;
while (getline(ss, tmp, ','))
{
tilemap.push_back(std::stoi(tmp));
}
}
else if (var == "")
{
}
else
{
success = false;
@@ -165,51 +262,123 @@ bool Room::setVars(std::string _var, std::string _value)
}
// Asigna variables a una estructura enemy_t
bool Room::setEnemy(enemy_t *enemy, std::string _var, std::string _value)
bool Room::setEnemy(enemy_t *enemy, std::string var, std::string value)
{
// Indicador de éxito en la asignación
bool success = true;
if (_var == "tileset")
if (var == "tileset")
{
enemy->tileset = _value;
enemy->tileset = value;
}
else if (_var == "x")
else if (var == "animation")
{
enemy->x = std::stof(_value);
enemy->animation = value;
}
else if (_var == "y")
else if (var == "width")
{
enemy->y = std::stof(_value);
enemy->w = std::stof(value);
}
else if (_var == "vx")
else if (var == "height")
{
enemy->vx = std::stof(_value);
enemy->h = std::stof(value);
}
else if (_var == "vy")
else if (var == "x")
{
enemy->vy = std::stof(_value);
enemy->x = std::stof(value) * BLOCK;
}
else if (_var == "x1")
else if (var == "y")
{
enemy->x1 = std::stoi(_value);
enemy->y = std::stof(value) * BLOCK;
}
else if (_var == "x2")
else if (var == "vx")
{
enemy->x2 = std::stoi(_value);
enemy->vx = std::stof(value);
}
else if (_var == "y1")
else if (var == "vy")
{
enemy->y1 = std::stoi(_value);
enemy->vy = std::stof(value);
}
else if (_var == "y2")
else if (var == "x1")
{
enemy->y2 = std::stoi(_value);
enemy->x1 = std::stoi(value) * BLOCK;
}
else if (_var == "color")
else if (var == "x2")
{
enemy->color = stringToColor(_value);
enemy->x2 = std::stoi(value) * BLOCK;
}
else if (var == "y1")
{
enemy->y1 = std::stoi(value) * BLOCK;
}
else if (var == "y2")
{
enemy->y2 = std::stoi(value) * BLOCK;
}
else if (var == "color")
{
enemy->color = stringToColor(value);
}
else if (var == "[/enemy]")
{
}
else
{
success = false;
}
return success;
}
// Asigna variables a una estructura item_t
bool Room::setItem(item_t *item, std::string var, std::string value)
{
// Indicador de éxito en la asignación
bool success = true;
if (var == "tileset")
{
item->tileset = value;
}
else if (var == "counter")
{
item->counter = std::stoi(value);
}
else if (var == "x")
{
item->x = std::stof(value) * BLOCK;
}
else if (var == "y")
{
item->y = std::stof(value) * BLOCK;
}
else if (var == "tile")
{
item->tile = std::stof(value);
}
else if (var == "[/item]")
{
}
else
{
success = false;
@@ -227,27 +396,25 @@ std::string Room::getName()
// Devuelve el color de la habitación
color_t Room::getBGColor()
{
return bg_color;
return bgColor;
}
// Crea la textura con el mapeado de la habitación
void Room::fillMapTexture()
{
SDL_SetRenderTarget(renderer, map_texture);
SDL_SetTextureBlendMode(map_texture, SDL_BLENDMODE_BLEND);
SDL_SetRenderTarget(renderer, mapTexture);
SDL_SetTextureBlendMode(mapTexture, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
SDL_RenderClear(renderer);
// Los tilesets son de 20x20 tiles. El primer tile es el 1. Cuentan hacia la derecha y hacia abajo
// printf("Filling map\n");
SDL_Rect clip = {0, 0, 8, 8};
for (int y = 0; y < 16; y++)
for (int x = 0; x < 32; x++)
{
clip.x = ((tilemap[(y * 32) + x] - 1) % 20) * 8;
clip.y = ((tilemap[(y * 32) + x] - 1) / 20) * 8;
// printf("tilemap [%i] = %i | x = %i | y = %i\n", ((y * 32) + x), tilemap[(y * 32) + x], clip.x, clip.y);
texture->render(renderer, x * 8, y * 8, &clip);
}
@@ -255,52 +422,148 @@ void Room::fillMapTexture()
}
// Dibuja el mapa en pantalla
void Room::drawMap()
void Room::renderMap()
{
SDL_Rect rect = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
// Dibuja la textura con el mapa en pantalla
SDL_RenderCopy(renderer, map_texture, &rect, NULL);
SDL_RenderCopy(renderer, mapTexture, &rect, NULL);
}
// Dibuja los enemigos en pantalla
void Room::drawEnemies()
void Room::renderEnemies()
{
for (auto enemy : enemy_list)
for (auto enemy : enemies)
{
enemy->draw();
enemy->render();
}
}
// Dibuja los objetos en pantalla
void Room::renderItems()
{
for (auto item : items)
{
item->render();
}
}
// Actualiza las variables y objetos de la habitación
void Room::update()
{
for (auto enemy : enemy_list)
for (auto enemy : enemies)
{
enemy->update();
}
for (auto item : items)
{
item->update();
}
}
// Devuelve el valor de la variable
std::string Room::getRoomUp()
// Devuelve la cadena del fichero de la habitación contigua segun el borde
std::string Room::getRoom(int border)
{
return room_up;
switch (border)
{
case BORDER_TOP:
return roomUp;
break;
case BORDER_BOTTOM:
return roomDown;
break;
case BORDER_RIGHT:
return roomRight;
break;
case BORDER_LEFT:
return roomLeft;
break;
default:
break;
}
return "";
}
// Devuelve el valor de la variable
std::string Room::getRoomDown()
// Devuelve el tipo de tile que hay en ese pixel
int Room::getTile(SDL_Point point)
{
return room_down;
int pos = ((point.y / 8) * 32) + (point.x / 8);
int tile = TILE_EMPTY;
if (pos < 512)
{
// Los tiles entre el 1 y el 80 son solidos
if ((tilemap[pos] > 0) && (tilemap[pos] < 201))
{
return TILE_SOLID;
}
// Devuelve el valor de la variable
std::string Room::getRoomLeft()
// Los tiles mayores de 80 son atravesables
if ((tilemap[pos] > 200) && (tilemap[pos] < 381))
{
return room_left;
return TILE_TRAVESSABLE;
}
// Devuelve el valor de la variable
std::string Room::getRoomRight()
// Los tiles mayores de 80 son atravesables
if ((tilemap[pos] > 380) && (tilemap[pos] < 400))
{
return room_right;
return TILE_KILL;
}
}
return tile;
}
// Indica si hay colision con un enemigo a partir de un rectangulo
bool Room::enemyCollision(SDL_Rect &rect)
{
bool collision = false;
for (auto enemy : enemies)
{
collision |= checkCollision(rect, enemy->getCollider());
}
return collision;
}
// Indica si hay colision con un objeto a partir de un rectangulo
bool Room::itemCollision(SDL_Rect &rect)
{
bool collision = false;
for (int i = 0; i < items.size(); i++)
{
if (checkCollision(rect, items[i]->getCollider()))
{
itemTracker->addItem(name, items[i]->getPos());
delete items[i];
items.erase(items.begin() + i);
JA_PlaySound(itemSound);
*itemsPicked = *itemsPicked + 1;
collision = true;
}
}
return collision;
}
// Recarga la textura
void Room::reLoadTexture()
{
texture->reLoad();
fillMapTexture();
for (auto enemy : enemies)
{
enemy->reLoadTexture();
}
for (auto item : items)
{
item->reLoadTexture();
}
}

View File

@@ -1,15 +1,24 @@
#pragma once
#include "ifdefs.h"
#include "const.h"
#include <SDL2/SDL.h>
#include "utils.h"
#include "asset.h"
#include "enemy.h"
#include "item.h"
#include "item_tracker.h"
#include "const.h"
#include "jail_audio.h"
#include <string>
#include <vector>
#ifndef ROOM_H
#define ROOM_H
#define TILE_EMPTY 0
#define TILE_SOLID 1
#define TILE_TRAVESSABLE 2
#define TILE_KILL 3
/*
Cada habitación se crea y destruye cada vez que se entra o sale de la misma
Cada habitacion si que tendra lo siguiente:
@@ -28,37 +37,42 @@ LISTADO DE ITEMS (tipo, posicion)
class Room
{
private:
std::string id; // Identificador
std::string name; // Nombre de la habitación
color_t bg_color; // Color de fondo de la habitación
std::string room_up; // Identificador de la habitación que se encuentra arriba
std::string room_down; // Identificador de la habitación que se encuentra abajp
std::string room_left; // Identificador de la habitación que se encuentra a la izquierda
std::string room_right; // Identificador de la habitación que se encuentra a la derecha
color_t bgColor; // Color de fondo de la habitación
std::string roomUp; // Identificador de la habitación que se encuentra arriba
std::string roomDown; // Identificador de la habitación que se encuentra abajp
std::string roomLeft; // Identificador de la habitación que se encuentra a la izquierda
std::string roomRight; // Identificador de la habitación que se encuentra a la derecha
std::string tileset; // Imagen con los graficos para la habitación
std::vector<int> tilemap; // Indice de los tiles a dibujar en la habitación
std::vector<Enemy *> enemy_list; // Listado con los enemigos de la habitación
std::vector<int> item_list; // Listado con los items que hay en la habitación
std::vector<Enemy *> enemies; // Listado con los enemigos de la habitación
std::vector<Item *> items; // Listado con los items que hay en la habitación
LTexture *texture; // Textura con los graficos de la habitación
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
ItemTracker *itemTracker; // Lleva el control de los objetos recogidos
SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Texture *map_texture; // Textura para dibujar el mapa de la habitación
SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación
JA_Sound itemSound; // Sonido producido al coger un objeto
int *itemsPicked; // Puntero a la cantidad de items recogidos que lleva el juego
// Carga las variables desde un fichero
bool load(std::string _file_path);
bool load(std::string file_path);
// Asigna variables a partir de dos cadenas
bool setVars(std::string _var, std::string _value);
bool setVars(std::string var, std::string value);
// Asigna variables a una estructura enemy_t
bool setEnemy(enemy_t *enemy, std::string _var, std::string _value);
bool setEnemy(enemy_t *enemy, std::string var, std::string value);
// Asigna variables a una estructura item_t
bool setItem(item_t *item, std::string var, std::string value);
// Pinta el mapa de la habitación en la textura
void fillMapTexture();
public:
// Constructor
Room(std::string _file_path, SDL_Renderer *_renderer, Asset *_asset);
Room(std::string file_path, SDL_Renderer *renderer, Asset *asset, ItemTracker *item_tracker, int *items);
// Destructor
~Room();
@@ -70,25 +84,31 @@ public:
color_t getBGColor();
// Dibuja el mapa en pantalla
void drawMap();
void renderMap();
// Dibuja los enemigos en pantalla
void drawEnemies();
void renderEnemies();
// Dibuja los objetos en pantalla
void renderItems();
// Actualiza las variables y objetos de la habitación
void update();
// Devuelve el valor de la variable
std::string getRoomUp();
// Devuelve la cadena del fichero de la habitación contigua segun el borde
std::string getRoom(int border);
// Devuelve el valor de la variable
std::string getRoomDown();
// Devuelve el tipo de tile que hay en ese pixel
int getTile(SDL_Point point);
// Devuelve el valor de la variable
std::string getRoomLeft();
// Indica si hay colision con un enemigo a partir de un rectangulo
bool enemyCollision(SDL_Rect &rect);
// Devuelve el valor de la variable
std::string getRoomRight();
// Indica si hay colision con un objeto a partir de un rectangulo
bool itemCollision(SDL_Rect &rect);
// Recarga la textura
void reLoadTexture();
};
#endif

138
source/scoreboard.cpp Normal file
View File

@@ -0,0 +1,138 @@
#include "scoreboard.h"
#include <fstream>
#include <sstream>
// Constructor
ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, int *lives, int *items, Uint32 *clock)
{
// Obten punteros a objetos
this->asset = asset;
this->renderer = renderer;
this->lives = lives;
this->items = items;
this->clock = clock;
// Reserva memoria para los objetos
texture = new LTexture(renderer, asset->get("player01.png"));
sprite = new AnimatedSprite(texture, renderer, asset->get("player01.ani"));
sprite->setCurrentAnimation("walk_menu");
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
// Inicializa las variables
counter = 0;
colorChangeSpeed = 4;
// Inicializa los colores
color_t c = stringToColor("blue");
color.push_back(c);
c = stringToColor("red");
color.push_back(c);
c = stringToColor("purple");
color.push_back(c);
c = stringToColor("green");
color.push_back(c);
c = stringToColor("cyan");
color.push_back(c);
c = stringToColor("yellow");
color.push_back(c);
c = stringToColor("white");
color.push_back(c);
c = stringToColor("light_blue");
color.push_back(c);
c = stringToColor("light_red");
color.push_back(c);
c = stringToColor("light_purple");
color.push_back(c);
c = stringToColor("light_green");
color.push_back(c);
c = stringToColor("light_cyan");
color.push_back(c);
c = stringToColor("light_yellow");
color.push_back(c);
c = stringToColor("light_white");
color.push_back(c);
}
// Destructor
ScoreBoard::~ScoreBoard()
{
delete texture;
delete sprite;
delete text;
}
// Pinta el objeto en pantalla
void ScoreBoard::render()
{
// Dibuja el fondo del marcador
const SDL_Rect rect = {0, 17 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect);
// Dibuja las vidas
sprite->setPosY(18 * BLOCK);
int index;
const int desp = (counter / 40) % 8;
const int frame = desp % 4;
sprite->setCurrentFrame(frame);
for (int i = 0; i < *lives; i++)
{
sprite->setPosX(8 + (16 * i) + desp);
index = i % color.size();
sprite->getTexture()->setColor(color[index].r, color[index].g, color[index].b);
sprite->render();
}
// Escribe los textos
const clock_t clock = getTime();
std::string itemsTxt = std::to_string(*items / 100) + std::to_string((*items % 100) / 10) + std::to_string(*items % 10);
std::string separator = " ";
if (clock.separator)
{
separator = ":";
}
std::string timeTxt = std::to_string((clock.minutes % 60) / 10) + std::to_string(clock.minutes % 10) + separator + std::to_string((clock.seconds % 60) / 10) + std::to_string(clock.seconds % 10);
std::string text = "Items collected " + itemsTxt + " Time " + timeTxt;
const color_t color = stringToColor("white");
this->text->writeColored(BLOCK, 21 * BLOCK, text, color);
}
// Actualiza las variables del objeto
void ScoreBoard::update()
{
counter++;
sprite->update();
}
// Obtiene el tiempo transcurrido de partida
ScoreBoard::clock_t ScoreBoard::getTime()
{
const Uint32 timeElapsed = SDL_GetTicks() - *clock;
clock_t time;
time.hours = timeElapsed / 3600000;
time.minutes = timeElapsed / 60000;
time.seconds = timeElapsed / 1000;
time.separator = (timeElapsed % 1000 <= 500);
return time;
}
// Recarga la textura
void ScoreBoard::reLoadTexture()
{
texture->reLoad();
text->reLoadTexture();
}

58
source/scoreboard.h Normal file
View File

@@ -0,0 +1,58 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include "text.h"
#include "asset.h"
#include "animatedsprite.h"
#include "const.h"
#include <string>
#ifndef SCOREBOARD_H
#define SCOREBOARD_H
// Clase ScoreBoard
class ScoreBoard
{
private:
struct clock_t
{
int hours;
int minutes;
int seconds;
bool separator;
};
LTexture *texture; // Textura con los graficos para las vidas
AnimatedSprite *sprite; // Sprite para mostrar las vidas en el marcador
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Text *text; // Objeto para escribir texto
std::vector<color_t> color; // Vector con los colores del objeto
int counter; // Contador interno
int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color
int *lives; // Número ara mostrar en el marcador de vidas
int *items; // Número para mostrar en el marcador de items
Uint32 *clock; // Contiene el tiempo de inicio de la partida
// Obtiene el tiempo transcurrido de partida
clock_t getTime();
public:
// Constructor
ScoreBoard(SDL_Renderer *renderer, Asset *asset, int *lives, int *items, Uint32 *clock);
// Destructor
~ScoreBoard();
// Pinta el objeto en pantalla
void render();
// Actualiza las variables del objeto
void update();
// Recarga la textura
void reLoadTexture();
};
#endif

View File

@@ -1,63 +1,174 @@
#include "screen.h"
#include "const.h"
#include <string>
#include <stdio.h>
// Constructor
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options, int gameInternalResX, int gameInternalResY)
{
// Inicializa variables
mWindow = window;
mRenderer = renderer;
this->window = window;
this->renderer = renderer;
this->options = options;
mScreenWidth = SCREEN_WIDTH;
mScreenHeight = SCREEN_HEIGHT;
mGameCanvasWidth = GAMECANVAS_WIDTH;
mGameCanvasHeight = GAMECANVAS_HEIGHT;
mGameCanvasPosX = (SCREEN_WIDTH - GAMECANVAS_WIDTH) / 2;
mGameCanvasPosY = (SCREEN_HEIGHT - GAMECANVAS_HEIGHT) / 2;
gameCanvasWidth = gameInternalResX;
gameCanvasHeight = gameInternalResY;
mBorderColor = {0x27, 0x27, 0x36};
// Establece el modo de video
setVideoMode(options->fullScreenMode);
// Define el color del borde para el modo de pantalla completa
borderColor = {0x00, 0x00, 0x00};
// Crea la textura donde se dibujan los graficos del juego
mGameCanvas = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (mGameCanvas == NULL)
gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight);
if (gameCanvas == NULL)
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError());
// Calcula los anclajes
anchor.left = 0;
anchor.right = gameCanvasWidth;
anchor.center = gameCanvasWidth / 2;
anchor.top = 0;
anchor.bottom = gameCanvasHeight;
anchor.middle = gameCanvasHeight / 2;
}
// Destructor
Screen::~Screen()
{
mRenderer = nullptr;
renderer = nullptr;
}
// Limpia la pantalla
void Screen::clean(color_t color)
{
SDL_SetRenderDrawColor(mRenderer, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(mRenderer);
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer);
}
// Prepara para empezar a dibujar en la textura de juego
void Screen::start()
{
SDL_SetRenderTarget(mRenderer, mGameCanvas);
SDL_SetRenderTarget(renderer, gameCanvas);
}
// Vuelca el contenido del renderizador en pantalla
void Screen::blit()
{
// Vuelve a dejar el renderizador en modo normal
SDL_SetRenderTarget(mRenderer, NULL);
SDL_SetRenderTarget(renderer, NULL);
// Borra el contenido previo
SDL_SetRenderDrawColor(mRenderer, mBorderColor.r, mBorderColor.g, mBorderColor.b, 0xFF);
SDL_RenderClear(mRenderer);
// Rectangulo de destino donde se dibujarà la textura con el juego
SDL_Rect dest = {mGameCanvasPosX, mGameCanvasPosY, mGameCanvasWidth, mGameCanvasHeight};
SDL_SetRenderDrawColor(renderer, borderColor.r, borderColor.g, borderColor.b, 0xFF);
SDL_RenderClear(renderer);
// Copia la textura de juego en el renderizador en la posición adecuada
SDL_RenderCopy(mRenderer, mGameCanvas, NULL, &dest);
SDL_RenderCopy(renderer, gameCanvas, NULL, &dest);
// Muestra por pantalla el renderizador
SDL_RenderPresent(mRenderer);
SDL_RenderPresent(renderer);
}
// Establece el modo de video
void Screen::setVideoMode(int fullScreenMode)
{
// Aplica el modo de video
SDL_SetWindowFullscreen(window, fullScreenMode);
// Si está activo el modo ventana quita el borde
if (fullScreenMode == 0)
{
screenWidth = gameCanvasWidth;
screenHeight = gameCanvasHeight;
dest = {0, 0, gameCanvasWidth, gameCanvasHeight};
// Modifica el tamaño del renderizador y de la ventana
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight);
SDL_SetWindowSize(window, screenWidth * options->windowSize, screenHeight * options->windowSize);
}
// Si está activo el modo de pantalla completa añade el borde
else if (fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
{
// Obten el alto y el ancho de la ventana
SDL_GetWindowSize(window, &screenWidth, &screenHeight);
// Aplica el escalado al rectangulo donde se pinta la textura del juego
if (options->integerScale)
{
// Calcula el tamaño de la escala máxima
int scale = 0;
while (((gameCanvasWidth * (scale + 1)) <= screenWidth) && ((gameCanvasHeight * (scale + 1)) <= screenHeight))
{
scale++;
}
dest.w = gameCanvasWidth * scale;
dest.h = gameCanvasHeight * scale;
dest.x = (screenWidth - dest.w) / 2;
dest.y = (screenHeight - dest.h) / 2;
}
else if (options->keepAspect)
{
float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight;
if ((screenWidth - gameCanvasWidth) >= (screenHeight - gameCanvasHeight))
{
dest.h = screenHeight;
dest.w = (int)((screenHeight * ratio) + 0.5f);
dest.x = (screenWidth - dest.w) / 2;
dest.y = (screenHeight - dest.h) / 2;
}
else
{
dest.w = screenWidth;
dest.h = (int)((screenWidth / ratio) + 0.5f);
dest.x = (screenWidth - dest.w) / 2;
dest.y = (screenHeight - dest.h) / 2;
}
}
else
{
dest.w = screenWidth;
dest.h = screenHeight;
dest.x = dest.y = 0;
}
// Modifica el tamaño del renderizador
SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight);
}
// Actualiza el valor de la variable
options->fullScreenMode = fullScreenMode;
}
// Camibia entre pantalla completa y ventana
void Screen::switchVideoMode()
{
if (options->fullScreenMode == 0)
{
setVideoMode(SDL_WINDOW_FULLSCREEN_DESKTOP);
}
else
{
setVideoMode(0);
}
}
// Cambia el tamaño de la ventana
void Screen::setWindowSize(int size)
{
options->windowSize = size;
setVideoMode(0);
}
// Cambia el color del borde
void Screen::setBorderColor(color_t color)
{
borderColor = color;
}
// Cambia el tipo de mezcla
void Screen::setBlendMode(SDL_BlendMode blendMode)
{
SDL_SetRenderDrawBlendMode(renderer, blendMode);
}

View File

@@ -1,42 +1,68 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "utils.h"
#ifndef SCREEN_H
#define SCREEN_H
struct anchor_t
{
int left; // Parte izquierda de la pantalla de juego
int right; // Parte drecha de la pantalla de juego
int center; // Parte central horizontal de la pantalla de juego
int top; // Parte superior de la pantalla de juego
int bottom; // Parte infoerior de la pantalla de juego
int middle; // Parte central vertical de la pantalla de juego
};
// Clase Screen
class Screen
{
private:
SDL_Window *mWindow; // Ventana de la aplicación
SDL_Renderer *mRenderer; // El renderizador de la ventana
SDL_Texture *mGameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa
SDL_Window *window; // Ventana de la aplicación
SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa
options_t *options; // Variable con todas las opciones del programa
int mScreenWidth; // Ancho de la pantalla
int mScreenHeight; // Alto de la pantalla
int mGameCanvasWidth; // Ancho de la textura donde se dibuja el juego
int mGameCanvasHeight; // Alto de la textura donde se dibuja el juego
int mGameCanvasPosX; // Posicion en el eje X donde se dibujará la textura del juego dentro de la pantalla
int mGameCanvasPosY; // Posicion en el eje Y donde se dibujará la textura del juego dentro de la pantalla
color_t mBorderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
int screenWidth; // Ancho de la pantalla o ventana
int screenHeight; // Alto de la pantalla o ventana
int gameCanvasWidth; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego
int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego
anchor_t anchor; // Variable con los anclajes de la pantalla
SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
public:
// Constructor
Screen(SDL_Window *windows, SDL_Renderer *renderer);
Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options, int gameInternalResX, int gameInternalResY);
// Destructor
~Screen();
// Limpia la pantalla
void clean(color_t color);
void clean(color_t color = {0x00, 0x00, 0x00});
// Prepara para empezar a dibujar en la textura de juego
void start();
// Vuelca el contenido del renderizador en pantalla
void blit();
// Establece el modo de video
void setVideoMode(int fullScreenMode);
// Camibia entre pantalla completa y ventana
void switchVideoMode();
// Cambia el tamaño de la ventana
void setWindowSize(int size);
// Cambia el color del borde
void setBorderColor(color_t color);
// Cambia el tipo de mezcla
void setBlendMode(SDL_BlendMode blendMode);
};
#endif

View File

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

View File

@@ -1,5 +1,6 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "ltexture.h"
#ifndef SPRITE_H
@@ -9,28 +10,25 @@
class Sprite
{
protected:
int mPosX; // Posición en el eje X donde dibujar el sprite
int mPosY; // Posición en el eje Y donde dibujar el sprite
Uint16 mWidth; // Ancho del sprite
Uint16 mHeight; // Alto del sprite
int x; // Posición en el eje X donde dibujar el sprite
int y; // Posición en el eje Y donde dibujar el sprite
int w; // Ancho del sprite
int h; // Alto del sprite
SDL_Renderer *mRenderer; // Puntero al renderizador de la ventana
LTexture *mTexture; // Textura donde estan todos los dibujos del sprite
SDL_Rect mSpriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla
SDL_Renderer *renderer; // Puntero al renderizador de la ventana
LTexture *texture; // Textura donde estan todos los dibujos del sprite
SDL_Rect spriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla
bool mEnabled; // Indica si el sprite esta habilitado
bool enabled; // Indica si el sprite esta habilitado
public:
// Constructor
Sprite();
Sprite(int x = 0, int y = 0, int w = 0, int h = 0, LTexture *texture = nullptr, SDL_Renderer *renderer = nullptr);
Sprite(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer);
// Destructor
~Sprite();
// Inicializador
void init(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *renderer);
void init(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer);
// Muestra el sprite por pantalla
void render();
@@ -46,12 +44,21 @@ public:
// Obten el valor de la variable
int getHeight();
// Establece la posición del objeto
void setPos(SDL_Rect rect);
// Establece el valor de la variable
void setPosX(int x);
// Establece el valor de la variable
void setPosY(int y);
// Incrementa el valor de la variable
void incPosX(int value);
// Incrementa el valor de la variable
void incPosY(int value);
// Establece el valor de la variable
void setWidth(int w);
@@ -81,6 +88,12 @@ public:
// Comprueba si el objeto está habilitado
bool isEnabled();
// Devuelve el rectangulo donde está el sprite
SDL_Rect getRect();
// Establece los valores de posición y tamaño del sprite
void setRect(SDL_Rect rect);
};
#endif

View File

@@ -1,15 +1,16 @@
#include "const.h"
#include "text.h"
#include <iostream>
#include <fstream>
// Constructor
Text::Text(std::string file, LTexture *texture, SDL_Renderer *renderer)
Text::Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer)
{
mSprite = new Sprite();
mSprite->setTexture(texture);
mSprite->setRenderer(renderer);
mFile = file;
texture = new LTexture(renderer, bitmapFile);
sprite = new Sprite({0, 0, 0, 0}, texture, renderer);
sprite->setTexture(texture);
sprite->setRenderer(renderer);
file = textFile;
init();
}
@@ -17,8 +18,8 @@ Text::Text(std::string file, LTexture *texture, SDL_Renderer *renderer)
// Destructor
Text::~Text()
{
delete mSprite;
mSprite = nullptr;
delete texture;
delete sprite;
}
// Inicializador
@@ -27,61 +28,61 @@ void Text::init()
// Inicializa a cero el vector con las coordenadas
for (int i = 0; i < 128; i++)
{
mOffset[i].x = 0;
mOffset[i].y = 0;
mOffset[i].w = 0;
offset[i].x = 0;
offset[i].y = 0;
offset[i].w = 0;
}
// Carga los offsets desde el fichero
initOffsetFromFile();
// Inicia los valores del sprite que dibuja las letras
mSprite->setWidth(mBoxWidth);
mSprite->setHeight(mBoxHeight);
mSprite->setPosX(0);
mSprite->setPosY(0);
mSprite->setSpriteClip(0, 0, mSprite->getWidth(), mSprite->getHeight());
sprite->setWidth(boxWidth);
sprite->setHeight(boxHeight);
sprite->setPosX(0);
sprite->setPosY(0);
sprite->setSpriteClip(0, 0, sprite->getWidth(), sprite->getHeight());
// Establece las coordenadas para cada caracter ascii de la cadena y su ancho
for (int i = 32; i < 128; i++)
{
mOffset[i].x = ((i - 32) % 15) * mBoxWidth;
mOffset[i].y = ((i - 32) / 15) * mBoxHeight;
offset[i].x = ((i - 32) % 15) * boxWidth;
offset[i].y = ((i - 32) / 15) * boxHeight;
}
}
// Escribe texto en pantalla
void Text::write(int x, int y, std::string text, int kerning, int lenght)
{
Uint16 shift = 0;
int shift = 0;
if (lenght == -1)
lenght = text.length();
for (int i = 0; i < lenght; ++i)
{
mSprite->setSpriteClip(mOffset[int(text[i])].x, mOffset[int(text[i])].y, mSprite->getWidth(), mSprite->getHeight());
mSprite->setPosX(x + shift);
mSprite->setPosY(y);
mSprite->render();
shift += (mOffset[int(text[i])].w + kerning);
sprite->setSpriteClip(offset[int(text[i])].x, offset[int(text[i])].y, sprite->getWidth(), sprite->getHeight());
sprite->setPosX(x + shift);
sprite->setPosY(y);
sprite->render();
shift += (offset[int(text[i])].w + kerning);
}
}
// Escribe el texto con colores
void Text::writeColored(int x, int y, std::string text, color_t color, int kerning, int lenght)
{
mSprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->getTexture()->setColor(color.r, color.g, color.b);
write(x, y, text, kerning, lenght);
mSprite->getTexture()->setColor(255, 255, 255);
sprite->getTexture()->setColor(255, 255, 255);
}
// Escribe el texto con sombra
void Text::writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance, int kerning, int lenght)
{
mSprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->getTexture()->setColor(color.r, color.g, color.b);
write(x + shadowDistance, y + shadowDistance, text, kerning, lenght);
mSprite->getTexture()->setColor(255, 255, 255);
sprite->getTexture()->setColor(255, 255, 255);
write(x, y, text, kerning, lenght);
}
@@ -126,33 +127,33 @@ void Text::writeDX(Uint8 flags, int x, int y, std::string text, int kerning, col
}
// Obtiene la longitud en pixels de una cadena
Uint16 Text::lenght(std::string text, int kerning)
int Text::lenght(std::string text, int kerning)
{
Uint16 shift = 0;
int shift = 0;
for (int i = 0; i < (int)text.length(); ++i)
shift += (mOffset[int(text[i])].w + kerning);
for (int i = 0; i < (int)text.length(); i++)
shift += (offset[int(text[i])].w + kerning);
return shift;
// Descuenta el kerning del último caracter
return shift - kerning;
}
// Inicializa el vector de offsets desde un fichero
void Text::initOffsetFromFile()
{
std::ifstream rfile(mFile);
std::ifstream rfile(file);
if (rfile.is_open() && rfile.good())
{
std::string buffer;
//printf("Reading %s file\n", mFile.c_str());
// Lee los dos primeros valores del fichero
std::getline(rfile, buffer);
std::getline(rfile, buffer);
mBoxWidth = std::stoi(buffer);
boxWidth = std::stoi(buffer);
std::getline(rfile, buffer);
std::getline(rfile, buffer);
mBoxHeight = std::stoi(buffer);
boxHeight = std::stoi(buffer);
// lee el resto de datos del fichero
int index = 32;
@@ -161,7 +162,7 @@ void Text::initOffsetFromFile()
{
// Almacena solo las lineas impares
if (line_read % 2 == 1)
mOffset[index++].w = std::stoi(buffer);
offset[index++].w = std::stoi(buffer);
// Limpia el buffer
buffer.clear();
@@ -171,7 +172,13 @@ void Text::initOffsetFromFile()
}
// Devuelve el valor de la variable
Uint8 Text::getCharacterWidth()
int Text::getCharacterWidth()
{
return mBoxWidth;
return boxWidth;
}
// Recarga la textura
void Text::reLoadTexture()
{
texture->reLoad();
}

View File

@@ -1,4 +1,5 @@
#pragma once
#include "sprite.h"
#include "utils.h"
@@ -14,33 +15,34 @@
class Text
{
private:
Sprite *mSprite; // Objeto con los graficos para el texto
Sprite *sprite; // Objeto con los graficos para el texto
struct Offset
{
int x;
int y;
Uint8 w;
int w;
};
Offset mOffset[128]; // Vector con las posiciones y ancho de cada letra
Offset offset[128]; // Vector con las posiciones y ancho de cada letra
Uint8 mBoxWidth; // Anchura de la caja de cada caracter en el png
Uint8 mBoxHeight; // Altura de la caja de cada caracter en el png
std::string mFile; // Fichero con los descriptores de la fuente
int boxWidth; // Anchura de la caja de cada caracter en el png
int boxHeight; // Altura de la caja de cada caracter en el png
std::string file; // Fichero con los descriptores de la fuente
LTexture *texture; // Textura con los bitmaps del texto
// Inicializador
void init();
// Inicializa el vector de offsets desde un fichero
void initOffsetFromFile();
public:
// Constructor
Text(std::string file, LTexture *texture, SDL_Renderer *renderer);
Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer);
// Destructor
~Text();
// Inicializador
void init();
// Escribe el texto en pantalla
void write(int x, int y, std::string text, int kerning = 1, int lenght = -1);
@@ -50,17 +52,20 @@ public:
// Escribe el texto con sombra
void writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1);
// Escribe el texto centrado en un punto x y con kerning
// Escribe el texto centrado en un punto x
void writeCentered(int x, int y, std::string text, int kerning = 1, int lenght = -1);
// Escribe texto con extras
void writeDX(Uint8 flags, int x, int y, std::string text, int kerning = 1, color_t textColor = {255, 255, 255}, Uint8 shadowDistance = 1, color_t shadowColor = {0, 0, 0}, int lenght = -1);
// Obtiene la longitud en pixels de una cadena
Uint16 lenght(std::string text, int kerning = 1);
int lenght(std::string text, int kerning = 1);
// Devuelve el valor de la variable
Uint8 getCharacterWidth();
int getCharacterWidth();
// Recarga la textura
void reLoadTexture();
};
#endif

186
source/title.cpp Normal file
View File

@@ -0,0 +1,186 @@
#include "title.h"
// Constructor
Title::Title(SDL_Renderer *renderer, Screen *screen, Asset *asset)
{
// Copia la dirección de los objetos
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
texture = new LTexture(renderer, asset->get("loading_screen2.png"));
sprite = new Sprite(0, 0, texture->getWidth(), texture->getHeight(), texture, renderer);
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
music = JA_LoadMusic(asset->get("title.ogg").c_str());
// Inicializa variables
counter = 0;
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
ticks = 0;
ticksSpeed = 15;
longText = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!! HAVE YOU HEARD IT? JAILGAMES ARE BACK!! YEEESSS BACK!! MORE THAN 10 TITLES ON JAILDOC'S KITCHEN!! THATS A LOOOOOOT OF JAILGAMES, BUT WHICH ONE WILL STRIKE FIRST? THERE IS ALSO A NEW DEVICE TO COME P.A.C.O. THAT WILL BLOW YOUR MIND WITH JAILGAMES ON THE GO. BUT WAIT! WHAT'S THAT BEAUTY I'M SEEING RIGHT OVER THERE?? OOOH THAT TINY MINIASCII IS PURE LOVE!! I WANT TO LICK EVERY BYTE OF IT!! OH SHIT! AND DON'T FORGET TO BRING BACK THOSE OLD AND FAT MS-DOS JAILGAMES TO GITHUB TO KEEP THEM ALIVE!! WHAT WILL BE THE NEXT JAILDOC RELEASE? WHAT WILL BE THE NEXT PROJECT TO COME ALIVE?? OH BABY WE DON'T KNOW BUT HERE YOU CAN FIND THE ANSWER, YOU JUST HAVE TO COMPLETE JAILDOCTOR'S DILEMMA ... COULD YOU?";
for (int i = 0; i < longText.length(); i++)
{
letter_t l;
l.letter = longText.substr(i, 1);
l.x = 256;
l.enabled = false;
letters.push_back(l);
}
letters[0].enabled = true;
}
// Destructor
Title::~Title()
{
delete eventHandler;
delete texture;
delete sprite;
delete text;
JA_DeleteMusic(music);
}
// Comprueba el manejador de eventos
void Title::checkEventHandler()
{
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(eventHandler) != 0)
{
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
break;
}
// Comprueba si se ha pulsado alguna tecla
else if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0))
{
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_QUIT;
break;
case SDL_SCANCODE_RETURN:
section.name = SECTION_PROG_GAME;
section.subsection = 0;
break;
default:
break;
}
}
}
}
// Actualiza la marquesina
void Title::updateMarquee()
{
for (int i = 0; i < letters.size(); i++)
{
if (letters[i].enabled)
{
letters[i].x -= 2;
if (letters[i].x < -10)
{
letters[i].enabled = false;
}
}
else
{
if (i > 0 && letters[i - 1].x < 250)
{
letters[i].enabled = true;
}
}
}
}
// Dibuja la marquesina
void Title::renderMarquee()
{
for (auto l : letters)
{
if (l.enabled)
{
// text->writeColored(l.x, 176, l.letter, {0, 0, 0});
text->write(l.x, 176, l.letter);
}
}
}
// Actualiza las variables
void Title::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Comprueba el manejador de eventos
checkEventHandler();
// Incrementa el contador
counter++;
// Actualiza la marquesina
updateMarquee();
// Comprueba si ha pasado mucho tiempo y acaba el titulo
// if (counter == 1000)
// Comprueba si ha terminado la marquesina y acaba con el titulo
if (letters[letters.size() - 1].x < -10)
{
section.name = SECTION_PROG_LOGO;
section.subsection = 0;
}
}
}
// Dibuja en pantalla
void Title::render()
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean();
// Dibuja el fondo del titulo
sprite->render();
// Dibuja el texto de PRESS ENTER TO PLAY
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
SDL_Rect rect = {0, 192 / 5 * 4, 256, 8};
SDL_RenderFillRect(renderer, &rect);
if (counter % 80 < 60)
text->writeCentered(256 / 2, 192 / 5 * 4, "PRESS ENTER TO PLAY");
// Dibuja la marquesina
renderMarquee();
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
// Bucle para el logo del juego
section_t Title::run()
{
JA_PlayMusic(music);
while (section.name == SECTION_PROG_TITLE)
{
update();
render();
}
JA_StopMusic();
return section;
}

68
source/title.h Normal file
View File

@@ -0,0 +1,68 @@
#pragma once
#include <SDL2/SDL.h>
#include "const.h"
#include "utils.h"
#include "sprite.h"
#include "screen.h"
#include "asset.h"
#include "text.h"
#include "jail_audio.h"
#include <vector>
#ifndef TITLE_H
#define TITLE_H
// Clase Title
class Title
{
private:
struct letter_t
{
std::string letter; // Letra a escribir
int x; // Posición en el eje x
bool enabled; // Solo se escriben y mueven si estan habilitadas
};
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
Asset *asset; // Objeto con los ficheros de recursos
SDL_Event *eventHandler; // Manejador de eventos
LTexture *texture; // Textura con los graficos
Sprite *sprite; // Sprite para manejar la textura
Text *text; // Objeto para escribir texto en pantalla
JA_Music music; // Musica del titulo
int counter; // Contador
section_t section; // Estado del bucle principal para saber si continua o se sale
std::string longText; // Texto que aparece en la parte inferior del titulo
int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
std::vector<letter_t> letters; // Vector con las letras de la marquesina
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
// Comprueba el manejador de eventos
void checkEventHandler();
// Actualiza la marquesina
void updateMarquee();
// Dibuja la marquesina
void renderMarquee();
public:
// Constructor
Title(SDL_Renderer *renderer, Screen *screen, Asset *asset);
// Destructor
~Title();
// Bucle principal
section_t run();
};
#endif

View File

@@ -3,8 +3,8 @@
// Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2)
{
int deltaX = x2 - x1;
int deltaY = y2 - y1;
const int deltaX = x2 - x1;
const int deltaY = y2 - y1;
return deltaX * deltaX + deltaY * deltaY;
}
@@ -71,20 +71,20 @@ bool checkCollision(circle_t &a, SDL_Rect &b)
return false;
}
// Detector de colisiones entre un dos rectangulos
// Detector de colisiones entre dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b)
{
// Calculate the sides of rect A
int leftA = a.x;
int rightA = a.x + a.w;
int topA = a.y;
int bottomA = a.y + a.h;
const int leftA = a.x;
const int rightA = a.x + a.w;
const int topA = a.y;
const int bottomA = a.y + a.h;
// Calculate the sides of rect B
int leftB = b.x;
int rightB = b.x + b.w;
int topB = b.y;
int bottomB = b.y + b.h;
const int leftB = b.x;
const int rightB = b.x + b.w;
const int topB = b.y;
const int bottomB = b.y + b.h;
// If any of the sides from A are outside of B
if (bottomA <= topB)
@@ -111,16 +111,33 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
return true;
}
// Carga un archivo de imagen en una textura
bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer)
// Detector de colisiones entre un punto y u rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r)
{
bool success = true;
if (!texture->loadFromFile(path, renderer))
// Comprueba si el punto está fuera del rectangulo en el eje X
if (p.x < r.x)
{
printf("Failed to load %s texture!\n", path.c_str());
success = false;
return false;
}
return success;
if (p.x > r.x + r.w)
{
return false;
}
// Comprueba si el punto está fuera del rectangulo en el eje Y
if (p.y < r.y)
{
return false;
}
if (p.y > r.y + r.h)
{
return false;
}
// Si ha llegado hasta aquí, es que está dentro
return true;
}
// Devuelve un color_t a partir de un string

View File

@@ -1,14 +1,30 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "ltexture.h"
#include <string>
#ifndef UTILS_H
#define UTILS_H
#define DIFFICULTY_EASY 0
#define DIFFICULTY_NORMAL 1
#define DIFFICULTY_HARD 2
#define FILTER_NEAREST 0
#define FILTER_LINEAL 1
// Secciones del programa
#define SECTION_PROG_LOGO 0
#define SECTION_PROG_INTRO 1
#define SECTION_PROG_TITLE 2
#define SECTION_PROG_GAME 3
#define SECTION_PROG_QUIT 4
// Subsecciones
#define SUBSECTION_GAME_PLAY 0
#define SUBSECTION_GAME_PAUSE 1
#define SUBSECTION_GAME_GAMEOVER 2
#define SUBSECTION_TITLE_1 3
#define SUBSECTION_TITLE_2 4
#define SUBSECTION_TITLE_3 5
#define SUBSECTION_TITLE_INSTRUCTIONS 6
// Estructura para definir un circulo
struct circle_t
@@ -33,35 +49,17 @@ struct section_t
Uint8 subsection;
};
// Estructura para mapear el teclado usado en la demo
struct demoKeys_t
{
Uint8 left;
Uint8 right;
Uint8 noInput;
Uint8 fire;
Uint8 fireLeft;
Uint8 fireRight;
};
// Estructura para albergar métodos de control
struct input_t
{
int id; // Identificador en el vector de mandos
std::string name; // Nombre del dispositivo
Uint8 deviceType; // Tipo de dispositivo (teclado o mando)
};
// Estructura con todas las opciones de configuración del programa
struct options_t
{
Uint8 difficulty; // Dificultad del juego
input_t input[2]; // Modo de control (teclado o mando)
Uint8 language; // Idioma usado en el juego
Uint32 fullScreenMode; // Contiene el valor del modo de pantalla completa
Uint8 windowSize; // Contiene el valor del tamaño de la ventana
int windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana
Uint32 filter; // Filtro usado para el escalado de la imagen
bool vSync; // Indica si se quiere usar vsync o no
int screenWidth; // Ancho de la pantalla o ventana
int screenHeight; // Alto de la pantalla o ventana
bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa
bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa
};
// Calcula el cuadrado de la distancia entre dos puntos
@@ -74,10 +72,10 @@ bool checkCollision(circle_t &a, circle_t &b);
bool checkCollision(circle_t &a, SDL_Rect &b);
// Detector de colisiones entre un dos rectangulos
bool checkCollision(SDL_Rect a, SDL_Rect b);
bool checkCollision(SDL_Rect &a, SDL_Rect &b);
// Carga un archivo de imagen en una textura
bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer);
// Detector de colisiones entre un punto y u rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r);
// Devuelve un color_t a partir de un string
color_t stringToColor(std::string str);

View File

@@ -1,158 +0,0 @@
#include "const.h"
#include "writer.h"
// Constructor
Writer::Writer(Text *text)
{
mText = text;
init();
}
// Destructor
Writer::~Writer()
{
mText = nullptr;
}
// Inicializador
void Writer::init()
{
mPosX = 0;
mPosY = 0;
mKerning = 0;
mCaption = "";
mSpeed = 0;
mTimer = 0;
mIndex = 0;
mLenght = 0;
mCompleted = false;
mEnabled = false;
mEnabledTimer = 0;
mId = -1;
mIntroEvents = nullptr;
}
// Establece el valor de la variable
void Writer::setPosX(int value)
{
mPosX = value;
}
// Establece el valor de la variable
void Writer::setPosY(int value)
{
mPosY = value;
}
// Establece el valor de la variable
void Writer::setKerning(int value)
{
mKerning = value;
}
// Establece el valor de la variable
void Writer::setCaption(std::string text)
{
mCaption = text;
mLenght = text.length();
}
// Establece el valor de la variable
void Writer::setSpeed(Uint16 value)
{
mSpeed = value;
mTimer = value;
}
// Establece el valor de la variable
void Writer::setEnabled(bool value)
{
mEnabled = value;
}
// Obtiene el valor de la variable
bool Writer::IsEnabled()
{
return mEnabled;
}
// Establece el valor de la variable
void Writer::setEnabledTimer(Uint16 value)
{
mEnabledTimer = value;
}
// Obtiene el valor de la variable
Uint16 Writer::getEnabledTimer()
{
return mEnabledTimer;
}
// Actualiza el objeto
void Writer::update()
{
if (mEnabled)
{
if (mCompleted == false)
{
if (mTimer > 0)
{
mTimer--;
}
if (mTimer == 0)
{
mIndex++;
mTimer = mSpeed;
}
if (mIndex == mLenght)
{
mCompleted = true;
}
}
if (mCompleted)
{
if (mEnabledTimer > 0)
{
mEnabledTimer--;
}
else if (mEnabledTimer == 0)
{
if (mId < 0)
{
mEnabled = false;
}
else
{
mIntroEvents[mId] = EVENT_COMPLETED;
}
}
}
}
}
// Dibuja el objeto en pantalla
void Writer::render()
{
if (mEnabled)
{
mText->write(mPosX, mPosY, mCaption, mKerning, mIndex);
}
}
// Centra la cadena de texto a un punto X
void Writer::center(int x)
{
setPosX(x - (mText->lenght(mCaption, mKerning) / 2));
}
// Establece el valor de la variable
void Writer::setId(int id)
{
mId = id;
}
// Establece el valor de la variable
void Writer::setIntroEvents(Uint8 *value)
{
mIntroEvents = value;
}

View File

@@ -1,80 +0,0 @@
#pragma once
#include "sprite.h"
#include "text.h"
#ifndef WRITER_H
#define WRITER_H
// Clase texto. Pinta texto en pantalla a partir de un bitmap
class Writer
{
private:
int mPosX; // Posicion en el eje X donde empezar a escribir el texto
int mPosY; // Posicion en el eje Y donde empezar a escribir el texto
int mKerning; // Kerning del texto, es decir, espaciado entre caracteres
std::string mCaption; // El texto para escribir
Uint16 mSpeed; // Velocidad de escritura
Uint16 mTimer; // Temporizador de escritura para cada caracter
Uint16 mIndex; // Posición del texto que se está escribiendo
Uint16 mLenght; // Longitud de la cadena a escribir
bool mCompleted; // Indica si se ha escrito todo el texto
bool mEnabled; // Indica si el objeto está habilitado
Uint16 mEnabledTimer; // Temporizador para deshabilitar el objeto
int mId; // Temporizador para deshabilitar el objeto
Uint8 *mIntroEvents; // Dirección del array de eventos donde notificar el estado
Text *mText; // Objeto encargado de escribir el texto
public:
// Constructor
Writer(Text *text);
// Destructor
~Writer();
// Inicializador
void init();
// Establece el valor de la variable
void setPosX(int value);
// Establece el valor de la variable
void setPosY(int value);
// Establece el valor de la variable
void setKerning(int value);
// Establece el valor de la variable
void setCaption(std::string text);
// Establece el valor de la variable
void setSpeed(Uint16 value);
// Establece el valor de la variable
void setEnabled(bool value);
// Obtiene el valor de la variable
bool IsEnabled();
// Establece el valor de la variable
void setEnabledTimer(Uint16 value);
// Obtiene el valor de la variable
Uint16 getEnabledTimer();
// Actualiza el objeto
void update();
// Dibuja el objeto en pantalla
void render();
// Centra la cadena de texto a un punto X
void center(int x);
// Establece el valor de la variable
void setId(int id);
// Establece el valor de la variable
void setIntroEvents(Uint8 *value);
};
#endif

66
todo.txt Normal file
View File

@@ -0,0 +1,66 @@
## TAREAS
x (A) Hacer que deje de poder moverse tras el salto al alcanzar la misma posicion en altura que tenia cuando saltó {cm:2022-08-29}
x (A) Arreglar que no atraviese tiles atravaseables al caer muy rapido {cm:2022-08-29}
x (A) Leer los mapas directamente del archivo tmx {cm:2022-08-29}
x (A) Crear la clase item {cm:2022-08-29}
x (A) Colisiones con los enemigos {cm:2022-08-29}
x (A) Decidir un diseño para qué sucede en caso de morir: Recordar el punto por donde se entró al mapa y la velocidad en el eje X/Y que llevaba el personaje, crear puntos de reaparicion en las habitaciones, etc {cm:2022-08-29}
x En el Jet Set Willy el juego recuerda la posicion y el momento. En las Tres Luces de Glaurung solo la posición. Se va a optar por seguir el diseño del Jet Set Willy {cm:2022-08-29}
x (A) Crear tiles que maten {cm:2022-08-29}
(A) Modificar el salto para que coincida con el del JSW, no ha de colisionar lateralmente
(A) Crear tiles que deslicen, (no tipo hielo sino cinta)
(A) Tiles animados
(A) Crear ascensores
x (A) Enemigos de diferente tamaño {cm:2022-08-30}
(A) Color de los items al estilo jet set willy de amstrad, que brillan con dos colores
x (A) Temporizador de inicio de los items, para poder hacer que brillen a distinto ritmo. Esto es incompatible con lo anterior {cm:2022-08-30}
(A) Crear efecto de fade estilo spectrum, cambiando el color de las cosas a rojo, morado, azul, negro
x (A) Poner la info de debug con la tipografia adecuada {cm:2022-08-30}
x (A) El modo debug debe pintar la rejilla {cm:2022-08-30}
x (A) Tecla F para pasar a pantalla completa {cm:2022-08-30}
x (A) Tecla + y - para cambiar tamaño de ventana. O control F1 a F4 {cm:2022-08-30}
(A) Poner en el marcador el indicador de si esta sonando la música
(A) Poner en el marcador el numero de habitaciones visitadas
(A) Añadir a cada habitación el color del borde
(A) Añadir a cada habitación el color del nombre de la habitación
(A) Crear el logo al estilo del logo de ERBE o TOPO, con lineas que lo formen
(A) El titulo del juego hacerlo parecido al del Jet Set Willy in Paris
- Ha de generarse como las cargas de pantalla de spectrum
- Luego se colorea
- Finalmente, cada elemento cambia de color como si fueran luces de neon
(A) En el titulo del juego, por la parte inferior ha de aparecer una marquesina con texto, al estilo demoscene
(A) La pantalla de titulo no tiene menu, solo un PRESS ENTER TO PLAY
## TEMAS
arounders
paku simbel
jail battle
arounders race
aee gba
matatunos
x sigmasua
calculin doom
leaper reaper
mini ascii
mappy
paco
chirping
abad y batman
jail
counter strike
starcraft
diablo
jailparty
maniac mansion
molotov
tutorials
gavina
puzzle restorer
qvoid
brick roll
dante's fall
repairing computers