🎮ArcadeLab

新闻热词快速配对

by LunarPanda37
369 lines14.8 KB
▶ Play
<!DOCTYPE html><html lang="zh-CN"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
    <title>新闻热词快速配对</title>
    
    <link href="https://lsbtta-fz-cdn.laoshibang.com/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://lsbtta-fz-cdn.laoshibang.com/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    
    <link href="https://lsbtta-fz-cdn.laoshibang.com/npm/fontawesome-free-7.1.0-web/css/all.min.css" rel="stylesheet">
    <script src="https://lsbtta-fz-cdn.laoshibang.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
    <script src="https://lsbtta-fz-cdn.laoshibang.com/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js"></script>
    
    <style>
        .pt-safe-top { padding-top: env(safe-area-inset-top, 0px); }
        .pb-safe-bottom { padding-bottom: env(safe-area-inset-bottom, 0px); }
        
        .vocab-card {
            cursor: pointer;
            transition: all 0.3s ease;
            min-height: 90px;
            display: flex;
            align-items: center;
            justify-content: center;
            border: 2px solid #dee2e6;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        
        .vocab-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(0,0,0,0.2);
        }
        
        .vocab-card.selected {
            border-color: #fbbf24;
            box-shadow: 0 0 20px rgba(251, 191, 36, 0.6);
            transform: scale(1.05);
        }
        
        .vocab-card.matched {
            background: linear-gradient(135deg, #10b981 0%, #059669 100%);
            border-color: #10b981;
            opacity: 0.7;
            pointer-events: none;
        }
        
        .vocab-card.wrong {
            animation: shake 0.5s;
        }
        
        @keyframes shake {
            0%, 100% { transform: translateX(0); }
            25% { transform: translateX(-10px); }
            75% { transform: translateX(10px); }
        }
        
        .timer-box {
            background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
            color: white;
            padding: 15px 25px;
            border-radius: 15px;
            font-size: 1.8rem;
            font-weight: bold;
            box-shadow: 0 4px 15px rgba(245, 158, 11, 0.3);
        }
        
        .score-box {
            background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
            color: white;
            padding: 15px 25px;
            border-radius: 15px;
            font-size: 1.8rem;
            font-weight: bold;
            box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3);
        }
    </style>
