Spaces:
Running
Running
Upload 7 files
Browse files- .gitattributes +2 -0
- README.md +95 -0
- attack_descriptions.js +205 -0
- audio_controller.js +228 -0
- images/Loss.jpg +3 -0
- images/README.md +47 -0
- images/king.jpg +3 -0
- index.html +0 -0
.gitattributes
CHANGED
|
@@ -34,3 +34,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
king.jpg filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
king.jpg filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
images/king.jpg filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
images/Loss.jpg filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: 雞排怪挑戰遊戲
|
| 3 |
+
emoji: 🍗
|
| 4 |
+
colorFrom: red
|
| 5 |
+
colorTo: yellow
|
| 6 |
+
sdk: static
|
| 7 |
+
pinned: false
|
| 8 |
+
license: mit
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
# 雞排怪挑戰遊戲
|
| 12 |
+
|
| 13 |
+
一個基於學生成績的互動式挑戰遊戲!輸入你的出生年月日+座號,挑戰強大的雞排怪!
|
| 14 |
+
|
| 15 |
+
## 🎮 遊戲特色
|
| 16 |
+
|
| 17 |
+
- **個人化體驗**:根據學生資料生成專屬挑戰
|
| 18 |
+
- **多科目戰鬥**:國文、英文、數學、自然、社會科全面挑戰
|
| 19 |
+
- **複雜戰鬥系統**:包含裝備加成、等級加成、套裝加成
|
| 20 |
+
- **成績比較功能**:與歷史成績對比並提供學習建議
|
| 21 |
+
- **聖物補刀系統**:最後的逆轉機會
|
| 22 |
+
- **響應式設計**:支援手機、平板、桌面等各種裝置
|
| 23 |
+
|
| 24 |
+
## 🎯 如何遊玩
|
| 25 |
+
|
| 26 |
+
1. **登入**:輸入你的出生年月日+座號(例如:100090601)
|
| 27 |
+
2. **查看資料**:確認你的學生資料和裝備加成
|
| 28 |
+
3. **開始戰鬥**:依序輸入各科目分數進行攻擊
|
| 29 |
+
4. **科目攻擊**:
|
| 30 |
+
- 國文攻擊:攻擊力 × 5
|
| 31 |
+
- 英文攻擊:攻擊力 × 3
|
| 32 |
+
- 數學攻擊:攻擊力 × 4
|
| 33 |
+
- 自然攻擊:攻擊力 × 3
|
| 34 |
+
- 社會攻擊:攻擊力 × 3(需輸入歷史、地理、公民三科)
|
| 35 |
+
5. **聖物補刀**:如果血量不足,可使用聖物進行最後攻擊
|
| 36 |
+
6. **查看結果**:獲得詳細的成績分析和學習建議
|
| 37 |
+
|
| 38 |
+
## ⚔️ 戰鬥機制
|
| 39 |
+
|
| 40 |
+
### 攻擊力計算公式
|
| 41 |
+
```
|
| 42 |
+
攻擊力 = (分數 + 套裝加成 + 等級加成) × 裝備加成 × 科目倍率
|
| 43 |
+
```
|
| 44 |
+
|
| 45 |
+
### 科目倍率
|
| 46 |
+
- 國文:× 5(最高倍率)
|
| 47 |
+
- 數學:× 4
|
| 48 |
+
- 英文:× 3
|
| 49 |
+
- 自然:× 3
|
| 50 |
+
- 社會:× 3
|
| 51 |
+
|
| 52 |
+
### 特殊機制
|
| 53 |
+
- **社會科攻擊**:需要輸入歷史、地理、公民三科分數,取平均值計算
|
| 54 |
+
- **聖物系統**:每個聖物造成 20 點固定傷害
|
| 55 |
+
- **裝備加成**:根據學生資料提供不同的科目加成倍率
|
| 56 |
+
|
| 57 |
+
## 🎨 技術特色
|
| 58 |
+
|
| 59 |
+
- **純前端實作**:HTML + CSS + JavaScript
|
| 60 |
+
- **內嵌資料系統**:學生資料以 Base64 編碼嵌入
|
| 61 |
+
- **響應式設計**:支援各種螢幕尺寸
|
| 62 |
+
- **音效控制**:完整的音效管理系統(可開關)
|
| 63 |
+
- **動態視覺效果**:血量條、攻擊描述、狀態變化
|
| 64 |
+
|
| 65 |
+
## 📱 裝置支援
|
| 66 |
+
|
| 67 |
+
- ✅ 桌面電腦(Chrome、Firefox、Safari、Edge)
|
| 68 |
+
- ✅ 平板電腦(iPad、Android 平板)
|
| 69 |
+
- ✅ 智慧型手機(iOS、Android)
|
| 70 |
+
- ✅ 觸控操作友善
|
| 71 |
+
|
| 72 |
+
## 🎵 音效說明
|
| 73 |
+
|
| 74 |
+
遊戲包含背景音樂和音效系統:
|
| 75 |
+
- 背景音樂:Cjbeards - Fire and Thunder
|
| 76 |
+
- 音樂提供:J&B 無版權音樂庫
|
| 77 |
+
- 可透過右下角按鈕控制音樂開關
|
| 78 |
+
|
| 79 |
+
## 🔒 隱私說明
|
| 80 |
+
|
| 81 |
+
- 本遊戲僅使用學號作為識別,不收集個人敏感資訊
|
| 82 |
+
- 所有資料處理均在本地進行,不會上傳到伺服器
|
| 83 |
+
- 建議不要在公共電腦上輸入真實學號
|
| 84 |
+
|
| 85 |
+
## 🎓 教育價值
|
| 86 |
+
|
| 87 |
+
- **學習動機**:透過遊戲化提升學習興趣
|
| 88 |
+
- **成績分析**:提供詳細的學習建議
|
| 89 |
+
- **多元評量**:涵蓋各主要學科領域
|
| 90 |
+
- **自我挑戰**:鼓勵持續進步和自我超越
|
| 91 |
+
|
| 92 |
+
---
|
| 93 |
+
|
| 94 |
+
*這是一個教育娛樂用途的遊戲,旨在透過有趣的方式激發學習動機。請理性看待遊戲結果,專注於真實的學習成長。*
|
| 95 |
+
|
attack_descriptions.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// 攻擊描述資料庫 - 完整版本
|
| 2 |
+
const attackDescriptions = {
|
| 3 |
+
// 國文攻擊描述
|
| 4 |
+
chinese: {
|
| 5 |
+
thresholds: [0.15, 0.08], // 強力攻擊閾值:15%以上,中等攻擊:8%以上
|
| 6 |
+
strong: [
|
| 7 |
+
"📚 文字的力量如詩如畫!古典文學爆發驚人威力,詩詞歌賦化作利劍直刺雞排怪心臟!",
|
| 8 |
+
"✍️ 修辭技巧形成強大攻擊!比喻擬人如雷電交加,文學底蘊震撼全場!",
|
| 9 |
+
"🎭 國學底蘊展現深厚功力!四書五經的智慧凝聚成無堅不摧的文字風暴!",
|
| 10 |
+
"📖 千年文化傳承爆發!從詩經到現代文學,文字的魅力摧枯拉朽!",
|
| 11 |
+
"🖋️ 筆墨紙硯化作神兵利器!書法的韻律與文學的美感完美融合!"
|
| 12 |
+
],
|
| 13 |
+
medium: [
|
| 14 |
+
"📝 語文能力發揮穩定效果!閱讀理解與寫作技巧並重,文字攻擊命中目標!",
|
| 15 |
+
"📄 作文技巧形成有效攻擊!起承轉合的結構展現文學素養!",
|
| 16 |
+
"✏️ 語言表達展現實力!詞彙運用恰到好處,語法結構清晰有力!",
|
| 17 |
+
"📚 文學知識穩定輸出!從古典到現代,文學史的脈絡清晰可見!",
|
| 18 |
+
"🎨 文字藝術展現美感!修辭手法運用得當,語言文字生動有趣!"
|
| 19 |
+
],
|
| 20 |
+
weak: [
|
| 21 |
+
"📄 文學攻擊略顯不足...字詞運用需要加強,多閱讀經典作品吧!",
|
| 22 |
+
"🤷 語文基礎有待提升...句型結構稍顯混亂,需要多練習寫作!",
|
| 23 |
+
"😐 國文攻擊力有限...古文理解需要努力,建議多背誦經典篇章!",
|
| 24 |
+
"📝 文字表達能力待加強...詞彙量需要擴充,多讀書多寫作!",
|
| 25 |
+
"🤔 語言運用不夠靈活...修辭技巧需要練習,文學素養有待提升!"
|
| 26 |
+
]
|
| 27 |
+
},
|
| 28 |
+
|
| 29 |
+
// 英文攻擊描述
|
| 30 |
+
english: {
|
| 31 |
+
thresholds: [0.12, 0.06],
|
| 32 |
+
strong: [
|
| 33 |
+
"🌟 English power strikes like lightning! Grammar mastery unleashed with devastating force!",
|
| 34 |
+
"🚀 Vocabulary explosion creates massive damage! Ten thousand words become weapons of mass instruction!",
|
| 35 |
+
"⭐ Perfect pronunciation forms devastating attack! Fluency dominates the battlefield with eloquence!",
|
| 36 |
+
"💫 Advanced grammar structures demolish the enemy! Complex sentences weave a web of linguistic destruction!",
|
| 37 |
+
"🎯 Idioms and phrases rain down like arrows! Native-level expression overwhelms all opposition!"
|
| 38 |
+
],
|
| 39 |
+
medium: [
|
| 40 |
+
"📘 英語能力發揮穩定效果!單字記憶與文法概念並重,語言攻擊命中目標!",
|
| 41 |
+
"🗣️ 聽說讀寫技能均衡發展!英語溝通能力展現實力!",
|
| 42 |
+
"📚 英文基礎紮實穩固!文法概念清晰,單字運用得當!",
|
| 43 |
+
"🎧 語言技能穩定輸出!聽力理解與口語表達相得益彰!",
|
| 44 |
+
"📖 閱讀理解能力良好!英文文章的脈絡掌握得宜!"
|
| 45 |
+
],
|
| 46 |
+
weak: [
|
| 47 |
+
"📝 英文攻擊力道不足...單字量需要擴充,多背誦常用詞彙!",
|
| 48 |
+
"🤔 語法概念有些混亂...時態變化需要練習,建議多做文法練習!",
|
| 49 |
+
"😅 英語表達略顯生澀...口語能力待加強,多聽多說很重要!",
|
| 50 |
+
"📚 英文基礎需要鞏固...從基本文法開始,循序漸進學習!",
|
| 51 |
+
"🙄 語言運用不夠流暢...需要多接觸英語環境,培養語感!"
|
| 52 |
+
]
|
| 53 |
+
},
|
| 54 |
+
|
| 55 |
+
// 數學攻擊描述
|
| 56 |
+
math: {
|
| 57 |
+
thresholds: [0.18, 0.10],
|
| 58 |
+
strong: [
|
| 59 |
+
"🔥 數學公式如雷電般劈向雞排怪!微積分的威力無人能擋,極限與導數交織成毀滅之網!",
|
| 60 |
+
"⚡ 幾何定理爆發出驚人能量!三角函數與解析幾何完美結合,數學之美震撼全場!",
|
| 61 |
+
"💥 代數方程式形成強大攻擊波!複數與矩陣的力量超越想像!",
|
| 62 |
+
"🌌 數學邏輯展現絕對真理!從基礎運算到高等數學,理性思維無堅不摧!",
|
| 63 |
+
"🧮 數字的奧秘完全展現!統計機率與數學分析融為一體,精確計算摧毀一切!"
|
| 64 |
+
],
|
| 65 |
+
medium: [
|
| 66 |
+
"📊 數學運算穩定發揮!代數與幾何並重,邏輯思維清晰有序!",
|
| 67 |
+
"📐 計算能力展現實力!基礎運算與進階概念相輔相成!",
|
| 68 |
+
"🔢 數學概念理解良好!從算術到代數,數學基礎紮實穩固!",
|
| 69 |
+
"📈 數學思維邏輯清晰!問題解決能力與計算技巧並重!",
|
| 70 |
+
"🎯 數學應用能力不錯!理論與實際相結合,數學素養展現!"
|
| 71 |
+
],
|
| 72 |
+
weak: [
|
| 73 |
+
"📝 數字攻擊略有成效...基礎運算需要加強,多練習計算題!",
|
| 74 |
+
"🤔 數學概念有些模糊...公式記憶需要複習,理解比背誦更重要!",
|
| 75 |
+
"😅 數學攻擊���道不足...邏輯思維需要訓練,多做推理題目!",
|
| 76 |
+
"📚 數學基礎待鞏固...從基本概念開始,循序漸進學習!",
|
| 77 |
+
"🙄 計算能力需要提升...細心與耐心同樣重要,避免粗心錯誤!"
|
| 78 |
+
]
|
| 79 |
+
},
|
| 80 |
+
|
| 81 |
+
// 自然科學攻擊描述
|
| 82 |
+
science: {
|
| 83 |
+
thresholds: [0.12, 0.06],
|
| 84 |
+
strong: [
|
| 85 |
+
"🔬 科學知識爆發驚人威力!實驗精神與理論基礎完美結合,科學真理震撼全場!",
|
| 86 |
+
"⚗️ 化學反應形成強大攻擊!元素週期表的奧秘與分子結構的美妙交織成毀滅之力!",
|
| 87 |
+
"🌌 物理定律展現深奧力量!從牛頓力學到量子物理,宇宙法則無所不能!",
|
| 88 |
+
"🧬 生物科學展現生命奧秘!DNA的雙螺旋結構與進化論的智慧融為一體!",
|
| 89 |
+
"🌍 地球科學揭示自然威力!板塊運動與氣候變化的力量超越想像!"
|
| 90 |
+
],
|
| 91 |
+
medium: [
|
| 92 |
+
"🧪 自然科學穩定發揮!觀察實驗與理論學習並重,科學素養展現!",
|
| 93 |
+
"🔍 科學方法運用得當!假設驗證與數據分析相輔相成!",
|
| 94 |
+
"📊 實驗技能展現實力!從觀察到結論,科學思維邏輯清晰!",
|
| 95 |
+
"🌿 自然現象理解良好!生物多樣性與生態平衡概念清楚!",
|
| 96 |
+
"⚛️ 科學概念掌握不錯!物理化學基礎知識紮實穩固!"
|
| 97 |
+
],
|
| 98 |
+
weak: [
|
| 99 |
+
"🤓 科學攻擊需要加強...實驗技巧有待提升,多動手做實驗!",
|
| 100 |
+
"😵 理論概念稍顯模糊...科學原理需要複習,理解比記憶重要!",
|
| 101 |
+
"🙄 自然科學力道不足...觀察能力待加強,培養科學好奇心!",
|
| 102 |
+
"📚 科學基礎需要鞏固...從基本概念開始,建立完整知識體系!",
|
| 103 |
+
"🤔 科學思維待培養...邏輯推理與批判思考同樣重要!"
|
| 104 |
+
]
|
| 105 |
+
},
|
| 106 |
+
|
| 107 |
+
// 社會科學攻擊描述
|
| 108 |
+
social: {
|
| 109 |
+
thresholds: [0.10, 0.05],
|
| 110 |
+
strong: [
|
| 111 |
+
"🏛️ 社會科學知識重擊敵人!歷史智慧與地理知識完美融合,人文素養威力無窮!",
|
| 112 |
+
"🗺️ 地理知識爆發強大能量!從地形氣候到人文地理,空間概念震撼全場!",
|
| 113 |
+
"⚖️ 公民意識形成正義攻擊!民主法治與人權觀念凝聚成不可撼動的力量!",
|
| 114 |
+
"📜 歷史智慧穿越時空!從古代文明到現代社會,歷史脈絡清晰可見!",
|
| 115 |
+
"🌍 全球視野展現格局!國際關係與文化交流的深度理解超越想像!"
|
| 116 |
+
],
|
| 117 |
+
medium: [
|
| 118 |
+
"📚 社會科學穩定發揮!歷史地理與公民知識並重,人文素養展現!",
|
| 119 |
+
"🏛️ 人文關懷展現實力!社會議題與公民責任意識清晰!",
|
| 120 |
+
"🌍 地理概念掌握良好!空間分布與區域特色理解得當!",
|
| 121 |
+
"📜 歷史脈絡理解不錯!時代背景與因果關係掌握得宜!",
|
| 122 |
+
"⚖️ 公民素養展現水準!民主參與與法治觀念具備!"
|
| 123 |
+
],
|
| 124 |
+
weak: [
|
| 125 |
+
"📚 社會科攻擊力有限...歷史脈絡需要梳理,多讀史書增廣見聞!",
|
| 126 |
+
"🤷 地理概念稍顯模糊...空間認知待加強,多看地圖培養方向感!",
|
| 127 |
+
"😐 人文素養有待提升...社會議題需要關注,培養公民意識!",
|
| 128 |
+
"📖 社會科學基礎待鞏固...從基本概念開始,建立完整知識架構!",
|
| 129 |
+
"🤔 批判思考能力需要培養...多元觀點與獨立思考同樣重要!"
|
| 130 |
+
]
|
| 131 |
+
}
|
| 132 |
+
};
|
| 133 |
+
|
| 134 |
+
// 隨機獲取攻擊描述的函數
|
| 135 |
+
function getRandomAttackDescription(subject, attackPower, totalHP) {
|
| 136 |
+
// 將科目名稱對應到描述資料庫的鍵值
|
| 137 |
+
const subjectMap = {
|
| 138 |
+
'國文': 'chinese',
|
| 139 |
+
'英文': 'english',
|
| 140 |
+
'數學': 'math',
|
| 141 |
+
'自科': 'science',
|
| 142 |
+
'社會': 'social'
|
| 143 |
+
};
|
| 144 |
+
|
| 145 |
+
const mappedSubject = subjectMap[subject];
|
| 146 |
+
if (!mappedSubject || !attackDescriptions[mappedSubject]) {
|
| 147 |
+
return null;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
const subjectData = attackDescriptions[mappedSubject];
|
| 151 |
+
const ratio = attackPower / totalHP;
|
| 152 |
+
|
| 153 |
+
let descriptions;
|
| 154 |
+
if (ratio >= subjectData.thresholds[0]) {
|
| 155 |
+
descriptions = subjectData.strong;
|
| 156 |
+
} else if (ratio >= subjectData.thresholds[1]) {
|
| 157 |
+
descriptions = subjectData.medium;
|
| 158 |
+
} else {
|
| 159 |
+
descriptions = subjectData.weak;
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
// 隨機選擇一個描述
|
| 163 |
+
const randomIndex = Math.floor(Math.random() * descriptions.length);
|
| 164 |
+
return descriptions[randomIndex];
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
// 獲取攻擊強度等級的函數
|
| 168 |
+
function getAttackLevel(subject, attackPower, totalHP) {
|
| 169 |
+
const subjectMap = {
|
| 170 |
+
'國文': 'chinese',
|
| 171 |
+
'英文': 'english',
|
| 172 |
+
'數學': 'math',
|
| 173 |
+
'自科': 'science',
|
| 174 |
+
'社會': 'social'
|
| 175 |
+
};
|
| 176 |
+
|
| 177 |
+
const mappedSubject = subjectMap[subject];
|
| 178 |
+
if (!mappedSubject || !attackDescriptions[mappedSubject]) {
|
| 179 |
+
return 'weak';
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
const subjectData = attackDescriptions[mappedSubject];
|
| 183 |
+
const ratio = attackPower / totalHP;
|
| 184 |
+
|
| 185 |
+
if (ratio >= subjectData.thresholds[0]) {
|
| 186 |
+
return 'strong';
|
| 187 |
+
} else if (ratio >= subjectData.thresholds[1]) {
|
| 188 |
+
return 'medium';
|
| 189 |
+
} else {
|
| 190 |
+
return 'weak';
|
| 191 |
+
}
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
// 獲取所有科目的攻擊閾值資訊
|
| 195 |
+
function getAttackThresholds() {
|
| 196 |
+
const thresholds = {};
|
| 197 |
+
for (const [subject, data] of Object.entries(attackDescriptions)) {
|
| 198 |
+
thresholds[subject] = {
|
| 199 |
+
strong: data.thresholds[0],
|
| 200 |
+
medium: data.thresholds[1]
|
| 201 |
+
};
|
| 202 |
+
}
|
| 203 |
+
return thresholds;
|
| 204 |
+
}
|
| 205 |
+
|
audio_controller.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// 音效控制器 - 完整版本
|
| 2 |
+
const audioController = {
|
| 3 |
+
bgm: null,
|
| 4 |
+
attackSounds: {},
|
| 5 |
+
resultSounds: {},
|
| 6 |
+
isBGMPlaying: false,
|
| 7 |
+
isInitialized: false,
|
| 8 |
+
|
| 9 |
+
// 初始化音效控制器
|
| 10 |
+
init() {
|
| 11 |
+
if (this.isInitialized) return;
|
| 12 |
+
|
| 13 |
+
console.log('音效控制器初始化中...');
|
| 14 |
+
|
| 15 |
+
// 初始化背景音樂
|
| 16 |
+
// 注意:由於版權考量,這裡不包含實際的音樂檔案
|
| 17 |
+
// 如果要添加背景音樂,請取消註解以下代碼並提供音樂檔案
|
| 18 |
+
/*
|
| 19 |
+
try {
|
| 20 |
+
this.bgm = new Audio('audio/background.mp3');
|
| 21 |
+
this.bgm.loop = true;
|
| 22 |
+
this.bgm.volume = 0.3;
|
| 23 |
+
this.bgm.preload = 'auto';
|
| 24 |
+
} catch (error) {
|
| 25 |
+
console.log('背景音樂載入失敗:', error);
|
| 26 |
+
}
|
| 27 |
+
*/
|
| 28 |
+
|
| 29 |
+
// 初始化攻擊音效
|
| 30 |
+
// 同樣由於版權考量,這裡不包含實際的音效檔案
|
| 31 |
+
/*
|
| 32 |
+
try {
|
| 33 |
+
this.attackSounds = {
|
| 34 |
+
weak: new Audio('audio/attack_weak.mp3'),
|
| 35 |
+
medium: new Audio('audio/attack_medium.mp3'),
|
| 36 |
+
strong: new Audio('audio/attack_strong.mp3')
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
// 設置攻擊音效音量
|
| 40 |
+
Object.values(this.attackSounds).forEach(sound => {
|
| 41 |
+
sound.volume = 0.5;
|
| 42 |
+
sound.preload = 'auto';
|
| 43 |
+
});
|
| 44 |
+
} catch (error) {
|
| 45 |
+
console.log('攻擊音效載入失敗:', error);
|
| 46 |
+
}
|
| 47 |
+
*/
|
| 48 |
+
|
| 49 |
+
// 初始化結果音效
|
| 50 |
+
/*
|
| 51 |
+
try {
|
| 52 |
+
this.resultSounds = {
|
| 53 |
+
win: new Audio('audio/victory.mp3'),
|
| 54 |
+
lose: new Audio('audio/defeat.mp3')
|
| 55 |
+
};
|
| 56 |
+
|
| 57 |
+
// 設置結果音效音量
|
| 58 |
+
Object.values(this.resultSounds).forEach(sound => {
|
| 59 |
+
sound.volume = 0.6;
|
| 60 |
+
sound.preload = 'auto';
|
| 61 |
+
});
|
| 62 |
+
} catch (error) {
|
| 63 |
+
console.log('結果音效載入失敗:', error);
|
| 64 |
+
}
|
| 65 |
+
*/
|
| 66 |
+
|
| 67 |
+
this.isInitialized = true;
|
| 68 |
+
console.log('音效控制器初始化完成');
|
| 69 |
+
},
|
| 70 |
+
|
| 71 |
+
// 播放背景音樂
|
| 72 |
+
playBGM() {
|
| 73 |
+
if (!this.bgm) {
|
| 74 |
+
console.log('背景音樂未載入');
|
| 75 |
+
return;
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
try {
|
| 79 |
+
const playPromise = this.bgm.play();
|
| 80 |
+
if (playPromise !== undefined) {
|
| 81 |
+
playPromise.then(() => {
|
| 82 |
+
this.isBGMPlaying = true;
|
| 83 |
+
console.log('背景音樂開始播放');
|
| 84 |
+
}).catch(error => {
|
| 85 |
+
console.log('背景音樂播放失敗:', error);
|
| 86 |
+
// 瀏覽器可能阻止自動播放,這是正常的
|
| 87 |
+
});
|
| 88 |
+
}
|
| 89 |
+
} catch (error) {
|
| 90 |
+
console.log('背景音樂播放錯誤:', error);
|
| 91 |
+
}
|
| 92 |
+
},
|
| 93 |
+
|
| 94 |
+
// 暫停背景音樂
|
| 95 |
+
pauseBGM() {
|
| 96 |
+
if (this.bgm && this.isBGMPlaying) {
|
| 97 |
+
this.bgm.pause();
|
| 98 |
+
this.isBGMPlaying = false;
|
| 99 |
+
console.log('背景音樂已暫停');
|
| 100 |
+
}
|
| 101 |
+
},
|
| 102 |
+
|
| 103 |
+
// 切換背景音樂
|
| 104 |
+
toggleBGM() {
|
| 105 |
+
if (!this.bgm) {
|
| 106 |
+
console.log('背景音樂功能暫時不可用');
|
| 107 |
+
return;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
if (this.isBGMPlaying) {
|
| 111 |
+
this.pauseBGM();
|
| 112 |
+
} else {
|
| 113 |
+
this.playBGM();
|
| 114 |
+
}
|
| 115 |
+
},
|
| 116 |
+
|
| 117 |
+
// 播放攻擊音效
|
| 118 |
+
playAttackSound(type = 'medium') {
|
| 119 |
+
if (!this.attackSounds[type]) {
|
| 120 |
+
console.log(`攻擊音效 ${type} 未載入`);
|
| 121 |
+
return;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
try {
|
| 125 |
+
// 重置音效到開始位置
|
| 126 |
+
this.attackSounds[type].currentTime = 0;
|
| 127 |
+
const playPromise = this.attackSounds[type].play();
|
| 128 |
+
|
| 129 |
+
if (playPromise !== undefined) {
|
| 130 |
+
playPromise.then(() => {
|
| 131 |
+
console.log(`播放 ${type} 攻擊音效`);
|
| 132 |
+
}).catch(error => {
|
| 133 |
+
console.log(`${type} 攻擊音效播放失敗:`, error);
|
| 134 |
+
});
|
| 135 |
+
}
|
| 136 |
+
} catch (error) {
|
| 137 |
+
console.log(`${type} 攻擊音效播放錯誤:`, error);
|
| 138 |
+
}
|
| 139 |
+
},
|
| 140 |
+
|
| 141 |
+
// 播放結果音效
|
| 142 |
+
playResultSound(type = 'win') {
|
| 143 |
+
if (!this.resultSounds[type]) {
|
| 144 |
+
console.log(`結果音效 ${type} 未載入`);
|
| 145 |
+
return;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
try {
|
| 149 |
+
// 重置音效到開始位置
|
| 150 |
+
this.resultSounds[type].currentTime = 0;
|
| 151 |
+
const playPromise = this.resultSounds[type].play();
|
| 152 |
+
|
| 153 |
+
if (playPromise !== undefined) {
|
| 154 |
+
playPromise.then(() => {
|
| 155 |
+
console.log(`播放 ${type} 結果音效`);
|
| 156 |
+
}).catch(error => {
|
| 157 |
+
console.log(`${type} 結果音效播放失敗:`, error);
|
| 158 |
+
});
|
| 159 |
+
}
|
| 160 |
+
} catch (error) {
|
| 161 |
+
console.log(`${type} 結果音效播放錯誤:`, error);
|
| 162 |
+
}
|
| 163 |
+
},
|
| 164 |
+
|
| 165 |
+
// 停止所有音效
|
| 166 |
+
stopAll() {
|
| 167 |
+
// 停止背景音樂
|
| 168 |
+
if (this.bgm) {
|
| 169 |
+
this.bgm.pause();
|
| 170 |
+
this.bgm.currentTime = 0;
|
| 171 |
+
this.isBGMPlaying = false;
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
// 停止攻擊音效
|
| 175 |
+
Object.values(this.attackSounds).forEach(sound => {
|
| 176 |
+
if (sound) {
|
| 177 |
+
sound.pause();
|
| 178 |
+
sound.currentTime = 0;
|
| 179 |
+
}
|
| 180 |
+
});
|
| 181 |
+
|
| 182 |
+
// 停止結果音效
|
| 183 |
+
Object.values(this.resultSounds).forEach(sound => {
|
| 184 |
+
if (sound) {
|
| 185 |
+
sound.pause();
|
| 186 |
+
sound.currentTime = 0;
|
| 187 |
+
}
|
| 188 |
+
});
|
| 189 |
+
|
| 190 |
+
console.log('所有音效已停止');
|
| 191 |
+
},
|
| 192 |
+
|
| 193 |
+
// 設置音量
|
| 194 |
+
setVolume(bgmVolume = 0.3, effectVolume = 0.5) {
|
| 195 |
+
if (this.bgm) {
|
| 196 |
+
this.bgm.volume = Math.max(0, Math.min(1, bgmVolume));
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
Object.values(this.attackSounds).forEach(sound => {
|
| 200 |
+
if (sound) {
|
| 201 |
+
sound.volume = Math.max(0, Math.min(1, effectVolume));
|
| 202 |
+
}
|
| 203 |
+
});
|
| 204 |
+
|
| 205 |
+
Object.values(this.resultSounds).forEach(sound => {
|
| 206 |
+
if (sound) {
|
| 207 |
+
sound.volume = Math.max(0, Math.min(1, effectVolume));
|
| 208 |
+
}
|
| 209 |
+
});
|
| 210 |
+
|
| 211 |
+
console.log(`音量設置 - 背景音樂: ${bgmVolume}, 音效: ${effectVolume}`);
|
| 212 |
+
},
|
| 213 |
+
|
| 214 |
+
// 檢查音效支援
|
| 215 |
+
checkAudioSupport() {
|
| 216 |
+
const audio = new Audio();
|
| 217 |
+
const support = {
|
| 218 |
+
mp3: audio.canPlayType('audio/mpeg') !== '',
|
| 219 |
+
ogg: audio.canPlayType('audio/ogg') !== '',
|
| 220 |
+
wav: audio.canPlayType('audio/wav') !== '',
|
| 221 |
+
m4a: audio.canPlayType('audio/mp4') !== ''
|
| 222 |
+
};
|
| 223 |
+
|
| 224 |
+
console.log('音效格式支援:', support);
|
| 225 |
+
return support;
|
| 226 |
+
}
|
| 227 |
+
};
|
| 228 |
+
|
images/Loss.jpg
ADDED
|
Git LFS Details
|
images/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 圖片資源說明
|
| 2 |
+
|
| 3 |
+
## 📁 圖片檔案
|
| 4 |
+
|
| 5 |
+
### king.jpg
|
| 6 |
+
- **描述**:雞排怪的正常狀態圖片
|
| 7 |
+
- **用途**:在戰鬥開始、聖物使用階段顯示
|
| 8 |
+
- **來源**:CG Cookie - The Chicken Monster
|
| 9 |
+
- **尺寸**:1280x1280 像素
|
| 10 |
+
- **格式**:PNG(重新命名為 .jpg)
|
| 11 |
+
|
| 12 |
+
### Loss.jpg
|
| 13 |
+
- **描述**:雞排怪被擊敗後的狀態圖片
|
| 14 |
+
- **用途**:當雞排怪血量歸零時顯示
|
| 15 |
+
- **來源**:CleanPNG - Crying Cartoon Chicken
|
| 16 |
+
- **尺寸**:900x900 像素
|
| 17 |
+
- **格式**:WebP(重新命名為 .jpg)
|
| 18 |
+
|
| 19 |
+
## 🎨 圖片特色
|
| 20 |
+
|
| 21 |
+
- **風格一致**:都是卡通風格的雞肉角色
|
| 22 |
+
- **表情豐富**:正常狀態威猛,失敗狀態可憐
|
| 23 |
+
- **高解析度**:適合在各種螢幕尺寸下顯示
|
| 24 |
+
- **透明背景**:部分圖片支援透明背景
|
| 25 |
+
|
| 26 |
+
## 📝 版權說明
|
| 27 |
+
|
| 28 |
+
- 圖片來源於公開的圖庫網站
|
| 29 |
+
- 用於教育和非商業用途
|
| 30 |
+
- 如有版權疑慮,可替換為自製圖片
|
| 31 |
+
|
| 32 |
+
## 🔄 替換建議
|
| 33 |
+
|
| 34 |
+
如果需要替換圖片,建議:
|
| 35 |
+
|
| 36 |
+
1. **保持尺寸比例**:建議使用正方形或接近正方形的圖片
|
| 37 |
+
2. **風格一致**:選擇卡通或遊戲風格的圖片
|
| 38 |
+
3. **表情對比**:king.jpg 應該看起來強大,Loss.jpg 應該看起來被擊敗
|
| 39 |
+
4. **檔案大小**:建議每張圖片不超過 500KB
|
| 40 |
+
|
| 41 |
+
## 🛠️ 技術規格
|
| 42 |
+
|
| 43 |
+
- **支援格式**:JPG、PNG、WebP、GIF
|
| 44 |
+
- **建議尺寸**:300x300 到 1000x1000 像素
|
| 45 |
+
- **最大檔案大小**:建議不超過 1MB
|
| 46 |
+
- **命名規則**:必須使用 `king.jpg` 和 `Loss.jpg`
|
| 47 |
+
|
images/king.jpg
ADDED
|
Git LFS Details
|
index.html
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|