Diseño de juegos de cerdos usando JavaScript

En este artículo, explicaremos los pasos y varias lógicas requeridas para hacer el famoso Pig Game, que es un juego de dados virtual. 

Acerca del juego: en este juego, la interfaz de usuario (UI) contiene usuario/jugador que puede hacer tres cosas, son las siguientes:

Habrá dos jugadores en este juego. Al comienzo del juego, el jugador 1 será el jugador actual y el jugador 2 será el inactivo .

  1. Tirar los dados: el jugador actual tiene que tirar los dados y luego se generará un número aleatorio. Si el jugador actual obtiene cualquier número que no sea 1 en los dados , ese número se agregará al puntaje actual ( inicialmente, el puntaje actual será 0 ) y luego el nuevo puntaje se mostrará en la sección de puntaje actual .  Nota: si el jugador actual obtiene 1 en los dados , los jugadores se cambiarán, es decir, el jugador actual quedará inactivo y viceversa.
  2. Retener: si el jugador actual hace clic en ESPERAR , el puntaje actual se agregará al puntaje total . Cuando el jugador activo hace clic en el botón Retener, se evalúa la puntuación total. Si la puntuación total es >= 100 , el jugador actual gana; de lo contrario, se cambian los jugadores.
  3. Restablecer: todos los puntajes se establecen en 0 y el jugador 1 se establece como el jugador inicial (jugador actual).

Realización del juego: al ser un juego renderizado por el navegador web, está construido con la ayuda de HTML, CSS (para el front-end) y JavaScript (para el back-end). La lógica principal del juego radica en el archivo JS, mientras que la apariencia y la interfaz de usuario se representan mediante HTML y CSS. En este proyecto existen básicamente cuatro tipos de archivos:

  • Archivo HTML (index.html)
  • Archivo CSS (estilo.css)
  • Archivo JavaScript (archivo script.js)
  • Imágenes (archivo dice.png)

Analizaremos todos estos archivos y así te haremos entender su trabajo/contribución en este juego. Entonces, primero comencemos con el archivo index.html :

Archivo HTML: el archivo Index.html es el archivo que hace que los navegadores web entiendan y, por lo tanto, interpreten qué tipo de documento estamos haciendo. Son las siglas de Hyper Text Markup Language , nuestros navegadores web leen este archivo y entienden su componente a través del motor V8 (que analiza el código en un idioma para que el navegador pueda entenderlo). A continuación se muestra el código HTML de este juego:

HTML

<!DOCTYPE html>
<html lang="en">
  
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content=
        "width=device-width, initial-scale=1.0" />
  
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="style.css" />
    <title>Pig Game Design using JavaScript</title>
</head>
  
<body>
    <div class="container">
        <section class="player player--0 player--active">
            <div class="tscore">
                <h2 class="name" id="name--0">
                    Total Score<br>
                    <span class="pl">Player 1</span>
                </h2>
                <p class="score" id="score--0">43</p>
            </div>
  
            <div class="current">
                <p class="current-label">Current Score</p>
  
                <p class="current-score" id="current--0">0</p>
  
            </div>
        </section>
  
        <section class="player player--1">
            <div class="tscore">
                <h2 class="name" id="name--1">
                    Total Score<br>
                    <span class="pl">Player 2</span>
                </h2>
                <p class="score" id="score--1">24</p>
            </div>
  
            <div class="current">
                <p class="current-label">Current Score</p>
  
                <p class="current-score" id="current--1">0</p>
  
            </div>
        </section>
  
        <img src="dice-5.png" 
            alt="Playing dice" class="dice" />
        <button class="btn btn--new">Start Game</button>
        <button class="btn btn--roll">Roll dice</button>
        <button class="btn btn--hold">Hold</button>
    </div>
    <script src="gfg.js"></script>
</body>
  
</html>

En el código anterior, hemos usado varias clases (por ejemplo: btn btn–roll, rte), estas se usarán con fines de estilo en el archivo CSS y las analizaremos en los archivos CSS.

