Spaces:
Running
Running
| document.addEventListener('DOMContentLoaded', function() { | |
| // 檢查是否有玩家資料 | |
| const currentPlayerId = localStorage.getItem('currentPlayerId'); | |
| const playerName = localStorage.getItem('playerName'); | |
| const playerProfession = localStorage.getItem('playerProfession'); | |
| // 如果沒有玩家資料,重定向到首頁 | |
| if (!currentPlayerId || !playerName || !playerProfession) { | |
| alert('請先登入遊戲!'); | |
| window.location.href = 'index.html'; | |
| return; | |
| } | |
| // 獲取DOM元素 | |
| const startChallengeBtn = document.getElementById('start-challenge'); | |
| const quizContainer = document.getElementById('quiz-container'); | |
| const resultContainer = document.getElementById('result-container'); | |
| const questionTitle = document.getElementById('question-title'); | |
| const questionText = document.getElementById('question-text'); | |
| const optionsContainer = document.getElementById('options-container'); | |
| const nextQuestionBtn = document.getElementById('next-question'); | |
| const currentQuestionSpan = document.getElementById('current-question'); | |
| const resultTitle = document.getElementById('result-title'); | |
| const resultMessage = document.getElementById('result-message'); | |
| const retryBtn = document.getElementById('retry-challenge'); | |
| const backToMapBtn = document.getElementById('back-to-map'); | |
| const rocksProgress = document.getElementById('rocks-progress').children; | |
| const bgmAudio = document.getElementById('bgm'); | |
| const correctSound = document.getElementById('correct-sound'); | |
| const wrongSound = document.getElementById('wrong-sound'); | |
| const toggleBgmBtn = document.getElementById('toggle-bgm'); | |
| const starResults = [ | |
| document.getElementById('star-1'), | |
| document.getElementById('star-2'), | |
| document.getElementById('star-3') | |
| ]; | |
| // 音樂控制 | |
| let isBgmPlaying = false; | |
| // 播放背景音樂 | |
| function playBgm() { | |
| bgmAudio.volume = 0.3; // 設置音量 | |
| bgmAudio.play().catch(e => console.log('自動播放被阻止:', e)); | |
| isBgmPlaying = true; | |
| toggleBgmBtn.textContent = '音樂關'; | |
| } | |
| // 嘗試自動播放背景音樂(大多數瀏覽器會阻止) | |
| playBgm(); | |
| // 音樂開關按鈕 | |
| toggleBgmBtn.addEventListener('click', function() { | |
| if (isBgmPlaying) { | |
| bgmAudio.pause(); | |
| isBgmPlaying = false; | |
| toggleBgmBtn.textContent = '音樂開'; | |
| localStorage.setItem('valleyMusicPlaying', 'false'); | |
| } else { | |
| bgmAudio.play(); | |
| isBgmPlaying = true; | |
| toggleBgmBtn.textContent = '音樂關'; | |
| localStorage.setItem('valleyMusicPlaying', 'true'); | |
| } | |
| }); | |
| // 問題資料 | |
| const questions = [ | |
| { | |
| question: "102² 最適合看成哪個平方的變化形式?", | |
| options: [ | |
| "(A) (100 + 2)²", | |
| "(B) (101 + 1)²", | |
| "(C) (99 + 3)²", | |
| "(D) (90 + 12)²" | |
| ], | |
| correctIndex: 0 | |
| }, | |
| { | |
| question: "204² 最適合看成哪一種轉換?", | |
| options: [ | |
| "(A) (210 - 6)²", | |
| "(B) (200 + 4)²", | |
| "(C) (199 + 5)²", | |
| "(D) (190 + 14)²" | |
| ], | |
| correctIndex: 1 | |
| }, | |
| { | |
| question: "598² 最適合看成哪一種平方形式?", | |
| options: [ | |
| "(A) (590 + 8)²", | |
| "(B) (580 + 18)²", | |
| "(C) (600 - 2)²", | |
| "(D) (599 - 1)²" | |
| ], | |
| correctIndex: 2 | |
| }, | |
| { | |
| question: "89² 最適合看成哪一種計算方式?", | |
| options: [ | |
| "(A) (80 + 9)²", | |
| "(B) (91 - 2)²", | |
| "(C) (88 + 1)²", | |
| "(D) (90 - 1)²" | |
| ], | |
| correctIndex: 3 | |
| }, | |
| { | |
| question: "51² 最適合轉換成什麼?", | |
| options: [ | |
| "(A) (49 + 2)²", | |
| "(B) (55 - 4)²", | |
| "(C) (50 + 1)²", | |
| "(D) (52 - 1)²" | |
| ], | |
| correctIndex: 2 | |
| }, | |
| { | |
| question: "297² 最適合轉換成什麼?", | |
| options: [ | |
| "(A) (290 + 7)²", | |
| "(B) (280 + 17)²", | |
| "(C) (295 + 2)²", | |
| "(D) (300 - 3)²" | |
| ], | |
| correctIndex: 3 | |
| } | |
| ]; | |
| // 遊戲狀態 | |
| let currentQuestionIndex = 0; | |
| let correctAnswers = 0; | |
| let userAnswers = []; // 記錄用戶答案 | |
| let hasAnswered = false; // 是否已回答當前問題 | |
| // 獲取遊戲進度 | |
| const gameProgress = JSON.parse(localStorage.getItem(`gameProgress_${currentPlayerId}`)) || { | |
| completedTrials: { | |
| "平方之泉": { completed: false, score: 0, challengesCompleted: [false, false, false, false, false, false] }, | |
| "變換山谷": { completed: false, score: 0, challengesCompleted: [false, false, false, false, false, false] }, | |
| "展開之塔": { completed: false, score: 0, challengesCompleted: [false, false, false, false, false, false] } | |
| }, | |
| currentLocation: "變換山谷", | |
| lastSaved: new Date().toISOString() | |
| }; | |
| // 開始挑戰按鈕點擊事件 | |
| startChallengeBtn.addEventListener('click', function() { | |
| startChallengeBtn.style.display = 'none'; | |
| quizContainer.style.display = 'block'; | |
| loadQuestion(0); | |
| }); | |
| // 載入問題 | |
| function loadQuestion(index) { | |
| hasAnswered = false; | |
| currentQuestionIndex = index; | |
| currentQuestionSpan.textContent = index + 1; | |
| questionTitle.textContent = `問題 ${index + 1}`; | |
| questionText.textContent = questions[index].question; | |
| // 清除選項的所有類別 | |
| const options = optionsContainer.children; | |
| for (let i = 0; i < options.length; i++) { | |
| options[i].className = 'option'; | |
| options[i].textContent = questions[index].options[i]; | |
| } | |
| // 隱藏下一題按鈕 | |
| nextQuestionBtn.style.display = 'none'; | |
| } | |
| // 選項點擊事件 | |
| optionsContainer.addEventListener('click', function(e) { | |
| if (!e.target.classList.contains('option') || hasAnswered) return; | |
| hasAnswered = true; | |
| const selectedOption = e.target; | |
| const selectedIndex = parseInt(selectedOption.dataset.index); | |
| const correctIndex = questions[currentQuestionIndex].correctIndex; | |
| // 記錄用戶答案 | |
| userAnswers[currentQuestionIndex] = selectedIndex === correctIndex; | |
| // 顯示正確/錯誤 | |
| if (selectedIndex === correctIndex) { | |
| selectedOption.classList.add('correct'); | |
| correctAnswers++; | |
| correctSound.play(); | |
| // 更新岩石進度 | |
| rocksProgress[currentQuestionIndex].classList.add('broken'); | |
| } else { | |
| selectedOption.classList.add('incorrect'); | |
| // 顯示正確答案 | |
| optionsContainer.children[correctIndex].classList.add('correct'); | |
| wrongSound.play(); | |
| } | |
| // 顯示下一題按鈕 | |
| nextQuestionBtn.style.display = 'block'; | |
| }); | |
| // 下一題按鈕點擊事件 | |
| nextQuestionBtn.addEventListener('click', function() { | |
| if (currentQuestionIndex < questions.length - 1) { | |
| loadQuestion(currentQuestionIndex + 1); | |
| } else { | |
| showResult(); | |
| } | |
| }); | |
| // 顯示結果 | |
| function showResult() { | |
| quizContainer.style.display = 'none'; | |
| resultContainer.style.display = 'block'; | |
| // 獲取成功和失敗按鈕容器 | |
| const successButtons = document.getElementById('success-buttons'); | |
| const failButtons = document.getElementById('fail-buttons'); | |
| // 計算得分 | |
| const score = Math.round((correctAnswers / questions.length) * 100); | |
| // 計算當前星數 | |
| let currentStars = 0; | |
| if (correctAnswers >= 6) currentStars = 3; | |
| else if (correctAnswers >= 5) currentStars = 2; | |
| else if (correctAnswers >= 4) currentStars = 1; | |
| console.log("當前答對題數:", correctAnswers, "當前星數:", currentStars); | |
| // 檢查是否已有變換山谷的紀錄及其星數 | |
| const existingTrial = gameProgress.completedTrials["變換山谷"]; | |
| const existingStars = existingTrial && existingTrial.stars ? existingTrial.stars : 0; | |
| console.log("歷史星數:", existingStars); | |
| // 根據答對題數顯示不同結果 | |
| if (correctAnswers >= 4) { | |
| gameProgress.completedTrials["變換山谷"].completed = true; | |
| gameProgress.completedTrials["變換山谷"].challengesCompleted = userAnswers; | |
| // 只有當前星數高於歷史星數時才更新 | |
| if (currentStars > existingStars) { | |
| gameProgress.completedTrials["變換山谷"].score = score; | |
| gameProgress.completedTrials["變換山谷"].stars = currentStars; | |
| } | |
| resultTitle.textContent = '試煉成功!'; | |
| resultMessage.innerHTML = ` | |
| <p>恭喜你答對了 ${correctAnswers} 題,獲得了 ${score} 分!</p> | |
| <p>成功通過試煉後,山谷之靈讚賞道:「你已經掌握了轉換的精髓,但真正的平方之力還需要最後一步——展開與融合。前往展開之塔吧,那裡的守衛會引導你完成最終試煉。」</p> | |
| `; | |
| // 顯示星星 - 顯示歷史最高星數與當前星數中的較高者 | |
| const displayStars = Math.max(currentStars, existingStars); | |
| console.log("顯示星數:", displayStars); | |
| updateStars(displayStars); | |
| // 顯示成功按鈕,隱藏失敗按鈕 | |
| successButtons.style.display = 'flex'; | |
| failButtons.style.display = 'none'; | |
| } else { | |
| gameProgress.completedTrials["變換山谷"].completed = false; | |
| gameProgress.completedTrials["變換山谷"].challengesCompleted = userAnswers; | |
| // 保留歷史星數 | |
| if (existingTrial && existingTrial.stars) { | |
| gameProgress.completedTrials["變換山谷"].stars = existingTrial.stars; | |
| } | |
| resultTitle.textContent = '試煉失敗'; | |
| resultMessage.innerHTML = ` | |
| <p>你只答對了 ${correctAnswers} 題,需要至少答對4題才能通過試煉。</p> | |
| <p>山谷之靈說道:「不要氣餒,再試一次吧!轉換的力量需要更多練習才能掌握。」</p> | |
| `; | |
| // 不顯示星星,但保留歷史星數 | |
| console.log("失敗時顯示歷史星數:", existingStars); | |
| updateStars(existingStars); | |
| // 顯示失敗按鈕,隱藏成功按鈕 | |
| successButtons.style.display = 'none'; | |
| failButtons.style.display = 'flex'; | |
| } | |
| // 保存遊戲進度 | |
| localStorage.setItem(`gameProgress_${currentPlayerId}`, JSON.stringify(gameProgress)); | |
| } | |
| // 更新星星顯示 | |
| function updateStars(correctCount) { | |
| // 根據答對題數顯示星星 | |
| // 6題全對 = 3星, 5題對 = 2星, 4題對 = 1星, 少於4題 = 0星 | |
| let earnedStars = 0; | |
| if (correctCount >= 6) earnedStars = 3; | |
| else if (correctCount >= 5) earnedStars = 2; | |
| else if (correctCount >= 4) earnedStars = 1; | |
| console.log("更新星星顯示,獲得星數:", earnedStars); | |
| // 更新星星顯示 | |
| for (let i = 0; i < starResults.length; i++) { | |
| if (i < earnedStars) { | |
| starResults[i].classList.add('earned'); | |
| } else { | |
| starResults[i].classList.remove('earned'); | |
| } | |
| } | |
| } | |
| // 重新挑戰按鈕點擊事件 | |
| retryBtn.addEventListener('click', function() { | |
| // 重置遊戲狀態 | |
| currentQuestionIndex = 0; | |
| correctAnswers = 0; | |
| userAnswers = []; | |
| // 重置岩石進度 | |
| for (let i = 0; i < rocksProgress.length; i++) { | |
| rocksProgress[i].classList.remove('broken'); | |
| } | |
| // 顯示問題 | |
| resultContainer.style.display = 'none'; | |
| quizContainer.style.display = 'block'; | |
| loadQuestion(0); | |
| }); | |
| // 返回地圖按鈕點擊事件 | |
| backToMapBtn.addEventListener('click', function() { | |
| window.location.href = 'kingdom_map.html'; | |
| }); | |
| // 前往下一試煉按鈕點擊事件 | |
| const nextTrialBtn = document.getElementById('next-trial'); | |
| nextTrialBtn.addEventListener('click', function() { | |
| // 直接導向展開之塔 | |
| window.location.href = 'tower.html'; | |
| }); | |
| }); |