简介
记忆翻牌是一款经典的记忆力训练游戏,玩家翻开卡片寻找配对。游戏厅版本使用 CSS 3D Transform 实现逼真的卡片翻转动画,支持简单(4x4,8对)和困难(6x6,18对)两种难度。
卡片数据
符号库
使用 emoji 作为卡片图案,直观且跨平台:
1var emojis = [
2 '🍎', '🍊', '🍋', '🍇', '🍓', '🍒',
3 '🥝', '🍑', '🌮', '🍕', '🍔', '🌭',
4 '🥨', '🧁', '🍩', '🍪', '🥑', '🌶️'
5];
洗牌算法
使用 Fisher-Yates 洗牌算法打乱卡片顺序:
1function shuffle(cards) {
2 for (var i = cards.length - 1; i > 0; i--) {
3 var j = Math.floor(Math.random() * (i + 1));
4 var temp = cards[i];
5 cards[i] = cards[j];
6 cards[j] = temp;
7 }
8}
难度配置
1var difficulties = {
2 easy: { rows: 4, cols: 4, pairs: 8 }, // 16 张卡片
3 hard: { rows: 6, cols: 6, pairs: 18 } // 36 张卡片
4};
CSS 3D 翻转动画
卡片结构
每张卡片由正反两面组成,使用 CSS 3D Transform 实现翻转:
1<div class="memo-card">
2 <div class="memo-card-inner">
3 <div class="memo-card-front">?</div>
4 <div class="memo-card-back">🍎</div>
5 </div>
6</div>
翻转 CSS
1.memo-card {
2 perspective: 600px;
3 width: var(--memo-size);
4 height: var(--memo-size);
5}
6.memo-card-inner {
7 position: relative;
8 width: 100%;
9 height: 100%;
10 transition: transform 0.4s ease;
11 transform-style: preserve-3d;
12}
13.memo-card.flipped .memo-card-inner {
14 transform: rotateY(180deg);
15}
16.memo-card-front,
17.memo-card-back {
18 position: absolute;
19 inset: 0;
20 backface-visibility: hidden;
21 border-radius: 10px;
22 display: flex;
23 align-items: center;
24 justify-content: center;
25 font-size: calc(var(--memo-size) * 0.45);
26}
27.memo-card-back {
28 transform: rotateY(180deg);
29 background: linear-gradient(135deg, #fce7f3, #fbcfe8);
30}
31.memo-card-front {
32 background: linear-gradient(135deg, #6366f1, #818cf8);
33 color: #fff;
34 font-weight: 800;
35}
关键 CSS 属性:
perspective: 600px— 3D 透视距离transform-style: preserve-3d— 子元素保留 3D 位置backface-visibility: hidden— 隐藏背面transform: rotateY(180deg)— Y 轴翻转 180°
匹配状态
配对成功的卡片添加特殊样式:
1.memo-card.matched .memo-card-back {
2 background: linear-gradient(135deg, #bbf7d0, #86efac);
3 border: 2px solid #22c55e;
4 box-shadow: 0 0 12px rgba(34, 197, 94, 0.3);
5}
6.memo-card.matched {
7 pointer-events: none;
8}
游戏逻辑
翻转控制
每次最多翻开两张卡片,使用 lock 锁防止快速点击:
1var flipped = []; // 当前翻开的卡片索引
2var lock = false; // 翻转锁定
3
4function flipCard(idx) {
5 if (lock) return; // 锁定中
6 if (flipped.length >= 2) return; // 已经翻开两张
7 if (flipped.indexOf(idx) !== -1) return; // 已经翻开
8
9 grid.children[idx].classList.add('flipped');
10 flipped.push(idx);
11
12 if (flipped.length === 2) {
13 moves++;
14 checkMatch();
15 }
16}
配对判定
对比两张翻开的卡片是否相同:
1function checkMatch() {
2 if (cards[flipped[0]] === cards[flipped[1]]) {
3 // 配对成功
4 matched++;
5 setTimeout(function() {
6 grid.children[flipped[0]].classList.add('matched');
7 grid.children[flipped[1]].classList.add('matched');
8 flipped = [];
9 if (matched === totalPairs) {
10 showWinMessage();
11 }
12 }, 300);
13 } else {
14 // 配对失败,延时翻回
15 lock = true;
16 setTimeout(function() {
17 grid.children[flipped[0]].classList.remove('flipped');
18 grid.children[flipped[1]].classList.remove('flipped');
19 flipped = [];
20 lock = false;
21 }, 800);
22 }
23}
等待 300ms 让玩家看清两张卡片后再翻回,提升用户体验。
响应式卡片尺寸
根据屏幕宽度和难度动态计算卡片大小:
1function renderBoard() {
2 var maxW = Math.min(window.innerWidth - 300, 600);
3 if (window.innerWidth <= 900) maxW = window.innerWidth - 50;
4
5 var cellSize = Math.floor(maxW / cols) - 8;
6 cellSize = Math.max(46, Math.min(cellSize, 82));
7
8 grid.style.setProperty('--memo-size', cellSize + 'px');
9 grid.style.gridTemplateColumns = 'repeat(' + cols + ', var(--memo-size))';
10}
难度切换
简单和困难双模式按钮:
1document.querySelectorAll('.memo-diff-btn').forEach(function(btn) {
2 btn.addEventListener('click', function() {
3 document.querySelectorAll('.memo-diff-btn').forEach(function(b) {
4 b.classList.remove('active');
5 });
6 btn.classList.add('active');
7 diff = btn.dataset.diff;
8 initGame();
9 });
10});
步数统计
记录玩家完成游戏所用的步数:
1var moves = 0;
2
3function updateUI() {
4 document.getElementById('amem-moves').textContent = moves;
5 document.getElementById('amem-pairs').textContent = matched + '/' + totalPairs;
6}
通关提示显示步数:
1function showWinMessage() {
2 document.getElementById('amem-status').innerHTML =
3 '<span>🎉</span><span>恭喜通关!用了 ' + moves + ' 步</span>';
4}
总结
记忆翻牌的核心在于 CSS 3D Transform 翻转动画和配对判定逻辑。backface-visibility 和 preserve-3d 的组合实现了真实的卡片翻转效果。延时翻回机制(800ms)给玩家足够的观察时间。响应式卡片尺寸确保了在不同屏幕和设备上的良好体验。
留言评论
期待你的想法评论加载中