iT邦幫忙

2023 iThome 鐵人賽

DAY 21
0

前言

今天預計實作的項目顯示分數顯示遊玩時間
但實作顯示分數必須配合實作累計分數的功能,不然分數都不會變動也是尷尬😂。

儲存分數、遊玩時間的變數宣告:

const gameScore = ref(0);
const gameTime = ref(0);
const gameTimer = ref(null);

實作遊戲分數

實作分數累計規則

先整理出接龍的分數在什麼情況會增加?

  1. 發牌區移出則加10分,因為發牌區的牌不會被重新移入所以不用擔心重複加分。
// DragDemo.vue
/** 發牌區移動 */
function dealerMove(evt) {
    // 略
    if(result){
        changeOption.value = () => {
            // 略
            gameScore.value += 10;
        }
    }
}
  1. 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.isOpen = true;
                gameScore.value += 5;
            }
        }
    });
});
  1. 卡牌移入結算牌堆加15分,移出則扣15分。
    • 移出的部分直接調整結算牌堆移動進行扣分
    /** 結算牌堆移動 */
    function finishedCardMove(evt) {
        // 略
        if (result) {
            changeOption.value = () => {
                gameScore.value -= 15;
                changeOption.value = null;
            };
        }
        return result;
    }
    
    • 移入結算牌堆則會需要調整發牌區7牌堆的移動,一樣是調整changeOption.value的程式碼要加15分。

    因為第1點的規則(10分),如果直接從發牌區拖曳至結算牌堆會加25分(15+10)

    /** 發牌區移動 */
    function dealerMove(evt) {
        // 如果目標是結算盤堆,則套用結算盤堆的規則
        const isToFinishedArea = FOUR_SUITS.includes(to);
        // 略
        if (result) {
            changeOption.value = () => {
                cardStacks.delaerStacks = cardStacks.delaerStacks.filter(card => card.value !== dealerCard.value);
                gameScore.value += 10 + (isToFinishedArea ? 15 : 0);
                changeOption.value = null;
            };
        }
        return result;
    }
     /** 7牌堆移動 */
     function limitLocalMove(evt) {
         const isToFinishedArea = FOUR_SUITS.includes(to);
         // 略
         if (result) {
             // 略
             changeOption.value = () => {
                 cardStacks[from] = newFromCards;
                 cardStacks[to] = newToCards;
                 if (isToFinishedArea) {
                     gameScore.value += 15;
                 }
                 changeOption.value = null;
             };
         }
         // 仍使用原生的拖曳效果
         return result;
     }
    
    

實作顯示樣板

這邊只是把分數、時間、重置按鈕都移動至同一區塊,部分程式碼如下:

<!-- DragDemo.vue -->
<div
    style=" display: flex; flex-wrap: wrap; flex-direction: row;justify-content: space-around; align-items: center;  background-color: antiquewhite; font-size: large;">
    <div>累計分數: {{ gameScore }}</div>
    <div>經過時間: {{ gameTime }} 秒</div>
    <button style="font-size: 1.5rem;" @click="resetGame">重置</button>
</div>

實作遊玩時間

撰寫遊戲計時的函數startTimer()

  • 變數gameTime負責儲存秒數
  • 變數gameTimer負責儲存intervalID
function startTimer() {
    if (!gameTimer.value) {
        gameTimer.value = setInterval(() => {
            gameTime.value++;
        }, 1000);
    }
}

當點擊GameBoard時則執行startTimer()的樣板:

<GameBoard style="display: flex;" @click="startTimer">

遊戲重置時,使用clearInterval(gameTimer.value)清除遊玩時間的計時器。

小結

程式碼逐漸變得複雜,但依舊完成預期的功能分數時間

明天想實作看看如何做到下一步提示

程式碼: https://github.com/kabuto412rock/ithelp-pokergame/tree/day21
Yes


上一篇
Day20 實作結算牌堆元件(四) 實作移入7牌堆的拖曳&遊戲重置
下一篇
Day22 接龍移牌提示
系列文
毫無自信的開發Web遊戲接龍-成為創造龍的英雄之路!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言