終於~ 來到鐵人賽的最後一天啦
今天的工作就是把小專題剩下的功能給完成,為這次的鐵人賽歡呼~ 完賽啦!!!
<div class="card" @click="transCard(card)" v-for="card in remderCards" :key="card.id">
<div class="front" :class="{transfront: card.ispair}" :style="{color: card.cardColor}">
{{ card.cardText }}
</div>
<div class="back" :class="{transback: card.ispair}"></div>
</div>
@click
時,將點到的該卡牌 ispair
設定為 true
,產生翻牌效果(觸發綁定的 calss)
function transCard(item){
item.ispair = true;
}
宣告一個變數存放要配對的第一張牌
const tempCard = ref({});
改寫,當點選卡牌時,除了要做翻牌的動作,還需要判斷是否配對成功
function transCard(item){
item.ispair = true;
if (Object.keys(tempCard.value).length === 0){
// 紀錄要配對的第一張牌
tempCard.value = item;
}else{
// 判斷是否配對成功
// 配對成功
if(item.cardText === tempCard.value.cardText) {
console.log("配對成功")
}else{
console.log("配對失敗")
}
}
}
繼續,把判斷配對寫成一個 function,搭配延遲達到兩張都翻開後再判斷的效果
如果配對成功,我們必需清除暫存的第一張牌,讓我們可以繼續翻下一組的配對
如果配對失敗,則將兩張卡牌恢復覆蓋狀態,同時清除暫存的卡牌,開始新的一組配對
function transCard(item){
item.ispair = true;
if (Object.keys(tempCard.value).length === 0){
// 紀錄要配對的第一張牌
tempCard.value = item;
}else{
// 達到兩張都翻開後在判斷的效果
setTimeout(()=>{
checkPair(item)
},1000);
}
}
function checkPair(item){
// 判斷是否配對成功
if(item.cardText === tempCard.value.cardText) {
// 配對成功 >> 清除暫存的第一張牌
tempCard.value = {};
}else{
// 配對失敗 >> 兩張卡牌恢復覆蓋狀態
item.ispair = false;
resetPrevCard();
}
}
function resetPrevCard(){
// 第一張牌恢復覆蓋狀態
cardlist.value.forEach(ele=>{
if(ele.id === tempCard.value.id){
ele.ispair = false;
}
})
// 清除第一張牌的暫存
tempCard.value = {};
}
這樣應該算是完成了瑕疵品了 XDD, 下面繼續修改
為了預防點擊過快,還沒判斷完是否配對就可以翻開第三張牌
所以我們需要加上控制器,等待結果出爐才能繼續動作
並且為預防連續點擊到同一張而造成判斷錯誤,需要再加上判斷條件(這個測試超久的~才發現原來是這麼回事 )
// 控制是否可以繼續翻牌
const canChoose = ref(true);
// 卡片翻面控制
function transCard(item){
if(canChoose.value === false) return;
item.ispair = true;
if (Object.keys(tempCard.value).length === 0){
// 紀錄要配對的第一張牌
tempCard.value = item;
}else{
// 如果點擊速度太快點到同一張返回
if(item.id === tempCard.value.id) return;
// 禁止繼續翻牌
canChoose.value = false;
// 達到兩張都翻開後在判斷的效果
setTimeout(()=>{
checkPair(item)
},1000);
}
}
function checkPair(item){
// 判斷是否配對成功
if(item.cardText === tempCard.value.cardText) {
// 配對成功
setTimeout(()=>{
// 清除暫存的第一張牌
tempCard.value = {};
// 允許繼續翻牌
canChoose.value = true;
},1000);
}else{
// 配對失敗 >> 兩張卡牌恢復覆蓋狀態
item.ispair = false;
resetPrevCard();
}
}
function resetPrevCard(){
// 第一張牌恢復覆蓋狀態
cardlist.value.forEach(ele=>{
if(ele.id === tempCard.value.id){
ele.ispair = false;
// 清除第一張牌的暫存
tempCard.value = {};
// 允許繼續翻牌
setTimeout(()=>{
canChoose.value = true;
},1000);
}
})
}
原本沒去注意到這點,後來才發現
所以必需要阻擋當點擊卡牌時,要先判斷是否已經是配對過的牌(利用 item.ispair === true)
function transCard(item){
// 如果還不能翻牌或是該點選的牌已經被翻開了
if(canChoose.value === false || item.ispair === true) return;
.......
這邊運用簡單的計數器做控制,當達成八組的配對,重新打亂順序並把一些變數還原成預設值
所以當配對成功時,計數器做 +1 的動作,使用監聽器監聽當計數器等於八,跳出按鈕可以重新一局
.....
// 監聽是否全部配對成功
const count = ref(0);
watch(count,(newValue)=>{
if(newValue === 8){
alert("恭喜挑戰遊戲成功!!!")
}
})
// 重新一局遊戲
function restartGame(){
// 計數器歸零
count.value = 0;
// 清除第一張牌的暫存
tempCard.value = {};
// 重新寫入隨機順序
randomIdx();
assignIdx();
// 還原蓋牌狀態
cardlist.value.forEach(ele=>{
ele.ispair = false;
})
}
return {
transCard,
remderCards,
count,
restartGame
}
哈哈,如果被打開開發者工具
那麼會被看到卡牌花色,所以必需先隱藏掉~ 加上 v-if
<div class="front" :class="{transfront: card.ispair}" :style="{color: card.cardColor}">
<!-- -->
<span v-if="card.ispair">{{ card.cardText }}</span>
</div>
所以只有點擊卡牌作翻牌動作時,才可以顯示
那麼我們就完成了~
很高興自己堅持完30天,終於完賽~
想想還有點不可思議,一開始真的覺得很難,也很怕寫不出來
但是~ 撐過來了~
趁著這30天的鐵人賽文章,剛好讓自己複習 Vue 框架的一些寫法或者一些平時不會去注意的
也很開心在貼人賽開始之前有跟到一波六角學院的 Vue3 夏令營的公開免費活動
讓我跟著前進到 Vue3 ,不然自己可能毫無該怎麼前進到 Vue3 概念(哈哈~
那麼也感謝各位讀者的支持
也恭喜有跟著實作小專題的讀者
現在有了兩個小作品啦~ (應該算作品啦~ XD)
旅遊小幫手
➢ open api 串接
➢ vue 的入門實作
網頁翻牌小遊戲
➢ vue3 的入門實作
javascript如何判斷Object是空物件 | IT人 wdapp