儿童趣味记忆配对游戏

发布于:2025-07-07 ⋅ 阅读:(21) ⋅ 点赞:(0)

儿童趣味记忆配对游戏

将设计一个适合6岁以下儿童的记忆配对游戏,包含可爱的动物图案、简单操作和丰富的视觉反馈。
在这里插入图片描述

设计思路

  • 使用明亮友好的色彩方案
  • 采用大尺寸卡片方便儿童点击
  • 添加成功动画和音效反馈
  • 实现简单的游戏进度指示
  • 添加游戏完成庆祝动画

下面是完整的实现代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>儿童记忆配对游戏</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Comic Sans MS', 'Marker Felt', '华文圆体', cursive;
        }
        
        body {
            background: linear-gradient(135deg, #6ecbf5 0%, #e4f5fc 100%);
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 20px;
            overflow-x: hidden;
        }
        
        header {
            text-align: center;
            margin: 15px 0 30px;
            width: 100%;
        }
        
        h1 {
            color: #ff6b6b;
            font-size: 2.8rem;
            text-shadow: 3px 3px 0 #ffd166;
            margin-bottom: 10px;
            letter-spacing: 1px;
        }
        
        .subtitle {
            color: #4a4a9c;
            font-size: 1.5rem;
            margin-bottom: 20px;
        }
        
        .game-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            max-width: 800px;
            width: 100%;
        }
        
        .stats {
            display: flex;
            justify-content: space-around;
            width: 100%;
            background: rgba(255, 255, 255, 0.7);
            padding: 15px;
            border-radius: 20px;
            margin-bottom: 25px;
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
        }
        
        .stat-box {
            text-align: center;
            padding: 10px 20px;
            background: #ffd166;
            border-radius: 15px;
            min-width: 120px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        }
        
        .stat-value {
            font-size: 2.2rem;
            font-weight: bold;
            color: #ef476f;
        }
        
        .stat-label {
            font-size: 1.2rem;
            color: #4a4a9c;
        }
        
        .game-board {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 15px;
            width: 100%;
            max-width: 600px;
            margin: 0 auto 30px;
            perspective: 1000px;
        }
        
        .card {
            height: 120px;
            position: relative;
            transform-style: preserve-3d;
            transition: transform 0.6s;
            cursor: pointer;
            border-radius: 20px;
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
        }
        
        .card.flipped {
            transform: rotateY(180deg);
        }
        
        .card.matched .card-front {
            background: #06d6a0;
        }
        
        .card-face {
            position: absolute;
            width: 100%;
            height: 100%;
            backface-visibility: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            border-radius: 20px;
            overflow: hidden;
        }
        
        .card-back {
            background: radial-gradient(circle, #ff6b6b, #ef476f);
            transform: rotateY(0deg);
        }
        
        .card-back::before {
            content: "?";
            font-size: 4rem;
            color: white;
            text-shadow: 3px 3px 0 rgba(0, 0, 0, 0.2);
        }
        
        .card-front {
            background: white;
            transform: rotateY(180deg);
            padding: 10px;
        }
        
        .card-front img {
            width: 80%;
            height: auto;
            max-height: 90px;
            object-fit: contain;
        }
        
        .controls {
            display: flex;
            gap: 20px;
            margin-top: 15px;
        }
        
        button {
            background: #ffd166;
            border: none;
            padding: 15px 30px;
            font-size: 1.4rem;
            border-radius: 50px;
            cursor: pointer;
            color: #4a4a9c;
            font-weight: bold;
            box-shadow: 0 6px 0 #ffb700;
            transition: all 0.2s;
            min-width: 180px;
        }
        
        button:hover {
            background: #ffd880;
            transform: translateY(2px);
            box-shadow: 0 4px 0 #ffb700;
        }
        
        button:active {
            transform: translateY(6px);
            box-shadow: none;
        }
        
        .instructions {
            background: rgba(255, 255, 255, 0.9);
            border-radius: 20px;
            padding: 20px;
            margin: 30px 0;
            width: 100%;
            max-width: 600px;
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
        }
        
        .instructions h2 {
            color: #118ab2;
            text-align: center;
            margin-bottom: 15px;
            font-size: 1.8rem;
        }
        
        .instructions ol {
            padding-left: 25px;
            font-size: 1.3rem;
            line-height: 1.6;
            color: #4a4a9c;
        }
        
        .instructions li {
            margin-bottom: 12px;
        }
        
        .celebration {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.7);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 100;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.5s;
        }
        
        .celebration.show {
            opacity: 1;
            pointer-events: all;
        }
        
        .celebration-content {
            background: white;
            padding: 40px;
            border-radius: 30px;
            text-align: center;
            max-width: 90%;
            box-shadow: 0 0 50px rgba(255, 255, 255, 0.5);
        }
        
        .celebration h2 {
            color: #ef476f;
            font-size: 3.5rem;
            margin-bottom: 20px;
        }
        
        .celebration p {
            font-size: 2rem;
            color: #4a4a9c;
            margin-bottom: 30px;
        }
        
        .confetti {
            position: absolute;
            width: 15px;
            height: 15px;
            background: #ffd166;
            animation: fall linear forwards;
        }
        
        @keyframes fall {
            to {
                transform: translateY(100vh) rotate(360deg);
            }
        }
        
        @media (max-width: 600px) {
            .game-board {
                grid-template-columns: repeat(3, 1fr);
                gap: 10px;
            }
            
            .card {
                height: 100px;
            }
            
            h1 {
                font-size: 2.2rem;
            }
            
            .subtitle {
                font-size: 1.2rem;
            }
            
            button {
                font-size: 1.2rem;
                padding: 12px 20px;
                min-width: 140px;
            }
        }
    </style>