<link rel="stylesheet" href="https://lsbtta-cdn.laoshibang.com/aiteacher/h5/tailwind-826c52fb_1773146410863.css"></head>
<body class="bg-light pt-safe-top pb-safe-bottom" style="touch-action: manipulation; user-select: none;"><span style="font-size: 14px;color: #33333359;position: absolute;bottom: 8px;left: 50%;transform: translateX(-50%);">内容由AI生成</span>

    <nav class="navbar navbar-light bg-white shadow-sm mb-4">
        <div class="container-fluid">
            <span class="navbar-brand mb-0 h1 text-lg">
                <i class="fas fa-newspaper text-indigo-600"></i>
                新闻热词快速配对
            </span>
            <button class="btn btn-outline-primary btn-sm" onclick="resetGame()">
                <i class="fas fa-redo"></i> 重新开始
            </button>
        </div>
    </nav>

    <main class="container mb-5 pb-5">
        <div class="row g-4 mb-4">
            <div class="col-12 col-md-6">
                <div class="text-center timer-box">
                    <i class="fas fa-clock"></i> <span id="timer">120</span>秒
                </div>
            </div>
            <div class="col-12 col-md-6">
                <div class="text-center score-box">
                    <i class="fas fa-star"></i> <span id="score">0</span> / 10
                </div>
            </div>
        </div>

        <div class="card shadow-lg mb-4">
            <div class="card-body p-4">
                <div class="text-center mb-4">
                    <img src="https://lsbtta-cdn.laoshibang.com/tta/picture/019cd7c2-5f8c-7d66-b2cc-b106c00848b3.png" alt="新闻记者" class="img-fluid" style="max-height: 200px;">
                    <h4 class="text-xl font-bold mt-3 text-indigo-700">找出匹配的中英文热词</h4>
                    <p class="text-lg text-gray-600">点击两张卡片进行配对,找出所有匹配项!</p>
                </div>
                
                <div id="gameArea" class="row g-3"></div>
            </div>
        </div>

        <div class="card shadow-lg bg-gradient-to-r from-blue-50 to-indigo-50">
            <div class="card-body">
                <h5 class="text-xl font-bold text-indigo-700 mb-3">
                    <i class="fas fa-lightbulb"></i> 游戏提示
                </h5>
                <ul class="text-lg text-gray-700 mb-0">
                    <li>每次点击两张卡片进行配对</li>
                    <li>配对正确得10分,卡片变绿色</li>
                    <li>配对错误卡片会震动提示</li>
                    <li>在120秒内完成所有配对</li>
                </ul>
            </div>
        </div>
    </main>

    <div class="modal fade" id="resultModal" tabindex="-1">
        <div class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header bg-gradient-to-r from-indigo-500 to-purple-600 text-white">
                    <h5 class="modal-title text-2xl font-bold">
                        <i class="fas fa-trophy"></i> 游戏结束
                    </h5>
                    <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body text-center p-5">
                    <img id="resultImage" src="https://lsbtta-cdn.laoshibang.com/tta/picture/019cd7c2-5f8d-7087-a83f-7420b81f9312.png" alt="成就" class="img-fluid mb-4" style="max-height: 150px;">
                    <h3 id="resultTitle" class="text-3xl font-bold mb-3"></h3>
                    <p class="text-xl mb-3">最终得分: <span id="finalScore" class="text-4xl font-bold text-indigo-600">0</span> / 10</p>
                    <p class="text-xl">用时: <span id="finalTime" class="text-2xl font-bold text-orange-600">0</span> 秒</p>
                </div>
                <div class="modal-footer justify-content-center">
                    <button type="button" class="btn btn-primary btn-lg px-5" onclick="resetGame()" data-bs-dismiss="modal">
                        <i class="fas fa-redo"></i> 再玩一次
                    </button>
                </div>
            </div>
        </div>
    </div>

    <script>function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
