Programar un combate entre mascotas en JavaScript exige que el ataque del enemigo se dispare en el mismo momento en que el jugador elige fuego, agua o tierra. La clave está en encadenar funciones, usar una variable global y aplicar aleatoriedad con condicionales para que el rival responda solo, sin botones extra.
¿Cómo se conecta el ataque del jugador con el del enemigo?
La lógica parte de un detalle simple: el enemigo no tiene su propio botón. Su ataque debe ejecutarse justo después de que tú elijas el tuyo.
Para lograrlo, dentro de cada función de ataque del jugador (ataqueFuego, ataqueAgua, ataqueTierra) reemplazas la alerta original por una llamada a una nueva función: ataqueAleatorioEnemigo. Así, cualquier clic en los tres botones dispara dos cosas en cadena:
Guarda el ataque del jugador en su variable global.
Llama a la función que genera el ataque del enemigo.
¿Por qué llamar una función dentro de otra en JavaScript? Porque permite encadenar comportamientos sin crear nuevos eventos. Si dos acciones siempre ocurren juntas, una puede invocar a la otra directamente.
¿Por qué evitar nombres iguales entre variable y función?
Al principio la función se llamaba ataqueEnemigo, igual que la variable global donde se guardaba el resultado. JavaScript se confunde y tú también.
La solución fue renombrar la función a ataqueAleatorioEnemigo y dejar la variable como ataqueEnemigo. Lo mismo pasó con mascotaAleatoria, que antes se llamaba ataqueAleatorio aunque guardaba mascotas, no ataques. Nombrar bien evita bugs silenciosos.
¿Cómo se generan los ataques aleatorios del enemigo?
La aleatoriedad se resuelve con la función aleatorio, que ya existía en el proyecto y devuelve un número entre dos límites. En este caso, entre 1 y 3.
Cada número representa un elemento:
Fuego.
Agua.
Tierra.
Es el mismo patrón de piedra, papel o tijera del curso de Freddy, solo que con los elementos del juego. Dentro de ataqueAleatorioEnemigo se crea la variable ataqueAleatorio con el número generado, y a partir de ahí los condicionales asignan el ataque correspondiente.
¿Cómo se estructuran los condicionales?
El flujo usa if, else if y else para cubrir las tres posibilidades sin redundar:
javascript
function ataqueAleatorioEnemigo() {
let ataqueAleatorio = aleatorio(1, 3);
El else final cierra la lógica: si no es 1 ni 2, solo queda 3, así que no hace falta otro else if. Menos código, mismo resultado.
¿Qué es una variable global en JavaScript? Es una variable declarada fuera de cualquier función. Se puede leer y modificar desde cualquier parte del código, incluso desde la consola del navegador.
¿Cómo verificar que el código funciona desde la consola?
Al recargar la página y dar clic en fuego, agua o tierra, en pantalla no pasa nada visible. Eso es esperado: por ahora solo guardas valores en variables globales.
La prueba se hace en la consola del navegador. Si escribes ataqueJugador después de hacer clic en agua, devuelve Agua. Si escribes ataqueEnemigo, devuelve el ataque aleatorio que se generó en ese mismo clic. Cada clic actualiza ambos valores: el del jugador queda fijo según el botón, y el del enemigo cambia con cada llamada porque depende del número aleatorio.
Esto confirma tres cosas:
Las funciones encadenadas se ejecutan en orden.
Las variables globales conservan el último valor asignado.
La aleatoriedad funciona en cada clic, no solo la primera vez.
Lo que falta es traducir todo esto en mensajes visibles para el jugador, porque pedirle a alguien que abra la consola para jugar no es opción. Cuéntame en los comentarios cómo resolviste tú esta parte antes de ver la solución.
A este punto ya se va complicando un poco el tema con tanto codigo. Pero no me rendire ya quiero ver este videojuego terminado.
Hola, estamos igual. Por suerte los profes son muy buenos para explicar. Paciencia, vas a ver que te va a ir muy bien!!!
Hola muchachos, les recomiendo que no se desesperen, tomen esto como un abrebocas, mas adelante encontraran cursos donde se explican mejor estos temas
Me adelanté a realizar la lógica de la función del ataque enemigo y me siento re feliz de que sí me salió parecida a la del profesor, muy muy parecida. Me siento increíble de que cada vez voy mejorando :D
:tada::clap::tada::clap::tada:
JAJAJA yo quiero vivir esa experiencia
La comunidad es tan hermosa al compartir sus cosas, pero admito que me pone ansiosa ver como cada uno le agrega su toque personalizado a su código mientras que yo apenas le voy llevando el ritmo al profe jsjs :'(
Me pasa lo mismo jajajjaj
a mi también me pasa igual , con trabajos le entiendo al prof
A mi se me ocurrió utilizar una variable global de tipo arreglo (ataquesDisponibles), en la cual almacené los ataques disponibles, para que luego, dentro de la función ataqueAleatorioEnemigo(), se le asignara a otra variable global (ataqueEnemigo) el ataque del enemigo de manera aleatoria.
let ataquesDisponibles =["FUEGO 🔥","AGUA 💧","TIERRA 🌱"]let ataqueJugador
let ataqueEnemigo
functioniniciarJuego(){//variableslet botonMascotaJugador =document.getElementById("boton-mascota");//eventos botonMascotaJugador.addEventListener("click", seleccMascotaJugador);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)}//FUNCIONES PARA MASCOTASfunctionseleccMascotaJugador(){let inputHipodoge =document.getElementById("hipodoge");let inputCapipepo =document.getElementById("capipepo");let inputRatigueya =document.getElementById("ratigueya");let mascotaSeleccJugador =document.getElementById("mascota-jugador");let mascotaActualJugador ="";if(inputHipodoge.checked){ mascotaActualJugador ="Hipodoge";alert("Has a seleccionado a "+ mascotaActualJugador); mascotaSeleccJugador.innerHTML= mascotaActualJugador;}elseif(inputCapipepo.checked){ mascotaActualJugador ="Capipepo";alert("Has a seleccionado a "+ mascotaActualJugador); mascotaSeleccJugador.innerHTML= mascotaActualJugador;}elseif(inputRatigueya.checked){ mascotaActualJugador ="Ratigüeya";alert("Has a seleccionado a "+ mascotaActualJugador); mascotaSeleccJugador.innerHTML= mascotaActualJugador;}else{alert("Selecciona tu mascota");}seleccMascotaenemigo()}functionseleccMascotaenemigo(){let ataqueAleatorio =aleatorio(1,3)let mascotaSeleccEnemigo =document.getElementById("mascota-enemigo");let mascotaActualEnemigo ="";if(ataqueAleatorio ==1){//Hipodoge mascotaActualEnemigo ="Hipodoge" mascotaSeleccEnemigo.innerHTML= mascotaActualEnemigo;}elseif(ataqueAleatorio ==2){//Capipepo mascotaActualEnemigo ="Capipepo" mascotaSeleccEnemigo.innerHTML= mascotaActualEnemigo;}else{//Ratigüeya mascotaActualEnemigo ="Ratigüeya" mascotaSeleccEnemigo.innerHTML= mascotaActualEnemigo;}}functionaleatorio(min, max){returnMath.floor(Math.random()*(max - min +1)+ min);}//FUNCIONES PARA ATAQUESfunctionataqueFuego(){ ataqueJugador ="FUEGO 🔥"alert(ataqueJugador)let spanAtaqueJugador =document.getElementById("ataque-jugador") spanAtaqueJugador.innerHTML= ataqueJugador
ataqueAleatorioEnemigo()}functionataqueAgua(){ ataqueJugador ="AGUA 💧"alert(ataqueJugador)let spanAtaqueJugador =document.getElementById("ataque-jugador") spanAtaqueJugador.innerHTML= ataqueJugador
ataqueAleatorioEnemigo()}functionataqueTierra(){ ataqueJugador ="TIERRA 🌱"alert(ataqueJugador)let spanAtaqueJugador =document.getElementById("ataque-jugador") spanAtaqueJugador.innerHTML= ataqueJugador
ataqueAleatorioEnemigo()}functionataqueAleatorioEnemigo(){ ataqueEnemigo = ataquesDisponibles[Math.floor(Math.random()* ataquesDisponibles.length)]let spanAtaqueEnemigo =document.getElementById("ataque-enemigo") spanAtaqueEnemigo.innerHTML= ataqueEnemigo
}window.addEventListener("load", iniciarJuego);//otra manera de llamar al script después de que se cargue todo el HTML//la función iniciarJuego se carga cuando ya todo el contenido está cargado.
eso mismo hice, me parece una mejor solucion, pero que no la implementaron acá porque todavia no se vieron los arrays en el curso.
de igual manera se soluciona con una funcion que retorna el valor del atributo
Aquí mi manera dejar saber al usuario el ataque del enemigo después de elegir su ataque.
Buen trabajo.
Un detalle con los botones de ataque es que deberian habilitarse solamente cuando escojamos nuestra mascota.
Esto es muy facil, en el html cuando creamos los botones, le agregamos la propiedad disabled, así estarán deshabilitados en un inicio.
Ahora nos vamos al javascript, por el momento tenemos la logica de los botones en la función iniciar juego, estas lineas las podemos mover a una función nueva llamada habilitarBotonesAtaque(), dicha función la utilizariamos al final de la función seleccionarMascotaJugador().
En la función que creamos, vamos a ir por cada botón habilitandolo con la propiedad .disabled (la misma que colocamos en el html). Le colocamos que su valor sea false, ya que en un primer momento su valor es true. Nos quedaria de la siguiente forma:
Todo el código con el nuevo orden que le dimos quedaria así:
Muy bien! Algo así vamos a hacer en las últimas clases de este módulo :D
wow es mucho por procesar ;-; ksjksj
También tenemos otra forma de escribir las funciones llamada "Función Flecha" que normalmente se utiliza con funciones cortas para que el código se vea mas compacto. Ambas formas funcionan pero ésta última tiene algunas limitaciones. mas información al respecto aquí: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Functions/Arrow_functions
También para aquellos que tengan un nivel de inglés intermedio es bueno para practicar que lo traduscan todo al inglés (nombres de variable, funciones, etc). de esa manera se van acostumbrando para cuando les toque leer el codigo de alguien más (lo que según me dijeron pasa seguido).
Les dejo como va mi código hasta ahora y cualquier correción y crítica constructiva sobre como mejorarlo es bienvenida.
Tienes toda la razon
Muchas gracias esta excelente !!!!
Hola comunidad, ¿cómo están?
Considero más efectivo realizar el proyecto Mokepón con diferente temática pero con misma lógica.
Es por eso que me he puesto a la tarea de realizar un juego algo diferente.
He aquí mis avances en el navegador
también un poco de mi código:
Html:
<<!DOCTYPE html><html><head><meta charset="uft-8"/><title>Leyendsof warriors</title><script src="./Js/Leyends of warriors.js"></script></head><body><h2>¡Leyends of warriors! ⚔️</h2><!--S.SELECCIONARPERSONAJE--><section id="Seleccionar-guerrero"><h3>Opta por el guerrero de tu preferencia:</h3><label for="ballista">Ballista</label><input type="radio" name="guerrero" id="ballista"/><label for="espadachin">Espadachin</label><input type="radio" name="guerrero" id="espadachin"/><label for="infante">Infante</label><input type="radio" name="guerrero" id="infante"/><button id="boton-guerrero">Poseer</button></section><!--S.ATAQUES--><section id="Seleccionar-arremetida"><h3>Opta por la arremetida de tu preferencia:</h3><p>Tu guerrero <span id="guerrero-jugador"></span> posee <span>3</span> vidas</p><p>El guerrero enemigo <span id="guerrero-enemigo"></span> posee <span>3</span> vidas</p><p><button id="boton-ballesta">Ballesta 🏹</button><button id="boton-espada">Espada 🗡</button><button id="boton-hacha">Hacha 🪓</button></p></section><section id="avisos"><p>Tu guererto ha atacado con Ballesta, el guerrero enemigo ha atacado con Espada- ¡la victoria es tuya! 🎊</p></section><section id="reiterar"><button id="boton-reiterar">¡Vuelve a luchar!</button></section></body></html>>
Espero que este proyecto pueda concluirse exitosamente, sin más, gracias por llegar hasta el final. Espero que les guste. :D
esta buenisimo
Algún día podré hacer un aporte :( , por el momento estaré siguiendo las instrucciones de Juan :D
Este es mi aporte, me funciona perfectamente :D}
functionataqueFuego(){ ataqueJugador ='FUEGO'alert(ataqueJugador)ataqueEnemigo()}functionataqueAgua(){ ataqueJugador ="AGUA"alert(ataqueJugador)ataqueEnemigo()}functionataqueTierra(){ ataqueJugador ='TIERRA'alert(ataqueJugador)ataqueEnemigo()}functionataqueEnemigo(){let variableAtaqueEnemigo =aleatorio(1,3)if(variableAtaqueEnemigo ==1){alert('El ataque de tu enemigo es de Fuego')}elseif(variableAtaqueEnemigo ==2){alert('El ataque de tu enemigo es de Agua')}else{alert('El ataque de tu enemigo es de Tierra')}}
Ufff está clase la tuve que repetir varias veces, no me arrojaba ningún resultado, al final, me di cuenta que no tenía declarada la variable global.
Mi codigo no arroja error, pero tampoco me esta arrojando la variables en consola como a Juan David, me dice "undefined", por lo que de seguro tengo algun fallo. Alguna recomendacion de como depurar el codigo?, algun tip?, herramienta? Gracias¡¡
Deja ver tu codigo
Leonardo a mi también me pasó lo mismo, pero después de revisar varias veces mi código; me di cuenta que "undefined" aparece cuando una variable no ha sido declarada, entonces intente seleccionando primero mi ataque y ahora si arrojaba el ataque del enemigo. Creería que esto se debe a que en el código lleva un orden y debe cumplirse primero el ataque del Jugador para poder ejecutar la función "ataqueEnemigo".
y pensar que hace un mes no sabia nada de codigos y empece en PLATZI , ahora entiendo lo que escriben en cada linea de codigo! no me atrevo aun a irme solo por el mar de los codigos! pero no me rendire y seguire aprendiendo un poco cada dia mas! NUNCA PAREMOS DE APRENDER
Estuve un rato tratando de ver como resolver el minireto hasta que recorde una frase de cursos anteriores de "No reinventar la rueda" y fui a ver el codigo que habiamos hecho con Freddy y ahi continue con esa logica que me parecia bastante acertada, por suerte, quedo funcional el codigo
Le agregue un par de cosas para que en los alert diga que pokemon ataca pj
Siendo sincero, me gusta mas como lo hizo el profe, es mas agradable a la vista, me falta calle
Este es mi primer aporte, realmente no necesite preguntar o escribir nada en esta seccion de comentarios, pero este es un momento especial, al fin logre realizar por mi mismo mi parte del código que el profe dijo antes de ver su respuesta, parece tonto pero las ultimas veces no pude lograrlo por mi mismo y me fastidiaba, pensaba que no había aprendido nada y que era inútil, que solo calqueo que el profe dictaba y listo, pero por fin veo que algo esta funcionando, lento pero si funciona.
lo que intente fue que cuando el jugador eligiera cualquiera de los botones de ataques elementales, osea fuego, agua y tierra, te saliera un alert, pero que al instante despues tambien te saliera un alert para la eleccion del rival que es completamente aleatoria, reutilize la logica aleatoria del piedra papel y tijeras, y lo cambie por los elementos, y asi al momento de elegir por ejemplo fuego, el rival tambien elige uno de forma aleatoria.
hay un monton de cosas que se pueden mejorar, pero estoy orgulloso del bebe que logre crear, esta feo, pero al menos respira ajajjaa 😅.
igualmente a veces siento que no comprendo bien las cosas y cuando menos me doy cuenta ya estoy creando algo de codigo por mi cuenta
agosto 2024.
a mi me paso lo mismo, este fue el primer ejercicio de parar la clase que pude resolver, es realmente satisfactorio, además que pensaba exactamente lo mismo, de que pareciera que solo calcaba lo que decía el profe
es imposible entenderlo,, tantas funciones muy complicado mantener encendido el cerebro 🤣🤣
Jajajaja es normal, a mi también me pasa, y más porque deje el curso unos días y acabo de regresar, tuve que darle una leída a todo el código de HTML y JS para recordar que hacia cada cosa, más adelante tengo entendido veremos como ir dividiendo por módulos las funciones, es decir, las funciones que se relacionen van en un archivo, otras en otro archivo y así sucesivamente… se supone que eso ayuda a que sea más legible el código y también cuando se necesita modificar algo es más fácil encontrarlo pero ya estoy imaginando como nos dará vuelta la cabeza jajajajaja seguro que poco a poco esto que se nos complica un poco será pan comido más adelante!!!
Clase 24 y la cosa se complica cada vez más. Pero aquí estamos para no rendirnos y aprender.
Nota mental, nombrar correctamente las variables para evitar cambios futuros o al menos poner notas que te ayuden a guiarte por tu código, no copiar solo lo que menciona el instructor, sino razonar la lógica del juego
En este punto me empezó a sudar la frente 🤣
 vendría a ser el id que no puse en el HTML . La consola dice que el error es debido a que no puede leer propiedades vacías, y esto puede ocurrir ya sea por que cambiamos de ubicación el document HTML o por lo ya mencionado. Recuerden que JS es sensible a mayúsculas.