Compare commits

..

43 Commits
v0.6 ... v0.7

Author SHA1 Message Date
1a78020ddd Subido el número de versión 2022-09-11 20:00:17 +02:00
ccb58c169c Añadida mas información al marcador 2022-09-11 19:59:09 +02:00
3eab857267 Sonidos de saltar, caer y morir 2022-09-11 18:20:08 +02:00
37daa9a8a0 Añadiendo efectos de sonido 2022-09-11 13:59:08 +02:00
abb38e490e Merge branch 'master' of https://gitea.sustancia.synology.me/JailDesigner/jaildoctors_dilemma 2022-09-11 11:42:10 +02:00
771ac32a3f Añadidos ficheros de sonido 2022-09-11 11:41:59 +02:00
61e62a625c cafe 2022-09-11 11:10:38 +02:00
cc68a02111 Corregido un bug en las colisiones. El rectangulo era un pixel demasiado bajo o estrecho 2022-09-10 21:04:42 +02:00
c905c348d5 Ya baja por las rampas 2022-09-10 19:18:56 +02:00
0b405e4f99 Solo sube las rampas desde el principio. Las atraviesa al saltar 2022-09-10 18:31:28 +02:00
edaa59af7d Ya sube las rampas. Aun queda por acabar 2022-09-10 18:26:24 +02:00
2ccb02258c Ya se detectan las rampas en el mapa 2022-09-09 19:02:36 +02:00
36fc848779 AHORA SI: Colisiones finalizadas 2022-09-09 14:01:49 +02:00
00b47a5910 Colisiones 2022-09-09 07:53:57 +02:00
197bf71c12 Las colisiones siguen fallando 2022-09-08 23:33:46 +02:00
98916cd1be Completadas las colisiones y estados 2022-09-08 21:31:51 +02:00
88d6471dc8 Trabajando en las colisiones y estados 2022-09-08 14:09:05 +02:00
9fc4c2d8b0 Ahora si, terminado el calculo de superficies 2022-09-08 10:22:52 +02:00
044cf97857 Terminado el cálculo de superficies 2022-09-07 22:47:22 +02:00
a73c11effa Haciendo las superficies verticales 2022-09-07 17:31:40 +02:00
2039b2f8db Creando las superficies del mapa 2022-09-07 14:00:02 +02:00
4193414f10 Antes de rehacer todo el engine de colisiones 2022-09-06 21:58:25 +02:00
247e0060ee Todavía falla MUCHO con las rampas 2022-09-06 21:25:41 +02:00
9af135100c Progresos con las rampas 2022-09-06 20:37:39 +02:00
066a9ab811 Trabajando con las rampas 2022-09-06 14:03:12 +02:00
189b933622 Añadida la clase debug 2022-09-06 13:26:12 +02:00
7e9daddbb6 Voy a implementar una clase para mostrar el informacion de debug en pantalla 2022-09-06 11:25:30 +02:00
16ae06a755 Solucion con checkUpSlopes y checkDownSlopes. No funciona 2022-09-06 11:06:09 +02:00
ce8a4a8050 Ya sube cuestas pero no las baja 2022-09-05 23:22:49 +02:00
b6cfe45872 Empezando a trabajar con slope-tiles 2022-09-05 18:55:36 +02:00
65eac860b1 Corregida la paleta de color zxspectrum 2022-09-05 17:02:17 +02:00
e50aa77514 Añadido color de borde para el logo, intro y titulo 2022-09-05 16:24:16 +02:00
014312732b Merge branch 'master' of https://gitea.sustancia.synology.me/JailDesigner/jaildoctors_dilemma 2022-09-05 16:13:50 +02:00
0e91809429 Cambiado el fichero de tiles con colores de zxspectrum 2022-09-05 16:13:44 +02:00
a121850adb Añadido el color del borde para cada habitación 2022-09-05 13:51:55 +02:00
87d7bd03ff Añadida la paleta de spectrum 2022-09-05 10:15:07 +02:00
73d394388b Terminadas las nuevas colisiones. Ya no se detiene al colisionar horizontalmente 2022-09-04 21:33:42 +02:00
796a31a099 Colisiones casi acabadas 2022-09-04 19:43:43 +02:00
1351943c79 Seguimos con las nuevas colisiones 2022-09-04 18:04:32 +02:00
8630a0ae56 Trabajando en las nuevas colisiones 2022-09-04 15:39:12 +02:00
5eaf44d0b8 Terminada la intro 2022-09-04 09:46:27 +02:00
eba04a32fb Ya colorea la intro 2022-09-04 00:03:44 +02:00
c46637092a Trabajando en la intro 2022-09-03 20:55:55 +02:00
84 changed files with 2812 additions and 700 deletions

View File

@@ -1,9 +1,10 @@
name=void main
bgColor=black
border=red
tileset=standard.png
roomUp=0
roomDown=0
roomLeft=0
roomLeft=06.room
roomRight=02.room
[tilemap]
@@ -11,8 +12,8 @@ roomRight=02.room
[/tilemap]
[enemy]
tileset=paco.png
animation=paco.ani
tileset=diskette.png
animation=diskette.ani
width=16
height=16
x=1
@@ -27,8 +28,8 @@ color=red
[/enemy]
[enemy]
tileset=paco.png
animation=paco.ani
tileset=diskette.png
animation=diskette.ani
width=16
height=16
x=5
@@ -44,7 +45,7 @@ color=yellow
[item]
tileset=items.png
tile=0
tile=1
x=1
y=7
counter=6
@@ -52,7 +53,7 @@ counter=6
[item]
tileset=items.png
tile=0
tile=1
x=17
y=8
counter=7
@@ -62,7 +63,7 @@ counter=7
[item]
tileset=items.png
tile=0
tile=1
x=12
y=12
counter=1
@@ -70,7 +71,7 @@ counter=1
[item]
tileset=items.png
tile=0
tile=1
x=13
y=12
counter=2
@@ -78,7 +79,7 @@ counter=2
[item]
tileset=items.png
tile=0
tile=1
x=14
y=12
counter=3
@@ -86,7 +87,7 @@ counter=3
[item]
tileset=items.png
tile=0
tile=1
x=15
y=12
counter=4
@@ -94,7 +95,7 @@ counter=4
[item]
tileset=items.png
tile=0
tile=1
x=16
y=12
counter=5

View File

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

View File

@@ -1,5 +1,6 @@
name=case switch
bgColor=black
border=green
tileset=standard.png
roomUp=0
roomDown=04.room
@@ -23,7 +24,7 @@ x1=14
y1=0
x2=14
y2=12
color=purple
color=magenta
[/enemy]
[item]

View File

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

View File

@@ -1,5 +1,6 @@
name=the edge
bgColor=light_black
bgColor=bright_black
border=black
tileset=standard.png
roomUp=0
roomDown=05.room
@@ -39,7 +40,7 @@ x1=10
y1=2
x2=10
y2=13
color=light_blue
color=bright_blue
[/enemy]
[enemy]
@@ -55,7 +56,7 @@ x1=16
y1=2
x2=16
y2=13
color=purple
color=magenta
[/enemy]
[item]

View File

@@ -1,5 +1,6 @@
name=The Fridge
bgColor=blue
border=blue
tileset=standard.png
roomUp=02.room
roomDown=0
@@ -23,7 +24,7 @@ x1=1
y1=3
x2=14
y2=3
color=purple
color=magenta
[/enemy]
[enemy]
@@ -39,7 +40,7 @@ x1=10
y1=7
x2=30
y2=7
color=light_white
color=bright_white
[/enemy]
[enemy]
@@ -55,7 +56,7 @@ x1=15
y1=12
x2=30
y2=12
color=light_purple
color=bright_magenta
[/enemy]
[item]

View File

@@ -1,5 +1,6 @@
name=sigmasua
bgColor=black
border=blue
tileset=standard.png
roomUp=03.room
roomDown=0
@@ -55,7 +56,7 @@ x1=10
y1=10
x2=10
y2=13
color=light_red
color=bright_red
[/enemy]
[enemy]
@@ -71,7 +72,7 @@ x1=23
y1=10
x2=23
y2=13
color=light_red
color=bright_red
[/enemy]
[item]

12
data/room/06.room Normal file
View File

@@ -0,0 +1,12 @@
name=the test room
bgColor=black
border=blue
tileset=standard.png
roomUp=0
roomDown=0
roomLeft=0
roomRight=01.room
[tilemap]
06.tmx
[/tilemap]

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

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.1" orientation="orthogonal" renderorder="right-down" width="32" height="16" tilewidth="8" tileheight="8" infinite="0" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv">
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,0,0,86,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,86,86,86,0,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,86,0,86,0,0,0,0,0,0,0,0,167,66,66,66,66,187,0,0,0,0,164,65,65,0,0,0,26,
26,0,0,0,86,0,86,0,0,0,0,0,0,0,162,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,0,0,0,0,0,0,0,0,0,162,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,0,0,0,0,0,0,0,0,162,0,0,0,0,0,0,0,0,0,0,0,0,62,62,0,0,0,0,26,
26,0,0,0,0,0,0,0,0,161,212,212,212,212,212,212,212,0,212,212,0,0,0,0,0,62,62,0,0,0,0,26,
26,0,0,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,
26,0,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,269,0,0,0,0,0,0,0,0,22,22,0,0,0,26,
26,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,269,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,81,289,81,0,0,0,0,0,0,0,0,0,0,0,0,0,
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,
26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26
</data>
</layer>
</map>

View File

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

BIN
media/enemies/diskette.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
media/player/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

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

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

BIN
media/player/player2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

BIN
media/sound/death.wav Normal file

Binary file not shown.

Binary file not shown.

BIN
media/sound/jump1.wav Normal file

Binary file not shown.

BIN
media/sound/jump10.wav Normal file

Binary file not shown.

BIN
media/sound/jump11.wav Normal file

Binary file not shown.

BIN
media/sound/jump12.wav Normal file

Binary file not shown.

BIN
media/sound/jump13.wav Normal file

Binary file not shown.

BIN
media/sound/jump14.wav Normal file

Binary file not shown.

BIN
media/sound/jump15.wav Normal file

Binary file not shown.

BIN
media/sound/jump16.wav Normal file

Binary file not shown.

BIN
media/sound/jump17.wav Normal file

Binary file not shown.

BIN
media/sound/jump18.wav Normal file

Binary file not shown.

BIN
media/sound/jump19.wav Normal file

Binary file not shown.

BIN
media/sound/jump2.wav Normal file

Binary file not shown.

BIN
media/sound/jump20.wav Normal file

Binary file not shown.

BIN
media/sound/jump21.wav Normal file

Binary file not shown.

BIN
media/sound/jump22.wav Normal file

Binary file not shown.

BIN
media/sound/jump23.wav Normal file

Binary file not shown.

BIN
media/sound/jump24.wav Normal file

Binary file not shown.

BIN
media/sound/jump3.wav Normal file

Binary file not shown.

BIN
media/sound/jump4.wav Normal file

Binary file not shown.

BIN
media/sound/jump5.wav Normal file

Binary file not shown.

BIN
media/sound/jump6.wav Normal file

Binary file not shown.

BIN
media/sound/jump7.wav Normal file

Binary file not shown.

BIN
media/sound/jump8.wav Normal file

Binary file not shown.

BIN
media/sound/jump9.wav Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -10,7 +10,7 @@
// Textos
#define WINDOW_CAPTION "JailDoctor's Dilemma"
#define TEXT_COPYRIGHT "@2022 JailDesigner"
#define VERSION "0.1"
#define VERSION "0.7"
// Tamaño de bloque
#define BLOCK 8

85
source/debug.cpp Normal file
View File

@@ -0,0 +1,85 @@
#include "debug.h"
// Constructor
Debug::Debug(SDL_Renderer *renderer, Screen *screen, Asset *asset)
{
// Copia la dirección de los objetos
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
// Reserva memoria para los punteros
text = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer);
// Inicializa variables
x = 0;
y = 0;
enabled = false;
}
// Destructor
Debug::~Debug()
{
delete text;
}
// Actualiza las variables
void Debug::update()
{
}
// Dibuja en pantalla
void Debug::render()
{
int y = this->y;
int w = 0;
for (auto s : slot)
{
text->write(x, y, s);
w = (std::max(w, (int)s.length()));
y += text->getCharacterSize() + 1;
if (y > 192 - text->getCharacterSize())
{
y = this->y;
x += w * text->getCharacterSize() + 2;
}
}
}
// Establece la posición donde se colocará la información de debug
void Debug::setPos(SDL_Point p)
{
x = p.x;
y = p.y;
}
// Añade un texto para mostrar
void Debug::add(std::string text)
{
slot.push_back(text);
}
// Borra la información de debug
void Debug::clear()
{
slot.clear();
}
// Establece el valor de la variable
void Debug::setEnabled(bool value)
{
enabled = value;
}
// Obtiene el valor de la variable
bool Debug::getEnabled()
{
return enabled;
}
// Cambia el valor de la variable
void Debug::switchEnabled()
{
enabled = !enabled;
}

60
source/debug.h Normal file
View File

@@ -0,0 +1,60 @@
#pragma once
#include <SDL2/SDL.h>
#include "const.h"
#include "utils.h"
#include "screen.h"
#include "asset.h"
#include "text.h"
#include <vector>
#include <string>
#ifndef DEBUG_H
#define DEBUG_H
// Clase Debug
class Debug
{
private:
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
Asset *asset; // Objeto con los ficheros de recursos
Text *text; // Objeto encargado de escribir texto en pantalla
std::vector<std::string> slot; // Vector con los textos a escribir
int x; // Posicion donde escribir el texto de debug
int y; // Posición donde escribir el texto de debug
bool enabled; // Indica si esta activo el modo debug
public:
// Constructor
Debug(SDL_Renderer *renderer, Screen *screen, Asset *asset);
// Destructor
~Debug();
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
// Establece la posición donde se colocará la información de debug
void setPos(SDL_Point p);
// Añade un texto para mostrar
void add(std::string text);
// Borra la información de debug
void clear();
// Establece el valor de la variable
void setEnabled(bool value);
// Obtiene el valor de la variable
bool getEnabled();
// Cambia el valor de la variable
void switchEnabled();
};
#endif

View File

