1

My memory game is almost complete, it has one last error to fix. Timer stops and returns to zero after the game is complete and a modal box appears to congratulate the player with total time and stars scored. However, while in this state, clicking somewhere in the deck (colored with linear-gradient property) causes it to start back again. Normally, it shouldn't start until the player has restarted the game and clicked on one of the closed cards.

How can I prevent it in a way so that after the modal box kicks in, clicking anywhere on the screen will NOT cause the timer to start?

Here is my project. If you finish and click someplace on the deck you'll see the timer starting even though the game is finished. I want to prevent that from happening.

https://codepen.io/Caysle/pen/aYYKRp

Here is the bit that collects all the progress you've made in the game:

//Collect cards to check if all are open and match:

let matchingCards = document.getElementsByClassName('card match open show');
if (matchingCards.length == 16) {
  setTimeout (function() {document.querySelector(".winPage").className = 
"winPage"}, 1000);
  stopTimer = true;
  }
}
Caysle
  • 65
  • 2
  • 9
  • At a z-index directly under the modal, put a divorce that covers the screen but is invisible. It will catch the clicks. – Sam H. Apr 01 '18 at 04:43

1 Answers1

2

Besides a higher z-index for .winPage - which only 'overrules' the part that is overlaid - add some click-disabling css: pointer-events: none; cursor: none. In your current css you're also using inherit: auto. But instead you can try to disable clicks on the container div and let inner elements inherit it (except for .winpage of course). (jsfiddle)

css

let card1 = ''; // The former
let card2 = ''; // The latter
let card1Parent = '';
let card2Parent = '';
let ready = true;
let stopTimer = false;
let cardCounter = 0;

document.querySelector(".restart").addEventListener("click", restart);
document.querySelector(".deck").addEventListener("click", function() {stopTimer = false; timerStart()});
document.querySelector(".deck").addEventListener("click", cardOpen);
document.querySelector(".playAgain").addEventListener("click", function() {
  document.querySelector(".winPage").className = "winPage closed"; restart()});

// Unlocking clicked cards and comparing them

function cardOpen(evt) {
  if (evt.target.className == "card" && cardCounter != 2) {
     evt.target.className += " open show";

    // Determines which card comes first in a unlocked pair of cards

    if (card1 == false) {
      card1 = evt.target.firstElementChild.className;
      card1Parent = evt.target;
      cardCounter = 1;
    } else {

      // Increasing the amount of moves

      document.querySelector(".moves").innerText = +document.querySelector(".moves").innerText + 1;

      // Rating system. Stars decrease depending on how many moves you've made

      if (document.querySelector(".moves").innerText == '16' || document.querySelector(".moves").innerText == '22') {
        document.querySelector(".fa-star").parentNode.removeChild(document.querySelector(".fa-star"));
      }

      card2 = evt.target.firstElementChild.className;
      card2Parent = evt.target;
      cardCounter = 2;

      // Card matching

      if (card1 == card2) {
        card1Parent.className = "card open show match";
        card2Parent.className = "card open show match";
        card1 = '';
        card2 = '';
        cardCounter = 0;
        win();
      } else {
        setTimeout(function () {
          evt.target.className = "card close"; card1Parent.className = "card close"}, 700);
        setTimeout(function () {
          evt.target.className = "card"; card1Parent.className = "card"; card1 = ''; card2 = ''; cardCounter = 0}, 900);
      }
    }

    ready = false;

  }
}

// Rating system renewal

function returnStars() {
  while (document.getElementsByClassName("fa-star").length != 3) {
    var newStar = document.createElement("li");
    newStar.className = "fa fa-star";
    document.querySelector(".stars").appendChild(newStar);
  }
}

//Resets all the progress you've made when you finish the game

function restart() {
  card1 = "";
  card2 = "";
 document.querySelector(".moves").innerText = "0";
 returnStars();
  document.querySelector(".winPage").className = "winPage closed";
  document.querySelector(".container").className = "container"

 let cards = Array.prototype.slice.call(document.querySelectorAll('.card'));
 cards = shuffle(cards);
 const deck = document.querySelector(".deck");

 for (let i = 0; i < cards.length; i++) {
  deck.appendChild(cards[i]);
  cards[i].className = "card";
 }

 ready = true;
  stopTimer = true;

 }

