Math_Adventure_8thgrade / philosophy.html
Lashtw's picture
Upload philosophy.html
64b672e verified
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>數學探險島 - 哲學之塔</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;500;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans TC', sans-serif;
background-image: url('https://i.meee.com.tw/wCWCOGx.png');
background-size: cover;
background-position: center;
background-attachment: fixed;
}
.tower-bg {
background-image: url('https://www.transparenttextures.com/patterns/stone-wall.png');
background-color: #e2e8f0;
}
/* 自訂拉桿樣式 */
input[type=range] {
-webkit-appearance: none;
width: 100%;
background: transparent;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 12px;
cursor: pointer;
background: #93c5fd;
border-radius: 5px;
border: 1px solid #60a5fa;
}
input[type=range]::-webkit-slider-thumb {
border: 2px solid #3b82f6;
height: 30px;
width: 30px;
border-radius: 50%;
background: #eff6ff;
cursor: pointer;
-webkit-appearance: none;
margin-top: -10px;
}
/* 成功時的閃爍動畫 */
@keyframes flash {
0%, 100% { box-shadow: 0 0 20px 5px rgba(34, 197, 94, 0.7); }
50% { box-shadow: 0 0 5px 0px rgba(34, 197, 94, 0.2); }
}
.success-flash {
animation: flash 1.5s ease-in-out;
}
/* 測驗選項樣式 */
.quiz-option {
display: block;
padding: 0.75rem 1rem;
border: 2px solid #e5e7eb;
border-radius: 0.5rem;
margin-bottom: 0.5rem;
cursor: pointer;
transition: all 0.2s;
}
.quiz-option:hover {
background-color: #f3f4f6;
}
input[type="radio"]:checked + .quiz-option {
background-color: #dbeafe;
border-color: #60a5fa;
}
.question-container.incorrect {
border: 2px solid #ef4444;
border-radius: 0.75rem;
padding: 1rem;
background-color: #fee2e2;
}
</style>
</head>
<body class="flex items-center justify-center min-h-screen p-4">
<div id="main-container" class="container mx-auto max-w-5xl">
<!-- 故事引導畫面 -->
<div id="story-view" class="bg-white/80 backdrop-blur-md rounded-xl shadow-2xl p-8 text-center">
<h1 class="text-3xl md:text-4xl font-bold text-gray-800 text-center mb-6">前情提要:西帕索斯的悲劇</h1>
<div class="border rounded-lg shadow-inner bg-gray-100 p-12 flex flex-col items-center justify-center" style="height: 50vh;">
<svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-indigo-300 mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v11.494m-9-5.747h18" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v11.494m-9-5.747h18" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 18h16" />
</svg>
<p class="text-xl text-gray-600">故事即將展開...</p>
<p class="mt-4 text-lg text-indigo-600 font-semibold">點擊下方按鈕,在新分頁閱讀故事前情提要!</p>
</div>
<p class="mt-8 text-gray-600 font-semibold">閱讀完故事後,請回來按下開始挑戰</p>
<a href="https://g.co/gemini/share/d181055c5aa2" target="_blank" id="story-link-button" class="mt-2 inline-block w-full md:w-auto bg-blue-500 text-white font-bold py-3 px-8 rounded-lg hover:bg-blue-600 transition-colors shadow-lg text-lg">
閱讀故事
</a>
<button id="start-quiz-button" class="mt-4 w-full md:w-auto bg-indigo-600 text-white font-bold py-3 px-8 rounded-lg hover:bg-indigo-700 transition-colors shadow-lg text-lg">
開始挑戰!
</button>
</div>
<!-- 閱讀測驗畫面 (新增) -->
<div id="quiz-view" class="hidden bg-white/80 backdrop-blur-md rounded-xl shadow-2xl p-8">
<h1 class="text-3xl font-bold text-gray-800 text-center mb-6">閱讀測驗:西帕索斯的考驗</h1>
<div class="space-y-6 text-left">
<!-- 問題 1 -->
<div id="question-container-0" class="question-container">
<p class="font-semibold mb-2">1. 根據故事內容,西帕索斯為什麼被畢達哥拉斯囚禁在哲學之塔?</p>
<div class="space-y-2">
<label><input type="radio" name="q0" value="A" class="hidden"> <span class="quiz-option">(A) 因為他試圖偷取畢達哥拉斯的數學理論。</span></label>
<label><input type="radio" name="q0" value="B" class="hidden"> <span class="quiz-option">(B) 因為他在公開場合侮辱了畢達哥拉斯本人。</span></label>
<label><input type="radio" name="q0" value="C" class="hidden"> <span class="quiz-option">(C) 因為他發現了一個無法用分數或小數表示的數字,這與畢達哥拉斯學派的信念相衝突。</span></label>
<label><input type="radio" name="q0" value="D" class="hidden"> <span class="quiz-option">(D) 因為他沒能成功計算出一個正方形的面積。</span></label>
</div>
</div>
<!-- 問題 2 -->
<div id="question-container-1" class="question-container">
<p class="font-semibold mb-2">2. 故事中,那個動搖了畢達哥拉斯學派信念的「神秘數字」,最初是源自於什麼?</p>
<div class="space-y-2">
<label><input type="radio" name="q1" value="A" class="hidden"> <span class="quiz-option">(A) 一個面積為3的圓形半徑。</span></label>
<label><input type="radio" name="q1" value="B" class="hidden"> <span class="quiz-option">(B) 一個面積為2的正方形邊長。</span></label>
<label><input type="radio" name="q1" value="C" class="hidden"> <span class="quiz-option">(C) 一個從未有人見過的全新立體圖形。</span></label>
<label><input type="radio" name="q1" value="D" class="hidden"> <span class="quiz-option">(D) 一個畢達哥拉斯自己提出的數學謎題。</span></label>
</div>
</div>
<!-- 問題 3 -->
<div id="question-container-2" class="question-container">
<p class="font-semibold mb-2">3. 在故事的結尾,你(讀者)被賦予的主要任務是什麼?</p>
<div class="space-y-2">
<label><input type="radio" name="q2" value="A" class="hidden"> <span class="quiz-option">(A) 找到一把萬能鑰匙,趁半夜把西帕索斯從監獄裡救出來。</span></label>
<label><input type="radio" name="q2" value="B" class="hidden"> <span class="quiz-option">(B) 回到未來,尋找歷史文獻來證明西帕索斯是對的。</span></label>
<label><input type="radio" name="q2" value="C" class="hidden"> <span class="quiz-option">(C) 成為畢達哥拉斯的學徒,從內部瓦解他的學派。</span></label>
<label><input type="radio" name="q2" value="D" class="hidden"> <span class="quiz-option">(D) 找出幾個「神秘數字」的近似值,用具體的證據去說服畢達哥拉斯。</span></label>
</div>
</div>
</div>
<div id="quiz-feedback" class="text-center font-semibold mt-6 min-h-[24px]"></div>
<div class="flex flex-col md:flex-row gap-4 mt-6">
<button id="reread-story-button" class="w-full md:w-1/2 bg-gray-500 text-white font-bold py-3 px-6 rounded-lg hover:bg-gray-600 transition-colors">再看一次故事</button>
<button id="submit-quiz-button" class="w-full md:w-1/2 bg-green-500 text-white font-bold py-3 px-6 rounded-lg hover:bg-green-600 transition-colors">提交答案</button>
</div>
</div>
<!-- 遊戲畫面 (預設隱藏) -->
<div id="game-view" class="hidden bg-white/80 backdrop-blur-md rounded-xl shadow-2xl p-8 tower-bg">
<h1 class="text-3xl md:text-4xl font-bold text-gray-800 text-center mb-2">哲學之塔</h1>
<p class="text-center text-gray-600 mb-6">幫助被囚禁的西帕索斯,找出正方形的神秘邊長!</p>
<div class="grid md:grid-cols-2 gap-8 items-center">
<!-- 左側:正方形展示區 -->
<div class="flex flex-col items-center justify-center bg-white/70 p-6 rounded-lg shadow-inner">
<div id="square-display" class="w-48 h-48 bg-blue-300 border-4 border-blue-500 flex items-center justify-center relative transition-transform duration-500">
<p class="text-2xl font-bold text-white">面積 = <span id="target-area-text">2</span></p>
</div>
<p class="mt-4 text-2xl font-mono text-gray-700">邊長 = <span id="target-sqrt-text">√2</span></p>
</div>
<!-- 右側:互動操作區 -->
<div class="flex flex-col space-y-6">
<div class="bg-white/80 p-4 rounded-lg text-center">
<p class="text-lg">你的猜測邊長 <span id="guess-sqrt-text" class="font-mono">√2</span><span id="current-value" class="font-bold text-2xl text-indigo-600">1.50</span></p>
<p class="text-lg">邊長的平方(正方形面積):<span id="current-squared-value" class="font-bold text-2xl text-red-500">2.25</span></p>
</div>
<input type="range" id="value-slider" min="1" max="2" value="1.5" step="0.01" class="w-full">
<button id="check-button" class="w-full bg-green-500 text-white font-bold py-3 px-4 rounded-lg hover:bg-green-600 transition-colors shadow-md text-xl">
確定答案
</button>
<div id="feedback-box" class="text-center text-xl font-semibold min-h-[32px]"></div>
<button id="next-level-button" class="w-full bg-indigo-500 text-white font-bold py-3 px-4 rounded-lg hover:bg-indigo-600 transition-colors shadow-md text-xl hidden">
挑戰下一關
</button>
</div>
</div>
</div>
<!-- 生活應用畫面 (預設隱藏) -->
<div id="application-view" class="hidden bg-white/80 backdrop-blur-md rounded-xl shadow-2xl p-8">
<h1 class="text-3xl md:text-4xl font-bold text-green-600 mb-4 text-center">恭喜你,成功解救了西帕索斯!</h1>
<p class="text-lg text-gray-700 mb-8 text-center">你們玩遊戲的時候,有沒有想過,為什麼角色撞到怪物就會扣血?為什麼子彈會正好打到你?這不是靠神奇的第六感,是靠數學──而且關鍵數學招式就是平方根!</p>
<div class="bg-blue-50 p-6 rounded-lg text-left">
<h2 class="text-2xl font-bold text-indigo-600 mb-4 text-center">🎮 遊戲物理引擎裡的平方根魔法</h2>
<div class="space-y-6">
<div>
<h3 class="font-semibold text-xl mb-2">判斷「有沒有撞到」</h3>
<p>遊戲世界是由座標組成的(就像地圖上的 X、Y 點)。當角色和怪物在不同位置,遊戲必須算兩者的距離,來判斷是不是近到可以碰撞。</p>
<p class="mt-2 p-3 bg-gray-200 rounded-md text-center font-mono text-lg">距離 = √((x₁ - x₂)² + (y₁ - y₂)²)</p>
<p class="mt-2">最後那個開根號,就是讓距離變回「真實長度」。沒有平方根,遊戲根本不知道你到底是不是碰到牆、怪物、寶箱。</p>
</div>
<div>
<h3 class="font-semibold text-xl mb-2">算出移動的真速度</h3>
<p>在 3D 遊戲中,速度不只有一個方向。例如你同時向前(X 軸)+ 向右(Y 軸)移動,總速度不是單純相加,而是:</p>
<p class="mt-2 p-3 bg-gray-200 rounded-md text-center font-mono text-lg">總速度 = √(水平速度² + 垂直速度²)</p>
<p class="mt-2">這樣遊戲才能正確決定動畫快慢、物理反應強度。</p>
</div>
<div>
<h3 class="font-semibold text-xl mb-2">模擬「真實的碰撞反應」</h3>
<p>角色被怪物推一下,會往斜方向飛。遊戲會算推力向量的大小(也就是「合力長度」)來決定你飛多遠,這裡也要平方根。</p>
</div>
</div>
<div class="mt-6 pt-6 border-t">
<p class="text-xl text-center"><span class="font-bold">💡 簡單比喻:</span>「平方根在遊戲引擎裡,就像一把『距離測量尺』,沒有它,遊戲世界就不知道東西有多近、有多快,甚至不會知道你到底撞到沒。」</p>
</div>
</div>
<div class="mt-12 text-center">
<a href="index.html" class="inline-block w-full md:w-1/2 bg-indigo-600 text-white font-bold py-3 md:py-4 px-6 rounded-lg hover:bg-indigo-700 transition-colors shadow-lg text-lg md:text-xl">
回到探險島地圖
</a>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// --- 關卡設定 ---
const levels = [
{ target: 2, min: 1, max: 2, tolerance: 0.05, type: 'manual' },
{ target: 3, min: 1, max: 2, tolerance: 0.05, type: 'auto', speed: 0.007 },
{ target: 5, min: 2, max: 3, tolerance: 0.05, type: 'auto', speed: 0.011 }
];
let currentLevel = 0;
const quizQuestions = [
{ answer: 'C' },
{ answer: 'B' },
{ answer: 'D' }
];
// --- DOM 元素 ---
const storyView = document.getElementById('story-view');
const startQuizButton = document.getElementById('start-quiz-button');
const quizView = document.getElementById('quiz-view');
const submitQuizButton = document.getElementById('submit-quiz-button');
const rereadStoryButton = document.getElementById('reread-story-button');
const quizFeedback = document.getElementById('quiz-feedback');
const gameView = document.getElementById('game-view');
const applicationView = document.getElementById('application-view');
const squareDisplay = document.getElementById('square-display');
const targetAreaText = document.getElementById('target-area-text');
const targetSqrtText = document.getElementById('target-sqrt-text');
const guessSqrtText = document.getElementById('guess-sqrt-text');
const currentValue = document.getElementById('current-value');
const currentSquaredValue = document.getElementById('current-squared-value');
const valueSlider = document.getElementById('value-slider');
const checkButton = document.getElementById('check-button');
const feedbackBox = document.getElementById('feedback-box');
const nextLevelButton = document.getElementById('next-level-button');
// --- 遊戲狀態 ---
let sliderAnimationId = null;
let sliderDirection = 1;
// --- 核心函式 ---
function initLevel(levelIndex) {
const level = levels[levelIndex];
if (sliderAnimationId) {
cancelAnimationFrame(sliderAnimationId);
sliderAnimationId = null;
}
targetAreaText.textContent = level.target;
targetSqrtText.innerHTML = `√${level.target}`;
guessSqrtText.innerHTML = `√${level.target}`;
valueSlider.min = level.min;
valueSlider.max = level.max;
valueSlider.value = (level.min + level.max) / 2;
valueSlider.step = 0.01;
updateSliderDisplay();
feedbackBox.textContent = '';
feedbackBox.className = 'text-center text-xl font-semibold min-h-[32px]';
checkButton.disabled = false;
nextLevelButton.classList.add('hidden');
squareDisplay.classList.remove('success-flash');
if (level.type === 'manual') {
valueSlider.style.pointerEvents = 'auto';
checkButton.textContent = '確定答案';
} else {
valueSlider.style.pointerEvents = 'none';
checkButton.textContent = '按下鎖定!';
sliderDirection = 1;
startSliderAnimation();
}
if (levelIndex === levels.length - 1) {
nextLevelButton.textContent = '查看生活應用';
} else {
nextLevelButton.textContent = '挑戰下一關';
}
}
function startSliderAnimation() {
const level = levels[currentLevel];
let val = parseFloat(valueSlider.value);
val += sliderDirection * level.speed;
if (val >= level.max || val <= level.min) {
sliderDirection *= -1;
val = Math.max(level.min, Math.min(level.max, val));
}
valueSlider.value = val;
updateSliderDisplay();
sliderAnimationId = requestAnimationFrame(startSliderAnimation);
}
function updateSliderDisplay() {
const val = parseFloat(valueSlider.value);
const squaredVal = val * val;
currentValue.textContent = val.toFixed(2);
currentSquaredValue.textContent = squaredVal.toFixed(2);
}
function checkAnswer() {
const level = levels[currentLevel];
if (level.type === 'auto' && sliderAnimationId) {
cancelAnimationFrame(sliderAnimationId);
sliderAnimationId = null;
}
checkButton.disabled = true;
const val = parseFloat(valueSlider.value);
const squaredVal = val * val;
const difference = Math.abs(squaredVal - level.target);
feedbackBox.textContent = '';
if (difference <= level.tolerance) {
feedbackBox.textContent = '太棒了!你找到了!';
feedbackBox.className = 'text-center text-xl font-semibold text-green-600';
nextLevelButton.classList.remove('hidden');
squareDisplay.classList.add('success-flash');
} else {
const hint = squaredVal < level.target ? '太小了' : '太大了';
feedbackBox.textContent = `喔喔!${hint},再試一次!`;
feedbackBox.className = 'text-center text-xl font-semibold text-red-600';
if (level.type === 'auto') {
setTimeout(() => {
initLevel(currentLevel);
}, 2000);
} else {
checkButton.disabled = false;
}
}
}
function loadNext() {
currentLevel++;
if (currentLevel < levels.length) {
initLevel(currentLevel);
} else {
gameView.classList.add('hidden');
applicationView.classList.remove('hidden');
}
}
function checkQuiz() {
let allCorrect = true;
quizFeedback.textContent = '';
quizFeedback.classList.remove('text-red-500', 'text-green-600');
quizQuestions.forEach((question, index) => {
const container = document.getElementById(`question-container-${index}`);
const selected = document.querySelector(`input[name="q${index}"]:checked`);
container.classList.remove('incorrect');
if (!selected || selected.value !== question.answer) {
allCorrect = false;
container.classList.add('incorrect');
}
});
if (allCorrect) {
quizFeedback.textContent = '太棒了!你很用心在看故事喔!';
quizFeedback.classList.add('text-green-600');
submitQuizButton.disabled = true;
rereadStoryButton.disabled = true;
setTimeout(() => {
quizView.classList.add('hidden');
gameView.classList.remove('hidden');
}, 2000);
} else {
quizFeedback.textContent = '有題目答錯了,再檢查看看或重讀一次故事吧!';
quizFeedback.classList.add('text-red-500');
}
}
// --- 事件監聽 ---
startQuizButton.addEventListener('click', () => {
storyView.classList.add('hidden');
quizView.classList.remove('hidden');
submitQuizButton.disabled = false;
rereadStoryButton.disabled = false;
quizFeedback.textContent = '';
quizQuestions.forEach((_, index) => {
document.getElementById(`question-container-${index}`).classList.remove('incorrect');
});
});
rereadStoryButton.addEventListener('click', () => {
quizView.classList.add('hidden');
storyView.classList.remove('hidden');
});
submitQuizButton.addEventListener('click', checkQuiz);
valueSlider.addEventListener('input', updateSliderDisplay);
checkButton.addEventListener('click', checkAnswer);
nextLevelButton.addEventListener('click', loadNext);
// --- 初始啟動 ---
initLevel(currentLevel);
});
</script>
</body>
</html>