@@ -17,7 +17,7 @@ Director::Director(std::string path)
}
else
{
section.name = SECTION_PROG_LOGO;
section.name = SECTION_PROG_GAME;
section.subsection = 0;
}
@@ -43,6 +43,7 @@ Director::Director(std::string path)
initInput();
screen = new Screen(window, renderer, options, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
screen->setBorderColor(borderColor);
debug = new Debug(renderer, screen, asset);
}
Director::~Director()
@@ -51,6 +52,7 @@ Director::~Director()
delete asset;
delete input;
delete screen;
delete debug;
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
@@ -164,11 +166,13 @@ bool Director::setFileList()
asset->add("/data/room/03.room", room);
asset->add("/data/room/04.room", room);
asset->add("/data/room/05.room", room);
asset->add("/data/room/06.room", room);
asset->add("/data/room/01.tmx", room);
asset->add("/data/room/02.tmx", room);
asset->add("/data/room/03.tmx", room);
asset->add("/data/room/04.tmx", room);
asset->add("/data/room/05.tmx", room);
asset->add("/data/room/06.tmx", room);
asset->add("/media/tilesets/standard.png", bitmap);
@@ -180,16 +184,46 @@ bool Director::setFileList()
asset->add("/media/enemies/wave.ani", data);
asset->add("/media/enemies/sigmasua.png", bitmap);
asset->add("/media/enemies/sigmasua.ani", data);
asset->add("/media/enemies/diskette.png", bitmap);
asset->add("/media/enemies/diskette.ani", data);
asset->add("/media/player/player01.png", bitmap);
asset->add("/media/player/player01.ani", data);
asset->add("/media/player/player.png", bitmap);
asset->add("/media/player/player.ani", data);
asset->add("/media/items/items.png", bitmap);
asset->add("/media/music/title.ogg", music);
asset->add("/media/music/game.ogg", music);
asset->add("/media/music/loading_sound1.ogg", music);
asset->add("/media/music/loading_sound2.ogg", music);
asset->add("/media/music/loading_sound3.ogg", music);
asset->add("/media/sound/item.wav", sound);
asset->add("/media/sound/death.wav", sound);
asset->add("/media/sound/jump1.wav", sound);
asset->add("/media/sound/jump2.wav", sound);
asset->add("/media/sound/jump3.wav", sound);
asset->add("/media/sound/jump4.wav", sound);
asset->add("/media/sound/jump5.wav", sound);
asset->add("/media/sound/jump6.wav", sound);
asset->add("/media/sound/jump7.wav", sound);
asset->add("/media/sound/jump8.wav", sound);
asset->add("/media/sound/jump9.wav", sound);
asset->add("/media/sound/jump10.wav", sound);
asset->add("/media/sound/jump11.wav", sound);
asset->add("/media/sound/jump12.wav", sound);
asset->add("/media/sound/jump13.wav", sound);
asset->add("/media/sound/jump14.wav", sound);
asset->add("/media/sound/jump15.wav", sound);
asset->add("/media/sound/jump16.wav", sound);
asset->add("/media/sound/jump17.wav", sound);
asset->add("/media/sound/jump18.wav", sound);
asset->add("/media/sound/jump19.wav", sound);
asset->add("/media/sound/jump20.wav", sound);
asset->add("/media/sound/jump21.wav", sound);
asset->add("/media/sound/jump22.wav", sound);
asset->add("/media/sound/jump23.wav", sound);
asset->add("/media/sound/jump24.wav", sound);
asset->add("/media/logo/jailgames.png", bitmap);
asset->add("/media/logo/since_1998.png", bitmap);
@@ -230,6 +264,9 @@ void Director::runLogo()
// Ejecuta la seccion de juego de la introducción
void Director::runIntro()
{
intro = new Intro(renderer, screen, asset);
setSection(intro->run());
delete intro;
}
// Ejecuta la seccion de juego con el titulo y los menus
@@ -243,7 +280,7 @@ void Director::runTitle()
// Ejecuta la seccion de juego donde se juega
void Director::runGame()
{
game = new Game(renderer, screen, asset, input);
game = new Game(renderer, screen, asset, input, debug);
setSection(game->run());
delete game;
}

View File

@@ -9,7 +9,9 @@
#include "game.h"
#include "logo.h"
#include "title.h"
#include "intro.h"
#include "asset.h"
#include "debug.h"
#include "const.h"
#ifndef DIRECTOR_H
@@ -26,7 +28,9 @@ private:
Game *game; // Objeto para gestionar la sección del juego
Logo *logo; // Objeto para gestionar la sección del logo del programa
Title *title; // Objeto para gestionar la pantalla de título
Intro *intro; // Onjeto para gestionar la introducción del juego
Asset *asset; // Objeto que gestiona todos los ficheros de recursos
Debug *debug; // Objeto para getsionar la información de debug
struct options_t *options; // Variable con todas las opciones del programa

View File

@@ -1,35 +1,47 @@
#include "game.h"
// Constructor
Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input)
Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Debug *debug)
{
// Inicia variables
clock = SDL_GetTicks();
// Inicia algunas variables
board.iniClock = SDL_GetTicks();
currentRoom = "01.room";
spawnPoint = {2 * 8, 12 * 8, 0, 0, 0, STATUS_STANDING, SDL_FLIP_NONE};
debug = false;
spawnPoint = {16, 96, 0, 0, 0, s_standing, SDL_FLIP_NONE};
// Copia los punteros
this->renderer = renderer;
this->asset = asset;
this->screen = screen;
this->input = input;
this->debug = debug;
//this->debug->setEnabled(true);
//currentRoom = "06.room";
//spawnPoint = {240, 96, 0, 0, 0, s_standing, SDL_FLIP_HORIZONTAL};
// Crea los objetos
scoreboard = new ScoreBoard(renderer, asset, &playerLives, &itemsPicked, &clock);
scoreboard = new ScoreBoard(renderer, asset, &board);
itemTracker = new ItemTracker();
room = new Room(asset->get(currentRoom), renderer, asset, itemTracker, &itemsPicked);
player = new Player(spawnPoint, asset->get("player01.png"), asset->get("player01.ani"), renderer, asset, input, room);
roomTracker = new RoomTracker();
room = new Room(asset->get(currentRoom), renderer, screen, asset, itemTracker, &board.items, debug);
player = new Player(spawnPoint, asset->get("player.png"), asset->get("player.ani"), renderer, asset, input, room, debug);
eventHandler = new SDL_Event();
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
debugText = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer);
music = JA_LoadMusic(asset->get("game.ogg").c_str());
deathSound = JA_LoadSound(asset->get("death.wav").c_str());
test = new Test(renderer, screen, asset, debug);
// Inicializa variables
// Inicializa el resto de variables
ticks = 0;
ticksSpeed = 15;
playerLives = 9;
itemsPicked = 0;
board.lives = 9;
board.items = 0;
board.rooms = 1;
roomTracker->addRoom(currentRoom);
player->setInvincible(debug->getEnabled());
board.music = !debug->getEnabled();
section.name = SECTION_PROG_GAME;
section.subsection = SUBSECTION_GAME_PLAY;
@@ -44,25 +56,17 @@ Game::~Game()
// Libera la memoria de los objetos
delete scoreboard;
scoreboard = nullptr;
delete itemTracker;
itemTracker = nullptr;
delete roomTracker;
delete room;
room = nullptr;
delete player;
player = nullptr;
delete eventHandler;
eventHandler = nullptr;
delete text;
text = nullptr;
delete debugText;
debugText = nullptr;
JA_DeleteMusic(music);
JA_DeleteSound(deathSound);
delete test;
}
// Comprueba los eventos de la cola
@@ -75,6 +79,7 @@ void Game::checkEventHandler()
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
screen->setBorderColor(stringToColor("black"));
break;
}
else if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0))
@@ -86,11 +91,15 @@ void Game::checkEventHandler()
break;
case SDL_SCANCODE_D:
debug = !debug;
debug->switchEnabled();
player->setInvincible(debug->getEnabled());
board.music = !debug->getEnabled();
board.music ? JA_ResumeMusic() : JA_PauseMusic();
break;
case SDL_SCANCODE_M:
(JA_GetMusicState() == JA_MUSIC_PLAYING) ? JA_PauseMusic() : JA_ResumeMusic();
board.music = !board.music;
board.music ? JA_ResumeMusic() : JA_PauseMusic();
break;
case SDL_SCANCODE_F:
@@ -129,6 +138,10 @@ void Game::checkEventHandler()
section_t Game::run()
{
JA_PlayMusic(music);
if (!board.music)
{
JA_PauseMusic();
}
while (section.name == SECTION_PROG_GAME)
{
@@ -158,16 +171,14 @@ void Game::update()
checkEventHandler();
// Actualiza los objetos
debug->clear();
room->update();
{
player->update();
checkPlayerAndWalls(); // Debe ir detras del player update, por si se ha metido en algun muro
}
checkPlayerOnBorder();
checkPlayerOnFloor();
checkPlayerAndItems();
checkPlayerAndEnemies();
scoreboard->update();
updateDebugInfo();
}
}
@@ -187,21 +198,35 @@ void Game::render()
// Debug info
renderDebugInfo();
// test->render();
// Actualiza la pantalla
screen->blit();
}
// Pasa la información de debug
void Game::updateDebugInfo()
{
debug->add("X = " + std::to_string((int)player->x) + ", Y = " + std::to_string((int)player->y));
debug->add("VX = " + std::to_string(player->vx).substr(0, 4) + ", VY = " + std::to_string(player->vy).substr(0, 4));
debug->add("STATE = " + std::to_string(player->state));
}
// Pone la información de debug en pantalla
void Game::renderDebugInfo()
{
if (!debug)
if (!debug->getEnabled())
{
return;
}
// Borra el marcador
SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect);
// Pinta la rejilla
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 64);
/*SDL_SetRenderDrawColor(renderer, 255, 255, 255, 32);
for (int i = 0; i < PLAY_AREA_BOTTOM; i += 8)
{ // Lineas horizontales
SDL_RenderDrawLine(renderer, 0, i, PLAY_AREA_RIGHT, i);
@@ -209,39 +234,23 @@ void Game::renderDebugInfo()
for (int i = 0; i < PLAY_AREA_RIGHT; i += 8)
{ // Lineas verticales
SDL_RenderDrawLine(renderer, i, 0, i, PLAY_AREA_BOTTOM - 1);
}
}*/
// Pinta el texto
std::string text;
const int inc = debugText->getCharacterWidth() + 1;
int line = 131;
text = "status: " + std::to_string(player->status);
debugText->write(0, line += inc, text);
text = "foot: " + std::to_string((int)player->getLeftFoot().y);
debugText->write(0, line += inc, text);
const int a = (player->lastPosition.y + 16) / 8;
const int b = player->getLeftFoot().y / 8;
text = "tile: " + std::to_string(a) + " - " + std::to_string(b);
debugText->write(0, line += inc, text);
const bool collision = checkPlayerAndEnemies();
text = "collision: " + std::to_string(collision);
debugText->write(0, line += inc, text);
debug->setPos({1, 18 * 8});
debug->render();
}
// Escribe el nombre de la pantalla
void Game::renderRoomName()
{
// Texto en el centro de la pantalla
SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK};
color_t color = stringToColor("light_black");
SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2};
color_t color = stringToColor("white");
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(renderer, &rect);
text->writeCentered(GAMECANVAS_CENTER_X, 16 * 8, room->getName());
text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, 16 * 8 + 4, room->getName(), 1, room->getBGColor());
}
// Cambia de habitación
@@ -259,7 +268,16 @@ bool Game::changeRoom(std::string file)
room = nullptr;
// Crea un objeto habitación nuevo a partir del fichero
room = new Room(asset->get(file), renderer, asset, itemTracker, &itemsPicked);
room = new Room(asset->get(file), renderer, screen, asset, itemTracker, &board.items, debug);
// Actualiza el marcador
if (roomTracker->addRoom(file))
{
board.rooms++;
}
// Pasa la nueva habitación al jugador
player->setRoom(room);
success = true;
}
@@ -282,105 +300,6 @@ void Game::checkPlayerOnBorder()
}
}
// Comprueba si el jugador esta sobre el suelo
void Game::checkPlayerOnFloor()
{
// Comprueba si tiene suelo bajo los pies solo cuando no hay velocidad de subida
// y solo cuando el pie este encima de un bloque, es decir, en multiplos de 8
// *** HAY UN POSIBLE PROBLEMA y es que caiga muy rapido y viaje a mas de un pixel de velocidad,
// con lo que se saltaria la comprobación
// *** POSIBLE SOLUCION. Comprobar si el tile actual del pie es diferente al tile del pie previo.
// Esto indica que se ha saltado la comprobacion cada 8 pixeles.
// En este caso habría que recolocar al jugador en el sitio
// *** PARECE RESUELTO
const int a = (player->lastPosition.y + 16) / 8;
const int b = player->getLeftFoot().y / 8;
const bool tile_change = a != b;
const bool is_not_going_up = player->getVelY() >= 0;
const bool is_tile_aligned = player->getLeftFoot().y % 8 == 0;
if (((is_not_going_up) && (is_tile_aligned)) || ((is_not_going_up) && (tile_change)))
{
bool test = false;
test |= (room->getTile(player->getLeftFoot()) == TILE_SOLID);
test |= (room->getTile(player->getRightFoot()) == TILE_SOLID);
test |= (room->getTile(player->getLeftFoot()) == TILE_TRAVESSABLE);
test |= (room->getTile(player->getRightFoot()) == TILE_TRAVESSABLE);
// Tiene uno de los pies sobre una superficie
if (test)
{
player->setStatus(STATUS_STANDING);
// Si ha habido un cambio de tile, hay que recolocarlo
if (tile_change)
{
int offset = (int)player->sprite->getPosY() % 8;
player->sprite->setPosY((int)player->sprite->getPosY() - offset);
}
}
// Tiene ambos pies sobre el vacío
else if (player->getStatus() != STATUS_JUMPING)
{
player->setStatus(STATUS_FALLING);
}
}
}
// Comprueba que el jugador no atraviese ninguna pared
void Game::checkPlayerAndWalls()
{
// Obtiene los ocho puntos de colisión del jugador
const SDL_Rect rect = player->getRect();
const SDL_Point p1 = {rect.x, rect.y};
const SDL_Point p2 = {rect.x + 7, rect.y};
const SDL_Point p3 = {rect.x + 7, rect.y + 7};
const SDL_Point p4 = {rect.x, rect.y + 7};
const SDL_Point p5 = {rect.x, rect.y + 8};
const SDL_Point p6 = {rect.x + 7, rect.y + 8};
const SDL_Point p7 = {rect.x + 7, rect.y + 15};
const SDL_Point p8 = {rect.x, rect.y + 15};
// Comprueba si ha colisionado con un muro
bool wall = false;
wall |= (room->getTile(p1) == TILE_SOLID);
wall |= (room->getTile(p2) == TILE_SOLID);
wall |= (room->getTile(p3) == TILE_SOLID);
wall |= (room->getTile(p4) == TILE_SOLID);
wall |= (room->getTile(p5) == TILE_SOLID);
wall |= (room->getTile(p6) == TILE_SOLID);
wall |= (room->getTile(p7) == TILE_SOLID);
wall |= (room->getTile(p8) == TILE_SOLID);
if (wall)
{
// Si hay colisión, deshace el movimiento y lo pone en modo caída
player->undoLastMove();
player->setStatus(STATUS_FALLING);
}
// Comprueba si ha colisionado con un tile de los que matan al jugador
bool death = false;
death |= (room->getTile(p1) == TILE_KILL);
death |= (room->getTile(p2) == TILE_KILL);
death |= (room->getTile(p3) == TILE_KILL);
death |= (room->getTile(p4) == TILE_KILL);
death |= (room->getTile(p5) == TILE_KILL);
death |= (room->getTile(p6) == TILE_KILL);
death |= (room->getTile(p7) == TILE_KILL);
death |= (room->getTile(p8) == TILE_KILL);
if (death)
{
killPlayer();
}
}
// Comprueba las colisiones del jugador con los enemigos
bool Game::checkPlayerAndEnemies()
{
@@ -401,15 +320,23 @@ void Game::checkPlayerAndItems()
// Mata al jugador
void Game::killPlayer()
{
playerLives--;
if (player->getInvincible())
{
return;
}
board.lives--;
// Destruye la habitacion y el jugador
delete room;
delete player;
// Sonido
JA_PlaySound(deathSound);
// Crea la nueva habitación y el nuevo jugador
room = new Room(asset->get(currentRoom), renderer, asset, itemTracker, &itemsPicked);
player = new Player(spawnPoint, asset->get("player01.png"), asset->get("player01.ani"), renderer, asset, input, room);
room = new Room(asset->get(currentRoom), renderer, screen, asset, itemTracker, &board.items, debug);
player = new Player(spawnPoint, asset->get("player.png"), asset->get("player.ani"), renderer, asset, input, room, debug);
}
// Recarga todas las texturas

View File

@@ -10,9 +10,12 @@
#include "asset.h"
#include "room.h"
#include "item_tracker.h"
#include "room_tracker.h"
#include "player.h"
#include "jail_audio.h"
#include "scoreboard.h"
#include "debug.h"
#include "test.h"
#ifndef GAME_H
#define GAME_H
@@ -27,21 +30,22 @@ private:
Room *room; // Objeto encargado de gestionar cada habitación del juego
Player *player; // Objeto con el jugador
ItemTracker *itemTracker; // Lleva el control de los objetos recogidos
RoomTracker *roomTracker; // Lleva el control de las habitaciones visitadas
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Input *input; // Objeto pata gestionar la entrada
Text *text; // Objeto para los textos del juego
Text *debugText; // Objeto para los textos de debug del juego
ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador
JA_Music music; // Musica que suena durante el juego
Debug *debug; // Objeto para gestionar la información de debug
int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
section_t section; // Seccion actual dentro del juego
std::string currentRoom; // Fichero de la habitación actual
player_t spawnPoint; // Lugar de la habitación donde aparece el jugador
bool debug; // Indica si el modo debug está activo
int playerLives; // Lleva la cuenta de ls vidas restantes del jugador
int itemsPicked; // Lleva la cuenta de los objetos recogidos
Uint32 clock; // Cuenta el tiempo que dura la partida
JA_Sound deathSound; // Sonido a reproducir cuando muere el jugador
board_t board; // Estructura con los datos del marcador
Test *test;
// Actualiza el juego, las variables, comprueba la entrada, etc.
void update();
@@ -52,6 +56,9 @@ private:
// Comprueba los eventos de la cola
void checkEventHandler();
// Pone la información de debug en pantalla
void updateDebugInfo();
// Pone la información de debug en pantalla
void renderDebugInfo();
@@ -64,12 +71,6 @@ private:
// Comprueba si el jugador esta en el borde de la pantalla y actua
void checkPlayerOnBorder();
// Comprueba si el jugador esta sobre el suelo
void checkPlayerOnFloor();
// Comprueba que el jugador no atraviese ninguna pared
void checkPlayerAndWalls();
// Comprueba las colisiones del jugador con los enemigos
bool checkPlayerAndEnemies();
@@ -84,7 +85,7 @@ private:
public:
// Constructor
Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input);
Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Debug *debug);
// Destructor
~Game();