Archivo CSS: para formatear y diseñar el marcado creado por HTML, necesitamos hojas de estilo en cascada para que el marcado (código) se vea mucho mejor. A continuación se muestra el código CSS para el juego. Antes de sumergirse en el código, solo eche un vistazo rápido a qué clases e identificadores son para qué propósito:

  1. Para la página HTML general y los elementos: * afectará a todos los elementos y etiquetas en el marcado. Hemos utilizado 2 etiquetas más para proporcionar un estilo particular, que son el estilo de la etiqueta html y del cuerpo.
  2. Elementos de diseño: etiqueta principal definida y estilo de clase de jugador allí. Hemos definido el atributo de posición para la etiqueta principal y hemos establecido su propiedad en relativa.
  3. Clases hechas a sí mismas: se necesita un estilo general para hacer que la página sea más atractiva.
  4. Clases posicionadas absolutas: he establecido el atributo de posición de btn y otras clases y he establecido su valor en absoluto , ya que tenemos que asegurarnos de que los botones y otros elementos estén siempre en el lugar correcto de la página. La posición absoluta hará la disposición de ese elemento en particular de acuerdo con el elemento que está posicionado relativo (en este caso, es la etiqueta principal).

CSS

* {
    margin: 0;
    padding: 0;
}
  
body {
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}
  
.container {
    position: relative;
    width: 80%;
    height: 90%;
    background-color: lightgreen;
    overflow: hidden;
    display: flex;
}
  
.player {
    flex: 50%;
    padding: 150px;
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: all 0.75s;
}
  
.name {
    position: relative;
    font-weight: bold;
    font-size: 38px;
    text-align: center;
}
  
.pl {
    font-size: 24px;
}
  
.tscore {
    background-color: #fff;
    border-radius: 9px;
    width: 65%;
    padding: 2rem;
    text-align: center;
    transition: all 0.75s;
}
  
.score {
    font-size: 38px;
    font-weight: bold;
    margin-bottom: auto;
    padding-top: 10px;
}
  
.player--active {
    background-color: green;
}
  
.player--active .current {
    opacity: 1;
}
  
.current {
    margin-top: 10rem;
    background-color: #fff;
    border-radius: 9px;
    width: 65%;
    padding: 2rem;
    text-align: center;
    transition: all 0.75s;
}
  
.current-label {
    text-transform: uppercase;
    margin-bottom: 1rem;
    font-size: 1.7rem;
    color: #ddd;
}
  
.current-score {
    font-size: 3.5rem;
}
  
.btn {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    color: rgb(7, 124, 69);
    border: none;
    font-size: 30px;
    cursor: pointer;
    font-weight: bold;
    background-color: rgba(255, 255, 255, 0.6);
    backdrop-filter: blur(10px);
    padding: 10px 30px;
    border-radius: 10px;
}
  
.btn--new {
    top: 4rem;
}
  
.btn--roll {
    top: 39.3rem;
}
  
.btn--hold {
    top: 46.1rem;
}
  
.dice {
    position: absolute;
    left: 50%;
    top: 24rem;
    transform: translateX(-50%);
}
  
.player--winner {
    background-color: #003612;
}
  
.player--winner .name {
    font-weight: 700;
    color: #c7365f;
}
  
.hidden {
    display: none;
}

En el código HTML, hemos proporcionado nombres de varias clases. En este archivo, hemos proporcionado sus diferentes funcionalidades. El archivo CSS juega un papel importante para que una página web o un juego se vean bien (solo en el caso de los navegadores web).

Hasta ahora, hemos creado la interfaz de usuario del juego a la perfección, ahora viene la parte más complicada. Entonces, profundicemos en la lógica del juego…

