Day 05 引入Vue Router切換頁面

因為想留著昨天完成的撲克牌連連看,預計將不同遊戲的頁面可以做保留並切換, 所以我打算在做牌堆之前,首先應該要了解Vue3在路由頁面的實作是如何切換頁面。 引入 Vue Router 接下來步驟我是參考『直接使用npm create vue@latest指令產生預設攜帶有用Vue Router專案的檔案架構』 下去調整的,所以步驟草率請敬請見諒。 安裝依賴Vue Router npm install vue-router@4 在src底下新增兩個資料夾views和router 在views資料夾底下新增兩個頁面檔Game1View.vue和HomeView.vue src ├─App.vue ├─main.js ├─views | ├─Game1View.vue # 撲克連連看 | └─HomeView.vue # 首頁 ├─utils | ├─constants.js | └─poker-helper.js ├─router | └─index.js ├─components | ├─Card.vue | ├─FoxyHeader.vue | ├─GameBoard.vue | 略... 如果想知道是怎麼產生樹狀目錄,我是在src目錄下執行npx treer -e ./result.txt 便會 將樹狀結構寫到當前的result.txt文件中 定義路由應對應的元件,routes的部分可以有預先載入的功能 // router/index.js import { createRouter, createWebHistory } from 'vue-router' import HomeView from '../views/HomeView.vue' const router = createRouter({ history: createWebHistory(import....

September 14, 2023 · 2 min · 宗嘉

Day 04 調整翻牌效果&實作洗牌&外加撲克牌連連看

改變翻牌效果 研究Transition的文件後發現跟我想像的動畫變換不同,官方用法<Transition></Transition> 包裹內的新舊元件其中一個在動畫過程會先被移除掉或新增,但我先前設計好的CSS會是兩個元素都存在只是一個會被轉到CSS效果轉到背後,因此我的水平翻轉動畫需要兩個元素都存在HTML上。 為了在時間內完成,我打消原本水平翻轉的作法,我改採Transition結合v-if的方式去顯示卡牌正反兩面, 發現用漸進式出現消失也是不錯的效果,以下是樣板的改變: // Card.vue <template> <div class="card " @click="emit('poker-flip', value)"> <Transition name="card-flip"> <div v-if="isOpen" class="card-front" :class="numberClass">{{ content }}</div> <div v-else class="card-back"></div> </Transition> </div> </template> 參考Vue官方的範例, 在style添加以下後綴是-enter-active/leave-active/-enter-from/-leave-to的class,是為了讓Transition知道動畫要如何改變。 // Card.vue <style scoped> .card-flip-enter-active, .card-flip-leave-active { transition: all 0.5s ease-out; } .card-flip-enter-from, .card-flip-leave-to { opacity: 0; } {/* 略 */} 實作洗牌 實作兩個函數存於utils/poker-helper.js 洗牌的函數shuffle,洗牌採用的演算法參考看別人文章實作 Fisher-Yates 演算法,雖然洗牌用其他方法也可以,但看參考的文章說這個時間複雜度最低。 function shuffle(deck) { let length = deck.length; for (let i = 0; i < length; i++) { let rand_to_swap = Math....

September 13, 2023 · 1 min · 宗嘉

Day 03 完成卡牌自動翻面的效果,但還不完整

原本今天預計製作發牌和卡牌自動翻面的效果,希望兩個都能有動畫效果, 但現實的能力讓我想先說說今天的開發方式 實際思考/開發的過程 卡牌翻面 想像的實作過程 沿用原本的Card.vue內的樣板,在裡面分成兩個div區塊, 一個div區塊放正面有花色數字的牌面,另一個則放一張背圖。 在Card.vue內撰寫 @click 去改變卡片的狀態 撰寫CSS的動畫去實現翻面的過程 現實開發 先調整撲克牌背面的樣板,花了些時間讓圖片不會超出卡牌寬高 background-size: cover; 上網查詢是怎麼做翻轉撲克的效果,甚至查到有人做出6個div欄位做出3D方塊,但嘗試改成只有前後的div欄位但發現景深會產生兩張卡片交疊的一點位移就放棄這個寫法 意外查到IT邦上有個純CSS挑戰撲克翻轉,所以就先照著原作的CSS翻轉寫法調整Card.vue樣板 並且添加@click 會觸發emit將點到的卡牌數字回傳至上層進行更新 // Card.vue <template> <div class="card " @click="emit('poker-flip', value)" :class="backCardClass"> <div class="card-front" :class="numberClass">{{ content }}</div> <div class="card-back"></div> </div> </template> 因為我Vue3是採用SFC(Single-File Components)的寫法,所以定義emit的方式如下所示: // Card.vue const emit = defineEmits(["poker-flip"]); 在上層的元件要接會使用剛剛定義在defineEmits的名稱 @poker-flip // GameBoard.vue 其他都略 <Card v-for="card in boardCards" key="card.value" :value="card.value" :isOpen="card.isOpen" @poker-flip="toggleFlip" /> 可能因為練習過ReactJS官網的的關係,知道狀態提升(Lifting State Up)的概念,所以目前所有卡牌資料依然是先放在上層的GameBoard.vue裡面,toggleFlip是我撰寫 // GameBoard.vue function toggleFlip(num) { // 找到對應的開牌狀態且翻轉 const targetIdx = boardCards....