239
source/intro.cpp Normal file
View File

@@ -0,0 +1,239 @@
#include "intro.h"
// Constructor
Intro::Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset)
{
// Copia la dirección de los objetos
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
texture = new LTexture(renderer, asset->get("loading_screen1.png"));
texture2 = new LTexture(renderer, asset->get("loading_screen2.png"));
sprite = new Sprite(0, 0, texture->getWidth(), texture->getHeight(), texture, renderer);
sprite2 = new Sprite(0, 0, texture2->getWidth(), texture2->getHeight(), texture2, renderer);
loadingSound1 = JA_LoadMusic(asset->get("loading_sound1.ogg").c_str());
loadingSound2 = JA_LoadMusic(asset->get("loading_sound2.ogg").c_str());
loadingSound3 = JA_LoadMusic(asset->get("loading_sound3.ogg").c_str());
// Inicializa variables
preCounter = 0;
counter = 0;
section.name = SECTION_PROG_INTRO;
section.subsection = 0;
ticks = 0;
ticksSpeed = 15;
loadCounter = 0;
loadCounter = 0;
load1 = true;
load2 = false;
// Cambia el color del borde
screen->setBorderColor(stringToColor("black"));
}
// Destructor
Intro::~Intro()
{
delete texture;
delete texture2;
delete sprite;
delete sprite2;
delete eventHandler;
JA_DeleteMusic(loadingSound1);
JA_DeleteMusic(loadingSound2);
JA_DeleteMusic(loadingSound3);
// delete text;
}
// Comprueba el manejador de eventos
void Intro::checkEventHandler()
{
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(eventHandler) != 0)
{
// Evento de salida de la aplicación
if (eventHandler->type == SDL_QUIT)
{
section.name = SECTION_PROG_QUIT;
break;
}
// Cualquier tecla pulsada
if ((eventHandler->type == SDL_KEYDOWN) || (eventHandler->type == SDL_JOYBUTTONDOWN))
{
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
}
}
}
// Gestiona el contador de carga
void Intro::updateLoad()
{
if (load1)
{
loadCounter = counter / 20;
if (loadCounter == 25)
{
load1 = false;
load2 = true;
loadCounter = 0;
JA_PlayMusic(loadingSound3);
}
}
else
{
loadCounter += 2;
loadCounter = std::min(loadCounter, 768);
}
}
// Gestiona el contador interno
void Intro::updateCounter()
{
if (preCounter >= 50)
{
if (counter == 0)
{
JA_PlayMusic(loadingSound2);
}
counter++;
}
else
{
preCounter++;
}
}
// Dibuja la pantalla de carga
void Intro::renderLoad()
{
// Carga 1 - Blanco y negro
if (load1)
{
sprite->render();
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
// Muestra las lineas 0..63
if (loadCounter < 8)
{
SDL_Rect rect = {0, 0 + loadCounter, 256, 8 - loadCounter};
SDL_RenderFillRect(renderer, &rect);
for (int i = 0; i < 6; i++)
{
rect.y += 8;
SDL_RenderFillRect(renderer, &rect);
}
rect.y += 8;
rect.h = 128;
SDL_RenderFillRect(renderer, &rect);
}
// Muestra las lineas 64..127
else if (loadCounter >= 8 && loadCounter < 16)
{
SDL_Rect rect = {0, 64 + (loadCounter - 8), 256, 8 - (loadCounter - 8)};
SDL_RenderFillRect(renderer, &rect);
for (int i = 0; i < 6; i++)
{
rect.y += 8;
SDL_RenderFillRect(renderer, &rect);
}
rect.y += 8;
rect.h = 64;
SDL_RenderFillRect(renderer, &rect);
}
// Muestra las lineas 128..191
else if (loadCounter >= 16 && loadCounter < 23)
{
SDL_Rect rect = {0, 128 + (loadCounter - 16), 256, 8 - (loadCounter - 16)};
SDL_RenderFillRect(renderer, &rect);
for (int i = 0; i < 6; i++)
{
rect.y += 8;
SDL_RenderFillRect(renderer, &rect);
}
}
}
else
// Carga 2 - Color
{
sprite->render();
SDL_Rect rect = {0, 0, 8, 8};
for (int i = 0; i < loadCounter; i++)
{
rect.x = (i * 8) % 256;
rect.y = (i / 32) * 8;
sprite2->setPos(rect);
sprite2->setSpriteClip(rect);
sprite2->render();
}
}
}
// 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 el manejador de eventos
checkEventHandler();
// Gestiona el contador interno
updateCounter();
// Gestiona el contador de carga
updateLoad();
// Comprueba si ha terminado la intro
if (loadCounter >= 768)
{
section.name = SECTION_PROG_TITLE;
section.subsection = 0;
JA_StopMusic();
}
}
}
// Dibuja en pantalla
void Intro::render()
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean();
// Dibuja la pantalla de carga
renderLoad();
// text->write(0, 0, std::to_string(loadCounter));
// text->write(0, 8, std::to_string(loadCounter));
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
// Bucle para el logo del juego
section_t Intro::run()
{
// Inicia el sonido de carga
JA_PlayMusic(loadingSound1);
while (section.name == SECTION_PROG_INTRO)
{
update();
render();
}
return section;
}

70
source/intro.h Normal file
View File

@@ -0,0 +1,70 @@
#pragma once
#include <SDL2/SDL.h>
#include "const.h"
#include "utils.h"
#include "sprite.h"
#include "screen.h"
#include "asset.h"
#include "jail_audio.h"
#include <vector>
#include <string>
#include "text.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
Asset *asset; // Objeto con los ficheros de recursos
LTexture *texture; // Textura con los graficos "JAILGAMES"
LTexture *texture2; // Textura con los graficos "Since 1998"
SDL_Event *eventHandler; // Manejador de eventos
Sprite *sprite; // Sprite para manejar la textura
Sprite *sprite2; // Sprite para manejar la textura2
int preCounter; // Contador previo para realizar una pausa inicial
int counter; // Contador
section_t section; // Estado del bucle principal para saber si continua o se sale
int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
int loadCounter; // Contador para controlar las cargas
bool load1, load2;
JA_Music loadingSound1, loadingSound2, loadingSound3;
// Text *text;
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
// Comprueba el manejador de eventos
void checkEventHandler();
// Gestiona el contador interno
void updateCounter();
// Gestiona el contador de carga
void updateLoad();
// Dibuja la pantalla de carga
void renderLoad();
public:
// Constructor
Intro(SDL_Renderer *renderer, Screen *screen, Asset *asset);
// Destructor
~Intro();
// Bucle principal
section_t run();
};
#endif

View File

@@ -26,7 +26,7 @@ Item::Item(item_t item)
c = stringToColor("red");
color.push_back(c);
c = stringToColor("purple");
c = stringToColor("magenta");
color.push_back(c);
c = stringToColor("green");
@@ -61,12 +61,6 @@ void Item::update()
counter++;
}
// Coge el objeto
void Item::pick()
{
sprite->setEnabled(false);
}
// Obtiene el rectangulo de colision del objeto
SDL_Rect &Item::getCollider()
{

View File

@@ -51,9 +51,6 @@ public:
// Actualiza las variables del objeto
void update();
// Coge el item
void pick();
// Obtiene el rectangulo de colision del objeto
SDL_Rect &getCollider();

View File

@@ -49,7 +49,7 @@ Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset)
c = stringToColor("red");
color.push_back(c);
c = stringToColor("purple");
c = stringToColor("magenta");
color.push_back(c);
c = stringToColor("green");
@@ -61,8 +61,11 @@ Logo::Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset)
c = stringToColor("yellow");
color.push_back(c);
c = stringToColor("light_white");
c = stringToColor("bright_white");
color.push_back(c);
// Cambia el color del borde
screen->setBorderColor(stringToColor("black"));
}
// Destructor
@@ -102,22 +105,9 @@ void Logo::checkEventHandler()
}
}
// Actualiza las variables
void Logo::update()
// Gestiona el logo de JAILGAME
void Logo::updateJAILGAMES()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Comprueba el manejador de eventos
checkEventHandler();
// Incrementa el contador
counter++;
// update de JAILGAMES
if (counter > 30)
{
for (int i = 1; i < sprite.size(); i++)
@@ -145,8 +135,10 @@ void Logo::update()
}
}
}
}
// update de fade
// Gestiona el color de las texturas
void Logo::updateTextureColors()
{
const int ini = 70;
const int inc = 4;
@@ -222,10 +214,31 @@ void Logo::update()
}
}
// Actualiza las variables
void Logo::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Comprueba el manejador de eventos
checkEventHandler();
// Incrementa el contador
counter++;
// Gestiona el logo de JAILGAME
updateJAILGAMES();
// Gestiona el color de las texturas
updateTextureColors();
// Comprueba si ha terminado el logo
if (counter == endLogo + postLogo)
{
section.name = SECTION_PROG_TITLE;
section.name = SECTION_PROG_INTRO;
section.subsection = 0;
}
}

View File

@@ -42,6 +42,12 @@ private:
// Comprueba el manejador de eventos
void checkEventHandler();
// Gestiona el logo de JAILGAME
void updateJAILGAMES();
// Gestiona el color de las texturas
void updateTextureColors();
public:
// Constructor
Logo(SDL_Renderer *renderer, Screen *screen, Asset *asset);

View File

