Fundamentos de Programación

1

Bienvenida a Platzi: ¿qué necesitas para tomar el curso?

2

¿Cómo aprender programación?

3

Crea tu primer sitio web

4

Sitios web con HTML

5

Estructura de árbol en HTML

6

Instalando tu primer editor de código

7

Cómo declarar variables y usar prompt

8

Algoritmo de piedra, papel o tijera

9

Algoritmo avanzado de piedra, papel o tijera

10

Aleatoriedad

11

Refactor del código usando funciones

12

Ciclos

13

Gana 3 veces

14

Archivos de HTML y JavaScript

15

¿Qué es el DOM?

Quiz: Fundamentos de Programación

Desarrollando un juego con HTML y JavaScript

16

Maquetación con HTML

17

Sección de elegir mascota

18

¿Dónde ubicar la etiqueta script? Conectando HTML con JavaScript

19

Escuchando eventos con JavaScript

20

addEventListener

21

Manipulación del DOM

22

Enemigos aleatorios

23

Ataques en JavaScript

24

Ataques aleatorios del enemigo

25

Imprimiendo ataques del enemigo

26

¿Ganaste, perdiste o empataste?

27

Tablas de verdad

28

Creando el contador de vidas

29

¿Quién ganó el juego?

30

Reiniciando el juego

31

Ocultando elementos HTML con JS para mejorar la UX del juego

Quiz: Desarrollando un juego con HTML y JavaScript

Estilos con CSS

32

Anatomía de CSS

33

Tipos de display

34

Flexbox

35

Modelo de caja

36

Imágenes para los Mokepones

37

Estilos del botón

38

Adaptando HTML al diseño del juego

39

Layout: título y ataques

40

Adaptando JavaScript al diseño del juego

41

CSS Grid

42

Responsive Design

43

Detalles finales

Quiz: Estilos con CSS

Optimización de código

44

Revisión de código

45

Don't repeat yourself (DRY)

46

Clases y objetos

47

Clases y objetos de Mokepon

48

Arrays o arreglos

49

Objetos vs. arreglos

50

Ciclos: manipulando el DOM con iteradores

51

Declaración lenta de variables

52

Una sola fuente de la verdad

53

Mascotas aleatorias con arreglos

54

Ataques dinámicos por cada mascota: extraer

55

Renderizado dinámico en HTML

56

Eventos de click dinámicos

57

Secuencia de ataques del enemigo

58

Iniciando el combate

59

Resolviendo el reto de condicionales

60

Optimizando el frontend del juego

Quiz: Optimización de código

Mapa con canvas

61

Introducción a canvas: dibujando con JavaScript

62

Moviendo a Capipepo hacia la derecha

63

Movimiento hacia todas las direcciones

64

Movimientos con el teclado

65

Imágenes y personajes de fondo

66

Métodos en las clases

67

Obstáculos y colisiones

68

Combate entre mokepones colisionados

69

Mapa responsive

70

Botones bonitos y viewport

Quiz: Mapa con canvas

Backend: videojuego multijugador

71

¿Qué es backend?

72

Instalación de Node.js y NPM

73

Terminal de comandos y Node.js

74

Servidor web con Express.js

75

HTTP, localhost, servidores y puertos

76

Express.js y fetch: API REST con JavaScript

77

JSON y POST: mokepon online

78

Transmisión de coordenadas

79

Mokepones dinámicos en el mapa

80

Optimizando el mapa del juego

81

Batalla entre jugadores

82

Consumiendo la API de ataques del enemigo

Quiz: Backend: videojuego multijugador

Próximos pasos

83

Probando el juego en varios dispositivos

84

¿Y ahora qué curso tomar?

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso Gratis de Programación Básica

Curso Gratis de Programación Básica

Juan David Castro Gallego

Juan David Castro Gallego

Ocultando elementos HTML con JS para mejorar la UX del juego

31/84
Recursos

Aportes 356

Preguntas 109

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Gracias estimado profesor, en lo muy personal ya tengo mas de 30 años y siempre toda mi carrera me he orientado al soporte tecnico y con eso he sacado adelante a mi esposa y mis hijas, estoy queriendo cambiar el rumbo de mi vida profesional para ser Desarrollador Web y de aplicaciones, al momento siento que estoy en cero, pero quiero demostrarles a mis hijas que realmente lo que uno quiere puede lograrlo.

Un fuerte abrazo a todo el equipo de Platzi que hicieron posible este curso, y mas aun por poder tenerlo gratuito , no es facil ser sustento de familia y querer invertir en uno mismo, simplemente uno ve que siempre las cosas de los hijos son prioridad sobre nuestros deseos, y bueno, muy agradecido.

Muchas Bendiciones.

Felicidades jugador


Has finalizado la sección Desarrollando un juego con HTML y JavaScript, descansa aquí.

Por cierto, para deshabilitar los botones preferí crear una función para después llamarla en la función “crearMensajeFinal”, me parece más estético:

function deshabilitarBotones(){
    let botonFuego = document.getElementById("boton-fuego")
    botonFuego.disabled = true

    let botonAgua = document.getElementById("boton-agua")
    botonAgua.disabled = true

    let botonTierra = document.getElementById("boton-tierra")
    botonTierra.disabled = true

        let sectionReiniciar = document.getElementById("reiniciar")
        sectionReiniciar.style.display = "block"
}

Si se da click en el botón seleccionar sin escoger mascota, el juego permite continuar, lo que yo hice, es es disparar la función reiniciar para que no permita continuar si no se seleccionó la mascota del jugador

else{
alert(‘No se selecionó mascota’);
reiniciarJuego();
}

Me super encanta este nuevo curso! Voy entendiendo mejor que el primero que hicieron, se nota por mucho toda la planeación detrás. Me gusta también el cambio de profesores, aunque en una parte de mi corazón se queda cada uno de ellos. He aprendido muchísimo, y cada vez me siento más capaz de realizar nuevas cosas en mi camino ninja de ser desarrolladora web.

Pase mucho tiempo revisando el script porque la sección 1 no desaparecía, y resulto ser un simple error en el html.

PD: Si algo no les funciona, no olviden revisar también el html.

Quiero compartir mi código hasta la clase 31, me ha llevado algunas semanas pero creo que esta bien dentro de lo aprendido. Toca mejorar la visualizacion con html y css

Tambien les comparto algunas capturas del gameplay.





