Crear un juego web Whack-a-Mole

JavaScriptJavaScriptBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este proyecto, aprenderás a crear un juego de Whack-a-Mole utilizando HTML, CSS y JavaScript. El juego consiste en golpear a los topitos que aparecen al azar de los agujeros dentro de un límite de tiempo especificado. Crearás los archivos HTML, CSS y JavaScript necesarios e implementarás la lógica del juego paso a paso.

👀 Vista previa

Juego web de Whack-a-Mole

🎯 Tareas

En este proyecto, aprenderás:

  • Cómo configurar los archivos del proyecto para el juego de Whack-a-Mole
  • Cómo agregar los estilos CSS necesarios para crear el diseño y la disposición del juego
  • Cómo implementar la lógica del juego para hacer que los topitos aparezcan y desaparezcan, llevar la cuenta de los puntos y controlar el tiempo
  • Cómo crear oyentes de eventos para golpear a los topitos y comenzar el juego

🏆 Logros

Después de completar este proyecto, podrás:

  • Crear archivos HTML, CSS y JavaScript para un juego basado en la web
  • Utilizar CSS para dar estilo y disposición a los elementos del juego
  • Manipular el DOM utilizando JavaScript para hacer que los elementos del juego aparezcan y desaparezcan
  • Manejar las interacciones del usuario y actualizar el estado del juego
  • Utilizar temporizadores en JavaScript para controlar el tiempo y el flujo del juego

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL javascript(("JavaScript")) -.-> javascript/DOMManipulationGroup(["DOM Manipulation"]) javascript(("JavaScript")) -.-> javascript/BasicConceptsGroup(["Basic Concepts"]) javascript(("JavaScript")) -.-> javascript/AdvancedConceptsGroup(["Advanced Concepts"]) javascript/BasicConceptsGroup -.-> javascript/functions("Functions") javascript/AdvancedConceptsGroup -.-> javascript/async_prog("Asynchronous Programming") javascript/DOMManipulationGroup -.-> javascript/dom_select("DOM Selection") javascript/DOMManipulationGroup -.-> javascript/dom_manip("DOM Manipulation") javascript/DOMManipulationGroup -.-> javascript/event_handle("Event Handling") subgraph Lab Skills javascript/functions -.-> lab-445717{{"Crear un juego web Whack-a-Mole"}} javascript/async_prog -.-> lab-445717{{"Crear un juego web Whack-a-Mole"}} javascript/dom_select -.-> lab-445717{{"Crear un juego web Whack-a-Mole"}} javascript/dom_manip -.-> lab-445717{{"Crear un juego web Whack-a-Mole"}} javascript/event_handle -.-> lab-445717{{"Crear un juego web Whack-a-Mole"}} end

Crear los archivos del proyecto

Primero, creemos los archivos del proyecto para el juego de Whack-a-Mole.

  1. cd a la carpeta ~/proyecto.
  2. Crea un nuevo archivo llamado index.html.
  3. Copia y pega el siguiente código en index.html:
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="styles.css" />
    <title>Whack-a-Mole!</title>
  </head>

  <body
    class="bg-gradient-to-r from-yellow-400 via-red-500 to-pink-500 flex items-center justify-center h-screen"
  >
    <div class="game bg-white p-8 rounded-lg shadow-2xl text-center">
      <h1 class="text-4xl font-bold mb-4 text-red-600">Whack-a-Mole!</h1>
      <p class="score text-2xl text-red-600">
        Puntuación: <span id="score">0</span>
      </p>
      <p class="time text-2xl text-red-600">
        Tiempo restante: <span id="time">0</span>
      </p>
      <button
        id="startBtn"
        class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded mt-4 transition duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-110"
      >
        Iniciar juego
      </button>
      <div id="grid" class="grid grid-cols-3 gap-4 mt-4">
        <!-- Aquí se agregarán los agujeros -->
      </div>
    </div>
    <script src="main.js"></script>
  </body>
