memoji JS, игра с карточками
При верном открытии всех карточек время должно останавливаться и выскакивать надпись WIN, при нажатии на кнопку на ней карточки должны рандомиться и игра готова к использованию без перезагрузки страницы.
Мы имеем: надпись WIN не вылетает, время не останавливается, а после нажатия на кнопку Lose эмоджи с карточек исчезают
let emoji = ['\u{1F984}', '\u{1F43C}', '\u{1F437}', '\u{1F981}', '\u{1F41E}', '\u{1F438}', '\u{1F984}', '\u{1F43C}', '\u{1F437}', '\u{1F981}', '\u{1F41E}', '\u{1F438}'];
const rotate = document.querySelectorAll('.card');
const emojis = document.querySelectorAll('.emoji');
const front = document.querySelectorAll('.back_card');
let time = 60;
let conditions = randomCard();
const timer = document.querySelector('.timer');
timer.textContent = '0' + (time - time % 60) / 60 + ':' + ((time < 10) ? '0' + time : (time % 60 < 10) ? '0' + time % 60 : time % 60);
const playBtn = document.querySelector('.play');
const endGame = document.querySelector('.end_game');
// Для первого клика
let isClicked = false;
playBtn.addEventListener('click', newGame);
// let conditions = randomCard();
//массив, в котором будут хранится выбранные карты
let pickArr = []
var intervalId;
function anima_cards(target) {
if (!isClicked) {
isClicked = true;
intervalId = setInterval(gameIter, 1000);
}
if (pickArr.length < 2) {
target.children[0].classList.add('anima_front');
target.children[1].classList.add('anima_back');
pickArr.push(target)
}
if (pickArr.length == 2) {
//запускаем проверку на совпадение с некоторой задержкой, т.к. дом дерево надо перерисовать.
setTimeout(checker, 500)
}
if (hasWon()) {
win();
}
}
//проверяет совпадение, подствечивает плейсхолдер.
const checker = () => {
let color = pickArr[0].querySelector('.emoji').textContent == pickArr[1].querySelector('.emoji').textContent ? 'success' : 'fail';
pickArr.forEach((item) => {
item.querySelector('.card_placeholder').classList.toggle(color)
})
//оканчиваем ход
setTimeout(finisher, 500, color)
}
//заканчивает ход - отключает плейсхолдер, поворачивает обратно карты, если не угадал.
const finisher = (color) => {
pickArr.forEach((item) => {
item.querySelector('.card_placeholder').classList.toggle(color);
if (color == 'fail') {
item.children[0].classList.toggle('anima_front');
item.children[1].classList.toggle('anima_back');
}
})
pickArr = pickArr.slice(-1, 0)
}
rotate.forEach((card) => card.addEventListener('click', ({
currentTarget
}) => {
//Если необходимо, здесь вы можете передавать индексы в anima_cards,
//т.к. каллбек ф-я forEach вторым аргументом принимает индекс элемента, который можно пробросить дальше
anima_cards(currentTarget);
}));
function newGame() {
uncertainCardsNumber = 0
for (var card of rotate) {
card.children[0].classList.remove('anima_front');
card.children[1].classList.remove('anima_back');
}
time = 60;
timer.textContent = '0' + (time - time % 60) / 60 + ':' + ((time < 10) ? '0' + time : (time % 60 < 10) ? '0' + time % 60 : time % 60);
isClicked = false;
endGame.classList.add('invisible');
document.querySelector('.jump:nth-child(4)').classList.remove('invisible');
conditions = randomCard();
}
function randomCard() {
emojis.forEach((elem => {
let max = emoji.length;
let index = getRandom(0, max);
elem.textContent = emoji[index];
emoji.splice(index, 1);
}));
}
function gameIter() {
time--;
timer.textContent = '0' + (time - time % 60) / 60 + ':' + ((time < 10) ? '0' + time : (time % 60 < 10) ? '0' + time % 60 : time % 60);
if (time == 0) {
clearInterval(intervalId);
timeIsOver();
}
}
function win() {
showResult(true);
clearInterval(intervalId);
}
// Функция вызывается при окончании времени, те при поражении
function timeIsOver() {
showResult(false);
}
function hasWon() {
for (var condition of conditions) {
if (condition['state'] != SOLVED) {
return false;
}
}
return true;
}
function showResult(res) {
var spans = Array.from(document.querySelectorAll('.jump'));
var letters;
if (res) {
playBtn.textContent = 'Play again';
letters = ['W', 'i', 'n'];
spans[3].classList.add('invisible');
} else {
playBtn.textContent = 'Try again';
letters = ['L', 'o', 's', 'e'];
}
for (var i = 0; i < letters.length; i++) {
spans[i].textContent = letters[i];
}
endGame.classList.remove('invisible');
}
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
// randomCard();
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
height: 100vh;
background: #cfd0cf;
}
h1 {
text-align: center;
font-size: 42px;
margin: 40px;
color: #434344;
font-family: Arial, Helvetica, sans-serif;
line-height: 47px;
}
main {
display: flex;
flex-direction: column;
align-items: center;
}
.memory_card {
display: grid;
width: 620px;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 25px;
grid-row-gap: 25px;
}
.card {
perspective: 600px;
cursor: pointer;
width: 130px;
height: 130px;
position: relative;
}
.front_card {
width: 130px;
height: 130px;
background: linear-gradient(45deg, #22AB93, #19668D);
border: 5px solid white;
}
.back_card {
width: 130px;
height: 130px;
transform: rotateY(180deg);
background: white;
text-align: center;
}
.front_card,
.back_card,
.card_placeholder {
position: absolute;
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.5);
top: 0;
left: 0;
backface-visibility: hidden;
transition: 1s;
border-radius: 9px;
}
.card_placeholder {
z-index: 100;
width: 100%;
height: 100%;
opacity: .5;
}
.emoji {
margin: 0;
font-size: 75px;
line-height: 130px;
}
.anima_back {
transform: rotateY(360deg);
}
.anima_front {
transform: rotateY(360deg);
}
.fail {
background: #F44336;
z-index: 100;
}
.success {
background: #5AD66F;
}
.not-active {
pointer-events: none;
}
.timer {
font-size: 32px;
font-family: Arial, sans-serif;
color: #434344;
line-height: 36px;
margin-top: 30px;
display: flex;
justify-content: center;
}
.end_game {
outline: none;
position: fixed;
z-index: 999;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
background: rgba(0, 0, 0, 0.5);
}
.result_window {
display: inline-block;
min-width: 350px;
background-color: #CFD0CF;
margin-top: 15%;
}
.result {
font-size: 48px;
font-family: Arial, sans-serif;
margin: 30px auto 0;
}
.invisible {
display: none !important;
}
.play {
color: white;
display: inline-block;
font-size: 20px;
font-family: Arial, sans-serif;
padding: 10px 30px;
margin: 40px 0 30px;
background: linear-gradient(45deg, #22AB93, #19668d);
box-sizing: border-box;
text-decoration: none;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 1);
}
.play:hover {
opacity: 0.9;
}
.play:active {
box-shadow: inset 2px 1px 8px rgba(0, 0, 0, 1);
}
.jump:nth-child(1) {
display: inline-block;
animation: jump 1s ease-out infinite;
}
.jump:nth-child(2) {
display: inline-block;
animation: jump 1s 0.1s ease-out infinite;
}
.jump:nth-child(3) {
display: inline-block;
animation: jump 1s 0.2s ease-out infinite;
}
.jump:nth-child(4) {
display: inline-block;
animation: jump 1s 0.3s ease-out infinite;
}
@keyframes jump {
30% {
transform: translateY(-10px) scaleY(1.2);
}
85% {
transform: translateY(10px) scaleY(0.7);
}
}
<header>
<h1>Memoji</h1>
</header>
<main>
<div class="memory_card">
<div class="card" data-card="unicorn">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="unicorn">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="raccoon">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="raccoon">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="pig">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="pig">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="tiger">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="tiger">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="bag">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="bag">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="frog">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
<div class="card" data-card="frog">
<div class="front_card"></div>
<div class="back_card">
<div class="emoji"></div>
</div>
<div class='card_placeholder'></div>
</div>
</div>
</main>
<div class='end_game invisible'>
<div class='result_window'>
<div class='result'><span class='jump'></span><span class='jump'></span><span class='jump'></span><span class='jump'>e</span></div>
<a class='play'>Play again</a>
</div>
</div>
<footer class="timer">01:00</footer>