var vocabPairs = [{
  en: 'trending topics',
  cn: '热门话题'
}, {
  en: 'carbon neutrality',
  cn: '碳中和'
}, {
  en: 'digital economy',
  cn: '数字经济'
}, {
  en: 'sustainable development',
  cn: '可持续发展'
}, {
  en: 'artificial intelligence',
  cn: '人工智能'
}, {
  en: 'renewable energy',
  cn: '可再生能源'
}, {
  en: 'climate change',
  cn: '气候变化'
}, {
  en: 'global cooperation',
  cn: '全球合作'
}, {
  en: 'economic recovery',
  cn: '经济复苏'
}, {
  en: 'technological innovation',
  cn: '技术创新'
}];
var cards = [];
var selectedCards = [];
var matchedPairs = 0;
var score = 0;
var timeLeft = 120;
var timerInterval;
var startTime;
function shuffleArray(array) {
  var newArray = _toConsumableArray(array);
  for (var i = newArray.length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var _ref = [newArray[j], newArray[i]];
    newArray[i] = _ref[0];
    newArray[j] = _ref[1];
  }
  return newArray;
}
function initGame() {
  var gameArea = document.getElementById('gameArea');
  if (!gameArea) return;
  gameArea.innerHTML = '';
  cards = [];
  selectedCards = [];
  matchedPairs = 0;
  score = 0;
  timeLeft = 120;
  startTime = Date.now();
  document.getElementById('score').textContent = '0';
  document.getElementById('timer').textContent = '120';
  vocabPairs.forEach(function (pair, index) {
    cards.push({
      id: index * 2,
      text: pair.en,
      pairId: index,
      type: 'en'
    });
    cards.push({
      id: index * 2 + 1,
      text: pair.cn,
      pairId: index,
      type: 'cn'
    });
  });
  cards = shuffleArray(cards);
  cards.forEach(function (card) {
    var col = document.createElement('div');
    col.className = 'col-6 col-md-4 col-lg-3';
    var cardDiv = document.createElement('div');
    cardDiv.className = 'vocab-card rounded-3 shadow';
    cardDiv.dataset.id = card.id;
    cardDiv.dataset.pairId = card.pairId;
    cardDiv.innerHTML = "<span class=\"text-center px-2 font-semibold\" style=\"font-size: 1rem;\">".concat(card.text, "</span>");
    cardDiv.addEventListener('click', function () {
      return selectCard(cardDiv, card);
    });
    col.appendChild(cardDiv);
    gameArea.appendChild(col);
  });
  startTimer();
}
function selectCard(cardElement, card) {
  if (cardElement.classList.contains('matched') || cardElement.classList.contains('selected') || selectedCards.length >= 2) {
    return;
  }
  cardElement.classList.add('selected');
  selectedCards.push({
    element: cardElement,
    card: card
  });
  anime({
    targets: cardElement,
    scale: [1, 1.1, 1.05],
    duration: 300,
    easing: 'easeOutElastic(1, .5)'
  });
  if (selectedCards.length === 2) {
    checkMatch();
  }
}
function checkMatch() {
  var _selectedCards = selectedCards,
    _selectedCards2 = _slicedToArray(_selectedCards, 2),
    first = _selectedCards2[0],
    second = _selectedCards2[1];
  setTimeout(function () {
    if (first.card.pairId === second.card.pairId) {
      first.element.classList.remove('selected');
      second.element.classList.remove('selected');
      first.element.classList.add('matched');
      second.element.classList.add('matched');
      matchedPairs++;
      score++;
      var scoreElement = document.getElementById('score');
      if (scoreElement) {
        scoreElement.textContent = score;
      }
      anime({
        targets: [first.element, second.element],
        scale: [1, 1.2, 0.95],
        duration: 500,
        easing: 'easeOutElastic(1, .8)'
      });
      confetti({
        particleCount: 50,
        spread: 60,
        origin: {
          y: 0.6
        }
      });
      if (matchedPairs === vocabPairs.length) {
        setTimeout(function () {
          return endGame(true);
        }, 500);
      }
    } else {
      first.element.classList.add('wrong');
      second.element.classList.add('wrong');
      setTimeout(function () {
        first.element.classList.remove('selected', 'wrong');
        second.element.classList.remove('selected', 'wrong');
      }, 600);
    }
    selectedCards = [];
  }, 600);
}
function startTimer() {
  if (timerInterval) clearInterval(timerInterval);
  timerInterval = setInterval(function () {
    timeLeft--;
    var timerElement = document.getElementById('timer');
    if (timerElement) {
      timerElement.textContent = timeLeft;
    }
    if (timeLeft <= 0) {
      endGame(false);
    }
  }, 1000);
}
function endGame(success) {
  if (timerInterval) clearInterval(timerInterval);
  var elapsedTime = Math.floor((Date.now() - startTime) / 1000);
  var finalScoreElement = document.getElementById('finalScore');
  var finalTimeElement = document.getElementById('finalTime');
  var resultTitleElement = document.getElementById('resultTitle');
  if (finalScoreElement) finalScoreElement.textContent = score;
  if (finalTimeElement) finalTimeElement.textContent = elapsedTime;
  if (resultTitleElement) {
    if (success) {
      resultTitleElement.textContent = '恭喜完成!';
      resultTitleElement.className = 'text-3xl font-bold mb-3 text-green-600';
      confetti({
        particleCount: 100,
        spread: 70,
        origin: {
          y: 0.6
        }
      });
    } else {
      resultTitleElement.textContent = '时间到!';
      resultTitleElement.className = 'text-3xl font-bold mb-3 text-orange-600';
    }
  }
  var resultModal = new bootstrap.Modal(document.getElementById('resultModal'));
  resultModal.show();
}
function resetGame() {
  if (timerInterval) clearInterval(timerInterval);
  initGame();
}
window.addEventListener('load', initGame);</script>

</body></html>

Game Source: 新闻热词快速配对

Creator: LunarPanda37

Libraries: none

Complexity: complex (369 lines, 14.8 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-lunarpanda37" to link back to the original. Then publish at arcadelab.ai/publish.