Spaces:
Sleeping
Sleeping
| import { useState } from 'react'; | |
| import { motion } from 'framer-motion'; | |
| import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; | |
| import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism'; | |
| const buttonInteractionScript = ` | |
| -- 按鈕互動腳本 | |
| -- 獲取按鈕模型及其組件 | |
| local button = script.Parent | |
| local buttonTop = button:WaitForChild("ButtonTop") -- 按鈕頂部可互動部分 | |
| local door = workspace:WaitForChild("Door") -- 門模型 | |
| local doorPanel = door:WaitForChild("DoorPanel") -- 門板 | |
| -- 按鈕狀態變數 | |
| local isPressed = false | |
| local cooldownTime = 1 -- 按鈕冷卻時間(秒) | |
| local isCooldown = false | |
| -- 按鈕視覺效果設置 | |
| local defaultColor = Color3.fromRGB(255, 0, 0) -- 紅色 | |
| local pressedColor = Color3.fromRGB(0, 255, 0) -- 綠色 | |
| local defaultPosition = buttonTop.Position | |
| local pressedPosition = defaultPosition - Vector3.new(0, 0.2, 0) -- 按下時下降0.2個單位 | |
| -- 門的狀態變數 | |
| local doorTransparency = 0.8 -- 透明狀態的透明度值 | |
| local doorTransitionTime = 1 -- 門變透明的過渡時間(秒) | |
| local doorOpenTime = 30 -- 門保持透明的時間(秒) | |
| -- 按鈕按下效果函數 | |
| local function pressButton() | |
| if isCooldown then return end | |
| -- 設置冷卻狀態 | |
| isCooldown = true | |
| isPressed = true | |
| -- 播放按鈕按下音效(可選) | |
| local sound = Instance.new("Sound") | |
| sound.SoundId = "rbxassetid://142376088" -- 按鈕音效ID | |
| sound.Volume = 0.5 | |
| sound.Parent = button | |
| sound:Play() | |
| -- 按鈕視覺效果 | |
| buttonTop.Color = pressedColor | |
| buttonTop.Position = pressedPosition | |
| -- 觸發門變透明 | |
| makeDoorTransparent() | |
| -- 按鈕恢復 | |
| wait(cooldownTime) | |
| buttonTop.Color = defaultColor | |
| buttonTop.Position = defaultPosition | |
| isPressed = false | |
| isCooldown = false | |
| end | |
| -- 使門變透明的函數 | |
| function makeDoorTransparent() | |
| -- 創建過渡效果 | |
| local startTime = tick() | |
| local initialTransparency = doorPanel.Transparency | |
| -- 漸變透明度 | |
| while tick() - startTime < doorTransitionTime do | |
| local alpha = (tick() - startTime) / doorTransitionTime | |
| doorPanel.Transparency = initialTransparency * (1 - alpha) + doorTransparency * alpha | |
| wait() | |
| end | |
| -- 確保最終透明度正確 | |
| doorPanel.Transparency = doorTransparency | |
| -- 門變為可穿透(但仍然可見) | |
| doorPanel.CanCollide = false | |
| -- 添加發光效果(可選) | |
| local highlight = Instance.new("Highlight") | |
| highlight.FillColor = Color3.fromRGB(0, 200, 255) | |
| highlight.OutlineColor = Color3.fromRGB(0, 100, 255) | |
| highlight.FillTransparency = 0.5 | |
| highlight.Parent = doorPanel | |
| -- 設置計時器,讓門在一段時間後恢復 | |
| wait(doorOpenTime) | |
| -- 如果沒有被數學題系統覆蓋,則恢復門的狀態 | |
| if doorPanel.Transparency == doorTransparency then | |
| -- 漸變回不透明 | |
| startTime = tick() | |
| while tick() - startTime < doorTransitionTime do | |
| local alpha = (tick() - startTime) / doorTransitionTime | |
| doorPanel.Transparency = doorTransparency * (1 - alpha) + initialTransparency * alpha | |
| wait() | |
| end | |
| -- 恢復門的碰撞 | |
| doorPanel.Transparency = initialTransparency | |
| doorPanel.CanCollide = true | |
| -- 移除發光效果 | |
| if highlight and highlight.Parent then | |
| highlight:Destroy() | |
| end | |
| end | |
| end | |
| -- 設置按鈕觸發 | |
| buttonTop.Touched:Connect(function(hit) | |
| -- 檢查是否是玩家角色的一部分 | |
| local humanoid = hit.Parent:FindFirstChild("Humanoid") | |
| if humanoid and not isPressed then | |
| pressButton() | |
| end | |
| end) | |
| print("按鈕互動腳本已加載!") | |
| `; | |
| const doorMathInteractionScript = ` | |
| -- 透明門與數學題互動腳本 | |
| -- 獲取門板及相關組件 | |
| local doorPanel = script.Parent | |
| local door = doorPanel.Parent | |
| -- 數學題相關變數 | |
| local mathProblemActive = false | |
| local currentAnswer = 0 | |
| local currentProblem = "" | |
| -- 服務引用 | |
| local Players = game:GetService("Players") | |
| local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
| -- 創建遠端事件用於UI更新 | |
| local mathProblemEvent = Instance.new("RemoteEvent") | |
| mathProblemEvent.Name = "MathProblemEvent" | |
| mathProblemEvent.Parent = ReplicatedStorage | |
| -- 生成二位數乘法題目 | |
| local function generateMathProblem() | |
| -- 生成兩個10-99之間的隨機數 | |
| local num1 = math.random(10, 99) | |
| local num2 = math.random(10, 99) | |
| -- 計算答案 | |
| local answer = num1 * num2 | |
| -- 創建題目字串 | |
| local problem = num1 .. " × " .. num2 .. " = ?" | |
| return problem, answer | |
| end | |
| -- 創建數學題UI | |
| local function createMathProblemUI(player) | |
| -- 創建ScreenGui | |
| local mathGui = Instance.new("ScreenGui") | |
| mathGui.Name = "MathProblemGui" | |
| -- 創建主框架 | |
| local frame = Instance.new("Frame") | |
| frame.Size = UDim2.new(0, 300, 0, 200) | |
| frame.Position = UDim2.new(0.5, -150, 0.5, -100) | |
| frame.BackgroundColor3 = Color3.fromRGB(50, 50, 50) | |
| frame.BorderSizePixel = 2 | |
| frame.BorderColor3 = Color3.fromRGB(255, 255, 255) | |
| frame.Parent = mathGui | |
| -- 創建標題 | |
| local titleLabel = Instance.new("TextLabel") | |
| titleLabel.Size = UDim2.new(1, 0, 0.2, 0) | |
| titleLabel.Position = UDim2.new(0, 0, 0, 0) | |
| titleLabel.BackgroundTransparency = 1 | |
| titleLabel.TextColor3 = Color3.fromRGB(255, 255, 255) | |
| titleLabel.TextSize = 24 | |
| titleLabel.Font = Enum.Font.SourceSansBold | |
| titleLabel.Text = "解答數學題以通過門" | |
| titleLabel.Parent = frame | |
| -- 創建問題標籤 | |
| local problemLabel = Instance.new("TextLabel") | |
| problemLabel.Size = UDim2.new(1, 0, 0.3, 0) | |
| problemLabel.Position = UDim2.new(0, 0, 0.2, 0) | |
| problemLabel.BackgroundTransparency = 1 | |
| problemLabel.TextColor3 = Color3.fromRGB(255, 255, 255) | |
| problemLabel.TextSize = 36 | |
| problemLabel.Font = Enum.Font.SourceSansBold | |
| problemLabel.Name = "ProblemLabel" | |
| problemLabel.Text = currentProblem | |
| problemLabel.Parent = frame | |
| -- 創建答案輸入框 | |
| local answerBox = Instance.new("TextBox") | |
| answerBox.Size = UDim2.new(0.6, 0, 0.2, 0) | |
| answerBox.Position = UDim2.new(0.2, 0, 0.5, 0) | |
| answerBox.BackgroundColor3 = Color3.fromRGB(255, 255, 255) | |
| answerBox.TextColor3 = Color3.fromRGB(0, 0, 0) | |
| answerBox.TextSize = 24 | |
| answerBox.Font = Enum.Font.SourceSans | |
| answerBox.PlaceholderText = "輸入答案..." | |
| answerBox.Text = "" | |
| answerBox.Name = "AnswerBox" | |
| answerBox.ClearTextOnFocus = true | |
| answerBox.Parent = frame | |
| -- 創建提交按鈕 | |
| local submitButton = Instance.new("TextButton") | |
| submitButton.Size = UDim2.new(0.4, 0, 0.15, 0) | |
| submitButton.Position = UDim2.new(0.3, 0, 0.75, 0) | |
| submitButton.BackgroundColor3 = Color3.fromRGB(0, 150, 255) | |
| submitButton.TextColor3 = Color3.fromRGB(255, 255, 255) | |
| submitButton.TextSize = 20 | |
| submitButton.Font = Enum.Font.SourceSansBold | |
| submitButton.Text = "提交答案" | |
| submitButton.Name = "SubmitButton" | |
| submitButton.Parent = frame | |
| -- 創建結果標籤 | |
| local resultLabel = Instance.new("TextLabel") | |
| resultLabel.Size = UDim2.new(1, 0, 0.1, 0) | |
| resultLabel.Position = UDim2.new(0, 0, 0.9, 0) | |
| resultLabel.BackgroundTransparency = 1 | |
| resultLabel.TextColor3 = Color3.fromRGB(255, 255, 255) | |
| resultLabel.TextSize = 18 | |
| resultLabel.Font = Enum.Font.SourceSans | |
| resultLabel.Name = "ResultLabel" | |
| resultLabel.Text = "" | |
| resultLabel.Parent = frame | |
| -- 將UI添加到玩家的PlayerGui | |
| mathGui.Parent = player.PlayerGui | |
| -- 創建本地腳本處理UI交互 | |
| local localScript = Instance.new("LocalScript") | |
| localScript.Parent = mathGui | |
| localScript.Source = [[ | |
| local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
| local mathProblemEvent = ReplicatedStorage:WaitForChild("MathProblemEvent") | |
| local player = game.Players.LocalPlayer | |
| local gui = script.Parent | |
| local frame = gui:WaitForChild("Frame") | |
| local submitButton = frame:WaitForChild("SubmitButton") | |
| local answerBox = frame:WaitForChild("AnswerBox") | |
| local resultLabel = frame:WaitForChild("ResultLabel") | |
| -- 提交答案 | |
| local function submitAnswer() | |
| local answer = tonumber(answerBox.Text) | |
| if answer then | |
| mathProblemEvent:FireServer(answer) | |
| else | |
| resultLabel.Text = "請輸入有效的數字!" | |
| resultLabel.TextColor3 = Color3.fromRGB(255, 100, 100) | |
| end | |
| end | |
| -- 連接提交按鈕 | |
| submitButton.MouseButton1Click:Connect(submitAnswer) | |
| -- 按Enter鍵也可提交 | |
| answerBox.FocusLost:Connect(function(enterPressed) | |
| if enterPressed then | |
| submitAnswer() | |
| end | |
| end) | |
| -- 處理服務器回應 | |
| mathProblemEvent.OnClientEvent:Connect(function(action, message) | |
| if action == "result" then | |
| resultLabel.Text = message | |
| if message:find("正確") then | |
| resultLabel.TextColor3 = Color3.fromRGB(100, 255, 100) | |
| -- 答對後關閉UI | |
| wait(1.5) | |
| gui:Destroy() | |
| else | |
| resultLabel.TextColor3 = Color3.fromRGB(255, 100, 100) | |
| -- 清空輸入框 | |
| answerBox.Text = "" | |
| end | |
| elseif action == "close" then | |
| -- 關閉UI | |
| gui:Destroy() | |
| end | |
| end) | |
| ]] | |
| return mathGui | |
| end | |
| -- 處理玩家碰觸透明門 | |
| doorPanel.Touched:Connect(function(hit) | |
| -- 確保門是透明狀態 | |
| if doorPanel.Transparency < 0.5 then return end | |
| -- 檢查是否是玩家角色的一部分 | |
| local character = hit.Parent | |
| local player = Players:GetPlayerFromCharacter(character) | |
| if player and not mathProblemActive then | |
| -- 防止多次觸發 | |
| mathProblemActive = true | |
| -- 生成數學題 | |
| currentProblem, currentAnswer = generateMathProblem() | |
| -- 創建並顯示數學題UI | |
| createMathProblemUI(player) | |
| -- 發送題目到客戶端 | |
| mathProblemEvent:FireClient(player, "problem", currentProblem) | |
| end | |
| end) | |
| -- 處理玩家答題 | |
| mathProblemEvent.OnServerEvent:Connect(function(player, answer) | |
| if answer == currentAnswer then | |
| -- 答案正確 | |
| mathProblemEvent:FireClient(player, "result", "正確!門已開啟。") | |
| -- 允許玩家通過門 | |
| local character = player.Character | |
| if character then | |
| -- 創建一個臨時的無碰撞區域,只對這個玩家有效 | |
| local noCollisionPart = Instance.new("Part") | |
| noCollisionPart.Size = doorPanel.Size | |
| noCollisionPart.CFrame = doorPanel.CFrame | |
| noCollisionPart.Transparency = 1 | |
| noCollisionPart.CanCollide = false | |
| noCollisionPart.Anchored = true | |
| noCollisionPart.Parent = workspace | |
| -- 設置門完全透明(對這個玩家) | |
| local tempHighlight = Instance.new("Highlight") | |
| tempHighlight.FillColor = Color3.fromRGB(0, 255, 100) | |
| tempHighlight.OutlineColor = Color3.fromRGB(0, 200, 50) | |
| tempHighlight.FillTransparency = 0.7 | |
| tempHighlight.Parent = doorPanel | |
| -- 5秒後恢復 | |
| wait(5) | |
| if noCollisionPart and noCollisionPart.Parent then | |
| noCollisionPart:Destroy() | |
| end | |
| if tempHighlight and tempHighlight.Parent then | |
| tempHighlight:Destroy() | |
| end | |
| end | |
| else | |
| -- 答案錯誤 | |
| mathProblemEvent:FireClient(player, "result", "錯誤!請再試一次。") | |
| end | |
| -- 重置狀態,允許再次觸發 | |
| wait(2) | |
| mathProblemActive = false | |
| end) | |
| print("透明門與數學題互動腳本已加載!") | |
| `; | |
| export default function Lesson3Page() { | |
| const [activeSection, setActiveSection] = useState('intro'); | |
| const scrollToSection = (sectionId: string) => { | |
| setActiveSection(sectionId); | |
| const element = document.getElementById(sectionId); | |
| if (element) { | |
| element.scrollIntoView({ behavior: 'smooth' }); | |
| } | |
| }; | |
| return ( | |
| <div className="flex flex-col md:flex-row gap-6"> | |
| {/* Sidebar Navigation */} | |
| <div className="md:w-1/4 lg:w-1/5"> | |
| <div className="bg-white rounded-xl shadow-md p-6 sticky top-24"> | |
| <h3 className="text-lg font-bold text-gray-800 mb-4">課程目錄</h3> | |
| <nav className="space-y-2"> | |
| <button | |
| onClick={() => scrollToSection('intro')} | |
| className={`w-full text-left px-3 py-2 rounded-md text-sm font-medium transition-colors ${ | |
| activeSection === 'intro' | |
| ? 'bg-purple-100 text-purple-700' | |
| : 'text-gray-600 hover:bg-gray-100' | |
| }`} | |
| > | |
| 課程簡介 | |
| </button> | |
| <button | |
| onClick={() => scrollToSection('part1')} | |
| className={`w-full text-left px-3 py-2 rounded-md text-sm font-medium transition-colors ${ | |
| activeSection === 'part1' | |
| ? 'bg-purple-100 text-purple-700' | |
| : 'text-gray-600 hover:bg-gray-100' | |
| }`} | |
| > | |
| 機關門模型建構 | |
| </button> | |
| <button | |
| onClick={() => scrollToSection('part2')} | |
| className={`w-full text-left px-3 py-2 rounded-md text-sm font-medium transition-colors ${ | |
| activeSection === 'part2' | |
| ? 'bg-purple-100 text-purple-700' | |
| : 'text-gray-600 hover:bg-gray-100' | |
| }`} | |
| > | |
| 按鈕互動機制 | |
| </button> | |
| <button | |
| onClick={() => scrollToSection('part3')} | |
| className={`w-full text-left px-3 py-2 rounded-md text-sm font-medium transition-colors ${ | |
| activeSection === 'part3' | |
| ? 'bg-purple-100 text-purple-700' | |
| : 'text-gray-600 hover:bg-gray-100' | |
| }`} | |
| > | |
| 數學題互動系統 | |
| </button> | |
| <button | |
| onClick={() => scrollToSection('part4')} | |
| className={`w-full text-left px-3 py-2 rounded-md text-sm font-medium transition-colors ${ | |
| activeSection === 'part4' | |
| ? 'bg-purple-100 text-purple-700' | |
| : 'text-gray-600 hover:bg-gray-100' | |
| }`} | |
| > | |
| 優化與擴展 | |
| </button> | |
| <button | |
| onClick={() => scrollToSection('part5')} | |
| className={`w-full text-left px-3 py-2 rounded-md text-sm font-medium transition-colors ${ | |
| activeSection === 'part5' | |
| ? 'bg-purple-100 text-purple-700' | |
| : 'text-gray-600 hover:bg-gray-100' | |
| }`} | |
| > | |
| 匯出與分享 | |
| </button> | |
| <button | |
| onClick={() => scrollToSection('summary')} | |
| className={`w-full text-left px-3 py-2 rounded-md text-sm font-medium transition-colors ${ | |
| activeSection === 'summary' | |
| ? 'bg-purple-100 text-purple-700' | |
| : 'text-gray-600 hover:bg-gray-100' | |
| }`} | |
| > | |
| 總結與挑戰 | |
| </button> | |
| </nav> | |
| </div> | |
| </div> | |
| {/* Main Content */} | |
| <div className="md:w-3/4 lg:w-4/5"> | |
| <motion.div | |
| initial={{ opacity: 0 }} | |
| animate={{ opacity: 1 }} | |
| transition={{ duration: 0.5 }} | |
| > | |
| <div className="bg-gradient-to-r from-purple-600 to-indigo-600 rounded-xl p-8 mb-8 text-white"> | |
| <h1 className="text-3xl md:text-4xl font-bold mb-4">Roblox 基礎入門第三課 - 遊戲互動學習:機關門與數學題互動</h1> | |
| <p className="text-lg opacity-90"> | |
| 學習建構互動機關門、按鈕觸發、透明效果與數學題答題系統 | |
| </p> | |
| </div> | |
| {/* Course Introduction */} | |
| <section id="intro" className="mb-12 scroll-mt-24"> | |
| <h2 className="text-2xl font-bold text-gray-800 mb-4">課程簡介</h2> | |
| <div className="bg-white rounded-xl shadow-md p-6"> | |
| <p className="text-gray-700 mb-4"> | |
| 本課程將帶領學習者建構一個互動機關門系統,包含按鈕觸發、透明門效果與數學題答題機制。通過實際操作,學習者將掌握 Roblox Studio 中的互動機制設計、UI 創建與程式控制等進階技能。 | |
| </p> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">課程目標</h3> | |
| <ul className="list-disc pl-6 space-y-2 text-gray-700"> | |
| <li>在 Roblox Studio 中建構互動機關門模型</li> | |
| <li>設計並實現按鈕觸發機制</li> | |
| <li>編寫透明門效果控制腳本</li> | |
| <li>設計數學題生成與答題系統</li> | |
| </ul> | |
| <h3 className="text-xl font-bold text-purple-700 mt-6 mb-3">前置準備</h3> | |
| <ul className="list-disc pl-6 space-y-2 text-gray-700"> | |
| <li>已安裝最新版本的 Roblox Studio</li> | |
| <li>具備 Roblox Studio 基本操作能力(第一課內容)</li> | |
| <li>了解基本的 Lua 程式語法(第二課內容)</li> | |
| </ul> | |
| </div> | |
| </section> | |
| {/* Part 1: Door Model Construction */} | |
| <section id="part1" className="mb-12 scroll-mt-24"> | |
| <h2 className="text-2xl font-bold text-gray-800 mb-4">第一部分:機關門模型建構</h2> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 1:創建新專案</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700"> | |
| <li>打開 Roblox Studio</li> | |
| <li>選擇「基礎模板」創建新專案</li> | |
| <li>保存專案,命名為「InteractiveDoorGame」</li> | |
| </ol> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 2:建立門框架</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700 mb-4"> | |
| <li>在工作區中插入一個方塊部件(Part)</li> | |
| <li>調整門框尺寸與位置:Size: 6, 8, 0.5 (寬, 高, 厚), Position: 0, 4, 0 (X, Y, Z), 命名為「DoorFrame」</li> | |
| <li>設置門框外觀:Color: 深棕色, Material: Wood, Anchored: true</li> | |
| </ol> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 3:創建門板</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700 mb-4"> | |
| <li>插入一個方塊部件作為門板</li> | |
| <li>設置屬性:Size: 5, 7, 0.3, Position: 調整至門框內, 命名為「DoorPanel」</li> | |
| <li>設置門板外觀:Color: 淺棕色, Material: Wood, Anchored: true, CanCollide: true</li> | |
| </ol> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 4:添加門把手</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700 mb-4"> | |
| <li>插入一個圓柱體(Cylinder)作為門把手</li> | |
| <li>設置屬性:Size: 0.3, 0.3, 0.8, Position: 調整至門板側面, Orientation: 水平, 命名為「DoorHandle」</li> | |
| <li>設置門把手外觀:Color: 金色/銀色, Material: Metal, Anchored: true</li> | |
| </ol> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 5:創建按鈕</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700 mb-4"> | |
| <li>創建按鈕基座:插入方塊部件, Size: 1, 1, 0.5, Position: 門旁牆壁, 命名為「ButtonBase」</li> | |
| <li>創建按鈕頂部:插入方塊部件, Size: 0.8, 0.8, 0.3, Position: 基座前方, Color: 紅色, Material: Neon, 命名為「ButtonTop」</li> | |
| <li>設置按鈕外觀:基座顏色深灰, 確保按鈕突出</li> | |
| </ol> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 6:組織模型結構</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700 mb-4"> | |
| <li>組織門模型:選中門框、門板、門把手, 右鍵「Group」, 命名為「Door」</li> | |
| <li>組織按鈕模型:選中按鈕基座、按鈕頂部, 右鍵「Group」, 命名為「Button」</li> | |
| </ol> | |
| </div> | |
| </section> | |
| {/* Part 2: Button Interaction Mechanism */} | |
| <section id="part2" className="mb-12 scroll-mt-24"> | |
| <h2 className="text-2xl font-bold text-gray-800 mb-4">第二部分:按鈕互動機制設計</h2> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 1:創建按鈕互動腳本</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700 mb-4"> | |
| <li>在 Button 模型中添加腳本, 命名為「ButtonScript」</li> | |
| <li>編寫按鈕互動腳本(見下方代碼)</li> | |
| <li>保存腳本</li> | |
| </ol> | |
| <SyntaxHighlighter language="lua" style={vscDarkPlus} className="rounded-lg"> | |
| {buttonInteractionScript} | |
| </SyntaxHighlighter> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 2:測試按鈕互動</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700 mb-4"> | |
| <li>點擊「Play」按鈕進入測試模式</li> | |
| <li>控制角色接觸按鈕</li> | |
| <li>觀察按鈕按下效果與門變透明的過程</li> | |
| <li>點擊「Stop」按鈕退出測試模式</li> | |
| </ol> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 3:調整按鈕互動參數</h3> | |
| <p className="text-gray-700 mb-4"> | |
| 根據測試結果調整 ButtonScript 腳本中的參數: | |
| </p> | |
| <ul className="list-disc pl-6 space-y-2 text-gray-700"> | |
| <li>cooldownTime:調整按鈕冷卻時間</li> | |
| <li>doorTransparency:調整門的透明度</li> | |
| <li>doorTransitionTime:調整門變透明的過渡時間</li> | |
| <li>doorOpenTime:調整門保持透明的時間</li> | |
| </ul> | |
| </div> | |
| </section> | |
| {/* Part 3: Transparent Door & Math Problem Interaction */} | |
| <section id="part3" className="mb-12 scroll-mt-24"> | |
| <h2 className="text-2xl font-bold text-gray-800 mb-4">第三部分:透明門與數學題互動系統</h2> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 1:創建透明門互動腳本</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700 mb-4"> | |
| <li>在 DoorPanel 中添加腳本, 命名為「DoorMathScript」</li> | |
| <li>編寫透明門與數學題互動腳本(見下方代碼)</li> | |
| <li>保存腳本</li> | |
| </ol> | |
| <SyntaxHighlighter language="lua" style={vscDarkPlus} className="rounded-lg"> | |
| {doorMathInteractionScript} | |
| </SyntaxHighlighter> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 2:設置 ReplicatedStorage</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700 mb-4"> | |
| <li>確保 ReplicatedStorage 中有正確的遠端事件</li> | |
| <li>如果腳本沒有自動創建,手動創建一個 RemoteEvent</li> | |
| <li>命名為「MathProblemEvent」</li> | |
| <li>放置在 ReplicatedStorage 中</li> | |
| </ol> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 3:測試數學題互動</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700 mb-4"> | |
| <li>點擊「Play」按鈕進入測試模式</li> | |
| <li>按下按鈕使門變透明</li> | |
| <li>接觸透明門觸發數學題 UI</li> | |
| <li>測試答題功能:輸入正確/錯誤答案,觀察結果</li> | |
| <li>確認答對後門可以穿透</li> | |
| <li>點擊「Stop」按鈕退出測試模式</li> | |
| </ol> | |
| </div> | |
| </section> | |
| {/* Part 4: Optimization and Expansion */} | |
| <section id="part4" className="mb-12 scroll-mt-24"> | |
| <h2 className="text-2xl font-bold text-gray-800 mb-4">第四部分:優化與擴展</h2> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 1:添加視覺效果</h3> | |
| <ul className="list-disc pl-6 space-y-2 text-gray-700"> | |
| <li>按鈕按下效果:粒子效果、光源</li> | |
| <li>門變透明效果:過渡動畫、粒子效果</li> | |
| <li>答題成功效果:成功音效、視覺反饋</li> | |
| </ul> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 2:擴展功能</h3> | |
| <ul className="list-disc pl-6 space-y-2 text-gray-700"> | |
| <li>調整數學題難度:修改 generateMathProblem 函數,添加難度選項</li> | |
| <li>添加計時功能:設置答題時間限制,添加倒計時顯示</li> | |
| <li>添加積分系統:記錄答題正確率,顯示積分排行榜</li> | |
| </ul> | |
| </div> | |
| </section> | |
| {/* Part 5: Export and Share */} | |
| <section id="part5" className="mb-12 scroll-mt-24"> | |
| <h2 className="text-2xl font-bold text-gray-800 mb-4">第五部分:匯出與分享</h2> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 1:最終測試與調整</h3> | |
| <ul className="list-disc pl-6 space-y-2 text-gray-700"> | |
| <li>進行全面測試:按鈕、透明門、數學題、性能</li> | |
| <li>根據測試結果進行調整:優化腳本、修復問題</li> | |
| </ul> | |
| </div> | |
| <div className="bg-white rounded-xl shadow-md p-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">步驟 2:匯出專案</h3> | |
| <ol className="list-decimal pl-6 space-y-2 text-gray-700"> | |
| <li>保存專案:File {'>'}Save</li> | |
| <li>發布到 Roblox:File {'>'}Publish to Roblox</li> | |
| <li>匯出模型(可選):選中 Door 和 Button 模型, File {'>'}Export Selection</li> | |
| </ol> | |
| </div> | |
| </section> | |
| {/* Summary and Challenge */} | |
| <section id="summary" className="mb-12 scroll-mt-24"> | |
| <h2 className="text-2xl font-bold text-gray-800 mb-4">總結</h2> | |
| <div className="bg-white rounded-xl shadow-md p-6 mb-6"> | |
| <p className="text-gray-700 mb-4"> | |
| 在本課程中,我們成功建構了一個互動機關門系統,包含按鈕觸發、透明門效果與數學題答題機制。通過這個項目,學習者掌握了 Roblox Studio 中的互動機制設計、UI 創建與程式控制等進階技能。 | |
| </p> | |
| <p className="text-gray-700 mb-4"> | |
| 這些技能可以應用於更複雜的遊戲開發項目,例如解謎遊戲、教育類遊戲、互動式學習環境、技能挑戰系統等。 | |
| </p> | |
| </div> | |
| <div className="bg-gradient-to-r from-purple-50 to-indigo-50 rounded-xl shadow-md p-6 mb-6"> | |
| <h3 className="text-xl font-bold text-purple-700 mb-3">進階挑戰</h3> | |
| <p className="text-gray-700 mb-4"> | |
| 想要進一步提升您的互動機關系統?嘗試以下挑戰: | |
| </p> | |
| <ul className="list-disc pl-6 space-y-2 text-gray-700"> | |
| <li>添加多種類型的數學題(加減乘除、方程式等)</li> | |
| <li>實現難度漸進系統</li> | |
| <li>添加多人競賽模式</li> | |
| <li>創建更複雜的機關系統,如需要多個按鈕同時按下</li> | |
| <li>添加視覺化教學提示系統</li> | |
| </ul> | |
| </div> | |
| <div className="bg-gradient-to-r from-blue-50 to-purple-50 rounded-xl shadow-md p-6"> | |
| <h3 className="text-xl font-bold text-blue-700 mb-3">資源推薦</h3> | |
| <div className="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <a href="https://create.roblox.com/docs" target="_blank" rel="noopener noreferrer" className="bg-white p-4 rounded-lg shadow hover:shadow-md transition-shadow"> | |
| <h4 className="font-bold text-blue-800 mb-2">Roblox 開發者文檔</h4> | |
| <p className="text-gray-700">官方開發文檔,包含詳細的 API 參考和教程</p> | |
| </a> | |
| <a href="https://developer.roblox.com/en-us/articles/ui-design" target="_blank" rel="noopener noreferrer" className="bg-white p-4 rounded-lg shadow hover:shadow-md transition-shadow"> | |
| <h4 className="font-bold text-blue-800 mb-2">Roblox UI 設計指南</h4> | |
| <p className="text-gray-700">官方關於 UI 設計的最佳實踐和指南</p> | |
| </a> | |
| <a href="https://www.lua.org/manual/5.1/" target="_blank" rel="noopener noreferrer" className="bg-white p-4 rounded-lg shadow hover:shadow-md transition-shadow"> | |
| <h4 className="font-bold text-blue-800 mb-2">Lua 程式設計指南</h4> | |
| <p className="text-gray-700">學習 Lua 語言的官方手冊</p> | |
| </a> | |
| <a href="https://devforum.roblox.com/" target="_blank" rel="noopener noreferrer" className="bg-white p-4 rounded-lg shadow hover:shadow-md transition-shadow"> | |
| <h4 className="font-bold text-blue-800 mb-2">Roblox 開發者論壇</h4> | |
| <p className="text-gray-700">與其他開發者交流,獲取幫助和分享經驗</p> | |
| </a> | |
| </div> | |
| </div> | |
| </section> | |
| {/* Navigation Buttons */} | |
| <div className="flex justify-between mt-12"> | |
| <a | |
| href="/lesson2" | |
| className="px-6 py-3 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition-colors flex items-center" | |
| > | |
| <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor"> | |
| <path fillRule="evenodd" d="M9.707 14.707a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 1.414L7.414 9H15a1 1 0 110 2H7.414l2.293 2.293a1 1 0 010 1.414z" clipRule="evenodd" /> | |
| </svg> | |
| 上一課:賽車遊戲 | |
| </a> | |
| <a | |
| href="/lesson4" | |
| className="px-6 py-3 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors flex items-center" | |
| > | |
| 下一課:視覺化設計 | |
| <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 ml-2" viewBox="0 0 20 20" fill="currentColor"> | |
| <path fillRule="evenodd" d="M10.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L12.586 11H5a1 1 0 110-2h7.586l-2.293-2.293a1 1 0 010-1.414z" clipRule="evenodd" /> | |
| </svg> | |
| </a> | |
| </div> | |
| </motion.div> | |
| </div> | |
| </div> | |
| ); | |
| } | |