</html>
✨ Revisar Solución y Practicar

Agregar los estilos CSS

  1. Crea un nuevo archivo llamado styles.css.
  2. Copia y pega el siguiente código en styles.css:
.game {
  width: 600px;
  border-radius: 2rem;
}

.hole {
  height: 0;
  padding-bottom: 100%;
  position: relative;
  background: #eee;
  border: 3px solid #ccc;
  border-radius: 50%;
  overflow: hidden;
}

.mole {
  width: 100%;
  height: 100%;
  background: #a0522d;
  border-radius: 50%;
  position: absolute;
  transform: translateY(100%);
  transition: transform 0.3s;
}

.mole.up {
  transform: translateY(0);
}

.mole.whacked {
  background: #008cff;
}

#startBtn {
  background-color: #0051ff;
  color: #fff;
  padding: 10px 20px;
  border-radius: 20px;
  border: none;
  cursor: pointer;
  transition: background-color 0.3s;
}

#startBtn:hover {
  background-color: #028a5f;
}
✨ Revisar Solución y Practicar

Agregar la lógica del juego

  1. Crea un nuevo archivo llamado main.js.
  2. Agregaremos el código JavaScript en los pasos siguientes.

Ahora, agreguemos la lógica del juego al archivo main.js.

  1. Abre el archivo main.js.
  2. Copia y pega el siguiente código en main.js:
const grid = document.querySelector("#grid");
const scoreDisplay = document.querySelector("#score");
const timeDisplay = document.querySelector("#time");
const startBtn = document.querySelector("#startBtn");
let holes = [];
let score = 0;
let lastHole;
let timeUp = false;
let gameTimer;
let countdownTimer;
let countdown;

function createHoles() {
  for (let i = 0; i < 6; i++) {
    const hole = document.createElement("div");
    const mole = document.createElement("div");

    hole.classList.add("hole");
    mole.classList.add("mole");

    hole.appendChild(mole);
    grid.appendChild(hole);

    holes.push(hole);
  }
}

function randomTime(min, max) {
  return Math.round(Math.random() * (max - min) + min);
}

function randomHole(holes) {
  const idx = Math.floor(Math.random() * holes.length);
  const hole = holes[idx];
  if (hole === lastHole) {
    return randomHole(holes);
  }
  lastHole = hole;
  return hole;
}

function peep() {
  // TODO: Implementar esta función en el Paso 3.
}

function startGame() {
  // TODO: Implementar esta función en el Paso 4.
}

function whack(e) {
  // TODO: Implementar esta función en el Paso 5.
}

createHoles();
// TODO: Implementar el resto del código en el Paso 6.

Este código define variables para almacenar referencias a varios elementos HTML e inicializa otras variables necesarias. También define varias funciones para crear agujeros, generar tiempos y agujeros aleatorios, hacer que los topitos aparezcan y desaparezcan, iniciar el juego y manejar los golpes a los topitos. Finalmente, crea los agujeros, agrega oyentes de eventos a los agujeros y configura el oyente de eventos de clic del botón de inicio.

✨ Revisar Solución y Practicar

Implementar la función peep

En este paso, implementaremos la función peep, que hace que los topitos aparezcan y desaparezcan al azar.

  1. Abre el archivo main.js.
  2. Localiza la función peep.
  3. Reemplaza el código existente con el siguiente código:
function peep() {
  const time = randomTime(200, 1000);
  const hole = randomHole(holes);
  hole.querySelector(".mole").classList.add("up");

  setTimeout(() => {
    hole.querySelector(".mole").classList.remove("up");
    hole.querySelector(".mole").classList.remove("whacked");
    if (!timeUp) peep();
  }, time);
}

Esta función establece un intervalo de tiempo aleatorio entre 200ms y 1000ms utilizando la función randomTime. Selecciona un agujero al azar utilizando la función randomHole y hace que el topo aparezca agregando la clase up al elemento del topo. Después del intervalo de tiempo especificado, el topo desaparece quitando la clase up. Si el juego no ha terminado (timeUp es false), la función se llama a sí misma recursivamente para que aparezca otro topo.