En esta clase falto un detalle pequeño para el javascript,
y es que, cuando no seleccionamos una mascota y le damos al boton seleccionar, ok, nos sale una alerta de que tenemos que escoger una mascota, ahi todo bien, pero al darle aceptar a ese alert, nos lleva a elegir ataque, como si hubiesemos escogido mascota, y lo que sale es "Tu mascota tiene 3 vidas

La mascota Hipodoge (un ejemplo) del enemigo tiene 3 vidas
pero no se si solo me paso a mi o es en general, del resto, espectacular la manera de enseñar del profe, excelente!!

Muchas gracias Juan David, eres un gran profesor, la verdad estoy sorprendida de como poco a poco he estado aprendiendo, aunque me costo mucho trabajo.

Ya tengo 38 años y estoy decidida a realizar este rumbo en mi carrera para sacar adelante a mi hija y mis padres, la verdad hasta el momento Fredy y tu me han dado mucho animo para continuar.

Hace 2 años tuve una desagradable experiencia en un bootcam y deje este sueño a tras, pero con estos pequeños pasos se que lo lograre, tarde o temprano.

Si a alguien le pasa que no desaparece la sección de Seleccionar Mascota, revisen el HTML. Yo tenía el siguiente error:

 <section id="seleccionar-mascota"></section>
            <h2>Elige tu mascota</h2>
            
            <label for="hipodoge">Hipodoge</label>
            <input type="radio" name="mascota" id="hipodoge">

            <label for="capipepo">Capipepo</label>
            <input type="radio" name="mascota" id="capipepo">

            <label for="ratigueya">Ratigueya</label>
            <input type="radio" name="mascota" id="ratigueya">
                           
            
            <button id="boton-mascota">Seleccionar</button>

Y la solución está en la ubicación de la etiqueta de cierre </section>

<section id="seleccionar-mascota">
            <h2>Elige tu mascota</h2>
            
            <label for="hipodoge">Hipodoge</label>
            <input type="radio" name="mascota" id="hipodoge">

            <label for="capipepo">Capipepo</label>
            <input type="radio" name="mascota" id="capipepo">

            <label for="ratigueya">Ratigueya</label>
            <input type="radio" name="mascota" id="ratigueya">
                           
            
            <button id="boton-mascota">Seleccionar</button>
        
        </section>

Me gusto mucho esta opción de quitarle y ponerle algunas secciones del juego , lo hace mas interactivo. felicitaciones profe 💚💚.
ahora empecemos con CCS 💗 😃

Me encantó esta sección del curso y sobretodo esta ultima clase de mostrar y ocultar secciones! Gracias por todo Juan David!!

Como amante del modo oscuro en esta clase decidí buscar en google como añadirlo al juego y este fue el resultado:

Que genial forma de enseñar, felicitaciones Juan David sos un capo!

Muchas gracias profe JD es usted un duro.

Esta nueva dinamica en los cursos que dice: "pausa la clase mientras completas el ejerciio, Es un game changer en estos cursos. Ese pequeño detalle como nos guia y nos hace mejorar jaja! 👍

Aquí les va mi aporte completo, espero les sirva y sea lo suficientemente descriptivo:



En esta clase utilizaremos a JavaScript Para que algunas de las secciones no estén visibles todo el tiempo sino únicamente cuando se requiera

Ya que tenemos algunas cosas por mejorar

  • Como la selección de una mascota, la cual no es necesaria para empezar a atacar
  • El hecho de que el botón de reiniciar está habilitado todo el tiempo
  • Aparece toda la información al cargar la página y solo necesitamos una parte

Para ello, vamos a utilizar

let sectionSeleccionarAtaque = document.getElementById("seleccionar-ataque")
sectionSeleccionarAtaque.style.display = "none";

Dado que todo el código de los ataques ya se encontraba incluida en una section solo debiamos llamarla y cambiarle los estilos

Sin embargo, cuando seleccionemos la mascota deberá llamarse una función donde se debe tener el código:

let sectionSeleccionarAtaque = document.getElementById("seleccionar-ataque")
sectionSeleccionarAtaque.style.display = "none";

Dado que necesitamos mostrar la sección de ataques para poder jugar

De esta manera podemos ir ocultando partes que no nos interesa mostrar, como por ejemplo el enunciado de seleccionar mascota

let sectionSeleccionarMascota = document.getElementById("seleccionar-mascota")
sectionSeleccionarMascota.style.display = "none";

Así podemos ir jugando con el código para mostrar solo lo que realmente nos interesa

El código para mostrar un texto sería:

let sectionSeleccionarMascota = document.getElementById("seleccionar-mascota")
sectionSeleccionarMascota.style.display = "block";
Ha sido un desafío el curso hasta este momento y apenas estamos comenzando. Toda la información explicada por Juan y Freddy ha sido un 10 de 10, mil Felicidades y agradecimientos por excelente curso. ESTO PARECE MAGIA! vamos con toda.

Gracias profe por explicar todo esto de una manera tan pedagógica y didáctica. Me quede con la duda de sí se puede asignar los ataques a una mascota en especifico que uno elija (ejemplo ratigueya solo fuego y tierra), pero eso tratare de descubrirlo yo mismo 😄

para los que se preguntan como evitar que se pueda avanzar jugando si aun no eliges un personaje se me ocurrio lo siguiente:

ejectuar los codigos de estilo que muestran y ocultan las secciones de la pagina otra vez, para que se quede exactamente como estaba
si no elijes un jugador.

Me encanta tu energia Juan, ojala hubiese mas maestros como tu, Gracias por la clase.

Gracias por todo profe JUAN, encantado de verdad de haberlo conocido a traves de estas clases y ansioso por verlo nuevos cursos para seguir aprendiendo!!!

Que genialhaber creado un juego así en JavaScript, primera vez que hago algo como esto

Gracias a prendi mucho con este maestro y pensar que iva a estrañar a Freddy cuando se fue pero eso nos hace aprender a conocer mas maestro y podemos aprender de mas personas , hice muchos metodos por mi mismo y aprendi a desarrollar mas mi logica por que pude hacer el progmama por mi propia forma son con lo que del decia trata de pensar decomo resolver hay duraba horas estudiando como hacer lo ante que lo hice mejore mucho mi logica gracias a que el nos pide que intentaramos hacer lo primero y no darnos el ejercicio echo.

Gracias profesor por las clases me encanto todo, y pude resolver el ultimo problema, Sino seleccionaba ningun personaje para jugar, el juego seguia normal, y no salia los nombres que tenia de jugador, ni el nombre del enemigo. Mi solucion fue la siguiente:
estoy perfeccionando cada vez más , gracias por las clases ❤

