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 (
學習建構互動機關門、按鈕觸發、透明效果與數學題答題系統
本課程將帶領學習者建構一個互動機關門系統,包含按鈕觸發、透明門效果與數學題答題機制。通過實際操作,學習者將掌握 Roblox Studio 中的互動機制設計、UI 創建與程式控制等進階技能。
根據測試結果調整 ButtonScript 腳本中的參數:
在本課程中,我們成功建構了一個互動機關門系統,包含按鈕觸發、透明門效果與數學題答題機制。通過這個項目,學習者掌握了 Roblox Studio 中的互動機制設計、UI 創建與程式控制等進階技能。
這些技能可以應用於更複雜的遊戲開發項目,例如解謎遊戲、教育類遊戲、互動式學習環境、技能挑戰系統等。
想要進一步提升您的互動機關系統?嘗試以下挑戰: