49 Commits
v0.5 ... 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
92 changed files with 2970 additions and 3766 deletions

View File

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

View File

@@ -1,17 +1,18 @@
name=void main name=void main
bg_color=black bgColor=black
tileset=room1.png tileset=standard.png
room_up=0 roomUp=0
room_down=0 roomDown=0
room_left=0 roomLeft=0
room_right=02.room roomRight=02.room
[tilemap] [tilemap]
room1.tmx 01.tmx
[tilemap-end] [/tilemap]
[enemy] [enemy]
tileset=enemy01.png tileset=paco.png
animation=paco.ani
width=16 width=16
height=16 height=16
x=1 x=1
@@ -23,10 +24,11 @@ y1=0
x2=1 x2=1
y2=6 y2=6
color=red color=red
[enemy-end] [/enemy]
[enemy] [enemy]
tileset=enemy01.png tileset=paco.png
animation=paco.ani
width=16 width=16
height=16 height=16
x=5 x=5
@@ -38,18 +40,62 @@ y1=9
x2=22 x2=22
y2=9 y2=9
color=yellow color=yellow
[enemy-end] [/enemy]
[item] [item]
tileset=items.png tileset=items.png
tile=0 tile=0
x=1 x=1
y=7 y=7
[item-end] counter=6
[/item]
[item] [item]
tileset=items.png tileset=items.png
tile=0 tile=0
x=17 x=17
y=8 y=8
[item-end] 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]

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <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="../../resources/tilesets/room1.tsx"/> <tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16"> <layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv"> <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,

View File

@@ -1,17 +1,18 @@
name=case switch name=case switch
bg_color=black bgColor=black
tileset=room1.png tileset=standard.png
room_up=0 roomUp=0
room_down=04.room roomDown=04.room
room_left=01.room roomLeft=01.room
room_right=03.room roomRight=03.room
[tilemap] [tilemap]
room2.tmx 02.tmx
[tilemap-end] [/tilemap]
[enemy] [enemy]
tileset=enemy01.png tileset=paco.png
animation=paco.ani
width=16 width=16
height=16 height=16
x=14 x=14
@@ -23,11 +24,11 @@ y1=0
x2=14 x2=14
y2=12 y2=12
color=purple color=purple
[enemy-end] [/enemy]
[item] [item]
tileset=items.png tileset=items.png
tile=1 tile=1
x=19 x=19
y=6 y=6
[item-end] [/item]

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <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="../../resources/tilesets/room1.tsx"/> <tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16"> <layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv"> <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,

View File

@@ -1,17 +1,18 @@
name=the edge name=the edge
bg_color=light_black bgColor=light_black
tileset=room1.png tileset=standard.png
room_up=0 roomUp=0
room_down=0 roomDown=05.room
room_left=02.room roomLeft=02.room
room_right=0 roomRight=0
[tilemap] [tilemap]
room3.tmx 03.tmx
[tilemap-end] [/tilemap]
[enemy] [enemy]
tileset=enemy02.png tileset=chip.png
animation=chip.ani
width=8 width=8
height=16 height=16
x=4 x=4
@@ -23,10 +24,11 @@ y1=2
x2=4 x2=4
y2=13 y2=13
color=green color=green
[enemy-end] [/enemy]
[enemy] [enemy]
tileset=enemy02.png tileset=chip.png
animation=chip.ani
width=8 width=8
height=16 height=16
x=10 x=10
@@ -38,10 +40,11 @@ y1=2
x2=10 x2=10
y2=13 y2=13
color=light_blue color=light_blue
[enemy-end] [/enemy]
[enemy] [enemy]
tileset=enemy02.png tileset=chip.png
animation=chip.ani
width=8 width=8
height=16 height=16
x=16 x=16
@@ -53,11 +56,11 @@ y1=2
x2=16 x2=16
y2=13 y2=13
color=purple color=purple
[enemy-end] [/enemy]
[item] [item]
tileset=items.png tileset=items.png
tile=5 tile=5
x=12 x=12
y=2 y=2
[item-end] [/item]

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <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="../../resources/tilesets/room1.tsx"/> <tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16"> <layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv"> <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,

View File

@@ -1,17 +1,18 @@
name=The Fridge name=The Fridge
bg_color=blue bgColor=blue
tileset=room1.png tileset=standard.png
room_up=02.room roomUp=02.room
room_down=0 roomDown=0
room_left=0 roomLeft=0
room_right=05.room roomRight=05.room
[tilemap] [tilemap]
room4.tmx 04.tmx
[tilemap-end] [/tilemap]
[enemy] [enemy]
tileset=enemy02.png tileset=chip.png
animation=chip.ani
width=8 width=8
height=16 height=16
x=1 x=1
@@ -23,10 +24,11 @@ y1=3
x2=14 x2=14
y2=3 y2=3
color=purple color=purple
[enemy-end] [/enemy]
[enemy] [enemy]
tileset=enemy02.png tileset=chip.png
animation=chip.ani
width=8 width=8
height=16 height=16
x=30 x=30
@@ -38,10 +40,11 @@ y1=7
x2=30 x2=30
y2=7 y2=7
color=light_white color=light_white
[enemy-end] [/enemy]
[enemy] [enemy]
tileset=enemy03.png tileset=wave.png
animation=wave.ani
width=8 width=8
height=8 height=8
x=15 x=15
@@ -53,21 +56,21 @@ y1=12
x2=30 x2=30
y2=12 y2=12
color=light_purple color=light_purple
[enemy-end] [/enemy]
[item] [item]
tileset=items.png tileset=items.png
tile=6 tile=6
x=2 x=2
y=2 y=2
[item-end] [/item]
[item] [item]
tileset=items.png tileset=items.png
tile=6 tile=6
x=29 x=29
y=5 y=5
[item-end] [/item]
[item] [item]
@@ -75,4 +78,4 @@ tileset=items.png
tile=6 tile=6
x=21 x=21
y=12 y=12
[item-end] [/item]

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <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="../../resources/tilesets/room1.tsx"/> <tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16"> <layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv"> <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,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,

View File

@@ -1,11 +1,107 @@
name=coruscant name=sigmasua
bg_color=light_black bgColor=black
tileset=room1.png tileset=standard.png
room_up=03.room roomUp=03.room
room_down=0 roomDown=0
room_left=04.room roomLeft=04.room
room_right=0 roomRight=0
[tilemap] [tilemap]
room5.tmx 05.tmx
[tilemap-end] [/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>

View File

@@ -1,24 +0,0 @@
<?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="../../resources/tilesets/room1.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv">
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,0,
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,0,
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,0,
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,0,
25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,0,0,0,
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,0,
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,0,
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,0,
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,0,
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,0,
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,0,
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,0,
25,0,0,0,0,0,0,0,48,0,0,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,48,48,382,382,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,48,48,48,47,47,48,48,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48
</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]

View File

Before

Width:  |  Height:  |  Size: 208 B

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]

View File

Before

