玩家現在可以收集硬幣並在死亡時失去它們,但這些硬幣沒有任何作用,並且在沒有能力跳得很高的情況下,大部分 3D 世界是無法訪問的。本教程的這一部分教你如何通過添加一個在螢幕上的按鈕來完成遊戲的邏輯,該按鈕花費硬幣來增加跳躍能力。
創建升級按鈕
Roblox 中的 2D 界面通常由一組 GUI 組件組成,這些組件位於 GUI 容器內。在這種情況下,你只需要一個 TextButton 組件,裡面顯示「升級跳躍 (5 硬幣)」的文字,並放在 ScreenGui 容器內。
在 ReplicatedStorage 中,創建一個名為 Instances 的文件夾。
在 Instances 文件夾內,創建一個名為 JumpPurchaseGui 的 ScreenGui,並禁用 ResetOnSpawn。
在 JumpPurchaseGui 內,創建一個名為 JumpButton 的 TextButton,並設置以下屬性:
- Text: "升級跳躍 (5 硬幣)"
- TextSize: 25
- AnchorPoint: 1, 1
- Position: {1, 0}, {1, 0}
在 Instances 文件夾內,還創建一個名為 IncreaseJumpPowerFunction 的 RemoteFunction。
最後,在 StarterPlayer 服務上,啟用 CharacterUseJumpPower 屬性。定義跳躍能力數據
目前,只有每個玩家的硬幣數量存儲在 PlayerData 模塊腳本中。你還需要以相同的方式存儲和更新跳躍能力。由於 PlayerData 中的函數與要更改的數據無關,因此只需添加一個 Jump 鍵並在 defaultPlayerData() 中初始化其初始值即可。
在 ServerStorage 中,將現有的 PlayerData ModuleScript 的代碼替換為以下內容:
```lua
local PlayerData = {}
PlayerData.COIN_KEY_NAME = "Coins"
PlayerData.JUMP_KEY_NAME = "Jump"
local playerData = {
--[[
[userId: string] = {
["Coins"] = coinAmount: number,
["Jump"] = jumpPower: number
}
--]]
}
local function defaultPlayerData()
return {
[PlayerData.COIN_KEY_NAME] = 0,
[PlayerData.JUMP_KEY_NAME] = 0,
}
end
local function getData(player)
local data = playerData[tostring(player.UserId)] or defaultPlayerData()
playerData[tostring(player.UserId)] = data
return data
end
function PlayerData.getValue(player, key)
return getData(player)[key]
end
function PlayerData.updateValue(player, key, updateFunction)
local data = getData(player)
local oldValue = data[key]
local newValue = updateFunction(oldValue)
data[key] = newValue
return newValue
end
return PlayerData
```更新跳躍能力數據
現在 PlayerData 能夠跟踪跳躍能力,你需要在伺服器上實現邏輯,以根據玩家的客戶端請求升級跳躍能力。
伺服器和客戶端可以通過 RemoteEvents 或 RemoteFunctions 進行通信。Remote events 在觸發時不會阻塞,並且可以用於單向通信。另一方面,Remote functions 會阻塞,直到收到回覆,這允許雙向通信。
對於本教程,客戶端需要知道伺服器是否成功升級了玩家的跳躍能力,因此你應該使用一個遠程函數。
在 ServerScriptService 中,創建一個名為 JumpService 的腳本,並使用以下代碼:
```lua
-- 服務
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- 模塊
local Leaderboard = require(ServerStorage.Leaderboard)
local PlayerData = require(ServerStorage.PlayerData)
-- 事件
local IncreaseJumpPowerFunction = ReplicatedStorage.Instances.IncreaseJumpPowerFunction
local JUMP_KEY_NAME = PlayerData.JUMP_KEY_NAME
local COIN_KEY_NAME = PlayerData.COIN_KEY_NAME
local JUMP_POWER_INCREMENT = 30
local JUMP_COIN_COST = 5
local 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 then
humanoid.JumpPower = newJumpPower
-- 更新跳躍排行榜
Leaderboard.setStat(player, JUMP_KEY_NAME, newJumpPower)
end
end
local function onPurchaseJumpIncrease(player)
local coinAmount = PlayerData.getValue(player, COIN_KEY_NAME)
if coinAmount < JUMP_COIN_COST then
return false
end
-- 增加玩家的跳躍能力
updateJumpPower(player, function(oldJumpPower)
oldJumpPower = oldJumpPower or 0
return oldJumpPower + JUMP_POWER_INCREMENT
end)
-- 更新硬幣表
local newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, function(oldCoinAmount)
return oldCoinAmount - JUMP_COIN_COST
end)
-- 更新硬幣排行榜
Leaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)
return true
end
local function onCharacterAdded(player)
-- 當角色被添加時重置玩家的跳躍能力
updateJumpPower(player, function(_)
return 0
end)
end
-- 初始化在連接到 PlayerAdded 事件之前添加的任何玩家
for _, player in Players:GetPlayers() do
onCharacterAdded(player)
end
-- 正常初始化來自 PlayerAdded 事件的玩家
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function()
onCharacterAdded(player)
end)
end
local function onPlayerRemoved(player)
updateJumpPower(player, function(_)
return nil
end)
end
IncreaseJumpPowerFunction.OnServerInvoke = onPurchaseJumpIncrease
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoved)
```將按鈕添加到玩家 GUI
ScreenGui 對象只有在其被作為玩家的 PlayerGui 對象的子項時才會顯示在螢幕上。默認情況下,這包含系統 GUI,例如聊天窗口。你現在需要在 ReplicatedStorage 中創建一個腳本,將升級按鈕複製到每個玩家的 GUI 中,並實現按下按鈕時的行為。
在 ReplicatedStorage 中,創建一個名為 JumpButtonClickHandler 的腳本,並將 RunContext 設置為 Client,然後使用以下代碼:
```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local playerGui = player.PlayerGui
local IncreaseJumpPowerFunction = ReplicatedStorage.Instances.IncreaseJumpPowerFunction
local jumpPurchaseGui = ReplicatedStorage.Instances.JumpPurchaseGui
local jumpButton = jumpPurchaseGui.JumpButton
local function onButtonClicked()
local success, purchased = pcall(IncreaseJumpPowerFunction.InvokeServer, IncreaseJumpPowerFunction)
if not success then
-- purchased 將是錯誤消息,如果成功為 false
error(purchased)
elseif success and not purchased then
warn("硬幣不足!")
end
end
jumpButton.Activated:Connect(onButtonClicked)
-- 將 JumpPurchaseGui 添加到玩家的 Gui
jumpPurchaseGui.Parent = playerGui
```以下部分將更詳細地描述代碼。
- 獲取對 GUI 和伺服器函數的引用 - 變量 IncreaseJumpPowerFunction、jumpPurchaseGui 和 jumpButton 包含對函數和 GUI 的引用,這些引用在稍後需要調用函數。
- 定義事件處理程序 - onButtonClicked() 定義了用戶單擊升級按鈕時的邏輯。它使用 pcall()(保護調用)來調用 RemoteFunction。任何這樣的客戶端-伺服器通信都需要 pcall() 來處理錯誤或連接問題。
測試遊戲
從下拉菜單中選擇 測試,然後點擊 播放。升級跳躍 按鈕會顯示在右下角。
嘗試在收集任何硬幣之前點擊按鈕,以檢查它是否不會給你額外的跳躍能力,然後嘗試收集一些硬幣,看看當你再次點擊時升級是否有效。
隨著代碼的完成,嘗試調整難度:如果節奏感覺緩慢,可以增加硬幣,或者如果升級來得太容易,可以減少一些並將它們放在更棘手的位置。