新闻热词快速配对
by LunarPanda37369 lines14.8 KB
<!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.