今天預計實作的項目顯示分數、顯示遊玩時間,
但實作顯示分數必須配合實作累計分數的功能,不然分數都不會變動也是尷尬😂。
儲存分數、遊玩時間的變數宣告:
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.isOpen = true;
gameScore.value += 5;
}
}
});
});
結算牌堆
加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