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

Eventos de click dinámicos

56/84
Recursos

Luego de que el usuario de tu videojuego haya seleccionado un mokepon para jugar, la lógica interna de la aplicación requiere capturar los ataques del personaje y renderizarlos hacia el HTML para que el usuario pueda interactuar con los botones.

Renderizado de los ataques

Comienza creando un <div> en el HTML y seleccionando el mismo desde el Javascript donde renderizaremos cada botón de ataque del mokepon seleccionado.

<div id="contenedorAtaques" class="tarjetas-ataques">
</div>
const contenedorAtaques = document.getElementById('contenedorAtaques');

Luego de haber capturado los ataques del mokepón seleccionado en la función extraerAtaques(), envía esta información a una nueva función llamada mostrarAtaques() donde crearemos el código HTML.

function extraerAtaques(mascotaJugador) {
    // ...
    mostrarAtaques(ataques)
}
function mostrarAtaques(ataques) {
    ataques.forEach((ataque) => {
        ataquesMokepon = `
            <button id=${ataque.id} class="boton-de-ataque">
                ${ataque.nombre}
            </button>
        `;
        // Renderizamos cada ataque del personaje
        contenedorAtaques.innerHTML += ataquesMokepon;
    });
    
    // Seleccionar botones luego de crearlos
    botonFuego = document.getElementById('boton-fuego');
    botonAgua = document.getElementById('boton-agua');
    botonTierra = document.getElementById('boton-tierra');

    // Agregar evento a los botones
    botonFuego.addEventListener('click', ataqueFuego);
    botonAgua.addEventListener('click', ataqueAgua);
    botonTierra.addEventListener('click', ataqueTierra);
}

Al crear el código nuevo código HTML para cada botón de los ataques del mokepon, tienes que tener en cuenta que debes seleccionar los mismos con document.getElementById() y posteriormente agregarle el evento al hacer clic con addEventListener().

Asegúrate también de borrar el código que tu aplicación ya no necesite, dado que ahora estamos creando código HTML dinámicamente. A diferencia de crear el código de forma estática, es importante evaluar el momento de captura de los elementos HTML y su posterior asignación de eventos.


Contribución creada por: Kevin Fiorentino (Platzi Contributor)

Aportes 213

Preguntas 88

Ordenar por:

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

Asi es como va aumentando la dificultad del curso:
Freddy: dificultad nivel 1
Juan: dificultad nivel 3
Estefany: dificultad nivel 5
Diego: dificultad nivel 1847
pero no me rendiré…

Capítulo UNO del curso de programación básica:

.
.
.
Capitulo CINCUENTA Y SEIS del curso de programación básica:

Les soy sincero, entendi todo lo que hizo, incluso me salio al pie del cañon!, peroooooo… si tengo q hacerlo por propia logica mia en alguna actividad totalmente diferente, dudo poder lograrlo!

y la verdad me ofusca de sobre manera saber q no voy a poder hacerlo solo!

el nivel de comprensión está aumentando exponencialmente para tratarse de un curso básico D: no me rendiré!!

Es verdad cuando dicen que la programación es frustrante, pasé tres horas buscando un error que simplemente era un espacio en blanco que no debía estar.

aquí estoy llorando, pero no me rendí.

Les dejo esto para que no les pase lo mismo que a mi…
Al momento de comparar los botones con el texto del botón no me coincidían, el problema era que tenia un espacio en blanco al inicio del texto de identificación de cada botón…

la corrección es súper fácil, pero me rompió la cabeza encantararla jejeje

simplemente erra eliminar el espacio, para que al momento de comparar el click del botón con la palabra Agua, Fuego o tierra Consideran en el if(e.target.textContent == Água’)

en el: e.target.textContent cuando esta malo me salía
" Agua" al corregirlo “Agua” sin el espacio en blanco

Ya en este punto el curso se pone mas intenso y complejo, sin embargo, es muy satisfactorio notar que estamos aprendiendo y que le damos vida al juego de diferentes maneras.