De verdad que poco a poco uno ve que sí avanza, muchas gracias al equipo y a los profesores.

Pude hacerlo antes que el Profe 😀🙋

lo logre completar antes que el profe y me salió igual estoy muy feliz

POR FIN T.T, por fin hice algo yo solo y funciona: fue solo lo último adivne donde tenía que ir, gloría a Dios.
Ojalá vea este mensaje cuando sea rico 😂-
Dios te bendiga Rafa

wey! me parece que dejamos un bug, y es que aquí si le doy seleccionar sin marcar ninguno, me salta la alerta debo seleccionar mascota, pero igual pasa a combate sin mascota

<- Den like acá los que hicieron el código con los 6 Mokepones 😂😂
PD: Se olvidaron de Langostelvis, Tucapalma y Pydos

Comparto por si a alguien le sirve las dos funciones (con modificaciones) más grandes hasta el momento, iniciarJuego() y combate().

Les comparto mi avance https://madexgamer.mx/pruebas-rapidas/mokepon/
No es muy bonito, pero trate de hacerlo más interactivo, solo deshabilite los botones, según la línea del tiempo, y le añadí música, aunque en mi computadora la música si funciona bien, en mi servidor web hace cosas raras

🤯💥 ¡Esto de ocultar elementos me ha volado la cabeza!

Se me ocurren mil formas de explotar esto ahora que estoy estudiando UX.

¡Gracias!

Estoy contento tenia un problema, y era que cuando no seleccionaba la mascota pero apretaba el boton Seleccionar me aparecia el combate, pero no tenia mokepon, asi que lo solucione de la siguiente manera (esto esta escrito al final en la function Seleccionar mascota jugador)

 else {
        alert("NO SELECCIONASTE TU MOKEPON!!")
        let sectionSeleccionarMascota = document.getElementById("elija-pet")
        sectionSeleccionarMascota.style.display = "block"
    
        let sectionSeleccionarAtaque = document.getElementById("elija-skill")
        sectionSeleccionarAtaque.style.display = "none"
    }

Ha sido muy agradable el curso con las enseñanzas del profe Juan David Castro!!! Explica muy bien y motiva

  • HTML File

  • JavaScript File



Quede impresionado con el metodo de ocultar y mostrar los elementos del JS a nuestro HTML. Jamas imagine que esto puede ser divertido y dinamico. Fue poco tiempo que este profesor enseño HTML pero me gusto demasiado su forma de motivar en este tema y me gustaria profundizarlo un poco mas por mi cuenta. Gracias y espero verlo en algun otro curso de programacion.

¡IMPORTANTE¡ Les dejo un tutorial que funciona para poder COMAPAR archivos en VisualStudioCode. Así encontraran errores mas rápidamente.

El vídeo es corto, pero es muy, muy, muy útil, espero les pueda ayudar.

https://www.youtube.com/watch?v=CbgO6C_NuZg

Se me presentó el problema que cuando doy seleccionar mascota sin haber elegido mascota se activa el display none de la seccion de elegir mascota, es decir la oculta y ya no me deja elegir mascota y si me muestra la sección de ataques en nuestro html.

Solución propuesta:
Poner la lógica de mostrar la sección de seleccionar ataque y ocultar la sección de seleccionar mascota al final de la función selecciónMascotaEnemigo y no al inicio de la función seleccionarMascotaJugador.

function seleccionMascotaEnemigo() {
    let mascotaEnemigoAleatorio = aleatorio(1,6)
    let spanMascotaEnemigo = document.getElementById('mascota-enemigo')

    if (mascotaEnemigoAleatorio == 1) {
        spanMascotaEnemigo.innerHTML = 'Hipodoge'
    } else if (mascotaEnemigoAleatorio == 2) {
        spanMascotaEnemigo.innerHTML = 'Capipepo'
    } else if (mascotaEnemigoAleatorio == 3) {
        spanMascotaEnemigo.innerHTML = 'Ratigueya'
    }else if (mascotaEnemigoAleatorio == 4) {
        spanMascotaEnemigo.innerHTML = 'Langostelvis'
    }else if (mascotaEnemigoAleatorio == 5) {
        spanMascotaEnemigo.innerHTML = 'Tucapalma'
    } else {
        spanMascotaEnemigo.innerHTML = 'Pydos'
    }
    combateListo = 'ok'

    let sectionSeleccionarAtaque = document.getElementById('Seleccionar-ataque')
    sectionSeleccionarAtaque.style.display = 'block'

    let sectionSeleccionarMascota = document.getElementById('Seleccionar-mascota')
    sectionSeleccionarMascota.style.display = 'none'
}

Intente ocultar y mostrar las secciones y el botón de reiniciar a mi modo (antes de ver el video o las partes donde el profe dice como hacerlo) y la forma que se me ocurrió fue creando funciones y también obtuve el mismo resultado, por ejemplo:

para mostrar el botón reiniciar

function mostrarBotonReiniciar(){
let seccionBotonReiniciar=document.getElementById(‘reiniciar’);
seccionBotonReiniciar.style.display=‘block’;
}

y mande a llamar en la misma posicion donde el profe escribio el codigo. Y FUNCIONO!!! 😃

Gracias Juan David! excelente profe!

Muchas gracias al Profe Juan David, muy didáctica su forma de enseñar 👌

Hola mi proyecto es un poco distinto, en vez de mascotas preferí usar “caballero”, “arquero” y “mago” y que el oponente sea “ciclope”, “orco” y “rey esqueleto”.