// Shuffle function from http://stackoverflow.com/a/2450976

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

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

    return array;
}

// Timer

function timerStart() {
 if (ready == true) {
  var timer = 0;
  var hour = 0;
  var minute = 0;
  var second = 0;
  window.setInterval (function() {
    ++timer;
    hour = Math.floor(timer / 3600);
    minute = Math.floor((timer - hour * 3600) / 60);
    second = timer - hour * 3600 - minute * 60;
    if (hour < 10) hour = '0' + hour;
    if (minute < 10) minute = '0' + minute;
    if (second < 10) second = '0' + second;
    document.querySelector('#timer').innerHTML = hour + ':' + minute + ':' + second;
    if(stopTimer) {
   document.querySelector('#timer').innerHTML = "00:00:00";
   timer = 0;
   hour = 0;
   minute = 0;
   second = 0;
   return;
    }
  }, 1000);
 }
}

// Shows a modal box when you win:

function win() {
 document.querySelector(".movesCount").innerText = document.querySelector(".moves").innerText;
 document.querySelector(".starsCount").innerText = document.getElementsByClassName("fa-star").length;
 document.querySelector(".finalTime").innerText = document.querySelector('#timer').innerHTML;

 //Collect cards to check if all are open and match:

 let matchingCards = document.getElementsByClassName('card match open show');
 if (matchingCards.length == 16) {
   setTimeout (function() {document.querySelector(".winPage").className = "winPage"}, 1000);
   stopTimer = true;
   document.querySelector('.container').className = "container no-click"
 }
}
html {
    box-sizing: border-box;
}

*,
*::before,
*::after {
    box-sizing: inherit;
}

html,
body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

body {
    font-family: 'Coda', cursive;
}

.container {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
}

h1 {
    font-family: 'Open Sans', sans-serif;
    font-weight: 300;
    margin-bottom: 20px;
}

/*
 * Styles for the deck of cards
 */

.deck {
    width: 660px;
    min-height: 680px;
    background: linear-gradient(160deg, #ddbf4f 0%, #d33a32 100%);
    padding: 32px;
    border-radius: 10px;
    box-shadow: 12px 15px 20px 0 rgba(46, 61, 73, 0.65);
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    margin: 0 0 3em;
    z-index: 2;
    pointer-events: inherit;
}

.deck .card {
    height: 125px;
    width: 125px;
    background: #2e3d49;
    font-size: 0;
    color: #ffffff;
    border-radius: 8px;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 5px 2px 20px 0 rgba(46, 61, 73, 0.65);
    pointer-events: inherit;
}


.deck .card.open {
    transform: rotateY(180deg);
    transition: 0.3s;
    background: #2f91f9;
    cursor: default;
    pointer-events: none;
}

.deck .card.close {
 transform: rotateY(360deg);
 transition: 0.2s;
 transform-style: preserve-3d;
 background: #2e3d49;
}

.deck .card.show {
    font-size: 33px;
}

.deck .card.match {
    cursor: default;
    background: #1bc45f;
    font-size: 33px;
}

/*
 * Styles for the Score Panel
 */

.score-panel {
    text-align: left;
    width: 345px;
    margin-bottom: 10px;
    z-index: 2;
}

.score-panel .stars {
    margin: 0;
    padding: 0;
    display: inline-block;
    margin: 0 5px 0 0;
}

.score-panel .stars li {
    list-style: none;
    display: inline-block;
    color: #3572a8;
}

.score-panel .restart {
    float: right;
    cursor: pointer;
}

.score-panel #timer {
 display: inline-block;
 text-align: center;
 color: white;
 margin-left: 40px;
 border-radius: 5px;
 width: 90px;
 height: 27px;
 background-color: #3572a8;
}

