玩家現在可以收集硬幣,並在死亡時失去它們,但這些硬幣沒有任何作用,而遊戲世界的大部分區域在沒有能夠跳得很高的能力的情況下是無法進入的。本教程的這一部分教你如何完成你體驗的邏輯,通過添加一個在螢幕上的按鈕來花費硬幣來增加跳躍能力。
創建升級按鈕
Roblox 的 2D 界面通常由一組 GUI 組件組成,這些組件位於一個 GUI 容器內。在這種情況下,你只需要一個 TextButton 組件,顯示 升級跳躍 (5 硬幣),放置在 ScreenGui 容器內。
要創建 GUI:
- 在 Explorer 窗口中,向 ReplicatedStorage 添加一個新的文件夾,然後將該文件夾更名為 Instances。 任何在 ReplicatedStorage 中的物件都可以被每個玩家的 Roblox 客戶端訪問,這就是 GUIs 被顯示的地方。
- 在 Instances 文件夾中添加一個 ScreenGui 物件。
- 選擇 ScreenGui 物件,然後在 Properties 窗口中,
- 將 Name 設置為 JumpPurchaseGui。
- 禁用 ResetOnSpawn 以確保 GUI 在玩家重生時仍然保留在父物件下。
- 在 Explorer 窗口中,將一個 TextButton 插入到 JumpPurchaseGui 容器中,然後將文本按鈕重新命名為 JumpButton。
- (可選) 透過配置其屬性來自訂按鈕的外觀和位置。簡單的建議包括:
- 將 Text 屬性設置為 升級跳躍 (5 硬幣)。
- 將 TextSize 屬性設置為 25。
- 將 AnchorPoint 設置為 1, 1 並將 Position 設置為 {1, 0},{1, 0} 以將按鈕移到右下角。
你稍後將按鈕添加到玩家的 GUI 中,但在此之前,你需要定義按鈕運作所需的所有邏輯和數據。
定義跳躍能力數據
目前,每玩家的硬幣數量僅儲存在 PlayerData 模組腳本中。你還需要以相同的方式儲存和更新跳躍能力。由於 PlayerData 中的函數與所更改的數據並無特定關係,因此只需在 DEFAULT_PLAYER_DATA 中添加一個 Jump 鍵並初始化其初始值即可存儲玩家的跳躍能力。
要更新 PlayerData 模組腳本以儲存跳躍能力:
在 Explorer 窗口中,打開 ServerStorage 中的 PlayerData 模組腳本。
用以下示例代碼替換腳本中的代碼,這將為每個玩家初始化一個 Jump 值及其現有的 Coins 值:
local PlayerData = {}PlayerData.COIN_KEY_NAME = "Coins"PlayerData.JUMP_KEY_NAME = "Jump"local playerData = {--[[[userId: string] = {["Coins"] = coinAmount: number,["Jump"] = jumpPower: number}--]]}local DEFAULT_PLAYER_DATA = {[PlayerData.COIN_KEY_NAME] = 0,[PlayerData.JUMP_KEY_NAME] = 0,}local function getData(player)local data = playerData[tostring(player.UserId)] or DEFAULT_PLAYER_DATAplayerData[tostring(player.UserId)] = datareturn dataendfunction PlayerData.getValue(player, key)return getData(player)[key]endfunction PlayerData.updateValue(player, key, updateFunction)local data = getData(player)local oldValue = data[key]local newValue = updateFunction(oldValue)data[key] = newValuereturn newValueendreturn PlayerData
更新跳躍能力數據
現在 PlayerData 能跟踪跳躍能力,你需要在伺服器上實現邏輯,以根據玩家的客戶端請求來升級跳躍能力。
伺服器和客戶端可以通過 Remote events 或 Remote functions 進行通信。當遠端事件觸發時不會等待,適合單向通信。而遠端函數會等待直到收到回覆,這允許雙向通信。在這種情況下,客戶端需要知道伺服器是否成功升級了玩家的跳躍能力,因此遠端函數是理想的選擇。
要實施跳躍升級:
在 Explorer 窗口中,打開 ReplicatedStorage 中的 Instances 文件夾。
在 Instances 文件夾中插入一個 RemoteFunction,然後將該遠端函數重新命名為 IncreaseJumpPowerFunction。你應該一直在 ReplicatedStorage 中創建遠端函數,因為客戶端和伺服器都必須能夠訪問它們。
在 Explorer 窗口中,選擇 StarterPlayer。
在 Properties 窗口中,啟用 CharacterUseJumpPower 屬性。默認情況下,角色的跳躍能力值不會定義角色的跳躍高度,因此這需要被啟用。
在 Explorer 窗口中,在 ServerScriptService 中插入一個新腳本,然後將該腳本重新命名為 JumpService。該腳本將包含跳躍升級的邏輯。
用以下代碼替換默認代碼:
-- Serviceslocal ReplicatedStorage = game:GetService("ReplicatedStorage")local ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Moduleslocal Leaderboard = require(ServerStorage.Leaderboard)local PlayerData = require(ServerStorage.PlayerData)-- Eventslocal IncreaseJumpPowerFunction = ReplicatedStorage.Instances.IncreaseJumpPowerFunctionlocal JUMP_KEY_NAME = PlayerData.JUMP_KEY_NAMElocal COIN_KEY_NAME = PlayerData.COIN_KEY_NAMElocal JUMP_POWER_INCREMENT = 30local JUMP_COIN_COST = 5local function updateJumpPower(player, updateFunction)-- 更新跳躍能力表local newJumpPower = PlayerData.updateValue(player, JUMP_KEY_NAME, updateFunction)-- 更新玩家的跳躍能力local character = player.Character or player.CharacterAdded:Wait()local humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.JumpPower = newJumpPower-- 更新跳躍排行榜Leaderboard.setStat(player, JUMP_KEY_NAME, newJumpPower)endendlocal function onPurchaseJumpIncrease(player)local coinAmount = PlayerData.getValue(player, COIN_KEY_NAME)if coinAmount < JUMP_COIN_COST thenreturn falseend-- 增加玩家的跳躍能力updateJumpPower(player, function(oldJumpPower)oldJumpPower = oldJumpPower or 0return oldJumpPower + JUMP_POWER_INCREMENTend)-- 更新硬幣表local newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, function(oldCoinAmount)return oldCoinAmount - JUMP_COIN_COSTend)-- 更新硬幣排行榜Leaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)return trueendlocal function onCharacterAdded(player)-- 當角色被添加時重置玩家的跳躍能力updateJumpPower(player, function(_)return 0end)end-- 初始化在連接到 PlayerAdded 事件之前添加的任何玩家for _, player in Players:GetPlayers() doonCharacterAdded(player)end-- 通常從 PlayerAdded 事件初始化玩家local function onPlayerAdded(player)player.CharacterAdded:Connect(function()onCharacterAdded(player)end)endlocal function onPlayerRemoved(player)updateJumpPower(player, function(_)return nilend)endIncreaseJumpPowerFunction.OnServerInvoke = onPurchaseJumpIncreasePlayers.PlayerAdded:Connect(onPlayerAdded)Players.PlayerRemoving:Connect(onPlayerRemoved)
將按鈕添加到玩家 GUI
只有當 ScreenGui 物件被設為玩家的 PlayerGui 物件的父物件時,它才會顯示在螢幕上。默認情況下,這包含系統 GUI,例如聊天窗口。現在,你需要在 ReplicatedStorage 中創建一個腳本,將升級按鈕複製到每個玩家的 GUI 中,並實現按壓時的行為。
要在玩家加入時將按鈕添加到他們的 GUI 中:
在 Explorer 窗口中,在 ReplicatedStorage 中創建一個 Script。
選擇該腳本,然後在 Properties 窗口中,
- 將 Name 設置為 JumpButtonClickHandler。
- 將 RunContext 設置為 Client。這告訴引擎始終在客戶端運行此腳本以優化網絡通信。
在打開的腳本中,用以下代碼替換默認代碼:
local ReplicatedStorage = game:GetService("ReplicatedStorage")local Players = game:GetService("Players")local player = Players.LocalPlayerlocal playerGui = player.PlayerGuilocal IncreaseJumpPowerFunction = ReplicatedStorage.Instances.IncreaseJumpPowerFunctionlocal jumpPurchaseGui = ReplicatedStorage.Instances.JumpPurchaseGuilocal jumpButton = jumpPurchaseGui.JumpButtonlocal function onButtonClicked()local success, purchased = pcall(IncreaseJumpPowerFunction.InvokeServer, IncreaseJumpPowerFunction)if not success then-- purchased 將成為錯誤消息如果 success 為 falseerror(purchased)elseif success and not purchased thenwarn("硬幣不足!")endendjumpButton.Activated:Connect(onButtonClicked)-- 將 JumpPurchaseGui 添加到玩家的 GUIjumpPurchaseGui.Parent = playerGui代碼解釋以下部分將更詳細說明代碼。
- 獲取對 GUI 和伺服器函數的引用 - 變量 IncreaseJumpPowerFunction、jumpPurchaseGui 和 jumpButton 包含對調用該函數所需的函數和 GUI 的引用。
- 定義事件處理器 - onButtonClicked() 定義了用戶點擊升級按鈕時的邏輯。它使用 pcall() (保護調用)來調用 RemoteFunction。任何這樣的客戶端-伺服器通信都需要 pcall() 來處理錯誤或連接問題。
測試
你現在應該能夠使用升級按鈕用硬幣購買跳躍升級。要測試該項目:
在工具欄中,單擊 播放 按鈕。Studio 進入測試模式。
如果你的腳本正常運行,則將在螢幕上顯示一個用於購買跳躍能力的按鈕。嘗試在你收集任何硬幣之前單擊該按鈕,以檢查它是否不會獎勵你額外的跳躍能力,然後嘗試收集一些硬幣,看看當你再次單擊時升級是否有效。
現在代碼已經完成,試著通過硬幣的數量和位置來平衡遊戲。如果遊戲感覺太慢,可以添加更多的硬幣;如果感覺太快且太容易,可以減少硬幣並將其放置在挑戰性的位置。