@@ -2,15 +2,15 @@
#include <fstream>
#include <sstream>
// CAUTION!!!!! si no se gasta al final, quitar la referencia a la habitación
// Constructor
Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room)
Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room, Debug *debug)
{
// Obten punteros a objetos
this->asset = asset;
this->renderer = renderer;
this->input = input;
this->room = room;
this->debug = debug;
// Crea objetos
texture = new LTexture(renderer, asset->get(tileset));
@@ -20,21 +20,78 @@ Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Ren
color = stringToColor("white");
onBorder = false;
border = BORDER_TOP;
invincible = false;
jump_ini = ini.jump_ini;
status = ini.status;
jumpIni = ini.jumpIni;
state = ini.state;
prevState = state;
x = ini.x;
y = ini.y;
vx = ini.vx;
vy = ini.vy;
w = 8;
h = 16;
maxVY = 1.2f;
sprite->setPosX(ini.x);
sprite->setPosY(ini.y);
sprite->setVelX(ini.vx);
sprite->setVelY(ini.vy);
sprite->setWidth(8);
sprite->setHeight(16);
sprite->setFlip(ini.flip);
sprite->setCurrentAnimation("walk");
sprite->animate();
lastPosition = getRect();
collider = getRect();
colliderBox = getRect();
const SDL_Point p = {0, 0};
colliderPoints.insert(colliderPoints.end(), {p, p, p, p, p, p, p, p});
underFeet.insert(underFeet.end(), {p, p});
feet.insert(feet.end(), {p, p});
jumpSound.push_back(JA_LoadSound(asset->get("jump1.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump2.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump3.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump4.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump5.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump6.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump7.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump8.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump9.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump10.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump11.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump12.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump13.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump14.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump15.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump16.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump17.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump18.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump19.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump20.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump21.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump22.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump23.wav").c_str()));
jumpSound.push_back(JA_LoadSound(asset->get("jump24.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump11.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump12.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump13.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump14.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump15.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump16.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump17.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump18.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump19.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump20.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump21.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump22.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump23.wav").c_str()));
fallSound.push_back(JA_LoadSound(asset->get("jump24.wav").c_str()));
r = {0, 0, 0, 0};
jumpCounter = 0;
fallCounter = 0;
}
// Destructor
@@ -42,6 +99,11 @@ Player::~Player()
{
delete texture;
delete sprite;
for (auto s : jumpSound)
{
JA_DeleteSound(s);
}
}
// Pinta el jugador en pantalla
@@ -49,43 +111,67 @@ void Player::render()
{
sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->render();
if (debug->getEnabled())
{
// Pinta los underfeet
SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
SDL_RenderDrawPoint(renderer, underFeet[0].x, underFeet[0].y);
SDL_RenderDrawPoint(renderer, underFeet[1].x, underFeet[1].y);
// Pinta rectangulo del jugador
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 192);
SDL_Rect rect = getRect();
SDL_RenderFillRect(renderer, &rect);
// Pinta el rectangulo de movimiento
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &r);
debug->add("RECT: " + std::to_string(r.x) + "," + std::to_string(r.y) + "," + std::to_string(r.w) + "," + std::to_string(r.h));
}
}
// Actualiza las variables del objeto
void Player::update()
{
setLastPosition(); // Guarda la posición actual en la variable lastPosition
checkInput(); // Comprueba las entradas y modifica variables
move(); // Recalcula la posición del jugador y su animación
move(); // Recalcula la posición del jugador
animate(); // Establece la animación del jugador
checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación
applyGravity(); // Aplica gravedad al jugador
checkJump(); // Comprueba si ha finalizado el salto
collider = getRect(); // Obtiene el rectangulo que delimita al jugador
checkJumpEnd(); // Comprueba si ha finalizado el salto al alcanzar la altura de inicio
}
// Comprueba las entradas y modifica variables
void Player::checkInput()
{
// Solo comprueba las entradas de dirección cuando está de pie
if ((input->checkInput(INPUT_LEFT, REPEAT_TRUE)) && (status == STATUS_STANDING))
// Solo comprueba las entradas de dirección cuando está dsobre una superficie
if (state != s_standing)
{
sprite->setVelX(-0.6f);
return;
}
if (input->checkInput(INPUT_LEFT, REPEAT_TRUE))
{
vx = -0.6f;
sprite->setFlip(SDL_FLIP_HORIZONTAL);
}
else if ((input->checkInput(INPUT_RIGHT, REPEAT_TRUE)) && (status == STATUS_STANDING))
else if (input->checkInput(INPUT_RIGHT, REPEAT_TRUE))
{
sprite->setVelX(0.6f);
vx = 0.6f;
sprite->setFlip(SDL_FLIP_NONE);
}
else if (status == STATUS_STANDING)
else
{
sprite->setVelX(0);
vx = 0.0f;
}
if (input->checkInput(INPUT_UP, REPEAT_TRUE))
{
setStatus(STATUS_JUMPING);
setState(s_jumping);
vy = -maxVY;
jumpIni = y;
jumpCounter = 0;
}
}
@@ -104,22 +190,22 @@ int Player::getBorder()
// Comprueba si está situado en alguno de los cuatro bordes de la habitación
void Player::checkBorders()
{
if (sprite->getPosX() < PLAY_AREA_LEFT)
if (x < PLAY_AREA_LEFT)
{
border = BORDER_LEFT;
onBorder = true;
}
else if (sprite->getPosX() > PLAY_AREA_RIGHT - sprite->getWidth())
else if (x > PLAY_AREA_RIGHT - w)
{
border = BORDER_RIGHT;
onBorder = true;
}
else if (sprite->getPosY() < PLAY_AREA_TOP)
else if (y < PLAY_AREA_TOP)
{
border = BORDER_TOP;
onBorder = true;
}
else if (sprite->getPosY() > PLAY_AREA_BOTTOM - sprite->getHeight())
else if (y > PLAY_AREA_BOTTOM - h)
{
border = BORDER_BOTTOM;
onBorder = true;
@@ -130,92 +216,69 @@ void Player::checkBorders()
}
}
// Comprueba el estado del jugador
void Player::checkState()
{
// Actualiza las variables en función del estado
if (state == s_falling)
{
vx = 0.0f;
vy = maxVY;
fallCounter++;
playFallSound();
}
else if (state == s_standing)
{
vy = 0.0f;
jumpCounter = 0;
fallCounter = 0;
}
else if (state == s_jumping)
{
jumpCounter++;
playJumpSound();
}
}
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
void Player::switchBorders()
{
if (border == BORDER_TOP)
{
sprite->setPosY(PLAY_AREA_BOTTOM - sprite->getHeight() - 1);
jump_ini += 128;
y = PLAY_AREA_BOTTOM - h - 1;
jumpIni += 128;
}
else if (border == BORDER_BOTTOM)
{
sprite->setPosY(PLAY_AREA_TOP + 1);
y = PLAY_AREA_TOP + 1;
}
else if (border == BORDER_RIGHT)
{
sprite->setPosX(PLAY_AREA_LEFT + 1);
x = PLAY_AREA_LEFT + 1;
}
if (border == BORDER_LEFT)
{
sprite->setPosX(PLAY_AREA_RIGHT - sprite->getWidth() - 1);
x = PLAY_AREA_RIGHT - w - 1;
}
onBorder = false;
}
// Obtiene el valor del pixel inferior izquierdo del jugador
SDL_Point Player::getLeftFoot()
{
SDL_Point point = {(int)sprite->getPosX(), (int)sprite->getPosY() + sprite->getHeight()};
return point;
}
// Obtiene el valor del pixel inferior derecho del jugador
SDL_Point Player::getRightFoot()
{
SDL_Point point = {(int)sprite->getPosX() + sprite->getWidth() - 1, (int)sprite->getPosY() + sprite->getHeight()};
return point;
}
// Cambia el estado del jugador
void Player::setStatus(int value)
{
// Si quiere cambiar a saltando, ha de ser desde quieto
if ((value == STATUS_JUMPING) && (status == STATUS_STANDING))
{
status = STATUS_JUMPING;
sprite->setVelY(-MAX_VY);
jump_ini = sprite->getPosY();
}
// Modifica el estado a 'cayendo'
if (value == STATUS_FALLING)
{
status = STATUS_FALLING;
sprite->setVelY(MAX_VY);
sprite->setVelX(0);
}
// Modifica el estado a 'de pie'
if (value == STATUS_STANDING)
{
status = STATUS_STANDING;
sprite->setVelY(0.0f);
}
}
// Obtiene el estado del jugador
int Player::getStatus()
{
return status;
}
// Obtiene la velocidad en el eje Y del jugador
float Player::getVelY()
{
return sprite->getVelY();
}
// Aplica gravedad al jugador
void Player::applyGravity()
{
if (status == STATUS_JUMPING)
const float gf = 0.035f;
// La gravedad solo se aplica cuando el jugador esta saltando
// Nunca mientras cae o esta de pie
if (state == s_jumping)
{
sprite->setVelY(sprite->getVelY() + GRAVITY);
if (sprite->getVelY() > MAX_VY)
vy += gf;
if (vy > maxVY)
{
sprite->setVelY(MAX_VY);
vy = maxVY;
}
}
}
@@ -223,64 +286,299 @@ void Player::applyGravity()
// Obtiene el rectangulo que delimita al jugador
SDL_Rect Player::getRect()
{
return sprite->getRect();
return {(int)x, (int)y, w, h};
}
// Obtiene el rectangulo de colision del jugador
SDL_Rect &Player::getCollider()
{
return collider;
}
// Guarda la posición actual en la variable lastPosition
void Player::setLastPosition()
{
lastPosition = getRect();
}
// Deshace el ultimo movimiento
void Player::undoLastMove()
{
sprite->setPosX(lastPosition.x);
sprite->setPosY(lastPosition.y);
colliderBox = getRect();
return colliderBox;
}
// Recalcula la posición del jugador y su animación
void Player::move()
{
sprite->update();
if (sprite->getVelX() != 0)
lastPosition = {(int)x, (int)y}; // Guarda la posicion actual antes de modificarla
applyGravity(); // Aplica gravedad al jugador
checkState(); // Comprueba el estado del jugador
// Se mueve hacia la izquierda
if (vx < 0.0f)
{
sprite->setCurrentAnimation("walk");
// Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj;
proj.x = (int)(x + vx);
proj.y = (int)y;
proj.h = h;
proj.w = ceil(abs(vx)); // Para evitar que tenga un ancho de 0 pixels
r = proj;
// Comprueba la colisión con las superficies
const int pos = room->checkRightSurfaces(&proj);
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
x += vx;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona
x = pos + 1;
}
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende
if (state != s_jumping)
{
sprite->setCurrentAnimation("stand");
v_line_t leftSide = {(int)x, (int)y + h - 2, (int)y + h - 1};
const int ly = room->checkLeftSlopes(&leftSide);
if (ly > -1)
{
y = ly - h;
// setState(s_standing);
}
}
// Comprueba si ha finalizado el salto
void Player::checkJump()
// Si está bajando la rampa, recoloca al jugador
if (isOnDownSlope())
{
if (status == STATUS_JUMPING)
if (sprite->getVelY() > 0)
if (sprite->getPosY() > jump_ini)
{
setStatus(STATUS_FALLING);
y += 1;
}
}
// Se mueve hacia la derecha
else if (vx > 0.0f)
{
// Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj;
proj.x = (int)x + w;
proj.y = (int)y;
proj.h = h;
proj.w = ceil(vx); // Para evitar que tenga un ancho de 0 pixels
r = proj;
// Comprueba la colisión
const int pos = room->checkLeftSurfaces(&proj);
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
x += vx;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona
x = pos - w;
}
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende
if (state != s_jumping)
{
v_line_t rightSide = {(int)x + w - 1, (int)y + h - 2, (int)y + h - 1};
const int ry = room->checkRightSlopes(&rightSide);
if (ry > -1)
{
y = ry - h;
// setState(s_standing);
}
}
// Si está bajando la rampa, recoloca al jugador
if (isOnDownSlope())
{
y += 1;
}
}
// Si ha salido del suelo, el jugador cae
if (state == s_standing && !isOnFloor())
{
setState(s_falling);
}
// Se mueve hacia arriba
if (vy < 0.0f)
{
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
SDL_Rect proj;
proj.x = (int)x;
proj.y = (int)(y + vy);
proj.h = ceil(abs(vy)); // Para evitar que tenga una altura de 0 pixels
proj.w = w;
r = proj;
// Comprueba la colisión
const int pos = room->checkBottomSurfaces(&proj);
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
y += vy;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona y entra en caída
y = pos + 1;
setState(s_falling);
}
}
// Se mueve hacia abajo
else if (vy > 0.0f)
{
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
SDL_Rect proj;
proj.x = (int)x;
proj.y = (int)y + h;
proj.h = ceil(vy); // Para evitar que tenga una altura de 0 pixels
proj.w = w;
r = proj;
// Comprueba la colisión con los muros
const int pos = room->checkTopSurfaces(&proj);
// Calcula la nueva posición
if (pos == -1)
{ // Si no hay colisión
y += vy;
}
else
{ // Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre el suelo
y = pos - h;
setState(s_standing);
}
}
// Actualiza la posición del sprite
sprite->setPosX(x);
sprite->setPosY(y);
}
// Establece la animación del jugador
void Player::animate()
{
if (vx != 0)
{
sprite->animate();
}
}
// Comprueba si ha finalizado el salto al alcanzar la altura de inicio
void Player::checkJumpEnd()
{
if (state == s_jumping)
{
if (vy > 0)
{
if (y >= jumpIni)
{ // Si alcanza la altura de salto inicial, pasa al estado de caída
setState(s_falling);
vy = maxVY;
jumpCounter = 0;
}
}
}
}
// Calcula y reproduce el sonido de salto
void Player::playJumpSound()
{
if (jumpCounter % 4 == 0)
{
JA_PlaySound(jumpSound[jumpCounter / 4]);
}
debug->add("JUMP: " + std::to_string(jumpCounter / 4));
}
// Calcula y reproduce el sonido de caer
void Player::playFallSound()
{
if (fallCounter % 4 == 0)
{
JA_PlaySound(fallSound[std::min((fallCounter / 4), (int)fallSound.size() - 1)]);
}
debug->add("FALL: " + std::to_string(fallCounter / 4));
}
// Comprueba si el jugador tiene suelo debajo de los pies
bool Player::isOnFloor()
{
bool onFloor = false;
updateFeet();
// Comprueba las superficies
for (auto f : underFeet)
{
onFloor |= room->checkTopSurfaces(&f);
}
// Comprueba las rampas
onFloor |= room->checkLeftSlopes(&underFeet[0]);
onFloor |= room->checkRightSlopes(&underFeet[1]);
if (onFloor)
{
debug->add("ONFLOOR");
}
return onFloor;
}
// Comprueba si el jugador está sobre una rampa hacia abajo
bool Player::isOnDownSlope()
{
bool onSlope = false;
updateFeet();
// Cuando el jugador baja una escalera, se queda volando
// Hay que mirar otro pixel más por debajo
underFeet[0].y += 1;
underFeet[1].y += 1;
// Comprueba las rampas
onSlope |= room->checkLeftSlopes(&underFeet[0]);
onSlope |= room->checkRightSlopes(&underFeet[1]);
if (onSlope)
{
debug->add("ONSLOPE");
}
return onSlope;
}
// Comprueba que el jugador no atraviese ninguna pared
bool Player::checkWalls()
{
// Actualiza los puntos de colisión
updateColliderPoints();
// Comprueba si ha colisionado con un muro
bool wall = false;
for (auto c : colliderPoints)
{
wall |= (room->getTile(c) == t_wall);
}
return wall;
}
// Obtiene algunos parametros del jugador
player_t Player::getSpawnParams()
{
player_t params;
params.x = sprite->getPosX();
params.y = sprite->getPosY();
params.vx = sprite->getVelX();
params.vy = sprite->getVelY();
params.jump_ini = jump_ini;
params.status = status;
params.x = x;
params.y = y;
params.vx = vx;
params.vy = vy;
params.jumpIni = jumpIni;
params.state = state;
params.flip = sprite->getFlip();
return params;
@@ -291,3 +589,54 @@ void Player::reLoadTexture()
{
texture->reLoad();
}
// Establece el valor de la variable
void Player::setRoom(Room *room)
{
this->room = room;
}
// Actualiza los puntos de colisión
void Player::updateColliderPoints()
{
const SDL_Rect rect = getRect();
colliderPoints[0] = {rect.x, rect.y};
colliderPoints[1] = {rect.x + 7, rect.y};
colliderPoints[2] = {rect.x + 7, rect.y + 7};
colliderPoints[3] = {rect.x, rect.y + 7};
colliderPoints[4] = {rect.x, rect.y + 8};
colliderPoints[5] = {rect.x + 7, rect.y + 8};
colliderPoints[6] = {rect.x + 7, rect.y + 15};
colliderPoints[7] = {rect.x, rect.y + 15};
}
// Actualiza los puntos de los pies
void Player::updateFeet()
{
const SDL_Point p = {(int)x, (int)y};
underFeet[0] = {p.x, p.y + h};
underFeet[1] = {p.x + 7, p.y + h};
feet[0] = {p.x, p.y + h - 1};
feet[1] = {p.x + 7, p.y + h - 1};
}
// Obtiene el valor de la variable
bool Player::getInvincible()
{
return invincible;
}
// Establece el valor de la variable
void Player::setInvincible(bool value)
{
invincible = value;
}
// Cambia el estado del jugador
void Player::setState(state_e value)
{
prevState = state;
state = value;
}

View File

@@ -7,18 +7,19 @@
#include "animatedsprite.h"
#include "input.h"
#include "const.h"
#include "debug.h"
#include <string>
#include <vector>
#ifndef PLAYER_H
#define PLAYER_H
//#define VX 0.6
#define STATUS_STANDING 0
#define STATUS_JUMPING 1
#define STATUS_FALLING 2
#define GRAVITY 0.035f
#define MAX_VY 1.2f
enum state_e
{
s_standing,
s_jumping,
s_falling
};
struct player_t
{
@@ -26,25 +27,46 @@ struct player_t
float y;
float vx;
float vy;
int jump_ini;
int status;
int jumpIni;
state_e state;
SDL_RendererFlip flip;
};
// Clase Player
class Player
{
private:
LTexture *texture; // Textura con los graficos del enemigo
Input *input; // Objeto para gestionar la entrada
public:
float x; // Posición del jugador en el eje X
float y; // Posición del jugador en el eje Y
float vx; // Velocidad/desplazamiento del jugador en el eje X
float vy; // Velocidad/desplazamiento del jugador en el eje Y
int w; // Ancho del jugador
int h; // ALto del jugador
SDL_Renderer *renderer; // El renderizador de la ventana
Input *input; // Objeto para gestionar la entrada
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Room *room; // Objeto encargado de gestionar cada habitación del juego
LTexture *texture; // Textura con los graficos del enemigo
AnimatedSprite *sprite; // Sprite del enemigo
Debug *debug; // Objeto para gestionar la información de debug
color_t color; // Color del jugador
SDL_Rect collider; // Caja de colisión
SDL_Rect colliderBox; // Caja de colisión con los enemigos u objetos
std::vector<SDL_Point> colliderPoints; // Puntos de colisión con el mapa
std::vector<SDL_Point> underFeet; // Contiene los puntos que hay bajo cada pie del jugador
std::vector<SDL_Point> feet; // Contiene los puntos que hay en el pie del jugador
state_e state; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
state_e prevState; // Estado previo en el que se encontraba el jugador
bool onBorder; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla
int border; // Indica en cual de los cuatro bordes se encuentra
bool invincible; // Si es invencible, no puede morir
SDL_Rect lastPosition; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento
int jumpIni; // Valor del eje Y en el que se inicia el salto
float maxVY; // Velocidad máxima que puede alcanzar al desplazarse en vertical
std::vector<JA_Sound> jumpSound; // Vecor con todos los sonidos del salto
std::vector<JA_Sound> fallSound; // Vecor con todos los sonidos de la caída
int jumpCounter; // Cuenta el tiempo de salto
int fallCounter; // Cuenta el tiempo de caida
SDL_Rect r;
// Comprueba las entradas y modifica variables
void checkInput();
@@ -52,29 +74,51 @@ private:
// Comprueba si se halla en alguno de los cuatro bordes
void checkBorders();
// Comprueba el estado del jugador
void checkState();
// Asigna velocidad negativa en el eje Y al jugador
void jump();
// Aplica gravedad al jugador
void applyGravity();
// Guarda la posición actual en la variable lastPosition
void setLastPosition();
// Recalcula la posición del jugador y su animación
void move();
// Comprueba si ha finalizado el salto
void checkJump();
// Establece la animación del jugador
void animate();
// Comprueba si ha finalizado el salto al alcanzar la altura de inicio
void checkJumpEnd();
// Calcula y reproduce el sonido de salto
void playJumpSound();
// Calcula y reproduce el sonido de caer
void playFallSound();
// Comprueba si el jugador tiene suelo debajo de los pies
bool isOnFloor();
// Comprueba si el jugador está sobre una rampa hacia abajo
bool isOnDownSlope();
// Comprueba que el jugador no atraviese ninguna pared
bool checkWalls();
// Actualiza los puntos de colisión
void updateColliderPoints();
// Actualiza los puntos de los pies
void updateFeet();
// Cambia el estado del jugador
void setState(state_e value);
public:
AnimatedSprite *sprite; // Sprite del enemigo
SDL_Rect lastPosition; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento
int jump_ini; // Valor del eje Y en el que se inicia el salto
int status; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo
// Constructor
Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room);
Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room, Debug *debug);
// Destructor
~Player();
@@ -94,35 +138,26 @@ public:
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
void switchBorders();
// Obtiene el valor del pixel inferior izquierdo del jugador
SDL_Point getLeftFoot();
// Obtiene el valor del pixel inferior derecho del jugador
SDL_Point getRightFoot();
// Cambia el estado del jugador
void setStatus(int value);
// Obtiene el estado del jugador
int getStatus();
// Obtiene la velocidad en el eje Y del jugador
float getVelY();
// Obtiene el rectangulo que delimita al jugador
SDL_Rect getRect();
// Obtiene el rectangulo de colision del jugador
SDL_Rect &getCollider();
// Deshace el ultimo movimiento
void undoLastMove();
// Obtiene algunos parametros del jugador
player_t getSpawnParams();
// Recarga la textura
void reLoadTexture();
// Establece el valor de la variable
void setRoom(Room *room);
// Obtiene el valor de la variable
bool getInvincible();
// Establece el valor de la variable
void setInvincible(bool value);
};
#endif