Quiero compartir mi código que tiene algunas variaciones al que mostró Juan David y me gustaría que me dijeran qué les parece y qué se puede mejorar.
Muchas gracias.
![](

<!DOCTYPE html>
<html lang="es">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Guerreros</title>
    <link rel="stylesheet" href="css/styles.css">
    <script src="js/code.js"></script>
</head>

<body>
    <h1>¡Guerreros! 🗡️ 🏹 🪄</h1>

    <section id="sec-warrior">
        <h2>Elige a tu guerrero:</h2>
        <p>
            <input type="radio" name="warrior" id="rd-knight">
            <label for="rd-knight">Caballero 🗡️</label>
            <input type="radio" name="warrior" id="rd-archer">
            <label for="rd-archer">Arquero 🏹</label>
            <input type="radio" name="warrior" id="rd-mage">
            <label for="rd-mage">Mago 🪄</label>
        </p>
        <p>
            <button id="btn-select">Seleccionar</button>
        </p>
    </section>

    <section id="sec-attack" hidden="true">
        <h2>Elige tu ataque:</h2>
        <p>Tu <span id="spn-player">guerrero</span> tiene <span id="spn-player_health">3</span> puntos de vida ❤️.</p>
        <p>El <span id="spn-enemy">enemigo</span> tiene <span id="spn-enemy_health">3</span> puntos de vida 💚.</p>
        <p>
            <button id="btn-mele">Cuerpo a cuerpo 💪</button>
            <button id="btn-range">Rango 💨</button>
            <button id="btn-magic">Magia 🔥</button>
        </p>
    </section>

    <section id="sec-messages" hidden="true">
        <p></p>
    </section>

    <section id="sec-reset" hidden="true">
        <p>
            <button id="btn-reset">Reiniciar</button>
        </p>
    </section>
</body>

</html>
function aleatorio(min, max) {
    /* 
        DESCRIPTION: Genera un número aleatorio entre el min y el max.
        PARAMETERS:
                    min = valor mínimo
                    max = valor máximo
    */
    return Math.floor(Math.random() * (max - min + 1) + min)
}


function select_enemy() {
    /* 
        DESCRIPTION: Selecciona un enemigo de forma aleatoria.
    */

    // Generar un número entre 1 y 3 que representará a un enemigo a elegir:
    // 1 = ciclop, 2 = orc y 3 = skeleton
    let enemy_number = aleatorio(1, 3)
    let enemy_name = ""
    let spn_enemy = document.getElementById("spn-enemy")

    if (enemy_number == 1) {
        enemy_name = "Cíclope"
    } else if (enemy_number == 2) {
        enemy_name = "Orco"
    } else {
        enemy_name = "Rey Esqueleto"
    }

    spn_enemy.innerHTML = enemy_name
}


function select_warrior() {
    /* 
        DESCRIPTION: Selecciona el personaje del jugador.
    */

    let sec_warrior = document.getElementById("sec-warrior")
    let sec_attack = document.getElementById("sec-attack")
    let sec_messages = document.getElementById("sec-messages")
    let rd_knight = document.getElementById("rd-knight")
    let rd_archer = document.getElementById("rd-archer")
    let rd_mage = document.getElementById("rd-mage")
    let spn_player = document.getElementById("spn-player")
    let warrior_selected = ""

    if (rd_knight.checked) {
        warrior_selected = "Caballero"
    } else if (rd_archer.checked) {
        warrior_selected = "Arquero"
    } else if (rd_mage.checked) {
        warrior_selected = "Mago"
    } else {
        alert("Debes seleccionar un guerrero para luchar")
        return // Salir de la función.
    }
    // Mostrar el jugador elegido.
    spn_player.innerHTML = warrior_selected
    alert("Has seleccionado al " + warrior_selected)
    // Ocultar la sección de selección de jugador
    sec_warrior.hidden = true
    // Mostrar las secciones de ataque y mensajes.
    sec_attack.hidden = false
    sec_messages.hidden = false

    select_enemy()
}


function lets_combat(player, enemy) {
    /* 
        DESCRIPTION: Devuelve un entero con el resultado del juego.
                     Si es 0 es empate, si es 1 gana player y si
                     es 2 gana enemy.
        PARAMETERS:
                    player = identifica el ataque del jugador.
                    enemy = identifica el ataque del enemigo.
                    1 = cuerpo a cuerpo, 2 = rango y 3 = magia
    */
    let result = 0

    if (player == enemy) {
        result = 0
    } else if (player == 1 && enemy == 2) {
        result = 1
        enemy_health -= 1 // Resto un punto de vida al enemigo.
    } else if (player == 2 && enemy == 3) {
        result = 1
        enemy_health -= 1 // Resto un punto de vida al enemigo.
    } else if (player == 3 && enemy == 1) {
        result = 1
        enemy_health -= 1 // Resto un punto de vida al enemigo.
    } else {
        result = 2
        player_health -= 1 // Resto un punto de vida al jugador.
    }

    return result
}

function translate_result(match_result) {
    /* 
        DESCRIPTION: Devuelve un texto con el resultado del combate.
        PARAMETERS:  match_result = número que indica el resultado.
                     0 = empate, 1 = victoria, 2 = derrota
    */
    
    if (match_result == 1) {
        return "¡Ganaste! 😎"
    } else if (match_result == 2) {
        return "¡Perdiste! 😢"
    } else {
        return "¡Empate! 😐"
    }

}


function translate_attack(attack_number) {
    /* 
        DESCRIPTION: Devuelve el nombre del ataque según se su número.
    */

    let selected_attack = ""

    if (attack_number == 1) {
        selected_attack = "cuerpo a cuerpo"
    } else if (attack_number == 2) {
        selected_attack = "rango"
    } else {
        selected_attack = "magia"
    }
    return selected_attack
}


function check_health() {
    /* 
        DESCRIPTION: Revisa si la vida de alguno de los contrincantes está
        en 0 lo que determinará quién ganó el juego.
    */
        
    let sec_messages = document.getElementById("sec-messages")
    let sec_reset = document.getElementById("sec-reset")
    let message = document.createElement("h2")
    let btn_magic = document.getElementById("btn-magic")
    let btn_range = document.getElementById("btn-range")
    let btn_mele = document.getElementById("btn-mele")

    if (enemy_health == 0) {
        message.innerHTML = "¡Ganaste! 🥳🏆"
    } else if (player_health == 0) {
       message.innerHTML = "¡Perdiste! 😭🥀"
    } else {
        return
    }
    
    sec_messages.appendChild(message)

    // Deshabilitar botones de ataque.
    btn_magic.disabled = true
    btn_range.disabled = true
    btn_mele.disabled = true
    // Mostrar el botón reiniciar.
    sec_reset.hidden = false
}


function show_status(match_result) {
    /* 
        DESCRIPTION: Muestra mensajes de estado del juego.
    */
    
    let sec_messages = document.getElementById("sec-messages")
    let player = document.getElementById("spn-player").innerHTML
    let enemy = document.getElementById("spn-enemy").innerHTML
    let spn_player_health = document.getElementById("spn-player_health")
    let spn_enemy_health = document.getElementById("spn-enemy_health")
    let message = document.createElement("p")
    let text_player_attack = translate_attack(player_attack)
    let text_enemy_attack = translate_attack(enemy_attack)
    let text_match_result = translate_result(match_result)

    // Actualizar puntos de vida.
    spn_player_health.innerHTML = player_health
    spn_enemy_health.innerHTML = enemy_health
    // Actualizar mensaje de estado.
    message.innerHTML = "Tu " + player + " lanza un ataque de " +
                        text_player_attack + ".<br>El " + enemy +
                        " lanza un ataque de " + text_enemy_attack + "." + 
                        "<br>" + text_match_result

    sec_messages.appendChild(message)

    check_health()
}


function attack(event) {
    /* 
        DESCRIPTION: Selecciona el ataque del jugador según el botón 
                     presionado indicado por el parámetro 
                     "event.target.id".
                     Genera un ataque aleatorio del enemigo y muestra el
                     resultado.
    */

    let match_result = 0
    let spn_player = document.getElementById("spn-player")

    // Verificar que antes de un ataque se haya seleccionado un guerrero.
    if (spn_player.innerHTML == "guerrero") {
        alert("Debes seleccionar un guerrero para poder realizar un ataque.")
        return
    }
    
    if (event.target.id == "btn-mele") {
        player_attack = 1 // Cuerpo a cuarpo
    } else if (event.target.id == "btn-range") {
        player_attack = 2 // Rango
    } else {
        player_attack = 3 // Magia
    }

    // Generar un número entre 1 y 3 que representará el ataque enemigo:
    enemy_attack = aleatorio(1, 3)

    match_result = lets_combat(player_attack, enemy_attack)

    // Mostrar mensajes de estado.
    show_status(match_result)
}


function reset_game() {
    /* 
        DESCRIPTION: Reinicia todas las opciones para jugar otra vez.
    */

    // window.location.reload() recarga la página devolviendo el html 
    // original.
    location.reload()
}


function init() {
    /* 
        DESCRIPTION: Inicializa los elementos del html.
    */
    let btn_select = document.getElementById("btn-select")
    btn_select.addEventListener("click", select_warrior)
    let btn_magic = document.getElementById("btn-magic")
    btn_magic.addEventListener("click", attack)
    let btn_range = document.getElementById("btn-range")
    btn_range.addEventListener("click", attack)
    let btn_mele = document.getElementById("btn-mele")
    btn_mele.addEventListener("click", attack)
    let btn_reset = document.getElementById("btn-reset")
    btn_reset.addEventListener("click", reset_game)
}


let player_attack = 0
let enemy_attack = 0
let player_health = 3
let enemy_health = 3

// Agregar el EventListener "load" de window para hacer uso del js.
window.addEventListener("load", init)
Yo: Uiiiii mi primera aplicacion terminada !!! Juan DC: mmm no esta taaaan bonito!!! LOL

Gracias Profe Juan! 💚

Gracias Profe Juan 😃

Yo resolví el “Bug” de poder continuar el juego aunque no hayas seleccionado ningún personaje unas clases atrás, y ahora no me da problemas

else {         //En caso de que no haya jugador seleccionado
    if (numAleatorio == 1) {
        personajeSeleccionado = 'Brandon'
        spanPersonajeJugador.innerHTML = 'Brandon'
    }
    else if (numAleatorio == 2) {
        personajeSeleccionado = 'Nelly'
        spanPersonajeJugador.innerHTML = 'Nelly'
    }
    else if (numAleatorio == 3) {
        personajeSeleccionado = 'Brianna'
        spanPersonajeJugador.innerHTML = 'Brianna'
    }
    alert('No haz seleccionado un personaje, se ha elegido aleatoriamente a ' + personajeSeleccionado)
}

De esa manera, el personaje se selecciono de manera aleatoria, y puede continuar el juego sin que el jugador haya hecho una elección

El profesor explica super bien, yo venia de un anterior curso de CSS pero no tenia idea de como programar botones e input y con juan se aprende bastante, las próximas clases serán de CSS y me adelante un poco, y le hice un diseño especial al juego, para que entren compañeros, le den un visto bueno y me dicen que si están preparados para el verdadero MOKEPON!

https://jcdanieljimenez.github.io/mokepon

Espero que disfruten del juego y de las siguientes clases 😉😎

Me estaba volviendo loco! tenia el código de JS bien escrito pero no desaparecía la sección de ataque…

Resulta que en HTML mi sección de ataque estaba mal escrita porque tenia dos etiquetas de cierre…
Abría y cerraba sin nada en el medio y después estaba bien puesta otra de cierre!

Me parecen excelentes las pausas para el desarrollo personal de habilidades, veo que eres uno de los pocos profes que lo pone en practica te felicito @JuanDC.

Muchas gracias Juan David, he aprendido diferentes formas de manipular el DOM, llamar a elementos de HTML por su ID, Saber en qué momento crear variables locales y globales en JS y muchas cosas más
Gracias a ti y a Freddy está mi primera versión de Mokepon funcional con unos detalles adicionales míos

https://github.com/p3podev/mokepon/releases/tag/v0.01

Y el estado actual del juego está así
https://p3podev.github.io/mokepon/

Ver el codigo que he desarrollado clase tras clase (en algunas ocasiones con diferencias al del prf Juan), y entenderlo… No tiene precio…

Realmente gracias Prf…

Sigamos avanzando!🎉

te extrañaremos Mike Wheeler gracias por todo jejejeje

y pooommmm lo entendi super
Gracias profe Juan por todo, Heroe
Diooooooooooos que felicidad, ya estoy entendiendo como funciona todo y los ultimos pasos los hice simplemente usando la lógica. Solo vi al profe para asegurame que lo tenia bien, que felicidad saber que ya se me esta dando!!!!!!!
profe te voy a extrañar. Mucha Gracias.... enseñas Super super Super muy excelentemente BIEN. Gracias. Dios te Bendiga
1. ```js //revisar vidas function revisarVidas(){ if (vidasEnemigo == 0){ crearMensajeFinal("FELICITACION! GANASTE:") reiniciar = document.getElementById('boton-reiniciar') reiniciar.style.display = 'block' }else if (vidasJugador == 0){ crearMensajeFinal("LO SIENTO, PERDISTE ;(") reiniciar = document.getElementById('boton-reiniciar') reiniciar.style.display = 'block' } } ``` //revisar vidas   function revisarVidas(){    if (vidasEnemigo == 0){      crearMensajeFinal("FELICITACION! GANASTE:")      reiniciar = document.getElementById('boton-reiniciar')      reiniciar.style.display = 'block'         }else if (vidasJugador == 0){      crearMensajeFinal("LO SIENTO, PERDISTE ;(")      reiniciar = document.getElementById('boton-reiniciar')      reiniciar.style.display = 'block'         }      }    //revisar vidas   function revisarVidas(){    if (vidasEnemigo == 0){      crearMensajeFinal("FELICITACION! GANASTE:")      reiniciar = document.getElementById('boton-reiniciar')      reiniciar.style.display = 'block'         }else if (vidasJugador == 0){      crearMensajeFinal("LO SIENTO, PERDISTE ;(")      reiniciar = document.getElementById('boton-reiniciar')      reiniciar.style.display = 'block'         }      }  
Usando CSS dandole un estilizada rapida: ![](https://static.platzi.com/media/user_upload/image-1f9f0d87-90f4-4487-8664-e2b91d5793a9.jpg)![](https://static.platzi.com/media/user_upload/image-b70745e6-47da-4a54-97f2-269cf5e48b66.jpg)
Dejo mi aporte para que no se rindan :) ![](https://static.platzi.com/media/user_upload/imagen%204-587af3c8-af6d-47d5-928e-fb1f7b3b99f5.jpg)![](https://static.platzi.com/media/user_upload/imagen%205-66d08f42-b016-4794-9424-6f9d5aa2234a.jpg)![](https://static.platzi.com/media/user_upload/imagen%204-af21a99c-e3b0-4b0a-9280-2bc124c524c5.jpg)![]()![](https://static.platzi.com/media/user_upload/imagen%204-5437086d-9cd8-46b8-9766-e9c89a772298.jpg)![](https://static.platzi.com/media/user_upload/imagen%204-3cb86446-c2ee-4654-a5c9-5c1383fe6050.jpg)![](https://static.platzi.com/media/user_upload/imagen%204-9984111a-44a0-41f2-a65b-0e72e8a57e42.jpg)![](https://static.platzi.com/media/user_upload/imagen%204-5a4f57c8-bbb5-4cc1-b8f1-730c7bcdb702.jpg)![](https://static.platzi.com/media/user_upload/imagen%204-c0ec0819-ee9a-4a89-bbbc-f8a90b7943d0.jpg)![](https://static.platzi.com/media/user_upload/imagen%204-f99bafc0-b585-40d0-9615-f37687213ed5.jpg)![]()![]()
por aqui les dejo lo que he logrado con los cursos de platzi y el chat GPT <https://lugarcreativo.netlify.app/>

Me gustaría añadirle un poco más de complejidad a mi juego ¿alguien sabe como podría añadir puntos de defensa?

estoy super orgullosa por que pude resolver el desaparecer y aparecer el boton reiniciar!!! :’)

Despues de 31 clases despues vine a entender y cogerle el tiro a todo jajaja :p

un detalle que se le fue al profe es que cuando iniciamos el juego y no elegimos la mascota, lo que debe pasar es que el juego se reinicie y no continue satandose esa parte, es seguro que mas uno lo ha visto en sus juegos, esto se soluciona colocando
location.reload() en la parte donde creas el mensaje de debe seleccionar mascota, as{i el juego vuelve al principio y no continua mostrando las siguientes secciones del juego.

if(inputHipodoge.checked) {
        spanMascotaJugador.innerHTML = 'Hipodoge'
    } else if(inputCapipepo.checked) {
        spanMascotaJugador.innerHTML = 'Capipepo'
        
    } else if(inputRatigueya.checked) {
        spanMascotaJugador.innerHTML = 'Ratigueya'
        
    } else {
        alert('Debe seleccionar una mascota')
        location.reload()
    }

gracias profe juan me encanta tu actitud , ojala existieran mas profesores como usted ,nunca crei poder hacer lo que estoy haciendo pero bueno voy empezando apenas ♥️

el código actual permite realizar ataques sin seleccionar mascota, yo lo solucioné con con condicional validando que al menos un elemento de tipo radio este seleccionado, tambien puse el codigo ocultar la sección de ataque en ese condicional, así me aseguro que no se muestre sin haber seleccionado una mascota

function verificarMascota() {
    if((inputHipodoge.checked)||(inputCapipepo.checked)||(inputLangostelvis.checked)||(inputPydos.checked)||(inputRatigueya.checked)||(inputTucapalma.checked)){
        return true
    }else {
        return false
    }
}

function selecionarMascotaJugador(){
    
    let mascotaJugador = document.getElementById('mascota-jugador')

    if(inputHipodoge.checked){
        mascotaJugador.innerHTML = ' Hipodoge'
        seccionSeleccionarAtaque.style.display = 'block'
        seccionSeleccionarMascota = document.getElementById('seleccionar-mascota')
        seccionSeleccionarMascota.style.display = 'none'
    } else if(inputCapipepo.checked){
        mascotaJugador.innerHTML = ' Capipepo'
        seccionSeleccionarAtaque.style.display = 'block'
        seccionSeleccionarMascota = document.getElementById('seleccionar-mascota')
        seccionSeleccionarMascota.style.display = 'none'
    } else if(inputRatigueya.checked){
        mascotaJugador.innerHTML = ' Ratigueya'
        seccionSeleccionarAtaque.style.display = 'block'
        seccionSeleccionarMascota = document.getElementById('seleccionar-mascota')
        seccionSeleccionarMascota.style.display = 'none'
    } else if(inputLangostelvis.checked){
        mascotaJugador.innerHTML = ' Langostelvis'
        seccionSeleccionarAtaque.style.display = 'block'
        seccionSeleccionarMascota = document.getElementById('seleccionar-mascota')
        seccionSeleccionarMascota.style.display = 'none'
    } else if(inputTucapalma.checked){
        mascotaJugador.innerHTML = ' Tucapalma'
        seccionSeleccionarAtaque.style.display = 'block'
        seccionSeleccionarMascota = document.getElementById('seleccionar-mascota')
        seccionSeleccionarMascota.style.display = 'none'
    } else if(inputPydos.checked){
        mascotaJugador.innerHTML = ' Pydos'
        seccionSeleccionarAtaque.style.display = 'block'
        seccionSeleccionarMascota = document.getElementById('seleccionar-mascota')
        seccionSeleccionarMascota.style.display = 'none'
    } else {
        alert("Debe seleccionar una masota ")
    }
    selecionarMascotaEnemigo()
}

Mi solución para la el minuto 11:00

	// Iniciar Juego
    let sectionBotonReiniciar = document.getElementById("boton-reiniciar")
    sectionBotonReiniciar.style.display = "none"
	
	//Crear Mensaje Final
    let sectionBotonReiniciar = document.getElementById("boton-reiniciar")
    sectionBotonReiniciar.style.display = "block"

Creo q lo extrañare Profe jajaaj

Gracias profe, nunca creí que podia lograr algo así, aunque me explicaran.🙂

Gracias por estos conceptos, ya es solo de ponerlo en práctica.

Gracias 🙂

Para ocultar periodicamente alguna sección de HTML usamos el método: style.display = “none”

Para hacerla aparecer a pantalla usamos el metodo:
style.display = “block”

Muchas Gracias profesor… es usted el mejor

Yo colocarìa el còdigo en la función donde se comienza el principio del juego

gg ez Computadora

los puse, teniendo el video pausado en el minuto 11:04’… en la function iniciarJuego oculte la sectionReiniciar y luego, en la function crearMensajeFinal al final del codigo para que se visualice el boton

Primero que nada agradecer por la clase es uno de los mejores profes que tiene Platzi.

Y otra para aportar una solución en el dado caso donde no seleccionemos ninguna mascota, solo sale una alerta pero nos permitía seguir jugando sin mascota.

La solución que yo encontré fue en la función seleccionarMascotaJugador lo siguiente:

function seleccionarMascotaJugador(){
    let sectionSeleccionarAtaque = document.getElementById("seleccionar-ataque")
    sectionSeleccionarAtaque.style.display = "block"
    let sectionSeleccionarMascota = document.getElementById("seleccionar-mascota")
    sectionSeleccionarMascota.style.display = "none"


    let inputHipodoge = document.getElementById("Hipodoge")
    let inputCapipepo = document.getElementById("Capipepo")
    let inputRatigueya = document.getElementById("Ratigueya")
    let spanMascotaJugador = document.getElementById("mascota-jugador")
    

    if(inputHipodoge.checked){
        spanMascotaJugador.innerHTML = "Hipodoge "
    }
    else if(inputCapipepo.checked){
        spanMascotaJugador.innerHTML = "Capipepo "
    }
    else if(inputRatigueya.checked){
        spanMascotaJugador.innerHTML = "Ratigueya "
    }
    else{
        alert("Selecciona una mascota")
        let sectionSeleccionarAtaque = document.getElementById("seleccionar-ataque")
        sectionSeleccionarAtaque.style.display = "none"
        let sectionSeleccionarMascota = document.getElementById("seleccionar-mascota")
        sectionSeleccionarMascota.style.display = "block"
        let sectionSeleccionarReiniciar = document.getElementById("reiniciar")
    sectionSeleccionarReiniciar.style.display = "block"
    }
    seleccionarMascotaEnemigo()
}

Excelente curso logre hacer una gran base de datos con las funciones explicadas.

Pronto podremos hacer proyectos mas complicados al nunca parar de aprender

¡Muchas gracias profe Juan! usted sí que sabe orientarnos de una manera didáctica lo cual torna la clase más amena .

<p>profesor, le agradezco que compartiera su conocimiento, lo comprendi muy bien.</p>

Asi quedo mi codigo al final:

<let ataqueJugador 
let ataqueEnemigo
let resultado
let vidasEnemigo = 3
let vidasJugador = 3 


function iniciarJuego(){
    let sectionSeleccionarAtaque = document.getElementById('seleccionarAtaque')
    sectionSeleccionarAtaque.style.display = 'none'

    let sectionReiniciar = document.getElementById('reiniciar')
    sectionReiniciar.style.display = 'none'

    let botonMascotaJugador = document.getElementById('boton_mascota')
    botonMascotaJugador.addEventListener('click', seleccionarMascotaJugador)

    let botonFuego = document.getElementById('boton_fuego')
    botonFuego.addEventListener('click', ataqueFuego)
    let botonAgua = document.getElementById('boton_agua')
    botonAgua.addEventListener('click', ataqueAgua)
    let botonTierra = document.getElementById('boton_tierra')
    botonTierra.addEventListener('click', ataqueTierra)
    
    let botonReiniciar = document.getElementById('boton_reiniciar')
    botonReiniciar.addEventListener('click', reiniciarJuego)
}


function seleccionarMascotaJugador(){
    let inputHipodoge = document.getElementById('hipodoge').checked
    let inputCapipepo = document.getElementById('capipepo').checked
    let inputRatigueya = document.getElementById('ratigueya').checked
    let spanMascotaJugador = document.getElementById('mascotaJugador')
    let sectionSeleccionarAtaque = document.getElementById('seleccionarAtaque')
    let sectionSeleccionarMascota = document.getElementById('seleccionarMascota')

    if (inputHipodoge){
        //alert("seleccionaste a Hipodoge")
        spanMascotaJugador.innerHTML = "Hipodoge"
        sectionSeleccionarAtaque.style.display = 'block'
        sectionSeleccionarMascota.style.display = 'none'
    }else if (inputCapipepo){
        //alert("seleccionaste a Capipepo")
        spanMascotaJugador.innerHTML = "Capipepo"
        sectionSeleccionarAtaque.style.display = 'block'
        sectionSeleccionarMascota.style.display = 'none'
    }else if (inputRatigueya){
        //alert("seleccionaste a Ratigueya")
        spanMascotaJugador.innerHTML = "Ratigueya"
        sectionSeleccionarAtaque.style.display = 'block'
        sectionSeleccionarMascota.style.display = 'none'
    }else{
        alert("Debes seleccionar una mascota")
        spanMascotaJugador.innerHTML = ""
    }

    seleccionarMascotaEnemigo()
}


function seleccionarMascotaEnemigo(){
    let spanMascotaEnemigo = document.getElementById('mascotaEnemigo')
    let mascotaEnemigo = aleatotio(1, 3)
    if(mascotaEnemigo == 1){
        spanMascotaEnemigo.innerHTML = "Hipodoge"
    }else if(mascotaEnemigo == 2){
        spanMascotaEnemigo.innerHTML = "Capipepo"
    }else if(mascotaEnemigo == 3){
        spanMascotaEnemigo.innerHTML = "Ratigueya"
    }
}


function ataqueFuego(){
    ataqueJugador = 'FUEGO 🔥'
    seleccionarAtaqueEnemigo()
}

function ataqueAgua(){
    ataqueJugador = 'AGUA 💧'
    seleccionarAtaqueEnemigo()
}

function ataqueTierra(){
    ataqueJugador = 'TIERRA 🌱'
    seleccionarAtaqueEnemigo()
}

function seleccionarAtaqueEnemigo(){
    let ataqueEnemigo = aleatotio(1, 3)
    if(ataqueEnemigo == 1){
        ataqueEnemigo = 'FUEGO 🔥'
    }else if(ataqueEnemigo == 2){
        ataqueEnemigo = 'AGUA 💧'
    }else if(ataqueEnemigo == 3){
        ataqueEnemigo = 'TIERRA 🌱'
    }

    combate(ataqueEnemigo)
}

function combate(ataqueEnemigo){
    let spanVidasJugador = document.getElementById('vidas_jugador')
    let spanVidasEnemigo = document.getElementById('vidas_enemigo')
    if(ataqueEnemigo == ataqueJugador){
        //alert("Empate")
        resultado = 'Empataste 😬'
    }else if(ataqueJugador == 'FUEGO 🔥' && ataqueEnemigo == 'TIERRA 🌱'){
        //alert("Ganaste!!")
        resultado = 'Ganaste 🎉'
        vidasEnemigo -= 1
        spanVidasEnemigo.innerHTML = vidasEnemigo
    }else if(ataqueJugador == 'AGUA 💧' && ataqueEnemigo == 'FUEGO 🔥'){
        //alert("Ganaste!!")
        resultado = 'Ganaste 🎉'
        vidasEnemigo -= 1
        spanVidasEnemigo.innerHTML = vidasEnemigo
    }else if(ataqueJugador == 'TIERRA 🌱' && ataqueEnemigo == 'AGUA 💧'){
        //alert("Ganaste!!")
        resultado = 'Ganaste 🎉'
        vidasEnemigo -= 1
        spanVidasEnemigo.innerHTML = vidasEnemigo
    }else{
        //alert("PERDISTE")
        resultado = 'Perdiste 😔'
        vidasJugador -= 1
        spanVidasJugador.innerHTML = vidasJugador
    }
    
    revisarVidas()
    crearMensaje(ataqueEnemigo)
}


function revisarVidas(){
    if(vidasJugador == 0){
        alert("Que pena perdiste 😔")
        crearMensajeFinal("Que pena perdiste 😔")
    }else if(vidasEnemigo == 0){
        alert("Felicidades Ganaste!! 🎉")
        crearMensajeFinal("Felicidades Ganaste!! 🎉")
    }
}

function crearMensaje(ataqueEnemigo){
    let sectionMensaje = document.getElementById('mensajes')
    let parrafo = document.createElement('p')
    parrafo.innerHTML = "Tu mascota ataco con " + ataqueJugador + ", la mascota de tu enemigo ataco con " + ataqueEnemigo + " - " + resultado
    sectionMensaje.appendChild(parrafo) 
}

function crearMensajeFinal(resultadoFinal){
    let sectionMensaje = document.getElementById('mensajes')
    let parrafo = document.createElement('p')
    parrafo.innerHTML = resultadoFinal
    sectionMensaje.appendChild(parrafo) 

    let botonFuego = document.getElementById('boton_fuego')
    botonFuego.disabled = true
    let botonAgua = document.getElementById('boton_agua')
    botonAgua.disabled = true
    let botonTierra = document.getElementById('boton_tierra')
    botonTierra.disabled = true

    let sectionReiniciar = document.getElementById('reiniciar')
    sectionReiniciar.style.display = 'block'
}

function reiniciarJuego(){
    location.reload()
}

function aleatotio(min, max){
    return Math.floor(Math.random() * (max-min+1) + min)
}


window.addEventListener('load', iniciarJuego)

> 

alucinante todo perfecto soy un genio de la programacion lets go !!!

gracias Profe 😃

Gracias Profesor Juan David me gusto un monton las clases aprendi Mucho !!!

Tuve un problema al querer ocultar la sección de “seleccionar-mascota”, copie y pague la función, la volvía a escribir letra por letra, la cambiaba de orden y parecía que nada funcionaba. Luego recibe mi html y me di cuenta que la etiqueta </section> estaba mal cerrada. Se soluciono y mi presión arterial regreso a la normalidad.

Cuando se da click en Seleccionar sin elegir una mascota, el codigo sigue su ejecucion, pera ello, en lugar de usar ela función reinicarJuego(), usé esto. Ya que evita ese “salto de pantalla” cuando se recarga la pagina, haciendo que visualmente se vea un poco mejor

} else {
        alert("Selecciona una mascota")
        sectionSeleccionarMascota.style.display = "block";
        sectionSeleccionarAtaque.style.display = "none";
    }

Hice que apareciera con elemet.style.display = “contents” para mayor info de display visita https://developer.mozilla.org/es/docs/Web/CSS/display

/ * Valores <display-box> * /
display: none; // desaparece
display: contents; // aparece

Muchas gracias al profe Juan David, tienes el espíritu de la enseñanza en tu interior, lo cual hace que los estudiantes aprendan muy fácilmente. Espero que el resto de profes lo hagan igual de bien, lo cual no pongo en duda porque Platzi es lo mejor.

Una locura lo que he aprendido eneste curso, muy superior al primer la verdad. me estube quebrando la cabeza en los ultimos 2 video por un error que me daba, pero lo logre solucionar. tengo que agradecer al profe y decirle que espero verlo en algun otro curso, un saludo crack!

Muchas gracias JuanDC, primer curso que veo contigo, excelente pedagogía y dinámica para enseñar. Nos vemos pronto 💪💪💪

Muchas gracias por tus aulas Juan, me divertí mucho desarrolando mi proyecto

Ante todo, un cordial saludo profe Juan y un abrazo. le agradezco por ser una persona sumamente positiva y atenta en dar la mejor clase, logre comprender algo que realmente no tenía ni la más mínima idea de que hacer. es mi primera vez estudiando algo desde cero, tengo 23 años migrante en chile y sé que soy una joven promesa, apenas pueda lograre dar mi aporte a esta hermosa comunidad. gracias platzy

Gracias profe David, su energía de enseñanza es motivadora.

Ocultando elementos HTML con JS para mejorar la UX del juego

Es importante recordar que en una página web no tenemos una sola cosa, tenemos HTML+CSS+JAVASCRIPT

Un genio Juan, gracias por las clases.