Width:  |  Height:  |  Size: 149 B

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 B

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/sound/item.wav Normal file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

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,124 +1,278 @@
#include "const.h"
#include "animatedsprite.h" #include "animatedsprite.h"
// Constructor // Constructor
AnimatedSprite::AnimatedSprite(LTexture *texture, SDL_Renderer *renderer) AnimatedSprite::AnimatedSprite(LTexture *texture, SDL_Renderer *renderer, std::string file)
{ {
// Copia los punteros // Copia los punteros
setTexture(texture); setTexture(texture);
setRenderer(renderer); setRenderer(renderer);
init(); // Carga las animaciones
load(file);
// Inicializa variables
currentAnimation = 0;
} }
// Destructor // Destructor
AnimatedSprite::~AnimatedSprite() AnimatedSprite::~AnimatedSprite()
{ {
for (auto &a : animation)
{
a.frames.clear();
}
animation.clear();
} }
// Iniciador // Obtiene el indice de la animación a partir del nombre
void AnimatedSprite::init() 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; if (animation[i].name == name)
mAnimation[i].speed = 0;
mAnimation[i].loop = true;
mAnimation[i].completed = false;
for (int j = 0; i < 20; i++)
{ {
mAnimation[i].frames[j].x = 0; index = i;
mAnimation[i].frames[j].y = 0; }
mAnimation[i].frames[j].w = 0; }*/
mAnimation[i].frames[j].h = 0; 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 // 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 return;
mCurrentFrame = mAnimationCounter / mAnimation[index].speed; }
// Si alcanzamos el final de la animación, reiniciamos el contador de la animación // Calcula el frame actual a partir del contador
// en función de la variable loop animation[currentAnimation].currentFrame = animation[currentAnimation].counter / animation[currentAnimation].speed;
if (mCurrentFrame >= mAnimation[index].numFrames)
// 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) if (animation[currentAnimation].loop == -1)
mAnimationCounter = 0; { // Si no hay loop, deja el último frame
animation[currentAnimation].currentFrame = animation[currentAnimation].frames.size();
animation[currentAnimation].completed = true;
}
else 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 // En caso contrario
else else
{ {
// Escogemos el frame correspondiente de la animación // Escoge el frame correspondiente de la animación
setSpriteClip(mAnimation[index].frames[mCurrentFrame]); setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
// Incrementamos el contador de la animacion // Incrementa el contador de la animacion
mAnimationCounter++; animation[currentAnimation].counter++;
}
} }
} }
// Establece el frame actual de la animación // 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 // Establece el valor del contador
void AnimatedSprite::setAnimationCounter(Uint16 num) void AnimatedSprite::setAnimationCounter(std::string name, int num)
{ {
mAnimationCounter = num; animation[getIndex(name)].counter = 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;
} }
// Establece la velocidad de una animación // 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; animation[getIndex(name)].counter = speed;
}
// Establece el numero de frames de una animación
void AnimatedSprite::setAnimationNumFrames(Uint8 index, Uint8 num)
{
mAnimation[index].numFrames = num;
} }
// Establece si la animación se reproduce en bucle // 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 // 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 // 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 // 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 #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "movingsprite.h" #include "movingsprite.h"
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#ifndef ANIMATEDSPRITE_H #ifndef ANIMATEDSPRITE_H
#define ANIMATEDSPRITE_H #define ANIMATEDSPRITE_H
#define MAX_FRAMES 30
#define MAX_ANIMATIONS 20
// Clase AnimatedSprite // Clase AnimatedSprite
class AnimatedSprite : public MovingSprite class AnimatedSprite : public MovingSprite
{ {
private: private:
struct sAnimation struct t_animation
{ {
SDL_Rect frames[MAX_FRAMES]; // Cada uno de los frames que componen la animación std::string name; // Nombre de la animacion
Uint8 numFrames; // Numero de frames que componen la animación std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
Uint8 speed; // Velocidad de la animación int speed; // Velocidad de la animación
bool loop; // Indica si la animación se reproduce en bucle int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
bool completed; // Indica si ha finalizado la animación bool completed; // Indica si ha finalizado la animación
int currentFrame; // Frame actual
int counter; // Contador para las animaciones
}; };
sAnimation mAnimation[MAX_ANIMATIONS]; // Vector con las diferentes animaciones std::vector<t_animation> animation; // Vector con las diferentes animaciones
int currentAnimation; // Animacion activa
Uint8 mCurrentFrame; // Frame actual
Uint16 mAnimationCounter; // Contador para las animaciones
public: public:
// Constructor // Constructor
AnimatedSprite(LTexture *texture = nullptr, SDL_Renderer *renderer = nullptr); AnimatedSprite(LTexture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "");
// Destructor // Destructor
~AnimatedSprite(); ~AnimatedSprite();
// Iniciador // Calcula el frame correspondiente a la animación actual
void init(); void animate();
// Calcula el frame correspondiente a la animación
void animate(int index);
// Establece el frame actual de la animación // Establece el frame actual de la animación
void setCurrentFrame(Uint8 num); void setCurrentFrame(int num);
// Establece el valor del contador // Establece el valor del contador
void setAnimationCounter(Uint16 num); void setAnimationCounter(std::string name, int 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);
// Establece la velocidad de una animación // 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 // Establece el frame al que vuelve la animación al finalizar
void setAnimationNumFrames(Uint8 index, Uint8 num); void setAnimationLoop(std::string name, int loop);
// Establece si la animación se reproduce en bucle
void setAnimationLoop(Uint8 index, bool loop);
// Establece el valor de la variable // 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 // Comprueba si ha terminado la animación
bool isCompleted(Uint8 index); bool animationIsCompleted();
// Devuelve el rectangulo de una animación y frame concreto // 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 #endif

View File

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

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -32,6 +33,8 @@ private:
bool required; // Indica si es un fichero que debe de existir 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::vector<item_t> mFileList;
std::string mExecutablePath; std::string mExecutablePath;

View File

@@ -1,4 +1,5 @@
#pragma once #pragma once
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <string> #include <string>
#include "utils.h" #include "utils.h"
@@ -15,18 +16,10 @@
#define BLOCK 8 #define BLOCK 8
#define HALF_BLOCK 4 #define HALF_BLOCK 4
// Tamaño de la pantalla real
#define SCREEN_WIDTH 256
#define SCREEN_HEIGHT 192
// Tamaño de la pantalla virtual // Tamaño de la pantalla virtual
#define GAMECANVAS_WIDTH 256 #define GAMECANVAS_WIDTH 256
#define GAMECANVAS_HEIGHT 192 #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 // Zona de juego
const int PLAY_AREA_TOP = (0 * BLOCK); const int PLAY_AREA_TOP = (0 * BLOCK);
const int PLAY_AREA_BOTTOM = (16 * BLOCK); const int PLAY_AREA_BOTTOM = (16 * BLOCK);
@@ -61,37 +54,8 @@ const int GAMECANVAS_THIRD_QUARTER_Y = (GAMECANVAS_HEIGHT / 4) * 3;
#define SECTION_PROG_GAME 3 #define SECTION_PROG_GAME 3
#define SECTION_PROG_QUIT 4 #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 // Colores
const color_t bgColor = {0x27, 0x27, 0x36}; const color_t borderColor = {0x27, 0x27, 0x36};
const color_t noColor = {0xFF, 0xFF, 0xFF}; const color_t black = {0xFF, 0xFF, 0xFF};
const color_t shdwTxtColor = {0x43, 0x43, 0x4F};
// Tipo de filtro
#define FILTER_NEAREST 0
#define FILTER_LINEAL 1
#endif #endif

View File

@@ -1,4 +1,4 @@
#include "const.h"
#include "utils.h" #include "utils.h"
#include "director.h" #include "director.h"
#include <iostream> #include <iostream>
@@ -7,39 +7,30 @@
// Constructor // Constructor
Director::Director(std::string path) Director::Director(std::string path)
{ {
// Inicializa la ruta
setExecutablePath(path);
// Crea el objeto que controla los ficheros de recursos // Crea el objeto que controla los ficheros de recursos
mAsset = new Asset(mExecutablePath); asset = new Asset(path.substr(0, path.find_last_of("\\/")));
// Establece la lista de ficheros
setFileList();
// Si falta algún fichero no inicia el programa // Si falta algún fichero no inicia el programa
Uint8 section = SECTION_PROG_GAME; if (!setFileList())
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())
{ {
mOptions->fullScreenMode = 0; section.name = SECTION_PROG_QUIT;
mOptions->windowSize = 3; }
mOptions->language = en_UK; else
mOptions->difficulty = DIFFICULTY_NORMAL; {
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD; section.name = SECTION_PROG_LOGO;
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER; section.subsection = 0;
mOptions->filter = FILTER_NEAREST;
mOptions->vSync = true;
} }
// Crea los objetos // Crea el puntero a la estructura y carga el fichero de configuración
mInput = new Input(mAsset->get("gamecontrollerdb.txt")); 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 // Inicializa SDL
initSDL(); initSDL();
@@ -47,70 +38,48 @@ Director::Director(std::string path)
// Inicializa JailAudio // Inicializa JailAudio
initJailAudio(); initJailAudio();
// Aplica las opciones // Crea los objetos
SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode); input = new Input(asset->get("gamecontrollerdb.txt"));
SDL_SetWindowSize(mWindow, SCREEN_WIDTH * mOptions->windowSize, SCREEN_HEIGHT * mOptions->windowSize); initInput();
mLang->setLang(mOptions->language); screen = new Screen(window, renderer, options, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
screen->setBorderColor(borderColor);
// Inicializa el resto de variables
init(section);
} }
Director::~Director() Director::~Director()
{ {
saveConfigFile(); delete options;
delete asset;
delete mInput; delete input;
mInput = nullptr; delete screen;
delete mLang;
mLang = nullptr;
delete mOptions;
mOptions = nullptr;
delete mAsset;
mAsset = nullptr;
SDL_DestroyRenderer(mRenderer);
SDL_DestroyWindow(mWindow);
mRenderer = nullptr;
mWindow = nullptr;
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit(); SDL_Quit();
} }
// Inicia las variables necesarias para arrancar el programa // Inicia las variables necesarias para arrancar el programa
void Director::init(Uint8 name) void Director::initInput()
{ {
// Sección input->bindKey(INPUT_UP, SDL_SCANCODE_UP);
mSection.name = name; input->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN);
mSection.subsection = 0; 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 input->bindGameControllerButton(INPUT_UP, SDL_CONTROLLER_BUTTON_DPAD_UP);
mLang->setLang(mOptions->language); input->bindGameControllerButton(INPUT_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
input->bindGameControllerButton(INPUT_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
// Controles input->bindGameControllerButton(INPUT_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
mInput->bindKey(INPUT_UP, SDL_SCANCODE_UP); input->bindGameControllerButton(INPUT_ACCEPT, SDL_CONTROLLER_BUTTON_B);
mInput->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN); input->bindGameControllerButton(INPUT_CANCEL, SDL_CONTROLLER_BUTTON_A);
mInput->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT); input->bindGameControllerButton(INPUT_BUTTON_1, SDL_CONTROLLER_BUTTON_B);
mInput->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT); input->bindGameControllerButton(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE);
mInput->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN); input->bindGameControllerButton(INPUT_BUTTON_ESCAPE, SDL_CONTROLLER_BUTTON_GUIDE);
mInput->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE);
mInput->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_SPACE);
mInput->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_D);
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);
} }
// Inicializa JailAudio // Inicializa JailAudio
@@ -127,7 +96,6 @@ bool Director::initSDL()
// Inicializa SDL // Inicializa SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0) 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()); printf("SDL could not initialize!\nSDL Error: %s\n", SDL_GetError());
success = false; success = false;
@@ -138,14 +106,14 @@ bool Director::initSDL()
std::srand(static_cast<unsigned int>(SDL_GetTicks())); std::srand(static_cast<unsigned int>(SDL_GetTicks()));
// Establece el filtro de la textura a nearest // 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"); printf("Warning: Nearest texture filtering not enabled!\n");
} }
// Crea la ventana // 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); window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, options->screenWidth, options->screenHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (mWindow == NULL) if (window == NULL)
{ {
printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError()); printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false; success = false;
@@ -153,12 +121,12 @@ bool Director::initSDL()
else else
{ {
// Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones // Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones
if (mOptions->vSync) if (options->vSync)
mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
else 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()); printf("Renderer could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false; success = false;
@@ -166,13 +134,13 @@ bool Director::initSDL()
else else
{ {
// Inicializa el color de renderizado // 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 // 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 // Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(mRenderer, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
} }
} }
} }
@@ -182,198 +150,108 @@ bool Director::initSDL()
} }
// Crea el indice de ficheros // Crea el indice de ficheros
void Director::setFileList() bool Director::setFileList()
{ {
mAsset->add("/media/font/8bithud.png", font); asset->add("/media/font/smb2.png", font);
mAsset->add("/media/font/8bithud.txt", font); asset->add("/media/font/smb2.txt", font);
mAsset->add("/media/font/nokia.png", font); asset->add("/media/font/debug.png", font);
mAsset->add("/media/font/nokia.txt", font); asset->add("/media/font/debug.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("/data/room/03.room", room);
mAsset->add("/data/room/04.room", room);
mAsset->add("/data/room/05.room", room);
mAsset->add("/data/room/room1.tmx", room);
mAsset->add("/data/room/room2.tmx", room);
mAsset->add("/data/room/room3.tmx", room);
mAsset->add("/data/room/room4.tmx", room);
mAsset->add("/data/room/room5.tmx", room);
mAsset->add("/media/tilesets/room1.png", bitmap);
mAsset->add("/media/enemies/enemy01.png", bitmap);
mAsset->add("/media/enemies/enemy02.png", bitmap);
mAsset->add("/media/enemies/enemy03.png", bitmap);
mAsset->add("/media/player/player01.png", bitmap);
mAsset->add("/media/items/items.png", bitmap);
}
// Carga el fichero de configuración asset->add("/data/gamecontrollerdb.txt", data);
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;
// Indicador de éxito en la carga asset->add("/data/room/01.room", room);
bool success = true; 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"); asset->add("/media/tilesets/standard.png", bitmap);
std::string filename = p.substr(p.find_last_of("\\/") + 1);
SDL_RWops *file = SDL_RWFromFile(p.c_str(), "r+b");
// El fichero no existe asset->add("/media/enemies/paco.png", bitmap);
if (file == NULL) asset->add("/media/enemies/paco.ani", data);
{ asset->add("/media/enemies/chip.png", bitmap);
printf("Warning: Unable to open %s file\n", filename.c_str()); 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 asset->add("/media/player/player01.png", bitmap);
file = SDL_RWFromFile(p.c_str(), "w+b"); asset->add("/media/player/player01.ani", data);
if (file != NULL)
{
printf("New file (%s) created!\n", filename.c_str());
// Escribe los datos asset->add("/media/items/items.png", bitmap);
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);
// Cierra el fichero asset->add("/media/music/title.ogg", music);
SDL_RWclose(file); asset->add("/media/music/game.ogg", music);
}
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);
// Normaliza los valores asset->add("/media/sound/item.wav", sound);
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;
// Cierra el fichero asset->add("/media/logo/jailgames.png", bitmap);
SDL_RWclose(file); 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 return asset->check();
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("\\/"));
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint8 Director::getSubsection() Uint8 Director::getSubsection()
{ {
return mSection.subsection; return section.subsection;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint8 Director::getSection() Uint8 Director::getSection()
{ {
return mSection.name; return section.name;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Director::setSection(section_t section) void Director::setSection(section_t section)
{ {
mSection = section; this->section = section;
} }
// Ejecuta la seccion de juego con el logo
void Director::runLogo() 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() void Director::runIntro()
{ {
} }
// Ejecuta la seccion de juego con el titulo y los menus
void Director::runTitle() 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() void Director::runGame()
{ {
mGame = new Game(mWindow, mRenderer, mAsset, mLang, mInput); game = new Game(renderer, screen, asset, input);
setSection(mGame->run()); setSection(game->run());
delete mGame; delete game;
} }
void Director::run() void Director::run()
{ {
// Bucle principal // Bucle principal
while (!(getSection() == SECTION_PROG_QUIT)) while (getSection() != SECTION_PROG_QUIT)
{ {
switch (getSection()) switch (getSection())
{ {

View File

@@ -1,40 +1,37 @@
#pragma once #pragma once
#include "ifdefs.h" #include <SDL2/SDL.h>
#include "sprite.h" #include "sprite.h"
#include "movingsprite.h" #include "movingsprite.h"
#include "text.h" #include "text.h"
#include "writer.h"
#include "menu.h"
#include "const.h"
#include "jail_audio.h" #include "jail_audio.h"
#include "utils.h" #include "utils.h"
#include "input.h" #include "input.h"
#include "fade.h"
#include "game.h" #include "game.h"
#include "logo.h"
#include "title.h"
#include "asset.h" #include "asset.h"
#include "lang.h" #include "const.h"
#ifndef DIRECTOR_H #ifndef DIRECTOR_H
#define DIRECTOR_H #define DIRECTOR_H
#define MAX_FILE_LIST 100
// Director // Director
class Director class Director
{ {
private: private:
SDL_Window *mWindow; // La ventana donde dibujamos SDL_Window *window; // La ventana donde dibujamos
SDL_Renderer *mRenderer; // El renderizador de la ventana 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 struct options_t *options; // Variable con todas las opciones del programa
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 *mOptions; // Variable con todas las opciones del programa std::string executablePath; // Path del ejecutable
section_t section; // Sección y subsección actual del programa;
std::string mExecutablePath; // Path del ejecutable
section_t mSection; // Sección y subsección actual del programa;
// Inicializa jail_audio // Inicializa jail_audio
void initJailAudio(); void initJailAudio();
@@ -42,20 +39,11 @@ private:
// Arranca SDL y crea la ventana // Arranca SDL y crea la ventana
bool initSDL(); bool initSDL();
// Inicializa el objeto Input
void initInput();
// Crea el indice de ficheros // Crea el indice de ficheros
void setFileList(); bool 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);
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint8 getSubsection(); Uint8 getSubsection();
@@ -78,9 +66,6 @@ private:
// Ejecuta la seccion de juego donde se juega // Ejecuta la seccion de juego donde se juega
void runGame(); void runGame();
// Comprueba los ficheros del vector de ficheros que coinciden con una ruta dada
bool checkFolder(std::string name, std::string path);
public: public:
// Constructor // Constructor
Director(std::string path); Director(std::string path);
@@ -88,9 +73,6 @@ public:
// Destructor // Destructor
~Director(); ~Director();
// Inicia las variables necesarias para arrancar el programa
void init(Uint8 name);
// Bucle principal // Bucle principal
void run(); void run();
}; };

View File

@@ -10,11 +10,8 @@ Enemy::Enemy(enemy_t enemy)
renderer = enemy.renderer; renderer = enemy.renderer;
// Crea objetos // Crea objetos
texture = new LTexture(); texture = new LTexture(renderer, asset->get(enemy.tileset));
sprite = new AnimatedSprite(texture, renderer); sprite = new AnimatedSprite(texture, renderer, asset->get(enemy.animation));
// Carga la textura
loadTextureFromFile(texture, asset->get(enemy.tileset), renderer);
// Obten el resto de valores // Obten el resto de valores
x1 = enemy.x1; x1 = enemy.x1;
@@ -26,20 +23,8 @@ Enemy::Enemy(enemy_t enemy)
sprite->setPosY(enemy.y); sprite->setPosY(enemy.y);
sprite->setVelX(enemy.vx); sprite->setVelX(enemy.vx);
sprite->setVelY(enemy.vy); sprite->setVelY(enemy.vy);
// Inicializa el sprite con el resto de parametros comunes
sprite->setWidth(enemy.w); sprite->setWidth(enemy.w);
sprite->setHeight(enemy.h); sprite->setHeight(enemy.h);
sprite->setCurrentFrame(0);
sprite->setAnimationCounter(0);
sprite->setAnimationNumFrames(0, 4);
sprite->setAnimationSpeed(0, 5);
sprite->setAnimationLoop(0, true);
sprite->setAnimationFrames(0, 0, enemy.w * 0, 0, enemy.w, enemy.h);
sprite->setAnimationFrames(0, 1, enemy.w * 1, 0, enemy.w, enemy.h);
sprite->setAnimationFrames(0, 2, enemy.w * 2, 0, enemy.w, enemy.h);
sprite->setAnimationFrames(0, 3, enemy.w * 3, 0, enemy.w, enemy.h);
sprite->setSpriteClip(sprite->getAnimationClip(0, 0));
collider = getRect(); collider = getRect();
} }
@@ -47,16 +32,12 @@ Enemy::Enemy(enemy_t enemy)
// Destructor // Destructor
Enemy::~Enemy() Enemy::~Enemy()
{ {
texture->unload();
delete texture; delete texture;
texture = nullptr;
delete sprite; delete sprite;
sprite = nullptr;
} }
// Pinta el enemigo en pantalla // Pinta el enemigo en pantalla
void Enemy::draw() void Enemy::render()
{ {
sprite->getTexture()->setColor(color.r, color.g, color.b); sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->render(); sprite->render();
@@ -67,7 +48,7 @@ void Enemy::draw()
void Enemy::update() void Enemy::update()
{ {
sprite->update(); sprite->update();
sprite->animate(0); // sprite->animate();
checkPath(); checkPath();
collider = getRect(); collider = getRect();
} }
@@ -97,3 +78,9 @@ SDL_Rect &Enemy::getCollider()
{ {
return collider; return collider;
} }
// Recarga la textura
void Enemy::reLoadTexture()
{
texture->reLoad();
}

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include "ifdefs.h" #include <SDL2/SDL.h>
#include "utils.h" #include "utils.h"
#include "asset.h" #include "asset.h"
#include "animatedsprite.h" #include "animatedsprite.h"
@@ -29,6 +29,7 @@ struct enemy_t
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
std::string tileset; // Fichero con los graficos del enemigo std::string tileset; // Fichero con los graficos del enemigo
std::string animation; // Fichero con las animaciones del enemigo
int w; // Anchura del enemigo int w; // Anchura del enemigo
int h; // Altura del enemigo int h; // Altura del enemigo
float x; // Posición inicial en el eje X float x; // Posición inicial en el eje X
@@ -69,7 +70,7 @@ public:
~Enemy(); ~Enemy();
// Pinta el enemigo en pantalla // Pinta el enemigo en pantalla
void draw(); void render();
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update();
@@ -79,6 +80,9 @@ public:
// Obtiene el rectangulo de colision del enemigo // Obtiene el rectangulo de colision del enemigo
SDL_Rect &getCollider(); SDL_Rect &getCollider();
// Recarga la textura
void reLoadTexture();
}; };
#endif #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,202 +1,247 @@
#include "game.h" #include "game.h"
// Constructor // 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)
{ {
// Inicia variables // Inicia variables
mCurrentRoom = "02.room"; clock = SDL_GetTicks();
mSpawnPoint = {2 * BLOCK, 12 * BLOCK, 0, 0, 0, STATUS_STANDING, SDL_FLIP_NONE}; currentRoom = "01.room";
mDebug = false; spawnPoint = {2 * 8, 12 * 8, 0, 0, 0, STATUS_STANDING, SDL_FLIP_NONE};
debug = false;
// Copia los punteros // Copia los punteros
mRenderer = renderer; this->renderer = renderer;
mAsset = asset; this->asset = asset;
mLang = lang; this->screen = screen;
mInput = input; this->input = input;
// Crea los objetos // Crea los objetos
mScreen = new Screen(window, renderer); scoreboard = new ScoreBoard(renderer, asset, &playerLives, &itemsPicked, &clock);
mItemTracker = new Item_tracker(); itemTracker = new ItemTracker();
mRoom = new Room(mAsset->get(mCurrentRoom), mRenderer, mAsset, mItemTracker); room = new Room(asset->get(currentRoom), renderer, asset, itemTracker, &itemsPicked);
mPlayer = new Player(mSpawnPoint, mAsset->get("player01.png"), mRenderer, mAsset, mInput, mRoom); player = new Player(spawnPoint, asset->get("player01.png"), asset->get("player01.ani"), renderer, asset, input, room);
mEventHandler = new SDL_Event(); eventHandler = new SDL_Event();
mTextureText = new LTexture(); text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
mText = new Text(mAsset->get("smb2.txt"), mTextureText, renderer); debugText = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer);
mFade = new Fade(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() Game::~Game()
{ {
// Borra las referencias a los punteros // Borra las referencias a los punteros
mRenderer = nullptr; renderer = nullptr;
mAsset = nullptr; asset = nullptr;
mLang = nullptr; input = nullptr;
mInput = nullptr;
// Libera la memoria de los objetos // Libera la memoria de los objetos
delete mScreen; delete scoreboard;
mScreen = nullptr; scoreboard = nullptr;
delete mItemTracker; delete itemTracker;
mItemTracker = nullptr; itemTracker = nullptr;
delete mRoom; delete room;
mRoom = nullptr; room = nullptr;
delete mPlayer; delete player;
mPlayer = nullptr; player = nullptr;
delete mEventHandler; delete eventHandler;
mEventHandler = nullptr; eventHandler = nullptr;
mTextureText->unload(); delete text;
delete mTextureText; text = nullptr;
mTextureText = nullptr;
delete mText; delete debugText;
mText = nullptr; debugText = nullptr;
delete mFade;
mFade = nullptr;
} }
// Inicializa las variables necesarias para la sección 'Game' // Comprueba los eventos de la cola
void Game::init() void Game::checkEventHandler()
{ {
// Carga los recursos // Comprueba los eventos que hay en la cola
loadMedia(); while (SDL_PollEvent(eventHandler) != 0)
{
mTicks = 0; // Evento de salida de la aplicación
mTicksSpeed = 15; if (eventHandler->type == SDL_QUIT)
{
mSection.name = SECTION_PROG_GAME; section.name = SECTION_PROG_QUIT;
mSection.subsection = SECTION_GAME_PLAY; break;
} }
else if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0))
// Carga los recursos necesarios para la sección 'Game'
bool Game::loadMedia()
{ {
bool success = true; switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = SECTION_PROG_TITLE;
break;
// Texturas case SDL_SCANCODE_D:
success &= loadTextureFromFile(mTextureText, mAsset->get("smb2.png"), mRenderer); 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 // Bucle para el juego
section_t Game::run() section_t Game::run()
{ {
init(); JA_PlayMusic(music);
while (mSection.name == SECTION_PROG_GAME) while (section.name == SECTION_PROG_GAME)
{ {
// Sección juego jugando // Sección juego jugando
if (mSection.subsection == SECTION_GAME_PLAY) if (section.subsection == SUBSECTION_GAME_PLAY)
{ {
update(); update();
draw(); render();
} }
} }
return mSection; JA_StopMusic();
return section;
} }
// Actualiza el juego, las variables, comprueba la entrada, etc. // Actualiza el juego, las variables, comprueba la entrada, etc.
void Game::update() void Game::update()
{ {
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego // 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 // Actualiza el contador de ticks
mTicks = SDL_GetTicks(); ticks = SDL_GetTicks();
// Comprueba los eventos que hay en la cola // Comprueba los eventos de la cola
while (SDL_PollEvent(mEventHandler) != 0) checkEventHandler();
{
// Evento de salida de la aplicación
if (mEventHandler->type == SDL_QUIT)
{
mSection.name = SECTION_PROG_QUIT;
break;
}
}
mRoom->update(); // Actualiza los objetos
mPlayer->update(); room->update();
{
player->update();
checkPlayerAndWalls(); // Debe ir detras del player update, por si se ha metido en algun muro checkPlayerAndWalls(); // Debe ir detras del player update, por si se ha metido en algun muro
}
checkPlayerOnBorder(); checkPlayerOnBorder();
checkPlayerOnFloor(); checkPlayerOnFloor();
checkPlayerAndItems(); checkPlayerAndItems();
checkPlayerAndEnemies(); checkPlayerAndEnemies();
checkInput(); scoreboard->update();
} }
} }
// Pinta los objetos en pantalla // Pinta los objetos en pantalla
void Game::draw() void Game::render()
{ {
// Prepara para dibujar el frame // Prepara para dibujar el frame
mScreen->start(); screen->start();
mScreen->clean(mRoom->getBGColor()); screen->clean(room->getBGColor());
mRoom->drawMap(); room->renderMap();
mRoom->drawEnemies(); room->renderEnemies();
mRoom->drawItems(); room->renderItems();
mPlayer->draw(); player->render();
renderRoomName();
// Texto en el centro de la pantalla scoreboard->render();
SDL_Rect rect = {0, 16 * 8, PLAY_AREA_RIGHT, 8};
color_t color = stringToColor("light_black");
SDL_SetRenderDrawColor(mRenderer, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(mRenderer, &rect);
mText->writeCentered(GAMECANVAS_CENTER_X, 16 * 8, mRoom->getName());
// Debug info // Debug info
if (mDebug) renderDebugInfo();
// Actualiza la pantalla
screen->blit();
}
// Pone la información de debug en pantalla
void Game::renderDebugInfo()
{ {
if (!debug)
{
return;
}
// 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);
}
// Pinta el texto
std::string text; std::string text;
text = "status: " + std::to_string(mPlayer->status); const int inc = debugText->getCharacterWidth() + 1;
mText->write(0, 17 * 8, text); int line = 131;
text = "foot: " + std::to_string((int)mPlayer->getLeftFoot().y); text = "status: " + std::to_string(player->status);
mText->write(0, 18 * 8, text); debugText->write(0, line += inc, text);
const int a = (mPlayer->lastPosition.y + 16) / 8; text = "foot: " + std::to_string((int)player->getLeftFoot().y);
const int b = mPlayer->getLeftFoot().y / 8; 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); text = "tile: " + std::to_string(a) + " - " + std::to_string(b);
mText->write(0, 19 * 8, text); debugText->write(0, line += inc, text);
const bool collision = checkPlayerAndEnemies(); const bool collision = checkPlayerAndEnemies();
text = "collision: " + std::to_string(collision); text = "collision: " + std::to_string(collision);
mText->write(0, 20 * 8, text); debugText->write(0, line += inc, text);
} }
// Actualiza la pantalla // Escribe el nombre de la pantalla
mScreen->blit(); void Game::renderRoomName()
}
// Comprueba la entrada
void Game::checkInput()
{ {
/* // Texto en el centro de la pantalla
if (mInput->checkInput(INPUT_UP, REPEAT_FALSE)) SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK};
changeRoom(mRoom->getRoomUp()); color_t color = stringToColor("light_black");
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(renderer, &rect);
if (mInput->checkInput(INPUT_DOWN, REPEAT_FALSE)) text->writeCentered(GAMECANVAS_CENTER_X, 16 * 8, room->getName());
changeRoom(mRoom->getRoomDown());
if (mInput->checkInput(INPUT_LEFT, REPEAT_FALSE))
changeRoom(mRoom->getRoomLeft());
if (mInput->checkInput(INPUT_RIGHT, REPEAT_FALSE))
changeRoom(mRoom->getRoomRight());
*/
if (mInput->checkInput(INPUT_BUTTON_2, REPEAT_FALSE))
mDebug = !mDebug;
} }
// Cambia de habitación // Cambia de habitación
@@ -207,14 +252,14 @@ 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 // En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada
if (file != "0") if (file != "0")
// Verifica que exista el fichero que se va a cargar // Verifica que exista el fichero que se va a cargar
if (mAsset->get(file) != "") if (asset->get(file) != "")
{ {
// Elimina la habitación actual // Elimina la habitación actual
delete mRoom; delete room;
mRoom = nullptr; room = nullptr;
// Crea un objeto habitación nuevo a partir del fichero // Crea un objeto habitación nuevo a partir del fichero
mRoom = new Room(mAsset->get(file), mRenderer, mAsset, mItemTracker); room = new Room(asset->get(file), renderer, asset, itemTracker, &itemsPicked);
success = true; success = true;
} }
@@ -225,14 +270,14 @@ bool Game::changeRoom(std::string file)
// Comprueba si el jugador esta en el borde de la pantalla // Comprueba si el jugador esta en el borde de la pantalla
void Game::checkPlayerOnBorder() void Game::checkPlayerOnBorder()
{ {
if (mPlayer->getOnBorder()) if (player->getOnBorder())
{ {
const std::string room_name = mRoom->getRoom(mPlayer->getBorder()); const std::string room_name = room->getRoom(player->getBorder());
if (changeRoom(room_name)) if (changeRoom(room_name))
{ {
mPlayer->switchBorders(); player->switchBorders();
mCurrentRoom = room_name; currentRoom = room_name;
mSpawnPoint = mPlayer->getSpawnParams(); spawnPoint = player->getSpawnParams();
} }
} }
} }
@@ -252,37 +297,37 @@ void Game::checkPlayerOnFloor()
// *** PARECE RESUELTO // *** PARECE RESUELTO
const int a = (mPlayer->lastPosition.y + 16) / 8; const int a = (player->lastPosition.y + 16) / 8;
const int b = mPlayer->getLeftFoot().y / 8; const int b = player->getLeftFoot().y / 8;
const bool tile_change = a != b; const bool tile_change = a != b;
const bool is_not_going_up = mPlayer->getVelY() >= 0; const bool is_not_going_up = player->getVelY() >= 0;
const bool is_tile_aligned = mPlayer->getLeftFoot().y % 8 == 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))) if (((is_not_going_up) && (is_tile_aligned)) || ((is_not_going_up) && (tile_change)))
{ {
bool test = false; bool test = false;
test |= (mRoom->getTile(mPlayer->getLeftFoot()) == TILE_SOLID); test |= (room->getTile(player->getLeftFoot()) == TILE_SOLID);
test |= (mRoom->getTile(mPlayer->getRightFoot()) == TILE_SOLID); test |= (room->getTile(player->getRightFoot()) == TILE_SOLID);
test |= (mRoom->getTile(mPlayer->getLeftFoot()) == TILE_TRAVESSABLE); test |= (room->getTile(player->getLeftFoot()) == TILE_TRAVESSABLE);
test |= (mRoom->getTile(mPlayer->getRightFoot()) == TILE_TRAVESSABLE); test |= (room->getTile(player->getRightFoot()) == TILE_TRAVESSABLE);
// Tiene uno de los pies sobre una superficie // Tiene uno de los pies sobre una superficie
if (test) if (test)
{ {
mPlayer->setStatus(STATUS_STANDING); player->setStatus(STATUS_STANDING);
// Si ha habido un cambio de tile, hay que recolocarlo // Si ha habido un cambio de tile, hay que recolocarlo
if (tile_change) if (tile_change)
{ {
int offset = (int)mPlayer->sprite->getPosY() % 8; int offset = (int)player->sprite->getPosY() % 8;
mPlayer->sprite->setPosY((int)mPlayer->sprite->getPosY() - offset); player->sprite->setPosY((int)player->sprite->getPosY() - offset);
} }
} }
// Tiene ambos pies sobre el vacío // Tiene ambos pies sobre el vacío
else if (mPlayer->getStatus() != STATUS_JUMPING) else if (player->getStatus() != STATUS_JUMPING)
{ {
mPlayer->setStatus(STATUS_FALLING); player->setStatus(STATUS_FALLING);
} }
} }
} }
@@ -291,7 +336,7 @@ void Game::checkPlayerOnFloor()
void Game::checkPlayerAndWalls() void Game::checkPlayerAndWalls()
{ {
// Obtiene los ocho puntos de colisión del jugador // Obtiene los ocho puntos de colisión del jugador
const SDL_Rect rect = mPlayer->getRect(); const SDL_Rect rect = player->getRect();
const SDL_Point p1 = {rect.x, rect.y}; const SDL_Point p1 = {rect.x, rect.y};
const SDL_Point p2 = {rect.x + 7, rect.y}; const SDL_Point p2 = {rect.x + 7, rect.y};
const SDL_Point p3 = {rect.x + 7, rect.y + 7}; const SDL_Point p3 = {rect.x + 7, rect.y + 7};
@@ -303,32 +348,32 @@ void Game::checkPlayerAndWalls()
// Comprueba si ha colisionado con un muro // Comprueba si ha colisionado con un muro
bool wall = false; bool wall = false;
wall |= (mRoom->getTile(p1) == TILE_SOLID); wall |= (room->getTile(p1) == TILE_SOLID);
wall |= (mRoom->getTile(p2) == TILE_SOLID); wall |= (room->getTile(p2) == TILE_SOLID);
wall |= (mRoom->getTile(p3) == TILE_SOLID); wall |= (room->getTile(p3) == TILE_SOLID);
wall |= (mRoom->getTile(p4) == TILE_SOLID); wall |= (room->getTile(p4) == TILE_SOLID);
wall |= (mRoom->getTile(p5) == TILE_SOLID); wall |= (room->getTile(p5) == TILE_SOLID);
wall |= (mRoom->getTile(p6) == TILE_SOLID); wall |= (room->getTile(p6) == TILE_SOLID);
wall |= (mRoom->getTile(p7) == TILE_SOLID); wall |= (room->getTile(p7) == TILE_SOLID);
wall |= (mRoom->getTile(p8) == TILE_SOLID); wall |= (room->getTile(p8) == TILE_SOLID);
if (wall) if (wall)
{ {
// Si hay colisión, deshace el movimiento y lo pone en modo caída // Si hay colisión, deshace el movimiento y lo pone en modo caída
mPlayer->undoLastMove(); player->undoLastMove();
mPlayer->setStatus(STATUS_FALLING); player->setStatus(STATUS_FALLING);
} }
// Comprueba si ha colisionado con un tile de los que matan al jugador // Comprueba si ha colisionado con un tile de los que matan al jugador
bool death = false; bool death = false;
death |= (mRoom->getTile(p1) == TILE_KILL); death |= (room->getTile(p1) == TILE_KILL);
death |= (mRoom->getTile(p2) == TILE_KILL); death |= (room->getTile(p2) == TILE_KILL);
death |= (mRoom->getTile(p3) == TILE_KILL); death |= (room->getTile(p3) == TILE_KILL);
death |= (mRoom->getTile(p4) == TILE_KILL); death |= (room->getTile(p4) == TILE_KILL);
death |= (mRoom->getTile(p5) == TILE_KILL); death |= (room->getTile(p5) == TILE_KILL);
death |= (mRoom->getTile(p6) == TILE_KILL); death |= (room->getTile(p6) == TILE_KILL);
death |= (mRoom->getTile(p7) == TILE_KILL); death |= (room->getTile(p7) == TILE_KILL);
death |= (mRoom->getTile(p8) == TILE_KILL); death |= (room->getTile(p8) == TILE_KILL);
if (death) if (death)
{ {
@@ -339,7 +384,7 @@ void Game::checkPlayerAndWalls()
// Comprueba las colisiones del jugador con los enemigos // Comprueba las colisiones del jugador con los enemigos
bool Game::checkPlayerAndEnemies() bool Game::checkPlayerAndEnemies()
{ {
const bool death = mRoom->enemyCollision(mPlayer->getCollider()); const bool death = room->enemyCollision(player->getCollider());
if (death) if (death)
{ {
killPlayer(); killPlayer();
@@ -350,17 +395,28 @@ bool Game::checkPlayerAndEnemies()
// Comprueba las colisiones del jugador con los objetos // Comprueba las colisiones del jugador con los objetos
void Game::checkPlayerAndItems() void Game::checkPlayerAndItems()
{ {
mRoom->itemCollision(mPlayer->getCollider()); room->itemCollision(player->getCollider());
} }
// Mata al jugador // Mata al jugador
void Game::killPlayer() void Game::killPlayer()
{ {
playerLives--;
// Destruye la habitacion y el jugador // Destruye la habitacion y el jugador
delete mRoom; delete room;
delete mPlayer; delete player;
// Crea la nueva habitación y el nuevo jugador // Crea la nueva habitación y el nuevo jugador
mRoom = new Room(mAsset->get(mCurrentRoom), mRenderer, mAsset, mItemTracker); room = new Room(asset->get(currentRoom), renderer, asset, itemTracker, &itemsPicked);
mPlayer = new Player(mSpawnPoint, mAsset->get("player01.png"), mRenderer, mAsset, mInput, mRoom); 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,21 +1,18 @@
#pragma once #pragma once
#include "ifdefs.h" #include <SDL2/SDL.h>
#include "const.h"
#include "utils.h" #include "utils.h"
#include "sprite.h" #include "sprite.h"
#include "movingsprite.h" #include "animatedsprite.h"
#include "text.h" #include "text.h"
#include "writer.h"
#include "menu.h"
#include "input.h" #include "input.h"
#include "fade.h"
#include "lang.h"
#include "screen.h" #include "screen.h"
#include "asset.h" #include "asset.h"
#include "room.h" #include "room.h"
#include "item_tracker.h" #include "item_tracker.h"
#include "player.h" #include "player.h"
#include "jail_audio.h" #include "jail_audio.h"
#include "scoreboard.h"
#ifndef GAME_H #ifndef GAME_H
#define GAME_H #define GAME_H
@@ -24,39 +21,42 @@
class Game class Game
{ {
private: private:
SDL_Renderer *mRenderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Event *mEventHandler; // Manejador de eventos SDL_Event *eventHandler; // Manejador de eventos
Screen *mScreen; // Objeto encargado de manejar el renderizador Screen *screen; // Objeto encargado de manejar el renderizador
Room *mRoom; // Objeto encargado de gestionar cada habitación del juego Room *room; // Objeto encargado de gestionar cada habitación del juego
Player *mPlayer; // Objeto con el jugador Player *player; // Objeto con el jugador
Item_tracker *mItemTracker; // Lleva el control de los objetos recogidos ItemTracker *itemTracker; // Lleva el control de los objetos recogidos
Asset *mAsset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Lang *mLang; // Objeto para gestionar los textos en diferentes idiomas Input *input; // Objeto pata gestionar la entrada
Input *mInput; // Objeto pata gestionar la entrada Text *text; // Objeto para los textos del juego
Text *mText; // Objeto para los textos del juego Text *debugText; // Objeto para los textos de debug del juego
Fade *mFade; // Objeto para renderizar fades ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador
LTexture *mTextureText; // Textura para la fuente de texto JA_Music music; // Musica que suena durante el juego
Uint32 mTicks; // Contador de ticks para ajustar la velocidad del programa int ticks; // Contador de ticks para ajustar la velocidad del programa
Uint8 mTicksSpeed; // Velocidad a la que se repiten los bucles del programa int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
section_t mSection; // Seccion actual dentro del juego section_t section; // Seccion actual dentro del juego
std::string mCurrentRoom; // Fichero de la habitación actual std::string currentRoom; // Fichero de la habitación actual
player_t mSpawnPoint; // Lugar de la habitación donde aparece el jugador player_t spawnPoint; // Lugar de la habitación donde aparece el jugador
bool mDebug; // Indica si el modo debug está activo bool debug; // Indica si el modo debug está activo
int playerLives; // Lleva la cuenta de ls vidas restantes del jugador
// Inicializa las variables int itemsPicked; // Lleva la cuenta de los objetos recogidos
void init(); Uint32 clock; // Cuenta el tiempo que dura la partida
// Carga los recursos
bool loadMedia();
// Actualiza el juego, las variables, comprueba la entrada, etc. // Actualiza el juego, las variables, comprueba la entrada, etc.
void update(); void update();
// Pinta los objetos en pantalla // Pinta los objetos en pantalla
void draw(); void render();
// Comprueba la entrada y actua // Comprueba los eventos de la cola
void checkInput(); void checkEventHandler();
// Pone la información de debug en pantalla
void renderDebugInfo();
// Escribe el nombre de la pantalla
void renderRoomName();
// Cambia de habitación // Cambia de habitación
bool changeRoom(std::string file); bool changeRoom(std::string file);
@@ -79,9 +79,12 @@ private:
// Mata al jugador // Mata al jugador
void killPlayer(); void killPlayer();
// Recarga todas las texturas
void reLoadTextures();
public: public:
// Constructor // 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 // Destructor
~Game(); ~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 #pragma once
#include "ifdefs.h" #include <SDL2/SDL.h>
#include <string> #include <string>
#include <vector> #include <vector>

View File

@@ -10,15 +10,14 @@ Item::Item(item_t item)
renderer = item.renderer; renderer = item.renderer;
// Crea objetos // Crea objetos
texture = new LTexture(); texture = new LTexture(renderer,asset->get(item.tileset));
sprite = new Sprite(item.x, item.y, 8, 8, texture, renderer); sprite = new Sprite(item.x, item.y, 8, 8, texture, renderer);
// Carga la textura
loadTextureFromFile(texture, asset->get(item.tileset), renderer);
// Inicia variables // Inicia variables
sprite->setSpriteClip(item.tile * 8, 0, 8, 8); sprite->setSpriteClip(item.tile * 8, 0, 8, 8);
collider = sprite->getRect(); collider = sprite->getRect();
colorChangeSpeed = 4;
counter = item.counter * colorChangeSpeed;
// Inicializa los colores // Inicializa los colores
color_t c = stringToColor("blue"); color_t c = stringToColor("blue");
@@ -43,18 +42,14 @@ Item::Item(item_t item)
// Destructor // Destructor
Item::~Item() Item::~Item()
{ {
texture->unload();
delete texture; delete texture;
texture = nullptr;
delete sprite; delete sprite;
sprite = nullptr;
} }
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void Item::draw() void Item::render()
{ {
const int index = (counter / 2) % color.size(); const int index = (counter / colorChangeSpeed) % color.size();
sprite->getTexture()->setColor(color[index].r, color[index].g, color[index].b); sprite->getTexture()->setColor(color[index].r, color[index].g, color[index].b);
sprite->render(); sprite->render();
sprite->getTexture()->setColor(255, 255, 255); sprite->getTexture()->setColor(255, 255, 255);
@@ -84,3 +79,9 @@ SDL_Point Item::getPos()
const SDL_Point p = {sprite->getPosX(), sprite->getPosY()}; const SDL_Point p = {sprite->getPosX(), sprite->getPosY()};
return p; return p;
} }
// Recarga la textura
void Item::reLoadTexture()
{
texture->reLoad();
}

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include "ifdefs.h" #include <SDL2/SDL.h>
#include "utils.h" #include "utils.h"
#include "asset.h" #include "asset.h"
#include "sprite.h" #include "sprite.h"
@@ -22,6 +22,7 @@ struct item_t
int x; // Posicion del item en pantalla int x; // Posicion del item en pantalla
int y; // Posicion del item en pantalla int y; // Posicion del item en pantalla
int tile; // Numero de tile dentro de la textura int tile; // Numero de tile dentro de la textura
int counter; // Contador inicial. Es el que lo hace cambiar de color
}; };
// Clase Item // Clase Item
@@ -30,15 +31,12 @@ class Item
private: private:
LTexture *texture; // Textura con los graficos del objeto LTexture *texture; // Textura con los graficos del objeto
Sprite *sprite; // Sprite del objeto Sprite *sprite; // Sprite del objeto
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
std::vector<color_t> color; // Vector con los colores del objeto std::vector<color_t> color; // Vector con los colores del objeto
int counter; // Contador interno int counter; // Contador interno
SDL_Rect collider; // Rectangulo de colisión SDL_Rect collider; // Rectangulo de colisión
int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void checkPath();
public: public:
// Constructor // Constructor
@@ -48,7 +46,7 @@ public:
~Item(); ~Item();
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void draw(); void render();
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update();
@@ -61,6 +59,9 @@ public:
// Obtiene su ubicación // Obtiene su ubicación
SDL_Point getPos(); SDL_Point getPos();
// Recarga la textura
void reLoadTexture();
}; };
#endif #endif

View File

@@ -1,18 +1,18 @@
#include "item_tracker.h" #include "item_tracker.h"
// Constructor // Constructor
Item_tracker::Item_tracker() ItemTracker::ItemTracker()
{ {
} }
// Destructor // Destructor
Item_tracker::~Item_tracker() ItemTracker::~ItemTracker()
{ {
list.clear(); list.clear();
} }
// Comprueba si el objeto ya ha sido cogido // Comprueba si el objeto ya ha sido cogido
bool Item_tracker::hasBeenPicked(std::string name, SDL_Point pos) bool ItemTracker::hasBeenPicked(std::string name, SDL_Point pos)
{ {
bool success = false; bool success = false;
@@ -31,7 +31,7 @@ bool Item_tracker::hasBeenPicked(std::string name, SDL_Point pos)
} }
// Añade el objeto a la lista de objetos cogidos // Añade el objeto a la lista de objetos cogidos
void Item_tracker::addItem(std::string name, SDL_Point pos) void ItemTracker::addItem(std::string name, SDL_Point pos)
{ {
// Comprueba si el objeto no ha sido recogido con anterioridad // Comprueba si el objeto no ha sido recogido con anterioridad
if (!hasBeenPicked(name, pos)) if (!hasBeenPicked(name, pos))
@@ -55,7 +55,7 @@ void Item_tracker::addItem(std::string name, SDL_Point pos)
} }
// Busca una entrada en la lista por nombre // Busca una entrada en la lista por nombre
int Item_tracker::findByName(std::string name) int ItemTracker::findByName(std::string name)
{ {
const int c = -1; const int c = -1;
@@ -71,7 +71,7 @@ int Item_tracker::findByName(std::string name)
} }
// Busca una entrada en la lista por posición // Busca una entrada en la lista por posición
int Item_tracker::findByPos(int index, SDL_Point pos) int ItemTracker::findByPos(int index, SDL_Point pos)
{ {
const int c = -1; const int c = -1;

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include "ifdefs.h" #include <SDL2/SDL.h>
#include "utils.h" #include "utils.h"
#include <string> #include <string>
#include <vector> #include <vector>
@@ -13,8 +13,8 @@ struct item_tracker_t
std::vector<SDL_Point> pos; // Lista de objetos cogidos de la habitación std::vector<SDL_Point> pos; // Lista de objetos cogidos de la habitación
}; };
// Clase Item_tracker // Clase ItemTracker
class Item_tracker class ItemTracker
{ {
private: private:
std::vector<item_tracker_t> list; // Lista con todos los objetos recogidos std::vector<item_tracker_t> list; // Lista con todos los objetos recogidos
@@ -27,10 +27,10 @@ private:
public: public:
// Constructor // Constructor
Item_tracker(); ItemTracker();
// Destructor // Destructor
~Item_tracker(); ~ItemTracker();
// Comprueba si el objeto ya ha sido cogido // Comprueba si el objeto ya ha sido cogido
bool hasBeenPicked(std::string name, SDL_Point pos); bool hasBeenPicked(std::string name, SDL_Point pos);

View File

@@ -1,6 +1,7 @@
#ifndef __MIPSEL__
#include "jail_audio.h" #include "jail_audio.h"
#include "stb_vorbis.c" #include "stb_vorbis.c"
#include <SDL2/SDL.h>
#include <stdio.h>
#define JA_MAX_SIMULTANEOUS_CHANNELS 5 #define JA_MAX_SIMULTANEOUS_CHANNELS 5
@@ -30,16 +31,17 @@ JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
int JA_freq {48000}; int JA_freq {48000};
SDL_AudioFormat JA_format {AUDIO_S16}; SDL_AudioFormat JA_format {AUDIO_S16};
Uint8 JA_channels {2}; Uint8 JA_channels {2};
int JA_volume = 128;
void audioCallback(void * userdata, uint8_t * stream, int len) { void audioCallback(void * userdata, uint8_t * stream, int len) {
SDL_memset(stream, 0, len); SDL_memset(stream, 0, len);
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) { if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
const int size = SDL_min(len, current_music->samples*2-current_music->pos); 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; current_music->pos += size/2;
if (size < len) { if (size < len) {
if (current_music->times != 0) { 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; current_music->pos = (len-size)/2;
if (current_music->times > 0) current_music->times--; if (current_music->times > 0) current_music->times--;
} else { } else {
@@ -52,11 +54,11 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].state == JA_CHANNEL_PLAYING) { if (channels[i].state == JA_CHANNEL_PLAYING) {
const int size = SDL_min(len, channels[i].sound->length - channels[i].pos); const int size = SDL_min(len, channels[i].sound->length - channels[i].pos);
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, 64); SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_volume/2);
channels[i].pos += size; channels[i].pos += size;
if (size < len) { if (size < len) {
if (channels[i].times != 0) { 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; channels[i].pos = len-size;
if (channels[i].times > 0) channels[i].times--; if (channels[i].times > 0) channels[i].times--;
} else { } 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) { JA_Music JA_LoadMusic(const char* filename) {
int chan, samplerate; int chan, samplerate;
JA_Music music = new JA_Music_t(); 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_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq); SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq);
@@ -134,6 +148,13 @@ void JA_DeleteMusic(JA_Music music) {
delete 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 JA_LoadSound(const char* filename) {
JA_Sound sound = new JA_Sound_t(); JA_Sound sound = new JA_Sound_t();
SDL_AudioSpec wavSpec; 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; if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
return channels[channel].state; 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 #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_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 }; 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(); JA_Music_state JA_GetMusicState();
void JA_DeleteMusic(JA_Music music); void JA_DeleteMusic(JA_Music music);
JA_Sound JA_NewSound(Uint8* buffer, Uint32 length);
JA_Sound JA_LoadSound(const char* filename); JA_Sound JA_LoadSound(const char* filename);
int JA_PlaySound(JA_Sound sound, const int loop = 0); int JA_PlaySound(JA_Sound sound, const int loop = 0);
void JA_PauseChannel(const int channel); void JA_PauseChannel(const int channel);
@@ -24,3 +25,5 @@ void JA_ResumeChannel(const int channel);
void JA_StopChannel(const int channel); void JA_StopChannel(const int channel);
JA_Channel_state JA_GetChannelState(const int channel); JA_Channel_state JA_GetChannelState(const int channel);
void JA_DeleteSound(JA_Sound sound); 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" #include "ltexture.h"
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stb_image.h"
LTexture::LTexture() // Constructor
LTexture::LTexture(SDL_Renderer *renderer, std::string path)
{ {
// Initialize // Copia punteros
mTexture = NULL; this->renderer = renderer;
mWidth = 0; this->path = path;
mHeight = 0;
// Inicializa
texture = NULL;
width = 0;
height = 0;
// Carga el fichero en la textura
if (path != "")
{
loadFromFile(path, renderer);
}
} }
// Destructor
LTexture::~LTexture() LTexture::~LTexture()
{ {
// Deallocate // Libera memoria
unload(); unload();
} }
// Carga una imagen desde un fichero
bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer) bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
{ {
int req_format = STBI_rgb_alpha; int req_format = STBI_rgb_alpha;
@@ -33,7 +46,7 @@ bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
if (req_format == STBI_rgb) if (req_format == STBI_rgb)
{ {
depth = 24; 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; pixel_format = SDL_PIXELFORMAT_RGB24;
} }
else else
@@ -43,14 +56,13 @@ bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
pixel_format = SDL_PIXELFORMAT_RGBA32; pixel_format = SDL_PIXELFORMAT_RGBA32;
} }
// Get rid of preexisting texture // Limpia
unload(); unload();
// The final texture // La textura final
SDL_Texture *newTexture = NULL; SDL_Texture *newTexture = NULL;
// Load image at specified path // Carga la imagen desde una ruta específica
//SDL_Surface *loadedSurface = IMG_Load(path.c_str());
SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void *)data, width, height, depth, pitch, pixel_format); SDL_Surface *loadedSurface = SDL_CreateRGBSurfaceWithFormatFrom((void *)data, width, height, depth, pitch, pixel_format);
if (loadedSurface == NULL) if (loadedSurface == NULL)
{ {
@@ -58,10 +70,7 @@ bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
} }
else else
{ {
// Color key image // Crea la textura desde los pixels de la surface
//SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, COLOR_KEY_R, COLOR_KEY_G, COLOR_KEY_B));
// Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface); newTexture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
if (newTexture == NULL) if (newTexture == NULL)
{ {
@@ -69,73 +78,76 @@ bool LTexture::loadFromFile(std::string path, SDL_Renderer *renderer)
} }
else else
{ {
// Get image dimensions // Obtiene las dimensiones de la imagen
mWidth = loadedSurface->w; this->width = loadedSurface->w;
mHeight = loadedSurface->h; this->height = loadedSurface->h;
} }
// Get rid of old loaded surface // Elimina la textura cargada
SDL_FreeSurface(loadedSurface); SDL_FreeSurface(loadedSurface);
} }
// Return success // Return success
mTexture = newTexture; texture = newTexture;
return mTexture != NULL; return texture != NULL;
} }
// Crea una textura en blanco
bool LTexture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access) bool LTexture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access)
{ {
// Create uninitialized texture // Crea una textura sin inicializar
mTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height);
if (mTexture == NULL) if (texture == NULL)
{ {
printf("Unable to create blank texture! SDL Error: %s\n", SDL_GetError()); printf("Unable to create blank texture! SDL Error: %s\n", SDL_GetError());
} }
else else
{ {
mWidth = width; this->width = width;
mHeight = height; this->height = height;
} }
return mTexture != NULL; return texture != NULL;
} }
// Libera la memoria de la textura
void LTexture::unload() void LTexture::unload()
{ {
// Free texture if it exists // Libera la textura si existe
if (mTexture != NULL) if (texture != NULL)
{ {
SDL_DestroyTexture(mTexture); SDL_DestroyTexture(texture);
mTexture = NULL; texture = NULL;
mWidth = 0; width = 0;
mHeight = 0; height = 0;
} }
} }
// Establece el color para la modulacion
void LTexture::setColor(Uint8 red, Uint8 green, Uint8 blue) void LTexture::setColor(Uint8 red, Uint8 green, Uint8 blue)
{ {
// Modulate texture rgb SDL_SetTextureColorMod(texture, red, green, blue);
SDL_SetTextureColorMod(mTexture, red, green, blue);
} }
// Establece el blending
void LTexture::setBlendMode(SDL_BlendMode blending) void LTexture::setBlendMode(SDL_BlendMode blending)
{ {
// Set blending function SDL_SetTextureBlendMode(texture, blending);
SDL_SetTextureBlendMode(mTexture, blending);
} }
// Establece el alpha para la modulación
void LTexture::setAlpha(Uint8 alpha) void LTexture::setAlpha(Uint8 alpha)
{ {
// Modulate texture alpha SDL_SetTextureAlphaMod(texture, alpha);
SDL_SetTextureAlphaMod(mTexture, 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) 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 // Establece el destini de renderizado en la pantalla
SDL_Rect renderQuad = {x, y, mWidth, mHeight}; SDL_Rect renderQuad = {x, y, width, height};
// Set clip rendering dimensions // Obtiene las dimesiones del clip de renderizado
if (clip != NULL) if (clip != NULL)
{ {
renderQuad.w = clip->w; 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.w = renderQuad.w * zoomW;
renderQuad.h = renderQuad.h * zoomH; renderQuad.h = renderQuad.h * zoomH;
// Render to screen // Renderiza a pantalla
SDL_RenderCopyEx(renderer, mTexture, clip, &renderQuad, angle, center, flip); SDL_RenderCopyEx(renderer, texture, clip, &renderQuad, angle, center, flip);
} }
// Establece la textura como objetivo de renderizado
void LTexture::setAsRenderTarget(SDL_Renderer *renderer) void LTexture::setAsRenderTarget(SDL_Renderer *renderer)
{ {
// Make self render target SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderTarget(renderer, mTexture);
} }
// Obtiene el ancho de la imagen
int LTexture::getWidth() int LTexture::getWidth()
{ {
return mWidth; return width;
} }
// Obtiene el alto de la imagen
int LTexture::getHeight() 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 #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
#ifndef LTEXTURE_H #ifndef LTEXTURE_H
#define LTEXTURE_H #define LTEXTURE_H
// Texture wrapper class // Clase LTexture
class LTexture class LTexture
{ {
public: private:
// Initializes variables SDL_Texture *texture; // La textura
LTexture(); 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(); ~LTexture();
// Loads image at specified path // Carga una imagen desde un fichero
bool loadFromFile(std::string path, SDL_Renderer *renderer); 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); bool createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING);
// Deallocates texture // Libera la memoria de la textura
void unload(); void unload();
// Set color modulation // Establece el color para la modulacion
void setColor(Uint8 red, Uint8 green, Uint8 blue); void setColor(Uint8 red, Uint8 green, Uint8 blue);
// Set blending // Establece el blending
void setBlendMode(SDL_BlendMode blending); void setBlendMode(SDL_BlendMode blending);
// Set alpha modulation // Establece el alpha para la modulación
void setAlpha(Uint8 alpha); 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); 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); void setAsRenderTarget(SDL_Renderer *renderer);
// Gets image dimensions // Obtiene el ancho de la imagen
int getWidth(); int getWidth();
// Obtiene el alto de la imagen
int getHeight(); int getHeight();
// Pixel manipulators // Recarga la textura
bool lockTexture(); bool reLoad();
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;
}; };
#endif #endif

View File

@@ -1,7 +1,7 @@
/* /*
Código fuente creado por JailDesigner 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,52 +1,54 @@
#include "const.h"
#include "movingsprite.h" #include "movingsprite.h"
// Constructor // Constructor
MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, LTexture *texture, SDL_Renderer *renderer) MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vely, float accelx, float accely, LTexture *texture, SDL_Renderer *renderer)
{ {
// Copia los punteros // Copia los punteros
setTexture(texture); this->texture = texture;
setRenderer(renderer); this->renderer = renderer;
// Establece el alto y el ancho del sprite // Establece el alto y el ancho del sprite
setWidth(w); this->w = w;
setHeight(h); this->h = h;
// Establece la posición X,Y del sprite // Establece la posición X,Y del sprite
setPosX(x); this->x = x;
setPosY(y); this->y = y;
xPrev = x;
yPrev = y;
// Establece la velocidad X,Y del sprite // Establece la velocidad X,Y del sprite
setVelX(velx); vx = velx;
setVelY(vely); vy = vely;
// Establece la aceleración X,Y del sprite // Establece la aceleración X,Y del sprite
setAccelX(accelx); ax = accelx;
setAccelY(accely); ay = accely;
// Establece el zoom W,H del sprite // Establece el zoom W,H del sprite
setZoomW(1); zoomW = 1;
setZoomH(1); zoomH = 1;
// Establece el angulo con el que se dibujará // Establece el angulo con el que se dibujará
setAngle(0.0); angle = (double)0;
// Establece los valores de rotacion // Establece los valores de rotacion
setRotate(false); rotateEnabled = false;
setRotateSpeed(0); rotateSpeed = 0;
setRotateAmount(0.0); rotateAmount = (double)0;
// Contador interno // Contador interno
mCounter = 0; counter = 0;
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
setSpriteClip(0, 0, w, h); spriteClip = {0, 0, w, h};
// Establece el centro de rotación // Establece el centro de rotación
mCenter = {0,0}; center = {0, 0};
// Establece el tipo de volteado // Establece el tipo de volteado
mFlip = SDL_FLIP_NONE; currentFlip = SDL_FLIP_NONE;
}; };
// Destructor // Destructor
@@ -57,189 +59,201 @@ MovingSprite::~MovingSprite()
// Reinicia todas las variables // Reinicia todas las variables
void MovingSprite::clear() void MovingSprite::clear()
{ {
mPosX = 0.0f; // Posición en el eje X x = 0.0f; // Posición en el eje X
mPosY = 0.0f; // Posición en el eje Y y = 0.0f; // Posición en el eje Y
mVelX = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse vx = 0.0f; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
mVelY = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse vy = 0.0f; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
mAccelX = 0.0f; // Aceleración en el eje X. Variación de la velocidad ax = 0.0f; // Aceleración en el eje X. Variación de la velocidad
mAccelY = 0.0f; // Aceleración en el eje Y. Variación de la velocidad ay = 0.0f; // Aceleración en el eje Y. Variación de la velocidad
mZoomW = 1.0f; // Zoom aplicado a la anchura zoomW = 1.0f; // Zoom aplicado a la anchura
mZoomH = 1.0f; // Zoom aplicado a la altura zoomH = 1.0f; // Zoom aplicado a la altura
mAngle = 0.0; // Angulo para dibujarlo angle = 0.0; // Angulo para dibujarlo
mRotate = false; // Indica si ha de rotar rotateEnabled = false; // Indica si ha de rotar
mCenter = {0, 0}; // Centro de rotación center = {0, 0}; // Centro de rotación
mRotateSpeed = 0; // Velocidad de giro rotateSpeed = 0; // Velocidad de giro
mRotateAmount = 0.0; // Cantidad de grados a girar en cada iteración rotateAmount = 0.0; // Cantidad de grados a girar en cada iteración
mCounter = 0; // Contador interno counter = 0; // Contador interno
mFlip = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite currentFlip = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
} }
// Mueve el sprite // Mueve el sprite
void MovingSprite::move() void MovingSprite::move()
{ {
if (mEnabled) if (enabled)
{ {
mPosX += mVelX; xPrev = x;
mPosY += mVelY; yPrev = y;
mVelX += mAccelX; x += vx;
mVelY += mAccelY; y += vy;
vx += ax;
vy += ay;
} }
} }
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void MovingSprite::render() void MovingSprite::render()
{ {
if (mEnabled) if (enabled)
mTexture->render(mRenderer, (int)mPosX, (int)mPosY, &mSpriteClip, mZoomW, mZoomH, mAngle, &mCenter, mFlip); texture->render(renderer, (int)x, (int)y, &spriteClip, zoomW, zoomH, angle, &center, currentFlip);
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getPosX() float MovingSprite::getPosX()
{ {
return mPosX; return x;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getPosY() float MovingSprite::getPosY()
{ {
return mPosY; return y;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getVelX() float MovingSprite::getVelX()
{ {
return mVelX; return vx;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getVelY() float MovingSprite::getVelY()
{ {
return mVelY; return vy;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getAccelX() float MovingSprite::getAccelX()
{ {
return mAccelX; return ax;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getAccelY() float MovingSprite::getAccelY()
{ {
return mAccelY; return ay;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getZoomW() float MovingSprite::getZoomW()
{ {
return mZoomW; return zoomW;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
float MovingSprite::getZoomH() float MovingSprite::getZoomH()
{ {
return mZoomH; return zoomH;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
double MovingSprite::getAngle() 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 // 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 // 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 // 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 // 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 // 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 // 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 // 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 // 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 // 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 // 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 // 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 // Obtiene el valor de la variable
bool MovingSprite::getRotate() bool MovingSprite::getRotate()
{ {
return mRotate; return rotateEnabled;
} }
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 MovingSprite::getRotateSpeed() Uint16 MovingSprite::getRotateSpeed()
{ {
return mRotateSpeed; return rotateSpeed;
} }
// Establece la rotacion // Establece la rotacion
void MovingSprite::rotate() void MovingSprite::rotate()
{ {
if (mEnabled) if (enabled)
if (mRotate) 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 // Establece el valor de la variable
void MovingSprite::setRotate(bool value) void MovingSprite::setRotate(bool value)
{ {
mRotate = value; rotateEnabled = value;
} }
// Establece el valor de la variable // 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 // Establece el valor de la variable
void MovingSprite::setRotateAmount(double value) void MovingSprite::setRotateAmount(double value)
{ {
mRotateAmount = value; rotateAmount = value;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::disableRotate() void MovingSprite::disableRotate()
{ {
mRotate = false; rotateEnabled = false;
mAngle = 0; angle = (double)0;
} }
// Actualiza las variables internas del objeto // Actualiza las variables internas del objeto
@@ -275,31 +289,79 @@ void MovingSprite::update()
move(); move();
rotate(); rotate();
if (mEnabled) if (enabled)
++mCounter %= 60000; {
++counter %= 60000;
}
} }
// Cambia el sentido de la rotación // Cambia el sentido de la rotación
void MovingSprite::switchRotate() void MovingSprite::switchRotate()
{ {
mRotateAmount *= -1; rotateAmount *= -1;
} }
// Establece el valor de la variable // Establece el valor de la variable
void MovingSprite::setFlip(SDL_RendererFlip flip) void MovingSprite::setFlip(SDL_RendererFlip flip)
{ {
mFlip = 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 // Obtiene el valor de la variable
SDL_RendererFlip MovingSprite::getFlip() SDL_RendererFlip MovingSprite::getFlip()
{ {
return mFlip; return currentFlip;
} }
// Devuelve el rectangulo donde está el sprite // Devuelve el rectangulo donde está el sprite
SDL_Rect MovingSprite::getRect() SDL_Rect MovingSprite::getRect()
{ {
SDL_Rect rect = {(int)getPosX(), (int)getPosY(), getWidth(), getHeight()}; const SDL_Rect rect = {(int)x, (int)y, w, h};
return rect; 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 #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "sprite.h" #include "sprite.h"
#ifndef MOVINGSPRITE_H #ifndef MOVINGSPRITE_H
@@ -9,25 +10,28 @@
class MovingSprite : public Sprite class MovingSprite : public Sprite
{ {
protected: protected:
float mPosX; // Posición en el eje X float x; // Posición en el eje X
float mPosY; // Posición en el eje Y float y; // Posición en el eje Y
float mVelX; // Velocidad en el eje X. Cantidad de pixeles a desplazarse float xPrev; // Posición anterior en el eje X
float mVelY; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse float yPrev; // Posición anterior en el eje Y
float mAccelX; // Aceleración en el eje X. Variación de la velocidad float vx; // Velocidad en el eje X. Cantidad de pixeles a desplazarse
float mAccelY; // Aceleración en el eje Y. Variación de la velocidad float vy; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse
float mZoomW; // Zoom aplicado a la anchura float ax; // Aceleración en el eje X. Variación de la velocidad
float mZoomH; // Zoom aplicado a la altura float ay; // Aceleración en el eje Y. Variación de la velocidad
double mAngle; // Angulo para dibujarlo float zoomW; // Zoom aplicado a la anchura
bool mRotate; // Indica si ha de rotar float zoomH; // Zoom aplicado a la altura
Uint16 mRotateSpeed; // Velocidad de giro
double mRotateAmount; // Cantidad de grados a girar en cada iteración double angle; // Angulo para dibujarlo
Uint16 mCounter; // Contador interno bool rotateEnabled; // Indica si ha de rotar
SDL_Point mCenter; // Centro de rotación int rotateSpeed; // Velocidad de giro
SDL_RendererFlip mFlip; // Indica como se voltea el sprite 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: public:
// Constructor // Constructor
@@ -84,44 +88,47 @@ public:
// Obtiene el valor de la variable // Obtiene el valor de la variable
Uint16 getRotateSpeed(); Uint16 getRotateSpeed();
// Establece el valor de la variable // Establece la posición del objeto
void setPosX(float x); void setPos(SDL_Rect rect);
// Establece el valor de la variable // Establece el valor de la variable
void setPosY(float y); void setPosX(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setVelX(float x); void setPosY(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setVelY(float y); void setVelX(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setAccelX(float x); void setVelY(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setAccelY(float y); void setAccelX(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setZoomW(float w); void setAccelY(float value);
// Establece el valor de la variable // Establece el valor de la variable
void setZoomH(float h); void setZoomW(float value);
// Establece el valor de la variable // 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 // Incrementa el valor de la variable
void incAngle(double inc); void incAngle(double value);
// Decrementa el valor de la variable // Decrementa el valor de la variable
void decAngle(double dec); void decAngle(double value);
// Establece el valor de la variable // Establece el valor de la variable
void setRotate(bool value); void setRotate(bool value);
// Establece el valor de la variable // Establece el valor de la variable
void setRotateSpeed(Uint16 value); void setRotateSpeed(int value);
// Establece el valor de la variable // Establece el valor de la variable
void setRotateAmount(double value); void setRotateAmount(double value);
@@ -135,11 +142,32 @@ public:
// Establece el valor de la variable // Establece el valor de la variable
void setFlip(SDL_RendererFlip flip); void setFlip(SDL_RendererFlip flip);
// Gira el sprite horizontalmente
void flip();
// Obtiene el valor de la variable // Obtiene el valor de la variable
SDL_RendererFlip getFlip(); SDL_RendererFlip getFlip();
// Devuelve el rectangulo donde está el sprite // Devuelve el rectangulo donde está el sprite
SDL_Rect getRect(); 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 #endif

View File

@@ -5,19 +5,16 @@
// CAUTION!!!!! si no se gasta al final, quitar la referencia a la habitación // CAUTION!!!!! si no se gasta al final, quitar la referencia a la habitación
// Constructor // Constructor
Player::Player(player_t ini, std::string _tileset, SDL_Renderer *_renderer, Asset *_asset, Input *_input, Room *_room) Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room)
{ {
// Obten punteros a objetos // Obten punteros a objetos
asset = _asset; this->asset = asset;
renderer = _renderer; this->renderer = renderer;
input = _input; this->input = input;
// Crea objetos // Crea objetos
texture = new LTexture(); texture = new LTexture(renderer, asset->get(tileset));
sprite = new AnimatedSprite(texture, renderer); sprite = new AnimatedSprite(texture, renderer, animation);
// Carga la textura
loadTextureFromFile(texture, asset->get(_tileset), renderer);
// Inicializa variables // Inicializa variables
color = stringToColor("white"); color = stringToColor("white");
@@ -31,19 +28,8 @@ Player::Player(player_t ini, std::string _tileset, SDL_Renderer *_renderer, Asse
sprite->setPosY(ini.y); sprite->setPosY(ini.y);
sprite->setVelX(ini.vx); sprite->setVelX(ini.vx);
sprite->setVelY(ini.vy); sprite->setVelY(ini.vy);
sprite->setWidth(8); sprite->setWidth(8);
sprite->setHeight(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, 8 * 0, 0, 8, 16);
sprite->setAnimationFrames(0, 1, 8 * 1, 0, 8, 16);
sprite->setAnimationFrames(0, 2, 8 * 2, 0, 8, 16);
sprite->setAnimationFrames(0, 3, 8 * 3, 0, 8, 16);
sprite->setSpriteClip(sprite->getAnimationClip(0, 0));
sprite->setFlip(ini.flip); sprite->setFlip(ini.flip);
@@ -54,20 +40,15 @@ Player::Player(player_t ini, std::string _tileset, SDL_Renderer *_renderer, Asse
// Destructor // Destructor
Player::~Player() Player::~Player()
{ {
texture->unload();
delete texture; delete texture;
texture = nullptr;
delete sprite; delete sprite;
sprite = nullptr;
} }
// Pinta el enemigo en pantalla // Pinta el jugador en pantalla
void Player::draw() void Player::render()
{ {
sprite->getTexture()->setColor(color.r, color.g, color.b); sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->render(); sprite->render();
sprite->getTexture()->setColor(255, 255, 255);
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
@@ -80,7 +61,7 @@ void Player::update()
checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación
applyGravity(); // Aplica gravedad al jugador applyGravity(); // Aplica gravedad al jugador
checkJump(); // Comprueba si ha finalizado el salto checkJump(); // Comprueba si ha finalizado el salto
collider = getRect(); collider = getRect(); // Obtiene el rectangulo que delimita al jugador
} }
// Comprueba las entradas y modifica variables // Comprueba las entradas y modifica variables
@@ -270,7 +251,11 @@ void Player::move()
sprite->update(); sprite->update();
if (sprite->getVelX() != 0) if (sprite->getVelX() != 0)
{ {
sprite->animate(0); sprite->setCurrentAnimation("walk");
}
else
{
sprite->setCurrentAnimation("stand");
} }
} }
@@ -300,3 +285,9 @@ player_t Player::getSpawnParams()
return params; return params;
} }
// Recarga la textura
void Player::reLoadTexture()
{
texture->reLoad();
}

View File

@@ -1,11 +1,12 @@
#pragma once #pragma once
#include "ifdefs.h" #include <SDL2/SDL.h>
#include "const.h"
#include "utils.h" #include "utils.h"
#include "asset.h" #include "asset.h"
#include "room.h" #include "room.h"
#include "animatedsprite.h" #include "animatedsprite.h"
#include "input.h" #include "input.h"
#include "const.h"
#include <string> #include <string>
#ifndef PLAYER_H #ifndef PLAYER_H
@@ -73,13 +74,13 @@ public:
int status; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo int status; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
// Constructor // Constructor
Player(player_t ini, std::string _tileset, SDL_Renderer *_renderer, Asset *_asset, Input *_input, Room *_room); Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room);
// Destructor // Destructor
~Player(); ~Player();
// Pinta el enemigo en pantalla // Pinta el enemigo en pantalla
void draw(); void render();
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update();
@@ -119,6 +120,9 @@ public:
// Obtiene algunos parametros del jugador // Obtiene algunos parametros del jugador
player_t getSpawnParams(); player_t getSpawnParams();
// Recarga la textura
void reLoadTexture();
}; };
#endif #endif

View File

@@ -4,22 +4,23 @@
#include <sstream> #include <sstream>
// Constructor // Constructor
Room::Room(std::string _file_path, SDL_Renderer *_renderer, Asset *_asset, Item_tracker *_item_tracker) Room::Room(std::string file_path, SDL_Renderer *renderer, Asset *asset, ItemTracker *itemTracker, int *items)
{ {
// Copia los punteros a objetos // Copia los punteros a objetos
asset = _asset; this->asset = asset;
renderer = _renderer; this->renderer = renderer;
item_tracker = _item_tracker; this->itemTracker = itemTracker;
this->itemsPicked = items;
// Crea los objetos // Crea los objetos
texture = new LTexture(); load(file_path);
load(_file_path); texture = new LTexture(renderer, asset->get(tileset));
loadTextureFromFile(texture, asset->get(tileset), renderer); itemSound = JA_LoadSound(asset->get("item.wav").c_str());
// Crea la textura para el mapa de tiles de la habitación // 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); mapTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (map_texture == NULL) if (mapTexture == NULL)
printf("Error: map_texture could not be created!\nSDL Error: %s\n", SDL_GetError()); printf("Error: mapTexture could not be created!\nSDL Error: %s\n", SDL_GetError());
// Pinta el mapa de la habitación en la textura // Pinta el mapa de la habitación en la textura
fillMapTexture(); fillMapTexture();
@@ -29,24 +30,19 @@ Room::Room(std::string _file_path, SDL_Renderer *_renderer, Asset *_asset, Item_
Room::~Room() Room::~Room()
{ {
// Reclama la memoria utilizada por los objetos // Reclama la memoria utilizada por los objetos
texture->unload();
delete texture; delete texture;
texture = nullptr; JA_DeleteSound(itemSound);
SDL_DestroyTexture(mapTexture);
SDL_DestroyTexture(map_texture); for (auto enemy : enemies)
map_texture = nullptr;
for (auto enemy : enemy_list)
{ {
delete enemy; delete enemy;
} }
enemy_list.clear();
for (auto item : item_list) for (auto item : items)
{ {
delete item; delete item;
} }
item_list.clear();
} }
// Carga las variables desde un fichero // Carga las variables desde un fichero
@@ -85,10 +81,10 @@ 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()); printf("Warning: file %s\n, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false; success = false;
} }
} while (line != "[enemy-end]"); } while (line != "[/enemy]");
// Añade el enemigo al vector de enemigos // 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 // Si la linea contiene el texto [tilemap] se realiza el proceso de carga del fichero tmx
@@ -140,7 +136,7 @@ bool Room::load(std::string _file_path)
} }
} }
} }
} while (line != "[tilemap-end]"); } while (line != "[/tilemap]");
} }
// Si la linea contiene el texto [item] se realiza el proceso de carga de un item // Si la linea contiene el texto [item] se realiza el proceso de carga de un item
@@ -149,6 +145,7 @@ bool Room::load(std::string _file_path)
item_t item; item_t item;
item.asset = asset; item.asset = asset;
item.renderer = renderer; item.renderer = renderer;
item.counter = 0;
do do
{ {
@@ -162,13 +159,13 @@ 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()); printf("Warning: file %s\n, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false; success = false;
} }
} while (line != "[item-end]"); } while (line != "[/item]");
// Añade el item al vector de items // Añade el item al vector de items
const SDL_Point itemPos = {item.x, item.y}; const SDL_Point itemPos = {item.x, item.y};
if (!item_tracker->hasBeenPicked(name, itemPos)) if (!itemTracker->hasBeenPicked(name, itemPos))
{ {
item_list.push_back(new Item(item)); items.push_back(new Item(item));
} }
} }
@@ -201,52 +198,61 @@ bool Room::load(std::string _file_path)
} }
// Asigna variables a partir de dos cadenas // 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 // Indicador de éxito en la asignación
bool success = true; bool success = true;
if (_var == "name") if (var == "name")
{ {
name = _value; name = value;
} }
else if (_var == "bg_color")
else if (var == "bgColor")
{ {
bg_color = stringToColor(_value); bgColor = stringToColor(value);
} }
else if (_var == "tileset")
else if (var == "tileset")
{ {
tileset = _value; tileset = value;
} }
else if (_var == "room_up")
else if (var == "roomUp")
{ {
room_up = _value; roomUp = value;
} }
else if (_var == "room_down")
else if (var == "roomDown")
{ {
room_down = _value; roomDown = value;
} }
else if (_var == "room_left")
else if (var == "roomLeft")
{ {
room_left = _value; roomLeft = value;
} }
else if (_var == "room_right")
else if (var == "roomRight")
{ {
room_right = _value; roomRight = value;
} }
else if (_var == "tilemap")
else if (var == "tilemap")
{ {
// Se introducen los valores separados por comas en un vector // Se introducen los valores separados por comas en un vector
std::stringstream ss(_value); std::stringstream ss(value);
std::string tmp; std::string tmp;
while (getline(ss, tmp, ',')) while (getline(ss, tmp, ','))
{ {
tilemap.push_back(std::stoi(tmp)); tilemap.push_back(std::stoi(tmp));
} }
} }
else if (_var == "")
else if (var == "")
{ {
} }
else else
{ {
success = false; success = false;
@@ -256,62 +262,80 @@ bool Room::setVars(std::string _var, std::string _value)
} }
// Asigna variables a una estructura enemy_t // 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 // Indicador de éxito en la asignación
bool success = true; bool success = true;
if (_var == "tileset") if (var == "tileset")
{ {
enemy->tileset = _value; enemy->tileset = value;
} }
else if (_var == "width")
else if (var == "animation")
{ {
enemy->w = std::stof(_value); enemy->animation = value;
} }
else if (_var == "height")
else if (var == "width")
{ {
enemy->h = std::stof(_value); enemy->w = std::stof(value);
} }
else if (_var == "x")
else if (var == "height")
{ {
enemy->x = std::stof(_value) * BLOCK; enemy->h = std::stof(value);
} }
else if (_var == "y")
else if (var == "x")
{ {
enemy->y = std::stof(_value) * BLOCK; enemy->x = std::stof(value) * BLOCK;
} }
else if (_var == "vx")
else if (var == "y")
{ {
enemy->vx = std::stof(_value); enemy->y = std::stof(value) * BLOCK;
} }
else if (_var == "vy")
else if (var == "vx")
{ {
enemy->vy = std::stof(_value); enemy->vx = std::stof(value);
} }
else if (_var == "x1")
else if (var == "vy")
{ {
enemy->x1 = std::stoi(_value) * BLOCK; enemy->vy = std::stof(value);
} }
else if (_var == "x2")
else if (var == "x1")
{ {
enemy->x2 = std::stoi(_value) * BLOCK; enemy->x1 = std::stoi(value) * BLOCK;
} }
else if (_var == "y1")
else if (var == "x2")
{ {
enemy->y1 = std::stoi(_value) * BLOCK; enemy->x2 = std::stoi(value) * BLOCK;
} }
else if (_var == "y2")
else if (var == "y1")
{ {
enemy->y2 = std::stoi(_value) * BLOCK; enemy->y1 = std::stoi(value) * BLOCK;
} }
else if (_var == "color")
else if (var == "y2")
{ {
enemy->color = stringToColor(_value); enemy->y2 = std::stoi(value) * BLOCK;
} }
else if (_var == "[enemy-end]")
else if (var == "color")
{
enemy->color = stringToColor(value);
}
else if (var == "[/enemy]")
{ {
} }
else else
{ {
success = false; success = false;
@@ -321,30 +345,40 @@ bool Room::setEnemy(enemy_t *enemy, std::string _var, std::string _value)
} }
// Asigna variables a una estructura item_t // Asigna variables a una estructura item_t
bool Room::setItem(item_t *item, std::string _var, std::string _value) bool Room::setItem(item_t *item, std::string var, std::string value)
{ {
// Indicador de éxito en la asignación // Indicador de éxito en la asignación
bool success = true; bool success = true;
if (_var == "tileset") if (var == "tileset")
{ {
item->tileset = _value; item->tileset = value;
} }
else if (_var == "x")
else if (var == "counter")
{ {
item->x = std::stof(_value) * BLOCK; item->counter = std::stoi(value);
} }
else if (_var == "y")
else if (var == "x")
{ {
item->y = std::stof(_value) * BLOCK; item->x = std::stof(value) * BLOCK;
} }
else if (_var == "tile")
else if (var == "y")
{ {
item->tile = std::stof(_value); item->y = std::stof(value) * BLOCK;
} }
else if (_var == "[item-end]")
else if (var == "tile")
{
item->tile = std::stof(value);
}
else if (var == "[/item]")
{ {
} }
else else
{ {
success = false; success = false;
@@ -362,27 +396,25 @@ std::string Room::getName()
// Devuelve el color de la habitación // Devuelve el color de la habitación
color_t Room::getBGColor() color_t Room::getBGColor()
{ {
return bg_color; return bgColor;
} }
// Crea la textura con el mapeado de la habitación // Crea la textura con el mapeado de la habitación
void Room::fillMapTexture() void Room::fillMapTexture()
{ {
SDL_SetRenderTarget(renderer, map_texture); SDL_SetRenderTarget(renderer, mapTexture);
SDL_SetTextureBlendMode(map_texture, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(mapTexture, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00); SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
// Los tilesets son de 20x20 tiles. El primer tile es el 1. Cuentan hacia la derecha y hacia abajo // 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}; SDL_Rect clip = {0, 0, 8, 8};
for (int y = 0; y < 16; y++) for (int y = 0; y < 16; y++)
for (int x = 0; x < 32; x++) for (int x = 0; x < 32; x++)
{ {
clip.x = ((tilemap[(y * 32) + x] - 1) % 20) * 8; clip.x = ((tilemap[(y * 32) + x] - 1) % 20) * 8;
clip.y = ((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); texture->render(renderer, x * 8, y * 8, &clip);
} }
@@ -390,41 +422,41 @@ void Room::fillMapTexture()
} }
// Dibuja el mapa en pantalla // Dibuja el mapa en pantalla
void Room::drawMap() void Room::renderMap()
{ {
SDL_Rect rect = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; SDL_Rect rect = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
// Dibuja la textura con el mapa en pantalla // 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 // 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 // Dibuja los objetos en pantalla
void Room::drawItems() void Room::renderItems()
{ {
for (auto item : item_list) for (auto item : items)
{ {
item->draw(); item->render();
} }
} }
// Actualiza las variables y objetos de la habitación // Actualiza las variables y objetos de la habitación
void Room::update() void Room::update()
{ {
for (auto enemy : enemy_list) for (auto enemy : enemies)
{ {
enemy->update(); enemy->update();
} }
for (auto item : item_list) for (auto item : items)
{ {
item->update(); item->update();
} }
@@ -436,19 +468,19 @@ std::string Room::getRoom(int border)
switch (border) switch (border)
{ {
case BORDER_TOP: case BORDER_TOP:
return room_up; return roomUp;
break; break;
case BORDER_BOTTOM: case BORDER_BOTTOM:
return room_down; return roomDown;
break; break;
case BORDER_RIGHT: case BORDER_RIGHT:
return room_right; return roomRight;
break; break;
case BORDER_LEFT: case BORDER_LEFT:
return room_left; return roomLeft;
break; break;
default: default:
@@ -492,7 +524,7 @@ bool Room::enemyCollision(SDL_Rect &rect)
{ {
bool collision = false; bool collision = false;
for (auto enemy : enemy_list) for (auto enemy : enemies)
{ {
collision |= checkCollision(rect, enemy->getCollider()); collision |= checkCollision(rect, enemy->getCollider());
} }
@@ -504,15 +536,34 @@ bool Room::enemyCollision(SDL_Rect &rect)
bool Room::itemCollision(SDL_Rect &rect) bool Room::itemCollision(SDL_Rect &rect)
{ {
bool collision = false; bool collision = false;
for (auto item : item_list) for (int i = 0; i < items.size(); i++)
{ {
if (checkCollision(rect, item->getCollider())) if (checkCollision(rect, items[i]->getCollider()))
{ {
item->pick(); itemTracker->addItem(name, items[i]->getPos());
item_tracker->addItem(name, item->getPos()); delete items[i];
items.erase(items.begin() + i);
JA_PlaySound(itemSound);
*itemsPicked = *itemsPicked + 1;
collision = true; collision = true;
} }
} }
return collision; 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,11 +1,13 @@
#pragma once #pragma once
#include "ifdefs.h" #include <SDL2/SDL.h>
#include "const.h"
#include "utils.h" #include "utils.h"
#include "asset.h" #include "asset.h"
#include "enemy.h" #include "enemy.h"
#include "item.h" #include "item.h"
#include "item_tracker.h" #include "item_tracker.h"
#include "const.h"
#include "jail_audio.h"
#include <string> #include <string>
#include <vector> #include <vector>
@@ -36,39 +38,41 @@ class Room
{ {
private: private:
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
color_t bg_color; // Color de fondo de la habitación color_t bgColor; // Color de fondo de la habitación
std::string room_up; // Identificador de la habitación que se encuentra arriba std::string roomUp; // Identificador de la habitación que se encuentra arriba
std::string room_down; // Identificador de la habitación que se encuentra abajp std::string roomDown; // 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 roomLeft; // 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 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::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<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<Enemy *> enemies; // Listado con los enemigos de la habitación
std::vector<Item *> item_list; // Listado con los items que hay en 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 LTexture *texture; // Textura con los graficos de la habitación
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Item_tracker *item_tracker; // Lleva el control de los objetos recogidos ItemTracker *itemTracker; // Lleva el control de los objetos recogidos
SDL_Renderer *renderer; // El renderizador de la ventana 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 // 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 // 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 // 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 // Asigna variables a una estructura item_t
bool setItem(item_t *item, std::string _var, std::string _value); bool setItem(item_t *item, std::string var, std::string value);
// Pinta el mapa de la habitación en la textura // Pinta el mapa de la habitación en la textura
void fillMapTexture(); void fillMapTexture();
public: public:
// Constructor // Constructor
Room(std::string _file_path, SDL_Renderer *_renderer, Asset *_asset, Item_tracker *_item_tracker); Room(std::string file_path, SDL_Renderer *renderer, Asset *asset, ItemTracker *item_tracker, int *items);
// Destructor // Destructor
~Room(); ~Room();
@@ -80,13 +84,13 @@ public:
color_t getBGColor(); color_t getBGColor();
// Dibuja el mapa en pantalla // Dibuja el mapa en pantalla
void drawMap(); void renderMap();
// Dibuja los enemigos en pantalla // Dibuja los enemigos en pantalla
void drawEnemies(); void renderEnemies();
// Dibuja los objetos en pantalla // Dibuja los objetos en pantalla
void drawItems(); void renderItems();
// Actualiza las variables y objetos de la habitación // Actualiza las variables y objetos de la habitación
void update(); void update();
@@ -102,6 +106,9 @@ public:
// Indica si hay colision con un objeto a partir de un rectangulo // Indica si hay colision con un objeto a partir de un rectangulo
bool itemCollision(SDL_Rect &rect); bool itemCollision(SDL_Rect &rect);
// Recarga la textura
void reLoadTexture();
}; };
#endif #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 "screen.h"
#include "const.h" #include <string>
#include <stdio.h>
// Constructor // 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 // Inicializa variables
mWindow = window; this->window = window;
mRenderer = renderer; this->renderer = renderer;
this->options = options;
mScreenWidth = SCREEN_WIDTH; gameCanvasWidth = gameInternalResX;
mScreenHeight = SCREEN_HEIGHT; gameCanvasHeight = gameInternalResY;
mGameCanvasWidth = GAMECANVAS_WIDTH;
mGameCanvasHeight = GAMECANVAS_HEIGHT;
mGameCanvasPosX = (SCREEN_WIDTH - GAMECANVAS_WIDTH) / 2;
mGameCanvasPosY = (SCREEN_HEIGHT - GAMECANVAS_HEIGHT) / 2;
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 // Crea la textura donde se dibujan los graficos del juego
mGameCanvas = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight);
if (mGameCanvas == NULL) if (gameCanvas == NULL)
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError()); 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 // Destructor
Screen::~Screen() Screen::~Screen()
{ {
mRenderer = nullptr; renderer = nullptr;
} }
// Limpia la pantalla // Limpia la pantalla
void Screen::clean(color_t color) void Screen::clean(color_t color)
{ {
SDL_SetRenderDrawColor(mRenderer, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
SDL_RenderClear(mRenderer); SDL_RenderClear(renderer);
} }
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
void Screen::start() void Screen::start()
{ {
SDL_SetRenderTarget(mRenderer, mGameCanvas); SDL_SetRenderTarget(renderer, gameCanvas);
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
void Screen::blit() void Screen::blit()
{ {
// Vuelve a dejar el renderizador en modo normal // Vuelve a dejar el renderizador en modo normal
SDL_SetRenderTarget(mRenderer, NULL); SDL_SetRenderTarget(renderer, NULL);
// Borra el contenido previo // Borra el contenido previo
SDL_SetRenderDrawColor(mRenderer, mBorderColor.r, mBorderColor.g, mBorderColor.b, 0xFF); SDL_SetRenderDrawColor(renderer, borderColor.r, borderColor.g, borderColor.b, 0xFF);
SDL_RenderClear(mRenderer); SDL_RenderClear(renderer);
// Rectangulo de destino donde se dibujarà la textura con el juego
SDL_Rect dest = {mGameCanvasPosX, mGameCanvasPosY, mGameCanvasWidth, mGameCanvasHeight};
// Copia la textura de juego en el renderizador en la posición adecuada // 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 // 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 #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "utils.h" #include "utils.h"
#ifndef SCREEN_H #ifndef SCREEN_H
#define 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 // Clase Screen
class Screen class Screen
{ {
private: private:
SDL_Window *mWindow; // Ventana de la aplicación SDL_Window *window; // Ventana de la aplicación
SDL_Renderer *mRenderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Texture *mGameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa
options_t *options; // Variable con todas las opciones del programa
int mScreenWidth; // Ancho de la pantalla int screenWidth; // Ancho de la pantalla o ventana
int mScreenHeight; // Alto de la pantalla int screenHeight; // Alto de la pantalla o ventana
int mGameCanvasWidth; // Ancho de la textura donde se dibuja el juego int gameCanvasWidth; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego
int mGameCanvasHeight; // Alto de la textura donde se dibuja el juego int gameCanvasHeight; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego
int mGameCanvasPosX; // Posicion en el eje X donde se dibujará la textura del juego dentro de la pantalla anchor_t anchor; // Variable con los anclajes de la pantalla
int mGameCanvasPosY; // Posicion en el eje Y donde se dibujará la textura del juego dentro 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
color_t mBorderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
public: public:
// Constructor // Constructor
Screen(SDL_Window *windows, SDL_Renderer *renderer); Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options, int gameInternalResX, int gameInternalResY);
// Destructor // Destructor
~Screen(); ~Screen();
// Limpia la pantalla // 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 // Prepara para empezar a dibujar en la textura de juego
void start(); void start();
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
void blit(); void blit();
// Establece el modo de video
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 #endif

View File

@@ -3,168 +3,193 @@
// Constructor // Constructor
Sprite::Sprite(int x, int y, int w, int h, LTexture *texture, SDL_Renderer *renderer) Sprite::Sprite(int x, int y, int w, int h, 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 // Establece la posición X,Y del sprite
setPosX(x); this->x = x;
setPosY(y); 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 // Establece el puntero al renderizador de la ventana
setRenderer(renderer); this->renderer = renderer;
// Establece la textura donde están los gráficos para el sprite // Establece la textura donde están los gráficos para el sprite
setTexture(texture); this->texture = texture;
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
setSpriteClip(x, y, w, h); spriteClip = {x, y, w, h};
// Inicializa variables // Inicializa variables
setEnabled(true); enabled = true;
} }
Sprite::Sprite(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer) Sprite::Sprite(SDL_Rect rect, LTexture *texture, SDL_Renderer *renderer)
{ {
// Establece el alto y el ancho del sprite
setWidth(rect.w);
setHeight(rect.h);
// Establece la posición X,Y del sprite // Establece la posición X,Y del sprite
setPosX(rect.x); x = rect.x;
setPosY(rect.y); 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 // Establece el puntero al renderizador de la ventana
setRenderer(renderer); this->renderer = renderer;
// Establece la textura donde están los gráficos para el sprite // Establece la textura donde están los gráficos para el sprite
setTexture(texture); this->texture = texture;
// Establece el rectangulo de donde coger la imagen // Establece el rectangulo de donde coger la imagen
setSpriteClip(rect); spriteClip = {x, y, w, h};
// Inicializa variables // Inicializa variables
setEnabled(true); enabled = true;
} }
// Destructor // Destructor
Sprite::~Sprite() Sprite::~Sprite()
{ {
mTexture = nullptr; texture = nullptr;
mRenderer = nullptr; renderer = nullptr;
} }
// Muestra el sprite por pantalla // Muestra el sprite por pantalla
void Sprite::render() void Sprite::render()
{ {
if (mEnabled) if (enabled)
{ {
mTexture->render(mRenderer, mPosX, mPosY, &mSpriteClip); texture->render(renderer, x, y, &spriteClip);
} }
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getPosX() int Sprite::getPosX()
{ {
return mPosX; return x;
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getPosY() int Sprite::getPosY()
{ {
return mPosY; return y;
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getWidth() int Sprite::getWidth()
{ {
return mWidth; return w;
} }
// Obten el valor de la variable // Obten el valor de la variable
int Sprite::getHeight() 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 // Establece el valor de la variable
void Sprite::setPosX(int x) void Sprite::setPosX(int x)
{ {
mPosX = x; this->x = x;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setPosY(int y) void Sprite::setPosY(int y)
{ {
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 // Establece el valor de la variable
void Sprite::setWidth(int w) void Sprite::setWidth(int w)
{ {
mWidth = w; this->w = w;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setHeight(int h) void Sprite::setHeight(int h)
{ {
mHeight = h; this->h = h;
} }
// Obten el valor de la variable // Obten el valor de la variable
SDL_Rect Sprite::getSpriteClip() SDL_Rect Sprite::getSpriteClip()
{ {
return mSpriteClip; return spriteClip;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setSpriteClip(SDL_Rect rect) void Sprite::setSpriteClip(SDL_Rect rect)
{ {
mSpriteClip = rect; spriteClip = rect;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setSpriteClip(int x, int y, int w, int h) void Sprite::setSpriteClip(int x, int y, int w, int h)
{ {
mSpriteClip.x = x; spriteClip = {x, y, w, h};
mSpriteClip.y = y;
mSpriteClip.w = w;
mSpriteClip.h = h;
} }
// Obten el valor de la variable // Obten el valor de la variable
LTexture *Sprite::getTexture() LTexture *Sprite::getTexture()
{ {
return mTexture; return texture;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setTexture(LTexture *texture) void Sprite::setTexture(LTexture *texture)
{ {
mTexture = texture; this->texture = texture;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setRenderer(SDL_Renderer *renderer) void Sprite::setRenderer(SDL_Renderer *renderer)
{ {
mRenderer = renderer; this->renderer = renderer;
} }
// Establece el valor de la variable // Establece el valor de la variable
void Sprite::setEnabled(bool value) void Sprite::setEnabled(bool value)
{ {
mEnabled = value; enabled = value;
} }
// Comprueba si el objeto está habilitado // Comprueba si el objeto está habilitado
bool Sprite::isEnabled() bool Sprite::isEnabled()
{ {
return mEnabled; return enabled;
} }
// Devuelve el rectangulo donde está el sprite // Devuelve el rectangulo donde está el sprite
SDL_Rect Sprite::getRect() SDL_Rect Sprite::getRect()
{ {
SDL_Rect rect = {getPosX(), getPosY(), getWidth(), getHeight()}; SDL_Rect rect = {x, y, w, h};
return rect; 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 #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "ltexture.h" #include "ltexture.h"
#ifndef SPRITE_H #ifndef SPRITE_H
@@ -9,16 +10,16 @@
class Sprite class Sprite
{ {
protected: protected:
int mPosX; // Posición en el eje X donde dibujar el sprite int x; // Posición en el eje X donde dibujar el sprite
int mPosY; // Posición en el eje Y donde dibujar el sprite int y; // Posición en el eje Y donde dibujar el sprite
Uint16 mWidth; // Ancho del sprite int w; // Ancho del sprite
Uint16 mHeight; // Alto del sprite int h; // Alto del sprite
SDL_Renderer *mRenderer; // Puntero al renderizador de la ventana SDL_Renderer *renderer; // Puntero al renderizador de la ventana
LTexture *mTexture; // Textura donde estan todos los dibujos del sprite LTexture *texture; // Textura donde estan todos los dibujos del sprite
SDL_Rect mSpriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla SDL_Rect spriteClip; // Rectangulo de origen de la textura que se dibujará en pantalla
bool mEnabled; // Indica si el sprite esta habilitado bool enabled; // Indica si el sprite esta habilitado
public: public:
// Constructor // Constructor
@@ -43,12 +44,21 @@ public:
// Obten el valor de la variable // Obten el valor de la variable
int getHeight(); int getHeight();
// Establece la posición del objeto
void setPos(SDL_Rect rect);
// Establece el valor de la variable // Establece el valor de la variable
void setPosX(int x); void setPosX(int x);
// Establece el valor de la variable // Establece el valor de la variable
void setPosY(int y); void setPosY(int y);
// 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 // Establece el valor de la variable
void setWidth(int w); void setWidth(int w);
@@ -81,6 +91,9 @@ public:
// Devuelve el rectangulo donde está el sprite // Devuelve el rectangulo donde está el sprite
SDL_Rect getRect(); SDL_Rect getRect();
// Establece los valores de posición y tamaño del sprite
void setRect(SDL_Rect rect);
}; };
#endif #endif

View File

@@ -1,16 +1,16 @@
#include "const.h"
#include "text.h" #include "text.h"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
// Constructor // Constructor
Text::Text(std::string file, LTexture *texture, SDL_Renderer *renderer) Text::Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer)
{ {
SDL_Rect rect = {0,0,0,0}; texture = new LTexture(renderer, bitmapFile);
mSprite = new Sprite(rect, texture, renderer); sprite = new Sprite({0, 0, 0, 0}, texture, renderer);
mSprite->setTexture(texture); sprite->setTexture(texture);
mSprite->setRenderer(renderer); sprite->setRenderer(renderer);
mFile = file; file = textFile;
init(); init();
} }
@@ -18,8 +18,8 @@ Text::Text(std::string file, LTexture *texture, SDL_Renderer *renderer)
// Destructor // Destructor
Text::~Text() Text::~Text()
{ {
delete mSprite; delete texture;
mSprite = nullptr; delete sprite;
} }
// Inicializador // Inicializador
@@ -28,61 +28,61 @@ void Text::init()
// Inicializa a cero el vector con las coordenadas // Inicializa a cero el vector con las coordenadas
for (int i = 0; i < 128; i++) for (int i = 0; i < 128; i++)
{ {
mOffset[i].x = 0; offset[i].x = 0;
mOffset[i].y = 0; offset[i].y = 0;
mOffset[i].w = 0; offset[i].w = 0;
} }
// Carga los offsets desde el fichero // Carga los offsets desde el fichero
initOffsetFromFile(); initOffsetFromFile();
// Inicia los valores del sprite que dibuja las letras // Inicia los valores del sprite que dibuja las letras
mSprite->setWidth(mBoxWidth); sprite->setWidth(boxWidth);
mSprite->setHeight(mBoxHeight); sprite->setHeight(boxHeight);
mSprite->setPosX(0); sprite->setPosX(0);
mSprite->setPosY(0); sprite->setPosY(0);
mSprite->setSpriteClip(0, 0, mSprite->getWidth(), mSprite->getHeight()); sprite->setSpriteClip(0, 0, sprite->getWidth(), sprite->getHeight());
// Establece las coordenadas para cada caracter ascii de la cadena y su ancho // Establece las coordenadas para cada caracter ascii de la cadena y su ancho
for (int i = 32; i < 128; i++) for (int i = 32; i < 128; i++)
{ {
mOffset[i].x = ((i - 32) % 15) * mBoxWidth; offset[i].x = ((i - 32) % 15) * boxWidth;
mOffset[i].y = ((i - 32) / 15) * mBoxHeight; offset[i].y = ((i - 32) / 15) * boxHeight;
} }
} }
// Escribe texto en pantalla // Escribe texto en pantalla
void Text::write(int x, int y, std::string text, int kerning, int lenght) void Text::write(int x, int y, std::string text, int kerning, int lenght)
{ {
Uint16 shift = 0; int shift = 0;
if (lenght == -1) if (lenght == -1)
lenght = text.length(); lenght = text.length();
for (int i = 0; i < lenght; ++i) for (int i = 0; i < lenght; ++i)
{ {
mSprite->setSpriteClip(mOffset[int(text[i])].x, mOffset[int(text[i])].y, mSprite->getWidth(), mSprite->getHeight()); sprite->setSpriteClip(offset[int(text[i])].x, offset[int(text[i])].y, sprite->getWidth(), sprite->getHeight());
mSprite->setPosX(x + shift); sprite->setPosX(x + shift);
mSprite->setPosY(y); sprite->setPosY(y);
mSprite->render(); sprite->render();
shift += (mOffset[int(text[i])].w + kerning); shift += (offset[int(text[i])].w + kerning);
} }
} }
// Escribe el texto con colores // Escribe el texto con colores
void Text::writeColored(int x, int y, std::string text, color_t color, int kerning, int lenght) void Text::writeColored(int x, int y, std::string text, color_t color, int kerning, int lenght)
{ {
mSprite->getTexture()->setColor(color.r, color.g, color.b); sprite->getTexture()->setColor(color.r, color.g, color.b);
write(x, y, text, kerning, lenght); write(x, y, text, kerning, lenght);
mSprite->getTexture()->setColor(255, 255, 255); sprite->getTexture()->setColor(255, 255, 255);
} }
// Escribe el texto con sombra // Escribe el texto con sombra
void Text::writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance, int kerning, int lenght) void Text::writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance, int kerning, int lenght)
{ {
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); 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); write(x, y, text, kerning, lenght);
} }
@@ -127,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 // 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) for (int i = 0; i < (int)text.length(); i++)
shift += (mOffset[int(text[i])].w + kerning); 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 // Inicializa el vector de offsets desde un fichero
void Text::initOffsetFromFile() void Text::initOffsetFromFile()
{ {
std::ifstream rfile(mFile); std::ifstream rfile(file);
if (rfile.is_open() && rfile.good()) if (rfile.is_open() && rfile.good())
{ {
std::string buffer; std::string buffer;
//printf("Reading %s file\n", mFile.c_str());
// Lee los dos primeros valores del fichero // Lee los dos primeros valores del fichero
std::getline(rfile, buffer); std::getline(rfile, buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
mBoxWidth = std::stoi(buffer); boxWidth = std::stoi(buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
std::getline(rfile, buffer); std::getline(rfile, buffer);
mBoxHeight = std::stoi(buffer); boxHeight = std::stoi(buffer);
// lee el resto de datos del fichero // lee el resto de datos del fichero
int index = 32; int index = 32;
@@ -162,7 +162,7 @@ void Text::initOffsetFromFile()
{ {
// Almacena solo las lineas impares // Almacena solo las lineas impares
if (line_read % 2 == 1) if (line_read % 2 == 1)
mOffset[index++].w = std::stoi(buffer); offset[index++].w = std::stoi(buffer);
// Limpia el buffer // Limpia el buffer
buffer.clear(); buffer.clear();
@@ -172,7 +172,13 @@ void Text::initOffsetFromFile()
} }
// Devuelve el valor de la variable // 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 #pragma once
#include "sprite.h" #include "sprite.h"
#include "utils.h" #include "utils.h"
@@ -14,33 +15,34 @@
class Text class Text
{ {
private: private:
Sprite *mSprite; // Objeto con los graficos para el texto Sprite *sprite; // Objeto con los graficos para el texto
struct Offset struct Offset
{ {
int x; int x;
int y; 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 int boxWidth; // Anchura de la caja de cada caracter en el png
Uint8 mBoxHeight; // Altura de la caja de cada caracter en el png int boxHeight; // Altura de la caja de cada caracter en el png
std::string mFile; // Fichero con los descriptores de la fuente 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 // Inicializa el vector de offsets desde un fichero
void initOffsetFromFile(); void initOffsetFromFile();
public: public:
// Constructor // Constructor
Text(std::string file, LTexture *texture, SDL_Renderer *renderer); Text(std::string bitmapFile, std::string textFile, SDL_Renderer *renderer);
// Destructor // Destructor
~Text(); ~Text();
// Inicializador
void init();
// Escribe el texto en pantalla // Escribe el texto en pantalla
void write(int x, int y, std::string text, int kerning = 1, int lenght = -1); void write(int x, int y, std::string text, int kerning = 1, int lenght = -1);
@@ -50,17 +52,20 @@ public:
// Escribe el texto con sombra // Escribe el texto con sombra
void writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1); void writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1);
// Escribe el texto centrado en un punto x 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); void writeCentered(int x, int y, std::string text, int kerning = 1, int lenght = -1);
// Escribe texto con extras // Escribe texto con extras
void writeDX(Uint8 flags, int x, int y, std::string text, int kerning = 1, color_t textColor = {255, 255, 255}, Uint8 shadowDistance = 1, color_t shadowColor = {0, 0, 0}, int lenght = -1); 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 // 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 // Devuelve el valor de la variable
Uint8 getCharacterWidth(); int getCharacterWidth();
// Recarga la textura
void reLoadTexture();
}; };
#endif #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 // Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2) double distanceSquared(int x1, int y1, int x2, int y2)
{ {
int deltaX = x2 - x1; const int deltaX = x2 - x1;
int deltaY = y2 - y1; const int deltaY = y2 - y1;
return deltaX * deltaX + deltaY * deltaY; return deltaX * deltaX + deltaY * deltaY;
} }
@@ -71,20 +71,20 @@ bool checkCollision(circle_t &a, SDL_Rect &b)
return false; return false;
} }
// Detector de colisiones entre un dos rectangulos // Detector de colisiones entre dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b) bool checkCollision(SDL_Rect &a, SDL_Rect &b)
{ {
// Calculate the sides of rect A // Calculate the sides of rect A
int leftA = a.x; const int leftA = a.x;
int rightA = a.x + a.w; const int rightA = a.x + a.w;
int topA = a.y; const int topA = a.y;
int bottomA = a.y + a.h; const int bottomA = a.y + a.h;
// Calculate the sides of rect B // Calculate the sides of rect B
int leftB = b.x; const int leftB = b.x;
int rightB = b.x + b.w; const int rightB = b.x + b.w;
int topB = b.y; const int topB = b.y;
int bottomB = b.y + b.h; const int bottomB = b.y + b.h;
// If any of the sides from A are outside of B // If any of the sides from A are outside of B
if (bottomA <= topB) if (bottomA <= topB)
@@ -111,16 +111,33 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
return true; return true;
} }
// Carga un archivo de imagen en una textura // Detector de colisiones entre un punto y u rectangulo
bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer) bool checkCollision(SDL_Point &p, SDL_Rect &r)
{ {
bool success = true; // Comprueba si el punto está fuera del rectangulo en el eje X
if (!texture->loadFromFile(path, renderer)) if (p.x < r.x)
{ {
printf("Failed to load %s texture!\n", path.c_str()); return false;
success = 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 // Devuelve un color_t a partir de un string

View File

@@ -1,14 +1,30 @@
#pragma once #pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "ltexture.h" #include "ltexture.h"
#include <string> #include <string>
#ifndef UTILS_H #ifndef UTILS_H
#define UTILS_H #define UTILS_H
#define DIFFICULTY_EASY 0 #define FILTER_NEAREST 0
#define DIFFICULTY_NORMAL 1 #define FILTER_LINEAL 1
#define DIFFICULTY_HARD 2
// 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 // Estructura para definir un circulo
struct circle_t struct circle_t
@@ -33,35 +49,17 @@ struct section_t
Uint8 subsection; 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 // Estructura con todas las opciones de configuración del programa
struct options_t 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 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 Uint32 filter; // Filtro usado para el escalado de la imagen
bool vSync; // Indica si se quiere usar vsync o no bool vSync; // Indica si se quiere usar vsync o no
int 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 // Calcula el cuadrado de la distancia entre dos puntos
@@ -76,8 +74,8 @@ bool checkCollision(circle_t &a, SDL_Rect &b);
// Detector de colisiones entre un dos rectangulos // 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 // Detector de colisiones entre un punto y u rectangulo
bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer); bool checkCollision(SDL_Point &p, SDL_Rect &r);
// Devuelve un color_t a partir de un string // Devuelve un color_t a partir de un string
color_t stringToColor(std::string str); 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

View File

@@ -1,27 +1,48 @@
[x] Hacer que deje de poder moverse tras el salto al alcanzar la misma posicion en altura que tenia cuando saltó ## TAREAS
[x] Arreglar que no atraviese tiles atravaseables al caer muy rapido 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] Leer los mapas directamente del archivo tmx x (A) Arreglar que no atraviese tiles atravaseables al caer muy rapido {cm:2022-08-29}
[x] Crear la clase item x (A) Leer los mapas directamente del archivo tmx {cm:2022-08-29}
[x] Colisiones con los enemigos x (A) Crear la clase item {cm:2022-08-29}
[x] 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 x (A) Colisiones con los enemigos {cm:2022-08-29}
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 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] Crear tiles que maten 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}
[ ] Crear tiles que deslicen, (no tipo hielo sino cinta) x (A) Crear tiles que maten {cm:2022-08-29}
[ ] Tiles animados (A) Modificar el salto para que coincida con el del JSW, no ha de colisionar lateralmente
[ ] Crear ascensores
[ ] Enemigos de diferente tamaño (A) Crear tiles que deslicen, (no tipo hielo sino cinta)
[ ] Color de los items (A) Tiles animados
[ ] Temporizador de inicio de los items (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: ## TEMAS
arounders arounders
paku simbel paku simbel
jail battle jail battle
arounders race arounders race
aee gba aee gba
matatunos matatunos
sigmasua x sigmasua
calculin doom calculin doom
leaper reaper leaper reaper
mini ascii mini ascii