View File

@@ -4,19 +4,35 @@
#include <sstream>
// Constructor
Room::Room(std::string file_path, SDL_Renderer *renderer, Asset *asset, ItemTracker *itemTracker, int *items)
Room::Room(std::string file_path, SDL_Renderer *renderer, Screen *screen, Asset *asset, ItemTracker *itemTracker, int *items, Debug *debug)
{
// Inicializa variables
tileSize = 8;
mapWidth = 32;
mapHeight = 16;
tilesetWidth = 20;
// Copia los punteros a objetos
this->asset = asset;
this->renderer = renderer;
this->asset = asset;
this->screen = screen;
this->itemTracker = itemTracker;
this->itemsPicked = items;
this->debug = debug;
// Crea los objetos
load(file_path);
texture = new LTexture(renderer, asset->get(tileset));
itemSound = JA_LoadSound(asset->get("item.wav").c_str());
// Calcula las superficies
setBottomSurfaces();
setTopSurfaces();
setLeftSurfaces();
setRightSurfaces();
setLeftSlopes();
setRightSlopes();
// Crea la textura para el mapa de tiles de la habitación
mapTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (mapTexture == NULL)
@@ -24,6 +40,9 @@ Room::Room(std::string file_path, SDL_Renderer *renderer, Asset *asset, ItemTrac
// Pinta el mapa de la habitación en la textura
fillMapTexture();
// Establece el color del borde
screen->setBorderColor(borderColor);
}
// Destructor
@@ -90,13 +109,11 @@ bool Room::load(std::string _file_path)
// Si la linea contiene el texto [tilemap] se realiza el proceso de carga del fichero tmx
else if (line == "[tilemap]")
{
// printf("Loading tilemap...\n");
do
{
std::getline(file, line);
if (line.find(".tmx") != std::string::npos)
{
// printf("Reading file %s\n", asset->get(line).c_str());
std::ifstream file2(asset->get(line)); // Abre el fichero tmx
if (file2.good())
{
@@ -109,11 +126,7 @@ bool Room::load(std::string _file_path)
do
{
std::getline(file2, line);
// printf("parsing: %s\n", line.c_str());
pos = line.find("data encoding");
// printf("pos: %i\n", pos);
} while (pos == std::string::npos);
do
@@ -122,12 +135,10 @@ bool Room::load(std::string _file_path)
std::getline(file2, line);
if (line != "</data>")
{
// printf("data: %s\n", line.c_str());
std::stringstream ss(line);
std::string tmp;
while (getline(ss, tmp, ','))
{
// printf("tile: %s\n", tmp.c_str());
tilemap.push_back(std::stoi(tmp));
}
}
@@ -213,6 +224,11 @@ bool Room::setVars(std::string var, std::string value)
bgColor = stringToColor(value);
}
else if (var == "border")
{
borderColor = stringToColor(value);
}
else if (var == "tileset")
{
tileset = value;
@@ -416,7 +432,82 @@ void Room::fillMapTexture()
clip.x = ((tilemap[(y * 32) + x] - 1) % 20) * 8;
clip.y = ((tilemap[(y * 32) + x] - 1) / 20) * 8;
texture->render(renderer, x * 8, y * 8, &clip);
if (debug->getEnabled())
{
if (clip.x != -8)
{
clip.x = x * 8;
clip.y = y * 8;
SDL_SetRenderDrawColor(renderer, 64, 64, 64, 224);
SDL_RenderFillRect(renderer, &clip);
}
}
}
// ****
if (debug->getEnabled())
{
// BottomSurfaces
if (true)
{
for (auto l : bottomSurfaces)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y);
}
}
// TopSurfaces
if (true)
{
for (auto l : topSurfaces)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y);
}
}
// LeftSurfaces
if (true)
{
for (auto l : leftSurfaces)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2);
}
}
// RightSurfaces
if (true)
{
for (auto l : rightSurfaces)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2);
}
}
// LeftSlopes
if (true)
{
for (auto l : leftSlopes)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x1, l.y1, l.x2, l.y2);
}
}
// RightSlopes
if (true)
{
for (auto l : rightSlopes)
{
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer, l.x1, l.y1, l.x2, l.y2);
}
}
}
// ****
SDL_SetRenderTarget(renderer, nullptr);
}
@@ -490,29 +581,72 @@ std::string Room::getRoom(int border)
}
// Devuelve el tipo de tile que hay en ese pixel
int Room::getTile(SDL_Point point)
tile_e Room::getTile(SDL_Point point)
{
int pos = ((point.y / 8) * 32) + (point.x / 8);
int tile = TILE_EMPTY;
const int maxTile = mapWidth * mapHeight;
const int pos = ((point.y / tileSize) * mapWidth) + (point.x / tileSize);
tile_e tile = t_empty;
if (pos < 512)
if (pos < maxTile)
{
// Los tiles entre el 1 y el 80 son solidos
if ((tilemap[pos] > 0) && (tilemap[pos] < 201))
// Las filas 0-7 son de tiles t_wall
if ((tilemap[pos] > 0) && (tilemap[pos] < 8 * tilesetWidth))
{
return TILE_SOLID;
return t_wall;
}
// Los tiles mayores de 80 son atravesables
if ((tilemap[pos] > 200) && (tilemap[pos] < 381))
// La fila 8 es de tiles t_slope_r
else if ((tilemap[pos] >= 8 * tilesetWidth) && (tilemap[pos] < 9 * tilesetWidth))
{
return TILE_TRAVESSABLE;
return t_slope_r;
}
// Los tiles mayores de 80 son atravesables
if ((tilemap[pos] > 380) && (tilemap[pos] < 400))
// La fila 9 es de tiles t_slope_l
else if ((tilemap[pos] >= 9 * tilesetWidth) && (tilemap[pos] < 10 * tilesetWidth))
{
return TILE_KILL;
return t_slope_l;
}
// Las filas 10-14 son de tiles t_passable
if ((tilemap[pos] >= 10 * tilesetWidth) && (tilemap[pos] < 15 * tilesetWidth))
{
return t_passable;
}
}
return tile;
}
// Devuelve el tipo de tile que hay en ese indice
tile_e Room::getTile(int index)
{
const int maxTile = mapWidth * mapHeight;
tile_e tile = t_empty;
if (index < maxTile)
{
// Las filas 0-7 son de tiles t_wall
if ((tilemap[index] > 0) && (tilemap[index] < 8 * tilesetWidth))
{
return t_wall;
}
// La fila 8 es de tiles t_slope_r
else if ((tilemap[index] >= 8 * tilesetWidth) && (tilemap[index] < 9 * tilesetWidth))
{
return t_slope_r;
}
// La fila 9 es de tiles t_slope_l
else if ((tilemap[index] >= 9 * tilesetWidth) && (tilemap[index] < 10 * tilesetWidth))
{
return t_slope_l;
}
// Las filas 10-14 son de tiles t_passable
if ((tilemap[index] >= 10 * tilesetWidth) && (tilemap[index] < 15 * tilesetWidth))
{
return t_passable;
}
}
@@ -567,3 +701,399 @@ void Room::reLoadTexture()
item->reLoadTexture();
}
}
// Obten el tamaño del tile
int Room::getTileSize()
{
return 8;
}
// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
int Room::getSlopeHeight(SDL_Point p, tile_e slope)
{
// Calcula la base del tile
int base = ((p.y / tileSize) * tileSize) + tileSize;
debug->add("BASE = " + std::to_string(base));
// Calcula cuanto se ha entrado en el tile horizontalmente
const int pos = (p.x % tileSize); // esto da un valor entre 0 y 7
debug->add("POS = " + std::to_string(pos));
// Se resta a la base la cantidad de pixeles pos en funcion de la rampa
if (slope == t_slope_r)
{
base -= pos + 1;
debug->add("BASE_R = " + std::to_string(base));
}
else
{
base -= (tileSize - pos);
debug->add("BASE_L = " + std::to_string(base));
}
return base;
}
// Calcula las superficies inferiores
void Room::setBottomSurfaces()
{
std::vector<int> tile;
// Busca todos los tiles de tipo muro que no tengan debajo otro muro
// Hay que recorrer la habitación por filas (excepto los de la última fila)
for (int i = 0; i < tilemap.size() - mapWidth; i++)
{
if (getTile(i) == t_wall && getTile(i + mapWidth) != t_wall)
{
tile.push_back(i);
// Si llega al final de la fila, introduce un separador
if (i % mapWidth == mapWidth - 1)
{
tile.push_back(-1);
}
}
}
// Recorre el vector de tiles buscando tiles consecutivos para localizar las superficies
int i = 0;
while (i < tile.size())
{
h_line_t line;
line.x1 = (tile[i] % mapWidth) * tileSize;
line.y = ((tile[i] / mapWidth) * tileSize) + tileSize - 1;
while (tile[i] + 1 == tile[i + 1])
{
i++;
}
line.x2 = ((tile[i] % mapWidth) * tileSize) + tileSize - 1;
bottomSurfaces.push_back(line);
i++;
}
}
// Calcula las superficies superiores
void Room::setTopSurfaces()
{
std::vector<int> tile;
// Busca todos los tiles de tipo muro o pasable que no tengan encima un muro
// Hay que recorrer la habitación por filas (excepto los de la primera fila)
for (int i = mapWidth; i < tilemap.size(); i++)
{
if ((getTile(i) == t_wall || getTile(i) == t_passable) && getTile(i - mapWidth) != t_wall)
{
tile.push_back(i);
// Si llega al final de la fila, introduce un separador
if (i % mapWidth == mapWidth - 1)
{
tile.push_back(-1);
}
}
}
// Recorre el vector de tiles buscando tiles consecutivos para localizar las superficies
int i = 0;
while (i < tile.size())
{
h_line_t line;
line.x1 = (tile[i] % mapWidth) * tileSize;
line.y = (tile[i] / mapWidth) * tileSize;
while (tile[i] + 1 == tile[i + 1])
{
i++;
}
line.x2 = ((tile[i] % mapWidth) * tileSize) + tileSize - 1;
topSurfaces.push_back(line);
i++;
}
}
// Calcula las superficies laterales izquierdas
void Room::setLeftSurfaces()
{
std::vector<int> tile;
// Busca todos los tiles de tipo muro que no tienen a su izquierda un tile de tipo muro
// Hay que recorrer la habitación por columnas (excepto los de la primera columna)
for (int i = 1; i < mapWidth; ++i)
{
for (int j = 0; j < mapHeight; ++j)
{
const int pos = (j * mapWidth + i);
if (getTile(pos) == t_wall && getTile(pos - 1) != t_wall)
{
tile.push_back(pos);
}
}
}
// Recorre el vector de tiles buscando tiles consecutivos
// (Los tiles de la misma columna, la diferencia entre ellos es de mapWidth)
// para localizar las superficies
int i = 0;
while (i < tile.size())
{
v_line_t line;
line.x = (tile[i] % mapWidth) * tileSize;
line.y1 = ((tile[i] / mapWidth) * tileSize);
while (tile[i] + mapWidth == tile[i + 1])
{
i++;
}
line.y2 = ((tile[i] / mapWidth) * tileSize) + tileSize - 1;
leftSurfaces.push_back(line);
i++;
}
}
// Calcula las superficies laterales derechas
void Room::setRightSurfaces()
{
std::vector<int> tile;
// Busca todos los tiles de tipo muro que no tienen a su derecha un tile de tipo muro
// Hay que recorrer la habitación por columnas (excepto los de la última columna)
for (int i = 0; i < mapWidth - 1; ++i)
{
for (int j = 0; j < mapHeight; ++j)
{
const int pos = (j * mapWidth + i);
if (getTile(pos) == t_wall && getTile(pos + 1) != t_wall)
{
tile.push_back(pos);
}
}
}
// Recorre el vector de tiles buscando tiles consecutivos
// (Los tiles de la misma columna, la diferencia entre ellos es de mapWidth)
// para localizar las superficies
int i = 0;
while (i < tile.size())
{
v_line_t line;
line.x = ((tile[i] % mapWidth) * tileSize) + tileSize - 1;
line.y1 = ((tile[i] / mapWidth) * tileSize);
while (tile[i] + mapWidth == tile[i + 1])
{
i++;
}
line.y2 = ((tile[i] / mapWidth) * tileSize) + tileSize - 1;
rightSurfaces.push_back(line);
i++;
}
}
// Encuentra todas las rampas que suben hacia la izquierda
void Room::setLeftSlopes()
{
// Recorre la habitación entera por filas buscando tiles de tipo t_slope_l
std::vector<int> found;
for (int i = 0; i < tilemap.size(); ++i)
{
if (getTile(i) == t_slope_l)
{
found.push_back(i);
}
}
// El primer elemento es el inicio de una rampa. Se añade ese elemento y se buscan los siguientes,
// que seran i + mapWidth + 1. Conforme se añaden se eliminan y se vuelve a escudriñar el vector de
// tiles encontrados hasta que esté vacío
while (found.size() > 0)
{
d_line_t line;
line.x1 = (found[0] % mapWidth) * tileSize;
line.y1 = (found[0] / mapWidth) * tileSize;
int lookingFor = found[0] + mapWidth + 1;
int lastOneFound = found[0];
found.erase(found.begin());
for (int i = 0; i < found.size(); i++)
{
if (found[i] == lookingFor)
{
lastOneFound = lookingFor;
lookingFor += mapWidth + 1;
found.erase(found.begin() + i);
--i;
}
}
line.x2 = ((lastOneFound % mapWidth) * tileSize) + tileSize - 1;
line.y2 = ((lastOneFound / mapWidth) * tileSize) + tileSize - 1;
leftSlopes.push_back(line);
}
}
// Encuentra todas las rampas que suben hacia la derecha
void Room::setRightSlopes()
{
// Recorre la habitación entera por filas buscando tiles de tipo t_slope_r
std::vector<int> found;
for (int i = 0; i < tilemap.size(); ++i)
{
if (getTile(i) == t_slope_r)
{
found.push_back(i);
}
}
// El primer elemento es el inicio de una rampa. Se añade ese elemento y se buscan los siguientes,
// que seran i + mapWidth - 1. Conforme se añaden se eliminan y se vuelve a escudriñar el vector de
// tiles encontrados hasta que esté vacío
while (found.size() > 0)
{
d_line_t line;
line.x1 = ((found[0] % mapWidth) * tileSize) + tileSize - 1;
line.y1 = (found[0] / mapWidth) * tileSize;
int lookingFor = found[0] + mapWidth - 1;
int lastOneFound = found[0];
found.erase(found.begin());
for (int i = 0; i < found.size(); i++)
{
if (found[i] == lookingFor)
{
lastOneFound = lookingFor;
lookingFor += mapWidth - 1;
found.erase(found.begin() + i);
--i;
}
}
line.x2 = (lastOneFound % mapWidth) * tileSize;
line.y2 = ((lastOneFound / mapWidth) * tileSize) + tileSize - 1;
rightSlopes.push_back(line);
}
}
// Comprueba las colisiones
int Room::checkRightSurfaces(SDL_Rect *rect)
{
for (auto s : rightSurfaces)
{
if (checkCollision(s, *rect))
{
return s.x;
}
}
return -1;
}
// Comprueba las colisiones
int Room::checkLeftSurfaces(SDL_Rect *rect)
{
for (auto s : leftSurfaces)
{
if (checkCollision(s, *rect))
{
return s.x;
}
}
return -1;
}
// Comprueba las colisiones
int Room::checkTopSurfaces(SDL_Rect *rect)
{
for (auto s : topSurfaces)
{
if (checkCollision(s, *rect))
{
return s.y;
}
}
return -1;
}
// Comprueba las colisiones
int Room::checkBottomSurfaces(SDL_Rect *rect)
{
for (auto s : bottomSurfaces)
{
if (checkCollision(s, *rect))
{
return s.y;
}
}
return -1;
}
// Comprueba las colisiones
bool Room::checkTopSurfaces(SDL_Point *p)
{
for (auto s : topSurfaces)
{
if (checkCollision(s, *p))
{
return true;
}
}
return false;
}
// Comprueba las colisiones
int Room::checkLeftSlopes(v_line_t *line)
{
for (auto s : leftSlopes)
{
const SDL_Point p = checkCollision(s, *line);
if (p.x != -1)
{
return p.y;
}
}
return -1;
}
// Comprueba las colisiones
bool Room::checkLeftSlopes(SDL_Point *p)
{
for (auto s : leftSlopes)
{
if (checkCollision(*p, s))
{
return true;
}
}
return false;
}
// Comprueba las colisiones
int Room::checkRightSlopes(v_line_t *line)
{
for (auto s : rightSlopes)
{
const SDL_Point p = checkCollision(s, *line);
if (p.x != -1)
{
return p.y;
}
}
return -1;
}
// Comprueba las colisiones
bool Room::checkRightSlopes(SDL_Point *p)
{
for (auto s : rightSlopes)
{
if (checkCollision(*p, s))
{
return true;
}
}
return false;
}

