Está en la página 1de 28

1

00:00:00,240 --> 00:00:06,799


¡Hola, gente! Soy RyiSnow. A partir de este video

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]

También podría gustarte