-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript2.js
408 lines (339 loc) · 15.3 KB
/
script2.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
//Script file for Hard Level
window.addEventListener("DOMContentLoaded", function() {
// declaring some global variables
const overlay = document.getElementById('darkeningOverlay');
setInterval(() => {
// Toggle the flash class every 10 seconds
overlay.classList.toggle('flash');
}, 5000);
// array of images to be stored in the individual cards
const deckCards = ["hand.png", "candy.png","bucketPumpkin.png", "cat.png", "candy2.png", "ghost.png",
"hat.png", "skull1.png", "bat.png","mexicanskull.png","moon.png","mummy.png","witch.png","skull2.png","spider.png",
"web.png", "hand.png","candy.png", "bucketPumpkin.png", "cat.png", "candy2.png", "ghost.png", "hat.png", "skull1.png",
"bat.png","mexicanskull.png","moon.png","mummy.png","witch.png","skull2.png","spider.png","web.png",
"vampire.png","tree.png","tree2.png","spiders.png","vampire.png","tree.png","tree2.png","spiders.png" ];
// selecting <ul> with class of deck
const deck = document.querySelector(".deck");
// empty array to store openedCards cards
let openedCards = [];
// empty array to store matching cards
let matched = [];
// selecting the modal
const modal = document.getElementById("modal");
// selecting reset button
const reset = document.querySelector(".reset-btn");
// selecting play-again button
const playAgain = document.querySelector(".play-again-btn");
// selecting the moves counter, which will have its innerHTML changed depending on number of moves made
const movesCount = document.querySelector(".moves-counter");
// create variable for the number of moves made (cards clicked), starting at 0
let moves = 0;
// selecting the stars to give the player a rating
const star = document.getElementById("star-rating").querySelectorAll(".star");
let starCount = 3;
// selecting timer
const timeCounter = document.querySelector(".timer");
let time;
let minutes = 0;
let seconds = 0;
let timeStart = false;
/* create a function that shuffles the array every time the game is started
function will have a random number, a temporary variable which will be storing the value of the array at the current iteration
it will then pull out the value of the shuffledDeck at a random iteration and will swap it with the current iteration value (stored at temporary variable)
it will continue to loop through the array and repeat the same process, producting a randomly shuffled array
function will then return the shuffled array */
function shuffle(arr) {
for (let i = 0; i < arr.length; i++) {
let randomNumber = Math.floor(Math.random() * arr.length);
let temp = "";
let current = arr[i];
let randomElement = arr[randomNumber];
temp = current;
arr[i] = randomElement;
arr[randomNumber] = temp;
}
return arr;
}
function startGame() {
// Invoke shuffle function created earlier and store in variable
const shuffledDeck = shuffle(deckCards);
// Iterate over deck of cards array
for (let i = 0; i < shuffledDeck.length; i++) {
// at each iteration, create a <li> tag
const liTag = document.createElement("li");
// Give <li> class of card
liTag.classList.add("card");
// Create an <img> tag
const addImage = document.createElement("img");
// Append <img> to <li> tag
liTag.appendChild(addImage);
// Set the img src path with the shuffled deck
addImage.setAttribute("src", "images/" + shuffledDeck[i]);
// Add an alt tag to the image
addImage.setAttribute("alt", `Image of ${shuffledDeck[i]}`);
// Append the new <li> tag to the deck
deck.appendChild(liTag);
}
let cards = document.getElementsByClassName("card");
for (let i = 0; i < cards.length; i++) {
cards[i].addEventListener("click", function() {
let flip = new Audio("sounds/flip.mp3");
flip.play();
});
}
}
startGame();
// create a function that removes cards. Function will be called upon reset
function removeCard() {
// As long as <ul> deck has a child node, remove the child node
while (deck.hasChildNodes()) {
deck.removeChild(deck.firstChild);
}
}
/* Update the timer in the HTML for minutes and seconds
The timer function is called in the event listener the first time a card is clicked. */
function timer() {
// Update the count every 1 second
time = setInterval(function() {
seconds++;
if (seconds === 60) {
minutes++;
seconds = 0;
}
// Update the timer in HTML with the time it takes the user to play the game
if (screen.width <= 500) {
timeCounter.innerHTML = `<i class='fa fa-clock'></i> ${minutes} Mins ${seconds} Secs`;
} else {
timeCounter.innerHTML = `<i class='fa fa-clock' style="color: orange;"></i><strong style="color: orange;"> Time:</strong> ${minutes} Minutes ${seconds} Seconds`;
}
}, 1000);
}
// Create a function that stops the timer once all 16 cards are matched.
function stopTime() {
clearInterval(time);
}
// Create a function that resets all global variables and the content of HTML elements (timer, stars, moves, and their innerHTML)
function resetEverything() {
// Stop time, reset the minutes and seconds update the time inner HTML
stopTime();
timeStart = false;
seconds = 0;
minutes = 0;
timeCounter.innerHTML = `<h3 class="timer"><i class="far fa-clock"></i> <span class="timer-header">Time:</span> 00:00</h3>`;
// Reset star count and the add the class back to show stars again
star[1].firstElementChild.classList.add("fa-star");
star[2].firstElementChild.classList.add("fa-star");
starCount = 3;
// Reset moves count and reset its inner HTML
moves = 0;
movesCount.innerHTML = 0;
// Clear both arrays that hold the openedCards and matched cards
matched = [];
openedCards = [];
// Clear the deck
removeCard();
// Create a new deck
startGame();
}
/* Create a function that increments the moves counter, which is called at each comparison.
for every two cards compared add one to the count. */
function movesCounter() {
// Update the html for the moves counter
movesCount.innerHTML++;
// Keep track of the number of moves for every pair checked
moves++;
}
/* Create a function that updates the star rating depending on the number of moves the player has made to complete the Game
the number of starts will decrease the more moves a player makes. */
function starRating() {
if (moves === 40) {
// First element child is the <i> within the <li>
star[2].firstElementChild.classList.remove("fa-star");
starCount--;
document.querySelectorAll(".star")[0].style.animation = "stars-pulse 1s";
document.querySelectorAll(".star")[1].style.animation = "stars-pulse 1s";
}
if (moves === 42) {
star[1].firstElementChild.classList.remove("fa-star");
starCount--;
document.querySelector(".star").style.animation = "stars-pulse 1s";
}
}
// Create a function to compare two cards in the openedCards array to see if they match
function compareTwo() {
// When there are 2 cards in the openedCards array
if (openedCards.length === 2) {
// Disable any further mouse clicks on other cards
document.body.style.pointerEvents = "none";
}
// Compare the two images src
if (openedCards.length === 2 && openedCards[0].src === openedCards[1].src) {
// If matched call match()
match();
} else if (openedCards.length === 2 && openedCards[0].src != openedCards[1].src) {
// If No match call noMatch()
noMatch();
}
}
document.querySelector('.home-btn').addEventListener('click', function() {
window.location.href = 'index.html';
});
// Create a function that checks if the two cards match, and keep the cards open if they do and applie class of match.
function match() {
/* Access the two cards in openedCards array and add the class of match to the parent of the image, i.e the <li> tag */
setTimeout(function() {
openedCards[0].parentElement.classList.add("match");
openedCards[1].parentElement.classList.add("match");
// Push the matched cards to the matched array
matched.push(...openedCards);
// Allow for further mouse clicks on cards
document.body.style.pointerEvents = "auto";
// Check to see if the game has been won with all 8 pairs
winGame();
/* play sound when cards match */
let match = new Audio("sounds/match2.mp3");
match.play();
// Clear the openedCards array
openedCards = [];
}, 600);
// Call movesCounter to increment by one
movesCounter();
starRating();
}
/* function that checks if the two cards do not match, and removes the cards from the openedCards array
and flips the cards back over by removing the flip class. */
function noMatch() {
//after 400 milliseconds, add the noMatch class to the card
setTimeout(function() {
openedCards[0].parentElement.classList.add("noMatch");
openedCards[1].parentElement.classList.add("noMatch");
}, 450);
setTimeout(function() {
//after 1 seconds, play the "wrong.mp3" audio file
let wrong = new Audio("sounds/wrong.mp3");
wrong.play();
}, 600);
setTimeout(function() {
//after 1450 milliseconds, remove the noMatch class
openedCards[0].parentElement.classList.remove("noMatch");
openedCards[1].parentElement.classList.remove("noMatch");
}, 1450);
// After 1500 miliseconds the two cards open will have the class of flip removed from the images parent element <li>
setTimeout(function() {
// Remove class flip on images parent element
openedCards[0].parentElement.classList.remove("flip");
openedCards[1].parentElement.classList.remove("flip");
// Allow further mouse clicks on cards
document.body.style.pointerEvents = "auto";
// Remove the cards from openedCards array
openedCards = [];
}, 1500);
// Call movesCounter to increment by one
movesCounter();
starRating();
}
/*Function that produces stats regarding time, number of moves made,
and star rating for the end game and updates the modal with these stats. */
function AddStats() {
// Access the modal content div
const stats = document.querySelector(".modal-content");
// Create three different paragraphs
for (let i = 1; i <= 3; i++) {
// Create a new Paragraph
const statsElement = document.createElement("p");
// Add a class to the new Paragraph
statsElement.classList.add("stats");
// Add the new created <p> tag to the modal content
stats.appendChild(statsElement);
}
// Select all p tags with the class of stats and update the content
let p = stats.querySelectorAll("p.stats");
// Set the new <p> to have the content of stats (time, moves and star rating) depending on the star rating
if (starCount === 1) {
p[0].innerHTML = `<strong>Time to complete :</strong> ${minutes} Minutes and ${seconds} Seconds`;
p[1].innerHTML = `<strong>Moves made :</strong> ${moves} - Too many moves`;
p[2].innerHTML = `<strong>Your rating is :</strong> ${starCount} out of 3 stars ... <i class="fas fa-times-circle"></i> Fail - You must try harder`;
} else if (starCount === 2) {
p[0].innerHTML = `<strong>Time to complete :</strong> ${minutes} Minutes and ${seconds} Seconds`;
p[1].innerHTML = `<strong>Moves made :</strong> ${moves} - <i class="fas fa-check"></i> Pass - Not too bad!`;
p[2].innerHTML = `<strong>Your rating is :</strong> ${starCount} out of 3 stars`;
} else {
p[0].innerHTML = `<strong>Time to complete :</strong> ${minutes} Minutes and ${seconds} Seconds`;
p[1].innerHTML = `<strong>Moves made :</strong> ${moves}`;
p[2].innerHTML = `<strong>Your rating is :</strong> ${starCount} out of 3 stars ... <i class="fas fa-check-circle"></i> Success - Amazing Brain Memory`;
}
}
// create function that displays the modal when the game is won
function displayModal() {
// Access the modal <span> element (x) that closes the modal
const modalClose = document.getElementsByClassName("close")[0];
// When the game is won set modal to display block to show it
modal.style.display = "block";
// When the user clicks on <span> (x), close the modal
modalClose.onclick = function() {
modal.style.display = "none";
};
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
}
/* function used Check the length of the matched array and if there are 8 pairs 16 cards
all together then the game is won.
Stop the timer update the modal with stats and show the modal. */
function winGame() {
if (matched.length === 40) {
stopTime();
AddStats();
// play victory sound when all cards are matched and display modal 700ms after last match is made
setTimeout(() => {
let victory = new Audio("sounds/victory.mp3");
displayModal();
victory.play();
}, 800);
}
}
function clickHandler(event) {
if (event.target.nodeName === "LI") {
// Start the timer after the first click of one card
// Executes the timer() function
if (timeStart === false) {
timeStart = true;
timer();
}
// Call flipCard() function
flipCard();
}
//Flip the card and display cards img
function flipCard() {
//play "flip" audio file
let flip = new Audio("sounds/flip.mp3");
flip.play();
// When <li> is clicked add the class .flip to show img
event.target.classList.add("flip");
// Call addToOpenedCards() function
addToOpenedCards();
}
//Add the fliped cards to the empty array of openedCards
function addToOpenedCards() {
/* If the openedCards array has zero or one other img push another
img into the array so we can compare these two to be matched
*/
if (openedCards.length === 0 || openedCards.length === 1) {
// Push that img to openedCards array
openedCards.push(event.target.firstElementChild);
}
// Call compareTwo() function
compareTwo();
}
}
deck.addEventListener("click", clickHandler);
deck.addEventListener("touchstart", clickHandler);
reset.addEventListener('click', resetEverything);
playAgain.addEventListener('click', function() {
modal.style.display = "none";
resetEverything();
});
});