Day25 紙牌接龍-結算畫面採用Modal和修正移牌優先權

前言 今天會調整結算畫面的顯示、修正連點移牌的優先權錯誤(應該最優先移入結算牌堆而非七牌堆)。 結算畫面調整 安裝套件 bootstrap-vue-next 昨日完成的結算畫面是跳出來的瀏覽器訊息,畫面完全看各家的瀏覽器制式化只能點確認,即使擋住原本的遊戲畫面是我想要的效果,但更想要的是可客製化頁面的互動視窗Modal。 雖然可以自己土炮撰寫Modal但看帳號名字就知道我很懶,我打算撿現成的套件看能不能快速客製化介面…然後就找到bootstrap-vue-next這個套件,聽名字就知道是針對Vue3特別拉出來的實現。 先照著官方文件安裝依賴: npm i bootstrap bootstrap-vue-next npm i unplugin-vue-components -D 這個 unplugin-vue-components 主要是方便自動載入有副作用(side effect)的功能到你的元件中,詳細可參考官方說明,畢竟Bootstrap有副作用才方便?! 接著調整vite.config.js的內容,主要是在plugins屬性對應的陣列中添加Components 包裹 BootstrapVueNextResolver的依賴: // vite.config.js import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import Components from 'unplugin-vue-components/vite' import {BootstrapVueNextResolver} from 'unplugin-vue-components/resolvers' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), Components({ resolvers: [BootstrapVueNextResolver()], }), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import....

October 4, 2023 · 1 min · 宗嘉

Day24 紙牌接龍-結算畫面

前言 目前實作的紙牌接龍還沒有結算畫面,所以今天就來做! 初步思考 製作結算畫面本身不是問題,畢竟畫面沒有要做得超級漂亮的情況下都是沒問題的! 問題是何時跳出結算畫面? 我想到的情形有兩種: 結算牌堆四堆都集完13張的情況 畫面中7牌堆的牌全部已經打開的情況 我認為第一種判斷結算牌堆的方式實作起來比較簡單,接下來實作也會朝這個方向前進。 實作邏輯 製作檢查完成牌組的函數 宣告一個函數checkSolitaireGameDone負責檢查紙牌接龍是否完成。 依序檢查各結算牌堆,若數量不為13就直接回傳 否false 最後就回傳 是true 程式碼如下: /** * 檢查紙牌接龍是否完成 * @param {CardStacks} cardStacks */ function checkSolitaireGameDone(cardStacks) { for (let i = 0; i < FOUR_SUITS.length; i++) { if (cardStacks[FOUR_SUITS[i]].length !== 13) return false; } return true; } 監控觸發檢查 不意外的又使用到watch這個關鍵字做監控,這部分就是跟Day4的連連看一樣, 當 牌堆cardStacks 發生變化就去觸發檢查,判定完成就使用alert跳出結算訊息。 使用者點擊alert()之後,才會執行重設遊戲的函數resetGame() // DragDemo.vue watch(cardStacks, (newCardStacks) => { const isDone = checkSolitaireGameDone(newCardStacks); if (isDone) { alert(`遊戲結束,花費時間: ${gameTime.value} 秒 總分數: ${gameScore....

October 3, 2023 · 1 min · 宗嘉

Day23 連點2下自動移牌

前言 今天要實做的是點擊自動移牌的功能也算是昨天提示的延伸,差別只在會實際移動卡牌。 我打算連點移牌功能只做在七牌堆和發牌區,結算牌堆就不提供此功能。 實作過程 處理連點事件 調整發牌區/七牌堆的卡片元件<Card>添加對應的屬性@dblclick="emit('card-click', element)", 這會讓卡牌元件<Card>被連點兩下(Double Click)時,向父元件發送事件card-click然後攜帶的參數element則是Card物件 // Card { value: 0, // 卡牌對應數值,Ex: 梅花A isOpen: false, // 是否已開牌 } 然後修改上層樣板(DragDemo.vue)的部分: 為了接收card-click事件進行處理,在發牌區的樣板修改成有添加@card-click="(card) => clickAutoMove('dealerStacks', card) 在七牌堆的樣板,這七行依序添加屬性@dblcick 第一牌堆 @dblclick="clickAutoMove('first', element)" 第二牌堆 @dblclick="clickAutoMove('second', element)" 中間略… 第七牌堆的屬性 @dblclick="clickAutoMove('seventh', element)" 處理自動移動的邏輯 這邊出現的新函數clickAutoMove(fromName, card),主要是用來處理自動移動的邏輯,流程如下: 先利用findFollowDeckName找出card可以拖曳到的牌堆名稱,然後依照優先順序排序(結算牌堆排第一)。 如果沒有找到對應的牌堆,則不執行後續。 取出第一個牌堆名稱當作目標牌堆 接著就判斷來源牌堆是發牌堆還是七牌堆,來做不同的處理(修改對應牌組陣列 還有 加分等等) 可以參考下方的程式碼片段: // DragDemo.vue /** * 自動移動 * @param {String} fromName 來自的牌堆名稱 * @param {Card} card 想移動的牌 */ function clickAutoMove(fromName, card) { const toNames = findFollowDeckName(cardStacks, card)....