September 12, 2023 · 1 min · 宗嘉

Day 02 調整css調整桌面&產生52張紙牌

動工前的準備 因為昨天標題在畫面縮放的情況下會擋住放卡牌的地方,所以早上就先看CSS相關的網站學習並且如何在Vue專案中使用。 意外發現原來App.vue檔(放置卡牌區的元件)在<style scoped></style>定義的class雖然會套用到App.vue的<template>的元件中,但卻不影響App.vue內引入的GameBoard.vue<template>內使用相同class名稱的元素 修正重疊問題 關於排版的部分身為前端菜雞,就現學現賣使用將元件內部flex-wrap: wrap將包裹標題和卡牌區的main元素進行調整,如下所示: main { display: flex; flex-wrap: wrap; } 另外並且避免標題的狐狸圖太大,直接對包裹狐狸圖的header元素進行以下的配置, 採用 overflow: hidden; 這可以避免header內的元素超出限制範圍的部分進行隱藏。 header { padding: 1rem; display: flex; align-items: center; width: fit-content; max-height: 100px; text-align: center; overflow: hidden; } 顯示卡牌在牌桌 處理完之後想到今天好像約定要怎麼將卡牌一張張顯示在畫面,但腦袋不知道為什麼想到製作卡牌花色, 所以就使用線上工具vectr製作卡牌花色分別製作成svg檔案 https://vectr.com/design/editor/1dd3ff02-4dc1-4de6-84bb-17b9446450b8 因為我昨天刻的桌子似乎不太適合顯示一堆卡牌, 馬上詢問ChatGPT『能用HTML和CSS做出撲克牌桌的樣子嗎?』 複製得到的回應(HTML和CSS)渲染在瀏覽器上看看,發現它的作法花色其實是用字元表示。 我就放棄顯示svg在div元素上的想法,還有渲染出來的牌桌顏色、卡牌的外框也都採用ChatGPT的作法。 卡牌元件 每一張卡元件都會攜帶的資訊包含一個數字,使用0~51依序去表示梅花A至黑桃K。 另外使用布林值表示當前狀態是開牌/蓋牌,如下所示: // Card.vue const props = defineProps({ value: Number, isOpen: Boolean }); 另外也學到如果要在<script setup>中拿取屬性資料 defineProps() 需要先存在自訂義的變數,不能像 <template> 那麼自由直接取值 ,原本還想說怎麼白畫面且開發人員工具一直報Error跟我說『value is not defined』 // Card.vue const pokerValue = props....

September 11, 2023 · 1 min · 宗嘉

Day 01 開發遊戲前先設定目標策略

前言 最終目標是做一個個人版的紙牌接龍,中途也會嘗試做一些延伸的紙牌遊戲。 遊戲的畫面預計會使用我不熟悉的前端框架 Vue3,若有充足的時間我也會結合後端去做整合, 此次參賽也是為了督促自己在前端的技術進步。 原本是想單純參加自我挑戰組, 因為曾在2014參賽第9天就中斷,所以接下來想先在Day 1設定一些目標讓自己可以達成, 過了9年後的我可不想在同個地方掛彩。 中短期目標 目前預計想完成的目標如下: 前期目標 可以玩牌的畫面 產生紙牌 拖曳紙牌 洗牌 中期目標 紙牌動畫移動 紙牌翻轉 使用前面的技術實現心臟病遊戲 後期目標 紙牌接龍 今日目標-建好專案 建立Vue3專案並啟動成功 npm create vue@latest cd ithelp-pokergame && npm run dev 2. 在新專案中建好git repo git init git commit -am 'initial' 在Github建好一個新的儲存庫 ithelp-pokergame 將本地的git庫跟Github的庫連上對應 git remote add origin https://github.com/kabuto412rock/ithelp-pokergame.git 決定聽從Github老大的main分支選擇,後來又比較奇怪的方式推上Github的Repo過程 # 先在本地建一個main分支 git checkout -b main # 砍了本地原始master分支 git branch -D master # 嘗試拖拉儲存庫 git pull # 設定本地main和遠端main分支對應 git branch --set-upstream-to=origin/main main # 乾脆直接把本地分支全部強推上遠端 git push -f 自己使用平板畫了一隻小狐狸,也替換到了畫面上,但畫面徹底跑版… 照理來說狐狸圖應該要上下對齊才對!...

September 10, 2023 · 1 min · 宗嘉