iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
Modern Web

創意前端設計:用 Vue.js 打造 30 個互動實用功能系列 第 27

Day 27 Vue.js 動效分類實戰 (18) 整合特輯 - 技術全解析,打造精緻的卡片翻牌遊戲

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20241011/20124462vlhSzA18NM.jpg


翻牌效果深入解析,帶你揭開背後的技術秘密!

今天,我們將用 Vue.js 和 TypeScript 實現一個充滿趣味的翻牌遊戲,讓你不僅能挑戰自己的記憶力,還能學到豐富的前端技術知識。這篇文章會深入探討每一個技術細節,讓你在實作過程中真正掌握 Vue.js 和 TypeScript 的精髓。


img

設計核心概念

這次設計的核心概念是動態翻轉效果 + 卡片配對遊戲。我們通過組件化的方式,把卡片的翻轉效果、配對邏輯和遊戲狀態管理獨立實現。每張卡片都可以通過 props 接收父元件的狀態,並利用 CSS 的 3D 翻轉效果來呈現出流暢的翻牌動畫。

技術要點:

  • 深入理解 Vue.js 的組件化設計與狀態管理:掌握如何利用 refpropscomputed 高效地管理遊戲狀態。
  • 使用 TypeScript 加強類型安全,增強專案穩定性:學會如何在 Vue 組件中使用 TypeScript 確保參數的正確性和類型安全。
  • 使用 CSS 3D 翻轉製作流暢的卡片動畫效果:探索如何通過 perspectivetransform-style 創造真實的翻轉視覺效果。
  • 構建遊戲邏輯:如何處理卡片的點擊事件、配對檢查與動畫延遲:深入分析如何利用 setTimeout 和狀態管理來控制遊戲的流暢性。

卡片翻轉動畫的實現

我們先從卡片翻轉的動畫效果開始,這裡使用了一個名為 FlipCard 的子組件,每張卡片都可以通過 isFlipped 來控制是否翻轉。

子元件 FlipCard 設計

在 Vue.js 中,我們經常將可重複使用的功能拆分為獨立的組件。這樣可以提高專案的模組化程度,也便於重複使用和測試。

1. 接收 props 控制卡片狀態

<script lang="ts" setup>
import { defineProps } from 'vue';

const props = defineProps({
  isFlipped: Boolean,
});
</script>

這段程式碼使用了 defineProps 來接收來自父元件的 isFlipped 屬性。透過 TypeScript 的類型註解,確保 isFlipped 屬性只能是布林值,這樣在使用時會有更好的開發體驗和錯誤提示。

2. 使用 CSS 3D 翻轉效果

卡片的翻轉效果主要是通過 CSS 來實現的。我們在容器上應用了 perspective,這樣可以讓翻轉效果更具立體感:

<div class="cursor-pointer w-full h-full [perspective:800px]">
  <div
    class="card h-full w-full relative [transition:transform_1.5s] [transform-style:preserve-3d]"
    :class="{ '[transform:rotateY(180deg)]': props.isFlipped }"
  >
    <!-- 卡片的正面和背面 -->
  </div>
</div>
  • perspective: 800px:設置透視效果,使翻轉時具有真實的空間感。
  • transform-style: preserve-3d:保留 3D 效果,使子元素在 3D 空間中渲染。
  • transition: transform 1.5s:設置過渡效果,讓卡片在翻轉時更為平滑。

props.isFlippedtrue 時,卡片會添加 rotateY(180deg) 的樣式,實現翻轉。


https://ithelp.ithome.com.tw/upload/images/20241011/201244628xwYy3AoeM.png

父元件中的遊戲邏輯

接下來,我們來看父元件中如何管理卡片的狀態以及處理卡片配對的邏輯。

1. 生成隨機配對的卡片組

我們從一組動物表情符號中隨機選擇 12 個,並將它們各自複製一份以生成配對,然後打亂順序:

