iT邦幫忙

2025 iThome 鐵人賽

DAY 18
0
Modern Web

30天打造純前端互動小遊戲網站系列 第 18

Day 18 | 基礎邏輯測試

  • 分享至 

  • xImage
  •  

Day 18
主題:基礎邏輯測試 — 翻牌後能翻回、簡單配對測試

今日目標
在第 17 天,我們完成了卡片的生成以及翻牌事件,卡片可以翻開,但目前只要點擊就會翻過去,缺乏進一步的互動。今天要加入最基本的遊戲邏輯測試,讓遊戲開始有「規則」:

  1. 玩家一次只能翻兩張卡。
  2. 如果兩張卡相同 → 保持翻開。
  3. 如果不同 → 過一秒自動翻回去。
    這樣一來,遊戲就有了挑戰性,不再只是單純的翻牌動畫。

學習與操作重點

  1. 翻牌限制
    需要記錄目前翻開的卡片數量,避免玩家一次翻多張。
    使用陣列 flippedCards 暫存翻開的卡。

  2. 比對邏輯
    當翻開兩張卡片時,讀取它們的符號(或資料)。
    判斷是否一致:
    相同 → 保持翻開。
    不同 → 使用 setTimeout() 延遲後翻回。

  3. 避免暴力點擊
    在比對過程中,使用 lockBoard(鎖定)來避免快速連點造成 bug。

程式範例
以下程式碼延續第 17 天的結構,今天的差異是加上「翻回去」的邏輯:

<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="UTF-8">
  <title>Day 18 - 基礎邏輯測試</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>
    const symbols = ["🍎", "🍌", "🍇", "🍓", "🍍", "🥝"];
    let cards = [...symbols, ...symbols];
    cards.sort(() => Math.random() - 0.5);

    const board = document.getElementById("gameBoard");

    let flippedCards = [];
    let lockBoard = false;

    // 建立卡片
    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);
    });

    // 檢查配對邏輯
    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>

今日成果
完成了卡片翻牌後的「回復邏輯」,遊戲開始具備挑戰性。
確認配對的核心流程能正常運作。
玩家現在能夠進行一場「真正的配對遊戲」了!


上一篇
Day 17 | JS DOM 操作
下一篇
Day 19 | 音效 / 特效
系列文
30天打造純前端互動小遊戲網站19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言