Documentos de Académico
Documentos de Profesional
Documentos de Cultura
2
00:00:03,439 --> 00:00:08,720
empezaré un tutorial de juegos 2d en Java.
3
00:00:06,799 --> 00:00:11,679
Esto es algo que he querido
4
00:00:08,720 --> 00:00:14,920
hacer desde hace bastante tiempo así que
5
00:00:11,679 --> 00:00:18,000
Sí, me alegro de poder empezar por fin
6
00:00:14,920 --> 00:00:21,199
con ello. Comparado con otros tutoriales de juegos
7
00:00:18,000 --> 00:00:24,320
que he hecho antes, como el del
8
00:00:21,199 --> 00:00:27,439
juego de aventuras basado en texto, el desarrollo de juegos en 2d
9
00:00:24,320 --> 00:00:28,960
es un poco más complicado y requiere algo
10
00:00:27,439 --> 00:00:31,679
más de trabajo,
11
00:00:28,960 --> 00:00:34,320
así que me esforzaré al máximo para hacer esto tan
12
00:00:31,679 --> 00:00:37,520
fácil como sea posible para que podáis seguir los
13
00:00:34,320 --> 00:00:39,680
pasos incluso si no tenéis experiencia en
14
00:00:37,520 --> 00:00:40,719
el desarrollo de juegos 2d.
15
00:00:39,680 --> 00:00:43,440
Así que
16
00:00:40,719 --> 00:00:45,920
espero que lo disfrutéis.
17
00:00:43,440 --> 00:00:49,039
Para este tutorial no usaremos
18
00:00:45,920 --> 00:00:52,160
bibliotecas externas. Solamente usaremos
19
00:00:49,039 --> 00:00:54,719
clases de Java por defecto y empezaremos
20
00:00:52,160 --> 00:00:57,280
de cero, así que si tenéis un
21
00:00:54,719 --> 00:00:59,280
entorno de desarrollo (IDE) para escribir código Java podréis
22
00:00:57,280 --> 00:01:00,320
hacer este juego.
23
00:00:59,280 --> 00:01:03,600
Y...
24
00:01:00,320 --> 00:01:06,720
aquí os dejo la hoja de ruta de este tutorial:
25
00:01:03,600 --> 00:01:08,799
Primero haremos un juego relativamente simple
26
00:01:06,720 --> 00:01:11,360
de "búsqueda del tesoro".
27
00:01:08,799 --> 00:01:14,960
Creando esto, aprenderéis a
28
00:01:11,360 --> 00:01:18,080
crear un bucle de juego, que es esencial para el
29
00:01:14,960 --> 00:01:21,200
desarrollo de juegos en 2D y también cómo mostrar
30
00:01:18,080 --> 00:01:23,840
personajes, tiles para los escenarios,
31
00:01:21,200 --> 00:01:26,560
objetos en pantalla
32
00:01:23,840 --> 00:01:29,759
y también aprenderéis a mover
33
00:01:26,560 --> 00:01:32,960
el personaje del jugador en pantalla.
34
00:01:29,759 --> 00:01:35,759
Y tras completar este primer juego,
35
00:01:32,960 --> 00:01:38,840
le añadiremos más elementos
36
00:01:35,759 --> 00:01:43,040
y lo convertiremos en un RPG de acción
37
00:01:38,840 --> 00:01:47,360
en 2D, algo así como un Zelda de estilo retro.
38
00:01:43,040 --> 00:01:49,840
Añadiremos monstruos, npcs, diálogos
39
00:01:47,360 --> 00:01:51,520
inventario, algunos eventos,
40
00:01:49,840 --> 00:01:55,040
cosas así.
41
00:01:51,520 --> 00:01:59,119
ese es el objetivo final de este tutorial.
42
00:01:55,040 --> 00:02:01,439
Este es un tutorial para principiantes en Java
43
00:01:59,119 --> 00:02:04,799
así que explicaré
44
00:02:01,439 --> 00:02:08,319
muchas cosas, como por ejemplo, cómo funciona
45
00:02:04,799 --> 00:02:11,039
el bucle del juego (game loop), etc. Así que si ya tenéis algunas
46
00:02:08,319 --> 00:02:14,640
nociones de programación de juegos en 2d
47
00:02:11,039 --> 00:02:16,160
probablemente notéis que el ritmo es
48
00:02:14,640 --> 00:02:17,040
un poco lento.
49
00:02:16,160 --> 00:02:18,640
Pero
50
00:02:17,040 --> 00:02:21,520
por favor, tened un poco de paciencia conmigo.
51
00:02:18,640 --> 00:02:23,920
Todos somos principiantes al principio y
52
00:02:21,520 --> 00:02:26,640
alguien más podría encontrar útiles
53
00:02:23,920 --> 00:02:30,000
estas explicaciones.
54
00:02:26,640 --> 00:02:32,560
Bien, hasta aquí la introducción y ahora
55
00:02:30,000 --> 00:02:34,840
¡Empecémos el desarrollo!
56
00:02:32,560 --> 00:02:36,480
Crearemos un nuevo
57
00:02:34,840 --> 00:02:38,879
proyecto
58
00:02:36,480 --> 00:02:40,879
y voy a nombrar esto
59
00:02:38,879 --> 00:02:45,120
"My2DGame"
60
00:02:40,879 --> 00:02:46,959
es el nombre más genérico jamás escrito pero
61
00:02:45,120 --> 00:02:48,800
está bien.
62
00:02:46,959 --> 00:02:52,959
y no crearemos (el module-info.java).
63
00:02:48,800 --> 00:02:55,440
Vamos a crear primero un paquete y le pondremos
64
00:02:52,959 --> 00:02:58,159
de nombre "main"
65
00:02:55,440 --> 00:03:02,760
y crearemos una clase.
66
00:02:58,159 --> 00:03:02,760
Vamos a crear la clase "main".
67
00:03:05,360 --> 00:03:08,959
bien
68
00:03:06,720 --> 00:03:10,239
Primero creamos una
69
00:03:08,959 --> 00:03:12,800
ventana,
70
00:03:10,239 --> 00:03:14,159
así que usamos la clase JFrame
71
00:03:12,800 --> 00:03:16,000
"window = new JFrame();"
72
00:03:14,159 --> 00:03:19,000
73
00:03:16,000 --> 00:03:19,000
74
00:03:23,120 --> 00:03:28,799
window.setDefaultCloseOperation
75
00:03:25,440 --> 00:03:32,799
76
00:03:28,799 --> 00:03:35,280
(JFrame.EXIT ON CLOSE); para que podamos cerrar esta
77
00:03:32,799 --> 00:03:38,319
ventana correctamente.
78
00:03:35,280 --> 00:03:40,720
Y también añadimos window.
79
00:03:38,319 --> 00:03:43,120
setResizable(false);
80
00:03:40,720 --> 00:03:45,120
por lo que no podemos redimensionar la
81
00:03:43,120 --> 00:03:48,640
ventana.
82
00:03:45,120 --> 00:03:48,640
Bien, vamos a ponerle
83
00:03:49,280 --> 00:03:52,000
título al juego
84
00:03:52,080 --> 00:03:54,959
Algo así
85
00:03:52,879 --> 00:03:57,680
como "Aventura
86
00:03:54,959 --> 00:03:58,959
2D"
87
00:03:57,680 --> 00:04:02,720
o algo así
88
00:03:58,959 --> 00:04:04,799
entonces, window.setLocationRelativeTo(null);
89
00:04:02,720 --> 00:04:06,400
entonces, window.setLocationRelativeTo(null);
90
00:04:04,799 --> 00:04:08,560
entonces, window.setLocationRelativeTo(null);
91
00:04:06,400 --> 00:04:08,560
entonces, window.setLocationRelativeTo(null);
92
00:04:08,799 --> 00:04:14,080
por lo que las ventanas se mostrarán en el
93
00:04:11,200 --> 00:04:16,720
centro de la pantalla
94
00:04:14,080 --> 00:04:18,560
y finalmente, window.setVisible(true);
95
00:04:16,720 --> 00:04:21,440
y finalmente, window.setVisible(true);
96
00:04:18,560 --> 00:04:26,240
para poder ver esta ventana.
97
00:04:21,440 --> 00:04:26,240
Bien, ahora vamos a crear otra clase
98
00:04:27,040 --> 00:04:32,320
y le voy a poner de nombre
99
00:04:29,360 --> 00:04:32,320
"GamePanel"
100
00:04:33,199 --> 00:04:37,199
y este GamePanel
101
00:04:35,919 --> 00:04:40,160
hereda de
102
00:04:37,199 --> 00:04:40,160
JPanel
103
00:04:41,520 --> 00:04:47,360
así que básicamente esto es un
104
00:04:43,919 --> 00:04:50,639
una subclase de este JPanel así que esto hereda
105
00:04:47,360 --> 00:04:53,759
todas las funciones de JPanel
106
00:04:50,639 --> 00:04:55,759
por lo que este GamePanel funciona como una especie de
107
00:04:53,759 --> 00:04:58,000
pantalla de juego, así que
108
00:04:55,759 --> 00:05:00,160
primero vamos a poner
109
00:04:58,000 --> 00:05:01,919
vamos a decidir algunos (ajustes):
110
00:05:00,160 --> 00:05:03,919
"SCREEN SETTINGS"
111
00:05:01,919 --> 00:05:07,440
(Ajustes de pantalla)
112
00:05:03,919 --> 00:05:08,479
y crear algunas variables aquí
113
00:05:07,440 --> 00:05:10,960
final
114
00:05:08,479 --> 00:05:12,639
final int
115
00:05:10,960 --> 00:05:14,479
final int originalTileSize
116
00:05:12,639 --> 00:05:18,639
final int originalTileSize
117
00:05:14,479 --> 00:05:18,639
y voy a elegir 16
118
00:05:19,520 --> 00:05:28,880
así que esto significa 16 x 16 cuadrados y este 16
119
00:05:25,039 --> 00:05:32,160
x 16 va a ser el tamaño por defecto de
120
00:05:28,880 --> 00:05:36,000
personaje del jugador o npcs y tiles
121
00:05:32,160 --> 00:05:39,520
del mapa en este juego. 16 x 16 es algo
122
00:05:36,000 --> 00:05:42,800
así como un tamaño estándar para muchos juegos retro 2d
123
00:05:39,520 --> 00:05:46,000
juegos y muchos personajes y tiles son
124
00:05:42,800 --> 00:05:48,639
hechos con este tamaño por lo que se pueden encontrar muchos
125
00:05:46,000 --> 00:05:52,160
ejemplos. Algunos juegos utilizan más píxeles
126
00:05:48,639 --> 00:05:56,639
como 32 x 32 para mostrar un personaje
127
00:05:52,160 --> 00:05:59,840
pero en este caso utilizaremos 16 píxeles.
128
00:05:56,639 --> 00:06:00,800
Dicho esto, hay un pequeño problema
129
00:05:59,840 --> 00:06:04,000
ya que
130
00:06:00,800 --> 00:06:06,639
los ordenadores y monitores modernos tienen
131
00:06:04,000 --> 00:06:10,800
resoluciones mucho más altas que en las de
132
00:06:06,639 --> 00:06:11,600
épocas de nes o snes, ya sabéis, 80s, 90s
133
00:06:10,800 --> 00:06:15,840
así que
134
00:06:11,600 --> 00:06:17,759
Los personajes o tiles de 16 x 16 se verán muy
135
00:06:15,840 --> 00:06:23,240
pequeños en pantalla.
136
00:06:17,759 --> 00:06:24,960
Por ejemplo, la resolución de la nes era de 256 x
137
00:06:23,240 --> 00:06:30,479
224
138
00:06:24,960 --> 00:06:31,199
y la Genesis (Mega Drive) fue 320 por 224.
139
00:06:30,479 --> 00:06:34,639
Así que
140
00:06:31,199 --> 00:06:37,039
los personajes a 16 x 16 parecían tener un tamaño decente
141
00:06:34,639 --> 00:06:39,680
en esas configuraciones, pero
142
00:06:37,039 --> 00:06:43,120
seguramente vuestro monitor tiene una resolución mucho mayor
143
00:06:39,680 --> 00:06:45,199
que esa, así que entonces ¿qué podemos hacer?
144
00:06:43,120 --> 00:06:48,800
¡Lo escalaremos!.
145
00:06:45,199 --> 00:06:52,400
Así que vamos a crear una variable Integer
146
00:06:48,800 --> 00:06:55,120
final int "scale"
147
00:06:52,400 --> 00:06:58,880
y voy a poner 3.
148
00:06:55,120 --> 00:07:01,599
Así que, aunque creamos personajes en un
149
00:06:58,880 --> 00:07:02,880
marco de 16 x 16,
150
00:07:01,599 --> 00:07:07,120
se verán a
151
00:07:02,880 --> 00:07:10,080
48 x 48 píxeles en pantalla
152
00:07:07,120 --> 00:07:14,240
este tipo de escalado es bastante común
153
00:07:10,080 --> 00:07:17,360
para desarrollar juegos 2d de estilo retro, así que
154
00:07:14,240 --> 00:07:21,280
también nos ceñimos a la tradición.
155
00:07:17,360 --> 00:07:23,520
y otro entero: final int
156
00:07:21,280 --> 00:07:24,960
tileSize
157
00:07:23,520 --> 00:07:26,319
=
158
00:07:24,960 --> 00:07:27,360
originalTileSize
159
00:07:26,319 --> 00:07:29,360
tileSize = originalTileSize
160
00:07:27,360 --> 00:07:30,479
tileSize = originalTileSize
161
00:07:29,360 --> 00:07:32,960
*
162
00:07:30,479 --> 00:07:32,960
scale;
163
00:07:33,599 --> 00:07:39,199
así que básicamente esto es 48
164
00:07:37,759 --> 00:07:42,560
x 48 tiles,
165
00:07:39,199 --> 00:07:44,960
así que este será el tamaño real del tile (o cuadrado) que
166
00:07:42,560 --> 00:07:48,080
se mostrará en nuestra pantalla
167
00:07:44,960 --> 00:07:51,120
pantalla y luego decidimos el tamaño de
168
00:07:48,080 --> 00:07:54,080
nuestra pantalla de juego, para ello primero
169
00:07:51,120 --> 00:07:55,919
decidimos el número de tiles que el juego puede
170
00:07:54,080 --> 00:07:59,199
mostrar
171
00:07:55,919 --> 00:08:02,720
horizontal y verticalmente y esto
172
00:07:59,199 --> 00:08:05,759
decidirá el tamaño total de la pantalla, así que
173
00:08:02,720 --> 00:08:06,960
final int
174
00:08:05,759 --> 00:08:08,479
maxScreenCol
175
00:08:06,960 --> 00:08:09,440
final int maxScreenCol
176
00:08:08,479 --> 00:08:12,879
final int maxScreenCol
177
00:08:09,440 --> 00:08:15,440
para este juego elegimos
178
00:08:12,879 --> 00:08:15,440
16
179
00:08:16,720 --> 00:08:21,440
columnas y
180
00:08:19,039 --> 00:08:22,639
final int maxScreenRow
181
00:08:21,440 --> 00:08:24,720
final int maxScreenRow
182
00:08:22,639 --> 00:08:26,879
final int maxScreenRow
183
00:08:24,720 --> 00:08:28,720
y las filas son
184
00:08:26,879 --> 00:08:31,680
12.
185
00:08:28,720 --> 00:08:35,279
16 cuadrados horizontalmente y 12 cuadrados
186
00:08:31,680 --> 00:08:38,000
verticalmente por lo que la proporción es
187
00:08:35,279 --> 00:08:40,959
4:3
188
00:08:38,000 --> 00:08:43,839
y como el tamaño de un cuadrado es de 48
189
00:08:40,959 --> 00:08:45,519
píxeles por lo que
190
00:08:43,839 --> 00:08:47,120
int
191
00:08:45,519 --> 00:08:49,040
screenWidth
192
00:08:47,120 --> 00:08:50,959
int screenWidth
193
00:08:49,040 --> 00:08:54,320
int screenWidth =
194
00:08:50,959 --> 00:08:56,320
tileSize * maxScreenRow;
195
00:08:54,320 --> 00:08:57,839
int screenWidth = tileSize * maxScreenRow;
196
00:08:56,320 --> 00:08:59,519
final int screenWidth = tileSize * maxScreenRow;
197
00:08:57,839 --> 00:09:01,920
final
198
00:08:59,519 --> 00:09:01,920
final int
199
00:09:02,000 --> 00:09:04,800
final int screenHeight
200
00:09:03,040 --> 00:09:06,160
final int screenHeight =
201
00:09:04,800 --> 00:09:07,279
final int screenHeight = tileSize
202
00:09:06,160 --> 00:09:10,000
final int screenHeight = tileSize *
203
00:09:07,279 --> 00:09:11,279
final int screenHeight = tileSize * maxScreenRow;
204
00:09:10,000 --> 00:09:13,120
final int screenHeight = tileSize * maxScreenRow;
205
00:09:11,279 --> 00:09:14,560
final int screenHeight = tileSize * maxScreenRow;
206
00:09:13,120 --> 00:09:17,920
final int screenHeight = tileSize * maxScreenRow;
207
00:09:14,560 --> 00:09:21,839
así que esto será uh
208
00:09:17,920 --> 00:09:22,959
el tamaño de la tile es 48
209
00:09:21,839 --> 00:09:25,600
48 *
210
00:09:22,959 --> 00:09:25,600
16
211
00:09:26,200 --> 00:09:30,800
48 * 16 = 768
212
00:09:28,160 --> 00:09:33,360
píxeles
213
00:09:30,800 --> 00:09:35,040
y la altura es
214
00:09:33,360 --> 00:09:36,800
48
215
00:09:35,040 --> 00:09:37,920
48 * 12
216
00:09:36,800 --> 00:09:40,519
así que
217
00:09:37,920 --> 00:09:42,320
576
218
00:09:40,519 --> 00:09:44,240
576
219
00:09:42,320 --> 00:09:47,600
píxeles
220
00:09:44,240 --> 00:09:50,000
así que este será el tamaño de nuestra pantalla
221
00:09:47,600 --> 00:09:51,519
de juego pero por supuesto se puede cambiar
222
00:09:50,000 --> 00:09:52,800
si quieres, por ejemplo
223
00:09:51,519 --> 00:09:54,080
algo como
224
00:09:52,800 --> 00:09:56,399
no sé,
225
00:09:54,080 --> 00:09:58,480
18 por
226
00:09:56,399 --> 00:10:00,959
14 o
227
00:09:58,480 --> 00:10:00,959
algo así.
228
00:10:01,040 --> 00:10:06,000
y así el ancho de pantalla y el alto de pantalla
229
00:10:03,120 --> 00:10:07,920
cambiarán automáticamente.
230
00:10:06,000 --> 00:10:11,040
Y hasta aquí la
231
00:10:07,920 --> 00:10:16,040
configuración de la pantalla, así que ahora vamos a crear un
232
00:10:11,040 --> 00:10:16,040
constructor de este GamePanel.
233
00:10:18,720 --> 00:10:21,040
bien
234
00:10:21,680 --> 00:10:24,720
(¡no "GamePane,
235
00:10:23,200 --> 00:10:26,800
GamePanel!).
236
00:10:24,720 --> 00:10:29,120
Primero
237
00:10:26,800 --> 00:10:31,680
this.
238
00:10:29,120 --> 00:10:35,399
this.setPreferredSize
239
00:10:31,680 --> 00:10:35,399
this.setPreferredSize(new Dimension());
240
00:10:35,680 --> 00:10:40,000
así que vamos a establecer el tamaño de este
241
00:10:38,000 --> 00:10:41,519
GamePanel, así que
242
00:10:40,000 --> 00:10:44,640
screenWidth
243
00:10:41,519 --> 00:10:47,640
y screenHeight
244
00:10:44,640 --> 00:10:47,640
this.setPreferredSize(new Dimension(screenWidth, screenHeight));
245
00:10:49,600 --> 00:10:54,640
y luego
246
00:10:51,839 --> 00:10:57,360
no estoy seguro de que esto sea necesario, pero
247
00:10:54,640 --> 00:11:00,399
Sí, vamos a ponerle color de fondo
248
00:10:57,360 --> 00:11:03,720
a este GamePanel
249
00:11:00,399 --> 00:11:03,720
así que Color.black
250
00:11:07,519 --> 00:11:11,760
y además
251
00:11:10,160 --> 00:11:12,720
establecemos
252
00:11:11,760 --> 00:11:15,120
DoubleBuffered
253
00:11:12,720 --> 00:11:17,760
DoubleBuffered(true);
254
00:11:15,120 --> 00:11:21,040
Si tienes experiencia en el desarrollo de
255
00:11:17,760 --> 00:11:23,600
juegos 2d en java antes y
256
00:11:21,040 --> 00:11:24,959
si has utilizado Canvas para dibujar la
257
00:11:23,600 --> 00:11:28,320
pantalla,
258
00:11:24,959 --> 00:11:29,839
probablemente hayas utilizado también esta BufferStrategy
259
00:11:28,320 --> 00:11:32,560
pero esta vez vamos a usarlo en este
260
00:11:29,839 --> 00:11:36,079
JPanel. JPanel tiene una especie de
261
00:11:32,560 --> 00:11:38,320
función de doble buffering por defecto, así que
262
00:11:36,079 --> 00:11:41,279
creo que es una buena idea establecer esto
263
00:11:38,320 --> 00:11:44,079
en "true" para mejorar
264
00:11:41,279 --> 00:11:46,079
el rendimiento de renderizado.
265
00:11:44,079 --> 00:11:48,000
Bien, ahora volvamos a la clase Main
266
00:11:46,079 --> 00:11:52,720
y
267
00:11:48,000 --> 00:11:52,720
añadimos este GamePanel a esta ventana
268
00:11:53,120 --> 00:11:57,120
GamePanel
269
00:11:55,120 --> 00:11:59,279
GamePanel gamePanel
270
00:11:57,120 --> 00:12:01,760
GamePanel gamePanel = new
271
00:11:59,279 --> 00:12:01,760
GamePanel gamePanel = new GamePanel();
272
00:12:02,399 --> 00:12:08,560
y vamos a añadir este GamePanel
273
00:12:05,680 --> 00:12:08,560
a esta ventana.
274
00:12:10,959 --> 00:12:14,880
Bien,
275
00:12:12,000 --> 00:12:17,360
esta es una
276
00:12:14,880 --> 00:12:20,800
subclase de JPanel, así que básicamente esto es
277
00:12:17,360 --> 00:12:23,760
una clase de JPanel con algunas
278
00:12:20,800 --> 00:12:26,639
funcionalidades más para que puedas añadirlo
279
00:12:23,760 --> 00:12:29,360
a window, ya sabéis, como añadir JPanel a
280
00:12:26,639 --> 00:12:31,760
esta ventana y luego
281
00:12:29,360 --> 00:12:33,519
vamos a
282
00:12:31,760 --> 00:12:37,200
empaquetar
283
00:12:33,519 --> 00:12:39,839
este JPanel para que podamos verlo
284
00:12:37,200 --> 00:12:41,760
Bien, vamos a probarlo:
285
00:12:39,839 --> 00:12:42,560
¡Bien!
286
00:12:41,760 --> 00:12:45,120
Aquí tenemos
287
00:12:42,560 --> 00:12:47,360
nuestra pantalla de juego
288
00:12:45,120 --> 00:12:48,880
y el tamaño es
289
00:12:47,360 --> 00:12:49,800
768
290
00:12:48,880 --> 00:12:53,279
por
291
00:12:49,800 --> 00:12:54,560
576 para que podamos mostrar
292
00:12:53,279 --> 00:12:58,480
16 tiles
293
00:12:54,560 --> 00:13:03,600
de 48 * 48 en horizontal y 12
294
00:12:58,480 --> 00:13:06,480
tiles de 48 * 48 verticalmente
295
00:13:03,600 --> 00:13:09,839
así que ahora tenemos una ventana.
296
00:13:06,480 --> 00:13:13,040
Ahora, hablemos de la mecánicas básicas del
297
00:13:09,839 --> 00:13:16,240
juego. Creo que el concepto más importante
298
00:13:13,040 --> 00:13:19,519
en un juego 2D es
299
00:13:16,240 --> 00:13:22,079
la existencia del tiempo.
300
00:13:19,519 --> 00:13:25,279
En mi anterior juego de aventura de texto,
301
00:13:22,079 --> 00:13:26,399
cuando haces algo, por ejemplo, pulsar
302
00:13:25,279 --> 00:13:29,040
un botón,
303
00:13:26,399 --> 00:13:32,639
el programa
304
00:13:29,040 --> 00:13:34,959
efectúa unos procesos y luego se detiene.
305
00:13:32,639 --> 00:13:38,560
Simplemente espera hasta que vuelvas a
306
00:13:34,959 --> 00:13:39,839
hacer algo, como pulsar el botón de nuevo.
307
00:13:38,560 --> 00:13:43,760
Sin embargo,
308
00:13:39,839 --> 00:13:47,440
en los juegos 2d, una vez que se inicia el programa
309
00:13:43,760 --> 00:13:50,800
el programa sigue funcionando y no
310
00:13:47,440 --> 00:13:54,880
se detiene hasta que, lo más probable, se cierra el
311
00:13:50,800 --> 00:13:57,760
juego o hagas algo especial.
312
00:13:54,880 --> 00:14:01,519
Así que imagina que cuando juegas a juegos como
313
00:13:57,760 --> 00:14:05,760
Super Mario o Minecraft o Call of Duty
314
00:14:01,519 --> 00:14:07,920
o cualquier otro juego de acción,
315
00:14:05,760 --> 00:14:09,760
puedes mover a tu personaje en
316
00:14:07,920 --> 00:14:12,639
pantalla y
317
00:14:09,760 --> 00:14:17,760
otros personajes como monstruos o
318
00:14:12,639 --> 00:14:18,560
npcs también se mueven en pantalla
319
00:14:17,760 --> 00:14:20,240
pero
320
00:14:18,560 --> 00:14:23,680
¿cómo ocurre esto?
321
00:14:20,240 --> 00:14:27,040
su mecánica es básicamente la misma que con
322
00:14:23,680 --> 00:14:31,120
la animación tradicional. El personaje es
323
00:14:27,040 --> 00:14:33,760
en realidad una serie de imágenes estáticas pero
324
00:14:31,120 --> 00:14:34,720
como las imágenes se actualizan
325
00:14:33,760 --> 00:14:37,600
muy rápidamente,
326
00:14:34,720 --> 00:14:40,079
parece que el personaje se mueve.
327
00:14:37,600 --> 00:14:43,920
Lo mismo ocurre con los videojuegos.
328
00:14:40,079 --> 00:14:47,040
por lo que si los fps (Frames per Second) del juego son de 60, significa
329
00:14:43,920 --> 00:14:48,240
que la pantalla se actualiza 60 veces por
330
00:14:47,040 --> 00:14:50,639
segundo.
331
00:14:48,240 --> 00:14:54,160
Tu personaje parece estar en movimiento
332
00:14:50,639 --> 00:14:55,360
pero en realidad, es una serie de 60
333
00:14:54,160 --> 00:14:58,160
imágenes estáticas.
334
00:14:55,360 --> 00:15:01,760
Así que para hacer esta animación en nuestro juego
335
00:14:58,160 --> 00:15:04,880
necesitamos crear un flujo de tiempo en nuestro juego,
336
00:15:01,760 --> 00:15:08,079
así que necesitamos poner en marcha un reloj del juego
337
00:15:04,880 --> 00:15:10,480
y para ello utilizaremos una clase
338
00:15:08,079 --> 00:15:10,480
llamada
339
00:15:10,839 --> 00:15:17,440
Thread y
340
00:15:13,120 --> 00:15:21,600
lo voy a llamar gameThread.
341
00:15:17,440 --> 00:15:22,880
Un hilo es algo que se puede empezar y parar
342
00:15:21,600 --> 00:15:25,120
y una vez
343
00:15:22,880 --> 00:15:27,120
se inicia un hilo
344
00:15:25,120 --> 00:15:28,160
el programa sigue
345
00:15:27,120 --> 00:15:30,560
funcionando
346
00:15:28,160 --> 00:15:33,440
hasta que no lo detienes. No es que
347
00:15:30,560 --> 00:15:36,160
haga algo especial, pero cuando
348
00:15:33,440 --> 00:15:37,279
quieres repetir algún proceso una vez
349
00:15:36,160 --> 00:15:40,160
tras otra
350
00:15:37,279 --> 00:15:43,360
como dibujar la pantalla 60 veces por
351
00:15:40,160 --> 00:15:45,920
segundo, Thread es una clase muy útil.
352
00:15:43,360 --> 00:15:49,120
así que vamos a utilizar este hilo en este
353
00:15:45,920 --> 00:15:52,440
GamePanel y para ejecutar un hilo necesitamos
354
00:15:49,120 --> 00:15:52,440
implementar
355
00:15:54,079 --> 00:15:59,440
la interfaz "Runnable" a esta clase
356
00:15:56,880 --> 00:16:01,680
esa es clave para
357
00:15:59,440 --> 00:16:02,959
utilizar este hilo
358
00:16:01,680 --> 00:16:05,120
y
359
00:16:02,959 --> 00:16:07,360
estamos viendo algún error,
360
00:16:05,120 --> 00:16:11,120
sugiere añadir
361
00:16:07,360 --> 00:16:14,639
los métodos no implementado, así que lo hacemos.
362
00:16:11,120 --> 00:16:17,120
estonos generará automáticamente
363
00:16:14,639 --> 00:16:17,120
el método run().
364
00:16:17,920 --> 00:16:24,399
Pero, ¿Qué es este método run?
365
00:16:20,839 --> 00:16:25,199
probablemente puedes ver esta explicación
366
00:16:24,399 --> 00:16:27,680
sí,
367
00:16:25,199 --> 00:16:30,399
dice:
368
00:16:27,680 --> 00:16:33,199
cuando un objeto que implementa
369
00:16:30,399 --> 00:16:36,720
la interfaz runnable (en este caso nuestro
370
00:16:33,199 --> 00:16:39,519
GamePanel) se utiliza para crear un hilo
371
00:16:36,720 --> 00:16:42,000
el inicio del hilo hace que el método
372
00:16:39,519 --> 00:16:44,320
run del objeto sea llamado en un
373
00:16:42,000 --> 00:16:47,360
hilo de ejecución separado. Básicamente,
374
00:16:44,320 --> 00:16:50,399
cuando iniciamos este gameThread,
375
00:16:47,360 --> 00:16:52,959
llama automáticamente a este método run().
376
00:16:50,399 --> 00:16:56,399
Así es como funciona.
377
00:16:52,959 --> 00:17:00,240
Bien, voy a crear
378
00:16:56,399 --> 00:17:01,759
un nuevo método aquí public void
379
00:17:00,240 --> 00:17:05,560
public void
380
00:17:01,759 --> 00:17:05,560
startGameThread()
381
00:17:06,240 --> 00:17:10,319
y aquí
382
00:17:07,679 --> 00:17:11,280
vamos a instanciar este
383
00:17:10,319 --> 00:17:12,160
gameThread.
384
00:17:11,280 --> 00:17:13,199
gameThread
385
00:17:12,160 --> 00:17:15,600
=
386
00:17:13,199 --> 00:17:17,600
new
387
00:17:15,600 --> 00:17:19,280
Thread()
388
00:17:17,600 --> 00:17:20,240
y vamos a
389
00:17:19,280 --> 00:17:21,520
pasarle
390
00:17:20,240 --> 00:17:25,360
"this" como parámetro.
391
00:17:21,520 --> 00:17:27,919
a este constructor. "this" hace referencia
392
00:17:25,360 --> 00:17:30,400
a esta clase, es decir, GamePanel, así que básicamente
393
00:17:27,919 --> 00:17:33,039
pasamos la clase GamePanel a este
394
00:17:30,400 --> 00:17:35,679
constructor de la clase Thread, así es como
395
00:17:33,039 --> 00:17:37,360
instanciamos un hilo
396
00:17:35,679 --> 00:17:40,720
y ahora
397
00:17:37,360 --> 00:17:44,400
iniciamos este hilo.
398
00:17:40,720 --> 00:17:45,600
gameThread.start();
399
00:17:44,400 --> 00:17:48,480
y así
400
00:17:45,600 --> 00:17:50,960
se va a llamar automáticamente a este
401
00:17:48,480 --> 00:17:50,960
método run()
402
00:17:51,600 --> 00:17:55,760
y
403
00:17:52,880 --> 00:17:56,880
en este método "run" crearemos un bucle
404
00:17:55,760 --> 00:18:00,710
de juego
405
00:17:56,880 --> 00:18:12,550
que será el núcleo de nuestro juego.
406
00:18:00,710 --> 00:18:12,550
[Música]