Archivo JavaScript: Hay algunas variables de JavaScript, podemos usar dos tipos de variables, es decir , let y constante. Se pueden modificar las variables declaradas con let, mientras que las variables declaradas con constante no se pueden cambiar. En el archivo de JavaScript, básicamente estamos haciendo las Manipulaciones DOM (todo en JavaScript es un tipo de Objeto, por lo que llamamos a la IU Modelo de Objeto de Documento). Entonces document.querySelector() es una forma de seleccionar elementos del DOM. 

Para comprender el flujo de trabajo de la lógica, primero debemos comprender el concepto de detectores de eventos. Los detectores de eventos son las funciones que realizan una acción en función de ciertos eventos. Esperan a que suceda el evento específico. Tenemos un total de 03 detectores de eventos para este juego:   btnRoll, btnHold, btnNew.  Entenderemos las funcionalidades de todos estos detectores de eventos:

Nota: Antes de dirigirnos a la sección de controladores de eventos, debemos declarar algunas variables en el archivo para que podamos usarlas más tarde en nuestra lógica de juego.

Javascript

'use strict';
  
// Selecting elements
const player0El = document.querySelector('.player--0');
const player1El = document.querySelector('.player--1');
const score0El = document.querySelector('#score--0');
const score1El = document.getElementById('score--1');
const current0El = document.getElementById('current--0');
const current1El = document.getElementById('current--1');
  
const diceEl = document.querySelector('.dice');
const btnNew = document.querySelector('.btn--new');
const btnRoll = document.querySelector('.btn--roll');
const btnHold = document.querySelector('.btn--hold');
  
let scores, currentScore, activePlayer, playing;

Al principio del archivo JavaScript, hay una línea «uso estricto». El propósito de «uso estricto» es indicar que el código debe ejecutarse en «modo estricto». Todos los navegadores modernos admiten el «uso estricto», excepto Internet Explorer 9 y versiones anteriores. 

Ahora comencemos a ver el código para cada uno de los 3 controladores de eventos.

1. Controlador de eventos btnRoll:

Javascript

// Rolling dice functionality
btnRoll.addEventListener('click', function () {
  if (playing) {
    
    // 1. Generating a random dice roll
    const dice = Math.trunc(Math.random() * 6) + 1;
  
    // 2. Display dice
    diceEl.classList.remove('hidden');
    diceEl.src = `dice-${dice}.png`;
  
    // 3. Check for rolled 1
    if (dice !== 1) {
      
      // Add dice to current score
      currentScore += dice;
      document.getElementById(
        `current--${activePlayer}`
      ).textContent = currentScore;
    } else {
      
      // Switch to next player
      switchPlayer();
    }
  }
});

Este controlador de eventos está en acción cada vez que el jugador hace clic en el botón Roll (es por eso que hemos usado el evento de clic allí). Luego hay una función de devolución de llamada que comienza con un bloque if-else . Como hemos declarado la variable playing = true , el bloque if de este controlador de eventos será verdadero y, por lo tanto, se ejecutará el código del bloque if. Los siguientes son los pasos a seguir:

  1. Paso 1: después de que el jugador presiona el botón de tirar los dados, este controlador de eventos produce un número aleatorio usando la función Math.trunc(). Hemos utilizado la función Math.trunc() porque esta función devuelve la parte entera de la función generada aleatoriamente y le hemos agregado un 1 porque la función random() puede generar cualquier número a partir de 0 a 1, pero en nuestro caso, solo necesita números del 1 al 6. <br> Comprender la variable dados: La variable dados almacenará el número generado aleatoriamente. Digamos que la función Math.random() genera el número 0.02. De acuerdo con el código, el primer 0,02 se multiplicará por 6. Entonces, los dados variables ahora tendrán un valor de 0,12. Entonces entrará en juego la función Math.trunc() y hará que eldado variable 0 . Ahora se agregará 1 a la variable que hará que el dado = 1 (Eso es lo que necesitamos como número para nuestro dado)
  2. Paso 2: ahora que tenemos la puntuación de los dados, tenemos que mostrar los dados correspondientes al número de dados. (En el archivo CSS, hemos creado una clase nombrada como oculta que hará que los dados estén ocultos inicialmente al comienzo del juego) Pero como ahora tenemos un número de dado para mostrar en forma de imagen de dado, tenemos que eliminar la clase oculta. Esto se logra mediante la línea diceE1.classList.remove(‘hidden’) y luego se representa la imagen correcta de dados en la interfaz de usuario. 
  3. Paso 3. Ahora, según las reglas del juego, tenemos que verificar el número en los dados. Por lo tanto, si el número de dados no es 1, se actualiza la puntuación actual . Si el número de dados es 1, entonces se invoca switchPlayer()