const animals = ['😺', '😸', ...];
const shuffledEmojis = [...animals].sort(() => Math.random() - 0.5);
const cardBackEmoji = shuffledEmojis[0]; // 背面的表情符號
const animalItems = animals.slice(1, 13);
const selectedAnimals = ref([...animalItems, ...animalItems]); // 生成配對卡片

這段程式碼隨機選擇了 12 種動物表情符號,並將它們各複製一份生成 24 張卡片。這樣的設計可以確保遊戲中每個表情符號都有一個配對。

2. 使用 ref 管理遊戲狀態

在 Vue.js 中,ref 可以用來管理組件的反應式狀態。以下是我們在遊戲中管理卡片狀態的方式:

const pairCards = ref<string[]>([]); // 儲存當前翻開的卡片
const pairIndexs = ref<number[]>([]); // 儲存翻開卡片的索引
const flippedStates = ref<boolean[]>(selectedAnimals.value.map(() => false)); // 追蹤每張卡片的翻開狀態

這裡,我們使用 pairCards 來儲存翻開的卡片內容,pairIndexs 來儲存翻開卡片的索引,並使用 flippedStates 來追蹤每張卡片的翻開狀態。

3. 檢查卡片配對的邏輯

const checkCard = (animal: string, index: number) => {
  if (flippedStates.value[index]) return; // 防止重複翻開已經翻轉的卡片

  pairCards.value.push(animal);
  pairIndexs.value.push(index);
  flippedStates.value[index] = true; // 翻開卡片

  if (pairCards.value.length === 2) {
    if (compareAnimals(pairCards.value[0], pairCards.value[1])) {
      // 配對成功
      pairCards.value = [];
      pairIndexs.value = [];
      console.log('match');
    } else {
      // 配對失敗後翻回卡片
      setTimeout(() => {
        flippedStates.value[pairIndexs.value[0]] = false;
        flippedStates.value[pairIndexs.value[1]] = false;
        pairCards.value = [];
        pairIndexs.value = [];
        console.log('not match');
      }, 1000); // 延遲 1 秒後翻回
    }
  }
};

這段程式碼負責檢查卡片配對的結果:

  • 防止重複翻開:通過檢查 flippedStates.value[index],確保不會再次翻開已經翻開的卡片。
  • 配對檢查:當翻開兩張卡片後,檢查它們是否匹配,如果匹配,則清空已翻開的卡片資料;如果不匹配,則使用 setTimeout 延遲 1 秒將卡片翻回去。

這樣的設計使遊戲不會過於倉促,給玩家一點時間記住卡片的位置。

4. 使用 TypeScript 增強類型安全

在整個遊戲邏輯中,我們利用 TypeScript 來強化變數和函數的類型註解,避免類型錯誤。例如:

const compareAnimals = (animal1: string, animal2: string): boolean => {
  return animal1 === animal2;
};

這樣的類型註解可以保證我們的函數在處理不同類型的變數時不會出現錯誤,從而提高遊戲的穩定性和維護性。


結語

img

這次的翻牌遊戲實作,我們用 Vue.js 和 TypeScript 創造出了一個視覺效果驚豔且充滿趣味的遊戲。
透過 Vue.js 的組件化設計、CSS 3D 翻轉效果和 TypeScript 的類型安全,我們不僅讓遊戲看起來精緻流暢,還能確保程式碼的可讀性與可維護性。

希望這篇深入的技術教學能幫助你更好地理解 Vue.js 和 TypeScript 的使用技巧,並激發你在前端開發上的創意靈感!🎮✨


上一篇
Day26 Vue.js 動效分類實戰 (17) 雙十特輯 - 超燃國慶狂歡,打造專屬於你的沈浸式煙火秀
下一篇
Day 28 Vue.js 動效分類實戰 (19) 星球特輯 - 把宇宙裝進你的網頁
系列文
創意前端設計:用 Vue.js 打造 30 個互動實用功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言