Day 17
主題:JS DOM 操作 — 建立卡片生成與翻牌事件
今日目標
前幾天完成了介面、切版、配色以及基本動畫,現在正式進入遊戲邏輯的實作。今天的重點是使用 JavaScript 操作 DOM,讓遊戲能夠:
學習與操作重點
DOM 生成元素
使用 document.createElement
動態建立卡片。
將卡片加入遊戲區塊(appendChild
)。
為卡片設計 front(背面符號)與 back(正面符號)兩層。
事件監聽
使用 addEventListener("click", ...)
監聽卡片的翻牌行為。
透過切換 CSS class(如 flip
)來觸發翻牌動畫。
遊戲互動邏輯雛形
記錄已翻開的兩張卡片。
如果兩張相同 → 保持翻開狀態。
如果不同 → 等待一小段時間後再翻回去。
避免短時間內快速點擊導致 bug,需要 lockBoard
(鎖定狀態)。
程式範例
以下是一個簡單的翻牌遊戲雛形,今天的目標就是讓「卡片能生成+翻轉+簡單比對」。
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<title>翻牌遊戲 Day 17</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: #fef6e4;
}
.game-board {
display: grid;
grid-template-columns: repeat(4, 100px);
grid-gap: 10px;
}
.card {
width: 100px;
height: 140px;
perspective: 1000px;
cursor: pointer;
}
.card-inner {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.6s;
}
.card.flip .card-inner {
transform: rotateY(180deg);
}
.front, .back {
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 28px;
font-weight: bold;
border-radius: 10px;
backface-visibility: hidden;
}
.front {
background: #8ecae6;
color: white;
}
.back {
background: #ffb703;
color: black;
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div class="game-board" id="gameBoard"></div>
<script>
// 1. 卡片資料(6 對 = 12 張卡片)
const symbols = ["🍎", "🍌", "🍇", "🍓", "🍍", "🥝"];
let cards = [...symbols, ...symbols]; // 複製形成配對
// 2. 打亂陣列
cards.sort(() => Math.random() - 0.5);
const board = document.getElementById("gameBoard");
let flippedCards = [];
let lockBoard = false;
// 3. 建立卡片
cards.forEach(symbol => {
const card = document.createElement("div");
card.classList.add("card");
card.innerHTML = `
<div class="card-inner">
<div class="front">?</div>
<div class="back">${symbol}</div>
</div>
`;
// 點擊事件
card.addEventListener("click", () => {
if (lockBoard || card.classList.contains("flip")) return;
card.classList.add("flip");
flippedCards.push(card);
if (flippedCards.length === 2) {
checkMatch();
}
});
board.appendChild(card);
});
// 4. 檢查配對
function checkMatch() {
lockBoard = true;
const [card1, card2] = flippedCards;
const symbol1 = card1.querySelector(".back").textContent;
const symbol2 = card2.querySelector(".back").textContent;
if (symbol1 === symbol2) {
flippedCards = [];
lockBoard = false;
} else {
setTimeout(() => {
card1.classList.remove("flip");
card2.classList.remove("flip");
flippedCards = [];
lockBoard = false;
}, 1000);
}
}
</script>
</body>
</html>
今日成果
學會如何用 JS 生成卡片,讓遊戲不需要手動寫死。
完成翻牌事件,點擊即可觸發動畫。
加入比對邏輯,讓遊戲開始具備基本的「玩法」。
雖然目前還沒有計分、回合數、勝利判定,但今天的完成度已經讓遊戲進入 可以玩的雛形!後續只要加上更多功能,就能逐漸變成一個完整的小遊戲。