View File

@@ -3,35 +3,42 @@
#include "utils.h"
#include "asset.h"
#include "screen.h"
#include "enemy.h"
#include "item.h"
#include "item_tracker.h"
#include "const.h"
#include "jail_audio.h"
#include "debug.h"
#include <string>
#include <vector>
#ifndef ROOM_H
#define ROOM_H
#define TILE_EMPTY 0
#define TILE_SOLID 1
#define TILE_TRAVESSABLE 2
#define TILE_KILL 3
/*
Cada habitación se crea y destruye cada vez que se entra o sale de la misma
Cada habitacion si que tendra lo siguiente:
ID (numerico)
NOMBRE (texto)
COLOR DE FONDO (texto)
SET DE TILES (texto, hace referencia a un png de la colección)
LIMITE SUPERIOR (ID de la habitación superior), INFERIOR, IZQUIERDO y DERECHO
MAPA DE TILES (array con los indices de los tiles a utilizar) <-- hay que decidir si cada tile del set ya
Cada habitacion tiene lo siguiente:
- ID (numerico)
- NOMBRE (texto)
- COLOR DE FONDO (texto)
- COLOR DEL BORDE (texto)
- SET DE TILES (texto, hace referencia a un png de la colección)
- LIMITE SUPERIOR (ID de la habitación superior), INFERIOR, IZQUIERDO y DERECHO
- MAPA DE TILES (array con los indices de los tiles a utilizar) <-- hay que decidir si cada tile del set ya
tierne propiedades o se ponen en un mapa aparte
LISTADO DE ENEMIGOS (tipo, posicion, dx, dy)
LISTADO DE ITEMS (tipo, posicion)
- LISTADO DE ENEMIGOS (tipo, posicion, dx, dy)
- LISTADO DE ITEMS (tipo, posicion)
*/
enum tile_e
{
t_empty,
t_wall,
t_passable,
t_slope_l,
t_slope_r,
t_death
};
// Clase Room
class Room
@@ -39,6 +46,7 @@ class Room
private:
std::string name; // Nombre de la habitación
color_t bgColor; // Color de fondo de la habitación
color_t borderColor; // Color de fondo de la habitación
std::string roomUp; // Identificador de la habitación que se encuentra arriba
std::string roomDown; // Identificador de la habitación que se encuentra abajp
std::string roomLeft; // Identificador de la habitación que se encuentra a la izquierda
@@ -49,11 +57,24 @@ private:
std::vector<Item *> items; // Listado con los items que hay en la habitación
LTexture *texture; // Textura con los graficos de la habitación
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Screen *screen; // Objeto encargado de dibujar en pantalla
ItemTracker *itemTracker; // Lleva el control de los objetos recogidos
SDL_Renderer *renderer; // El renderizador de la ventana
SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación
JA_Sound itemSound; // Sonido producido al coger un objeto
int *itemsPicked; // Puntero a la cantidad de items recogidos que lleva el juego
Debug *debug; // Objeto para gestionar la información de debug
std::vector<h_line_t> bottomSurfaces; // Lista con las superficies inferiores de la habitación
std::vector<h_line_t> topSurfaces; // Lista con las superficies superiores de la habitación
std::vector<v_line_t> leftSurfaces; // Lista con las superficies laterales de la parte izquierda de la habitación
std::vector<v_line_t> rightSurfaces; // Lista con las superficies laterales de la parte derecha de la habitación
std::vector<d_line_t> leftSlopes; // Lista con todas las rampas que suben hacia la izquierda
std::vector<d_line_t> rightSlopes; // Lista con todas las rampas que suben hacia la derecha
int tileSize; // Ancho del tile en pixels
int mapWidth; // Ancho del mapa en tiles
int mapHeight; // Alto del mapa en tiles
int tilesetWidth; // Ancho del tileset en tiles
// Carga las variables desde un fichero
bool load(std::string file_path);
@@ -70,9 +91,30 @@ private:
// Pinta el mapa de la habitación en la textura
void fillMapTexture();
// Calcula las superficies inferiores
void setBottomSurfaces();
// Calcula las superficies superiores
void setTopSurfaces();
// Calcula las superficies laterales izquierdas
void setLeftSurfaces();
// Calcula las superficies laterales derechas
void setRightSurfaces();
// Encuentra todas las rampas que suben hacia la izquierda
void setLeftSlopes();
// Encuentra todas las rampas que suben hacia la derecha
void setRightSlopes();
// Devuelve el tipo de tile que hay en ese indice
tile_e getTile(int index);
public:
// Constructor
Room(std::string file_path, SDL_Renderer *renderer, Asset *asset, ItemTracker *item_tracker, int *items);
Room(std::string file_path, SDL_Renderer *renderer, Screen *screen, Asset *asset, ItemTracker *item_tracker, int *items, Debug *debug);
// Destructor
~Room();
@@ -99,7 +141,7 @@ public:
std::string getRoom(int border);
// Devuelve el tipo de tile que hay en ese pixel
int getTile(SDL_Point point);
tile_e getTile(SDL_Point point);
// Indica si hay colision con un enemigo a partir de un rectangulo
bool enemyCollision(SDL_Rect &rect);
@@ -109,6 +151,39 @@ public:
// Recarga la textura
void reLoadTexture();
// Obten el tamaño del tile
int getTileSize();
// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
int getSlopeHeight(SDL_Point p, tile_e slope);
// Comprueba las colisiones
int checkRightSurfaces(SDL_Rect *rect);
// Comprueba las colisiones
int checkLeftSurfaces(SDL_Rect *rect);
// Comprueba las colisiones
int checkTopSurfaces(SDL_Rect *rect);
// Comprueba las colisiones
int checkBottomSurfaces(SDL_Rect *rect);
// Comprueba las colisiones
bool checkTopSurfaces(SDL_Point *p);
// Comprueba las colisiones
int checkLeftSlopes(v_line_t *line);
// Comprueba las colisiones
bool checkLeftSlopes(SDL_Point *p);
// Comprueba las colisiones
int checkRightSlopes(v_line_t *line);
// Comprueba las colisiones
bool checkRightSlopes(SDL_Point *p);
};
#endif

