VibeTeacher
Tillbaka till resurser

Kopiera koden och använd den i ditt eget projekt eller klistra in den i en annan AI.

<!DOCTYPE html>
<html lang="sv">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Memory – Ljud och frekvens</title>

<style>
:root {
  --primar: #4a7cff;
  --bakgrund: #f1f4fb;
  --kort: #ffffff;
  --match: #4caf50;
  --skugga: rgba(0,0,0,0.15);
}

body {
  margin: 0;
  font-family: "Segoe UI", Arial, sans-serif;
  background: var(--bakgrund);
  display: flex;
  justify-content: center;
}

.container {
  max-width: 900px;
  width: 100%;
  padding: 20px;
  text-align: center;
}

h1 {
  color: var(--primar);
}

.instructions {
  background: white;
  padding: 15px;
  border-radius: 12px;
  box-shadow: 0 4px 8px var(--skugga);
  margin-bottom: 15px;
  line-height: 1.5;
}

.stats {
  font-size: 1.1rem;
  margin-bottom: 15px;
}

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  perspective: 1000px;
}

.card {
  position: relative;
  width: 100%;
  padding-top: 100%;
  cursor: pointer;
}

.card-inner {
  position: absolute;
  inset: 0;
  transition: transform 0.6s;
  transform-style: preserve-3d;
}

.card.flipped .card-inner {
  transform: rotateY(180deg);
}

.face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  border-radius: 12px;
  box-shadow: 0 4px 8px var(--skugga);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
}

.back {
  background: linear-gradient(135deg, var(--primar), #8fb1ff);
  color: white;
  font-size: 2.2rem;
  font-weight: bold;
}

.front {
  background: var(--kort);
  transform: rotateY(180deg);
  font-size: 0.9rem;
  line-height: 1.3;
  overflow-y: auto;
}

.card.matched .front {
  border: 4px solid var(--match);
  background: #eaffea;
}

/* Vinstskärm */
.win {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.6);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

.win-box {
  background: white;
  padding: 30px;
  border-radius: 16px;
  max-width: 400px;
  width: 90%;
  text-align: center;
}

.win-box h2 {
  color: var(--match);
}

button {
  margin-top: 15px;
  padding: 10px 20px;
  font-size: 1rem;
  border-radius: 8px;
  border: none;
  background: var(--primar);
  color: white;
  cursor: pointer;
}

button:hover {
  opacity: 0.9;
}

@media (max-width: 700px) {
  .grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
</style>
</head>

<body>
<div class="container">
  <h1>Memory – Ljud & frekvens</h1>

  <div class="instructions">
    <strong>Instruktioner:</strong><br>
    Klicka på två kort i taget för att hitta matchande par.  
    Om korten hör ihop stannar de öppna och markeras i grönt.  
    Om de inte matchar vänds de tillbaka efter en sekund.  
    Försök klara spelet med så få rörelser som möjligt!
  </div>

  <div class="stats">
    Rörelser: <span id="moves">0</span>
  </div>

  <div class="grid" id="grid"></div>
</div>

<div class="win" id="win">
  <div class="win-box">
    <h2>🎉 Bra jobbat!</h2>
    <p>Du har hittat alla par.</p>
    <p>Antal rörelser: <strong id="finalMoves"></strong></p>
    <button onclick="startGame()">Spela igen</button>
  </div>
</div>

<script>
const pairs = [
  ["Hertz", "En enhet för att mäta frekvensen av energivågor i till exempel ljud eller elektricitet. Den mäts i svängningar per sekund"],
  ["Ljud", "Mekaniska vågor, en varierande täthet som överförs av ett fast ämne, vätska eller gas, som kan höras eller uppfattas som vibrationer"],
  ["Frekvens", "Hur ofta något inträffar"],
  ["Ultraljud", "Ett ljud med så hög frekvens att människor inte kan uppfatta det"],
  ["Infraljud", "Ljud med en frekvens under 20 hertz, vilket är för lågt för att människor ska kunna höra det"],
  ["Decibel", "En enhet för att mäta ljudets volym"],
  ["Stigbygeln", "Ett av de tre benen i mellanörat som för vidare och förstärker ljudet från hörselgången till innerörat"],
  ["Eko", "När ljud studsar mot en yta och hörs igen efter en fördröjning"]
];

let deck = [];
let flipped = [];
let moves = 0;
let matched = 0;
let lock = false;

const grid = document.getElementById("grid");
const movesEl = document.getElementById("moves");
const win = document.getElementById("win");
const finalMoves = document.getElementById("finalMoves");

function startGame() {
  grid.innerHTML = "";
  deck = [];
  flipped = [];
  moves = 0;
  matched = 0;
  lock = false;
  movesEl.textContent = 0;
  win.style.display = "none";

  pairs.forEach(pair =>
    pair.forEach(text => deck.push({ text, id: pair[0] }))
  );

  deck.sort(() => Math.random() - 0.5);

  deck.forEach(data => {
    const card = document.createElement("div");
    card.className = "card";
    card.dataset.id = data.id;

    card.innerHTML = `
      <div class="card-inner">
        <div class="face back">?</div>
        <div class="face front">${data.text}</div>
      </div>
    `;

    card.addEventListener("click", () => flip(card));
    grid.appendChild(card);
  });
}

function flip(card) {
  if (lock || card.classList.contains("flipped") || card.classList.contains("matched")) return;

  card.classList.add("flipped");
  flipped.push(card);

  if (flipped.length === 2) {
    moves++;
    movesEl.textContent = moves;
    check();
  }
}

function check() {
  const [a, b] = flipped;

  if (a.dataset.id === b.dataset.id) {
    a.classList.add("matched");
    b.classList.add("matched");
    flipped = [];
    matched++;

    if (matched === pairs.length) {
      setTimeout(() => {
        finalMoves.textContent = moves;
        win.style.display = "flex";
      }, 500);
    }
  } else {
    lock = true;
    setTimeout(() => {
      a.classList.remove("flipped");
      b.classList.remove("flipped");
      flipped = [];
      lock = false;
    }, 1000);
  }
}

startGame();
</script>
</body>
</html>

Ljudmemory

Para ihop begreppet med rätt förklaring.

Information

Datum
28 april 2026
Typ
Spel
Visningar
0
Favoriter
0

Ämne & stadium

NOMellanstadiet

Skapad med

Copilot