October 2, 2023 · 3 min · 宗嘉

Day22 接龍移牌提示

前言 今天要實作接龍移牌提示,以下是會需要處理的題目: 怎麼取得場上牌的拖曳路線? 找到拖曳路線後,如何顯示要拖曳至哪個地方的提示(文字or動畫)? 取得拖曳路線 目前可知拖曳區塊有7牌堆、發牌區、結算牌堆,其中卡牌可拖曳的方向有: 7牌堆可以內部自拖曳或結算牌堆 發牌區只能拖曳至7牌堆、結算牌堆 結算牌堆只能拖曳至7牌堆 初步分析: 可以先計算可以移入7牌堆、結算牌堆牌尾的撲克牌 預計執行步驟: 計算出7牌堆、結算牌堆各自牌尾後能放什麼牌,儲存在Map 從發牌區/7牌堆/結算牌堆依序判斷可拖曳卡牌的數字是否存在Map中? 是,回傳比對成功的結果: { "可拖曳卡牌所在的牌堆", "拖曳卡牌在牌堆的位置", "預計移入的牌堆"} 否,繼續比對下一張直到無牌可比 實際程式碼 參數帶入要計算的全部牌堆,計算回傳每張牌可被移入的牌堆。 因為有可能出現梅花A可以移入結算牌堆或7牌堆的情況,所以實作設計成一張牌只會對應一個牌堆,此例梅花A會優先被移入結算牌堆。 // utils/poker-helper.js /** * 找出7牌堆、結算牌堆各牌尾後要接的牌 * @param {CardStacks} cardstacks * @returns {Map<Number, String>} Map<撲克牌編號, 目標牌堆名稱> */ function findTailCards(cardstacks) { const result = new Map(); // 找出可拖曳至7牌堆尾巴的牌 SEVEN_STACKS.forEach((name) => { const stack = cardstacks[name]; if (stack.length === 0) { [12, 25, 38, 51].forEach((value) => { result.set(value, name); }); return; } const lastCard = stack[stack....

October 1, 2023 · 3 min · 宗嘉

Day21 顯示接龍分數、遊戲時間

前言 今天預計實作的項目顯示分數、顯示遊玩時間, 但實作顯示分數必須配合實作累計分數的功能,不然分數都不會變動也是尷尬😂。 儲存分數、遊玩時間的變數宣告: const gameScore = ref(0); const gameTime = ref(0); const gameTimer = ref(null); 實作遊戲分數 實作分數累計規則 先整理出接龍的分數在什麼情況會增加? 從發牌區移出則加10分,因為發牌區的牌不會被重新移入所以不用擔心重複加分。 // DragDemo.vue /** 發牌區移動 */ function dealerMove(evt) { // 略 if(result){ changeOption.value = () => { // 略 gameScore.value += 10; } } } 7牌堆的牌被打開則加5分,因為被打開的牌不會被蓋回去。 原本程式就會將7牌堆最一張牌設為打開,改判斷最後一張原本是蓋牌才開牌、加5分避免分數重複累加。 // DragDemo.vue watch(cardStacks, (stacks) => { // 檢查每組牌堆最後一張 validNames.forEach(cardName => { if (stacks[cardName].length > 0) { const lastCard = stacks[cardName][stacks[cardName].length - 1]; if (!lastCard.isOpen) { lastCard....

September 29, 2023 · 2 min · 宗嘉