diff --git a/ASSets/card1.jpg b/ASSets/card1.jpg new file mode 100644 index 0000000..ff32a3b Binary files /dev/null and b/ASSets/card1.jpg differ diff --git a/ASSets/card2.jpg b/ASSets/card2.jpg new file mode 100644 index 0000000..a8e3710 Binary files /dev/null and b/ASSets/card2.jpg differ diff --git a/ASSets/card3.jpeg b/ASSets/card3.jpeg new file mode 100644 index 0000000..31a62cd Binary files /dev/null and b/ASSets/card3.jpeg differ diff --git a/ASSets/cardback.jpg b/ASSets/cardback.jpg new file mode 100644 index 0000000..a9ed6a2 Binary files /dev/null and b/ASSets/cardback.jpg differ diff --git a/ASSets/fart.mp3 b/ASSets/fart.mp3 new file mode 100644 index 0000000..b3aa485 Binary files /dev/null and b/ASSets/fart.mp3 differ diff --git a/README.md b/README.md index 4361cf2..8ddc124 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ -# memoatse +# Memory but with Goatse and memes + +loldongs diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..08f15c6 --- /dev/null +++ b/css/style.css @@ -0,0 +1,34 @@ +.container { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 12px; + padding: 12px; + max-width: 900px; + margin: 0 auto; +} +.container div { + background-color: #f1f1f1; + border: 1px solid #ddd; + border-radius: 8px; + overflow: hidden; + aspect-ratio: 3 / 4; +} + +.container div img { + width: 100%; + height: 100%; + display: block; + object-fit: cover; +} + +@media (max-width: 600px) { + .container { + grid-template-columns: repeat(2, 1fr); + } +} + +h1 { + text-align: center; + font-size: 2rem; + margin-bottom: 2rem; +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..fb12b7e --- /dev/null +++ b/index.html @@ -0,0 +1,17 @@ + + + + + + Memoatse + + + + +

Memoatse

+
+ + + diff --git a/js/script.js b/js/script.js new file mode 100644 index 0000000..e910602 --- /dev/null +++ b/js/script.js @@ -0,0 +1,104 @@ +class Card { + constructor(imgPath) { + this.img = "ASSets/" + imgPath; + this.name = imgPath.split(".")[0]; + this.pairId = Card.nextPairId++; + } + static altText = "Upside-down card"; + static nextPairId = 0; +} + +const cards = [ + "card1.jpg", + "card2.jpg", + "card3.jpeg", +] + +const deck = []; +cards.forEach(card => { + deck.push(new Card(card)); +}); + +// Fisher-Yates shuffle +const shuffle = (array) => { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array; +} + +const buildFullDeck = (baseDeck) => { + return shuffle([...baseDeck, ...baseDeck]); +}; + +const createCardElement = (backSrc) => { + const cardElem = document.createElement("div"); + cardElem.className = "card"; + cardElem.dataset.revealed = "false"; + const img = document.createElement("img"); + img.src = backSrc; + img.alt = Card.altText; + cardElem.appendChild(img); + return cardElem; +}; + +const revealCard = (elem, card) => { + const img = elem.querySelector("img"); + img.src = card.img; + elem.dataset.revealed = "true"; +}; + +const hideCard = (elem, backSrc) => { + const img = elem.querySelector("img"); + img.src = backSrc; + elem.dataset.revealed = "false"; +}; + +const startGame = () => { + const container = document.getElementById("cards"); + const backSrc = "ASSets/cardback.jpg"; + const winSfx = new Audio("ASSets/fart.mp3"); + const fullDeck = buildFullDeck(deck); + container.innerHTML = ""; + + let firstPick = null; + let isLocked = false; + let matchedCount = 0; + + fullDeck.forEach((card) => { + const el = createCardElement(backSrc); + + el.addEventListener("click", () => { + if (isLocked) return; + if (el.dataset.revealed === "true") return; + + revealCard(el, card); + + if (!firstPick) { + firstPick = { el, card }; + return; + } + + if (firstPick.card.pairId === card.pairId && firstPick.el !== el) { + matchedCount += 2; + firstPick = null; + if (matchedCount === fullDeck.length) { + try { winSfx.currentTime = 0; winSfx.play(); } catch (_) {} + setTimeout(startGame, 800); + } + } else { + isLocked = true; + const prev = firstPick; + firstPick = null; + setTimeout(() => { + hideCard(prev.el, backSrc); + hideCard(el, backSrc); + isLocked = false; + }, 700); + } + }); + + container.appendChild(el); + }); +};