40
source/room_tracker.cpp Normal file
View File

@@ -0,0 +1,40 @@
#include "room_tracker.h"
// Constructor
RoomTracker::RoomTracker()
{
}
// Destructor
RoomTracker::~RoomTracker()
{
list.clear();
}
// Comprueba si la habitación ya ha sido visitada
bool RoomTracker::hasBeenVisited(std::string name)
{
for (auto l : list)
{
if (l == name)
{
return true;
}
}
return false;
}
// Añade la habitación a la lista
bool RoomTracker::addRoom(std::string name)
{
// Comprueba si la habitación ya ha sido visitada
if (!hasBeenVisited(name))
{
// En caso contrario añádela a la lista
list.push_back(name);
return true;
}
return false;
}

30
source/room_tracker.h Normal file
View File

@@ -0,0 +1,30 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include <string>
#include <vector>
#ifndef ROOM_TRACKER_H
#define ROOM_TRACKER_H
// Clase RoomTracker
class RoomTracker
{
private:
std::vector<std::string> list; // Lista con las habitaciones visitadas
// Comprueba si la habitación ya ha sido visitada
bool hasBeenVisited(std::string name);
public:
// Constructor
RoomTracker();
// Destructor
~RoomTracker();
// Añade la habitación a la lista
bool addRoom(std::string name);
};
#endif

View File

@@ -3,18 +3,17 @@
#include <sstream>
// Constructor
ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, int *lives, int *items, Uint32 *clock)
ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, board_t *board)
{
// Obten punteros a objetos
this->asset = asset;
this->renderer = renderer;
this->lives = lives;
this->items = items;
this->clock = clock;
this->board = board;
// Reserva memoria para los objetos
texture = new LTexture(renderer, asset->get("player01.png"));
sprite = new AnimatedSprite(texture, renderer, asset->get("player01.ani"));
playerTexture = new LTexture(renderer, asset->get("player.png"));
itemTexture = new LTexture(renderer, asset->get("items.png"));
sprite = new AnimatedSprite(playerTexture, renderer, asset->get("player.ani"));
sprite->setCurrentAnimation("walk_menu");
text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
@@ -26,10 +25,10 @@ ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, int *lives, int *it
color_t c = stringToColor("blue");
color.push_back(c);
c = stringToColor("red");
color.push_back(c);
//c = stringToColor("red");
//color.push_back(c);
c = stringToColor("purple");
c = stringToColor("magenta");
color.push_back(c);
c = stringToColor("green");
@@ -44,32 +43,33 @@ ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Asset *asset, int *lives, int *it
c = stringToColor("white");
color.push_back(c);
c = stringToColor("light_blue");
c = stringToColor("bright_blue");
color.push_back(c);
c = stringToColor("light_red");
//c = stringToColor("bright_red");
//color.push_back(c);
c = stringToColor("bright_magenta");
color.push_back(c);
c = stringToColor("light_purple");
c = stringToColor("bright_green");
color.push_back(c);
c = stringToColor("light_green");
c = stringToColor("bright_cyan");
color.push_back(c);
c = stringToColor("light_cyan");
c = stringToColor("bright_yellow");
color.push_back(c);
c = stringToColor("light_yellow");
color.push_back(c);
c = stringToColor("light_white");
c = stringToColor("bright_white");
color.push_back(c);
}
// Destructor
ScoreBoard::~ScoreBoard()
{
delete texture;
delete playerTexture;
delete itemTexture;
delete sprite;
delete text;
}
@@ -78,18 +78,18 @@ ScoreBoard::~ScoreBoard()
void ScoreBoard::render()
{
// Dibuja el fondo del marcador
const SDL_Rect rect = {0, 17 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
const SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect);
// Dibuja las vidas
sprite->setPosY(18 * BLOCK);
sprite->setPosY(19 * BLOCK);
int index;
const int desp = (counter / 40) % 8;
const int frame = desp % 4;
sprite->setCurrentFrame(frame);
for (int i = 0; i < *lives; i++)
for (int i = 0; i < board->lives; i++)
{
sprite->setPosX(8 + (16 * i) + desp);
index = i % color.size();
@@ -97,18 +97,25 @@ void ScoreBoard::render()
sprite->render();
}
// Escribe los textos
const clock_t clock = getTime();
std::string itemsTxt = std::to_string(*items / 100) + std::to_string((*items % 100) / 10) + std::to_string(*items % 10);
std::string separator = " ";
if (clock.separator)
// Muestra si suena la música
if (board->music)
{
separator = ":";
const color_t c = stringToColor("bright_blue");
SDL_Rect clip = {0, 8, 8, 8};
itemTexture->setColor(c.r, c.g, c.b);
itemTexture->render(renderer, 20 * BLOCK, 20 * BLOCK, &clip);
}
std::string timeTxt = std::to_string((clock.minutes % 60) / 10) + std::to_string(clock.minutes % 10) + separator + std::to_string((clock.seconds % 60) / 10) + std::to_string(clock.seconds % 10);
std::string text = "Items collected " + itemsTxt + " Time " + timeTxt;
const color_t color = stringToColor("white");
this->text->writeColored(BLOCK, 21 * BLOCK, text, color);
// Escribe los textos
const std::string timeTxt = std::to_string((clock.minutes % 60) / 10) + std::to_string(clock.minutes % 10) + clock.separator + std::to_string((clock.seconds % 60) / 10) + std::to_string(clock.seconds % 10);
const std::string itemsTxt = std::to_string(board->items / 100) + std::to_string((board->items % 100) / 10) + std::to_string(board->items % 10);
const std::string roomsTxt = std::to_string(board->rooms / 100) + std::to_string((board->rooms % 100) / 10) + std::to_string(board->rooms % 10);
this->text->writeColored(22 * BLOCK, 20 * BLOCK, "Rooms", stringToColor("yellow"));
this->text->writeColored(28 * BLOCK, 20 * BLOCK, roomsTxt, stringToColor("bright_blue"));
this->text->writeColored(BLOCK, 22 * BLOCK, "Items collected ", stringToColor("yellow"));
this->text->writeColored(17 * BLOCK, 22 * BLOCK, itemsTxt, stringToColor("bright_blue"));
this->text->writeColored(20 * BLOCK, 22 * BLOCK, " Time ", stringToColor("yellow"));
this->text->writeColored(26 * BLOCK, 22 * BLOCK, timeTxt, stringToColor("bright_blue"));
}
// Actualiza las variables del objeto
@@ -116,23 +123,27 @@ void ScoreBoard::update()
{
counter++;
sprite->update();
clock = getTime();
}
// Obtiene el tiempo transcurrido de partida
ScoreBoard::clock_t ScoreBoard::getTime()
{
const Uint32 timeElapsed = SDL_GetTicks() - *clock;
const Uint32 timeElapsed = SDL_GetTicks() - board->iniClock;
clock_t time;
time.hours = timeElapsed / 3600000;
time.minutes = timeElapsed / 60000;
time.seconds = timeElapsed / 1000;
time.separator = (timeElapsed % 1000 <= 500);
time.separator = (timeElapsed % 1000 <= 500) ? ":" : " ";
return time;
}
// Recarga la textura
void ScoreBoard::reLoadTexture()
{
texture->reLoad();
playerTexture->reLoad();
itemTexture->reLoad();
text->reLoadTexture();
}

View File

@@ -11,6 +11,15 @@
#ifndef SCOREBOARD_H
#define SCOREBOARD_H
struct board_t
{
int items; // Lleva la cuenta de los objetos recogidos
int lives; // Lleva la cuenta de ls vidas restantes del jugador
int rooms; // Lleva la cuenta de las habitaciones visitadas
bool music; // Indica si ha de sonar la musica durante el juego
Uint32 iniClock;
};
// Clase ScoreBoard
class ScoreBoard
{
@@ -20,10 +29,10 @@ private:
int hours;
int minutes;
int seconds;
bool separator;
std::string separator;
};
LTexture *texture; // Textura con los graficos para las vidas
LTexture *playerTexture; // Textura con los graficos para las vidas
AnimatedSprite *sprite; // Sprite para mostrar las vidas en el marcador
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
@@ -31,16 +40,16 @@ private:
std::vector<color_t> color; // Vector con los colores del objeto
int counter; // Contador interno
int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color
int *lives; // Número ara mostrar en el marcador de vidas
int *items; // Número para mostrar en el marcador de items
Uint32 *clock; // Contiene el tiempo de inicio de la partida
clock_t clock; // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida
LTexture *itemTexture; // Textura con los graficos para las vidas
board_t *board; // Contiene las variables a mostrar en el marcador
// Obtiene el tiempo transcurrido de partida
clock_t getTime();
public:
// Constructor
ScoreBoard(SDL_Renderer *renderer, Asset *asset, int *lives, int *items, Uint32 *clock);
ScoreBoard(SDL_Renderer *renderer, Asset *asset, board_t *board);
// Destructor
~ScoreBoard();

79
source/test.cpp Normal file
View File

@@ -0,0 +1,79 @@
#include "test.h"
// Constructor
Test::Test(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug)
{
// Copia la dirección de los objetos
this->renderer = renderer;
this->screen = screen;
this->asset = asset;
this->debug = debug;
// Inicializa variables
for (int i = 0; i < 4; ++i)
{
point_t p;
p.x = rand() % 256;
p.y = rand() % 192;
p.vx = (float)((rand() % 10) + 1) / 10.0f;
p.vy = (float)((rand() % 10) + 1) / 10.0f;
rand() % 2 == 0 ? p.dx = -1 : p.dx = 1;
rand() % 2 == 0 ? p.dy = -1 : p.dy = 1;
p.vx *= p.dx;
p.vy *= p.dy;
points.push_back(p);
}
}
// Destructor
Test::~Test()
{
}
// Actualiza las variables
void Test::update()
{
for (int i = 0; i < points.size(); ++i)
{
points[i].x += points[i].vx;
points[i].y += points[i].vy;
if (points[i].x > 255)
{
points[i].x = 255;
points[i].vx = -(float)((rand() % 10) + 1) / 10.0f;
}
else if (points[i].x < 0)
{
points[i].x = 0;
points[i].vx = (float)((rand() % 10) + 1) / 10.0f;
}
if (points[i].y > 191)
{
points[i].y = 191;
points[i].vy = -(float)((rand() % 10) + 1) / 10.0f;
}
else if (points[i].y < 0)
{
points[i].y = 0;
points[i].vy = (float)((rand() % 10) + 1) / 10.0f;
}
std::string text = "P" + std::to_string(i) + ": x=" + std::to_string(points[i].x).substr(0,3) + " y=" + std::to_string(points[i].y).substr(0,3) + " vx=" + std::to_string(points[i].vx).substr(0,3) + " vy=" + std::to_string(points[i].vy).substr(0,3);
debug->add(text);
}
}
// Dibuja en pantalla
void Test::render()
{
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
line_t l1 = {(int)points[0].x, (int)points[0].y, (int)points[1].x, (int)points[1].y};
line_t l2 = {(int)points[2].x, (int)points[2].y, (int)points[3].x, (int)points[3].y};
SDL_RenderDrawLine(renderer, l1.x1, l1.y1, l1.x2, l1.y2);
SDL_RenderDrawLine(renderer, l2.x1, l2.y1, l2.x2, l2.y2);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
SDL_Point p = checkCollision(l1, l2);
SDL_RenderDrawPoint(renderer, p.x, p.y);
}

48
source/test.h Normal file
View File

@@ -0,0 +1,48 @@
#pragma once
#include <SDL2/SDL.h>
#include "const.h"
#include "utils.h"
#include "screen.h"
#include "asset.h"
#include "text.h"
#include "debug.h"
#include <vector>
#include <string>
#ifndef TEST_H
#define TEST_H
struct point_t
{
float x, y;
float vx, vy;
int dx, dy;
};
// Clase Test
class Test
{
private:
SDL_Renderer *renderer; // El renderizador de la ventana
Screen *screen; // Objeto encargado de dibujar en pantalla
Asset *asset; // Objeto con los ficheros de recursos
Debug *debug;
std::vector<point_t> points;
public:
// Constructor
Test(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug);
// Destructor
~Test();
// Actualiza las variables
void update();
// Dibuja en pantalla
void render();
};
#endif

View File

@@ -172,7 +172,7 @@ void Text::initOffsetFromFile()
}
// Devuelve el valor de la variable
int Text::getCharacterWidth()
int Text::getCharacterSize()
{
return boxWidth;
}

View File

@@ -62,7 +62,7 @@ public:
int lenght(std::string text, int kerning = 1);
// Devuelve el valor de la variable
int getCharacterWidth();
int getCharacterSize();
// Recarga la textura
void reLoadTexture();

View File

@@ -31,6 +31,9 @@ Title::Title(SDL_Renderer *renderer, Screen *screen, Asset *asset)
letters.push_back(l);
}
letters[0].enabled = true;
// Cambia el color del borde
screen->setBorderColor(stringToColor("bright_blue"));
}
// Destructor
@@ -70,6 +73,31 @@ void Title::checkEventHandler()
section.subsection = 0;
break;
case SDL_SCANCODE_F:
screen->switchVideoMode();
texture->reLoad();
break;
case SDL_SCANCODE_F1:
screen->setWindowSize(1);
texture->reLoad();
break;
case SDL_SCANCODE_F2:
screen->setWindowSize(2);
texture->reLoad();
break;
case SDL_SCANCODE_F3:
screen->setWindowSize(3);
texture->reLoad();
break;
case SDL_SCANCODE_F4:
screen->setWindowSize(4);
texture->reLoad();
break;
default:
break;
}

View File

