還沒有玩過的朋友,來想再玩一次的朋友,更新版本傳送門:
https://wowdacom.github.io/TimelineQuest-ithelp-sample/
修正目前答題題目標記的藍色框
以下是相關的程式碼片段:
<ul class="flex items-center">
<li
v-for="(isCorrect, index) in gameStatus.stepCorrect"
:key="index"
class="w-6 h-2.5 mr-[2px] border-2 rounded-full"
:class="
gameStatus.currentStep === index + 1
? 'border-[#5d72c9]'
: isCorrect === null
? 'bg-[#e3e0d5] border-[#e3e0d5]'
: isCorrect
? 'bg-[#5cb887] border-[#5cb887]'
: 'bg-[#d25353] border-[#d25353]'
"
/>
</ul>
之前根據 ChatGPT 的建議將卡片位置更新的邏輯獨立出一個 function updateTimelineEventsPosition,後來發現有過度優化的傾向。後來我 switch case簡化為一行的 if 判斷式,並移除 function updateTimelineEventsPosition 使整個函式閱讀起來更為直覺。
handleLineShare click
事件const saveGameStatus = () => {
if (gameStatus.currentStep > 1 && gameStatus.currentStep < 9) {
localStorage.setItem(
'gameStatus',
JSON.stringify({
...gameStatus,
clues: clues.value,
timelineEvents: timelineEvents.value,
selectedYear: selectedYear.value,
}),
);
} else {
localStorage.removeItem('gameStatus');
}
window.removeEventListener('beforeunload', saveGameStatus);
return null;
};
window.addEventListener('beforeunload', saveGameStatus);
在進入遊戲時,藉由抓取 localStorage 資料判斷是否已經玩過遊戲
const gameInit = () => {
const savedGameStatus = loadGameStatus();
if (savedGameStatus) {
isPlayed.value = true;
} else {
isPlayed.value = false;
}
};
<div v-if="isPlayed">
<div class="text-center font-extrabold m-1 text-[#5d72c9]">
<span class="">{{ selectedYear }} </span>那年出生的你,選擇要…
</div>
<div class="flex">
<button data-test="game-start-btn" class="rounded-full border w-[130px] h-[40px] bg-[#5d72c9] text-white flex justify-center items-center" @click="handleGameStart(true)">
重新開始 <i-solar-restart-square-bold class="ml-1 inline-block" />
</button>
<button data-test="game-start-btn" class="rounded-full border w-[130px] h-[40px] bg-[#5d72c9] text-white flex justify-center items-center" @click="handleGameKeep">
繼續遊戲 <i-maki-arrow class="ml-1 inline-block" />
</button>
</div>
</div>
<div v-else>
<div class="mb-2 flex">
<h1>選擇出生年份</h1>
<select v-model="selectedYear" class="text-[#5d72c9] font-extrabold">
<option v-for="year in yearOptions" :key="year" :value="year">
{{ year }}
</option>
</select>
</div>
<button data-test="game-start-btn" class="rounded-full border w-[150px] h-[40px] bg-[#5d72c9] text-white" @click="handleGameStart(false)">
開始遊戲 <i-maki-arrow class="inline-block" />
</button>
</div>
//開始(新)遊戲
const handleGameStart = (isRestart) => {
if (!isRestart) {
isShowTip.value = true;
}
isGameStart.value = true;
clues.value = [...cluesData];
timelineEvents.value = [];
timelineEvents.value.push({
year: `${selectedYear.value}`,
event: '一個孩子誕生囉!',
description: '慶祝生命的多彩多姿,每一刻都值得紀念和珍惜。',
image: 'https://i.imgur.com/xTWeFPu.jpg',
point: 0,
step: 0,
});
handleUpdateTimelinePosition(gameStatus.currentStep);
};
//繼續遊戲
const handleGameKeep = () => {
const savedGameStatus = loadGameStatus();
isGameStart.value = true;
isShowTip.value = false;
Object.assign(gameStatus, savedGameStatus);
clues.value = savedGameStatus.clues;
timelineEvents.value = savedGameStatus.timelineEvents;
selectedYear.value = savedGameStatus.selectedYear;
handleUpdateTimelinePosition(gameStatus.currentStep);
};
//重新開始
const handleGameReset = () => {
isGameEnd.value = false;
isGameStart.value = false;
Object.assign(gameStatus, JSON.parse(JSON.stringify(initialGameState)));
handleUpdateTimelinePosition(gameStatus.currentStep);
isPlayed.value = false;
localStorage.removeItem('gameStatus');
};