.restart button {
 border-radius: 5px;
 cursor: pointer;
}

.winPage {
 z-index: 1000;
  top: 35%;
  left: 50%; /*You should set this back to 50% ! */
  border-style: solid;
  border-radius: 10px;
  position: absolute;
  transform: translate(-50%, -50%);
  background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5));
  background-color: rgba(0, 0, 0, 0.2);
 color: white;
 display: flex;
  justify-content: center;
  align-items: center;
 flex-direction: column;
 width: 400px;
 height: 370px;
 opacity: 1;
 transition: 1s;
  animation-name: animatetop;
  animation-duration: 0.25s;
  animation-timing-function: linear;
}

.winPage.closed {
 display: none;
 z-index: 1;
}

.no-click {
  pointer-events: none;
  cursor: none;  
}

@keyframes animatetop {
    from {top: -300px; opacity: 0}
    to {top: 0; opacity: 1}
}
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Memory Game</title>
    <meta name="description" content="">
    <link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
    <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">
    <link rel="stylesheet" href="css/app.css">
</head>
<body>

    <div class="container">
        <header>
            <h1>Memory Game</h1>
        </header>

        <section class="score-panel">
         <ul class="stars">
          <li><i class="fa fa-star"></i></li>
          <li><i class="fa fa-star"></i></li>
          <li><i class="fa fa-star"></i></li>
         </ul>

         <span class="moves">0</span> Moves

          <div id="timer">00:00:00</div>

            <div class="restart">
              <button type="button" class="btn btn-info btn-sm">
          <i class="fa fa-repeat"></i>
            </button>
         </div>
        </section>

        <ul class="deck">
            <li class="card">
                <i class="fa fa-diamond"></i>
            </li>
            <li class="card">
                <i class="fa fa-paper-plane-o"></i>
            </li>
            <li class="card">
                <i class="fa fa-anchor"></i>
            </li>
            <li class="card">
                <i class="fa fa-bolt"></i>
            </li>
            <li class="card">
                <i class="fa fa-cube"></i>
            </li>
            <li class="card">
                <i class="fa fa-anchor"></i>
            </li>
            <li class="card">
                <i class="fa fa-leaf"></i>
            </li>
            <li class="card">
                <i class="fa fa-bicycle"></i>
            </li>
            <li class="card">
                <i class="fa fa-diamond"></i>
            </li>
            <li class="card">
                <i class="fa fa-bomb"></i>
            </li>
            <li class="card">
                <i class="fa fa-leaf"></i>
            </li>
            <li class="card">
                <i class="fa fa-bomb"></i>
            </li>
            <li class="card">
                <i class="fa fa-bolt"></i>
            </li>
            <li class="card">
                <i class="fa fa-bicycle"></i>
            </li>
            <li class="card">
                <i class="fa fa-paper-plane-o"></i>
            </li>
            <li class="card">
                <i class="fa fa-cube"></i>
            </li>
        </ul>
    </div>
    <div class="winPage closed">
  <h1>Congratulations!</h1>
  <p>You have finished the game with <span class="movesCount">0</span> Moves and <span class="starsCount">0</span> Stars.</p>
  <p>Your time: <span class="finalTime"></span></p>
  <p>Wanna play again?</p>
  <button type="button" role="button" class="playAgain btn btn-info">Play again!</button>
</div>


    <script src="js/app.js"></script>
</body>
</html>
/* change the following */

.deck {
    (...) /* everything you had before */
    pointer-events: inherit;
}

.deck .card {
    (...)
    pointer-events: inherit;
}

/* add the following at the bottom of your css */

.no-click {
    pointer-events: none;
    cursor: none;  
}

javascript

if function win() is called, add no-click class to <div class="container"></div>, on restart remove no-click

function win() {
    if (matchingCards.length == 16) {
        /* (...) */
        document.querySelector('.container').className = "container no-click"

}

function restart() {
    /* (...)*/
    document.querySelector(".container").className = "container"
}
axm__
  • 2,463
  • 1
  • 18
  • 34