@@ -1,4 +1,5 @@
#include "utils.h"
#include <math.h>
// Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2)
@@ -74,19 +75,19 @@ bool checkCollision(circle_t &a, SDL_Rect &b)
// Detector de colisiones entre dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b)
{
// Calculate the sides of rect A
// Calcula las caras del rectangulo a
const int leftA = a.x;
const int rightA = a.x + a.w;
const int topA = a.y;
const int bottomA = a.y + a.h;
// Calculate the sides of rect B
// Calcula las caras del rectangulo b
const int leftB = b.x;
const int rightB = b.x + b.w;
const int topB = b.y;
const int bottomB = b.y + b.h;
// If any of the sides from A are outside of B
// Si cualquiera de las caras de a está fuera de b
if (bottomA <= topB)
{
return false;
@@ -107,106 +108,425 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
return false;
}
// If none of the sides from A are outside B
// Si ninguna de las caras está fuera de b
return true;
}
// Detector de colisiones entre un punto y u rectangulo
// Detector de colisiones entre un punto y un rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r)
{
// Comprueba si el punto está fuera del rectangulo en el eje X
// Comprueba si el punto está a la izquierda del rectangulo
if (p.x < r.x)
{
return false;
}
// Comprueba si el punto está a la derecha del rectangulo
if (p.x > r.x + r.w)
{
return false;
}
// Comprueba si el punto está fuera del rectangulo en el eje Y
// Comprueba si el punto está por encima del rectangulo
if (p.y < r.y)
{
return false;
}
// Comprueba si el punto está por debajo del rectangulo
if (p.y > r.y + r.h)
{
return false;
}
// Si ha llegado hasta aquí, es que está dentro
// Si no está fuera, es que está dentro
return true;
}
// Detector de colisiones entre una linea horizontal y un rectangulo
bool checkCollision(h_line_t &l, SDL_Rect &r)
{
// Comprueba si la linea esta por encima del rectangulo
if (l.y < r.y)
{
return false;
}
// Comprueba si la linea esta por debajo del rectangulo
if (l.y >= r.y + r.h)
{
return false;
}
// Comprueba si el inicio de la linea esta a la derecha del rectangulo
if (l.x1 >= r.x + r.w)
{
return false;
}
// Comprueba si el final de la linea esta a la izquierda del rectangulo
if (l.x2 < r.x)
{
return false;
}
// Si ha llegado hasta aquí, hay colisión
return true;
}
// Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(v_line_t &l, SDL_Rect &r)
{
// Comprueba si la linea esta por la izquierda del rectangulo
if (l.x < r.x)
{
return false;
}
// Comprueba si la linea esta por la derecha del rectangulo
if (l.x >= r.x + r.w)
{
return false;
}
// Comprueba si el inicio de la linea esta debajo del rectangulo
if (l.y1 >= r.y + r.h)
{
return false;
}
// Comprueba si el final de la linea esta encima del rectangulo
if (l.y2 < r.y)
{
return false;
}
// Si ha llegado hasta aquí, hay colisión
return true;
}
// Detector de colisiones entre una linea horizontal y un punto
bool checkCollision(h_line_t &l, SDL_Point &p)
{
// Comprueba si el punto esta sobre la linea
if (p.y > l.y)
{
return false;
}
// Comprueba si el punto esta bajo la linea
if (p.y < l.y)
{
return false;
}
// Comprueba si el punto esta a la izquierda de la linea
if (p.x < l.x1)
{
return false;
}
// Comprueba si el punto esta a la derecha de la linea
if (p.x > l.x2)
{
return false;
}
// Si ha llegado aquí, hay colisión
return true;
}
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(line_t &l1, line_t &l2)
{
const float x1 = l1.x1;
const float y1 = l1.y1;
const float x2 = l1.x2;
const float y2 = l1.y2;
const float x3 = l2.x1;
const float y3 = l2.y1;
const float x4 = l2.x2;
const float y4 = l2.y2;
// calculate the direction of the lines
float uA = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
// if uA and uB are between 0-1, lines are colliding
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1)
{
// Calcula la intersección
const float x = x1 + (uA * (x2 - x1));
const float y = y1 + (uA * (y2 - y1));
return {(int)round(x), (int)round(y)};
}
return {-1, -1};
}
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(d_line_t &l1, v_line_t &l2)
{
const float x1 = l1.x1;
const float y1 = l1.y1;
const float x2 = l1.x2;
const float y2 = l1.y2;
const float x3 = l2.x;
const float y3 = l2.y1;
const float x4 = l2.x;
const float y4 = l2.y2;
// calculate the direction of the lines
float uA = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
float uB = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
// if uA and uB are between 0-1, lines are colliding
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1)
{
// Calcula la intersección
const float x = x1 + (uA * (x2 - x1));
const float y = y1 + (uA * (y2 - y1));
return {(int)x, (int)y};
}
return {-1, -1};
}
// Detector de colisiones entre una linea diagonal y una vertical
/*bool checkCollision(d_line_t &l1, v_line_t &l2)
{
// Normaliza la linea diagonal
normalizeLine(l1);
// Comprueba si la linea vertical esta a la izquierda de la linea diagonal
if (l2.x < l1.x1)
{
return false;
}
// Comprueba si la linea vertical esta a la derecha de la linea diagonal
if (l2.x > l1.x2)
{
return false;
}
// Inacabada
return true;
}*/
// Normaliza una linea diagonal
void normalizeLine(d_line_t &l)
{
// Las lineas diagonales van de izquierda a derecha
// x2 mayor que x1
if (l.x2 < l.x1)
{
const int x = l.x1;
const int y = l.y1;
l.x1 = l.x2;
l.y1 = l.y2;
l.x2 = x;
l.y2 = y;
}
}
// Detector de colisiones entre un punto y una linea diagonal
bool checkCollision(SDL_Point &p, d_line_t &l)
{
// Comprueba si el punto está en alineado con la linea
if (abs(p.x - l.x1) != abs(p.y - l.y1))
{
return false;
}
// Comprueba si está a la derecha de la linea
if (p.x > l.x1 && p.x > l.x2)
{
return false;
}
// Comprueba si está a la izquierda de la linea
if (p.x < l.x1 && p.x < l.x2)
{
return false;
}
// En caso contrario, el punto está en la linea
return true;
}
// Devuelve un color_t a partir de un string
color_t stringToColor(std::string str)
{
color_t color = {0x00, 0x00, 0x00};
const std::string palette = "spectrum";
if (palette == "spectrum")
{
if (str == "black")
{
color = {0x00, 0x00, 0x00};
return {0x00, 0x00, 0x00};
}
else if (str == "light_black")
else if (str == "bright_black")
{
color = {0x3C, 0x35, 0x1F};
return {0x00, 0x00, 0x00};
}
else if (str == "blue")
{
color = {0x31, 0x33, 0x90};
return {0x00, 0x00, 0xd8};
}
else if (str == "light_blue")
else if (str == "bright_blue")
{
color = {0x15, 0x59, 0xDB};
return {0x00, 0x00, 0xFF};
}
else if (str == "red")
{
color = {0xA7, 0x32, 0x11};
return {0xd8, 0x00, 0x00};
}
else if (str == "light_red")
else if (str == "bright_red")
{
color = {0xD8, 0x55, 0x25};
return {0xFF, 0x00, 0x00};
}
else if (str == "purple")
else if (str == "magenta")
{
color = {0xA1, 0x55, 0x89};
return {0xd8, 0x00, 0xd8};
}
else if (str == "light_purple")
else if (str == "bright_magenta")
{
color = {0xCD, 0x7A, 0x50};
return {0xFF, 0x00, 0xFF};
}
else if (str == "green")
{
color = {0x62, 0x9A, 0x31};
return {0x00, 0xd8, 0x00};
}
else if (str == "light_green")
else if (str == "bright_green")
{
color = {0x9C, 0xD3, 0x3C};
return {0x00, 0xFF, 0x00};
}
else if (str == "cyan")
{
color = {0x28, 0xA4, 0xCB};
return {0x00, 0xd8, 0xd8};
}
else if (str == "light_cyan")
else if (str == "bright_cyan")
{
color = {0x65, 0xDC, 0xD6};
return {0x00, 0xFF, 0xFF};
}
else if (str == "yellow")
{
color = {0xE8, 0xBC, 0x50};
return {0xd8, 0xd8, 0x00};
}
else if (str == "light_yellow")
else if (str == "bright_yellow")
{
color = {0xF1, 0xE7, 0x82};
return {0xFF, 0xFF, 0x00};
}
else if (str == "white")
{
color = {0xBF, 0xBF, 0xBD};
return {0xd8, 0xd8, 0xd8};
}
else if (str == "light_white")
else if (str == "bright_white")
{
color = {0xF2, 0xF1, 0xED};
return {0xFF, 0xFF, 0xFF};
}
return color;
}
else
{ // zxarne
if (str == "black")
{
return {0x00, 0x00, 0x00};
}
else if (str == "bright_black")
{
return {0x3C, 0x35, 0x1F};
}
else if (str == "blue")
{
return {0x31, 0x33, 0x90};
}
else if (str == "bright_blue")
{
return {0x15, 0x59, 0xDB};
}
else if (str == "red")
{
return {0xA7, 0x32, 0x11};
}
else if (str == "bright_red")
{
return {0xD8, 0x55, 0x25};
}
else if (str == "magenta")
{
return {0xA1, 0x55, 0x89};
}
else if (str == "bright_magenta")
{
return {0xCD, 0x7A, 0x50};
}
else if (str == "green")
{
return {0x62, 0x9A, 0x31};
}
else if (str == "bright_green")
{
return {0x9C, 0xD3, 0x3C};
}
else if (str == "cyan")
{
return {0x28, 0xA4, 0xCB};
}
else if (str == "bright_cyan")
{
return {0x65, 0xDC, 0xD6};
}
else if (str == "yellow")
{
return {0xE8, 0xBC, 0x50};
}
else if (str == "bright_yellow")
{
return {0xF1, 0xE7, 0x82};
}
else if (str == "white")
{
return {0xBF, 0xBF, 0xBD};
}
else if (str == "bright_white")
{
return {0xF2, 0xF1, 0xED};
}
}
return {0x00, 0x00, 0x00};
}

View File

@@ -34,6 +34,30 @@ struct circle_t
int r;
};
// Estructura para definir una linea horizontal
struct h_line_t
{
int x1, x2, y;
};
// Estructura para definir una linea vertical
struct v_line_t
{
int x, y1, y2;
};
// Estructura para definir una linea diagonal
struct d_line_t
{
int x1, y1, x2, y2;
};
// Estructura para definir una linea
struct line_t
{
int x1, y1, x2, y2;
};
// Estructura para definir un color
struct color_t
{
@@ -74,9 +98,33 @@ bool checkCollision(circle_t &a, SDL_Rect &b);
// Detector de colisiones entre un dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b);
// Detector de colisiones entre un punto y u rectangulo
// Detector de colisiones entre un punto y un rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r);
// Detector de colisiones entre una linea horizontal y un rectangulo
bool checkCollision(h_line_t &l, SDL_Rect &r);
// Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(v_line_t &l, SDL_Rect &r);
// Detector de colisiones entre una linea horizontal y un punto
bool checkCollision(h_line_t &l, SDL_Point &p);
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(line_t &l1, line_t &l2);
// Detector de colisiones entre dos lineas
SDL_Point checkCollision(d_line_t &l1, v_line_t &l2);
// Detector de colisiones entre una linea diagonal y una vertical
//bool checkCollision(d_line_t &l1, v_line_t &l2);
// Detector de colisiones entre un punto y una linea diagonal
bool checkCollision(SDL_Point &p, d_line_t &l);
// Normaliza una linea diagonal
void normalizeLine(d_line_t &l);
// Devuelve un color_t a partir de un string
color_t stringToColor(std::string str);

View File

@@ -7,11 +7,12 @@ x (A) Colisiones con los enemigos {cm:2022-08-29}
x (A) Decidir un diseño para qué sucede en caso de morir: Recordar el punto por donde se entró al mapa y la velocidad en el eje X/Y que llevaba el personaje, crear puntos de reaparicion en las habitaciones, etc {cm:2022-08-29}
x En el Jet Set Willy el juego recuerda la posicion y el momento. En las Tres Luces de Glaurung solo la posición. Se va a optar por seguir el diseño del Jet Set Willy {cm:2022-08-29}
x (A) Crear tiles que maten {cm:2022-08-29}
(A) Modificar el salto para que coincida con el del JSW, no ha de colisionar lateralmente
x (A) Modificar el salto para que coincida con el del JSW, no ha de colisionar lateralmente
(A) Crear tiles que deslicen, (no tipo hielo sino cinta)
(A) Crear tiles que arrastren, tipo cinta transportadora
(A) Tiles animados
(A) Crear ascensores
x (A) Crear rampas
x (A) Enemigos de diferente tamaño {cm:2022-08-30}
(A) Color de los items al estilo jet set willy de amstrad, que brillan con dos colores
x (A) Temporizador de inicio de los items, para poder hacer que brillen a distinto ritmo. Esto es incompatible con lo anterior {cm:2022-08-30}
@@ -23,16 +24,17 @@ x (A) Tecla F para pasar a pantalla completa {cm:2022-08-30}
x (A) Tecla + y - para cambiar tamaño de ventana. O control F1 a F4 {cm:2022-08-30}
(A) Poner en el marcador el indicador de si esta sonando la música
(A) Poner en el marcador el numero de habitaciones visitadas
(A) Añadir a cada habitación el color del borde
(A) Añadir a cada habitación el color del nombre de la habitación
(A) Los textos del marcador de colores
x (A) Añadir a cada habitación el color del borde
x (A) Añadir a cada habitación el color del nombre de la habitación
(A) Crear el logo al estilo del logo de ERBE o TOPO, con lineas que lo formen
(A) El titulo del juego hacerlo parecido al del Jet Set Willy in Paris
- Ha de generarse como las cargas de pantalla de spectrum
- Luego se colorea
- Finalmente, cada elemento cambia de color como si fueran luces de neon
(A) En el titulo del juego, por la parte inferior ha de aparecer una marquesina con texto, al estilo demoscene
(A) La pantalla de titulo no tiene menu, solo un PRESS ENTER TO PLAY
x (A) Crear el logo al estilo del logo de ERBE o TOPO, con lineas que lo formen
x (A) El titulo del juego hacerlo parecido al del Jet Set Willy in Paris
x - Ha de generarse como las cargas de pantalla de spectrum
x - Luego se colorea
x - Finalmente, cada elemento cambia de color como si fueran luces de neon
x (A) En el titulo del juego, por la parte inferior ha de aparecer una marquesina con texto, al estilo demoscene
x (A) La pantalla de titulo no tiene menu, solo un PRESS ENTER TO PLAY
## TEMAS