This graph shows how many times the word ______ has been mentioned throughout the history of the program.
Vamos a hacer un juego que parece sencillo, pero no lo es.
Un juego que os recomiendo mucho porque tiene cosas del Tetris, pero también tiene cosas de UI.
Tiene muchas cosas.
Por ejemplo, es este.
Se llama Stack Game.
¿El Stack Game de qué trata?
Es un juego en el que se supone que tú tienes que ir como apilando los bloques.
Pero la parte del bloque que no apilas correctamente desaparece, ¿vale?
Como podéis ver.
Y cada vez tienes un color totalmente distinto.
Ahora va bastante lento.
El nuestro va a ser un poco más difícil, ¿vale?
Entonces, tiene diferentes cosas.
Porque, primero, tenéis que detectar exactamente dónde se queda la parte del cuadrado que habría que eliminar.
Luego revisar si realmente se ha quedado exactamente encima del bloque.
Entonces, para revisar el tema de la lógica que vamos a hacer, nosotros vamos a hacer una versión en 2D.
Para hacerla con JavaScript y tal.
Esta versión que veis aquí no es la que vamos a hacer.
Tardaríamos más tiempo, ¿vale?
A ver, Midugato.
El Midugato está aquí, aunque no lo veáis, pero está aquí tocando mis cables.
Que no toquen mis cables.
No toquen mis cables y no me pongas esa cara de pena.
Bueno, total.
Que el 3D hoy no lo vamos a hacer, aunque, quién sabe.
Igual más adelante nos podemos animar.
Este que veis es totalmente de código abierto.
Lo podéis buscar como Stack Game JavaScript.
Y vais a ver, es este.
Que está hecho con 3GS y tenéis totalmente de código abierto.
No sé, deben ser...
Tampoco son muchas líneas.
Son 300 líneas o alguna cosa así.
A ver, a lo mejor no es el mejor código del mundo.
Pero tiene, mira, 300 líneas.
Y ese juego que habéis visto son 300 líneas más el CSS aparte, ¿vale?
Aquí tenéis el CSS.
Lo tenéis aparte.
Todo este sería el CSS.
CSS y también el Index HTML, que bueno, tampoco tiene mucha historia.
Y utiliza 3GS para el tema de 3D.
Os recomiendo mucho que le echéis un vistazo.
Vamos a hacer una versión en 2D.
Y os voy a explicar por qué.
Os voy a hacer una versión en 2D para que nos dé tiempo.
Eso es lo primero.
Y lo segundo, porque aún así vais a ver que tiene retos bastante interesantes.
De que hay que detectar exactamente si queda por encima, si queda por abajo.
La verdad que este está bastante bonito.
Os recomiendo mucho.
Vamos a hacer el Game Over.
Vamos a hacer que se tenga que hacer temas de eventos del teclado.
Un montón de cosas, ¿eh?
Un montón de cositas.
Así que, este proyecto lo vamos a poner entre los 9 que ya tenemos de JavaScript 100 proyectos.
Que no sé si algún día llegaremos a los 100 proyectos.
Yo lo voy a intentar.
Pero ya tenemos 9 proyectos.
Tenemos aquí, pues, por ejemplo, el chat GPT local.
El reto de mecanografía.
Hicimos una Arkanoid, el Tetris.
El Tier Maker.
El buscar la información de una IP.
Una hoja de cálculo.
Además, tenéis de cada uno, tenéis el código.
Tenéis la demo.
Y tenéis el vídeo.
O sea, le podéis dar click y aquí tenéis la demo.
Pero si volvéis para atrás, tenéis el código.
Y aquí tenéis todo el código.
Que muchas veces lo hacemos en un solo archivo HTML.
Simplemente para que esté todo en un solo archivo.
Y no os liéis.
Y no tengáis nada.
Y sea lo más simple posible.
Y también tenéis el vídeo donde lo hicimos.
Una hora y media, ¿eh?
Pues antes de empezar, voy a hacer una publicidad.
No, una publicidad no.
El tema es que os quiero explicar una cosa.
Que tenemos la academia, ¿vale?
Que estamos trabajando en ello.
Que estamos añadiendo contenido poco a poco.
En las últimas novedades de JavaScript ya tenemos el capítulo 1 completo.
Las 5 primeras clases.
Y estamos trabajando ya.
Mira, ya tenemos el progreso.
Para que podáis guardar el progreso que lleváis de la academia.
Por ejemplo, pues si habéis visto una clase, pues os va a hacer este check.
Para que tengáis el progreso.
Y por otra parte, estamos trabajando ya en los exámenes.
Porque los cursos van a tener certificaciones.
Y para conseguir la certificación, tendréis que pasar todos los exámenes del curso.
Y estamos trabajando justamente en la parte de los exámenes.
Todavía está en beta, ¿vale?
Porque estamos añadiendo el contenido.
Estamos evolucionando la plataforma.
Pero es totalmente gratuita la academia para todos los que seáis suscriptores.
Solo para que lo sepáis, ¿vale?
Así que si eres suscriptor, que sepas que puedes entrar a la academia y ver por ahora lo que hay.
Vamos a estar añadiendo cada día nuevo contenido.
Tanto del Figma para Deps como las últimas novedades de JavaScript.
Y pronto empezaremos con el curso de Clean Code que tengo por aquí.
Y tal.
Y que estamos evolucionando la plataforma.
Y que vuestro feedback, si queréis, lo podéis dar ahí en el Discord para que sigamos mejorándolo.
Pues dicho esto, yo creo que podemos arrancar ya y darle cañita a nuestro proyecto.
Hoy vamos a hacer el juego del Stack Game.
Pero en lugar de hacerlo en 3D, porque necesitaríamos la dependencia de 3GS.
¿Vale?
Bueno, la podríamos hacer en 3GS.
Lo puedo pensar más adelante, a ver si lo hacemos en 3D.
Pero claro, tendríamos que pasar de alguna base.
Este juego lo vamos a hacer, pero lo vamos a hacer en 2D.
Y lo vamos a hacer puramente con JavaScript, con CSS, desde cero, paso a paso.
Y vamos a ver cómo lo vamos a hacer.
Así que vamos...
Lo mejor es que además el código que vamos a utilizar lo vais a poder reutilizar para la versión 3D.
Porque al final no habría ningún problema.
Así que, ¿dónde voy a hacerlo yo?
Yo lo voy a hacer en el repositorio de JavaScript100.dev.
Aquí tenemos un repositorio.
Aquí tenéis el repositorio con todo el código.
Fijaos, tenéis todos los proyectos.
En cada proyecto tenéis los enlaces.
Este repositorio yo lo tengo aquí clonado.
Voy a entrar y voy a crear un nuevo proyecto.
¿Ves?
Aquí tengo todos los proyectos.
Vamos a crear ya el décimo proyecto, que le vamos a llamar stackgame.
Y vamos a crear nuestro index.html.
De nuevo, nuestros proyectos son 100% sin dependencias, sin absolutamente nada externo.
Entonces, verás que no vamos a utilizar ninguna dependencia.
Lo vamos a hacer todo puramente con JavaScript.
Vamos a iniciar nuestro proyecto con la exclamación para empezar como el HTML ahí fijo que tenemos por aquí.
Y le podemos poner aquí stack...
Vamos a poner stackgame.
¿Ok?
Esto sería lo mínimo que necesitáis en vuestro HTML, básicamente.
Así que, aquí en el body vamos a necesitar utilizar un solo elemento en nuestro proyecto, que va a ser el canvas.
Entonces, vamos a poner aquí canvas.
Mira, canvas.
Id, canvas.
With...
No, vamos a hacer que sea 320.
Vamos a hacer que sea como vertical el juego, ¿vale?
Porque tiene más sentido que sea vertical.
Entonces, le ponemos aquí un canvas.
Y con esto ya vamos a empezar, ¿vale?
Ya tenemos la estructura básica, donde definimos el tipo del elemento.
Aquí podemos poner que sea en español.
Esto es importante, por si no lo sabíais, el atributo lang del HTML.
Hay gente que no lo utiliza, que bueno, no está mal.
Pero sí que, si lo utilizáis, aseguraos de que utilizáis el idioma que vais a utilizar en vuestra aplicación.
En este caso, a ver, ni inglés ni español, porque no va a tener texto.
Pero es súper importante que aquí pongáis el correcto.
No os equivoquéis.
Para eso, mejor no ponerlo, ¿vale?
Entonces, con esto ya tendríamos la estructura básica.
Y ahora ya vamos con nuestros estilos básicos.
También vamos a poner aquí el estilo.
Yo voy a utilizar, siempre os lo digo, tengo una dependencia que se llama Live Preview.
Que es de Microsoft, que lo que te permite es levantar un entorno de desarrollo de un archivo HTML.
Entonces, pones Live Preview.
Bueno, en este caso es que ya lo he detenido.
Live Preview.
Iniciamos el servidor.
En este caso le decimos que es la carpeta 10.
Y esto es nuestro proyecto.
Para que veas que nuestro proyecto puedes poner aquí.
Aquí, ¿ves?
Y aparece por aquí.
¿Vale?
Esto aparece ahí porque me imagino que con...
No sé por qué aparece ahí.
¿Por qué aparece ahí?
Por el canvas no será.
Porque debería aparecer aquí arriba.
Bueno, no sé.
No sé por qué será.
El canvas, si el canvas está abajo...
No sé qué raro, ¿no?
O sea, debería...
Si lo pusiera aquí tendría sentido.
Ahora lo veremos con los estilos.
A ver, vamos a poner Body.
Vamos a poner un color, pues, negro.
Vamos a quitar los márgenes.
Vamos a hacer Display Grid.
¿Vale?
Display Grid.
Vamos a poner el canvas.
Le vamos a poner un borde para que lo veamos.
Porque si no, no lo vemos.
Vamos a hacer aquí que esto se centre.
¿Vale?
Que se centre por aquí.
Mi Dugato.
Deja el cable.
Deja el cable.
Venga.
Ahí tenemos el borde.
No hace falta ponerle la altura porque como ya se lo hemos puesto aquí, pues ya lo tendríamos.
Aquí es donde vamos a dibujar nuestro juego.
Donde vamos a empezar.
¿Vale?
Dentro de nuestro body hemos puesto el canvas.
Perfecto.
Estilos.
Estos son todos los estilos que vamos a necesitar.
¿Vale?
No necesitamos más estilos.
Porque vamos a dibujar dentro del canvas nuestro juego.
Y ahora lo que necesitaríamos sería nuestro script.
Vamos a poner tipo módulo.
¿Por qué ponemos tipo módulo?
Por dos cosas.
Ya os lo digo siempre.
Uno, porque va a cargarse siempre de forma de fair.
Esto significa que se va a cargar una vez que ha renderizado, ha parseado el HTML.
Y por lo tanto, si yo aquí intento recuperar el canvas, ¿vale?
El canvas lo va a encontrar sin ningún problema.
Que si pusiera esto, esto me daría un error.
De hecho, lo podéis ver.
Si yo hago esto sin el type módulo, vais a ver que...
Vale, me ha dejado ahí fatal.
¿Por qué?
¿Por qué?
¿Por qué?
Ah, no sé por qué no...
No sé por qué no lo están...
O sea, ¿por qué lo están encontrando?
Esto me debería estar petando.
Bueno, espérate.
Porque, claro, no es que me debe estar petando.
Me debería estar petando si lo intento utilizar.
Porque si ponemos el console.log del canvas, vamos a ver que es null.
Ahí está.
¿Veis? Es null.
Claro, si lo intento utilizar es que me va a petar.
Si aquí intento sacar el contexto 2D, que es donde vamos a dibujar, ¿vale?
Canvas get context 2D.
Como esto es null, aquí es que nos va a petar.
Fijaos, ¿vale?
Fíjate que me peta.
¿Por qué?
Porque esto va de arriba a abajo.
Es, ¿vale?
Primero pongo los estilos.
Este script se ejecuta antes de que pueda descubrir el HTML.
Y históricamente había mucha gente que hacía esto.
Y ahora os explicaré por qué no es buena idea, ¿vale?
Podrías hacer esto dentro del body.
Y esto funcionar funciona, ¿vale?
Podrías ponerlo aquí.
¿Ves?
Y ahora no te da el mismo problema porque como lo he puesto después del HTML,
entonces seguro, seguro que ahora funciona correctamente.
Porque sí que encuentra el HTML.
Si lo pones arriba es que tienes el problema.
Porque todavía no hemos creado el HTML, intentamos cargar estos elementos y dice, oye, que no lo encuentro.
Para eso podéis hacer lo del defer directamente.
Y esto lo debería solucionar, que veo que no me lo solucionan, no sé por qué.
O podríais hacer lo del type module.
No sé por qué...
QuireSelector Canvas.
No sé por qué el defer...
Es así, ¿no?
Hace tanto tiempo que no he utilizado el defer.
¿No se ponía defer?
Sí.
Defer debería.
Script defer se ejecutan en orden cuando aparece en el documento.
Se ejecutan con orden, pero debería esperar que se pasease todo.
Ya sé por qué, ya sé por qué.
Perdón, perdón.
Es que este defer no funciona para los scripts en línea.
Importante.
Solo funciona para los archivos que son externos.
O sea, si pones un source, entonces sí que lo hace.
Cierto, cierto.
En cambio, los de tipo módulo sí que hace el defer, aunque sea un código en línea.
Es verdad.
Es que hace tanto...
Es que el defer, a utilizarlo manualmente, hace mil millones de años que no lo utilizo.
Pero bueno, yo creo que lo ideal a día de hoy, pleno 2024, casi 2025, es que utilicéis el type module,
que tenéis la posibilidad de utilizar los inputs dentro y además va a ser de tipo defer, que es lo más recomendado.
Y también lo podéis utilizar, por supuesto, para archivos externos.
En este caso lo estamos haciendo aquí en línea, pero también serviría para archivos externos.
Vale.
Pues ahora sí, si miramos aquí el context, pues veremos que ya no tenemos un null.
Vale.
Ahora sí que funciona correctamente.
Así que ahí ya vamos a poder empezar a dibujar.
Para hacer este jueguecito, este jueguecito maravilloso, vamos a ver un poco cuáles son los modos.
Y esta es una de las cosas más importantes que tenéis que tener en vuestra cabeza cuando estamos hablando de programación de videojuegos.
Tenéis que pensar los estados en los que se encuentra un juego.
Por ejemplo, aquí tendríamos el primer estado que podríamos llamarle ready.
Este nos lo vamos a saltar porque directamente vamos a jugar y ya está.
¿Por qué no ponerlo al final y listo?
Ponerlo al final realmente...
Me sabe mal, pero voy a decir mala práctica.
Es que es mala práctica.
Y os voy a decir por qué.
Especialmente cuando estamos hablando de scripts que son externos.
Es mala práctica porque lo que va a ocurrir es que vas a cargar el JavaScript más tarde.
Y esto va a impactar negativamente en el rendimiento del usuario.
Cuando tú lo pones con un defer arriba, cuando es un archivo externo y haces un defer o un time module,
lo que hace de forma bastante inteligente el navegador es que lo va a ir descargando mientras va parseando el HTML.
Entonces, en lugar de tener que esperar a que se parsee todo el HTML y entonces empezar a descargarlo
y evaluarlo, lo que hace el navegador es ponerlo en segundo plano.
Dice, vale, me lo voy a ir descargando, lo voy a ir pues como compilando, lo voy a parsear y lo voy a evaluar,
pero cuando termine el HTML.
Lo podéis ver aquí bastante más claro con este pedazo de cosa para que lo veáis.
Mira, este se ve yo creo que bastante más claro.
Entonces, esto sería como vosotros decís, ¿no?
El synchronous script sería, vale, ¿qué es lo que pasa?
Como va a tener que esperar a parsear el HTML, luego descargaría el script y luego lo ejecutaría.
Entonces, lo haría como síncrono totalmente.
Pero no tiene mucho sentido, es verdad que te evitas los problemas,
pero no tiene sentido porque estás evitando descargar el JavaScript hasta que se parsee el HTML.
En cambio, con el defer, fijaos lo que ocurre.
Es que se parsea el HTML mientras empieza a descargar el script.
Y esto es súper interesante porque al final esto lo que hace es que, vale, me estoy descargando el JavaScript,
que puedo ocupar 100K, que no suele ser muy raro.
Mientras parseo el HTML, hago las dos cosas en paralelo y cuando termino de parsear el HTML,
entonces es que ejecuto el JavaScript y ahí estáis ahorrando tiempo.
Así que esa es la razón.
Si lo ponéis al fondo, es verdad, os evitáis los problemas,
pero lo que va a ocurrir en realidad es que vais a tener que esperar a que se parsee todo el HTML
para que empiece a descargar el JavaScript y luego se ejecute.
Así que la forma más correcta y recomendada, a no ser que tengáis un caso de uso muy específico,
sería utilizar el defer, incluso mejor que la sync, porque la sync es bastante peligroso.
Peligroso en el sentido de que la sync tiene la ventaja de que, es verdad, que lo hace en paralelo,
pero en cuanto se descarga el JavaScript, lo ejecuta, incluso aunque no haya terminado de parsear el HTML,
lo cual es bastante peligroso porque quizás dependes de algún elemento que haya en mitad de tu HTML
y además es como que está parando ese trabajo.
Así que esta sería mi recomendación, que utilicéis el defer y os quitáis un montón de problemas.
Mira, aquí también lo vais a ver bastante más claro, que también tiene bastante sentido,
porque es que el problema es este, que no vamos a querer pausar el parseo del HTML nunca,
porque es lo más importante para el usuario, para ver el HTML.
En cambio es el defer, fijaos que el fetch lo hace en paralelo, perfecto, fijaos que en el asíncrono no,
cuando haces el fetch se pausa el parseo del HTML, entonces mal asunto.
Y aquí con el defer, pues haces el fetch y lo ejecutas una vez que ya esté parseado y ya está,
lo tendrías sin ningún tipo de problema.
Muy bien, pues nada, vamos con ello.
Ahora, ah, lo de los modos.
Cuando veáis cualquier juego, cuando tengáis que desarrollar cualquier juego,
lo que tenéis que pensar, ¿vale? Es los modos que tiene el juego.
Modos, ¿qué quiere decir? Como los estados.
Por ejemplo, esto sería el estado ready, en el que te aparece lo del start y tal.
Este sería el estado jugando, en el que ya está jugando y aquí, pues hay unos eventos.
Luego tendríamos el estado de cuando le doy un click, pasa algo, ¿no?
Que es que hace el movimiento.
Y luego tendríamos el estado de game over.
Aquí tendríamos cuatro estados.
El de ready, jugando, jugado, jugada el movimiento y el game over.
Serían como cuatro estados.
O modos.
Yo me gusta más llamarle modos, pero bueno, le podéis llamar estados del juego.
En este caso nosotros vamos a tener solo tres.
Vamos a tener el de fall, que sería como cuando baja la pieza.
Vamos a tener el de bounce, que sería como cuando estamos jugando.
El bounce es que va de lado a lado, ¿no?
Fijaos que cuando jugáis va como de lado a lado la pieza.
Esto le vamos a llamar bounce, porque es como lo que hace, ¿no?
Es como ir de lado a lado.
Y vamos a tener el game over.
Que el game over lo que haríamos es empezar de nuevo.
O sea, nos aparecería el game over y ya está.
Vamos a necesitar algunas constantes importantes.
Por ejemplo, ¿cuál es el tamaño inicial que tienen las cajas?
Vamos a poner 200 píxeles.
Teniendo en cuenta que tenemos un width de 320, pues 200 es bastante grande.
Y luego le iremos haciendo cada vez más pequeñito.
Y luego le tenemos que decir cuál es la posición inicial de la caja.
Vamos a poner 600, que esté bastante arriba, aunque luego ya lo moveremos.
Vamos a poner cuál es la altura que tienen las cajas para dibujarlas.
Vamos a poner 50.
Si es mucho, luego lo hacemos un poco más pequeño.
Y luego la velocidad que va a tener tanto de caída.
Vamos a poner de caída como lateral.
Porque si os fijáis en el juego, vais a ver que conforme vais jugando, cada vez el juego va más rápido.
Va aumentando la velocidad.
Bueno, no de la caída, porque la caída, claro, como está tan cerca, igual lo podríamos hacer que esté más cerca.
Pero claro, creo que así le quita...
Claro, en 3D puede tener sentido.
Nosotros haremos que esté un poco más lejos para darle más dificultad.
Pero bueno, el juego cada vez tiene un poquito más de velocidad y además de dificultad porque se te va cayendo trozos.
Eso también lo haremos.
Y luego, estos serían las constantes y luego tendríamos como el estado.
Vamos a poner aquí.
Y aquí tendríamos el estado del juego.
Siempre, ya habréis visto que hemos hecho un montón de juegos con puramente JavaScript.
Y esto es que se repite tener constantes, luego el estado.
Y en el estado vamos a tener ahí unas variables que vamos a tener, por ejemplo, vamos a tener el scroll counter.
Porque fijaos que conforme vas jugando, el scroll va subiendo para arriba.
Bueno, pues esto lo vamos a tener que hacer.
Que vaya subiendo el scroll para que se vayan viendo las piezas que jugamos.
Igual con la cámara la vamos a ir subiendo.
El current será cuál es la caja actual a la que estamos jugando.
Porque aquí, por ejemplo, será la cuarta, esta será la quinta, que es como la puntuación realmente.
Tendríamos el modo actual, que tendrá uno de estos valores, de las constantes.
Por ahora, el modo actual debería ser...
Bueno, podría ser undefined o podría ser bounce.
Como empezar directamente con el bounce, tendría sentido.
Y luego vamos a tener cuál es la velocidad actual, tanto de izquierda a derecha como a la hora de caer.
¿Vale?
Esto sería el estado.
Ahora lo veremos un poco cómo lo hacemos.
Y ahora todo este estado habría que inicializarlo.
Así que vamos a poner un initialize game o podríamos poner game state para que quede más claro.
Y vamos a empezar a inicializar todas las variables.
Por ejemplo, de las cajas vamos a empezar a tener una.
Nada más iniciar, si os fijáis, ya tiene una caja aquí.
Y cuando juegas te aparece una caja ahí arriba.
O sea que ya tenemos que empezar con una caja en algún sitio, la tenemos que dibujar.
Nosotros la vamos a poner al principio, vamos a poner canvas width partido entre dos.
Vamos a ponerlo, lo vamos a centrar.
Pero claro, esto, esta X no te lo va a centrar de que te lo va a poner justo en el centro.
Lo voy a poner y luego veremos cómo lo centramos correctamente.
Solo para que lo tengamos en cuenta.
Voy a poner en la posición inicial 200 por poner ahí cualquier posición.
Oye, ¿dónde vas?
Vale, el gato ahí cruzando.
Y vamos a poner que la anchura de la caja sea el initial box.
Porque al principio fijaos que la caja es exactamente igual de grande que la que hay abajo.
Pero le van cayendo trozos, se va haciendo cada vez más pequeña.
Por ahora el color, vamos a hacer que siempre sea blanco.
Aunque fijaos que aquí también van cambiando los colores.
También haremos lo de cambiar los colores.
Vamos a ver, vamos a poner aquí current.
Esto es la caja actual, vamos a empezar por la número uno.
El modo, vamos a poner que sea el modo del bounce, ¿vale?
Que es el modo inicial para estar jugando.
La velocidad, pues la velocidad inicial.
La velocidad de caída, la velocidad inicial.
La cámara, la cámara no la vamos a iniciar.
Vamos a scroll counter, vamos a poner en cero.
Y la cámara, es que pone...
No, cámara vamos a ponerlo en cero también, ¿vale?
Y luego veremos cuando lo movamos, como lo iteramos esto.
Esto sería para inicializar ya nuestro juego.
Pero obviamente estamos inicializando todas las variables, pero no se ve absolutamente nada.
Vamos a dibujarlo.
Para empezar a dibujarlo, vamos a tener que reiniciar.
Bueno, a ver, podríamos llamar directamente el initializeGameState, así, directamente, de una.
Pero vamos a crear una función restart que también nos servirá como para reinicializar el juego.
Y que también lo llamaremos para empezar a dibujar el juego.
Entonces así, cuando tengamos el game over, volvemos a llamar al restart este.
Y ya está.
Así que llamamos a este restart.
Y también cuando hagamos el game over, llamaremos a esto.
Y ahora solo nos faltaría, pues, empezar a pintar.
Vamos a hacer function draw.
Si es game over, pues vamos a parar, ¿vale?
O sea, si por lo que sea hemos terminado, pues no seguimos pintando ningún movimiento ni nada.
Vamos a pintar el background, aunque ya os digo que el background en este caso va a ser totalmente oscuro, igual que está ahora.
Pero lo vamos a pintar por si el día de mañana queremos hacer algo o en el game over lo podríamos poner de color rojo o lo que sea.
Y esta función draw, lo importante es que la vamos a estar llamando constantemente.
Esto es lo que pasa con todos los juegos.
Todos los juegos que hemos hecho en JavaScript 100, si veis, hay un patrón.
Y el patrón es que vamos a querer constantemente reflejar los cambios.
Tanto en el Tetris, como en el Arkanoid, como en todos los juegos que hacemos, siempre es lo mismo.
Siempre hay que llamar constantemente.
Es como un loop infinito.
No es exactamente un loop infinito, ¿no?
Porque al final es que es la función que se llama a sí misma en cuanto acaba.
O sea, lo que estamos haciendo aquí es decir, oye, dibújate.
Y en la función de dibujar lo que hacemos es que cuando termine de dibujarlo todo le decimos, vale,
le vamos a decir al window que cuando esté disponible el siguiente frame vuelva a llamar al draw.
Entonces, no es tanto como un loop infinito, pero sí que es como una cola de eventos infinita
en la que cuando termina la función se vuelve a llamar a sí misma para dibujar en el siguiente frame.
Y así constantemente.
Y esto lo que va a conseguir es que estemos constantemente representando cómo han ido cambiando las variables.
Porque si la caja, nosotros cambiamos nuestro estado que tenemos aquí, cuando cambiemos este estado,
cuando se vuelva a llamar el draw, se reflejará diferente en la pantalla.
Que esa es la clave.
Así que vamos a dibujar ya lo primero.
Vamos a el background.
Esto fácil.
En el contexto que tenemos del canvas en 2D, le podéis poner en hexadecimal.
A mí me gusta muchas veces ponerlo así porque lo veo como más claro.
Y vamos a crear, pues, un rectángulo del 0 al 0.
Estas son las posiciones X e Y.
Y le tengo que decir el ancho, que va a ser el ancho de todo el canvas.
Y la altura de todo el canvas.
Aquí, pues, le podremos cambiar esto.
Y ya veis que se queda todo en amarillo, en rojo.
Aquí lo que estamos haciendo es dibujar simplemente el fondo.
Aquí lo interesante es que incluso le podéis poner un RGBA.
Y si queréis, pues, podéis decirle, vale, pues, quiero que sea de color como rojo.
Esto para el game over puede quedar bastante bien.
Así que por ahora lo vamos a hacer así.
Lo pongamos en negro.
Y luego en el game over, pues, lo pintaremos también.
Y ahora lo que nos falta es lo más importante, que es dibujar las cajas.
Para dibujar las cajas, lo que vamos a hacer es iterar sobre la variable boxes.
Ahora mismo es un array donde solo tenemos una.
Pero fijaos que en el juego, constantemente, claro, tú vas jugando.
Y aquí se van apilando constantemente cajas, ¿no?
Vas teniendo una caja, otra caja, otra caja.
Vas teniendo cajas, ¿no?
Y estas cajas las tienes que guardar.
Tienes que guardar el estado de cada una, cómo han quedado, su posición y todo esto.
Que esto es lo que estamos haciendo aquí.
Aunque ahora es solo con la inicial.
Pero esta la tenemos que pintar.
Y conforme se van añadiendo aquí, las vamos a tener que ir pintando todas.
Así que vamos a tener que iterarlo aquí con un for each.
Hacemos boxes, for each.
Que para cada caja, yo creo que no necesitamos el índice.
Vamos a recuperar para cada caja la X, la Y, el ancho, el color, ¿vale?
Del box.
Aquí deberíamos indicarle cuál es la posición donde deberíamos dibujar la caja en la Y.
Porque la Y no lo vamos a dibujarlo.
Pero fijaos que la posición Y, claro, primero está arriba, pero luego se queda ahí para siempre.
Entonces, tenemos que indicarle qué posición en la que se debe quedar.
Así que, por ahora voy a poner new Y y simplemente voy a poner initial box Y.
Luego veremos que esto lo tenemos que cambiar, ¿vale?
Porque, de hecho, la posición inicial, que es esta que pusimos, que era 600, tendríamos que tener en cuenta también, tendríamos que restarle la posición de la propia caja.
Para que esa diferencia haga que se quede ahí.
Vamos por ahora a dejarlo así para ver cómo funcionaría.
Y luego lo cambiamos.
¿Por qué entiendo?
Pero cuando soy yo el que quiera hacer algo, me quedo bloqueado.
Bueno, porque hay que practicar mucho.
¿Alguien me puede recomendar cómo mejora mi lógica de programación?
Pues justamente haciendo ejercicios como el que estamos haciendo ahora, porque tiene un montón de lógica de programación.
No es poco óptimo tener que pintar constantemente.
Ah, ¿y cómo lo harías entonces?
¿Cómo harías, Joaquín, en un videojuego, en cualquier videojuego, cómo harías para reflejar todos los cambios en la pantalla?
Como, por ejemplo, cuando ha cambiado tu vida, si te ha herido un jugador, si está en el escenario y al final hay otra cosa.
Es bastante complicado.
Sí que se pueden hacer a veces, a veces, se pueden cambiar cosas con observables, ¿no?
Por ejemplo, la puntuación, en lugar de pintarlo todo constantemente.
Pero en los videojuegos realmente es muy complicado.
Realmente se suele pintar frame a frame constantemente porque reflejar todos los cambios, por ejemplo, cuando el jugador se mueve.
Tú mueves la cámara del jugador, ¿qué haces?
¿Qué repintas?
Es que lo tienes que repintar todo.
Es muy complicado.
Y con juegos de este estilo, realmente, muchas veces, aunque parezca mentira, como el que estamos haciendo ahora,
suele ser mucho más interesante repintarlo todo que intentar repintar solo la parte que ha cambiado
porque es mucho, pero que mucho más complicado, mucho más difícil y no es tan performante como pensamos.
Muchas veces es más fácil como repintar todo el canvas, como limpiarlo y repintarlo entero
que no el hecho de intentar hacer cambios como granulares porque es mucho, mucho más difícil.
No es por nada que los juegos exigen tarjeta gráfica.
No, claro, totalmente.
Ahí está.
Todo esto me trae más recuerdo un semestre de la uni donde tuve que hacerlo como proyecto.
Ni siquiera me acuerdo cómo lo hice.
El HUD se puede cambiar solo, pero todo lo demás se repinta todo.
Las optimizaciones se hacen sobre procesado antes de volver a pintar.
Claro, totalmente.
Por eso, el HUD, que es lo que comentaba, eso lo podríamos hacer,
pero es que el resto del juego lo tienes muy complicado.
Y en estas cosas que, por ejemplo, va a haber una pieza que se va a estar moviendo,
es como bastante difícil.
Ahora, muchas tarjetas gráficas lo que sí que tienen son optimizaciones del repintado por su parte.
No tanto en el código, sino por su parte.
¿Te has quedado dormido?
La madre que te parió.
A ver, quédate ahí.
Voy a intentar que no se me caiga.
Luego están las técnicas tipo framebuffer.
Ahí está.
Ahí lo tenías.
¿Ese for each podría ser un map?
No, no podría ser un map.
Y, de hecho, te corto una mano como hagas un map.
Porque no.
Esto no puede ser un map, y no porque simplemente sea más corto,
porque realmente el map devuelve un nuevo array.
Y si vas a...
No, necesitas el nuevo array, pues no utilices el map.
Porque en realidad te va a ir más lento sin ninguna necesidad.
Entonces, si el map devuelve un nuevo array y no estamos utilizando el nuevo array,
¿por qué ibas a utilizar un map?
Y eso es un error muy, muy, muy común que veo un montón de veces
de gente que utiliza aquí el map.
Que funcionarles funciona, pero que, claro, no tiene sentido,
porque realmente no estás utilizando el array nuevo.
Así que no.
Podrías utilizar un for, podéis utilizar un while,
podrías utilizar este tipo de cosas, pero no utilicéis un map, por favor.
Entonces, vamos a restarle la posición de la caja que comentábamos antes.
Y vamos a poner aquí que la caja se pinte con el color,
que por ahora va a ser todo blanco, como hemos visto antes.
Y vamos a rellenar esta caja.
Le decimos las posiciones, con la nueva i, con el width.
Y esta es siempre la altura que es fija.
Vale, fijaos dónde está la caja.
¿Esto por qué aparece ahí?
Aparece ahí por diferentes motivos.
Ya veis en initial box, ya le hemos dicho aquí,
dónde nos tenía que pintar la caja.
Nos está restando la posición que tenía ya la caja por sí misma.
Hasta aquí bien, pero me lo está dejando justo, justo, justo en el centro.
Eso es porque aquí, cuando os he dicho de que si hacéis esto,
el problema es que la x es la posición inicial de pintado.
Claro, y la posición inicial de pintado le estamos diciendo que es justo en el medio.
Lo que necesitamos aquí, y esto es lógica de programación,
porque tienes que hacer un cálculo y tienes que pensar en ello desde el palo.
Oye, si le digo que la mitad es el inicio del pintado,
¿cómo podría hacer que el objeto quede realmente en el centro?
Lo que tendríamos que hacer para eso sería restarle la mitad del propio ancho de la caja.
Y con esto conseguimos que se centre.
Esto, que es una tontería, que parece una tontería,
mucha gente le cuesta la vida.
Porque tenemos la x es la posición inicial de pintado.
Y a partir de ahí tendría todo el ancho que pintar.
Si queremos que quede realmente el elemento en el centro,
tenemos que restarle la mitad del ancho del elemento.
Entonces, a esta posición, que es la que ya hemos visto que había,
le restamos la mitad del ancho de la caja,
y ahora sí lo tendríamos justamente en el centro.
¿Vale? ¿Se han tendido?
Porque esto parece una tontería, pero es súper importante.
Y es algo que se repite mucho y que incluso en CSS se puede hacer.
¿Es por el anchor? No es por el anchor.
Es porque la x, la posición x,
es simplemente la posición inicial de pintado.
Por lo tanto, la posición inicial de pintado,
bueno, es que claro, puede ser que sea el anchor.
Si lo queréis entender como anchor,
es que es verdad que el anchor es como le llaman en algunos motores de videojuegos.
Pero es que aquí no es que se llame anchor.
Es que simplemente la coordenada x es donde se empieza a pintar.
Ya está.
No se le llama anchor en este caso.
En CSS también se utiliza un montón.
Y aquí esto no hace falta utilizar paréntesis
porque tenéis que este matemáticamente tiene más prioridad las divisiones.
Por lo tanto, primero se hace esta operación
a la vez que se hace esta operación y luego se hace la resta.
Así que no hace falta que hagáis,
que si queréis lo podéis utilizar,
si os apetece para que quede más claro,
podéis hacer esto, pero sería exactamente lo mismo.
Así que ahí tenéis un poquito de lógica de programación,
que muchas veces me decís,
oh, lógica de programación, pues ahí lo tenéis.
Este tipo de lógicas que hay que estar repitiendo,
calculando y tal, son bastante importantes
para realmente hacer cositas.
Vale, entonces, claro, tenemos aquí el inicio.
Vemos aquí nuestro, como el primer box,
pero nos faltaría el de arriba con el que vamos a estar jugando.
Así que para crear cajas o box, como le queráis llamar,
vamos a crear una función que le vamos a llamar create new box.
Simplemente lo que vamos a hacer aquí es que vamos a tener boxes current,
¿vale?
Y vamos a crear la nueva caja.
Vamos a ponerle cuál es la X.
En este caso vamos a poner, vamos a hacer lo mismo,
vamos a centrarlo, o sea que vamos a hacer lo mismo,
la misma operación, la X,
porque esta aparecerá aquí arriba
y queremos que al inicio empiece la X.
Podemos hacer que empiece a la izquierda,
podemos hacer mil millones de historias,
pero vamos a hacer que quede centrado al principio
y luego ya haremos que se mueva.
Como queremos que quede bastante arriba,
le voy a poner que la posición Y sea 200,
el tamaño siempre es el mismo,
la caja va a ser esta, la de initial box width,
porque al inicio va a tener esto,
aunque luego vamos a ver que esto lo cambiaremos
para que vaya haciéndose cada vez más pequeño.
Vamos a poner que el color white,
de hecho estoy pensando,
vamos a hacerlo de otra forma,
vamos a hacer que empiece a la izquierda,
¿vale?
Para que no quede en centro,
vamos a hacer que quede a la izquierda.
En la Y, en lugar de ponerle 200,
vamos a hacer,
bueno, voy a empezar por,
no, 200 no,
porque 200 si no quedará muy arriba.
Vamos a hacer que,
estoy pensando,
la altura de la caja la tenía por aquí,
el box height,
esto es 50.
Vamos a poner 50 por ahora.
Ahora si no,
hacemos un cálculo ahí chulo.
Y este cálculo que habíamos hecho,
vamos a utilizar el ancho de la caja anterior,
porque fijaos que aquí lo que hace
es que cuando tú te caes aquí,
o sea,
cuando lo dejas aquí,
fijaos que la pieza de arriba
tiene el mismo tamaño
que la posición,
o sea,
el elemento anterior,
¿vale?
Es el mismo tamaño.
Por lo tanto,
lo que vamos a hacer aquí en el width,
en lugar de utilizar ya siempre el mismo,
el mismo ancho,
vamos a utilizar,
vamos a utilizar de las cajas
la posición anterior,
el ancho,
¿vale?
Y ahora al principio
siempre será el mismo ancho,
porque siempre tiene el mismo ancho,
pero luego,
cuando modifiquemos los anchos constantemente,
veremos que realmente
sí que vemos la caja
con un ancho inferior,
¿vale?
Y vamos a hacer que cuando inicializamos el juego
ya metemos nuestra primera caja,
¿vale?
Nuestra primera caja veo que no se está pintando,
¿por qué?
¿Por qué?
A ver,
x,
0,
width,
a ver,
esto está bien,
no sé si,
no sé,
no sé,
a ver si nos está fallando algo,
a ver si nos está apretando algo,
no nos está apretando nada,
a ver,
books,
boxes,
current,
el current lo habíamos puesto bien,
porque,
current había puesto aquí que empezaba en 1,
¿vale?
Y aquí,
draw boxes,
current,
el draw boxes ya lo estamos llamando aquí,
o sea que aquí sí que lo estamos teniendo,
vamos a ver aquí cuando se llama,
esto ahora va a parecer como un loop infinito,
¿vale?
pero ahí tenemos los dos,
vale,
tenemos la x en 0 y y en 0 y si no en 200,
o sea,
¿por qué no veo este?
A ver,
alguna cosa se me ha escapado ahí,
alguna cosa se me ha escapado ahí,
a ver si lo veis,
¿la llamaste?
Llámala papi,
sí,
no,
la estoy llamando,
la estoy llamando aquí,
cuando inicializamos el juego,
la estoy llamando una vez aquí,
create new,
ay,
create new box,
o sea,
estamos llamando para que nos cree el primero,
¿no?
El primero de initialize game state,
cuando inicializamos el juego,
lo que quiero que me lo cree aquí,
¿vale?
Y el color,
claro,
es que me lo está poniendo en el mismo sitio,
ah,
claro,
es que puede ser que esto me lo esté dejando en el mismo sitio,
¿no?
O sea,
me lo está poniendo uno encima del otro,
me lo está poniendo encima del otro,
¿puede ser?
A ver,
creo que sí,
me lo está dejando uno encima del otro,
y aquí,
en la initial box,
este,
por ejemplo,
el problema es que me lo está dejando seguramente uno encima del otro,
aunque aquí,
si le estoy cambiando esto,
¿sabes?
Si le estoy poniendo,
si le estoy restando 100,
a ver,
200,
ah,
claro,
ahí está,
¿vale?
Ahí está,
ahí está,
ahí está,
ahí está.
Sí,
el tema es que,
si está restando initial box i,
que es 600,
menos 100,
¿vale?
Esto de aquí,
pues ya vemos que ahí me está dando el problema.
Entonces,
no sé si poner aquí,
box,
claro,
lo que podríamos hacer,
lo que podríamos hacer es que conforme,
que cada vez sea un poquito más complicado,
o sea,
podríamos poner,
current más 10,
por box height,
¿vale?
Y entonces,
podríamos hacer que cada vez fuese un pelín más complicado,
el hecho de que se vaya alejando un poquito,
y así cada vez sea más,
más difícil atinar donde tiene que,
se tiene que apilar,
¿vale?
Pero esta sería un poco la idea.
Ahora miraremos un poco cómo funciona.
El tema es que esto lo tenemos que mover,
¿vale?
Porque es la gracia,
que se mueva,
si no,
pues no queda,
se ha caído,
estaba durmiendo y se ha caído,
pobrecito.
¡Ay!
Y el midugato,
está un poco torpe el pobre.
Vale,
ahora vamos a hacer que se mueva.
Entonces,
para eso,
aquí cuando estamos dibujando,
vamos a ver que si el modo de juego es el bounce,
o sea,
que se tenga que mover de izquierda a derecha,
vamos a llamar la función de move and detect collision,
¿vale?
Me parece bien el nombre este.
Nos vamos a ir por aquí,
y vamos a empezar a hacer que esto ya empieza a ser un juego de verdad,
con un poco de movimiento.
Vale,
esto está mal,
menos mal que no hay que hacerle caso a,
no hay que hacerle caso a,
a Gijacopailo porque se inventan las cosas.
Vamos a recuperar la caja actual,
que es con la que estamos jugando,
¿vale?
Esta caja,
el current box,
sería esta de aquí.
Ahora,
vamos a hacer que tenga un poquito de velocidad,
¿vale?
¡Ojo!
Ya se está moviendo,
¿vale?
Lo malo es que no vemos,
no se está chocando,
que es lo que debería hacer.
Pero fijaos,
ya se está moviendo y tal.
Podríamos hacer,
el tema de las colisiones,
no es para nada difícil.
Y aquí tenemos más lógica de programación.
Luego,
¿cómo practico la lógica de programación?
Pues aquí la tienes,
aquí la tienes.
El tema es,
Midu está registrando la animation callback dentro del mismo callback del draw.
Y está bien,
¿no?
¿Cuál es el problema de eso?
Claro,
no hay ningún problema,
Q15,
entonces,
¿cómo lo ibas a hacer si no?
O sea,
cuando llamas al draw y termina,
el tema es que el siguiente frame vuelva a llamarse.
Lo he explicado antes,
¿no?
Que tendría que ser necesario.
Después decían que saber matemáticas no es necesario.
¿Pero qué matemáticas hemos utilizado?
Dios mío.
Pues si,
estos son matemáticas.
Madre mía.
Bueno,
vale,
vamos con ello.
El tema es que ahora se está moviendo,
pero llega ahí y no choca.
Mirad,
esto es un tema de lógica que ocurre constantemente.
¿Qué es?
Primero,
hay que mirar si se está moviendo para la derecha.
Entonces,
si la velocidad es positiva,
pues tal.
Si es negativa,
probando el sistema de bits.
Para la izquierda.
Hombre,
gracias.
Esto para saber hacia dónde se está moviendo,
¿no?
Si se está moviendo para la derecha o para la izquierda,
dependiendo si la velocidad es positiva o negativa.
Luego,
lo que tenemos que mirar es si ha chocado con la derecha o con la izquierda.
Sabremos que has hit right side,
¿vale?
Cuando sabemos si ha chocado con la derecha.
Lo sabremos si la caja actual,
la posición X más su ancho,
es mayor al ancho del canvas.
Y lo mismo tendríamos con el left side,
pero más fácil todavía.
Porque si la posición X es más pequeña que cero,
pues ya sabemos que se ha chocado.
Y una vez que habéis hecho esto,
miramos.
Vale,
si se está moviendo a la derecha,
y además ha chocado con la derecha,
pues significa que hemos tenido,
o sea,
que ha hecho colisión.
o si se está moviendo a la izquierda y ha chocado con la izquierda.
Porque no se puede estar moviendo para la derecha y chocarse con la izquierda.
No tiene sentido.
Y una vez que ocurre esto,
podéis hacer esto,
que es básicamente cambiarle la velocidad.
Le estáis cambiando la velocidad.
Esto lo podéis hacer de diferentes formas.
Una puede ser con una multiplicación.
Lo podéis hacer así.
O podéis hacer cambiándole el signo.
¿Vale?
Que esto se puede ver un poquito más claro.
Yo creo que esto es un poco más claro.
Pero si lo queréis,
la forma más corta sería multiplicación por menos uno.
¿Vale?
Hacer la multiplicación y la asignación de X speed por menos uno.
Pero si os gusta verlo así,
pues podéis hacer la asignación simplemente cambiándole el signo de X speed.
De forma que si es negativo,
al cambiarle el signo a negativo,
pasará a ser positivo y si es positivo, a negativo.
Esto es muy típico en un montón de juegos,
en temas de colisiones,
cuando llegáis a cualquier,
pues al final de cada una de las pantallas.
¿Vale?
Ahora que ya tenemos esto,
de que se vaya a izquierda a derecha,
nos falta la caída.
O sea, el poder darle,
cuando estamos aquí en el juego,
lo que...
Aquí.
Cuando estamos aquí en el juego,
aquí es porque está como a ras.
Que puede ser...
No es mala idea,
que esté a ras.
Lo podríamos hacer.
Por ahora lo voy a hacer que esté bastante arriba,
porque me parece como más divertido.
Porque tienes que tener más ojos,
¿sabes?
Todavía.
Y como que aquí es más lento empezar a ir perdiendo y tal.
Pero el tema es que cuando le dais al espacio,
debería caer para abajo y ver hacia dónde se ha quedado.
Bueno, pues vamos a hacer un atvListener con el keyDown.
Vamos a tener aquí la función que queremos ejecutar
con nuestro evento.
y si el evento.keyCode es igual a space
y el modo en el que estamos.
Importante siempre mirar el modo,
porque si estamos en Game Over,
esto no tiene que funcionar.
Si no, la liamos parda.
¿Vale?
Si estamos en el bounce,
como que estamos jugando,
vamos a pasar el modo,
lo vamos a cambiar a modo caída.
Todavía ahora, pues no pasa nada,
porque le estoy dando el espacio,
no ocurre nada,
pero ya al cambiar solo este modo...
¿Qué pasa con la cámara?
No se ve, ¿cómo que no se ve?
¡Hostia!
¿Cómo que no se ve?
El mido y la cámara colisiona con el juego.
¡Ah!
¡Joder!
Bueno, perdón, perdón.
Es verdad.
Es verdad.
Bueno, más o menos.
Ya digo, hostia,
pero si yo lo veo ahí perfectamente.
A ver,
vamos a hacer esto un poco más pequeño.
Ahí lo tenéis.
A ver si así...
Es que, claro,
no sé dónde ponerme.
Bueno,
me puedo poner aquí en medio.
Ahí ya está.
Ahí ya está.
Ahora, ahora, ahora.
Vale, pues es esto, ¿vale?
Es el evento del keycode,
es el espacio,
y el modo,
si es bounce,
entonces lo cambiamos a modo caída, ¿vale?
Y entonces ahora,
ahí lo tenemos,
que como podemos cambiar el estado,
o sea, el modo de juego,
podemos irnos para aquí,
aquí, modo,
el modo bounce, ¿vale?
Y aquí,
en el cambio este que hacemos aquí,
del modo bounce,
lo que vamos a hacer es,
vale, pues si el modo no es bounce
y es modo es fall,
vamos a ver,
vamos a actualizar el modo de caída,
¿vale?
Esta función es la que vamos a crear ahora
y es la que nos va a ayudar,
pues básicamente hacer que caiga nuestra pieza para abajo.
Recuperamos la caja actual,
que es la que se ve arriba,
que está dando vueltas,
y ahora vamos a hacer que,
¿esto por qué me lo ha puesto en un modo HTML super raro?
Vale,
recuperamos la caja actual,
vamos a hacer que caiga de forma vertical,
y para eso,
hay que ir restándole la velocidad vertical,
¿vale?
Ahora,
update for mode,
vale, todavía no me lo hace,
¿por qué?
¿Por qué no me lo hace todavía?
¿Por qué?
¿Por qué esto no me lo hace?
Ajá,
¿por qué no me lo hace?
¿Por qué no me...?
¿Por qué no esto no lo...?
A ver si esto me está dando algún problema.
¿Caer debería caer?
Era solo cuando muestras el juego XD.
Ya,
cuando muestro el juego.
Ah,
cuando muestraba el otro juego.
Vale,
vale,
pensaba que era el código.
Vale,
vale,
tienes razón.
O sea,
estaba justo en medio,
¿eh?
Estaba justo,
justo en medio.
Vale,
¿por qué esto no me actualiza el movimiento mode fall?
Vale,
vamos a ver que esto aquí está entrando perfectamente,
¿vale?
Vamos a poner el mode,
esto,
en el else if,
esto lo hemos puesto bien,
correctamente,
en el draw,
dice si el modo es fall,
¿vale?
Aquí es update for mode,
¿vale?
Esto por aquí debería estar,
no está,
vale,
esto es el keycode seguramente,
que la he liado,
que no sé por qué,
event keycode,
a ver,
documental de listener keydown,
vale,
ah,
es 32,
la madre que me parió,
es que no es keycode,
es key,
key,
es que si utilizo key,
tengo que poner el espacio,
no es keycode,
es key,
ahora,
vale,
ahora sí,
vale,
vale,
vale,
vale,
perfecto,
bueno,
pues ya tenemos ahí el jueguecillo un poco,
¿vale?
Obviamente,
ahora nos faltan unas cosas,
por ejemplo,
vale,
voy a quitar aquí los console.log,
que había puesto,
el tema del keycode,
ahí me ha vuelto,
me ha vuelto loco,
vale,
update file mode,
ahí lo que estamos haciendo,
es que cuando le damos al espacio,
pues cae,
obviamente,
tendríamos que detectar,
dónde está esta caja,
para ver cuando ha hecho colisión también,
así que vamos a recuperar la posición,
de la caja previa,
así que de boxes,
current,
menos uno,
llamo la posición de la i,
más su altura,
vale,
y con esto,
ya podemos saber,
si la caja actual,
si es igual,
en algún momento,
a la posición previa,
de la caja,
de la caja anterior,
ahí es que hace hit,
y esto deberíamos verlo,
puede ser que más de una vez,
a ver,
vale,
una vez,
lo vemos una vez,
porque solo una vez,
pasa justo,
claro,
porque he puesto igual,
por eso es importante poner igual,
porque si hubiera puesto,
que fuese menor,
entonces veríamos que hace hit,
más de una vez,
pero con que lo haga una vez,
ya está bien,
claro,
ahora veréis,
que en cuanto pasa,
hace hit,
vale,
ahí estamos detectando esto,
y ahora lo que necesitaríamos,
es actualizar el stack,
así que,
a ver si tenéis alguna pregunta,
antes de continuar,
y me comentáis,
pone el código 32,
nada,
es que me gusta más,
con el keycode,
así que,
comentadme,
a ver si tenéis alguna pregunta,
en el full mode,
hay que parar el xspeed,
en realidad,
como puedes ver,
no vamos a tener el xspeed,
¿por qué?
porque,
cuando cambia el modo,
justo cambia el modo,
fíjate aquí en el draw,
que no hay que cambiar el speed,
porque en el draw,
que tenemos aquí,
solo en el move and detect collision,
es que se mueve horizontalmente,
como cambiamos el modo,
va a entrar a este update full mode,
y entonces ya solo va a utilizar la i,
¿sabes?
así que no necesitas hacer ningún tipo de cosa,
muy buenas,
estoy directo,
os ayudo un montón,
a entender javascript,
gracias programador,
se crearía otro box,
cada vez que colisione,
¿verdad?
e incrementar el current,
sí,
y eso lo vamos a hacer ahora,
justamente,
¿qué pasaría si el speed es alto?
no sucedería que el hit,
no se lograría,
ya que la posición,
se modifica bastante,
pero claro,
la posición,
se modifica,
uno a uno,
por lo tanto,
va a pasar sí o sí,
si la posición,
nos saltásemos valores,
de 5,5 o algo así,
pues entonces sí,
pero como el e-speed,
al final lo vamos a estar,
o sea,
está controlado,
no vamos a tener ningún tipo de problema,
vas a tener que poner una cámara en la caja,
ostras,
pues se pone idea,
rey,
¿qué cosa javascript recomiendas para aprender React?
cualquiera de los míos,
no invoquen de nuevo al miducat,
sí,
déjenlo descansar,
pobre,
vale,
ya tendríamos el tema este,
pero lo que necesitamos es actualizar el stack,
aquí cuando hacemos update,
fall mode,
aquí lo que deberíamos hacer,
es de alguna forma,
voy a hacer otra función,
lo vamos a llamar handlebox landing,
porque esto significa que ha hecho,
ha chocado,
y que por lo tanto tendríamos que fusionar o añadir una nueva caja,
así que vamos a poner handlebox landing,
cuando ocurre esto,
cuando ha llegado a chocar,
como ocurre aquí,
vale,
cuando choca,
lo primero que ocurre es que vuelve a jugar,
por lo tanto cambiamos el modo a modes bounce,
vale,
en cuanto choca,
vale,
pum,
bueno,
ahora cambiamos esto,
pero claro,
no hay que hacer eso,
lo tenemos que hacer con una nueva,
por eso lo que vamos a hacer,
es que además vamos a poner que el current box,
vamos a recuperar current box,
y el previous box,
vale,
previous box,
para comparar entre una y otra,
vale,
y vamos a ver la diferencia,
y esto es interesante,
aquí es donde vamos a tener que hacer la magia,
de calcular la diferencia,
entre lo que hay arriba y abajo,
o sea,
fijaos que aquí,
cuando por lo que sea,
dejas un espacio,
ahí detecta una diferencia,
y descarta la parte de la caja,
que no encaja con la de abajo,
esta cosa,
esta animación,
además de que se cae,
no la vamos a hacer en 3D,
pero la vamos a hacer,
o sea,
que es importante saber cuál es la diferencia,
y para eso,
primero vamos a recuperar la diferencia de la X,
como para saber la posición X,
qué diferencia hay entre la posición del de arriba,
con el de abajo,
o sea,
si yo lo doy aquí,
bueno,
espérate,
aquí,
ahí vemos que la X no es la misma,
vamos a ver qué diferencia hay entre las dos,
y luego lo que haremos,
es que dependiendo de si es por un lado,
o por el otro,
si es por la izquierda o por la derecha,
haremos un cálculo,
pero por ahora vamos a necesitar,
la diferencia,
entre la caja actual,
que sería la de arriba,
con la que tenemos abajo,
vale,
esta sería la diferencia,
si la diferencia,
si la diferencia que hemos creado,
aquí tendríamos ya el game over,
porque realmente,
si la diferencia en términos absolutos,
es más grande que el tamaño de la caja,
significa que ya está,
que hemos perdido,
porque claro,
si tenemos una diferencia,
que es más grande o igual,
que el tamaño de la caja,
por ejemplo,
aquí,
si yo la caja,
la he puesto,
en una diferencia que es más grande,
¿ves?
aquí la X,
la X era más grande,
que el tamaño completo,
no estaba dentro,
o sea,
la X no estaba,
en una posición,
dentro del tamaño de la caja anterior,
por lo tanto,
hemos perdido,
y eso lo estamos haciendo,
con esta diferencia,
cuando el término,
el valor absoluto,
de esa diferencia,
es mayor,
que el ancho,
de esa caja,
pues significa que,
directamente,
hemos perdido,
así que vamos a poner,
game over,
y a otra cosa,
hacemos un return,
no hace falta hacer nada más,
ahora,
si sí que,
por lo que sea,
sí que ha funcionado correctamente,
podemos continuar,
le vamos a cambiar esto,
podemos incrementar,
aquí esto para más del juego,
¿no?
Podemos incrementar la velocidad,
para hacer cada vez,
que sea un poquito más difícil,
así que,
vamos a mirar,
que si X speed,
es mayor a cero,
pues,
vamos a aumentarlo en uno,
o incrementarlo en menos uno,
esto dependerá,
de si vamos hacia la derecha,
o hacia la izquierda,
o sea,
para hacerlo un poquito más rápido,
pero dependiendo,
tenemos que tener en cuenta,
cuál es su orientación,
si va hacia la derecha,
será en positivo,
si va hacia la izquierda,
pues será en negativo,
así que esto,
lo tenemos que tener en cuenta,
luego,
también vamos a pasar a la siguiente caja,
por eso,
el current,
que es el número de caja,
en el que estamos trabajando,
que ahora mismo es uno,
cuando la dejemos abajo,
pasamos a la dos,
y así a la tres,
a la cuatro,
y es interesante,
porque el current,
no deja de ser la puntuación,
fijaos que aquí,
es cero,
uno,
¿no?
conforme vas poniendo,
en nuestro caso,
es verdad que hemos puesto ya,
como que es más,
o sea,
no empieza por cero,
empieza por uno,
pero sería eso,
¿no?
el número de cajas,
que tenemos en el stack,
así que en este caso,
como ya vamos a hacer,
que acabe abajo,
tenemos que incrementarlo,
¿no?
Y para,
podríamos mover aquí,
o tener en cuenta ya,
que tenemos que mover el scroll,
y lo tenemos que mover,
como,
la altura de la caja,
tendríamos que moverlo un poquito,
incrementándolo,
en la altura de la caja,
y además,
y finalmente,
tendríamos que crear,
una nueva caja,
así que,
create,
new box,
¿vale?
Así que,
ah,
bueno,
espérate,
que todavía no faltaría,
la caja esta actual,
pero bueno,
por ahora,
vamos a ver cómo funciona esto,
¿vale?
Ahí está,
vale,
ahí vemos que el problema,
es que,
¿cuál es el problema?
El problema es que,
fijaos,
que la caja,
la caja no se ve,
la siguiente,
¿por qué?
Porque,
habíamos puesto aquí,
que conforme,
claro,
que conforme la I,
conforme íbamos poniendo más abajo,
teníamos que ir subiéndolo arriba,
pero en realidad esto,
claro,
yo lo quería hacer en negativo,
como para,
pero claro,
no tiene mucho sentido,
porque al final,
si no,
¿no?
Al final,
si no,
no tiene mucha historia,
yo pensaba como para hacerlo más difícil,
pero claro,
a la mínima que lo vayamos subiendo,
como para hacerlo más difícil,
como empieza tan arriba,
podríamos ajustarlo y tal,
pero igualmente esto,
lo vamos a poder reutilizar,
para cuando movamos la cámara,
porque conforme,
vayamos apilando,
lo que vamos a hacer ahora,
es mover el scroll,
vamos a mover también la cámara,
¿vale?
Pero antes de hacer esto,
para que no quede esto tan blanco,
que me está poniendo un poco aburrido ya,
esto de ponerlo tan blanco,
voy a crear una función,
para hacer algo similar a lo que ellos tienen,
que vamos a poner,
create step color,
que básicamente nos cree,
que si el step es cero,
vamos a empezar con el white siempre,
pero luego vamos a tener,
que el red va a ser un math floor,
exacto,
ahí está,
perfecto,
vamos a ponerle colores random,
más que nada,
porque si no,
lo que va a pasar,
es que se van a repetir muy fácilmente,
y aquí,
cuando creemos una caja,
en el create new box,
en lugar de ponerle siempre el blanco,
vamos a poner esto,
que bueno,
ahora que lo veo,
bueno,
podríamos pasar el step aquí,
el current sería,
¿no?
no es el current,
create step color,
en el step,
ah,
porque aquí le tenemos que pasar el step,
vale,
entonces al menos,
ahora,
cada una sería diferente,
¿vale?
esto pasaría siempre,
que cada una que aparece es diferente,
que es algo parecido a lo que pasa aquí,
si os fijáis,
pues los colores que van saliendo,
son totalmente diferentes,
o sea,
son random,
puede ser que sean todos tono pastel,
eso se podría mirar,
para ajustarlo y tal,
pero son totalmente aleatorios,
porque cada vez que ejecutas,
pues si te fijas,
empieza con uno totalmente diferente,
no sé si tiene un diccionario,
pero bueno,
nosotros lo hacemos así,
que sea totalmente aleatorio,
y ya está,
vamos a hacerlo de mover la cámara,
porque tiene sentido,
que conforme vamos apilando,
de hecho,
este juego también lo hace,
que conforme cada vez que apila,
si os fijáis,
cada vez que apila,
como que sube un pelín para arriba,
¿vale?
esto mismo,
lo vamos a hacer también,
y es muy sencillo,
porque lo único que tenemos que hacer con esto,
vamos a crear una función,
que sea,
function update camera,
que lo que hace,
es que,
si el scroll counter,
es mayor a cero,
que esto debería ser,
porque lo incrementamos,
vamos a hacer que la cámara,
cámara,
sea más más,
y que el scroll counter,
sea menos,
ahora,
el tema es,
claro,
todavía tenemos que hacer otro cambio,
fijaos que ahora,
no está funcionando,
y esto es porque,
cuando lo hemos querido utilizar,
antes,
os he dicho,
hostia,
esto lo cambiaremos después,
en el draw box,
es este,
claro,
veis,
aquí teníamos,
que la nueva i,
es initial box,
menos i,
pero ahora tenemos que tener en cuenta,
también la cámara,
entonces,
vamos a incrementar,
con la posición de la cámara,
y ahora,
se supone,
que tampoco,
nos ha dejado fatal,
vale,
¿por qué no se mueve esto?
¿por qué no se nos mueve,
la cámara?
a ver,
el new i,
esto sí que está bien,
pero igualmente,
no sé,
en algún sitio,
en qué otro sitio,
tenía que cambiar,
porque lo he dicho,
baja la cámara,
no,
pero en otro sitio,
he dicho,
creo que nos estás llamando,
ay coño,
no estoy llamando la función,
es verdad,
tienes razón,
menos mal,
menos mal,
que me lo has comentado,
menos mal,
que me lo has comentado,
¿dónde tenemos que llamar?
en el draw,
menos mal,
que me lo has comentado,
sabía,
se me ha olvidado,
estaba pensando,
tanto en el otro,
de que no se me olvide,
que tengo que ponerlo ahí,
que no hemos puesto aquí,
claro,
lo tenemos que hacer,
cada vez que,
ahí está,
ahí está,
hostia,
hostia,
vale,
vale,
esto ya empieza a tener mejor pinta,
fijaos como se vuelve,
cada vez más loco,
vale,
vale,
obviamente,
una cosa,
es que,
ahora estoy jugando ahí,
en modo fácil,
porque,
la,
claro,
no se va haciendo cada vez más pequeño,
pero eso lo vamos a arreglar ahora,
vale,
y ahora ya sí que se va moviendo la cámara,
vale,
lo que vamos haciendo aquí,
es que se va moviendo la cámara,
cada vez se va haciendo más rápido,
vale,
cada vez que vamos jugando,
cada vez más rápida,
la,
el horizontal,
pero,
lo que nos faltaría es descartar,
la parte de la caja,
que no encaja,
vale,
así que eso lo vamos a hacer ahora,
ya hemos movido la cámara,
vamos a ajustar la caja,
para ajustar la caja,
vamos a hacer,
una cosita por aquí,
vale,
en el adjust,
no,
adjust,
no teníamos aquí un adjust,
a ver,
cuando estamos,
bueno,
claro,
todavía no tenemos un adjust,
vale,
todavía no tenemos un adjust,
por lo tanto,
vamos a tener que ajustar,
justo después,
aquí,
aquí,
vamos a llamar al adjust,
box exposition,
no,
adjust current box,
vale,
justamente antes,
esto lo que va a hacer,
es que al llamar a esta función,
va a revisar,
la diferencia,
de la caja,
y la va a recortar,
si sobra a la izquierda,
o la derecha,
vamos a hacer aquí un function,
adjust current box,
vamos a recuperar,
el current box,
vamos a recuperar,
uy,
eso se veía interesante,
la caja anterior,
current menos uno,
vamos a,
bueno,
básicamente,
primero,
deberíamos detectar,
mira,
más fácil que como lo había puesto Copilot,
tendríamos que decir,
vale,
vamos a ver,
si,
si,
la caja sobra,
por la derecha,
si sobra por la derecha,
significa,
que la x,
de la caja actual,
es mayor,
que de la,
que queda por debajo,
y esto significa,
que,
console.log,
sobra caja,
por la derecha,
y si no,
pues sobra caja,
por la izquierda,
vamos a mirar,
si esto tiene sentido,
en un momentito,
nos vamos aquí,
vamos acá,
ves,
sobra por la derecha,
ves,
ahora sobra por la izquierda,
pam,
vale,
entonces ya sabemos,
con esto,
y esto es lógica de programación,
esto sí que es lógica de programación,
o sea,
el hecho de entender,
que,
solo sabiendo,
la posición inicial x,
de la caja actual,
con la previa,
claro,
si la x,
la posición actual x,
que la posición x,
para que lo entendéis,
mira,
vamos a poner aquí,
un escalidro,
vamos a hacer un escalidro,
un momento,
pero básicamente,
el tema es,
que esto de aquí,
voy a hacer aquí esta,
hostia,
que mal la imagen,
pero aquí tendríamos,
la x,
la x,
joder,
la madre,
ah,
es que me lo está poniendo de color,
vale,
esta sería la posición x,
vale,
de esta caja,
y esta la posición x,
la podemos poner aquí,
porque es la misma,
x,
eh,
otra caja,
o caja,
o curren,
vale,
esta sea,
curren x,
mira,
lo voy a poner así,
curren x,
que creo que queda mejor,
de nombre,
curren x,
además lo ponemos así,
este sería el curren x,
vale,
curren x,
que sería,
esta posición exacta,
esta de aquí,
y esta sería,
el previous x,
previous x,
que sería exactamente,
esta posición de aquí,
vale,
por lo tanto,
si la x actual,
es mayor que la previa,
significa,
que sobra,
por la derecha,
o sea,
nos tenemos que,
quedar con este trozo,
y este es el trozo,
que le vamos a tener,
que,
que recortar,
cuál es,
cuál es el trozo,
que hay que recortar,
cuánto es lo que hay que recortar,
pues eso ya lo tenemos calculado,
porque lo hemos calculado antes,
que es la diferencia,
esta diferencia,
es la que hemos calculado,
se la podríamos pasar,
porque la diferencia,
es esta,
y esta,
no importa,
si va a ser,
por delante,
o por detrás,
lo que va a ser importante,
más bien,
es que,
si sobra,
como en este caso,
sobra por la derecha,
lo que vamos a tener que hacer,
es recortar,
esta parte de aquí,
por lo tanto,
lo que hacemos,
es que,
la caja actual,
su tamaño,
le vamos a restar,
la diferencia,
vale,
vamos a modificar,
la caja actual,
y le quitamos la diferencia,
claro,
lo que queremos es,
cortar por aquí,
no,
bueno,
lo he hecho un poco así,
pero bueno,
ya me entendéis,
por aquí,
hay que cortar por aquí,
y por lo tanto,
todo esto,
todo esto va afuera,
vale,
ese sería,
el caso de que sobre,
por la derecha,
el otro caso,
es un poquito más difícil,
no mucho más difícil,
pero tiene un poquito más de complejidad,
porque,
fíjate,
si sobra por la izquierda,
que este es el caso,
vamos a poner esto,
lo ponemos por aquí,
si sobra por la izquierda,
o sea,
que rabia,
ahora,
la madre que lo parió,
vale,
ahí está,
es que,
estoy intentando,
mover,
aquí,
vale,
mira,
voy a poner esto,
esto,
esto,
esto,
vale,
vale,
aquí tendríamos,
la actual x,
que esto va justamente aquí,
y el previous x,
que sería justamente aquí,
el previous x,
tened en cuenta,
que puede ser aquí,
o sea,
es todo donde empieza,
porque la x,
no tiene nada que ver con la y,
por lo tanto,
lo puedo poner aquí,
como que lo puedo poner aquí,
vale,
del bloque blanco,
la x empieza,
en toda esta parte,
o sea,
que es indiferente,
pero bueno,
lo dejo aquí,
un poco por referencia,
vale,
esto es que sobra por la izquierda,
por lo tanto,
lo que necesitamos,
es un poco más difícil,
porque no solo hay que recortar,
esto de aquí,
vale,
esto hay que recortarlo,
sí,
todo esto,
se va afuera,
pero,
el tema es que,
recortando esto de aquí,
aún así,
o sea,
eso sí que sería la diferencia,
o sea,
tendríamos que quitar,
pero claro,
¿cómo podríamos para que se quede?
Porque necesitamos que se quede ahí,
o sea,
no le podemos quitar,
o sea,
el tema es que visualmente,
sí que es esta parte,
pero no podemos hacer esta operación,
no podemos hacer menos,
quitarle al width,
no le podemos quitar la diferencia,
porque el width empieza por aquí,
entonces,
lo que vamos a hacer,
es diferente,
vamos a sumarle la diferencia,
y vamos a mover la caja,
vamos a hacer que ahora,
la x pase de aquí,
vale,
pase de este punto,
lo vamos a mover a aquí,
para que empiece a partir de ahí,
y con eso,
ahora sí,
si por ejemplo aquí,
le sumamos,
hacemos current box,
lo vamos a ver ahora,
a ver si funciona,
no os preocupéis,
esto es lo que tiene la lógica de programación,
que hay que ir probando,
pero ya entendéis que,
el tema es que,
ahora la x,
quitando esto,
tiene que empezar,
donde empieza la de abajo,
vale,
así que le vamos a quitar esto,
y vamos a utilizar,
la x de la caja,
cuando sobra por la izquierda,
y vamos a ver,
si solo con este cambio,
ha petado,
vale,
ha petado,
vamos a ver por qué ha petado,
porque obviamente,
no le ha gustado algo,
no le ha gustado,
difference is not defined,
vale,
porque no falta aquí,
vale,
eso,
con eso puedo vivir,
vale,
vale,
bueno,
pues ya lo tenemos,
o sea,
ahí lo tenemos,
¿no?
Fijaos,
que ahí se ve,
claro,
es verdad que,
el tema es,
como lo estamos,
a ver,
ahí,
claro,
que se queda,
porque es que le sobra,
claro,
todo lo demás le sobra,
todo lo demás se cae,
claro,
no se ve,
eso lo vamos a hacer ahora,
para que se vea lo que cae,
vale,
pero obviamente,
como sobra esa parte,
claro,
esta parte sobra,
y aquí,
pues no tiene que poner nada,
si sobra por la derecha,
lo mismo,
esa parte en la que sobra,
siempre tiene que ser que la parte que sobra,
eso vamos a hacer que se vea visualmente,
¿no?
pero ahí tenemos como la diferencia,
¿no?
que siempre vamos a estar apilando la parte,
solo la parte que realmente tiene sentido,
y ahí es donde está la parte del juego,
¿no?
Vale,
entonces,
hemos logrado esto,
con esto,
pero,
ahora lo que molaría,
sería mostrar la parte que sobra,
o sea,
porque si os fijáis,
lo que hace el efecto wow,
aquí en 3D,
es que cuando sobran aparte,
y le das,
se cae,
obviamente,
en 3D queda muy bonito,
no lo vamos a poder hacer en 3D,
pero sí que vamos a poder hacerlo,
de alguna forma,
que se vea bastante bonita,
para que se vea la parte que sobra,
vamos a necesitar esa diferencia,
que hemos calculado anteriormente,
y vamos a crear una nueva variable,
vamos a crear una nueva variable,
que sea como la de create new box,
create new box,
esta que hemos creado aquí,
pero lo vamos a hacer con un nuevo objeto,
que sea create new debris,
creo que se llama debris,
escombros,
perfecto,
me gusta,
para crear estos escombros,
que es la parte que sobra,
vamos a hacer lo mismo,
vamos a tener aquí el current box,
vamos a tener el current box,
vale,
aquí esto se le ha ido la olla totalmente,
obviamente,
esto no es lo que queremos hacer,
pero bueno,
se agradece el intento,
lo que vamos a querer es,
crear por aquí arriba,
vamos a crear una variable,
no sé si la habíamos creado antes,
no,
vale,
pues vamos a crear aquí,
debris,
que esto tenga,
va a ser un objeto directamente,
porque solo podemos mostrar un escombro a la vez,
que esto tenga la x,
la y,
la longitud,
y la altura,
que esto al final,
bueno,
la altura,
en realidad la altura siempre será la misma,
porque la altura sí que realmente,
debería ser la,
la altura que tenemos,
debería ser la del box,
este,
¿no?
o sea que el debris,
a ver,
lo voy a quitar,
porque ni siquiera lo necesitamos,
los tres,
porque siempre va a ser la misma,
lo más importante es la x,
la y,
y la,
y el ancho,
así que vamos a crear aquí en el estado,
este nuevo,
y ya está,
como lo tenemos aquí en el estado,
lo vamos a tener que reinicializar,
así que cuando inicializamos el juego,
además de los boxes,
vamos a reinicializarlo,
con los mismos valores,
vale,
con el cero,
esto es para cuando hagamos el reset del juego,
pues empezar en condiciones y que se vean los escombros,
vale,
inicializamos el juego,
vale,
inicializar game state,
perfecto,
vale,
y ahora cuando creamos el new debris,
lo que tenemos que hacer aquí,
ya tenemos el new box,
pero lo que tendríamos que hacer,
es que este objeto,
el debris,
tenga los valores correctos,
vale,
en este caso,
el,
cuando lo creamos,
¿dónde tiene que inicializarse?
La i se va a inicializar,
justamente en la caja actual,
o sea,
la posición de la i,
verticalmente,
donde está la posición actual,
luego,
el ancho que va a tener,
va a ser la diferencia,
la diferencia que hemos calculado antes,
se la podemos pasar por aquí,
y este create new debris,
lo vamos a tener que llamar,
junto a el adjust current box,
aquí,
vale,
así que llamamos el create new debris,
con la difference,
que por poco que sea,
pues algo,
algo será,
y si es cero,
pues no se verá nada,
y ya está,
¿vale?
Entonces ya tengo la diferencia,
y ahora,
lo más complicado realmente,
la x,
la x,
sería debris x,
porque esto sí que hay que calcularlo,
porque depende,
¿no?
Esto lo habíamos visto antes,
si es que sobra por la izquierda,
o sobra por la derecha,
es el mismo cálculo,
o sea,
podríamos ver,
que debris x,
sería,
si el current box x,
es mayor al previous box x,
significa que sobra por la derecha,
y por lo tanto,
la posición de la x,
sería,
la current box x,
más,
todo el ancho de la caja,
menos la diferencia,
¿vale?
Porque,
donde vamos a inicializar,
sería,
en este caso,
sería,
aquí,
¿vale?
aquí justamente,
es donde tendríamos que crear,
voy a poner en rojo,
no,
en rojo no puede ser,
en blanco,
¿vale?
Y esto lo vamos a poner un poco más así,
¿vale?
Justamente en este punto,
es donde deberíamos crear,
la posición x,
donde caerá,
este trozo,
entonces,
si,
sobra por la derecha,
¿cómo vamos a calcular la x?
Con,
el current x,
más,
todo el ancho,
que sería,
toda esta parte,
sería el width,
¿no?
Toda esta parte,
es el width,
esto sería el width,
el width,
el width del current box,
y luego,
la diferencia,
que sería,
esta parte de aquí,
esta parte de aquí,
esto de aquí,
sería la diferencia,
entonces,
esta diferencia,
que es este trozo,
así es como calculamos,
el nuevo x,
del debris,
y si es por el otro dado,
en realidad,
más fácil,
porque es,
la x,
menos la diferencia,
¿vale?
Y ya lo tendríamos,
el x,
menos la diferencia,
sería,
este caso de aquí,
claro,
es el current x,
sería,
sería,
no,
el current box,
claro,
el current box,
sí,
el current box,
el current box,
menos la diferencia,
porque ya habríamos actualizado,
entonces,
tendríamos justamente,
esta posición de aquí,
claro,
como lo hemos actualizado,
esto lo tenemos que hacer,
justamente,
después de hacer el ajuste,
claro,
justo después del ajuste,
porque si no,
la podemos liar,
pero con esto,
ya deberíamos tener,
pues los escombros,
¿vale?
Con esto,
ya estaríamos creando los escombros,
y lo que deberíamos hacer,
con los escombros,
estoy pensando,
cuando una vez que tenemos los escombros,
es pintarlos,
claro,
porque esto es el estado de los escombros,
a ver,
¿tenéis alguna pregunta,
amigos,
antes de que continúe,
para que,
esto es al revés,
que calcula el corte,
claro,
es al revés,
podríamos cambiar el orden de ejecución,
y guardar la posición,
pero bueno,
creo que no es muy importante,
¿no?
El debris es escombro,
es que,
creo que en inglés,
escombros,
en inglés,
a ver,
¿cómo se llama?
Es que se llama debris,
rubble,
bueno,
rubble también podría ser,
pero bueno,
el debris debería tener el mismo color,
que la current box,
sí que debería,
pero en este caso,
creo que lo vamos a poner de color rojo,
para que se vea bien,
¿vale?
Lo vamos a poner de color rojo,
y ya está.
Midu,
¿sí a la reacción del próximo Apple Iben?
Sí,
pero ¿lo han anunciado ya?
¿Lo han anunciado ya o no?
Normalmente tarda en anunciarlo,
no,
no han anunciado,
pero sí,
lo vamos a hacer seguro,
porque va a ser de,
van a ser,
aún no,
porque va a ser de los nuevos portátiles.
¿Vendrías presencial a la GSConf de Guadalajara?
¿México?
Sí,
si estoy anunciado,
voy a estar en México,
voy a estar en Medellín,
y voy a estar en San Francisco,
¿veis?
Estoy aquí.
Así que sí,
nos vemos allí en la GSConf de México,
que voy a estar por allí,
totalmente presencial,
¿eh?
Vale,
pues,
¿es posible hacerlo 3D como juego original,
solo con JavaScript?
Sí que se puede hacer,
a ver,
solo con JavaScript sí,
porque justamente el juego este del Stack Game,
está hecho solo con JavaScript,
con el 3GS,
así que sí,
se podría hacer sin ningún tipo de problema.
Si se ajusta el más random para evitar colores oscuros,
se podría hacer un montón de cosas,
de hecho,
le podría preguntar a ChatGPT,
para evitar los colores oscuros,
ningún problema.
Pero,
bueno,
en principio tampoco es muy grave,
y además puede ser parte de la dificultad,
¿no?
Puede ser parte de la dificultad.
Bueno,
vamos a dibujar los debris,
para que lo tengamos por ahí,
y lo podamos hacer.
La verdad es que podría ser interesante hacerlo con 3GS,
¿no?
Para hacer un curso de 3GS,
y hacerlo,
¿os animaríais?
¿Os gustaría que lo hiciéramos en 3D?
Porque lo bueno es que podríamos reutilizar muchas de las cosas que hemos hecho.
Pero podríamos hacer exactamente el mismo juego con 3GS,
y no debería ser muy complicado,
porque la lógica de la programación que hemos hecho hoy,
es exactamente muy parecida.
Es que,
por no decir que es la misma,
porque el hecho de que sea 3D,
realmente,
es un tema de visualización de la información que tenemos.
La información ya la tenemos,
no tiene mucha historia,
mucho más,
¿eh?
Si lo pasamos,
es verdad que tendríamos que crear los objetos y tal,
pero la información sería la misma,
porque el eje al final es una rotación,
y ya está,
ya lo tendríamos.
Así que la base sería.
Vale,
vamos a dibujar el debris,
porque es lo que nos falta.
Así que,
vamos a poner draw boxes,
draw boxes,
vale,
vamos a tener aquí,
function,
draw debris,
y aquí,
pues simplemente,
tenemos que recuperar la X,
la Y,
y la anchura de los escombros.
Vamos a,
la nueva Y de los escombros,
esto sí que es interesante,
¿no?
porque igual que pasa con las cajas,
la posición de la Y también cambia según la cámara,
por lo tanto,
sería la posición inicial de la caja,
sería el mismo cálculo,
menos la Y del debris,
más la cámara,
porque la cámara,
ya veis que la vamos moviendo,
para que vayan,
vayan apilándose las cajas.
Y ahora,
pues simplemente pintarlo,
podemos poner el color que sea de color rojo,
y vamos a pintar con fill rec,
le decimos la posición,
la posición de la X de la Y también,
el ancho,
y el tamaño,
ya os dije que iba a ser,
pues siempre el mismo,
que es la altura de la caja.
Y es verdad que con esto,
entiendo,
a ver una cosa,
si lo ponemos,
vale,
el draw debris,
debris,
lo tenemos que,
vamos a poner draw boxes,
¿dónde está con el draw boxes?
Vale,
aquí,
vamos a dibujar también los debris,
y aquí,
vale,
eh,
hostia,
pues la hemos liado,
¿veis?
Hemos liado ahí unas cuantas cosas,
ahora lo miramos,
vale,
hemos liado unas cuantas cosas,
porque,
el tema es,
que el debris,
también tendríamos que,
primero,
alguna posición no está bien,
alguna posición no está bien,
de las que he hecho,
¿veis?
Alguna posición no está bien,
no sé si es porque el cálculo este,
a ver,
el cálculo que hago del debris,
no sé si lo tenemos que hacer antes o después,
una cosa que es segura,
es que tendríamos que actualizar aquí,
el debris.y,
y restarle la velocidad para que baje,
esto seguro,
¿vale?
Vale,
tendríamos que hacer esto,
esto,
esto hay que hacerlo,
el problema que veo,
es que la posición no está bien,
o sea,
la posición de caída no está bien,
y la posición de caída no está bien,
seguramente,
porque lo hemos calculado mal,
en algún sitio,
cuando hemos hecho este,
no,
el draw debris no,
cuando hemos creado el debris,
create new debris,
este de aquí,
aquí,
este no lo estamos haciendo bien,
no estamos haciendo bien,
que se me escapa aquí,
coge la posición del buno y no del residuo,
del buno y no del residuo,
debris x,
current box,
la y sí que está bien,
o sea,
la y sí que funciona correctamente,
de eso no hay problema,
es la x,
¿veis?
está claro que es la x,
¿no?
Entonces,
esto,
hemos puesto que cuando x más,
es que estoy pensando,
si al final,
no será el previous box,
claro,
no sé,
claro,
en este caso es porque puede ser,
que lo esté calculando,
no,
tampoco,
fijaos que ahí tampoco,
lo está haciendo bien,
tampoco está haciendo bien,
porque está haciéndolo,
como,
es como que ya lo está calculando,
o sea,
ya lo estamos haciendo,
cuando,
a ver,
ahí sí,
claro,
esto es porque lo estamos haciendo justamente después,
después de recortar la,
la caja,
entonces,
claro,
como lo estamos haciendo después de recortar la página,
significa,
que ya no tenemos que hacer ningún cálculo de,
de las diferencias y tal,
y ahora sí que tendríamos,
oh,
ostras,
ahí se ha,
ahí ha penchado,
ahí se ha quedado penchado,
ah,
creo que el game over tiene algún error,
debe ser el game over,
creo que es el game over,
¿no?
Claro,
no es que tenga un error,
es que no estamos mostrando absolutamente nada con el game over,
pero vamos a,
vamos a hacer un game over en condiciones,
function,
game over,
vamos a hacer que,
el modo game over,
game over,
vamos a poner el modo,
vamos a poner lo que os decía del context.fillstyle,
que sea de color rojo,
vamos a dibujarlo todo,
eso,
vamos a poner,
con una fuente,
vamos a poner game over,
¿vale?
en el centro,
vale,
de color blanco,
en el centro,
y esto,
text game over,
y aquí la posición,
que sería,
en el centro,
del,
del canvas,
y con esto,
al menos,
mira,
ahí tenemos ya,
cuando no lo haces correctamente,
la parte que sobra,
cae,
¿vale?
y la parte,
si por lo que sea,
vamos aquí,
ahí tenemos game over,
y ya lo tendríamos,
ahora,
obviamente,
el único,
el último toquecito,
que deberíamos tener,
es que cuando,
vamos a ponerle,
al canvas,
un pointer down,
que cuando,
se haga click,
si,
el modo es,
modes,
punto,
game over,
vamos a cambiarlo,
vamos a poner un restart,
para que,
se reinicie,
y ya que estamos,
podríamos hacer,
que si el modo,
es,
modes,
punto bounce,
para que con el click,
también funcione,
vamos a hacer que,
se le pueda dar un click,
a esto,
ah,
me falta aquí,
un,
una llave,
aquí esto,
y ya está,
y ahora funcionará,
también con el click,
es que antes había hecho,
que solo funcionase,
con el espacio,
que tampoco pasa nada,
pero bueno,
así al menos,
y,
ahora game over,
le damos un click,
y ahí lo tenemos,
y ya tenemos,
el juego del fall stack,
en 2D,
pero puramente,
con javascript,
que hemos tenido,
que calcular algunas cositas,
algo de lógica,
de programación,
de lógica de programación,
de verdad,
o sea,
de tener que calcular cosas,
tener que pensar,
ahí tenemos el game over,
además le podéis poner música,
le podéis poner un montón de cosas,
pero ahí tenemos un proyectito más,
bastante interesante,
además,
súper fácil,
que le podáis añadir,
puntuación,
porque al final,
el contador,
ya lo tenemos,
que sería el current,
ya lo tenemos por aquí,
o sea,
podéis poner el contador,
en cualquier sitio,
por ejemplo,
pues aquí,
podéis poner un span,
que sea puntuación,
y aquí,
pues le podéis poner cero,
aquí,
de score,
súper fácil,
podéis hacer mimes de historias,
podéis hacer que la puntuación,
sea más interesante,
más complicada,
porque a lo mejor,
podéis hacer que,
vamos a hacer que esto,
de color blanco,
podéis hacer que la,
yo que sé,
mira,
puntuación,
vamos a poner,
form family,
form family,
system UI,
vamos a que esto sea,
un poquito más,
pequeñito,
pixels,
24 pixels,
y la puntuación,
esta,
la tendríamos que cambiar,
pues aquí,
podría ser en el draw,
esto es lo que decíamos,
como esto está fuera,
realmente esto,
sí que lo podríais cambiar,
en un momento en concreto,
esto no hace falta,
que lo hagáis en el draw,
constantemente,
esto por ejemplo,
podéis hacer en el handlebox landing,
podéis decir,
vale,
pues aquí,
voy a recuperar,
el elemento,
lo recuperamos solo una vez,
no hace falta recuperarlo,
constantemente,
así que tenemos aquí,
el score,
recuperamos el score,
y en la landing,
esta,
handlebox landing,
que es cuando justamente,
recuperamos,
y somos capaces,
de tener esto,
pues,
hacemos que tenga el current,
vale,
y,
bueno,
ahora saldrá 2,
directamente,
tendríamos que hacer,
que empiece con,
bueno,
podemos hacer,
punto text content,
menos 1,
y ya está,
menos 1,
y ya está,
o sea,
súper fácil,
tenéis la puntuación,
cómo se va actualizando,
conforme va apareciendo,
y ya está,
pim pam,
pim pam,
pim pam,
hay un montón de historias,
que podéis hacer,
me parece un proyectazo,
la verdad,
lo podéis intentar pasar a 3D,
lo podéis hacer,
es que podéis hacer,
vuestra,
la imaginación,
es vuestro límite,
en este caso,
parece un ejercicio sencillo,
mucha gente dirá,
ah,
no sé qué,
y luego mucha gente quiere practicar,
lógica de programación,
y creo que se confunde,
en la lógica de programación,
porque por ejemplo,
la gente enseña lógica de programación,
y dice,
no,
crear variables,
no,
a ver,
eso no es lógica de programación,
eso es sintaxis de programación,
básicamente,
y creo que,
la lógica de programación,
es algo en lo que te tengas que hacer pensar,
que tengas que iterar,
que tengas que hacer un montón de cosas,
¿no?
subestima mucho el proyecto,
bueno,
general,
muchas veces,
¿no?
Creo que es un proyecto que hace pensar,
que tenéis que tener en cuenta algunas cositas,
y que además ahora lo podéis llevar a otro nivel,
así que os recomiendo un montón,
que le deis un vistazo,
lo intentéis hacer en 3D,
creo que lo haremos un día,
la lógica de programación se enseña mal,
joder,
ya te digo,
que sí se enseña mal,
pero bueno,
ahí lo tenéis,
además está muy bien,
lo hemos hecho en un momento ahí,
que tenga el scroll,
es bastante divertido,
mira la vida,
que difícil,
ay,
Dios,
no,
no,
bueno,
está divertido además,
está bastante divertido,