88 Commits
v0.1 ... v0.4

Author SHA1 Message Date
2929b1efb9 Actualizado el numero de versión 2022-08-28 07:51:46 +02:00
d937e5578f Retocado el menu del titulo 2022-08-28 07:50:08 +02:00
b6cbc65a2a corregido un bug en la caída del personaje 2022-08-28 07:30:13 +02:00
bc464206c1 Retocado el mapa 2022-08-27 23:26:48 +02:00
7c7e0c01e2 Añadidos enemigos tipo path 2022-08-27 22:53:06 +02:00
3f232c6c25 Debugando la clase enemy 2022-08-27 21:02:51 +02:00
8a79737520 Implementando el enemy engine 2022-08-27 18:42:59 +02:00
0e71bc97b3 Modificados algunos mapas 2022-08-27 17:29:56 +02:00
17b10a8fef Ya recuerda los items recogidos 2022-08-27 16:39:44 +02:00
ce33b4e10c Añadida la clase item_tracker 2022-08-27 16:08:22 +02:00
e94e750ca1 Modificados algunos printf 2022-08-27 14:35:51 +02:00
11a8ea8c24 Modificados algunos sonidos 2022-08-27 14:30:37 +02:00
58b238fa45 Ya coge los diamantes, aunque no los recuerda 2022-08-27 14:15:46 +02:00
2e102160e6 Plataformas moviles completadas 2022-08-27 09:36:43 +02:00
43c10d335b Ya se engancha verticalmente en las plataformas moviles 2022-08-27 07:55:06 +02:00
6b7c49aecd Trabajando en las colisiones con plataformas moviles 2022-08-26 21:25:51 +02:00
dda1e049c6 Ya detecta las plataformas móviles bajo los pies 2022-08-26 20:41:48 +02:00
5ff62a6950 Retocados nombres de variables antiguos 2022-08-26 19:53:19 +02:00
a4000d25db Empezando con los actores y polimorfismo. Ya pinta la plataforma movil 2022-08-26 13:36:31 +02:00
aea71599ff Creando subclases de actors 2022-08-26 07:24:22 +02:00
6b2901cebc Creado el primer boceto de la clase padre actor 2022-08-25 21:27:00 +02:00
39a8e9048a Cambiados los nombres de variables en text.h 2022-08-25 13:57:09 +02:00
a0613ddd8d Trabajando en el menu del titulo 2022-08-24 22:39:36 +02:00
1f4d094593 Retocando la clase menu 2022-08-24 13:58:52 +02:00
0749862af2 Cambiado el tipo de vector de la clase menu a std::vector 2022-08-23 20:50:55 +02:00
bca15cd29e Retocados los nombres de las variables de la clase menu 2022-08-23 20:08:28 +02:00
f2ea31a564 Añadido el degradado de fondo al archivo de mapa 2022-08-23 19:00:09 +02:00
2425ab5142 Añadida música al titulo 2022-08-23 17:03:10 +02:00
87f6ec39ea Añadida la clase Menu desde Coffee Crisis 2022-08-23 16:35:01 +02:00
6b9360ee18 Añadida la fuente Dogica 2022-08-23 14:00:52 +02:00
b61677bda9 Empezada la sección del titulo del juego 2022-08-23 12:35:56 +02:00
6b4926efb8 Completado el logo y la intro 2022-08-22 23:25:12 +02:00
f1e3cfe892 Añadidos los ficheros de intro y logo del coffee crisis 2022-08-22 17:44:24 +02:00
debdc861d5 Modificado el loop de las animaciones 2022-08-22 17:42:26 +02:00
7c7dcf1a12 Añadido mas texto al debug 2022-08-21 10:25:28 +02:00
b394395fa7 Añadida la música 2022-08-21 10:16:29 +02:00
6d2fe4541a Añadidos los enemigos 2022-08-20 20:49:35 +02:00
82089bb780 Empezando a trabajar con los enemigos 2022-08-20 19:11:59 +02:00
bb5d772a4b Borrado sync.sh 2022-08-20 17:31:42 +02:00
8c87534848 Desaparición de la carpeta media 2022-08-20 17:30:11 +02:00
75c6acdd53 Implementado el cambio de pantalla 2022-08-20 15:41:23 +02:00
7e93b3150f Terminados los tiles atravesables 2022-08-20 09:15:51 +02:00
8765049b69 Trabajando con el isOnFloor y los tiles passable 2022-08-19 14:05:56 +02:00
5144a14bcd Aladidos estados al jugador para mejorar el control sobre el salto y las caídas 2022-08-19 13:21:23 +02:00
1882f57c57 Cambiado el método de gestion de las colisiones del jugador. En vez de recular ahora corrige 2022-08-19 12:42:47 +02:00
0624cff845 Primera implementacion de tiles atravesables. No funcionará si estan apilados 2022-08-19 12:33:42 +02:00
76696f9eb7 Retocado un poco mas el salto 2022-08-19 07:21:25 +02:00
6a5f0b3b46 Convertido el juego a mapas con tiles de 8x8 2022-08-18 21:18:15 +02:00
c848a8b234 Antes de pasar el juego a tiles de 8x8 2022-08-18 20:41:53 +02:00
4de34c388d Añadidas físicas al movimiento y salto 2022-08-18 13:42:30 +02:00
b1c91d2d0d Colisiones básicas terminadas 2022-08-17 17:06:49 +02:00
02c2c1bce2 Implementado el salto del jugador 2022-08-17 13:44:41 +02:00
9bd1e9b936 Colisiones básicas completadas 2022-08-17 13:26:22 +02:00
a6d6f2854e Ta muestra información de depuración 2022-08-17 08:55:05 +02:00
a941f72208 Trabajando en las colisiones 2022-08-16 13:54:22 +02:00
77980a4d70 Actualizado el Makefile 2022-08-13 13:36:00 +02:00
a1eaf8af07 Implementadas las animaciones en el jugador 2022-08-13 12:14:31 +02:00
e85f138be5 Finalizado el nuevo motor de animaciones 2022-08-13 11:07:04 +02:00
d2a2a1625d Trabajando en la carga de las animaciones 2022-08-12 23:44:31 +02:00
99005329de Trabajando en la clase animatedsprite 2022-08-12 13:55:56 +02:00
71897291ff Comienzo de la reescritura de la clase animatedsprite 2022-08-12 12:59:32 +02:00
60a969a9bc Ya se dibuja el grafico de fondo en el mapa 2022-08-12 12:43:51 +02:00
0afc0cf629 El jugador ya empieza a moverse 2022-08-12 12:29:35 +02:00
2740ae9b7e Ya pinta al jugador 2022-08-12 12:16:49 +02:00
fcd9cf3b79 Cambiado el nombre a una variable 2022-08-11 21:16:00 +02:00
5ec9cc4fc2 Ya empieza a pintar el mapa 2022-08-11 21:13:51 +02:00
89a43b3529 Trabajando en la clase screen 2022-08-11 18:39:56 +02:00
09ad78b02e Trabajando en prog.cpp 2022-08-11 13:58:51 +02:00
57ddf60c1b Borrado todo el código y vuelta a empezar 2022-08-11 09:19:49 +02:00
1301ef6a27 Eliminado el código del volcano_2016 del repositorio 2022-08-10 20:51:01 +02:00
3e9051f02d Añadidas mas funciones del código viejo 2022-08-10 20:49:40 +02:00
b7a2273d49 Añadiendo funciones viejas a la clase Map 2022-08-10 19:50:46 +02:00
2e4e549fd8 Añadido el audio al jugador 2022-08-10 13:57:17 +02:00
d216df7baf Eliminados los métodos init y reset de la clase player 2022-08-09 17:34:01 +02:00
61297ff340 Actualizado renderGame y screen.h 2022-08-09 17:23:58 +02:00
63bf42880e Modificado unLoadMedia por saveConfig 2022-08-09 17:16:12 +02:00
d7bd5a8ab1 Modificado loadMedia por loadConfig 2022-08-09 17:12:40 +02:00
4d1a08a300 Integrada la clase asset. Corregidos algunos fallos en el bucle principal 2022-08-09 13:58:32 +02:00
ff341d8cee Trabajando en integrar el objeto asset y mejorar los objetos player y map 2022-08-08 23:05:13 +02:00
0fa0368cca A medio integrar el objeto asset 2022-08-08 21:19:10 +02:00
4439f8477a Modificado el bucle principal 2022-08-08 20:12:51 +02:00
1801c23957 Añadidas las librerias asset y screen 2022-08-08 19:44:50 +02:00
a3c846c137 Actualizadas todas las librerias de sprites 2022-08-08 19:37:55 +02:00
c5acab7828 Actualizada la librería sprite.h 2022-08-08 19:25:03 +02:00
a180f1db46 Quitado el fichero menu.h y sus referencias 2022-08-08 18:41:57 +02:00
55c26df2a5 Actualizado el fichero utils.h a una versión posterior 2022-08-08 18:39:51 +02:00
386039336e Actualizada la libreria text.h a la última versión 2022-08-08 18:37:42 +02:00
2b2b822540 Actualizado gitignore 2022-08-08 18:35:04 +02:00
132 changed files with 9041 additions and 5364 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
.vscode/*
.DS_Store
desktop.ini
thumbs.db
bin
bin/*

View File

@@ -3,4 +3,4 @@ macos:
g++ source/*.cpp -std=c++11 -Wall -O2 -lSDL2 -o bin/volcano_macos
linux:
mkdir -p bin
g++ source/*.cpp -std=c++11 -Wall -O2 -lSDL2 -o bin/volcano_macos
g++ source/*.cpp -std=c++11 -Wall -O2 -lSDL2 -o bin/volcano_linux

View File

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

BIN
data/actors/enemies/bug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

BIN
data/font/8bithud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

194
data/font/8bithud.txt Normal file
View File

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

BIN
data/font/debug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

194
data/font/debug.txt Normal file
View File

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

BIN
data/font/dogica.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

194
data/font/dogica.txt Normal file
View File

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

File diff suppressed because it is too large Load Diff

17
data/intro/intro.ani Normal file
View File

@@ -0,0 +1,17 @@
frames_per_row=4
frame_width=320
frame_height=240
[animation]
name=intro
speed=12
loop=-1
frames=0,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
[/animation]
[animation]
name=menu
speed=12
loop=0
frames=18,26,18,26,18,26,18,26,18,26,18,26,18,26,18,19,20,21,22,23,24,25,26
[/animation]

View File

Before

Width:  |  Height:  |  Size: 670 KiB

After

Width:  |  Height:  |  Size: 670 KiB

BIN
data/logo/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

14
data/map/01.ene Normal file
View File

@@ -0,0 +1,14 @@
[path]
tileset=walking_eye.png
animation=walking_eye.ani
width=16
height=16
x=22
y=20
vx=0.4
vy=0
x1=22
y1=20
x2=27
y2=20
[/path]

74
data/map/01.map Normal file
View File

@@ -0,0 +1,74 @@
tileset_img=surface.png
enemy_file=01.ene
bgColor1=234,171,159
bgColor2=144,225,231
room_up=0
room_down=0
room_left=0
room_right=02.map
[tilemap]
01.tmx
[/tilemap]
[actors]
[moving platform]
tileset=moving_platform.png
animation=moving_platform.ani
width=16
height=8
x=9
y=11
vx=0.3
vy=0
x1=9
y1=11
x2=15
y2=11
[/moving platform]
[moving platform]
tileset=moving_platform.png
animation=moving_platform.ani
width=16
height=8
x=20
y=14
vx=0
vy=0.3
x1=20
y1=14
x2=20
y2=21
[/moving platform]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=1
y=10
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=24
y=10
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=25
y=12
[/diamond]
[/actors]

34
data/map/01.tmx Normal file
View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.1" orientation="orthogonal" renderorder="right-down" width="40" height="26" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="surface.tsx"/>
<layer id="1" name="Capa de patrones 1" width="40" height="26">
<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,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,19,20,0,0,0,0,0,87,88,89,90,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,51,52,0,0,0,0,0,119,120,121,122,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,19,20,0,0,0,0,0,0,0,0,0,0,0,151,152,153,154,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,51,52,0,0,0,0,0,0,0,0,0,0,0,183,184,185,186,0,0,0,0,0,0,
0,18,19,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,50,51,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,19,20,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,51,52,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93,94,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,237,238,0,0,0,0,0,0,0,0,125,126,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,362,364,0,0,0,0,0,0,0,0,369,371,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,426,428,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,362,364,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,426,428,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,583,584,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,239,240,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,93,94,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,366,367,367,368,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,0,125,126,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,430,431,431,432,0,0,0,0,577,578,579,580,581,582,0,0,0,0,0,0,0,0,159,160,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,191,192,0,0,0,0,0,93,94,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,189,190,241,242,0,0,0,125,126,0,0,0,0,0,0,
363,364,0,0,0,0,0,193,194,0,0,0,0,189,190,0,0,0,237,238,0,0,362,282,277,278,279,274,364,0,0,0,157,158,0,0,0,0,0,0,
295,396,0,0,0,0,0,225,226,0,0,0,0,189,190,0,0,362,275,275,275,275,313,314,309,310,311,312,396,0,0,0,189,190,0,0,237,238,0,0,
265,264,263,264,263,264,263,264,263,264,263,264,263,264,263,264,263,264,267,266,266,266,283,284,266,265,266,267,263,264,263,264,263,264,263,264,263,264,263,264,
295,296,295,296,295,296,295,296,295,265,295,296,295,296,295,296,295,296,295,296,295,296,315,316,298,297,298,296,295,296,295,296,295,296,295,296,295,296,295,296
</data>
</layer>
</map>

29
data/map/02.ene Normal file
View File

@@ -0,0 +1,29 @@
[path]
tileset=flying_eye.png
animation=flying_eye.ani
width=16
height=16
x=9
y=12
vx=0
vy=0.3
x1=9
y1=12
x2=9
y2=20
[/path]
[path]
tileset=flying_eye_horn.png
animation=flying_eye_horn.ani
width=16
height=16
x=15
y=5
vx=0.5
vy=0
x1=5
y1=5
x2=30
y2=5
[/path]

92
data/map/02.map Normal file
View File

@@ -0,0 +1,92 @@
tileset_img=surface.png
enemy_file=02.ene
bgColor1=234,100,159
bgColor2=144,235,231
bgColor1=153,229,80
bgColor2=95,205,228
room_up=0
room_down=03.map
room_left=01.map
room_right=0
[tilemap]
02.tmx
[/tilemap]
[actors]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=5
y=13
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=8
y=7
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=12
y=11
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=16
y=17
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=18
y=15
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=20
y=13
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=27
y=9
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=33
y=14
[/diamond]
[/actors]

34
data/map/02.tmx Normal file
View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.1" orientation="orthogonal" renderorder="right-down" width="40" height="26" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="surface.tsx"/>
<layer id="1" name="Capa de patrones 1" width="40" height="26">
<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,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,19,20,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,51,52,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,88,89,90,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,119,120,121,122,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,19,20,0,0,0,0,0,0,0,0,0,0,0,0,151,152,153,154,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,51,52,0,0,0,0,0,0,0,0,0,0,0,0,183,184,185,186,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,362,363,363,364,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,404,395,395,406,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,112,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,577,578,579,580,581,582,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,109,110,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,141,142,138,113,264,263,264,364,0,0,0,0,0,0,0,0,0,0,0,161,162,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,180,169,170,138,313,295,296,406,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,372,373,373,264,78,137,138,75,76,145,0,0,0,0,0,0,583,584,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,144,86,77,110,169,170,83,108,0,0,0,0,0,0,0,161,162,0,0,0,0,0,159,160,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,109,148,137,138,115,0,0,0,0,0,0,583,584,155,156,65,66,0,0,0,191,192,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,109,110,170,115,0,0,0,0,0,0,161,162,187,188,97,98,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,141,142,138,83,0,0,0,0,583,584,155,156,65,66,69,70,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,180,169,170,115,0,0,0,0,161,162,187,188,97,98,101,102,0,0,0,189,190,0,0,93,94,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,362,282,276,277,279,364,193,194,0,157,158,93,94,157,158,157,158,0,0,0,69,70,0,0,125,126,0,0,0,93,94,0,0,
0,0,0,0,0,0,0,394,314,308,309,311,396,225,226,0,189,190,125,126,189,190,189,190,0,0,0,101,102,0,0,157,158,0,0,0,125,126,0,0,
363,363,363,363,363,363,363,363,265,265,265,265,363,363,363,363,363,363,363,363,363,363,363,363,363,364,0,189,190,0,362,363,363,363,363,363,363,363,363,363,
295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,296,296,296,296,396,0,189,190,0,394,296,296,296,296,296,296,296,296,296
</data>
</layer>
</map>

44
data/map/03.ene Normal file
View File

@@ -0,0 +1,44 @@
[path]
tileset=walking_eye.png
animation=walking_eye.ani
width=16
height=16
x=13
y=23
vx=0.4
vy=0
x1=3
y1=23
x2=18
y2=23
[/path]
[path]
tileset=walking_eye.png
animation=walking_eye.ani
width=16
height=16
x=22
y=13
vx=0.4
vy=0
x1=20
y1=13
x2=24
y2=13
[/path]
[path]
tileset=walking_eye.png
animation=walking_eye.ani
width=16
height=16
x=27
y=8
vx=-0.4
vy=0
x1=25
y1=8
x2=29
y2=8
[/path]

44
data/map/03.map Normal file
View File

@@ -0,0 +1,44 @@
tileset_img=surface.png
enemy_file=03.ene
bgColor1=143,86,59
bgColor2=69,40,60
room_up=02.map
room_down=0
room_left=0
room_right=0
[tilemap]
03.tmx
[/tilemap]
[actors]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=25
y=19
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=22
y=12
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=2
y=22
[/diamond]
[/actors]

34
data/map/03.tmx Normal file
View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.1" orientation="orthogonal" renderorder="right-down" width="40" height="26" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="surface.tsx"/>
<layer id="1" name="Capa de patrones 1" width="40" height="26">
<data encoding="csv">
260,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,432,0,189,190,0,430,431,431,431,431,431,431,431,431,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,260,
291,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,577,578,579,580,581,582,0,0,0,0,0,0,0,0,292,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,291,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,577,578,579,580,581,582,0,0,0,0,0,0,0,0,292,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,0,0,260,
291,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,155,156,65,66,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,187,188,97,98,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,577,578,579,580,581,582,0,0,0,157,158,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,292,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,159,160,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,67,0,0,0,0,0,0,191,192,0,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,157,158,0,0,0,0,0,0,577,578,579,580,581,582,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,291,
291,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,159,160,0,0,0,0,0,0,0,0,189,190,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,191,192,577,578,579,580,581,582,0,0,67,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,69,70,0,0,189,190,0,0,0,157,158,0,0,0,0,0,0,0,260,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,102,0,0,189,190,0,0,0,189,190,0,0,0,0,0,0,0,260,
260,260,257,258,260,260,260,260,258,260,260,260,260,260,257,260,260,260,258,260,260,260,260,260,260,260,260,260,257,258,260,260,260,260,260,260,257,260,260,260
</data>
</layer>
</map>

BIN
data/map/surface.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

1028
data/map/surface.tsx Normal file

File diff suppressed because it is too large Load Diff

27
data/map/surface.world Normal file
View File

@@ -0,0 +1,27 @@
{
"maps": [
{
"fileName": "02.tmx",
"height": 208,
"width": 320,
"x": 256,
"y": 0
},
{
"fileName": "01.tmx",
"height": 208,
"width": 320,
"x": -64,
"y": 0
},
{
"fileName": "03.tmx",
"height": 208,
"width": 320,
"x": 256,
"y": 208
}
],
"onlyShowAdjacentMaps": false,
"type": "world"
}

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

31
data/player/player.ani Normal file
View File

@@ -0,0 +1,31 @@
frames_per_row=8
frame_width=16
frame_height=24
[animation]
name=stand
speed=8
loop=0
frames=0,1,2,2,1,0,0,1,2,2,1,0,0,1,2,2,1,0,0,1,2,2,1,0,0,1,2,3,4,5,4,5,5,5,6,6,7,7,0,0
[/animation]
[animation]
name=walk
speed=4
loop=0
frames=8,9,10,10,9,8,11,12,13,13,14,15
[/animation]
[animation]
name=jump
speed=10
loop=-1
frames=16,17,18,17,16
[/animation]
[animation]
name=death
speed=10
loop=-1
frames=24,25,26,27,28,29,30,31
[/animation]

BIN
data/player/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

4
data/sound/desktop.ini Normal file
View File

@@ -0,0 +1,4 @@
[ViewState]
Mode=
Vid=
FolderType=Generic

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

76
source/actor.cpp Normal file
View File

@@ -0,0 +1,76 @@
#include "actor.h"
#include <fstream>
#include <sstream>
// Constructor
Actor::Actor()
{
}
// Constructor
Actor::Actor(actor_t actor)
{
// Obten punteros a objetos
asset = actor.asset;
renderer = actor.renderer;
// Crea objetos
texture = new LTexture();
loadTextureFromFile(texture, asset->get(actor.tileset), renderer);
sprite = new AnimatedSprite(texture, renderer, asset->get(actor.animation));
// Obten el resto de valores
sprite->setPosX(actor.x);
sprite->setPosY(actor.y);
sprite->setWidth(actor.w);
sprite->setHeight(actor.h);
sprite->setVelX(actor.vx);
sprite->setVelY(actor.vy);
sprite->setFlip(actor.vx > 0 ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL);
this->name = actor.name;
}
// Destructor
Actor::~Actor()
{
texture->unload();
delete texture;
texture = nullptr;
delete sprite;
sprite = nullptr;
}
// Pinta el enemigo en pantalla
void Actor::render()
{
sprite->render();
}
// Actualiza las variables del objeto
void Actor::update()
{
sprite->update();
sprite->animate();
}
// Obtiene el rectangulo de colision del enemigo
SDL_Rect &Actor::getCollider()
{
collider = sprite->getRect();
return collider;
}
// Obtiene el nombre del actor
actor_name_e Actor::getName()
{
return name;
}
// Obtiene el valor de la variable
int Actor::getIncX()
{
return sprite->getIncX();
}

73
source/actor.h Normal file
View File

@@ -0,0 +1,73 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include "asset.h"
#include "animatedsprite.h"
#include <string>
#ifndef ACTOR_H
#define ACTOR_H
// Nombres de actores
enum actor_name_e
{
a_moving_platform,
a_key,
a_heart,
a_diamond,
a_door
};
// Estructura para pasar los datos de un enemigo
struct actor_t
{
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
std::string tileset; // Fichero con los graficos del enemigo
std::string animation; // Fichero con las animaciones del enemigo
int w; // Anchura del enemigo
int h; // Altura del enemigo
float x; // Posición inicial en el eje X
float y; // Posición inicial en el eje Y
float vx; // Velocidad en el eje X
float vy; // Velocidad en el eje Y
actor_name_e name; // Nombre del actor
};
// Clase Actor
class Actor
{
protected:
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
LTexture *texture; // Textura con los graficos del enemigo
AnimatedSprite *sprite; // Sprite del enemigo
SDL_Rect collider; // Caja de colisión
actor_name_e name; // Nombre del actor
public:
// Constructor
Actor();
Actor(actor_t actor);
// Destructor
virtual ~Actor();
// Pinta el enemigo en pantalla
void render();
// Actualiza las variables del objeto
virtual void update();
// Obtiene el rectangulo de colision del enemigo
SDL_Rect &getCollider();
// Obtiene el nombre del actor
actor_name_e getName();
// Obtiene el valor de la variable
int getIncX();
};
#endif

13
source/actor_diamond.cpp Normal file
View File

@@ -0,0 +1,13 @@
#include "actor_diamond.h"
#include <fstream>
#include <sstream>
// Constructor
ActorDiamond::ActorDiamond(actor_t actor) : Actor(actor)
{
}
// Destructor
ActorDiamond::~ActorDiamond()
{
}

25
source/actor_diamond.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
#include <SDL2/SDL.h>
#include "actor.h"
#include <string>
#ifndef ACTOR_DIAMOND_H
#define ACTOR_DIAMOND_H
// Clase Actor
class ActorDiamond : public Actor
{
private:
public:
// Constructor
ActorDiamond(actor_t actor);
// Destructor
~ActorDiamond();
};
#endif

View File

@@ -0,0 +1,39 @@
#include "actor_moving_platform.h"
#include <fstream>
#include <sstream>
// Constructor
ActorMovingPlatform::ActorMovingPlatform(actor_t actor, SDL_Point p1, SDL_Point p2) : Actor(actor)
{
this->p1 = p1;
this->p2 = p2;
}
// Destructor
ActorMovingPlatform::~ActorMovingPlatform()
{
}
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void ActorMovingPlatform::checkPath()
{
// Comprueba los límites horizontales
if (sprite->getPosX() > p2.x || sprite->getPosX() < p1.x)
{
sprite->setVelX(sprite->getVelX() * (-1));
}
// Comprueba los límites verticales
if (sprite->getPosY() > p2.y || sprite->getPosY() < p1.y)
{
sprite->setVelY(sprite->getVelY() * (-1));
}
}
// Actualiza las variables del objeto
void ActorMovingPlatform::update()
{
checkPath();
sprite->update();
sprite->animate();
}

View File

@@ -0,0 +1,34 @@
#pragma once
#include <SDL2/SDL.h>
#include "actor.h"
#include <string>
#ifndef ACTOR_MOVING_PLATFORM_H
#define ACTOR_MOVING_PLATFORM_H
// Clase Actor
class ActorMovingPlatform : public Actor
{
private:
SDL_Point p1; // Punto 1 (inicial) de la ruta
SDL_Point p2; // Punto 2 (final) de la ruta
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void checkPath();
// Actualiza la variable
void updateShift();
public:
// Constructor
ActorMovingPlatform(actor_t actor, SDL_Point p1, SDL_Point p2);
// Destructor
~ActorMovingPlatform();
// Actualiza las variables del objeto
void update();
};
#endif

View File

@@ -1,146 +1,267 @@
//#include "const.h"
#include "const.h"
#include "animatedsprite.h"
//#include <iostream>
// Constructor
AnimatedSprite::AnimatedSprite()
AnimatedSprite::AnimatedSprite(LTexture *texture, SDL_Renderer *renderer, std::string file)
{
MovingSprite::init(0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr);
init(nullptr, nullptr);
// Copia los punteros
setTexture(texture);
setRenderer(renderer);
// Carga las animaciones
load(file);
// Inicializa variables
currentAnimation = 0;
}
// Destructor
AnimatedSprite::~AnimatedSprite()
{
MovingSprite::init(0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr);
init(nullptr, nullptr);
for (auto &a : animation)
{
a.frames.clear();
}
animation.clear();
}
// Iniciador
void AnimatedSprite::init(LTexture *texture, SDL_Renderer *renderer)
// Obtiene el indice de la animación a partir del nombre
int AnimatedSprite::getIndex(std::string name)
{
mRenderer = renderer;
mTexture = texture;
for (Uint8 i = 0; i < 20; i++)
int index = -1;
for (int i = 0; i < animation.size(); i++)
{
mAnimation[i].numFrames = 0;
mAnimation[i].speed = 0;
mAnimation[i].loop = true;
mAnimation[i].currentFrame = 0;
mAnimation[i].counter = 0;
for (Uint8 j = 0; i < 50; i++)
if (animation[i].name == name)
{
mAnimation[i].frame[j].x = 0;
mAnimation[i].frame[j].y = 0;
mAnimation[i].frame[j].w = 0;
mAnimation[i].frame[j].h = 0;
index = i;
}
}
mCurrentAnimation = 0;
if (index == -1)
{
printf("** Warning: could not find \"%s\" animation\n", name.c_str());
index = 0;
}
return index;
}
// Calcula el frame correspondiente a la animación
void AnimatedSprite::animate(int index)
void AnimatedSprite::animate()
{
// Calculamos el frame actual a partir del contador
mAnimation[index].currentFrame = mAnimation[index].counter / mAnimation[index].speed;
if (enabled)
{
// Calcula el frame actual a partir del contador
animation[currentAnimation].currentFrame = animation[currentAnimation].counter / animation[currentAnimation].speed;
// Final de la animación
if (mAnimation[index].currentFrame >= 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())
{
// Si se reproduce en bucle
if (mAnimation[index].loop)
{
// Reiniciamos el contador de la animación
mAnimation[index].counter = 0;
if (animation[currentAnimation].loop == -1)
{ // Si no hay loop, deja el último frame
animation[currentAnimation].currentFrame = animation[currentAnimation].frames.size();
animation[currentAnimation].completed = true;
}
else
{
// Mantenemos el ultimo frame
mAnimation[index].currentFrame = mAnimation[index].numFrames;
{ // Si hay loop, vuelve al frame indicado
animation[currentAnimation].counter = 0;
animation[currentAnimation].currentFrame = animation[currentAnimation].loop;
}
}
// La animación no ha llegado a su fin
// En caso contrario
else
{
// Establece el frame correspondiente de la animación
setSpriteClip(mAnimation[index].frame[mAnimation[index].currentFrame]);
// Escoge el frame correspondiente de la animación
setSpriteClip(animation[currentAnimation].frames[animation[currentAnimation].currentFrame]);
// Incrementa el contador de la animacion
mAnimation[index].counter++;
animation[currentAnimation].counter++;
}
}
}
// Actualiza todas las variables del objeto: posición, velocidad y animación
void AnimatedSprite::update()
{
MovingSprite::update();
animate(mCurrentAnimation);
}
// Establece el frame actual de la animación
void AnimatedSprite::setCurrentFrame(Uint8 index, Uint8 num)
void AnimatedSprite::setCurrentFrame(std::string name, int num)
{
mAnimation[index].currentFrame = num;
animation[getIndex(name)].currentFrame = num;
}
// Establece el valor del contador
void AnimatedSprite::setAnimationCounter(Uint8 index, Uint16 num)
void AnimatedSprite::setAnimationCounter(std::string name, int num)
{
mAnimation[index].counter = num;
}
// Establece el rectangulo para un frame de una animación
void AnimatedSprite::setAnimationFrames(Uint8 index, Uint8 frame, int x, int y, int w, int h)
{
mAnimation[index].frame[frame].y = y;
mAnimation[index].frame[frame].w = w;
mAnimation[index].frame[frame].h = h;
mAnimation[index].frame[frame].x = x;
}
// Establece el rectangulo para un frame de una animación
void AnimatedSprite::setAnimationFrames(Uint8 index, Uint8 frame, SDL_Rect rect)
{
mAnimation[index].frame[frame] = rect;
animation[getIndex(name)].counter = num;
}
// Establece la velocidad de una animación
void AnimatedSprite::setAnimationSpeed(Uint8 index, Uint8 speed)
void AnimatedSprite::setAnimationSpeed(std::string name, int speed)
{
mAnimation[index].speed = speed;
}
// Establece el numero de frames de una animación
void AnimatedSprite::setAnimationNumFrames(Uint8 index, Uint8 num)
{
if (num < MAX_FRAMES)
mAnimation[index].numFrames = num;
animation[getIndex(name)].counter = speed;
}
// Establece si la animación se reproduce en bucle
void AnimatedSprite::setAnimationLoop(Uint8 index, bool loop)
void AnimatedSprite::setAnimationLoop(std::string name, int loop)
{
mAnimation[index].loop = loop;
animation[getIndex(name)].loop = loop;
}
// Establece el valor de la variable
void AnimatedSprite::setAnimationCompleted(std::string name, bool value)
{
animation[getIndex(name)].completed = value;
}
// Comprueba si ha terminado la animación
bool AnimatedSprite::animationIsCompleted()
{
return animation[currentAnimation].completed;
}
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect AnimatedSprite::getAnimationClip(Uint8 index, Uint8 frame)
SDL_Rect AnimatedSprite::getAnimationClip(std::string name, Uint8 index)
{
return mAnimation[index].frame[frame];
return animation[getIndex(name)].frames[index];
}
// Establece la animación actual
void AnimatedSprite::setCurrentAnimation(Uint8 index)
// Carga la animación desde un fichero
bool AnimatedSprite::load(std::string filePath)
{
if (index < MAX_ANIMATIONS)
mCurrentAnimation = index;
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;
}
// Obtiene la animación actual
Uint8 AnimatedSprite::getCurrentAnimation()
// Establece la animacion actual
void AnimatedSprite::setCurrentAnimation(std::string name)
{
return mCurrentAnimation;
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,75 +1,74 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
#include "movingsprite.h"
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#ifndef ANIMATEDSPRITE_H
#define ANIMATEDSPRITE_H
#define MAX_FRAMES 50
#define MAX_ANIMATIONS 20
// Clase AnimatedSprite
class AnimatedSprite : public MovingSprite
{
private:
struct t_animation
{
std::string name; // Nombre de la animacion
std::vector<SDL_Rect> frames; // Cada uno de los frames que componen la animación
int speed; // Velocidad de la animación
int loop; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
bool completed; // Indica si ha finalizado la animación
int currentFrame; // Frame actual
int counter; // Contador para las animaciones
};
std::vector<t_animation> animation; // Vector con las diferentes animaciones
int currentAnimation; // Animacion activa
public:
// Constructor
AnimatedSprite();
AnimatedSprite(LTexture *texture = nullptr, SDL_Renderer *renderer = nullptr, std::string file = "");
// Destructor
~AnimatedSprite();
// Iniciador
void init(LTexture *texture, SDL_Renderer *renderer);
// Calcula el frame correspondiente a la animación
void animate(int index);
// Actualiza todas las variables del objeto: posición, velocidad y animación
void update();
// Calcula el frame correspondiente a la animación actual
void animate();
// Establece el frame actual de la animación
void setCurrentFrame(Uint8 index, Uint8 num);
void setCurrentFrame(std::string name, int num);
// Establece el valor del contador
void setAnimationCounter(Uint8 index, Uint16 num);
// Establece el rectangulo para un frame de una animación
void setAnimationFrames(Uint8 index, Uint8 frame, int x, int y, int w, int h);
// Establece el rectangulo para un frame de una animación
void setAnimationFrames(Uint8 index, Uint8 frame, SDL_Rect rect);
void setAnimationCounter(std::string name, int num);
// Establece la velocidad de una animación
void setAnimationSpeed(Uint8 index, Uint8 speed);
void setAnimationSpeed(std::string name, int speed);
// Establece el numero de frames de una animación
void setAnimationNumFrames(Uint8 index, Uint8 num);
// Establece el frame al que vuelve la animación al finalizar
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
void setAnimationCompleted(std::string name, bool value);
// Comprueba si ha terminado la animación
bool animationIsCompleted();
// Devuelve el rectangulo de una animación y frame concreto
SDL_Rect getAnimationClip(Uint8 index, Uint8 frame);
SDL_Rect getAnimationClip(std::string name, Uint8 index);
// Establece la animación actual
void setCurrentAnimation(Uint8 index);
// Obtiene el indice de la animación a partir del nombre
int getIndex(std::string name);
// Obtiene la animación actual
Uint8 getCurrentAnimation();
// Carga la animación desde un fichero
bool load(std::string filePath);
private:
struct sAnimation
{
SDL_Rect frame[MAX_FRAMES]; // Vector con los rectangulos de cada frame de la animación
Uint8 numFrames; // Cantidad de frames de la animacion
Uint8 speed; // Velocidad de la animación
Uint8 currentFrame; // Frame actual
Uint16 counter; // Contador
bool loop; // Indica si la animación se reproduce en bucle
};
// Establece la animacion actual
void setCurrentAnimation(std::string name = "default");
sAnimation mAnimation[MAX_ANIMATIONS]; // Vector con las animaciones
Uint8 mCurrentAnimation; // Animación actual;
// Actualiza las variables del objeto
void update();
};
#endif

135
source/asset.cpp Normal file
View File

@@ -0,0 +1,135 @@
#include "asset.h"
// Constructor
Asset::Asset(std::string path)
{
mExecutablePath = path;
longest_name = 0;
}
// Destructor
Asset::~Asset()
{
}
// Añade un elemento a la lista
void Asset::add(std::string file, enum assetType type, bool required)
{
item_t temp;
temp.file = mExecutablePath + "/.." + file;
temp.type = type;
temp.required = required;
mFileList.push_back(temp);
const std::string filename = file.substr(file.find_last_of("\\/") + 1);
longest_name = SDL_max(longest_name, filename.size());
}
// Devuelve el fichero de un elemento de la lista a partir de una cadena
std::string Asset::get(std::string text)
{
for (int i = 0; i < mFileList.size(); i++)
if (mFileList[i].file.find(text) != std::string::npos)
return mFileList[i].file;
printf("Warning: file %s not found\n", text.c_str());
return "";
}
// Comprueba que existen todos los elementos
bool Asset::check()
{
bool success = true;
printf("\n** Checking files.\n");
// Comprueba la lista de ficheros clasificandolos por tipo
for (int type = 0; type < 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());
for (int i = 0; i < mFileList.size(); i++)
if ((mFileList[i].required) && (mFileList[i].type == type))
success &= checkFile(mFileList[i].file);
}
}
// Resultado
if (success)
printf("\n** All files OK.\n\n");
else
printf("\n** A file is missing. Exiting.\n\n");
return success;
}
// Comprueba que existe un fichero
bool Asset::checkFile(std::string path)
{
bool success = false;
std::string result = "ERROR";
// Comprueba si existe el fichero
const std::string filename = path.substr(path.find_last_of("\\/") + 1);
SDL_RWops *file = SDL_RWFromFile(path.c_str(), "r+b");
if (file != NULL)
{
result = "OK";
success = true;
SDL_RWclose(file);
}
const std::string s = "Checking file %-" + std::to_string(longest_name) + "s [" + result + "]\n";
printf(s.c_str(), filename.c_str());
return success;
}
// Devuelve el nombre del tipo de recurso
std::string Asset::getTypeName(int type)
{
switch (type)
{
case bitmap:
return "BITMAP";
break;
case music:
return "MUSIC";
break;
case sound:
return "SOUND";
break;
case font:
return "FONT";
break;
case lang:
return "LANG";
break;
case data:
return "DATA";
break;
case room:
return "ROOM";
break;
case enemy:
return "ENEMY";
break;
case item:
return "ITEM";
break;
default:
return "ERROR";
break;
}
}

64
source/asset.h Normal file
View File

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

View File

@@ -1,387 +1,18 @@
#pragma once
#include "ifdefs.h"
#include <string>
#ifndef CONST_H
#define CONST_H
// Textos
#define WINDOW_CAPTION "Volcano (@2016,2021 JailDesigner v0.5)"
const Uint8 GAME_SPEED = 24; //16 = normal-rapido, 24 = normal. Cuanto mas pequeño, más rápido
const Uint8 UP = 0;
const Uint8 DOWN = 2;
const Uint8 RIGHT = 1;
const Uint8 LEFT = 3;
const Uint8 NONE = 4;
const Uint8 MAP_TILE_HEIGHT = 16;
const Uint8 MAP_TILE_WIDTH = 16;
const Uint8 ROOM_WIDTH_IN_TILES = 20;
const Uint8 ROOM_HEIGHT_IN_TILES = 14;
const Uint16 GAME_WINDOW_WIDTH = 320;
const Uint16 GAME_WINDOW_HEIGHT = 234;
const Uint8 TEST_ROOM = 118;
const Uint8 STARTING_ROOM = 161; //TEST_ROOM;
const Uint8 STARTING_PLAYER_TILE_X = 5;
const Uint8 STARTING_PLAYER_TILE_Y = 11;
const Uint8 ENEMY_HITBOX_REDUCTION = 4;
const Uint8 COOLDOWN_TIME = 50;
const Uint8 GRAVITY = 1;
const Uint8 MAX_SPEED_Y = 5;
const Uint8 BASE_SPEED = 1;
const Uint8 MAX_SPEED = 8;
const Uint8 RATIO_SPEED = 8;
const Uint8 DROP_TIMER = 100;
const Uint8 TOP_COLLISION = 0;
const Uint8 BOTTOM_COLLISION = 1;
const Uint8 LEFT_COLLISION = 2;
const Uint8 RIGHT_COLLISION = 3;
const Uint8 NO_COLLISION = 4;
const Uint8 MAX_ACTORS = 50;
const Uint8 KIND_FLYING_ENEMY = 0;
const Uint8 KIND_COIN = 1;
const Uint8 KIND_HEART = 2;
const Uint8 KIND_STATIC_ENEMY = 3;
const Uint8 KIND_MOBILE_PLATFORM = 4;
const Uint8 KIND_WALKING_ENEMY = 5;
const Uint8 KIND_DROP_GENERATOR = 6;
const Uint8 KIND_DROP_ENEMY = 7;
const Uint8 KIND_DROP_SPLAT = 8;
const Uint8 KIND_SPEED_ENEMY = 9;
const Uint8 KIND_KEY = 10;
const Uint8 KIND_LOCK = 11;
const Uint8 CODE_ENEMY_V1U = 208;
const Uint8 CODE_ENEMY_V2U = 209;
const Uint8 CODE_ENEMY_V3U = 210;
const Uint8 CODE_ENEMY_V1D = 211;
const Uint8 CODE_ENEMY_V2D = 212;
const Uint8 CODE_ENEMY_V3D = 213;
const Uint8 CODE_ENEMY_H1L = 214;
const Uint8 CODE_ENEMY_H2L = 215;
const Uint8 CODE_ENEMY_H3L = 216;
const Uint8 CODE_ENEMY_H1R = 217;
const Uint8 CODE_ENEMY_H2R = 218;
const Uint8 CODE_ENEMY_H3R = 219;
const Uint8 CODE_ENEMY_W1L = 224;
const Uint8 CODE_ENEMY_W2L = 225;
const Uint8 CODE_ENEMY_W3L = 226;
const Uint8 CODE_ENEMY_W1R = 227;
const Uint8 CODE_ENEMY_W2R = 228;
const Uint8 CODE_ENEMY_W3R = 229;
const Uint8 CODE_ENEMY_DRP = 230;
const Uint8 CODE_ENEMY_SPL = 231;
const Uint8 CODE_ENEMY_SPR = 232;
const Uint8 CODE_COIN = 240;
const Uint8 CODE_HEART = 241;
const Uint8 CODE_KEY_RED = 242;
const Uint8 CODE_LOCK_RED = 243;
const Uint8 CODE_KEY_BLUE = 244;
const Uint8 CODE_LOCK_BLUE = 245;
const Uint8 CODE_KEY_GREEN = 246;
const Uint8 CODE_LOCK_GREEN = 247;
const Uint8 CODE_KEY_YELLOW = 248;
const Uint8 CODE_LOCK_YELLOW = 249;
const Uint8 MAX_ANIMATED_TILES = 200;
const Uint8 TILE_BACKGROUND = 0;
const Uint8 TILE_PLATFORM = 1;
const Uint8 TILE_KILLING_PLATFORM = 2;
const Uint8 TILE_ACTOR = 3;
const Uint8 TILE_TRAVESABLE_PLATFORM = 4;
const Uint8 PLAYER_ANIMATION_STANDING_LEFT = 0;
const Uint8 PLAYER_ANIMATION_STANDING_RIGHT = 1;
const Uint8 PLAYER_ANIMATION_WALKING_LEFT = 2;
const Uint8 PLAYER_ANIMATION_WALKING_RIGHT = 3;
const Uint8 PLAYER_ANIMATION_JUMPING_LEFT = 4;
const Uint8 PLAYER_ANIMATION_JUMPING_RIGHT = 5;
const Uint8 PLAYER_ANIMATION_DYING_LEFT = 6;
const Uint8 PLAYER_ANIMATION_DYING_RIGHT = 7;
const Uint8 SECTION_MENU = 0;
const Uint8 SECTION_GAME = 1;
const Uint8 SECTION_QUIT = 2;
const Uint8 MENU_SECTION_MAIN = 0;
const Uint8 MENU_SECTION_CREDITS = 1;
const Uint8 MENU_SECTION_ANIMATION = 2;
const Uint8 ZONE_SURFACE = 0;
const Uint8 ZONE_VOLCANO = 1;
// Recursos
const Uint8 FILE_MAP_VOLCANO = 0;
const Uint8 FILE_CONFIG = 1;
const Uint8 TOTAL_FILE = 2;
const Uint8 TEXTURE_ACTORS = 0;
const Uint8 TEXTURE_BKG_SURFACE = 1;
const Uint8 TEXTURE_FILTER = 2;
const Uint8 TEXTURE_HUD = 3;
const Uint8 TEXTURE_MENU = 4;
const Uint8 TEXTURE_MENU_ANIMATION = 5;
const Uint8 TEXTURE_PLAYER = 6;
const Uint8 TEXTURE_TILES_SURFACE = 7;
const Uint8 TEXTURE_TILES_VOLCANO = 8;
const Uint8 TOTAL_TEXTURE = 9;
const Uint8 SOUND_COIN = 0;
const Uint8 SOUND_DEATH = 1;
const Uint8 SOUND_DROP_ENEMY = 2;
const Uint8 SOUND_DROP_SPLAT = 3;
const Uint8 SOUND_JUMP = 4;
const Uint8 SOUND_MENU_LOGO = 5;
const Uint8 SOUND_MENU_START = 6;
const Uint8 TOTAL_SOUND = 7;
const Uint8 MUSIC_MENU = 0;
const Uint8 MUSIC_SURFACE = 1;
const Uint8 MUSIC_VOLCANO = 2;
const Uint8 TOTAL_MUSIC = 3;
///////////////////////////////COFFEE CRISIS//////////////////////////////////////////////
// Tamaño de bloque
const Uint8 BLOCK = 8;
const Uint8 HALF_BLOCK = BLOCK / 2;
#define BLOCK 16
#define HALF_BLOCK 8
// Tamaño de la pantalla real
const int SCREEN_WIDTH = 320;
const int SCREEN_HEIGHT = SCREEN_WIDTH * 3 / 4; // 240
// Tamaño de la pantalla que se muestra
const int VIEW_WIDTH = SCREEN_WIDTH * 3; // 960
const int VIEW_HEIGHT = SCREEN_HEIGHT * 3; // 720
// Cantidad de enteros a escribir en los ficheros de datos
const Uint8 TOTAL_SCORE_DATA = 3;
const Uint16 TOTAL_DEMO_DATA = 2000;
// Zona de juego
const int PLAY_AREA_TOP = (0 * BLOCK);
const int PLAY_AREA_BOTTOM = SCREEN_HEIGHT - (4 * BLOCK);
const int PLAY_AREA_LEFT = (0 * BLOCK);
const int PLAY_AREA_RIGHT = SCREEN_WIDTH - (0 * BLOCK);
const int PLAY_AREA_WIDTH = PLAY_AREA_RIGHT - PLAY_AREA_LEFT;
const int PLAY_AREA_HEIGHT = PLAY_AREA_BOTTOM - PLAY_AREA_TOP;
const int PLAY_AREA_CENTER_X = PLAY_AREA_LEFT + (PLAY_AREA_WIDTH / 2);
const int PLAY_AREA_CENTER_Y = PLAY_AREA_TOP + (PLAY_AREA_HEIGHT / 2);
const int PLAY_AREA_FIRST_QUARTER_Y = PLAY_AREA_HEIGHT / 4;
const int PLAY_AREA_THIRD_QUARTER_Y = (PLAY_AREA_HEIGHT / 4) * 3;
// Anclajes de pantalla
const int SCREEN_CENTER_X = SCREEN_WIDTH / 2;
const int SCREEN_FIRST_QUARTER_X = SCREEN_WIDTH / 4;
const int SCREEN_THIRD_QUARTER_X = (SCREEN_WIDTH / 4) * 3;
const int SCREEN_CENTER_Y = SCREEN_HEIGHT / 2;
const int SCREEN_FIRST_QUARTER_Y = SCREEN_HEIGHT / 4;
const int SCREEN_THIRD_QUARTER_Y = (SCREEN_HEIGHT / 4) * 3;
// Color transparente para los sprites
const Uint8 COLOR_KEY_R = 0xff;
const Uint8 COLOR_KEY_G = 0x00;
const Uint8 COLOR_KEY_B = 0xff;
// Opciones de menu
const int MENU_NO_OPTION = -1;
const int MENU_OPTION_START = 0;
const int MENU_OPTION_QUIT = 1;
const int MENU_OPTION_TOTAL = 2;
// Selector de menu
const int MENU_SELECTOR_BLACK = (BLOCK * 0);
const int MENU_SELECTOR_WHITE = (BLOCK * 1);
// Tipos de fondos para el menu
const int MENU_BACKGROUND_TRANSPARENT = 0;
const int MENU_BACKGROUND_SOLID = 1;
// Estados del jugador
const Uint8 PLAYER_STATUS_WALKING_LEFT = 0;
const Uint8 PLAYER_STATUS_WALKING_RIGHT = 1;
const Uint8 PLAYER_STATUS_WALKING_STOP = 2;
const Uint8 PLAYER_STATUS_FIRING_UP = 0;
const Uint8 PLAYER_STATUS_FIRING_LEFT = 1;
const Uint8 PLAYER_STATUS_FIRING_RIGHT = 2;
const Uint8 PLAYER_STATUS_FIRING_NO = 3;
const Uint8 PLAYER_ANIMATION_LEGS_WALKING_LEFT = 0;
const Uint8 PLAYER_ANIMATION_LEGS_WALKING_RIGHT = 1;
const Uint8 PLAYER_ANIMATION_LEGS_WALKING_STOP = 2;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_LEFT = 0;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_LEFT = 1;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_RIGHT = 2;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_RIGHT = 3;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_STOP = 4;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_UP = 5;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_LEFT_EXTRA_HIT = 6;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_LEFT_EXTRA_HIT = 7;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_RIGHT_EXTRA_HIT = 8;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_RIGHT_EXTRA_HIT = 9;
const Uint8 PLAYER_ANIMATION_BODY_WALKING_STOP_EXTRA_HIT = 10;
const Uint8 PLAYER_ANIMATION_BODY_FIRING_UP_EXTRA_HIT = 11;
// Variables del jugador
const Uint16 PLAYER_INVULNERABLE_TIMER = 200;
// Estados del juego
const Uint8 GAME_SECTION_TITLE = 0;
const Uint8 GAME_SECTION_PLAYING = 1;
const Uint8 GAME_SECTION_QUIT = 2;
const Uint8 GAME_SECTION_GAME_OVER_SCREEN = 3;
const Uint8 GAME_SECTION_INTRO = 4;
const Uint8 GAME_SECTION_DEMO = 5;
const Uint8 GAME_SECTION_INSTRUCTIONS = 6;
const Uint8 GAME_SECTION_LOGO = 7;
const Uint8 GAME_SECTION_INIT = 8;
// Estados de cada elemento que pertenece a un evento
const Uint8 EVENT_WAITING = 1;
const Uint8 EVENT_RUNNING = 2;
const Uint8 EVENT_COMPLETED = 3;
// Cantidad de eventos de la intro
const Uint8 INTRO_TOTAL_BITMAPS = 6;
const Uint8 INTRO_TOTAL_TEXTS = 9;
const Uint8 INTRO_TOTAL_EVENTS = INTRO_TOTAL_BITMAPS + INTRO_TOTAL_TEXTS;
// Cantidad de eventos de la pantalla de titulo
const Uint8 TITLE_TOTAL_EVENTS = 2;
// Relaciones de Id con nomnbres
const Uint8 BITMAP0 = 0;
const Uint8 BITMAP1 = 1;
const Uint8 BITMAP2 = 2;
const Uint8 BITMAP3 = 3;
const Uint8 BITMAP4 = 4;
const Uint8 BITMAP5 = 5;
const Uint8 TEXT0 = 6;
const Uint8 TEXT1 = 7;
const Uint8 TEXT2 = 8;
const Uint8 TEXT3 = 9;
const Uint8 TEXT4 = 10;
const Uint8 TEXT5 = 11;
const Uint8 TEXT6 = 12;
const Uint8 TEXT7 = 13;
const Uint8 TEXT8 = 14;
// Anclajes para el marcador de puntos
const int SCORE_WORD_X = (SCREEN_WIDTH / 4) - ((5 * BLOCK) / 2);
const int SCORE_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int SCORE_NUMBER_X = (SCREEN_WIDTH / 4) - ((6 * BLOCK) / 2);
const int SCORE_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
const int HISCORE_WORD_X = ((SCREEN_WIDTH / 4) * 3) - ((8 * BLOCK) / 2);
const int HISCORE_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int HISCORE_NUMBER_X = ((SCREEN_WIDTH / 4) * 3) - ((6 * BLOCK) / 2);
const int HISCORE_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
const int MULTIPLIER_WORD_X = (SCREEN_WIDTH / 2) - ((4 * BLOCK) / 2);
const int MULTIPLIER_WORD_Y = SCREEN_HEIGHT - (3 * BLOCK) + 2;
const int MULTIPLIER_NUMBER_X = (SCREEN_WIDTH / 2) - ((3 * BLOCK) / 2);;
const int MULTIPLIER_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2;
// Ningun tipo
const Uint8 NO_KIND = 0;
// Tipos de globo
const Uint8 BALLOON_1 = 1;
const Uint8 BALLOON_2 = 2;
const Uint8 BALLOON_3 = 3;
const Uint8 BALLOON_4 = 4;
// Velocidad del globo
const float BALLON_VELX_POSITIVE = 0.7f;
const float BALLON_VELX_NEGATIVE = -0.7f;
// Indice para las animaciones de los globos
const Uint8 BALLOON_MOVING_ANIMATION = 0;
const Uint8 BALLOON_POP_ANIMATION = 1;
const Uint8 BALLOON_BORN_ANIMATION = 2;
// Cantidad posible de globos
const Uint8 MAX_BALLOONS = 75;
// Tipos de bala
const Uint8 BULLET_UP = 1;
const Uint8 BULLET_LEFT = 2;
const Uint8 BULLET_RIGHT = 3;
// Cantidad posible de globos
const Uint8 MAX_BULLETS = 50;
// Tipos de objetos
const Uint8 ITEM_POINTS_1_DISK = 1;
const Uint8 ITEM_POINTS_2_GAVINA = 2;
const Uint8 ITEM_POINTS_3_PACMAR = 3;
const Uint8 ITEM_CLOCK = 4;
const Uint8 ITEM_TNT = 5;
const Uint8 ITEM_COFFEE = 6;
// Cantidad de objetos simultaneos
const Uint8 MAX_ITEMS = 5;
// Valores para las variables asociadas a los objetos
const Uint8 REMAINING_EXPLOSIONS = 3;
const Uint8 REMAINING_EXPLOSIONS_TIMER = 50;
const Uint16 TIME_STOPPED_TIMER = 300;
// Estados de entrada
const Uint8 NO_INPUT = 0;
const Uint8 INPUT_UP = 1;
const Uint8 INPUT_DOWN = 2;
const Uint8 INPUT_LEFT = 3;
const Uint8 INPUT_RIGHT = 4;
const Uint8 INPUT_ACCEPT = 5;
const Uint8 INPUT_CANCEL = 6;
const Uint8 INPUT_FIRE_UP = 7;
const Uint8 INPUT_FIRE_LEFT = 8;
const Uint8 INPUT_FIRE_RIGHT = 9;
const Uint8 INPUT_PAUSE = 10;
// Zona muerta del mando analógico
const int JOYSTICK_DEAD_ZONE = 8000;
// Tipos de mensajes para el retorno de las funciones
const Uint8 MSG_OK = 0;
const Uint8 MSG_BULLET_OUT = 1;
// Tipos de texto
const Uint8 TEXT_FIXED = 0;
const Uint8 TEXT_VARIABLE = 1;
// Cantidad de elementos del vector de SmartSprites
const Uint8 MAX_SMART_SPRITES = 10;
// Contadores
const Uint16 TITLE_TIMER = 800;
const Uint8 STAGE_COUNTER = 200;
const Uint16 INSTRUCTIONS_COUNTER = 600;
const Uint16 DEATH_COUNTER = 350;
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
// Tamaño de la pantalla virtual
#define GAMECANVAS_WIDTH 320
#define GAMECANVAS_HEIGHT 240
#endif

View File

@@ -1,685 +0,0 @@
#include "const.h"
#include "struct.h"
#include "director.h"
#include <iostream>
const Uint8 *keystates;
// Constructor
Director::Director(std::string _path)
{
// Crea todos los objetos del juego
initObjects();
// Inicializa todas las variables
init(_path);
}
Director::~Director()
{
// Borra todos los objetos del juego
deleteObjects();
// Destruye la ventana
SDL_DestroyRenderer(renderer);
SDL_DestroyTexture(backbuffer);
SDL_DestroyWindow(window);
backbuffer = nullptr;
renderer = nullptr;
window = nullptr;
// Sal del subsistema SDL
SDL_Quit();
}
// Inicializa todas las variables
void Director::init(std::string _path)
{
setPath(_path);
section = NONE;
gameControllerFound = false;
for (int i = 0; i < 360; i++)
sen[i] = sin(i * 3.14 / 180);
for (int i = 0; i < TOTAL_SCORE_DATA; i++)
scoreData[i] = 0;
initOptions();
quit = false;
}
// Inicializa las variables de las opciones
void Director::initOptions()
{
options.fullScreenMode = 0;
options.fullScreenModePrevious = 0;
options.windowSize = 0;
options.windowSizePrevious = 0;
}
// Inicializa las variables del juego
void Director::initGame()
{
// Variables
game.score = 0;
game.section = 0;
game.paused = false;
game.ticks = 0;
game.ticksSpeed = GAME_SPEED;
game.counter = 0;
// Player
resource.texture[TEXTURE_PLAYER].texture = new LTexture();
loadTextureFromFile(resource.texture[TEXTURE_PLAYER].texture, resource.texture[TEXTURE_PLAYER].file, renderer);
player = new Player(renderer, resource.texture[TEXTURE_PLAYER].texture);
// Map
resource.texture[TEXTURE_ACTORS].texture = new LTexture();
loadTextureFromFile(resource.texture[TEXTURE_ACTORS].texture, resource.texture[TEXTURE_ACTORS].file, renderer);
resource.texture[TEXTURE_BKG_SURFACE].texture = new LTexture();
loadTextureFromFile(resource.texture[TEXTURE_BKG_SURFACE].texture, resource.texture[TEXTURE_BKG_SURFACE].file, renderer);
resource.texture[TEXTURE_TILES_VOLCANO].texture = new LTexture();
loadTextureFromFile(resource.texture[TEXTURE_TILES_VOLCANO].texture, resource.texture[TEXTURE_TILES_VOLCANO].file, renderer);
map = new Map(renderer, resource.texture[TEXTURE_TILES_VOLCANO].texture, resource.texture[TEXTURE_ACTORS].texture,
resource.texture[TEXTURE_BKG_SURFACE].texture, resource.file[FILE_MAP_VOLCANO].file);
}
// Limpia las variables del juego
void Director::quitGame()
{
// Player
delete player;
player = nullptr;
delete resource.texture[TEXTURE_PLAYER].texture;
resource.texture[TEXTURE_PLAYER].texture = nullptr;
// Map
delete map;
map = nullptr;
delete resource.texture[TEXTURE_TILES_VOLCANO].texture;
resource.texture[TEXTURE_TILES_VOLCANO].texture = nullptr;
delete resource.texture[TEXTURE_ACTORS].texture;
resource.texture[TEXTURE_ACTORS].texture = nullptr;
delete resource.texture[TEXTURE_BKG_SURFACE].texture;
resource.texture[TEXTURE_BKG_SURFACE].texture = nullptr;
}
// Arranca SDL y crea la ventana
bool Director::initSDL()
{
// Indicador de inicialización
bool success = true;
// Inicializa SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_HAPTIC) < 0)
{
printf("SDL could not initialize!\nSDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
// Establece el filtro de la textura a nearest
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"))
{
printf("Warning: Nearest texture filtering not enabled!\n");
}
// Inicializa jail_audio
JA_Init(48000, AUDIO_S16, 2);
// Comprueba si hay algun mando conectado
if (SDL_NumJoysticks() < 1)
{
printf("Warning: No joysticks connected!\n");
gameControllerFound = false;
}
else
{
// Carga el mando
gameController = SDL_JoystickOpen(0);
gameControllerFound = true;
if (gameController == NULL)
{
printf("Warning: Unable to open game controller!\nSDL Error: %s\n", SDL_GetError());
gameControllerFound = false;
}
else
{
printf("%i joysticks were found.\n", SDL_NumJoysticks());
std::cout << SDL_JoystickNumButtons(gameController) << " buttons\n";
//Get controller haptic device
controllerHaptic = SDL_HapticOpenFromJoystick(gameController);
if (controllerHaptic == NULL)
{
printf("Warning: Controller does not support haptics!\nSDL Error: %s\n", SDL_GetError());
}
else
{
printf("Haptics detected\n");
//Get initialize rumble
if (SDL_HapticRumbleInit(controllerHaptic) < 0)
{
printf("Warning: Unable to initialize rumble!\nSDL Error: %s\n", SDL_GetError());
}
}
}
}
// Crea la ventana
window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, VIEW_WIDTH, VIEW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (window == NULL)
{
printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
// Crea un renderizador para la ventana con vsync
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (renderer == NULL)
{
printf("Renderer could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
// Inicializa el color de renderizado
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
// Establece el tamaño del buffer de renderizado
SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);
// Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
}
// Crea un backbuffer para el renderizador
backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT);
if (backbuffer == NULL)
{
printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError());
success = false;
}
}
}
printf("\n");
return success;
}
// Crea los objetos del programa
void Director::initObjects()
{
eventHandler = new SDL_Event();
text.white = new Text();
}
// Borra los objetos del programa
void Director::deleteObjects()
{
delete eventHandler;
delete text.white;
eventHandler = nullptr;
text.white = nullptr;
}
// Crea el indice de ficheros de recursos
void Director::setResourceList()
{
// Ficheros binarios
resource.file[FILE_MAP_VOLCANO].file = path + "/" + "../data/volcano.map";
resource.file[FILE_CONFIG].file = path + "/" + "../data/config.bin";
// Texturas
resource.texture[TEXTURE_ACTORS].file = path + "/" + "../media/gfx/actors.png";
resource.texture[TEXTURE_BKG_SURFACE].file = path + "/" + "../media/gfx/bkg_surface.png";
resource.texture[TEXTURE_FILTER].file = path + "/" + "../media/gfx/filter.png";
resource.texture[TEXTURE_HUD].file = path + "/" + "../media/gfx/hud.png";
resource.texture[TEXTURE_MENU_ANIMATION].file = path + "/" + "../media/gfx/menu_animation.png";
resource.texture[TEXTURE_MENU].file = path + "/" + "../media/gfx/menu.png";
resource.texture[TEXTURE_PLAYER].file = path + "/" + "../media/gfx/player.png";
resource.texture[TEXTURE_TILES_SURFACE].file = path + "/" + "../media/gfx/tiles_surface.png";
resource.texture[TEXTURE_TILES_VOLCANO].file = path + "/" + "../media/gfx/tiles_volcano.png";
for (Uint8 i = 0; i < TOTAL_TEXTURE; i++)
resource.texture[i].texture = nullptr;
// Sonidos
resource.sound[SOUND_COIN].file = path + "/" + "../media/sound/sound_player_coin.wav";
resource.sound[SOUND_DEATH].file = path + "/" + "../media/sound/sound_player_death.wav";
resource.sound[SOUND_DROP_ENEMY].file = path + "/" + "../media/sound/sound_drop_enemy.wav";
resource.sound[SOUND_DROP_SPLAT].file = path + "/" + "../media/sound/sound_drop_splat.wav";
resource.sound[SOUND_JUMP].file = path + "/" + "../media/sound/sound_player_jump.wav";
resource.sound[SOUND_MENU_LOGO].file = path + "/" + "../media/sound/sound_menu_logo.wav";
resource.sound[SOUND_MENU_START].file = path + "/" + "../media/sound/sound_menu_start.wav";
for (Uint8 i = 0; i < TOTAL_SOUND; i++)
resource.sound[i].sound = nullptr;
// Musicas
resource.music[MUSIC_MENU].file = path + "/" + "../media/music/music_menu.ogg";
resource.music[MUSIC_SURFACE].file = path + "/" + "../media/music/music_surface.ogg";
resource.music[MUSIC_VOLCANO].file = path + "/" + "../media/music/music_volcano.ogg";
for (Uint8 i = 0; i < TOTAL_TEXTURE; i++)
resource.music[i].music = nullptr;
}
// Comprueba que todos los ficheros de recursos existen
bool Director::checkResourceList()
{
bool success = true;
std::string p;
std::string filename;
SDL_RWops *file;
// Comprueba los ficheros de musica
printf("\n>> MUSIC FILES\n");
for (Uint8 i = 0; i < TOTAL_MUSIC; i++)
{
p = resource.music[i].file.c_str();
filename = p.substr(p.find_last_of("\\/") + 1);
file = SDL_RWFromFile(p.c_str(), "r+b");
if (file != NULL)
{
printf("Checking file %-20s [OK]\n", filename.c_str());
}
else
{
success = false;
printf("Checking file %-20s [ERROR]\n", filename.c_str());
}
SDL_RWclose(file);
}
// Comprueba los ficheros de sonidos
printf("\n>> SOUND FILES\n");
for (Uint8 i = 0; i < TOTAL_SOUND; i++)
{
p = resource.sound[i].file.c_str();
filename = p.substr(p.find_last_of("\\/") + 1);
file = SDL_RWFromFile(p.c_str(), "r+b");
if (file != NULL)
{
printf("Checking file %-20s [OK]\n", filename.c_str());
}
else
{
success = false;
printf("Checking file %-20s [ERROR]\n", filename.c_str());
}
SDL_RWclose(file);
}
// Comprueba los ficheros con texturas
printf("\n>> TEXTURE FILES\n");
for (Uint8 i = 0; i < TOTAL_TEXTURE; i++)
{
p = resource.texture[i].file.c_str();
filename = p.substr(p.find_last_of("\\/") + 1);
file = SDL_RWFromFile(p.c_str(), "r+b");
if (file != NULL)
{
printf("Checking file %-20s [OK]\n", filename.c_str());
}
else
{
success = false;
printf("Checking file %-20s [ERROR]\n", filename.c_str());
}
SDL_RWclose(file);
}
// Resultado
if (success)
{
printf("\n** All files OK.\n\n");
}
else
{
printf("\n** File is missing. Exiting.\n\n");
}
return success;
}
// Inicializa la variable con los ficheros de recursos
bool Director::initResourceList()
{
setResourceList();
return checkResourceList();
}
// Carga un archivo de imagen en una textura
bool Director::loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer)
{
bool success = true;
if (!texture->loadFromFile(path, renderer))
{
printf("Failed to load %s texture!\n", path.c_str());
success = false;
}
return success;
}
// Carga los recursos necesarios
bool Director::loadMedia(Uint8 section)
{
// Indicador de éxito en la carga
bool success = true;
std::string p;
switch (section)
{
case GAME_SECTION_INIT:
{
p = resource.file[FILE_CONFIG].file.c_str();
std::string filename = p.substr(p.find_last_of("\\/") + 1);
filename = p.substr(p.find_last_of("\\/") + 1);
// Abre el fichero con la configuracion de las opciones para leer en binario
SDL_RWops *file = SDL_RWFromFile(p.c_str(), "r+b");
// El fichero no existe
if (file == NULL)
{
printf("Warning: Unable to open %s file\n", filename.c_str());
// Crea el fichero para escribir
file = SDL_RWFromFile(p.c_str(), "w+b");
if (file != NULL)
{
printf("New file (%s) created!\n", filename.c_str());
// Inicializa los datos
options.fullScreenMode = 0;
SDL_RWwrite(file, &options.fullScreenMode, sizeof(options.fullScreenMode), 1);
options.windowSize = 3;
SDL_RWwrite(file, &options.windowSize, sizeof(options.windowSize), 1);
// Cierra el fichero
SDL_RWclose(file);
}
else
{
printf("Error: Unable to create file %s\n", filename.c_str());
success = false;
}
}
// El fichero existe
else
{
// Carga los datos
printf("Reading file %s\n", filename.c_str());
SDL_RWread(file, &options.fullScreenMode, sizeof(options.fullScreenMode), 1);
SDL_SetWindowFullscreen(window, options.fullScreenMode);
SDL_RWread(file, &options.windowSize, sizeof(options.windowSize), 1);
SDL_SetWindowSize(window, SCREEN_WIDTH * options.windowSize, SCREEN_HEIGHT * options.windowSize);
// Cierra el fichero
SDL_RWclose(file);
}
printf("\n");
// Texturas
// Sonidos
// Musicas
}
break;
case GAME_SECTION_TITLE:
{
}
break;
case GAME_SECTION_PLAYING:
{
}
break;
case GAME_SECTION_GAME_OVER_SCREEN:
{
}
break;
case GAME_SECTION_INTRO:
{
}
break;
case GAME_SECTION_DEMO:
{
}
break;
case GAME_SECTION_INSTRUCTIONS:
{
}
break;
case GAME_SECTION_LOGO:
{
}
break;
default:
{
}
break;
}
return success;
}
// Descrga los recursos necesarios
bool Director::unLoadMedia(Uint8 section)
{
// Indicador de éxito en la carga
bool success = true;
std::string p;
switch (section)
{
case GAME_SECTION_INIT:
{
p = resource.file[FILE_CONFIG].file;
std::string filename = p.substr(p.find_last_of("\\/") + 1);
// Abre el fichero de puntuación para escribir
SDL_RWops *file = SDL_RWFromFile(p.c_str(), "w+b");
if (file != NULL)
{
// Guardamos los datos
SDL_RWwrite(file, &options.fullScreenMode, sizeof(Uint32), 1);
SDL_RWwrite(file, &options.windowSize, sizeof(Uint8), 1);
printf("Writing file %s\n", filename.c_str());
// Cerramos el fichero
SDL_RWclose(file);
}
else
{
printf("Error: Unable to save %s file! %s\n", filename.c_str(), SDL_GetError());
}
}
break;
case GAME_SECTION_TITLE:
{
}
break;
case GAME_SECTION_PLAYING:
{
}
break;
case GAME_SECTION_GAME_OVER_SCREEN:
{
}
break;
case GAME_SECTION_INTRO:
{
}
break;
case GAME_SECTION_DEMO:
{
}
break;
case GAME_SECTION_INSTRUCTIONS:
{
}
break;
case GAME_SECTION_LOGO:
{
}
break;
default:
{
}
break;
}
return success;
}
// Establece el valor de la variable
void Director::setPath(std::string _path)
{
path = _path.substr(0, _path.find_last_of("\\/"));
}
// Obtiene el valor de la variable
Uint8 Director::getGameSection()
{
return game.section;
}
// Establece el valor de la variable
void Director::changeGameSection(_section sectionPrevious, _section sectionNext)
{
switch (sectionPrevious)
{
case GAME:
quitGame();
break;
default:
break;
}
switch (sectionNext)
{
case GAME:
initGame();
break;
default:
break;
}
game.section = sectionNext;
}
// Cambia el valor de la variable de modo de pantalla completa
void Director::changeFullScreenMode()
{
switch (options.fullScreenMode)
{
case 0:
options.fullScreenMode = SDL_WINDOW_FULLSCREEN;
break;
case SDL_WINDOW_FULLSCREEN:
options.fullScreenMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
break;
case SDL_WINDOW_FULLSCREEN_DESKTOP:
options.fullScreenMode = 0;
break;
default:
options.fullScreenMode = 0;
break;
}
}
// Comprueba si hay que salir
bool Director::isRunning()
{
return !quit;
}
// Bucle para el logo del juego
void Director::runLogo()
{
}
// Bucle para la intro del juego
void Director::runIntro()
{
}
// Bucle para el titulo del juego
void Director::runTitle()
{
}
// Bucle para el juego
void Director::runGame()
{
// Actualiza la lógica del juego
updateGame();
// Pinta la sección de juego
renderGame();
}
// Actualiza la lógica del juego
void Director::updateGame()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - game.ticks > game.ticksSpeed)
{
// Actualiza el contador de ticks
game.ticks = SDL_GetTicks();
// 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)
{
quit = true;
break;
}
}
game.counter++;
map->update();
player->update();
}
}
// Pinta la sección de juego
void Director::renderGame()
{
// Limpia la pantalla
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderClear(renderer);
// Dibuja los objetos
map->render();
player->render();
// Muestra el backbuffer en pantalla
SDL_RenderPresent(renderer);
}

View File

@@ -1,191 +0,0 @@
#pragma once
#include "ifdefs.h"
#include "sprite.h"
#include "movingsprite.h"
#include "smartsprite.h"
#include "player.h"
#include "map.h"
#include "text.h"
#include "text2.h"
#include "menu.h"
#include "const.h"
#include "jail_audio.h"
#include "utils.h"
#include <math.h>
#ifndef GAME_H
#define GAME_H
// director
class Director
{
private:
struct _text // Objetos de texto
{
Text *white;
};
struct _menu // Objetos menu
{
Menu *title; // Menu de la pantalla de título
};
struct _options // Variables relacionadas con las opciones del juego
{
Uint32 fullScreenMode; // Guarda el valor elegido para el modo de pantalla completa
Uint32 fullScreenModePrevious; // Guarda el valor previo del modo de pantalla completa
Uint8 windowSize; // Guarda el valor elegido para el tamaño de la ventana
Uint8 windowSizePrevious; // Guarda el valor previo del tamaño de la ventana
};
struct _game // Variables para el control del juego
{
Uint32 score; // Puntuación actual
Uint8 section; // Indicador para el bucle principal
bool paused; // Idica si el juego está en pausa
Uint32 ticks; // Contador de ticks para ajustar la velocidad del juego
Uint8 ticksSpeed; // Velocidad a la que se repite el bucle de juego
Uint32 counter; // Contador para el juego
};
// Recursos
struct _resourceFile
{
std::string file;
};
struct _resourceSound
{
std::string file;
JA_Sound sound;
};
struct _resourceMusic
{
std::string file;
JA_Music music;
};
struct _resourceTexture
{
std::string file;
LTexture *texture;
};
struct _resource
{
_resourceFile file[TOTAL_FILE];
_resourceSound sound[TOTAL_SOUND];
_resourceMusic music[TOTAL_MUSIC];
_resourceTexture texture[TOTAL_TEXTURE];
};
SDL_Window *window; // La ventana de la aplicación
SDL_Renderer *renderer; // El renderizador donde se dibuja todo
SDL_Event *eventHandler; // Manejador de eventos
SDL_Texture *backbuffer; // Texturas
SDL_Joystick *gameController; // Manejador para el mando 1
SDL_Haptic *controllerHaptic; // Manejador para la vibración del mando
_game game; // Contiene las variables de la sección de juego
//_menu menu; // Variable con los objetos menu
_resource resource; // Contiene todos los objetos y variables asociados a recursos
_options options; // Contiene todas las opciones del programa
_text text; // Variable con los objetos texto
bool gameControllerFound; // Indica si se ha encontrado algun mando conectado
double sen[360]; // Vector con los valores del seno para 360 grados
Player *player; // El jugador
Map *map; // El mapa del juego
Uint32 scoreData[TOTAL_SCORE_DATA]; // Datos del fichero de puntuación
std::string path; // Path donde está el ejecutable del juego
enum _section // Lista con todas las secciones en las que se divide el programa
{
GAME,
TITLE,
QUIT,
NONE
};
_section section; // Seccion actual del programa
bool quit; // Indica si hay que terminar el programa
public:
// Constructor
Director(std::string _path);
// Destructor
~Director();
// Inicializa todas las variables
void init(std::string _path);
// Inicializa las variables de las opciones
void initOptions();
// Inicializa las variables del juego
void initGame();
// Limpia las variables del juego
void quitGame();
// Arranca SDL y crea la ventana
bool initSDL();
// Crea los objetos del programa
void initObjects();
// Borra los objetos del programa
void deleteObjects();
// Establece el valor de la variable
void setPath(std::string _path);
// Crea el indice de ficheros de recursos
void setResourceList();
// Comprueba que todos los ficheros de recursos existen
bool checkResourceList();
// Inicializa la variable con los ficheros de recursos
bool initResourceList();
// Carga un archivo de imagen en una textura
bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer);
// Carga los recursos necesarios
bool loadMedia(Uint8 section);
// Descrga los recursos necesarios
bool unLoadMedia(Uint8 section);
// Obtiene el valor de la variable
Uint8 getGameSection();
// Establece el valor de la variable
void changeGameSection(_section sectionPrevious, _section sectionNext);
// Cambia el valor de la variable de modo de pantalla completa
void changeFullScreenMode();
// Comprueba si hay que salir
bool isRunning();
// Bucle para el logo del juego
void runLogo();
// Bucle para la intro del juego
void runIntro();
// Bucle para el titulo del juego
void runTitle();
// Bucle para el juego
void runGame();
// Pinta la sección de juego
void renderGame();
// Actualiza la lógica del juego
void updateGame();
};
#endif

71
source/enemy.cpp Normal file
View File

@@ -0,0 +1,71 @@
#include "enemy.h"
#include <fstream>
#include <sstream>
// Constructor
Enemy::Enemy()
{
}
// Constructor
Enemy::Enemy(enemy_t enemy)
{
// Obten punteros a objetos
asset = enemy.asset;
renderer = enemy.renderer;
// Crea objetos
texture = new LTexture();
loadTextureFromFile(texture, asset->get(enemy.tileset), renderer);
sprite = new AnimatedSprite(texture, renderer, asset->get(enemy.animation));
// Obten el resto de valores
sprite->setPosX(enemy.x);
sprite->setPosY(enemy.y);
sprite->setWidth(enemy.w);
sprite->setHeight(enemy.h);
sprite->setVelX(enemy.vx);
sprite->setVelY(enemy.vy);
sprite->setCurrentAnimation();
sprite->setFlip(enemy.vx > 0 ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL);
collider = getRect();
}
// Destructor
Enemy::~Enemy()
{
texture->unload();
delete texture;
texture = nullptr;
delete sprite;
sprite = nullptr;
}
// Pinta el enemigo en pantalla
void Enemy::render()
{
sprite->render();
}
// Actualiza las variables del objeto
void Enemy::update()
{
sprite->update();
sprite->animate();
collider = getRect();
}
// Devuelve el rectangulo que contiene al enemigo
SDL_Rect Enemy::getRect()
{
return sprite->getRect();
}
// Obtiene el rectangulo de colision del enemigo
SDL_Rect &Enemy::getCollider()
{
return collider;
}

58
source/enemy.h Normal file
View File

@@ -0,0 +1,58 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include "asset.h"
#include "animatedsprite.h"
#include <string>
#ifndef ENEMY_H
#define ENEMY_H
// Estructura para pasar los datos de un enemigo
struct enemy_t
{
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
std::string tileset; // Fichero con los graficos del enemigo
std::string animation; // Fichero con las animaciones del enemigo
int w; // Anchura del enemigo
int h; // Altura del enemigo
float x; // Posición inicial en el eje X
float y; // Posición inicial en el eje Y
float vx; // Velocidad en el eje X
float vy; // Velocidad en el eje Y
};
// Clase Enemy
class Enemy
{
protected:
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
LTexture *texture; // Textura con los graficos del enemigo
AnimatedSprite *sprite; // Sprite del enemigo
SDL_Rect collider; // Caja de colisión
public:
// Constructor
Enemy();
Enemy(enemy_t enemy);
// Destructor
virtual ~Enemy();
// Pinta el enemigo en pantalla
void render();
// Actualiza las variables del objeto
virtual void update();
// Devuelve el rectangulo que contiene al enemigo
SDL_Rect getRect();
// Obtiene el rectangulo de colision del enemigo
SDL_Rect &getCollider();
};
#endif

170
source/enemy_engine.cpp Normal file
View File

@@ -0,0 +1,170 @@
#include "enemy_engine.h"
#include <fstream>
#include <sstream>
// Constructor
EnemyEngine::EnemyEngine(SDL_Renderer *renderer, Asset *asset, Player *player, Map *map, std::string file)
{
this->renderer = renderer;
this->asset = asset;
this->player = player;
this->map = map;
load(file);
}
// Destructor
EnemyEngine::~EnemyEngine()
{
// Elimina todos los enemigos anteriores
for (auto enemy : enemies)
{
delete enemy;
}
enemies.clear();
}
// Pinta los enemigos en pantalla
void EnemyEngine::render()
{
for (auto enemy : enemies)
{
enemy->render();
}
}
// Actualiza las variables del objeto
void EnemyEngine::update()
{
for (auto enemy : enemies)
{
enemy->update();
}
}
// Carga las variables desde un fichero
bool EnemyEngine::load(std::string file_path)
{
// Indicador de éxito en la carga
bool success = true;
std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1);
std::string line;
std::ifstream file(file_path);
// 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 [actor] se realiza el proceso de carga de los actores
if (line == "[path]")
{
enemy_t enemy;
enemy.asset = asset;
enemy.renderer = renderer;
SDL_Point p1, p2;
do
{
std::getline(file, line);
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (!setEnemy(&enemy, &p1, &p2, line.substr(0, pos), line.substr(pos + 1, line.length())))
{
printf("Warning: file %s\n, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
} while (line != "[/path]");
printf("** enemy path loaded\n\n");
enemies.push_back(new EnemyPath(enemy, p1, p2));
}
}
// 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;
}
return success;
}
// Asigna variables a una estructura enemy_t
bool EnemyEngine::setEnemy(enemy_t *enemy, SDL_Point *p1, SDL_Point *p2, std::string var, std::string value)
{
const int tile_size = 8;
// Indicador de éxito en la asignación
bool success = true;
if (var == "tileset")
{
enemy->tileset = value;
}
else if (var == "animation")
{
enemy->animation = value;
}
else if (var == "width")
{
enemy->w = std::stof(value);
}
else if (var == "height")
{
enemy->h = std::stof(value);
}
else if (var == "x")
{
enemy->x = std::stof(value) * tile_size;
}
else if (var == "y")
{
enemy->y = std::stof(value) * tile_size;
}
else if (var == "vx")
{
enemy->vx = std::stof(value);
}
else if (var == "vy")
{
enemy->vy = std::stof(value);
}
else if (var == "x1")
{
p1->x = std::stoi(value) * tile_size;
}
else if (var == "x2")
{
p2->x = std::stoi(value) * tile_size;
}
else if (var == "y1")
{
p1->y = std::stoi(value) * tile_size;
}
else if (var == "y2")
{
p2->y = std::stoi(value) * tile_size;
}
else if (var == "[/path]")
{
}
else
{
success = false;
}
return success;
}

46
source/enemy_engine.h Normal file
View File

@@ -0,0 +1,46 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include "asset.h"
#include "enemy.h"
#include "enemy_path.h"
#include "map.h"
#include "player.h"
#include <string>
#include <vector>
#ifndef ENEMY_ENGINE_H
#define ENEMY_ENGINE_H
// Clase EnemyEngine
class EnemyEngine
{
private:
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Map *map; // Mapa con la información de la habitación
Player *player; // Puntero con el jugador
std::vector<EnemyPath *> enemies; // Vector con la lista de enemigos
// Carga las variables desde un fichero
bool load(std::string file_path);
// Asigna variables a una estructura enemy_t
bool setEnemy(enemy_t *enemy, SDL_Point *p1, SDL_Point *p2, std::string var, std::string value);
public:
// Constructor
EnemyEngine(SDL_Renderer *renderer, Asset *asset, Player *player, Map *map, std::string file);
// Destructor
~EnemyEngine();
// Pinta los enemigos en pantalla
void render();
// Actualiza las variables del objeto
void update();
};
#endif

43
source/enemy_path.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include "enemy_path.h"
#include <fstream>
#include <sstream>
// Constructor
EnemyPath::EnemyPath(enemy_t enemy, SDL_Point p1, SDL_Point p2) : Enemy(enemy)
{
// Obten el resto de valores
this->p1 = p1;
this->p2 = p2;
}
// Destructor
EnemyPath::~EnemyPath()
{
}
// Actualiza las variables del objeto
void EnemyPath::update()
{
sprite->update();
sprite->animate();
checkPath();
collider = getRect();
}
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void EnemyPath::checkPath()
{
// Comprueba los límites horizontales
if (sprite->getPosX() > p2.x || sprite->getPosX() < p1.x)
{
sprite->setVelX(sprite->getVelX() * (-1));
sprite->flip();
}
// Comprueba los límites verticales
if (sprite->getPosY() > p2.y || sprite->getPosY() < p1.y)
{
sprite->setVelY(sprite->getVelY() * (-1));
sprite->flip();
}
}

33
source/enemy_path.h Normal file
View File

@@ -0,0 +1,33 @@
#pragma once
#include <SDL2/SDL.h>
#include "enemy.h"
#include <string>
#ifndef ENEMY_PATH_H
#define ENEMY_PATH_H
// Clase EnemyPath
class EnemyPath : public Enemy
{
private:
SDL_Point p1; // Punto 1 (inicial) de la ruta
SDL_Point p2; // Punto 2 (final) de la ruta
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void checkPath();
public:
// Constructor
EnemyPath(enemy_t enemy, SDL_Point p1, SDL_Point p2);
// Destructor
~EnemyPath();
// Actualiza las variables del objeto
void update();
};
#endif

248
source/game.cpp Normal file
View File

@@ -0,0 +1,248 @@
#include "game.h"
// Constructor
Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input)
{
// Copia punteros
this->renderer = renderer;
this->asset = asset;
this->screen = screen;
this->input = input;
// Reserva memoria para los objetos
eventHandler = new SDL_Event();
itemTracker = new ItemTracker();
map = new Map(asset->get("01.map"), renderer, asset, itemTracker);
player = new Player(renderer, asset, input, map);
enemyEngine = new EnemyEngine(renderer, asset, player, map, asset->get(map->getEnemyFile()));
// enemyEngine->setEnemies(asset->get(map->getEnemyFile()));
debugText = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer);
music = JA_LoadMusic(asset->get("music_surface.ogg").c_str());
// Inicializa variables
ticks = 0;
ticksSpeed = 15;
section.name = SECTION_PROG_GAME;
section.subsection = SUBSECTION_GAME_PLAY;
musicEnabled = true;
debug = false;
musicEnabled = !debug;
}
// Destructor
Game::~Game()
{
delete eventHandler;
delete itemTracker;
delete map;
delete player;
delete enemyEngine;
delete debugText;
JA_DeleteMusic(music);
}
// Bucle para el juego
section_t Game::run()
{
if (musicEnabled)
{
JA_PlayMusic(music);
}
while (section.name == SECTION_PROG_GAME)
{
// Sección juego jugando
if (section.subsection == SUBSECTION_GAME_PLAY)
{
update();
render();
}
}
JA_StopMusic();
return section;
}
// Actualiza el juego, las variables, comprueba la entrada, etc.
void Game::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// 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;
}
}
player->update();
checkScreenBorders();
enemyEngine->update();
map->update();
checkInput();
}
}
// Pinta los objetos en pantalla
void Game::render()
{
// Prepara para dibujar el frame
screen->start();
screen->clean();
// Dibuja los objetos
map->render();
enemyEngine->render();
player->render();
renderDebugInfo();
// Actualiza la pantalla
screen->blit();
}
// Comprueba la entrada
void Game::checkInput()
{
if (input->checkInput(INPUT_BUTTON_2, REPEAT_FALSE))
{
debug = !debug;
musicEnabled = !debug;
if (musicEnabled)
{
JA_PlayMusic(music);
}
else
{
JA_StopMusic();
}
}
if (input->checkInput(INPUT_BUTTON_3, REPEAT_FALSE))
{
delete map;
map = new Map(asset->get("01.map"), renderer, asset, itemTracker);
delete player;
player = new Player(renderer, asset, input, map);
}
if (input->checkInput(INPUT_BUTTON_ESCAPE, REPEAT_FALSE))
{
section.name = SECTION_PROG_QUIT;
}
}
// Muestra información de depuración
void Game::renderDebugInfo()
{
if (!debug)
{
return;
}
// Pinta la rejilla
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 16);
for (int i = 0; i < 240; i += 8)
{
SDL_RenderDrawLine(renderer, 0, i, 320, i);
}
for (int i = 0; i < 320; i += 8)
{
SDL_RenderDrawLine(renderer, i, 0, i, 240);
}
// Pinta el texto
int line = 0;
std::string text = "";
text = "R - Reload player and map";
debugText->write(1, 210, text, -1);
text = "D - Toggle debug mode";
debugText->write(1, 216, text, -1);
text = std::to_string((int)player->sprite->getPosX()) + "," + std::to_string((int)player->sprite->getPosY()) + "," + std::to_string((int)player->sprite->getWidth()) + "," + std::to_string((int)player->sprite->getHeight());
debugText->write(0, line, text, -1);
text = "VY " + std::to_string(player->vy) + " " + std::to_string(player->jumpStrenght);
debugText->write(0, line += 6, text, -1);
text = "VX " + std::to_string(player->vx);
debugText->write(0, line += 6, text, -1);
text = "jump_pressed " + std::to_string(player->jumpPressed);
debugText->write(0, line += 6, text, -1);
text = "isOnFloor " + std::to_string(player->isOnFloor());
debugText->write(0, line += 6, text, -1);
const std::string foot_x = std::to_string(player->underFeet[0].x);
const std::string foot_y = std::to_string(player->underFeet[0].y);
const std::string gettile = std::to_string(player->map->getTile(player->underFeet[0]));
text = "getTile(" + foot_x + "," + foot_y + ") = " + gettile;
debugText->write(0, line += 6, text, -1);
text = "state " + std::to_string(player->state);
debugText->write(0, line += 6, text, -1);
text = map->getRoomFileName(b_top) + " " + map->getRoomFileName(b_right) + " " + map->getRoomFileName(b_bottom) + " " + map->getRoomFileName(b_left);
debugText->write(0, line += 6, text, -1);
text = "hookedOn = " + std::to_string(player->hookedOnMovingPlatform);
debugText->write(0, line += 6, text, -1);
text = "DIAMONDS = " + std::to_string(player->diamonds);
debugText->write(0, line += 6, text, -1);
// Pinta mascaras
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 128);
SDL_Rect rect = player->sprite->getRect();
SDL_RenderFillRect(renderer, &rect);
}
// Cambia el mapa
bool Game::changeMap(std::string file)
{
bool success = false;
// En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada
if (file != "0")
{ // Verifica que exista el fichero que se va a cargar
if (asset->get(file) != "")
{
// Elimina la habitación actual y crea un objeto nuevo a partir del fichero
delete map;
map = new Map(asset->get(file), renderer, asset, itemTracker);
// Elimina el gestor de enemigos y crea uno nuevo a partir de un fichero
delete enemyEngine;
enemyEngine = new EnemyEngine(renderer, asset, player, map, asset->get(map->getEnemyFile()));
success = true;
}
}
return success;
}
// Comprueba si el jugador está en el borde y se ha de cambiar el mapa
void Game::checkScreenBorders()
{
if (player->isOnScreenBorder())
{
if (changeMap(map->getRoomFileName(player->getBorder())))
{
player->setMap(map);
player->switchBorders();
}
}
}

66
source/game.h Normal file
View File

@@ -0,0 +1,66 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include "asset.h"
#include "screen.h"
#include "input.h"
#include "map.h"
#include "player.h"
#include "item_tracker.h"
#include "enemy_engine.h"
#include "text.h"
#ifndef GAME_H
#define GAME_H
class Game
{
private:
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto encargado de gestionar los ficheros de recursos
Screen *screen; // Objeto encargado de dibujar en pantalla
Input *input; // Objeto Input para gestionar las entradas
SDL_Event *eventHandler; // Manejador de eventos
JA_Music music; // Contiene la musica que se reproduce durante el juego
Text *debugText; // Objeto para escribir texto con información de debug
Map *map; // Objeto encargado de gestionar el mapeado del juego
Player *player; // Objeto para gestionar el jugador
ItemTracker *itemTracker; // Objeto para gestionar los items recogidos
EnemyEngine *enemyEngine; // Objeto encargado de gestionar los enemigos
section_t section; // Seccion actual dentro del programa
int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
bool debug; // Indica si esta activo el modo de depuración
bool musicEnabled; // Indica si la musica puede sonar o no
// Actualiza el juego, las variables, comprueba la entrada, etc.
void update();
// Pinta los objetos en pantalla
void render();
// Comprueba la entrada
void checkInput();
// Muestra información de depuración
void renderDebugInfo();
// Cambia el mapa
bool changeMap(std::string file);
// Comprueba si el jugador está en el borde y se ha de cambiar el mapa
void checkScreenBorders();
public:
// Constructor
Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input);
// Destructor
~Game();
// Bucle para el juego
section_t run();
};
#endif

View File

@@ -1 +0,0 @@
#include <SDL2/SDL.h>

206
source/input.cpp Normal file
View File

@@ -0,0 +1,206 @@
#include "input.h"
#include <iostream>
// Constructor
Input::Input(std::string file)
{
// Fichero gamecontrollerdb.txt
dbPath = file;
// Inicializa las variables
for (int i = 0; i < 17; i++)
{
keyBindings[i].scancode = 0;
keyBindings[i].active = false;
gameControllerBindings[i].button = SDL_CONTROLLER_BUTTON_INVALID;
gameControllerBindings[i].active = false;
}
discoverGameController();
}
// Destructor
Input::~Input()
{
for (int i = 0; i < numGamepads; i++)
connectedControllers[i] = nullptr;
}
// Asigna uno de los posibles inputs a una tecla del teclado
void Input::bindKey(Uint8 input, SDL_Scancode code)
{
keyBindings[input].scancode = code;
}
// Asigna uno de los posibles inputs a un botón del mando
void Input::bindGameControllerButton(Uint8 input, SDL_GameControllerButton button)
{
gameControllerBindings[input].button = button;
}
// Comprueba si un input esta activo
bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
{
bool successKeyboard = false;
bool successGameController = false;
if (device == INPUT_USE_ANY)
index = 0;
if ((device == INPUT_USE_KEYBOARD) || (device == INPUT_USE_ANY))
{
const Uint8 *mKeystates = SDL_GetKeyboardState(NULL);
if (repeat)
{
if (mKeystates[keyBindings[input].scancode] != 0)
successKeyboard = true;
else
successKeyboard = false;
}
else
{
if (!keyBindings[input].active)
{
if (mKeystates[keyBindings[input].scancode] != 0)
{
keyBindings[input].active = true;
successKeyboard = true;
}
else
{
successKeyboard = false;
}
}
else
{
if (mKeystates[keyBindings[input].scancode] == 0)
{
keyBindings[input].active = false;
successKeyboard = false;
}
else
{
successKeyboard = false;
}
}
}
}
if (gameControllerFound())
if ((device == INPUT_USE_GAMECONTROLLER) || (device == INPUT_USE_ANY))
{
if (repeat)
{
if (SDL_GameControllerGetButton(connectedControllers[index], gameControllerBindings[input].button) != 0)
successGameController = true;
else
successGameController = false;
}
else
{
if (!gameControllerBindings[input].active)
{
if (SDL_GameControllerGetButton(connectedControllers[index], gameControllerBindings[input].button) != 0)
{
gameControllerBindings[input].active = true;
successGameController = true;
}
else
{
successGameController = false;
}
}
else
{
if (SDL_GameControllerGetButton(connectedControllers[index], gameControllerBindings[input].button) == 0)
{
gameControllerBindings[input].active = false;
successGameController = false;
}
else
{
successGameController = false;
}
}
}
}
return (successKeyboard || successGameController);
}
// Comprueba si hay un mando conectado
bool Input::discoverGameController()
{
bool found = false;
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) != 1)
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
if (SDL_GameControllerAddMappingsFromFile(dbPath.c_str()) < 0)
printf("Error, could not load %s file: %s\n", dbPath.c_str(), SDL_GetError());
int nJoysticks = SDL_NumJoysticks();
numGamepads = 0;
// Cuenta el numero de mandos
for (int i = 0; i < nJoysticks; i++)
if (SDL_IsGameController(i))
numGamepads++;
printf("\nChecking for game controllers...\n");
printf("%i joysticks found, %i are gamepads\n", nJoysticks, numGamepads);
if (numGamepads > 0)
{
found = true;
for (int i = 0; i < numGamepads; i++)
{
// Abre el mando y lo añade a la lista
SDL_GameController *pad = SDL_GameControllerOpen(i);
if (SDL_GameControllerGetAttached(pad) == 1)
{
connectedControllers.push_back(pad);
std::string separator(" #");
std::string name = SDL_GameControllerNameForIndex(i);
name.resize(25);
name = name + separator + std::to_string(i);
std::cout << name << std::endl;
controllerNames.push_back(name);
}
else
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
}
//mGameController = connectedControllers[0];
SDL_GameControllerEventState(SDL_ENABLE);
}
return found;
}
// Comprueba si hay algun mando conectado
bool Input::gameControllerFound()
{
if (numGamepads > 0)
return true;
else
return false;
}
// Obten el nombre de un mando de juego
std::string Input::getControllerName(int index)
{
if (numGamepads > 0)
return controllerNames[index];
else
return "";
}
// Obten el numero de mandos conectados
int Input::getNumControllers()
{
return numGamepads;
}

87
source/input.h Normal file
View File

@@ -0,0 +1,87 @@
#pragma once
#include <SDL2/SDL.h>
#include <string>
#include <vector>
#ifndef INPUT_H
#define INPUT_H
#define INPUT_NULL 0
#define INPUT_UP 1
#define INPUT_DOWN 2
#define INPUT_LEFT 3
#define INPUT_RIGHT 4
#define INPUT_ACCEPT 5
#define INPUT_CANCEL 6
#define INPUT_BUTTON_1 7
#define INPUT_BUTTON_2 8
#define INPUT_BUTTON_3 9
#define INPUT_BUTTON_4 10
#define INPUT_BUTTON_5 11
#define INPUT_BUTTON_6 12
#define INPUT_BUTTON_7 13
#define INPUT_BUTTON_8 14
#define INPUT_BUTTON_PAUSE 15
#define INPUT_BUTTON_ESCAPE 16
#define REPEAT_TRUE true
#define REPEAT_FALSE false
#define INPUT_USE_KEYBOARD 0
#define INPUT_USE_GAMECONTROLLER 1
#define INPUT_USE_ANY 2
// Clase Input
class Input
{
private:
struct keyBindings_t
{
Uint8 scancode; // Scancode asociado
bool active; // Indica si está activo
};
keyBindings_t keyBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos
struct GameControllerBindings_t
{
SDL_GameControllerButton button; // GameControllerButton asociado
bool active; // Indica si está activo
};
GameControllerBindings_t gameControllerBindings[17]; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<SDL_GameController *> connectedControllers; // Vector con todos los mandos conectados
std::vector<std::string> controllerNames; // Vector con los nombres de los mandos
int numGamepads; // Numero de mandos conectados
std::string dbPath; // Ruta al archivo gamecontrollerdb.txt
// Comprueba si hay un mando conectado
bool discoverGameController();
public:
// Constructor
Input(std::string file);
// Destructor
~Input();
// Asigna uno de los posibles inputs a una tecla del teclado
void bindKey(Uint8 input, SDL_Scancode code);
// Asigna uno de los posibles inputs a un botón del mando
void bindGameControllerButton(Uint8 input, SDL_GameControllerButton button);
// Comprueba si un input esta activo
bool checkInput(Uint8 input, bool repeat, int device = INPUT_USE_ANY, int index = 0);
// Comprueba si hay algun mando conectado
bool gameControllerFound();
// Obten el numero de mandos conectados
int getNumControllers();
// Obten el nombre de un mando de juego
std::string getControllerName(int index);
};
#endif

103
source/intro.cpp Normal file
View File

@@ -0,0 +1,103 @@
#include "intro.h"
// Constructor
Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset)
{
// Copia los punteros
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
texture = new LTexture();
loadTextureFromFile(texture, asset->get("intro.png"), renderer);
sprite = new AnimatedSprite(texture, renderer, asset->get("intro.ani"));
// Inicializa variables
section = {SECTION_PROG_INTRO, 0};
ticks = 0;
ticksSpeed = 15;
}
// Destructor
Intro::~Intro()
{
renderer = nullptr;
screen = nullptr;
asset = nullptr;
delete eventHandler;
eventHandler = nullptr;
texture->unload();
delete texture;
texture = nullptr;
delete sprite;
sprite = nullptr;
}
// Actualiza las variables
void Intro::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 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;
}
}
sprite->animate();
// Comprueba si ha terminado la animación de la intro
if (sprite->animationIsCompleted())
{
section.name = SECTION_PROG_TITLE;
}
}
}
// Dibuja en pantalla
void Intro::render()
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean();
// Dibuja los objetos
sprite->render();
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
// Bucle principal
section_t Intro::run()
{
while (section.name == SECTION_PROG_INTRO)
{
update();
render();
}
return section;
}

45
source/intro.h Normal file
View File

@@ -0,0 +1,45 @@
#pragma once
#include <SDL2/SDL.h>
#include "const.h"
#include "asset.h"
#include "utils.h"
#include "screen.h"
#include "animatedsprite.h"
#include "jail_audio.h"
#ifndef INTRO_H
#define INTRO_H
// Clase Intro
class Intro
{
private:
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
LTexture *texture; // Textura con los graficos
SDL_Event *eventHandler; // Manejador de eventos
Asset *asset; // Objeto con los ficheros de recurso
AnimatedSprite *sprite; // Sprite para dibujar los graficos de la intro
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
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
public:
// Constructor
Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset);
// Destructor
~Intro();
// Bucle principal
section_t run();
};
#endif

87
source/item_tracker.cpp Normal file
View File

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

43
source/item_tracker.h Normal file
View File

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

View File

@@ -1,3 +1,4 @@
#ifndef __MIPSEL__
#include "jail_audio.h"
#include "stb_vorbis.c"
@@ -77,7 +78,7 @@ void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) {
JA_Music JA_LoadMusic(const char* filename) {
int chan, samplerate;
JA_Music music = (JA_Music)SDL_malloc(sizeof(JA_Music_t));
JA_Music music = new JA_Music_t();
music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output);
SDL_AudioCVT cvt;
@@ -129,8 +130,8 @@ JA_Music_state JA_GetMusicState() {
void JA_DeleteMusic(JA_Music music) {
if (current_music == music) current_music = NULL;
free(music->output);
free(music);
SDL_free(music->output);
delete music;
}
JA_Sound JA_LoadSound(const char* filename) {
@@ -144,7 +145,7 @@ JA_Sound JA_LoadSound(const char* filename) {
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
SDL_ConvertAudio(&cvt);
free(sound->buffer);
SDL_FreeWAV(sound->buffer);
sound->buffer = cvt.buf;
sound->length = cvt.len_cvt;
@@ -167,7 +168,7 @@ void JA_DeleteSound(JA_Sound sound) {
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].sound == sound) JA_StopChannel(i);
}
SDL_FreeWAV(sound->buffer);
SDL_free(sound->buffer);
delete sound;
}
@@ -209,4 +210,4 @@ JA_Channel_state JA_GetChannelState(const int channel) {
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
return channels[channel].state;
}
#endif

View File

@@ -1,5 +1,6 @@
#pragma once
#include "ifdefs.h"
#include <SDL2/SDL.h>
enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED };
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED };

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