In questa lezione realizzeremo il gioco memory game in JavaScript, ovvero il famoso gioco di abbinamento per testare la memoria di un giocatore.

Per lo sviluppo di questo gioco utilizzeremo alcuni metodi e proprietà di JavaScript che abbiamo studiato nelle lezioni precedenti, tra cui anche metodi e proprietà utili per manipolare il DOM in JavaScript. Vedremo anche l’utilizzo delle funzioni.

Ecco dunque una demo del gioco che andremo a realizzare:

Tempo: 0 min 0 sec

Ecco il link diretto al gioco:

Primo passaggio del gioco memory game in JavaScript

Innanzitutto occorre decidere la dimensione della matrice, nel nostro esempio realizzeremo una matrice 4 x 4. Quindi decidiamo come popolare ciascun elemento della matrice. Lo potremmo fare con dei numeri oppure con delle icone.

Scegliamo di utilizzare queste icone: https://html-css-js.com/html/character-codes/ e inseriamo alcune icone di animali. Dato che stiamo realizzando una matrice 4 x 4 mi serviranno 8 simboli, ripetuti 2 volte ciascuno.


var arrayAnimali  = ['🐱', '🦉', '🐾', 
                     '🦄', '🦋', '🐛', 
                     '🐝', '🐬', '🐱',
                     '🦉', '🐾', '🦄', 
                     '🦋', '🐛', '🐝','🐬'];

Adesso dobbiamo generare un array random e quindi ci servirà creare una funzione che generi in maniera random gli elementi e li inserisca in un array. Per fare ciò utilizzeremo l'algoritmo Fisher-Yates Shuffle, chi vuole può approfondire al seguente link: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle


function shuffle(a) {
  var currentIndex = a.length;
  var temporaryValue, randomIndex;

  while (currentIndex !== 0) {
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;
    temporaryValue = a[currentIndex];
    a[currentIndex] = a[randomIndex];
    a[randomIndex] = temporaryValue;
  }
  return a;
}

Secondo passaggio del gioco memory game in JavaScript

Il gioco avrà un timer per i secondi trascorsi, dunque creiamo una funzione apposita, dove appena la variabile dei secondi (s) arriva a 60 incrementiamo i minuti. Quando i minuti (m) arrivano a 60 allora incrementeremo le ore (h). Notiamo che è necessario creare una variabile globale (interval) per poi ripulirla ogni volta che avviamo il gioco.


 var interval;
/*creiamo la variabile globale interval 
per poterla poi ripulire ogni volta che si inizia il gioco.*/

function startTimer(){
  var s = 0, m = 0,  h = 0;
  interval = setInterval(function(){
  timer.innerHTML = 'Tempo: ' + m + " min " + s + " sec";
    s++;
    if(s == 60){
      m++;
      s = 0;
    }
    if(m == 60){
      h++;
      m = 0;
    }
  },1000);
}

Terzo passaggio del gioco memory game in JavaScript

Adesso realizziamo la funzione startGame che si occupa di far partire il tutto.

Utilizzeremo un array di appoggio (arrayComparison) per confrontare ogni volta le due carte scoperte.

Quindi quando parte il gioco creiamo innanzitutto l'array random di animali. Poi ripuliamo la variabile interval che tiene traccia del tempo trascorso e azzeriamo l'arrayComparison.
Ripuliamo il contenuto del contenitore griglia e con un ciclo for creiamo un elemento div che all'interno contiene un altro elemento div con classe icon.

Facciamo partire il timer e per ogni card cliccata facciamo partire la funzione displayIcon:


function startGame(){  

  var arrayShuffle = shuffle(arrayAnimali);

  clearInterval(interval);
  arrayComparison = [];

  var lista = document.getElementById('griglia');
  while (lista.hasChildNodes()) {  
    lista.removeChild(lista.firstChild);
  }

   for(var i = 0; i < 16; i++){    
      var box = document.createElement('div');
      var element = document.createElement('div');
      element.className = 'icon';
      document.getElementById('griglia')
         .appendChild(box).appendChild(element);
      element.innerHTML = arrayShuffle[i];
    }
  
  startTimer();

  var icon = document.getElementsByClassName("icon");
  var icons = [...icon];

  for (var i = 0; i < icons.length; i++){
    icons[i].addEventListener("click", displayIcon);
    icons[i].addEventListener("click", openModal);
  }

}

Facciamo partire questa funzione al click del pulsante start o quando si carica la pagina html.

document.body.onload = startGame();

Quarto passaggio del gioco memory game in JavaScript

La funzione displayicon legge tutte le icone caricate e attiva per ciascuna carta scoperta la classe show. Inoltre inserisce la carta scoperta nell'arrayComparison. Quindi determina la lunghezza dell'arrayComparison e se è due confronta le carte, se uguali aggiunge le classi find per attivare l'effetto a rotazione e disabled per disabilitare il click.