✨ Revisar Solución y Practicar

Implementar la función startGame

A continuación, implementaremos la función startGame, que inicializa el juego y comienza el temporizador.

  1. Abre el archivo main.js.
  2. Localiza la función startGame.
  3. Reemplaza el código existente con el siguiente código:
function startGame() {
  scoreDisplay.textContent = 0;
  timeUp = false;
  score = 0;
  peep();
  gameTimer = setTimeout(() => (timeUp = true), 10000);
  countdown = 10;
  timeDisplay.textContent = countdown;
  startBtn.disabled = true;
  countdownTimer = setInterval(() => {
    countdown--;
    if (countdown < 0) {
      clearInterval(countdownTimer);
      startBtn.disabled = false;
      return;
    }
    timeDisplay.textContent = countdown;
  }, 1000);
}

Esta función inicializa la puntuación, establece timeUp en false y restablece la visualización de la puntuación. Llama a la función peep para comenzar a que los topitos aparezcan. Inicia un temporizador de juego usando setTimeout para establecer timeUp en true después de 10 segundos. También configura un temporizador de cuenta atrás para actualizar la visualización del tiempo cada segundo. La cuenta atrás se establece inicialmente en 10, y cuando llega a 0, se cancela el temporizador de cuenta atrás, se habilita el botón de inicio y la función devuelve.

✨ Revisar Solución y Practicar

Implementar la función whack

Ahora, implementemos la función whack, que maneja el golpe a los topitos y actualiza la puntuación.

  1. Abre el archivo main.js.
  2. Localiza la función whack.
  3. Reemplaza el código existente con el siguiente código:
function whack(e) {
  if (!e.isTrusted || !this.querySelector(".mole").classList.contains("up"))
    return; // click falso detectado o el topo no está arriba
  score++;
  this.querySelector(".mole").classList.remove("up");
  this.querySelector(".mole").classList.add("whacked");
  scoreDisplay.textContent = score;
}

Esta función se llama cuando se hace clic en un topo. Verifica si el evento de clic es confiable (e.isTrusted) para evitar clics falsos. También verifica si el topo está actualmente arriba verificando si tiene la clase up. Si el clic es válido, incrementa la puntuación, quita la clase up del elemento del topo, agrega la clase whacked para indicar visualmente que el topo ha sido golpeado y actualiza la visualización de la puntuación.

✨ Revisar Solución y Practicar

Inicializar el juego y los oyentes de eventos

En este paso, inicializaremos el juego creando los agujeros y agregando oyentes de eventos a los agujeros y al botón de inicio.

  1. Abre el archivo main.js.
  2. Localiza la línea con la llamada a la función createHoles().
  3. Agrega el siguiente código después de la llamada a la función createHoles():
holes.forEach((hole) => hole.addEventListener("click", whack));

startBtn.addEventListener("click", startGame);

Este código agrega un oyente de eventos de clic a cada elemento de agujero. Cuando se hace clic en un agujero, se llama a la función whack. También agrega un oyente de eventos de clic al botón de inicio, que llama a la función startGame cuando se hace clic en él.

Prueba el juego Whack-a-Mole

Haga clic en el botón Go Live en la esquina inferior derecha de WebIDE y cambie a la pestaña Web 8080.

Botón Go Live de WebIDE

Esto abrirá el proyecto en la pestaña Web 8080.

Vista de la pestaña Web 8080
✨ Revisar Solución y Practicar

Resumen

En este proyecto, hemos creado los archivos del proyecto para el juego Whack-a-Mole. Hemos creado la estructura HTML, agregado estilos CSS e implementado la lógica del juego usando JavaScript. Los próximos pasos implicarían una mayor personalización y mejora del juego, como agregar sonidos, niveles y configuraciones de dificultad.