Jogo da Memória
Pares de cards virados para baixo que o aprendiz vira dois a dois. Quando os pares formam conceito e definição correspondentes, o par é removido. Desenvolve memorização através de tentativa, erro e reforço.
Experimente
Ferramentas e seus Usos
Vire duas cartas por vez e encontre a ferramenta que corresponde ao resultado do seu uso.
Código-fonte
Dados de exemplo
Cada par tem duas imagens diferentes que se correspondem — nunca a mesma foto duplicada.
| 1 |
<?php
|
| 2 |
$pares = [
|
| 3 |
['id' => 'p1', 'a' => ['imagem' => 'cachorro.jpg', 'legenda' => 'Cachorro'], 'b' => ['imagem' => 'pegada-cachorro.jpg', 'legenda' => 'Pegada de cachorro']],
|
| 4 |
['id' => 'p2', 'a' => ['imagem' => 'gato.jpg', 'legenda' => 'Gato'], 'b' => ['imagem' => 'pegada-gato.jpg', 'legenda' => 'Pegada de gato']],
|
| 5 |
['id' => 'p3', 'a' => ['imagem' => 'cavalo.jpg', 'legenda' => 'Cavalo'], 'b' => ['imagem' => 'pegada-cavalo.jpg', 'legenda' => 'Pegada de cavalo']],
|
| 6 |
['id' => 'p4', 'a' => ['imagem' => 'urso.jpg', 'legenda' => 'Urso'], 'b' => ['imagem' => 'pegada-urso.jpg', 'legenda' => 'Pegada de urso']],
|
| 7 |
];
|
| 8 |
|
| 9 |
$cartas = [];
|
| 10 |
foreach ($pares as $par) {
|
| 11 |
$cartas[] = ['par' => $par['id'], 'tipo' => 'a', 'imagem' => $par['a']['imagem'], 'legenda' => $par['a']['legenda']];
|
| 12 |
$cartas[] = ['par' => $par['id'], 'tipo' => 'b', 'imagem' => $par['b']['imagem'], 'legenda' => $par['b']['legenda']];
|
| 13 |
}
|
| 14 |
shuffle($cartas);
|
| 15 |
?>
|
Estrutura da questão
Uma grade de cartas viradas para baixo; cada uma guarda o id do par e um "tipo" (a/b) — o par só é válido quando os dois lados combinam por par mas divergem em tipo.
| 1 |
<div class="questao" data-tipo="jogo-memoria" data-pares="<?= count($pares) ?>">
|
| 2 |
|
| 3 |
<p class="questao-instrucao">Vire duas cartas por vez e encontre o animal que corresponde à sua pegada.</p>
|
| 4 |
<p class="placar">Pares encontrados: <span class="encontrados">0</span>/<?= count($pares) ?></p>
|
| 5 |
|
| 6 |
<div class="grade">
|
| 7 |
<?php foreach ($cartas as $carta): ?>
|
| 8 |
<button type="button" class="carta" data-par="<?= $carta['par'] ?>" data-tipo="<?= $carta['tipo'] ?>">
|
| 9 |
<span class="verso">?</span>
|
| 10 |
<img class="frente" src="<?= $carta['imagem'] ?>" alt="<?= htmlspecialchars($carta['legenda']) ?>" hidden>
|
| 11 |
</button>
|
| 12 |
<?php endforeach; ?>
|
| 13 |
</div>
|
| 14 |
|
| 15 |
</div>
|
Placar
Contagem simples de pares encontrados.
| 1 |
.placar {
|
| 2 |
margin: 0 0 8px;
|
| 3 |
font-size: 13px;
|
| 4 |
color: #64748b;
|
| 5 |
}
|
Grade de cartas
Cartas quadradas, viradas para baixo por padrão.
| 1 |
.grade {
|
| 2 |
display: grid;
|
| 3 |
grid-template-columns: repeat(4, 1fr);
|
| 4 |
gap: 8px;
|
| 5 |
margin: 16px 0;
|
| 6 |
}
|
| 7 |
|
| 8 |
.carta {
|
| 9 |
position: relative;
|
| 10 |
aspect-ratio: 1 / 1;
|
| 11 |
border: 1px solid #cbd5e1;
|
| 12 |
border-radius: 10px;
|
| 13 |
background: #f1f5f9;
|
| 14 |
overflow: hidden;
|
| 15 |
cursor: pointer;
|
| 16 |
}
|
| 17 |
|
| 18 |
.verso {
|
| 19 |
display: flex;
|
| 20 |
align-items: center;
|
| 21 |
justify-content: center;
|
| 22 |
width: 100%;
|
| 23 |
height: 100%;
|
| 24 |
font-size: 20px;
|
| 25 |
font-weight: 700;
|
| 26 |
color: #94a3b8;
|
| 27 |
}
|
| 28 |
|
| 29 |
.frente {
|
| 30 |
display: block;
|
| 31 |
width: 100%;
|
| 32 |
height: 100%;
|
| 33 |
object-fit: cover;
|
| 34 |
}
|
Estados de resultado
Verde para o par certo (fica assim permanentemente); vermelho enquanto o par errado está exposto, esperando ser dispensado pela próxima carta clicada.
| 1 |
.carta.correta {
|
| 2 |
border-color: #22c55e;
|
| 3 |
box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.3);
|
| 4 |
}
|
| 5 |
|
| 6 |
.carta.errada {
|
| 7 |
border-color: #ef4444;
|
| 8 |
box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.3);
|
| 9 |
}
|
Encontrar os elementos da questão
Localiza a grade de cartas e o contador de pares.
| 1 |
document.addEventListener('DOMContentLoaded', function () {
|
| 2 |
document.querySelectorAll('.questao[data-tipo="jogo-memoria"]').forEach(function (questao) {
|
| 3 |
var totalPares = parseInt(questao.dataset.pares, 10) || 0;
|
| 4 |
var placar = questao.querySelector('.encontrados');
|
| 5 |
var selecionadas = [];
|
| 6 |
// true quando um par errado está exposto, esperando o próximo clique
|
| 7 |
// pra sumir — em vez de sumir sozinho depois de um tempo.
|
| 8 |
var aguardandoDispensar = false;
|
| 9 |
var encontrados = 0;
|
| 10 |
|
| 11 |
function virar(carta) {
|
| 12 |
carta.classList.add('virada');
|
| 13 |
carta.querySelector('.verso').hidden = true;
|
| 14 |
carta.querySelector('.frente').hidden = false;
|
| 15 |
}
|
| 16 |
|
| 17 |
function desvirar(carta) {
|
| 18 |
carta.classList.remove('virada', 'errada');
|
| 19 |
carta.querySelector('.verso').hidden = false;
|
| 20 |
carta.querySelector('.frente').hidden = true;
|
| 21 |
}
|
Clicar numa carta
A primeira carta clicada depois de um par errado exposto dispensa esse par antes de continuar — nada de sumir sozinho depois de um tempo.
| 1 |
questao.querySelectorAll('.carta').forEach(function (carta) {
|
| 2 |
carta.addEventListener('click', function () {
|
| 3 |
if (carta.classList.contains('virada') || carta.disabled) return;
|
| 4 |
|
| 5 |
if (aguardandoDispensar) {
|
| 6 |
desvirar(selecionadas[0]);
|
| 7 |
desvirar(selecionadas[1]);
|
| 8 |
selecionadas = [];
|
| 9 |
aguardandoDispensar = false;
|
| 10 |
}
|
| 11 |
|
| 12 |
virar(carta);
|
| 13 |
selecionadas.push(carta);
|
| 14 |
|
| 15 |
if (selecionadas.length === 2) {
|
| 16 |
var a = selecionadas[0], b = selecionadas[1];
|
| 17 |
if (a.dataset.par === b.dataset.par && a.dataset.tipo !== b.dataset.tipo) {
|
Par correto
As duas cartas ficam viradas e travadas — saem do jogo definitivamente.
| 1 |
a.classList.add('correta');
|
| 2 |
b.classList.add('correta');
|
| 3 |
a.disabled = true;
|
| 4 |
b.disabled = true;
|
| 5 |
encontrados++;
|
| 6 |
placar.textContent = encontrados;
|
| 7 |
selecionadas = [];
|
| 8 |
} else {
|
Par errado
Fica exposto até a próxima carta clicada dispensar as duas.
| 1 |
a.classList.add('errada');
|
| 2 |
b.classList.add('errada');
|
| 3 |
aguardandoDispensar = true;
|
| 4 |
}
|
| 5 |
}
|
| 6 |
});
|
| 7 |
});
|