Se non sono uguali dopo 700 millisecondi rimuove la classe show:


 function displayIcon(){

  var iconsFind = document.getElementsByClassName("find");

  var icon = document.getElementsByClassName("icon");
  var icons = [...icon];

  this.classList.toggle("show");
  arrayComparison.push(this);

  var len = arrayComparison.length;
  if(len === 2){
    if(arrayComparison[0].innerHTML === arrayComparison[1].innerHTML){
      arrayComparison.forEach(function(elemento){
          elemento.classList.add("find","disabled");
      });
      arrayComparison = [];               
    } else {
      icons.forEach(function(item){
        item.classList.add('disabled');
      });
      setTimeout(function(){
        arrayComparison.forEach(function(elemento){
            elemento.classList.remove("show");
        });
        icons.forEach(function(item){
          item.classList.remove('disabled');
          for(var i = 0; i < iconsFind.length; i++){
              iconsFind[i].classList.add("disabled");
            }
        });
        arrayComparison = [];
      },700); 
     }
  }
}

Finestra modale

Pensiamo adesso alla finestra modale che appare quando abbiamo indovinato tutte le combinazioni:


var modal = document.getElementById("modal");
var timer = document.querySelector(".timer");

function openModal(){  
  if (iconsFind.length == 16){
      clearInterval(interval);
      modal.classList.add("active");
      document.getElementById("totalTime").innerHTML = timer.innerHTML;
      closeModal();
  }
}

function closeModal(){  
  closeicon.addEventListener("click", function(e){
      modal.classList.remove("active");
      startGame();
  });
}

Infine la funzione playAgain che ci consente di riavviare il gioco e chiudere la finestra modale:


function playAgain(){
  modal.classList.remove("active");
  startGame();
}

Pagina html del gioco memory game

Nella pagina html predispongo semplicemente la sezione griglia dove si inseriranno tutte le carte, la sezione che contiene il pulsante per ricominciare il gioco ed il tempo.

<div class="container icon-grid" id="griglia"></div>
  <div class="container text-center">  
    <input type="button" id="button" class="button" onclick=startGame() value="Ricomincia">
    <div class="timer">Tempo: 0 min 0 sec</div>  
  </div>





<div id="modal">       
   <div class="content">
       <h2>Congratulazioni hai risolto il gioco in </h2>
       <p><span id=totalTime> </span> </p>
       <p><input type="button" class="button" onclick=playAgain() value="Gioca Ancora!"></p>
   </div>        
</div>

<script src="script.js"></script>

Pagina CSS del gioco memory game in JavaScript

Potete personalizzare poi il CSS a vostro piacimento, vi allego quello creato nell'esempio:


.container{
  width: 600px;
  margin:auto;
  background-color: lightgrey;
}

.text-center {
  text-align: center;
}

.icon-grid {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

.show {
   visibility: visible;
   opacity: 100;
}

#griglia > div{
   margin: 20px 10px;
   width: 120px;
   height: 120px;
   background-color: #ffc83d;
   border: 1px solid #3889c4;
   border-radius: 10px;
}

.timer {
   padding: 10px 0;
}

.icon {
   font-size: 80px;
   text-align: center;
   visibility: visible;
   opacity:0;
   width: 100%;
   height: 100%;
   cursor: pointer;
}

.disabled {
   pointer-events: none;
   cursor:wait;
}

.show {
   animation-name: rotation-icon;
   animation-duration: .5s;
   background-color:white;
   border: 1px solid #3889c4;
   border-radius: 10px;
}

.find {
   animation-name: guessed;
   animation-duration: .5s;
   background-color:#3889c4;
   border: 1px solid #3889c4;
   border-radius: 10px;
}

.button{
  color: white;
  font-size: 22px;
  text-align: center;
  margin-top: 10px;
  padding: 10px;
  background-color: #ffc83d;
  border: 1px solid #3889c4;
  border-radius: 5px;
}

.button:hover{
  background-color: #16486c;
  border:none;
}

 #modal {
    display: none;
    justify-content: center;
    align-items: center;
    width: 100vw;
    height: 100vh;
    background-color: rgba(255, 255, 255, 0.9);
    position: fixed;
    top: 0;
    left: 0;
}

  #modal.active {
    display: flex;
  }
  
  #modal h2 {
    margin-top: 20px;
  }


@keyframes guessed{ 
 from { 
    transform: rotate(0deg);
   } 
  to { 
   transform: rotate(360deg);	 
  }
}

@keyframes rotation-icon {
   from {
	transform: perspective(300px) rotate3d(0, 1, 0, 80deg);
	animation-timing-function: ease-in;
   }

   50% {
	transform: perspective(300px) rotate3d(0, 1, 0, -10deg);
	animation-timing-function: ease-in;
   }

   to {
	transform: perspective(300px);
	animation-timing-function: ease-in;
   }
}

Divertitevi a creare altre varianti del Memory game in JavaScript.

Alcuni link utili

Indice tutorial JavaScript

Il linguaggio JavaScript

Come utilizzare JavaScript alert

Utilizzare JavaScript prompt

Variabili in JavaScript

Gioco indovina numero in JavaScript

Gioco della morra cinese in JavaScript

Semplice quiz utilizzando gli array

Come realizzare il gioco dei dadi online