WEEK4 CARD TEAM P’Faii GroupB
✨ KALYARAK CHOOBPHA
<!-- อ้างอิงโค้ดจาก https://codepen.io/Sonjya00/pen/LmaVKK?editors=1010--> <html> <style> @import url('https://fonts.googleapis.com/css2?family=Fredoka+One&display=swap'); body { min-height: 100vh; margin: 50px; background:url(https://i.pinimg.com/originals/d7/f2/5b/d7f25ba498e0f3ab2b3e0135d8a0f275.gif); background-size: 100% 120%; } p{ margin-top:20px; font-family: 'Fredoka One', cursive; margin-bottom: 3px; font-size: 3em; color:#3e50bc; animation: gradient 10s infinite; text-align: center; } a{ margin-top: 50px; font-size: 2em; color: #d60275; font-family: 'Fredoka One', cursive; text-shadow: 0px 1px 2px white; } .score-panel { display: flex; flex-wrap: nowrap; margin:0 auto; padding-top: 10px; padding-bottom: 10px; text-align: center; width: 530px; font-family: 'Fredoka One', cursive; font-size: 35px; color: #1a652c; } .score-panel .moves { display: inline-block; width: 50%; } .score-panel .restart { cursor: pointer; display: inline-block; width: 50%; } .deck { width: 650px; min-height: 500px; margin: 0 auto; margin-top: 1em; border-radius: 20px; background: #103b1a; padding: 50px; display: flex; align-items: center; flex-wrap: wrap; justify-content: space-between; box-shadow: 0px 0px 25px #00deff; } .deck .card { width: 100px; height:100px; border-radius: 20px; margin: 10px; background: url(https://p7.hiclipart.com/preview/968/732/36/new-super-mario-bros-wii-new-super-mario-bros-wii-super-mario-world-brick-best-images-free-clipart.jpg); background-size: 100%; box-shadow : 5px 5px 10px #2b6c3a; border: 5px solid white; border-inline-style: dashed; cursor:pointer; display: flex; justify-content: center; align-items: center; color: #fff; font-size: 0px; } /*หน้าแสดงผลเมื่อกดที่ card*/ .deck .card.open { background: #02b3e4; cursor: default; transform: rotateY(0); } .deck .card.open .img , .deck .card.match .img{ transform: scale(1.2) } /*แสดงผลของรูปเมื่อกดจับคู่ได้ถูกต้อง*/ .deck .card.match { cursor: default; background: #02cc10; } @keyframes gradient{ 0% { color: #c13c08; -webkit-text-stroke: 2px #e5602b; } 25% { color: #d60275; -webkit-text-stroke: 2px #ff52b0; } 50% { color: #0cdfcc; -webkit-text-stroke: 2px #53ffef; } 100% { color: #4347ff; -webkit-text-stroke: 2px #7477ff; } } .card:hover{ transform: scale(1.2); box-shadow: 0 10px 30px #7fc68f; display: flex; } /* * Styles for Animations */ @keyframes shake { 0% { transform: translate(1px, 1px) rotate(0deg); } 10% { transform: translate(-1px, -2px) rotate(-1deg); } 20% { transform: translate(-3px, 0px) rotate(1deg); } 30% { transform: translate(3px, 2px) rotate(0deg); } 40% { transform: translate(1px, -1px) rotate(1deg); } 50% { transform: translate(-1px, 2px) rotate(-1deg); } 60% { transform: translate(-3px, 1px) rotate(0deg); } 70% { transform: translate(3px, 1px) rotate(-1deg); } 80% { transform: translate(-1px, -1px) rotate(1deg); } 90% { transform: translate(1px, 2px) rotate(0deg); } 100% { transform: translate(1px, -2px) rotate(-1deg); } } .shake-to-shuffle { animation: shake 1s; } @keyframes wrong-cards-color { 0% {background-color: #ff3f00;} 25% {background-color: #ffbb00;} 100% {background-color: #ff3f00;} } @keyframes matching-cards-color { 0% {background-color: #02cc16;} 25% {background-color: #02cc16;} 50% {background-color: #88ff00;} 75% {background-color: #02cc16;} 100% {background-color: #02ccba;} } .toBeReflipped { animation: wrong-cards-color 1.2s; } .match { animation: matching-cards-color 1.2s; } img{ width: auto; max-height: 100%; transform: scale(0); transition: .2s; } </style> <head> <link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css"> </head> <body> <p>Matching Card Game</p> <section class="score-panel"> <div class="moves"> <span id="movesNumberDisplay">0</span> Moves </div> <div id="restartButton" class="restart"> Restart </div> </section> <ul id="deck" class="deck"> <li class="card num1"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806883142505725982/9fASFFq0On1DqlzoT2aB-AezEIgDRLAgieuZdlHZJgzJ_aJxzfKntD9FFFz8DlvksWdzU2k6DgcVngrowuPqPuIbXO-GWyDtbPga.png"class="img"></li> <li class="card num1"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806883142505725982/9fASFFq0On1DqlzoT2aB-AezEIgDRLAgieuZdlHZJgzJ_aJxzfKntD9FFFz8DlvksWdzU2k6DgcVngrowuPqPuIbXO-GWyDtbPga.png"class="img"></li> <li class="card num2"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806883063631052830/1200px-NSMBU_Fuzzy_Artwork.png"class="img"></li> <li class="card num2"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806883063631052830/1200px-NSMBU_Fuzzy_Artwork.png"class="img"></li> <li class="card num3"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882511690924067/mario-clipart-happy-18.png"class="img"></li> <li class="card num3"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882511690924067/mario-clipart-happy-18.png"class="img"></li> <li class="card num4"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882437979439194/latest.png"class="img"></li> <li class="card num4"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882437979439194/latest.png"class="img"></li> <li class="card num5"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882329074597889/Toad_3D_Land.png"class="img"></li> <li class="card num5"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882329074597889/Toad_3D_Land.png"class="img"></li> <li class="card num6"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882167916593223/latest.png"class="img"></li> <li class="card num6"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882167916593223/latest.png"class="img"></li> <li class="card num7"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882127638953994/Yoshi_Artwork_-_Mario_Party_6.png"class="img"></li> <li class="card num7"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882127638953994/Yoshi_Artwork_-_Mario_Party_6.png"class="img"></li> <li class="card num8"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882028498321450/Birdo-MP9.png"class="img"></li> <li class="card num8"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806882028498321450/Birdo-MP9.png"class="img"></li> <li class="card num9"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806881946168459274/Spiny_Artwork_-_New_Super_Mario_Bros.png"class="img"></li> <li class="card num9"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806881946168459274/Spiny_Artwork_-_New_Super_Mario_Bros.png"class="img"></li> <li class="card num0"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806881897111224330/220px-BooNSMBWarticle.png"class="img"></li> <li class="card num0"><img src="https://cdn.discordapp.com/attachments/798210236095004682/806881897111224330/220px-BooNSMBWarticle.png"class="img"></li> </ul> <center><a href="https://codepen.io/Sonjya00/pen/LmaVKK?editors=1010" target="_blank">CREDITS</a></center> <script> <!-- อ้างอิงโค้ดจาก https://codepen.io/Sonjya00/pen/LmaVKK?editors=1010--> const DECK = document.getElementById('deck'); const CARDS = document.getElementsByClassName('card'); const MOVES_NUMBER_DISPLAY = document.getElementById('movesNumberDisplay'); const RESTART_BUTTON = document.getElementById('restartButton'); let openCardsHC = document.getElementsByClassName('open'); let toBeReflippedHC = document.getElementsByClassName('toBeReflipped'); let matchCardsHC = document.getElementsByClassName('match'); let movesNumber = 0; //Call function to shuffle cards and create HTML to display the cards // เรียกฟังก์ชั่นเพื่อสับการ์ดและสร้าง HTML เพื่อโชว์หน้าการ์ด function newGame() { let cardsList = Array.prototype.slice.call(CARDS); cardsList = shuffle(cardsList); for (var i = 0; i < cardsList.length; i++) { DECK.appendChild(cardsList[i]) }; } newGame(); //Calls newGame function, reset timer, reset open/shown/matched cards, reset move number and matched cards number, reset star rating. function restartGame() { newGame(); DECK.classList.add('shake-to-shuffle'); if (matchCardsHC.length > 0 || openCardsHC.length > 0) { resetCards(); }; if (movesNumber !==0) { movesNumber = 0; MOVES_NUMBER_DISPLAY.textContent = movesNumber; } // matchNumber++; } // Shuffle function from http://stackoverflow.com/a/2450976 function shuffle(array) { let 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; } //Flip cards, store open/shown cards images in an array, run check matching cards function, and prevent more than 2 cards from being flipped. function flipCard(evt) { let flippedCard = evt.target; if (flippedCard.nodeName === 'LI') { if (!flippedCard.classList.contains('match') && !flippedCard.classList.contains('open')) { flippedCard.classList.add('open'); } } let openCardsArray = Array.prototype.slice.call(openCardsHC); if (openCardsArray.length ===2) { checkIfMatching(); } if (openCardsArray.length >2) { flipOpenCards(); } } //when 2 cards are open/shown, if their content match, assign class match, call function to unassign open/shown classes, add +1 matching couple found, call function to increment move by one and check if game is over. If they don't match, assign a temporary class to identity which cards need to be closed in case more than 2 cards were flipped, and call the function to close those 2 cards. In any case, the move number is incremented by one and the moves number is check to adjust star rating and to determine if game is over by max moves number reached function checkIfMatching() { let openCardsArray = Array.prototype.slice.call(openCardsHC); if (openCardsArray[0].classList[1] === openCardsArray[1].classList[1]) { openCardsArray.forEach(function(card) { card.classList.add('match'); }); handleMatchedCards(); // incrementMatchedCouples(); setTimeout(checkIfGameOver, 1200); } else { openCardsArray.forEach(function(card) { card.classList.add('toBeReflipped'); }); setTimeout(flipOpenCards, 1200); } incrementMovesNumber(); setTimeout(checkMovesNumber, 1200); } //close the 2 cards confronted and any other open card, preventing there to be more than 1 open card besides the matched ones function flipOpenCards() { let toBeReflipped = Array.prototype.slice.call(toBeReflippedHC); toBeReflipped.forEach(function(card) { card.classList.remove('open', 'toBeReflipped'); }); let openCardsArray = Array.prototype.slice.call(openCardsHC); if (openCardsArray.length>1) { openCardsArray.forEach(function(card) { card.classList.remove('open'); }); } } //remove open/show class to the matched couple function handleMatchedCards() { let matchCardsArray = Array.prototype.slice.call(matchCardsHC); matchCardsArray.forEach(function(card) { card.classList.remove('open'); }); } //remove open/show/match class to all matched cards. function resetCards() { let openCardsArray = Array.prototype.slice.call(openCardsHC); openCardsArray.forEach(function(card) { card.classList.remove('open'); }); let matchCardsArray = Array.prototype.slice.call(matchCardsHC); matchCardsArray.forEach(function(card) { card.classList.remove('match'); }); } //Increment moves number and display it function incrementMovesNumber() { movesNumber++; MOVES_NUMBER_DISPLAY.textContent = movesNumber; } //Check if all the couples have been matched, return alert according to star rating, stops timer function checkIfGameOver() { let matchCardsArray = Array.prototype.slice.call(matchCardsHC); if (matchCardsArray.length === 20) { let alertMessage = "Congratulations! You're the Winnerrrr!"; alert(alertMessage); restartGame(); } else { return; } } //Short function that removes the shuffle class from deck, so that it can be reapplied the next time the restart button is clicked function removeDeckShuffleClass() { DECK.classList.remove('shake-to-shuffle'); } //EVENT LISTENERS DECK.addEventListener('click', flipCard); RESTART_BUTTON.addEventListener('click', restartGame); RESTART_BUTTON.addEventListener('mouseover', removeDeckShuffleClass); </script> </body> </html>