玩家现在可以收集硬币并在死亡时失去它们,但这些硬币没有任何作用,而且在没有能力跳得很高的情况下,大多数 3D 世界是无法访问的。本教程的这一部分教你如何通过添加一个在屏幕上花费硬币以增加跳跃能力的按钮,来完成你体验的逻辑。
创建升级按钮
Roblox 中的 2D 界面通常由 GUI 容器内的一组 GUI 组件组成。在这种情况下,你只需要在 ScreenGui 容器内添加一个显示“升级跳跃(5 硬币)”的 TextButton 组件。
设置升级 GUI在 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() 中初始化其初始值。
更新 PlayerData 以添加跳跃能力在 ServerStorage 中,将现有 PlayerData ModuleScript 的代码替换为以下内容:```lualocal 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,}endlocal function getData(player)local data = playerData[tostring(player.UserId)] or defaultPlayerData()playerData[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 可以跟踪跳跃能力,你需要在服务器上实现逻辑,以根据玩家的客户端请求升级跳跃能力。
服务器和客户端可以通过 RemoteEvents 或 RemoteFunctions 进行通信。远程事件在触发时不会返回,适合单向通信。另一方面,远程函数会在收到回复之前返回,从而允许双向通信。
对于本教程,客户端需要知道服务器是否成功升级了玩家的跳跃能力,因此你应该使用远程函数。
创建 JumpService在 ServerScriptService 中,创建一个名为 JumpService 的 Script,并添加以下代码:```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.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 中,并实现按钮按下后的行为。
创建 JumpButtonClickHandler在 ReplicatedStorage 中,创建一个名为 JumpButtonClickHandler 的 Script,将 RunContext 设置为 Client,并添加以下代码:```lualocal 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 将是一个错误消息,如果成功返回 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() 来处理错误或连接问题。
玩游戏测试
选择下拉菜单中的 测试,点击 播放。升级跳跃 按钮会出现在右下角。
尝试在收集任何硬币之前点击按钮,以检查它是否不会奖励你额外的跳跃能力,然后尝试收集一些硬币,看看你再次点击时升级是否能够正常工作。
代码完成后,尝试调整难度:如果节奏感觉太慢,就加一些硬币;如果升级来得太容易,就减少一些硬币并将其放在更难到达的位置。