Javascript

const switchPlayer = function () {
  document.getElementById(`current--${activePlayer}`).textContent = 0;
  currentScore = 0;
  activePlayer = activePlayer === 0 ? 1 : 0;
  player0El.classList.toggle('player--active');
  player1El.classList.toggle('player--active');
};

De acuerdo con las reglas: «Si el jugador saca un 1, entonces pierde todo su puntaje actual» . Esta función logra la misma funcionalidad.

jugador activo = jugador activo === 0 ? 1 : 0 {Este es un operador ternario en el que decimos que si el jugador activo es 0, entonces vuélvalo a 1 y si lo es, vuélvalo a 0.

2.btnManejador de eventos de espera

Javascript

btnHold.addEventListener('click', function () {
  if (playing) {
    
    // 1. Add current score to active player's score
    scores[activePlayer] += currentScore;
    // scores[1] = scores[1] + currentScore
  
    document.getElementById(`score--${activePlayer}`)
      .textContent = scores[activePlayer];
  
    // 2. Check if player's score is >= 100
    if (scores[activePlayer] >= 100) {
      
      // Finish the game
      playing = false;
      diceEl.classList.add('hidden');
  
      document
        .querySelector(`.player--${activePlayer}`)
        .classList.add('player--winner');
      document
        .querySelector(`.player--${activePlayer}`)
        .classList.remove('player--active');
    } else {
      
      // Switch to the next player
      switchPlayer();
    }
  }
});

Este controlador de eventos se activa cada vez que un jugador presiona el botón HOLD. Los siguientes son los pasos involucrados en este controlador:

  1. Paso 1: tan pronto como el jugador mantiene presionado, el puntaje actual se agrega al puntaje general de ese jugador.
  2. Paso 2: la evaluación de las puntuaciones generales se realiza después de ese paso. Si se determina que la puntuación general es superior a 100, el juego finaliza y luego la clase de jugador ganador (que hace que el color de fondo sea negro y cambia el color y el peso de la fuente) y elimina la clase de jugador activo.

3. btnNuevo controlador de eventos:

btnNew.addEventListener(‘click’,init): Cada vez que se inicializa un nuevo juego, este controlador de eventos se activa. Solo inicializa la función Init(). Init() reinicia el juego desde el principio, es decir, hace lo siguiente:

  • Hace que las puntuaciones de ambos jugadores sean 0.
  • Hace que el jugador 1 sea el jugador activo/actual.
  • Esconde los dados por la clase oculta.
  • Elimina la clase jugador-ganador de ambos jugadores
  • Agrega la clase activa del jugador al jugador 1

Javascript

// Starting conditions
const init = function () {
  scores = [0, 0];
  currentScore = 0;
  activePlayer = 0;
  playing = true;
  
  score0El.textContent = 0;
  score1El.textContent = 0;
  current0El.textContent = 0;
  current1El.textContent = 0;
  
  diceEl.classList.add('hidden');
  player0El.classList.remove('player--winner');
  player1El.classList.remove('player--winner');
  player0El.classList.add('player--active');
  player1El.classList.remove('player--active');
};
init();

Nota: la función init() también se inicializa en el momento de cargar el juego. 

Producción:

Referencia de Imágenes Cortadas:

Publicación traducida automáticamente

Artículo escrito por versatile1990 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *