Jeu
Memory Match
Javascript
Bootstrap 5
Concentration
Jeu Memoire
Interactif
Cartes
Html Css Js
Gaming
Snippet
Fun
Jeu de mémoire Memory Match en Bootstrap 5 et JavaScript. Retournez les cartes, trouvez les paires et améliorez votre concentration avec ce jeu interactif.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="copyright" content="AngularForAll" />
<meta name="author" content="AngularForAll" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Cache-Control" content="public, max-age=604800" />
<title>Snippet Game Memory Match Bootstrap5 2026 05050005 | AngularForAll</title>
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">
<style>
body {
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
min-height: 100vh;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.game-container {
background: rgba(255,255,255,0.95);
border-radius: 25px;
padding: 25px;
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
}
.memory-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
max-width: 550px;
margin: 0 auto;
}
.memory-card {
aspect-ratio: 1 / 1;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
border-radius: 15px;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
font-size: 40px;
color: white;
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
position: relative;
transform-style: preserve-3d;
}
.memory-card:hover {
transform: scale(1.05);
box-shadow: 0 10px 25px rgba(0,0,0,0.3);
}
.memory-card.flipped {
background: white;
color: #667eea;
cursor: default;
}
.memory-card.flipped:hover {
transform: scale(1);
}
.memory-card.matched {
background: #4caf50;
color: white;
cursor: default;
opacity: 0.7;
}
.memory-card.matched:hover {
transform: scale(1);
}
.memory-card.disabled {
pointer-events: none;
}
.score-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 15px;
padding: 15px;
color: white;
text-align: center;
}
.timer-circle {
width: 80px;
height: 80px;
border-radius: 50%;
background: conic-gradient(#ffd700 0deg, #e0e0e0 0deg);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
position: relative;
}
.timer-inner {
width: 70px;
height: 70px;
border-radius: 50%;
background: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: bold;
color: #667eea;
}
.btn-play {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
padding: 10px 25px;
font-weight: bold;
color: white;
transition: all 0.3s ease;
border-radius: 10px;
}
.btn-play:hover {
transform: scale(1.05);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
@keyframes matchAnimation {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); background: #45a049; }
}
.match-animation {
animation: matchAnimation 0.3s ease-in-out;
}
@keyframes wrongAnimation {
0%, 100% { transform: scale(1); background: white; }
50% { transform: scale(0.95); background: #ff6b6b; }
}
.wrong-animation {
animation: wrongAnimation 0.3s ease-in-out;
}
.victory-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.9);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
}
.victory-overlay.show {
opacity: 1;
visibility: visible;
}
.victory-content {
background: white;
border-radius: 30px;
padding: 40px;
text-align: center;
max-width: 400px;
animation: bounceIn 0.5s ease-out;
}
@keyframes bounceIn {
0% { transform: scale(0); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
.stats-card {
background: #f8f9fa;
border-radius: 15px;
padding: 10px;
text-align: center;
}
@media (max-width: 500px) {
.memory-grid {
gap: 8px;
}
.memory-card {
font-size: 24px;
}
}
</style>
</head>
<body>
<div class="container py-4">
<div class="row justify-content-center">
<div class="col-lg-8">
<!-- Titre -->
<div class="text-center mb-4">
<h1 class="text-white display-5 fw-bold">
<i class="bi bi-grid-3x3-gap-fill"></i> Memory Match
</h1>
<p class="text-white-50">Trouve toutes les paires !</p>
</div>
<!-- Zone de jeu -->
<div class="game-container">
<!-- Statistiques -->
<div class="row g-3 mb-4">
<div class="col-4">
<div class="score-card">
<i class="bi bi-trophy fs-4"></i>
<h3 class="mb-0" id="pairsFound">0</h3>
<small>Paires trouvées</small>
</div>
</div>
<div class="col-4">
<div class="score-card" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);">
<i class="bi bi-hand-index fs-4"></i>
<h3 class="mb-0" id="attempts">0</h3>
<small>Tentatives</small>
</div>
</div>
<div class="col-4">
<div class="score-card" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);">
<i class="bi bi-brain fs-4"></i>
<h3 class="mb-0" id="concentrationScore">100</h3>
<small>Concentration %</small>
</div>
</div>
</div>
<!-- Timer et meilleur score -->
<div class="row g-3 mb-4 align-items-center">
<div class="col-6">
<div class="stats-card">
<i class="bi bi-clock-history text-primary"></i>
<div class="timer-circle" id="timerCircle">
<div class="timer-inner" id="timerDisplay">00:00</div>
</div>
<small class="text-muted">Temps écoulé</small>
</div>
</div>
<div class="col-6">
<div class="stats-card">
<i class="bi bi-star-fill text-warning"></i>
<h3 class="mb-0" id="bestScore">0</h3>
<small>Meilleur temps</small>
<div id="bestScoreName" class="small text-muted"></div>
</div>
</div>
</div>
<!-- Grille de mémoire -->
<div id="memoryGrid" class="memory-grid mb-4"></div>
<!-- Contrôles -->
<div class="text-center">
<button id="newGameBtn" class="btn-play me-2">
<i class="bi bi-play-fill"></i> Nouvelle partie
</button>
<button id="resetBtn" class="btn-play" style="background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);">
<i class="bi bi-arrow-repeat"></i> Réinitialiser
</button>
</div>
</div>
<!-- Conseils pour améliorer la concentration -->
<div class="alert alert-success mt-4">
<i class="bi bi-lightbulb"></i>
<strong>Astuces pour mieux mémoriser :</strong>
<ul class="mb-0 mt-2">
<li>🔍 Commence par chercher les coins et les bords</li>
<li>🧠 Nomme à voix haute ce que tu vois (ex: "chat, étoile...")</li>
<li>📍 Visualise l'emplacement des cartes dans ta tête</li>
<li>🎯 Prends ton temps, la mémoire a besoin de calme</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Overlay de victoire -->
<div id="victoryOverlay" class="victory-overlay">
<div class="victory-content">
<i class="bi bi-trophy-fill fs-1" style="color: #ffd700;"></i>
<h2 class="mt-3">Félicitations !</h2>
<p>Tu as trouvé toutes les paires !</p>
<div class="row g-2 mt-3">
<div class="col-6">
<div class="stats-card">
<small>Tentatives</small>
<h4 id="finalAttempts">0</h4>
</div>
</div>
<div class="col-6">
<div class="stats-card">
<small>Temps</small>
<h4 id="finalTime">0</h4>
</div>
</div>
</div>
<div class="mt-3">
<p class="text-muted" id="victoryMessage"></p>
</div>
<button id="playAgainBtn" class="btn-play mt-3">
<i class="bi bi-arrow-repeat"></i> Rejouer
</button>
</div>
</div>
<script>
// Configuration du jeu
const icons = [
'🐶', '🐱', '🐭', '🐹', // Animaux
'🐰', '🦊', '🐻', '🐼', // Animaux 2
'⭐', '🌙', '☀️', '🌈', // Nature
'🍎', '🍕', '🎮', '🎵' // Divers
];
let cards = [];
let flippedCards = [];
let matchedPairs = 0;
let attempts = 0;
let gameActive = true;
let canFlip = true;
let startTime = null;
let timerInterval = null;
let concentration = 100;
let bestTimes = JSON.parse(localStorage.getItem('memoryBestTimes')) || [];
// Éléments HTML
const gridContainer = document.getElementById('memoryGrid');
const pairsFoundEl = document.getElementById('pairsFound');
const attemptsEl = document.getElementById('attempts');
const concentrationEl = document.getElementById('concentrationScore');
const timerDisplay = document.getElementById('timerDisplay');
const bestScoreEl = document.getElementById('bestScore');
const bestScoreNameEl = document.getElementById('bestScoreName');
const newGameBtn = document.getElementById('newGameBtn');
const resetBtn = document.getElementById('resetBtn');
const victoryOverlay = document.getElementById('victoryOverlay');
const finalAttempts = document.getElementById('finalAttempts');
const finalTime = document.getElementById('finalTime');
const victoryMessage = document.getElementById('victoryMessage');
const playAgainBtn = document.getElementById('playAgainBtn');
// Afficher le meilleur temps
function updateBestScoreDisplay() {
if (bestTimes.length > 0) {
const best = bestTimes[0];
const minutes = Math.floor(best.time / 60);
const seconds = best.time % 60;
bestScoreEl.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
bestScoreNameEl.textContent = `${best.attempts} tentatives`;
} else {
bestScoreEl.textContent = '--:--';
bestScoreNameEl.textContent = 'Aucun record';
}
}
// Sauvegarder le temps
function saveBestTime(time, attemptsCount) {
bestTimes.push({ time: time, attempts: attemptsCount, date: new Date() });
bestTimes.sort((a, b) => a.time - b.time);
bestTimes = bestTimes.slice(0, 5);
localStorage.setItem('memoryBestTimes', JSON.stringify(bestTimes));
updateBestScoreDisplay();
}
// Démarrer le timer
function startTimer() {
if (timerInterval) clearInterval(timerInterval);
startTime = Date.now();
timerInterval = setInterval(() => {
if (!gameActive) return;
const elapsed = Math.floor((Date.now() - startTime) / 1000);
const minutes = Math.floor(elapsed / 60);
const seconds = elapsed % 60;
timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
// Mettre à jour le cercle de timer
const progress = (elapsed % 60) / 60 * 360;
document.getElementById('timerCircle').style.background = `conic-gradient(#ffd700 ${progress}deg, #e0e0e0 ${progress}deg)`;
}, 1000);
}
// Arrêter le timer
function stopTimer() {
if (timerInterval) {
clearInterval(timerInterval);
timerInterval = null;
}
}
// Mélanger les cartes
function shuffleArray(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;
}
// Initialiser les cartes
function initCards() {
const selectedIcons = icons.slice(0, 8);
const cardPairs = [...selectedIcons, ...selectedIcons];
cards = shuffleArray(cardPairs).map((icon, index) => ({
id: index,
icon: icon,
flipped: false,
matched: false
}));
}
// Créer la grille HTML
function renderGrid() {
gridContainer.innerHTML = '';
cards.forEach((card, index) => {
const cardDiv = document.createElement('div');
cardDiv.className = 'memory-card';
if (card.flipped) cardDiv.classList.add('flipped');
if (card.matched) cardDiv.classList.add('matched');
cardDiv.innerHTML = (card.flipped || card.matched) ? card.icon : '?';
cardDiv.addEventListener('click', () => handleCardClick(index));
gridContainer.appendChild(cardDiv);
});
}
// Vérifier la concentration
function updateConcentration() {
const remainingPairs = 8 - matchedPairs;
const difficulty = remainingPairs;
let newConcentration = Math.max(0, 100 - (attempts * 2) - (difficulty * 3));
concentration = Math.min(100, newConcentration);
concentrationEl.textContent = Math.max(0, concentration);
}
// Gérer le clic sur une carte
function handleCardClick(index) {
if (!gameActive || !canFlip) return;
const card = cards[index];
if (card.flipped || card.matched) return;
// Retourner la carte
card.flipped = true;
renderGrid();
// Ajouter à la liste des cartes retournées
flippedCards.push(index);
// Vérifier si on a 2 cartes
if (flippedCards.length === 2) {
canFlip = false;
attempts++;
attemptsEl.textContent = attempts;
updateConcentration();
const card1 = cards[flippedCards[0]];
const card2 = cards[flippedCards[1]];
if (card1.icon === card2.icon) {
// Paire trouvée !
setTimeout(() => {
card1.matched = true;
card2.matched = true;
card1.flipped = false;
card2.flipped = false;
matchedPairs++;
pairsFoundEl.textContent = matchedPairs;
// Animation
const cardsElements = document.querySelectorAll('.memory-card');
cardsElements[flippedCards[0]].classList.add('match-animation');
cardsElements[flippedCards[1]].classList.add('match-animation');
setTimeout(() => {
renderGrid();
}, 200);
flippedCards = [];
canFlip = true;
// Vérifier victoire
if (matchedPairs === 8) {
gameWin();
}
}, 500);
} else {
// Pas une paire
setTimeout(() => {
card1.flipped = false;
card2.flipped = false;
renderGrid();
flippedCards = [];
canFlip = true;
}, 800);
// Animation d'erreur
const cardsElements = document.querySelectorAll('.memory-card');
cardsElements[flippedCards[0]].classList.add('wrong-animation');
cardsElements[flippedCards[1]].classList.add('wrong-animation');
setTimeout(() => {
cardsElements[flippedCards[0]].classList.remove('wrong-animation');
cardsElements[flippedCards[1]].classList.remove('wrong-animation');
}, 300);
}
}
}
// Victoire
function gameWin() {
gameActive = false;
stopTimer();
const elapsed = Math.floor((Date.now() - startTime) / 1000);
const minutes = Math.floor(elapsed / 60);
const seconds = elapsed % 60;
const timeString = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
finalAttempts.textContent = attempts;
finalTime.textContent = timeString;
// Message personnalisé
if (elapsed < 30) {
victoryMessage.textContent = '🏆 Exceptionnel ! Tu as une mémoire d\'éléphant ! 🏆';
} else if (elapsed < 60) {
victoryMessage.textContent = '🎉 Excellent ! Continue comme ça ! 🎉';
} else if (elapsed < 120) {
victoryMessage.textContent = '👍 Bien joué ! Entraîne-toi pour battre ton record ! 👍';
} else {
victoryMessage.textContent = '💪 Bon travail ! Avec de l\'entraînement, tu iras plus vite ! 💪';
}
// Sauvegarder le meilleur temps
saveBestTime(elapsed, attempts);
victoryOverlay.classList.add('show');
}
// Nouvelle partie
function newGame() {
stopTimer();
initCards();
flippedCards = [];
matchedPairs = 0;
attempts = 0;
gameActive = true;
canFlip = true;
concentration = 100;
pairsFoundEl.textContent = matchedPairs;
attemptsEl.textContent = attempts;
concentrationEl.textContent = concentration;
renderGrid();
startTimer();
victoryOverlay.classList.remove('show');
}
// Réinitialiser
function resetGame() {
newGame();
}
// Rejouer
function playAgain() {
newGame();
}
// Événements
newGameBtn.addEventListener('click', newGame);
resetBtn.addEventListener('click', resetGame);
playAgainBtn.addEventListener('click', playAgain);
// Initialiser
updateBestScoreDisplay();
newGame();
// Message de bienvenue
setTimeout(() => {
alert('🧠 Memory Match - Jeu de concentration !\n\nComment jouer :\n1. Clique sur une carte pour la retourner\n2. Trouve la carte identique\n3. Forme toutes les paires\n4. Bat ton record de temps !');
}, 500);
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
Télécharger le fichier source