Qué se hace en esta clase:

  1. Se guardan en un array los 5 botones creados (recordemos que los botónes serán distintos de acuerdo al mokepón seleccionado)
    • A través de botones = document.querySelectorAll('.b-ataque')
  2. Se crea una función que va a iterar (recorrer) cada uno de los botones guardados en el array y les agregará un escuhador de eventos
    • Para la iteración se usa el método forEach del array botones.forEach((boton) => { }
    • Para que el escuchador de eventos sea dínamico se hace una validación dentro del mismo usando boton.addEventListener('click', (e) => { if (Condición) {código} })
  3. Se inyecta en una array nuevo el orden de los ataques seleccionados
    • A través de ataqueJugador.push('ATAQUE_SELECCIONADO')

Por si al ustedes buscar la propiedad textContent en el console no les aparece, como fue mi caso, tambien pueden buscar la propiedad innerText, y reemplazarla, a mi no me aparecía textContent, y al querer usarla me daba error, entonces usé innerText y la función funciona :v jaja. ![]()

A todos los que les de el error del ataque que se queda pegado en TIERRA. Esto se debe a haber dejado un espacio en blanco al momento de crear el botón, despues de la variable nombre. Entre ${ataque.nombre}</button>, no debe ir ningún espacio. Entonces cuando hace el IF jamás va a coincidir FUEGO o AGUA, porque estas comparando ‘🔥’ con '🔥 '. Siempre va ir a parar al “else”, es decir a la TIERRA. Hay lugares donde dejar espacios no tiene ninguna importancia, pero otros donde un simple espacio te puede romper todo el código. Saludos !

Por si los ocupas:

🔥
💧
🌱

Estube apunto de perder los pelos jajajaaj, por alguna razon al momento de validar los ataques que se guardaban en el array, al darle al primer boton de agua (de hipodoge) en el console log me marcaba que elegi tierra jajaja, resulta que al momento de declarar los ataques de cada mokepon, por accidente puse 2 espacios entre caracteres jajaja, siempre tengan cuidado, los espacios tambien cuentan 👀👀
![]()

Excelente curso, a los que dicen que se pasaron un poco, pues tengo una opinión, es un curso de introducción y están tratando de crear un juego desde cero y lo mas sencillo, solo puedo decir que es sublime el trabajo que están haciendo y créanme que esta muy resumido, normalmente meter tantos temas conlleva mucho mas tiempo y eso le da mucho merito al curso.

y pues si, es difícil de seguir para alguien que no tiene experiencia previa pero también tengamos en cuenta que para alguien que viene de cero es una mina de oro conocer aunque sea de forma resumida tantos temas, es una introducción larga pero funciona en ir a maquetado, estilizado, interactividad y creo que le implementan hasta backend, el curso esta mas que perfecto

solo les recuerdo que el aprender algo no es una carrera que el primero que llegue es el ganador, ES UNA MARATÓN, donde todo el que termine la carrera es un ganador, si es difícil, respiren, jueguen un rato y luego continúen, disfruten del curso, que es excelente y pues no vayan con prisa, vayan con calidad.

Mucha suerte a todos!!

A mí personalmente me desconcentra mucho, que cometa tantos errores de digitación, me distrae, deberían permitir a cada profesor llevar su teclado propio o usar su propio computador. No sé porque se enreda tanto al escribir y la explicación me toco repetir varios videos para entender 😦

Cada vez que Diego agrega una nueva linea o concepto. Esta clase estuvo potente.

Creo que hubiese sido interesante que, antes de ponerse a hacer todas las modificaciones en el código, hubiesen explicado a que se quería llegar concretamente. Es decir, mostrar un bosquejo de como se quiere que sea el nuevo funcionamiento y aspecto del juego. Porque así no entendemos por qué se hacen las cosas hasta que vemos el resultado final, y es bastante confuso.

si asi es el básico, como será el avanzado. no se rindan…

El profe Jorge utiliza mucho la palabra parse y significa:

“Parsing” significa analizar y convertir un programa en un formato interno que un entorno de ejecución pueda realmente ejecutar, por ejemplo el motor JavaScript dentro de los navegadores.

Fuente: https://developer.mozilla.org/es/docs/Glossary/Parse

Esta clase estuvo heavy! :’(

Siento que este curso, o al menos en este bloque con Diego es demasiado heavy para ser de los primeros cursos de la ruta. De hecho he tomado varios cursos y entiendo ciertas cosas pero teniendo conocimiento previo aun asi es dificil de entener, no me imagino a alguien que esta empezando “de cero” a ver este curso “de programacion basica”

Siempre me imprimia TIERRA pero lo solucione dejando espacios a los lados de los emoji:


e.target.textContent === ' 🔥 '
e.target.textContent === ' 💧 '

Si no les funciona bien la parte de e.target.textContent prueben con e.target.innerText y con las comillas dobles " ", me estaba fallando esto y lo solucioné cambiando a innerText

Al igual que a muchos, mi código no leía el evento (e), aun así lo reemplazara por el “Event” que sugirió Zoe.

Mi solución fue subir el llamado a la función secuenciaAtaque () al final de la función seleccionarMascotJugador() del seleccionarMascotaEnemigo() que propone la clase, con eso el código reconoció todo lo programado en esta y clases pasadas.

Lo comparto por si le sirve a alguien
No se rindan y sigamos aprendiendo!

¿A poco no? 🤣

Repite el video cuantas veces sea necesario, demorate, comprende, utilizalo y vence.

Sería buenísimo que explicaran qué es lo que se espera de estas funciones, pues para dejarnos los mini retos debemos entender qué es lo que se quiere hacer, personalmente tuve que adelantar la soluciones de los videos de los botones de ataque y bueno este iba igual y ya adelantado el video se entendió más claramente que es lo que se iba a hacer.

Terminé hasta aquí, deshabilitando los botones para que sólo sean cinco ataques y no más, pero no sé si después se vayan a usar…

amazing el curso

El profesor escribe " === " y no " == " al momento de la validación porque él está usando el operador de igualdad estricta. Les comparto este link para que puedan leer más sobre este y ver algunos ejemplos. ➡️ https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Strict_equality

el que explica aprende 2 veces

Al final solo vamos a tener 5 ataques para usar 1 por cada turno. Aqui las 3 vidas no estan siendo tomadas.

pasos de esta clase:
1-capturar y guardar cada boton de html generado en array botones.
2-por cada elemento del array botones crear el evento CLICK (el evento CLICK es un objeto con propiedades)
3-validar que 💧 o 🔥 o 🌱 esté dentro de textCont que a su vez está dentro de target y dentro del evento/objeto CLICK, para asi ir llenando el array ataqueJugador con AGUA FUEGO O TIERRA respectivamente.
4-montrar en la consola del navegador lo que va teniendo el array ataqueJugador.
5-cambiar color de fondo del boton al ser usado.

Mejor idea hubiera sido empezar un proyecto nuevo. cambiar todo lo que ya existia como si no sirviera confunde mucho mas. No me gusta para nada el metodo empleado al final de este curso

Vi comentarios que se desaniman por cometer errores. Pero eso siempre va a pasar. Sin ir mas lejos fíjense que al mismísimo Diego de Granda le pasa (Solo que ellos cortan y editan el video) pero noten esos detalles. Les puedo asegurar que él se paso un buen rato buscando cual fue el error! Siempre pasa, solo hay que tenerlo en cuenta y luchar contra eso!

Me parece excelente el nivel que esta tomando este curso abierto de programacion, ya que al principio era todo divertido y de facil comprension, pero ahora el nivel ha aumentado a tal punto que ya no es un curso basico de programacion y que mucha gente vea este curso de manera gratis y explicada me parece excelente

Quizás Diego De Granda no sea el profesor más gracioso como Freddy o carismático como Juan, pero no me cabe duda que es de los mejores profesores de Platzi, clase que da clase que entiendes.

Aquí te presento una lista sencilla de algunos grupos de métodos de JavaScript:
.

  • Métodos de selección de elementos HTML: Permiten seleccionar elementos HTML del documento, como document.getElementById(), document.getElementsByClassName(), document.getElementsByTagName(), document.querySelector(), document.querySelectorAll(), entre otros.
    .
  • Métodos de manipulación de contenido: Permiten manipular el contenido de los elementos HTML seleccionados, como innerHTML, textContent, setAttribute(), getAttribute(), removeAttribute(), appendChild(), removeChild(), entre otros.
    .
  • Métodos de manipulación de estilos: Permiten manipular los estilos CSS de los elementos HTML seleccionados, como style.setProperty(), style.getPropertyValue(), classList.add(), classList.remove(), classList.toggle(), entre otros.
    .
  • Métodos de eventos: Permiten agregar y remover eventos a los elementos HTML seleccionados, como addEventListener(), removeEventListener(), event.preventDefault(), event.stopPropagation(), entre otros.
    .
  • Métodos de arrays: Permiten manipular arrays y sus elementos, como push(), pop(), shift(), unshift(), splice(), slice(), map(), filter(), reduce(), entre otros.
    .
  • Métodos de objetos: Permiten manipular objetos y sus propiedades, como Object.keys(), Object.values(), Object.entries(), Object.assign(), Object.freeze(), Object.seal(), Object.create(), entre otros.

Y esto es programación básica 💀🧗

creo que se nos está haciendo muy difícil de entender a todos por que cuando pasamos con este nuevo maestro se dejaron de explicar punto a punto y eso es lo que nos ayudaba con los otros maestros, solo estamos copiando lo que hace el maestro pero no lo estamos entendiendo.

Lo siento… En la última clase se destruyó mi código y por más que vi el video de nuevo y pasé horas y horas buscando el error, perdí la cabeza y…

En la línea botones = document.querySelectorAll(’.BAtaque’) no se les olvide que antes de escribir BAtaque va un . (punto)

Porfe seria mas facil de entender si mantuviera la indentación 😦 😦 😦 😦 sus clases estan hardcore!!

Se me presentó un problema con contentText ya que al colocar el la función para ver el nombre de cada botón, unicamente imprimía la consola “TIERRA”,

y encontre una solución. Usar outerText, ya que al momento de colocarlo en el código y ver la web, funcionó : 🦾🦾🧑‍💻

este curso esta genial

Para los que borran las variables y los eventros de ataqueJugador y aun les sigue dando error; es por que deben agregar un espacio vacio al condicional. ya q el textContent tiene un espacio vacio despues del emoticon:

function secuenciaAtaque(){
    botones.forEach(boton => {
        boton.addEventListener('click',(e)=> {
            console.log(e)
            if(e.target.textContent === '🔥 '){
                ataqueJugador.push('FUEGO')
                console.log(ataqueJugador)
                boton.style.background= '#832b4b'
            }else if(e.target.textContent === '💧 '){
                ataqueJugador.push('AGUA')
                console.log(ataqueJugador)
                boton.style.background= '#832b4b'
            }else {
                ataqueJugador.push('TIERRA')
                console.log(ataqueJugador)
                boton.style.background= '#832b4b'
            }
        })
    });
}

Le añadí: boton.disabled = true para que además de cambiar de color el botón ya no esté activo, me quedó así:

function secuenciaAtaque() {
botones.forEach((boton) => {
boton.addEventListener(‘click’,(e)=>{
if(e.target.textContent =‘🔥’){
ataqueJugador.push(‘FUEGO’)
console.log(ataqueJugador)
boton.style.background = '#112F58’
boton.disabled = true
} else if(e.target.textContent
=‘💧’){
ataqueJugador.push(‘AGUA’)
console.log(ataqueJugador)
boton.style.background = '#112F58’
boton.disabled = true
} else{
ataqueJugador.push(‘TIERRA’)
console.log(ataqueJugador)
boton.style.background = '#112F58’
boton.disabled = true
}

    })
})

}

SOLO MIREN MIS COMMIT SE PUSE DIFICIL PERO NO ME RINDO

Javascript en la vida real 👹👹👹👺👺👺

USTEDES PUEDEN CREER QUE YO NO ENTENDI ABSOLUTAMENTE NADA XD

Cada vez más el curso va subiendo de dificultad, repasar las clases, ver los videos par de veces me ha ayudado a entender mejor que es lo que vamos haciendo.

En vez de cambiar el background puse para que el botón se deshabilite

Me encantó esta clase! Resulta super útil querySelectorAll.
Le dejo un enlace a una explicación sencilla de estos selectores.
document.querySelector y document.querySelectorAll

Que denso esta esto

Porfabor recuerden que son importantes los espacios, las comillas simples y dobles

Me ha costado horas sacar los errores, como que no detectaba el evento, que no podía ir a una variable o selecciónala, mismo que aparezcan los ataques en pantalla, ya no daba MAS!!! Pero lo que hice para solucionar esto fue, descargarme la carpeta de la ultima clase que avía visto, y en el visual estudio code los compare, para que yo viera lo que hice y lo que estaba escrito en el código del Js del curso (también compare el HTML), me di cuenta que había EN MI CODIGO espacios donde no IVAN, que había comillas dobles donde no debería, así que comencé a remplazar elementos y no me la puedo creer FUNCIONO!!! Mi codigo es el de Sonic Infinite, el del curso es el de los mokepones.![](

Por si a alguien le pasa a mi no me quería agarra en la consola los otros ataques solo me salía "Tierra", entonces empecé a buscar con los distintos lugares donde salía el texto y me funciono con innerHTML. ![](https://static.platzi.com/media/user_upload/image-55fa2f59-7df6-44a2-b223-1befe4f6472f.jpg)
Abandoné este curso hace 2 años, en ese tiempo hice 1 de html, css, js y github, cada uno básico, hice y publiqué mi página web estática, radiogotica.com, hace unos meses volví a este curso, voy poco a poco, a este punto el curso es otro nivel, definitivamente la programación es para gente muy aplicada y gracias a Freddy Vega en cada video que hace me da ánimos de seguir.
Para que no les ocurra un error de que solo sale tierra (En la consola) pueden ingresar un trim (), ya que eso les ayudara a eliminar caracteres o espaciados que no se necesitan ese momento, fue un error que me llevo horas solucionarlo. ![](https://static.platzi.com/media/user_upload/image-d46f64f7-c9ae-468c-a1e6-0464a6571ef9.jpg)
Quiero decir unas de las posibles razones por las que la función secuenciaAtaque() va en la zona de seleccionarMascotaJugador y es por el orden en que aparecen los elementos: me explico en primer lugar se elige la mascota del enemigo, en segundo lugar se cargan los ataques de la mascota y siguiente de esto si se pueden elegir los ataques mediante los clicks. ![](https://static.platzi.com/media/user_upload/image-704aa12a-de2d-4758-9e8a-074b48738279.jpg)

Si alguien les pregunta. Estoy en mi casa. jejeje

si te sale TIERRA CUANDO ELIJES LOS BOTONES EN LA CONSOLA ES LA SIGUIENTE LINEA QUE HAY UN ESPACIO DESPUES DEL CORCHETE DE ataque.nombe `\<button id=${ataque.id} class="boton-de-ataque BAtaque">${ataque.nombre}\</button>`   es sin ningun espacio entre las comillas
A lo mejor es porque yo soy muy tonto y no me entero de nada, pero el codigo funciona, en teoria no esta mal escrito, mi funcion "seleccionarpuchamonenemigo" esta funcionando y ejecuta todo lo que tiene que ejecutar, pero cuando hago que secuencia sea llamada desde ahi, no ejecuta la secuencia, pero cuando lo pongo arriba, lo ejecuta osea, el codigo no esta mal escrito solo no esta siendo llamado por alguna razon .\_. , es algun tipo de racismo entre funciones o algo asi XDxdxDXD ![](https://static.platzi.com/media/user_upload/imagen-0bea08ad-c8a1-4df5-80cd-3fbef4480ef8.jpg)

Aportes de entendimiento:

  • addEventListener('click', (e)
    • la e hace referencia al evento en si, que es el click, entonces traerá el dato de donde se le de click.
    • para poder ver a quien se le da click usamos el method target que aquí viene el botón, y este tiene sus propiedades como el id y la class
    • en el targetpodemos ver todas las propiedades que son parte de este elemento botón. y los elementos HTML se convierten en objetos. buscamos el textContent y para acceder el contenido seria target.textContent ya podemos validar cosas a partir de este valor.

Hola a todxs!
Si cuando seleccionan un botón no les sale ‘FUEGO’, ´TIERRA´o lo que tengan prueben esto:
En la función mostrarAtaques dejen toda la linea de código correspondiente a ataquesMokepon sin espacios, o sea, todo seguido.
Es la solución cuando vamos a verificar y nos sale un \n al lado del emoji.
Saludos

Si alguien tiene problema para hacer que el programa entre a las condicionales, puede ser por el uso de emojis. Logre solucionarlo usando e.target.id y usar el id de cada botón.

Es importante también mencionar que si seguimos dando clic en los ataques se seguiran agregando a nuestro arreglo, para ello podemos hacer una validación que no agregue mas luego de tener los 5.

if(ataqueJugador.length == 5){
return;
}

Esto nos permitira validar que en el momento que le demos clic y ya tengamos los 5 ataques no permitra agregar mas.

Información adicional: Sentencia return

Yo tuve un problema con el array de los ataques del jugador, debido a que siempre me indicaba que era Tierra en todos los casos.

Le pregunté a ChatGPT como solucionarlo y me sugirió un código en el cuál se compare el id del elemento e.target con los identificadores de los botones de ataque (‘boton-fuego’, ‘boton-agua’, ‘boton-tierra’) en lugar de comparar con el contenido de texto.

Así quedó mi código:

function secuenciaAtaque() {
    botones.forEach((boton) => {
        boton.addEventListener('click', (e) => {
            if (e.target.id === 'boton-fuego') {
                ataqueJugador.push('FUEGO');
                console.log(ataqueJugador);
                boton.style.background = '#112f58';
            } else if (e.target.id === 'boton-agua') {
                ataqueJugador.push('AGUA');
                console.log(ataqueJugador);
                boton.style.background = '#112f58';
            } else if (e.target.id === 'boton-tierra') {
                ataqueJugador.push('TIERRA');
                console.log(ataqueJugador);
                boton.style.background = '#112f58';
            }
            ataqueAleatorioEnemigo();
        });
    });
}

Debería haber una opción de LIKE a las clases
👍🏻 like a esta clase 🤯

No se si a uds les pasa, que al dar click una vez sobre el ataque, la rutina del addEventListener la hace 2 veces… muy extraño

💪 EY ES POSIBLE QUE EL “e” no les devuelva ningún valor, a mi me funcionó llamandolo en la función de “mostrar ataques” en lugar de la de la clase

Hasta este punto es donde extraño solo usar pseudocódigo. Pero no me rendiré.

Okey en mi caso yo no coloque emojis sino sus nombres literal Ejem: “Agua”, al principio tuve el mismo problema que la mayoría de aquí que cuando daba click a un boton y le daba a varios siempre salia era TIERRA, mi solucion, luego de tanto ver comentarios de mis compañeros y pensar, volvi a hacer un console.log(), pero esta vez meti nuevamente el (e) para ver si realmente me aparecia el nombre por textContent o por InnerText, al percatarme que fue por InnerText lo que hice fue modificar el cont por inner y listo problema resuelto!! Ejemplo:
Antes: else if (e.target.textContent === “Agua”)
Ahota: elsse if(e.target.InnerText === “Agua”)

Por este espacio que agregué en el ciclo forEach de ataques me aparecía que todos eran tierra lo quité y todo funcionó.

Es una percepción muy personal pero esto no me parece que sea programación básica. En este momento trato de digerir lo que hemos visto hasta ahora pero la verdad aun me es difícil internalizar algunos conceptos de los que explica. Por otro lado el tema de los errores, se entiende que va a ser el día a día pero preferiría que este tipo de cosas se pudieran tratar con una didáctica distinta. Los cambios hacen que de cierta manera confundan mas a lo que empezamos desde cero. Ojo que no dudo de lo experto que es el Profe Diego pero lo que esta tratando de enseñar yo lo fuera puesto en niveles mas avanzados.

nivel de dificultad a este punto es de 1000 pero no me rendiré seguiré tratando de romper el algoritmo.

Fue una de las clases que más me llevó tiempo buscando mis propios errores en algunas funciones pasadas, pero me siento orgulloso de mi al haber encontrado los fallos. Ahora existe un pequeño detalle el botón cambia de color, pero puedo seguir seleccionado muchos mas ataques. Lo he solucionado agregando la línea boton.disabled = true

<code> 
function secuenciaAtaque() {
    botones.forEach((boton) => {
        boton.addEventListener('click', (e) => {
            if (e.target.textContent === '🔥') {
                ataqueJugador.push('FUEGO')
                console.log(ataqueJugador)
                boton.style.background = '#112f58'  
                boton.disabled = true 
            } else if (e.target.textContent === '💧') {
                ataqueJugador.push('AGUA')
                console.log(ataqueJugador)
                boton.style.background = '#112f58'
                boton.disabled = true
            } else {
                ataqueJugador.push('TIERRA')
                console.log(ataqueJugador)
                boton.style.background = '#112f58'
                boton.disabled = true
            }
        })
    })
    ataqueAleatorioEnemigo()
}

Para los que hayan puesto una imagen encima del boton en vez de un texto, y quieran que el PointerEvent no reconozca la imagen sino solamente el boton, existe una propiedad en css llamada “pointer-events” donde al ponerle

pointer-events: none

Anulará todos los Eventos del Puntero en ese elemento y seleccionará en este caso solamente el boton.

“Populating” es un término común en programación que se refiere a llenar una estructura de datos con valores. Por ejemplo, si tienes un array vacío y deseas llenarlo con números, puedes “populate” el array con esos valores.

document.querySelectorAll()
.
Este un método de JavaScript que devuelve una lista de todos los elementos que coinciden con un selector CSS especificado. La sintaxis de este método es la siguiente:

document.querySelectorAll(selectores);

Donde “selectores” es una cadena de texto que contiene uno o más selectores CSS separados por comas. Por ejemplo, para seleccionar todos los elementos p y h1 del documento, podemos usar el siguiente código:

var elementos = document.querySelectorAll("p, h1");

.
El método document.querySelectorAll() devuelve una lista de nodos llamada NodeList, que es similar a un array y contiene todos los elementos que coinciden con el selector CSS especificado. Podemos acceder a cada elemento en la lista utilizando su índice, como se hace con un array.
.
Una vez que tenemos la lista de elementos, podemos hacer operaciones en ellos, como cambiar su estilo, añadir o eliminar contenido, o manipular sus atributos.
.
Es importante tener en cuenta que document.querySelectorAll() devuelve todos los elementos que coinciden con el selector especificado, incluso si hay varios elementos con el mismo identificador. También es importante tener en cuenta que la lista de elementos devueltos por document.querySelectorAll() se actualiza dinámicamente si se agregan o eliminan elementos que coinciden con el selector especificado.

tuve que cambiar textContent por innerText, ya que en el array me arrojaba solo “TIERRA”.
algo que pude haber hecho mal?

function secuenciaAtaque() {
botones.forEach((boton) => {
boton.addEventListener(“click”, (e) => {
if (e.target.innerText === “🔥”) {
ataqueJugador.push(“FUEGO”)
console.log(ataqueJugador)
boton.style.background = “#112f58”
} else if (e.target.innerText === “💧”) {
ataqueJugador.push(“AGUA”)
console.log(ataqueJugador)
boton.style.background = “#112f58”
} else {
ataqueJugador.push(“TIERRA”)
console.log(ataqueJugador)
boton.style.background = “#112f58”
}
})
})
}

Me tomo 2 días terminar este modulo, la verdad que es todo un reto, al final nunca pude acceder al console.log(e) me seguía marcando error, sin embargo logré hacer que los botones entren dentro del array y que cambien de color al seleccionarlos.

Es increible la forma en que se puede usar una funcion para pintar los elementos del JS. Me quede impresionado, sabiendo que solo se usa en un pequeño juego. La verdad en una verdadera pagina web u otro viedojuego debe tener un monton de codigo que debe marear la verdad.

Al cambiar el codigo de la logica de Stefany, se debe implementar esta nueva logica.
Como es un curso basico era mejor dejarlo con los 3 botones de ataque y no 5, para no complicar las cosas

Quiero aportar en esta clase algo que me paso al momento de crear la secuencia de ataques.
En mi proceso, estuve buscando el target Text content , y no me aparecia la informacion ahi, sino que si me aparecia en Target.innerText . Probe y se me resolvio el problema. Lo comparto y quien tenga una observacion productiva para mi codigo, bienvenido sea:

function secuAtaques() {
botones.forEach((boton) => {
boton.addEventListener(‘click’, (e) => {
if (e.target.innerText ===‘🔥’) {
ataqueJugador.push(‘FUEGO’)
console.log(ataqueJugador)
boton.style.background ="#112f58"
} else if (e.target.innerText ===‘💧’) {
ataqueJugador.push(‘AGUA’)
console.log(ataqueJugador)
boton.style.background ="#112f58"
} else {
ataqueJugador.push(‘TIERRA’)
console.log(ataqueJugador)
boton.style.background ="#112f58"
}
ataqueAleatorioEnemigo()
})
})
}

Si quieren en vez del style.background, pongan de una vez el

boton.disable = true

Así queda deshabilitado el botón luego de hundirlo

Me duele un poco ver que borre tantas líneas de código.

Cuando yo inicié en la programación me enseñaron a no borrarlas sino comentarlas porque en un futuro se podría revisar mejor cuáles fueron los posibles errores (por ej: la clase anterior dónde se lleva el botón de Reiniciar en vez del de Tierra y tiene que volver a copiar y pegar todo en su lugar nuevamente)

Solía borrar todo lo comentado una vez finalizada la aplicación para dejar el código más prolijo.

bueno vamos bien, excelente curso 👹

Después de ponerle el background también podríamos ponerle “disabled = true” para que cuando se le de click a un botón, este quede desactivado y no se le pueda volver a dar click

Al principio dije “joder, si yo prefiero jugar con vidas que el mejor de 5 partidas” luego pensé “pues con tal de aprender, puedo crear un nuevo branch en github para esta versión” y problema resuelto ! Jeje. Recomendación: creen otra rama para esta clase y así conserven el código anterior si lo prefieren en esos aspectos.

Realmente me sorprende el clavado en profundidad que ha tomado este curso, en lo más mínimo parece programación básica, a mi me agrada, me lleva a un contexto desde donde puedo ampliar, engordar digo yo, los conocimientos. Sigo adelante con más ganas que nunca.
No pares de aprender dicen por ahí.

Me esta costando una locura!! 😅

A este punto es mas complejo de entender, pero hay que darle esfuerzo, este profe es mas técnico que los anteriores. 😉

El curso se esta poniendo bastante complejo y a veces me cuesta razonar estas cosas tan dinamica 🥴

Recomiendo que después de agregarle el “.style” a los botones, agreguen también un “.disabled = true” para que dicho botón no vuelva a guardar nuevamente la información del ataque en el arreglo.
Para que quede de esta manera:
" if (e.target.outerText === 🔥) {
ataqueJugador.push(FUEGO);
console.log(ataqueJugador);
boton.style.background= linear-gradient(to bottom right, rgba(66, 6, 6, 0.5), rgba(71, 71, 4, 0.5))
boton.disabled = true;
}"

Agrego, en mi caso no aparecía como “textContent” la propiedad del contenido del botón, sino como “outerText”, a lo que funciona de igual manera.

Ta fuerte!

hay que terminar

Están fuertes estas clases me volví a repasar todo desde el principio, haciéndolo yo solo o adelantándome al profesor, ya sea con el CSS, las funciones los ciclos pero al llegar con este profesor todo se me complica xD. Pero seguiremos hasta el final banda.

una nota que quiero hacer para el minuto 2:25 al 2:29 y es que indica que los id no se deben de repetir ya que es una mala práctica. Pues en este caso estamos repitiendo el id de tres de los 5 botones que creamos. Se debería revisar esto, no sé si lo harán más adelante, pero creo que puede dar a confusión. Por otro lado crea una nueva clase que se llama BAtaque y el dice botón de ataque, que si nos fijamos ya está creada y podríamos aprovecharla para hacer el querySelectorAll, pero bueno esto es mi percepción, de hecho así es como lo voy haciendo, poniendo los nombres de variables, ids y clases como son más descriptivos para mi. Sigamos con la clase....
Buen día, tengo un inconveniente. Me aparecen solamente ataque "TIERRA" al darle clic en cualquier botón. ![](https://i.ibb.co/mS2q6tG/Captura-de-pantalla-2024-07-31-090713.png)![]()![](file:///C:/Users/DLM/Pictures/Screenshots/Captura%20de%20pantalla%202024-07-31%20090713.png)![](https://ibb.co/nRYczfb)
Me había quedado bieen perdido, vi esta misma clase y algunas de las anteriores varias veces hasta que me quedo bien claro. El problema era que tenía una lógica un poco distinta a la que se tiene en la función que decide quien gana y las funciones que fueron eliminadas en esta clase. Me tomo un día completo pero por fin pude hacer que el código volviera a funcionar. No se rindan panas! ![](https://static.platzi.com/media/user_upload/image-68108b76-07fe-4b9f-8d44-b5a35c66e058.jpg)
Por alguna razón mi TextContent no solo traía el Emoji solo, lo que provocaba que no encontrara la coincidencia en el código, en su lugar, use la propiedad de target.outerText. Cambiando esto mi código funciono correctamente. ![](https://static.platzi.com/media/user_upload/image-efa5e87c-51b1-476d-8140-187521330d0b.jpg)
![](https://static.platzi.com/media/user_upload/image-373050f0-09d2-4b23-ab42-86f8fcc3514b.jpg) Por alguna rason mi TextContent no solo traia el emogi, lo que hacie que no encontrara la coincidencia en el codigo, en su lugar, use la propiedad de target.outerText, la cual al estar revisando, en mi caso, solo traia el emogi. Cambiando esto mi codigo funciono correctamente. ![](https://static.platzi.com/media/user_upload/image-63537cde-8784-4efa-a2a0-ab69e450442a.jpg)
cómo es que cada clase de este man termino trasnochando intentando resolver algo, para que al final sea que no deje un espacio entre un" /"