</head>
<body>
    <header>
        <h1>动物记忆配对游戏</h1>
        <div class="subtitle">找出所有相同的动物朋友!</div>
    </header>
    
    <div class="game-container">
        <div class="stats">
            <div class="stat-box">
                <div class="stat-value" id="moves">0</div>
                <div class="stat-label">步数</div>
            </div>
            <div class="stat-box">
                <div class="stat-value" id="pairs">0</div>
                <div class="stat-label">已配对</div>
            </div>
            <div class="stat-box">
                <div class="stat-value" id="timer">0</div>
                <div class="stat-label"></div>
            </div>
        </div>
        
        <div class="game-board" id="game-board"></div>
        
        <div class="controls">
            <button id="restart-btn">重新开始</button>
            <button id="help-btn">游戏说明</button>
        </div>
    </div>
    
    <div class="instructions">
        <h2>游戏玩法</h2>
        <ol>
            <li>点击卡片,看看是什么动物</li>
            <li>再点击另一张卡片,尝试找到相同的动物</li>
            <li>如果两张卡片相同,它们会保持翻开</li>
            <li>如果两张卡片不同,它们会翻回去</li>
            <li>记住动物的位置,尽快找到所有配对!</li>
        </ol>
    </div>
    
    <div class="celebration" id="celebration">
        <div class="celebration-content">
            <h2>太棒了!</h2>
            <p>你找到了所有动物朋友!</p>
            <button id="play-again">再玩一次</button>
        </div>
    </div>
    
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // 游戏配置
            const animals = ['🐶', '🐱', '🐰', '🐻', '🐯', '🦁', '🐮', '🐷'];
            const cardValues = [...animals, ...animals];
            let flippedCards = [];
            let matchedPairs = 0;
            let moves = 0;
            let timer = 0;
            let timerInterval;
            let gameStarted = false;
            
            const gameBoard = document.getElementById('game-board');
            const movesElement = document.getElementById('moves');
            const pairsElement = document.getElementById('pairs');
            const timerElement = document.getElementById('timer');
            const restartBtn = document.getElementById('restart-btn');
            const playAgainBtn = document.getElementById('play-again');
            const celebration = document.getElementById('celebration');
            
            // 初始化游戏
            function initGame() {
                gameBoard.innerHTML = '';
                flippedCards = [];
                matchedPairs = 0;
                moves = 0;
                timer = 0;
                gameStarted = false;
                
                movesElement.textContent = moves;
                pairsElement.textContent = matchedPairs;
                timerElement.textContent = timer;
                
                clearInterval(timerInterval);
                
                // 洗牌
                const shuffledCards = [...cardValues].sort(() => Math.random() - 0.5);
                
                // 创建卡片
                shuffledCards.forEach((value, index) => {
                    const card = document.createElement('div');
                    card.classList.add('card');
                    card.dataset.value = value;
                    
                    card.innerHTML = `
                        <div class="card-face card-back"></div>
                        <div class="card-face card-front">
                            <div style="font-size: 4rem;">${value}</div>
                        </div>
                    `;
                    
                    card.addEventListener('click', flipCard);
                    gameBoard.appendChild(card);
                });
            }
            
            // 翻牌函数
            function flipCard() {
                // 如果游戏未开始,启动计时器
                if (!gameStarted) {
                    startTimer();
                    gameStarted = true;
                }
                
                // 如果已经翻开了两张牌或这张牌已经匹配,则返回
                if (flippedCards.length === 2 || 
                    this.classList.contains('flipped') || 
                    this.classList.contains('matched')) {
                    return;
                }
                
                // 翻牌
                this.classList.add('flipped');
                flippedCards.push(this);
                
                // 播放音效
                playSound('flip');
                
                // 如果翻开了两张牌,检查是否匹配
                if (flippedCards.length === 2) {
                    moves++;
                    movesElement.textContent = moves;
                    
                    const card1 = flippedCards[0];
                    const card2 = flippedCards[1];
                    
                    if (card1.dataset.value === card2.dataset.value) {
                        // 匹配成功
                        card1.classList.add('matched');
                        card2.classList.add('matched');
                        matchedPairs++;
                        pairsElement.textContent = matchedPairs;
                        
                        playSound('match');
                        
                        flippedCards = [];
                        
                        // 检查游戏是否结束
                        if (matchedPairs === animals.length) {
                            endGame();
                        }
                    } else {
                        // 匹配失败
                        setTimeout(() => {
                            card1.classList.remove('flipped');
                            card2.classList.remove('flipped');
                            flippedCards = [];
                        }, 1000);
                    }
                }
            }
            
            // 开始计时器
            function startTimer() {
                clearInterval(timerInterval);
                timerInterval = setInterval(() => {
                    timer++;
                    timerElement.textContent = timer;
                }, 1000);
            }
            
            // 结束游戏
            function endGame() {
                clearInterval(timerInterval);
                
                // 创建庆祝效果
                createConfetti();
                
                // 显示庆祝画面
                setTimeout(() => {
                    celebration.classList.add('show');
                }, 1000);
            }
            
            // 创建五彩纸屑效果
            function createConfetti() {
                const colors = ['#ff6b6b', '#ffd166', '#06d6a0', '#118ab2', '#ef476f'];
                
                for (let i = 0; i < 150; i++) {
                    const confetti = document.createElement('div');
                    confetti.classList.add('confetti');
                    
                    // 随机位置
                    const posX = Math.random() * window.innerWidth;
                    const posY = Math.random() * -100;
                    
                    // 随机大小
                    const size = Math.random() * 10 + 5;
                    
                    // 随机颜色
                    const color = colors[Math.floor(Math.random() * colors.length)];
                    
                    // 随机动画时长
                    const duration = Math.random() * 3 + 2;
                    
                    // 随机延迟
                    const delay = Math.random() * 2;
                    
                    confetti.style.left = `${posX}px`;
                    confetti.style.top = `${posY}px`;
                    confetti.style.width = `${size}px`;
                    confetti.style.height = `${size}px`;
                    confetti.style.backgroundColor = color;
                    confetti.style.animation = `fall ${duration}s linear ${delay}s forwards`;
                    
                    document.body.appendChild(confetti);
                    
                    // 动画结束后移除元素
                    setTimeout(() => {
                        confetti.remove();
                    }, (duration + delay) * 1000);
                }
                
                playSound('win');
            }
            
            // 播放音效
            function playSound(type) {
                try {
                    const audioContext = new (window.AudioContext || window.webkitAudioContext)();
                    
                    let oscillator = audioContext.createOscillator();
                    let gainNode = audioContext.createGain();
                    
                    oscillator.connect(gainNode);
                    gainNode.connect(audioContext.destination);
                    
                    // 根据不同事件设置不同音效
                    switch(type) {
                        case 'flip':
                            oscillator.type = 'sine';
                            oscillator.frequency.setValueAtTime(523.25, audioContext.currentTime); // C5
                            gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
                            break;
                        case 'match':
                            oscillator.type = 'sine';
                            oscillator.frequency.setValueAtTime(659.25, audioContext.currentTime); // E5
                            gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
                            break;
                        case 'win':
                            // 播放一个简单的胜利旋律
                            const melody = [
                                {note: 784.00, duration: 0.2}, // G5
                                {note: 880.00, duration: 0.2}, // A5
                                {note: 987.77, duration: 0.4}  // B5
                            ];
                            
                            let time = audioContext.currentTime;
                            
                            melody.forEach(tone => {
                                let oscillator = audioContext.createOscillator();
                                let gainNode = audioContext.createGain();
                                
                                oscillator.connect(gainNode);
                                gainNode.connect(audioContext.destination);
                                
                                oscillator.type = 'triangle';
                                oscillator.frequency.setValueAtTime(tone.note, time);
                                gainNode.gain.setValueAtTime(0.3, time);
                                gainNode.gain.exponentialRampToValueAtTime(0.01, time + tone.duration);
                                
                                oscillator.start(time);
                                oscillator.stop(time + tone.duration);
                                
                                time += tone.duration;
                            });
                            return;
                    }
                    
                    oscillator.start();
                    gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.3);
                    oscillator.stop(audioContext.currentTime + 0.3);
                } catch(e) {
                    console.log("音频播放失败:", e);
                }
            }
            
            // 事件监听器
            restartBtn.addEventListener('click', initGame);
            playAgainBtn.addEventListener('click', () => {
                celebration.classList.remove('show');
                initGame();
            });
            
            // 初始游戏
            initGame();
        });
    </script>
</body>
</html>

游戏特点

  1. 儿童友好设计

    • 使用明亮鲜艳的色彩和圆角设计
    • 大尺寸卡片方便儿童点击
    • 可爱的动物表情符号作为配对元素
  2. 游戏机制

    • 记忆配对核心玩法
    • 实时显示步数、配对数量和用时
    • 成功匹配的卡片会有视觉反馈
  3. 交互反馈

    • 卡片翻转动画
    • 匹配成功时的音效
    • 游戏完成时的庆祝动画和五彩纸屑效果
  4. 教育价值

    • 锻炼记忆力和观察力
    • 培养专注力和耐心
    • 学习识别不同动物
  5. 响应式设计

    • 适应不同屏幕尺寸
    • 在手机和平板上都能良好显示

这个游戏不需要任何外部依赖,可以直接在浏览器中打开运行,非常适合6岁以下儿童使用。游戏操作简单直观,界面友好,能够提供愉快的游戏体验。