玩家现在可以收集硬币并在死亡时失去它们,但硬币无法做任何事情,大部分游戏世界无法通过跳跃很高的能力访问。本教程的这一部分教你如何通过添加屏幕上的按钮来完成体验的逻辑,该按钮花费金币来提高跳跃力。
创建升级按钮
Roblox 中的 2D 界面通常由一个 GUI 容器内的一组 GUI 组件组成。在这种情况下,您只需要一个 组件,该组件内部说明 升级跳跃(5 枚硬币) 在一个 容器中。
要创建 GUI:
- 在 资源管理器 窗口中,添加一个新文件夹到 ReplicatedStorage ,然后将文件夹重命名为 实例 。 复制存储 中的任何对象都可以访问每个玩家的 Roblox 客户端,这是显示用户界面的地方。
- 将 ScreenGui 对象添加到 实例 文件夹。
- 选择 ScreenGui 对象,然后在 属性 窗口中,
- 将 名称 设置为 JumpPurchaseGui 。
- 禁用 重置在生成时 以确保在玩家重生时保持图形用户界面的父级地位。
- 在 探索器 窗口中,将 文本按钮 插入 JumpPurchaseGui 容器中,然后将文本按钮重命名为 跳跃按钮 。
- (可选) 通过配置按钮的属性来自定义按钮的外观和位置。简单的建议包括:
- 将 文本 属性设置为 升级跳跃 (5 枚金币) .
- 将 文本大小 属性设置为 25。
- 将 锚点 设置为 1, 1 和 位置 为 {1, 0},{1, 0} 移动按钮到右下角。
在本教程中稍后添加按钮到玩家的 GUI,但在此之前,您需要定义所有必需的逻辑和数据,以便按钮正常运行。
定义跳跃力数据
目前,只有硬币数量在 PlayerData 模块脚本中存储给每个玩家。您还需要以同样的方式存储和更新跳跃力。因为 PlayerData 中的函数不特定于正在更改的数据,所有需要存储玩家跳跃力的都是添加 Jump 键并在 DEFAULT_PLAYER_DATA 中初始化其初始值。
要更新 PlayerData 模块脚本以存储跳跃力:
在 浏览器 窗口中,在 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 能够跟踪跳跃力,你需要在服务器上实现从玩家客户端请求升级跳跃力的逻辑。
服务器和客户端可以通过 远程事件 或 远程函数 进行通信。远程事件在发射时不会产生,且适合单向通信。远程函数会持续返回直到收到回复,这使得双向通信成为可能。在这种情况下,客户端需要知道服务器是否成功升级了玩家的跳跃力,因此远程函数是理想的。
要实现跳跃升级:
在 浏览器 窗口中,在 ReplicatedStorage 中打开 实例 文件夹。
将 远程函数 插入到 实例 文件夹,然后将远程函数重命名为 增加跳跃力函数 。你总是在 复制存储 中创建远程函数,因为客户端和服务器都必须能够访问它们。
在 资源管理器 窗口中,选择 启动玩家 。
在 属性 窗口中,启用 字符使用跳跃力 属性。默认情况下,角色的跳跃力值不定义角色跳跃的数量,因此需要启用。
在 浏览器 窗口中,插入新脚本到 ServerScriptService ,然后将脚本重命名为 JumpService 。该脚本将包含跳跃升级的逻辑。
将默认代码替换为以下验证码:
-- 服务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 并实现按下时的行为。
要将按钮添加到玩家的 GUI 当他们加入时:
在 资源管理器 窗口中,在 ReplicatedStorage 中创建一个 脚本 。
选择脚本,然后在 属性 窗口中,
- 将 名称 设置为 JumpButtonClickHandler 。
- 将 运行上下文 设置为 客户端 。这告诉引擎始终在客户端运行此脚本以优化网络通信。
在打开的脚本中,将默认代码替换为以下验证码:
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-- 购买将是错误消息,如果成功为 falseerror(purchased)elseif success and not purchased thenwarn("Not enough coins!")endendjumpButton.Activated:Connect(onButtonClicked)-- 将 JumpPurchaseGui 添加到玩家的 GuijumpPurchaseGui.Parent = playerGui代码说明以下部分更详细地描述了代码。
- 获得对图形用户界面和服务器函数的引用 - 变量 IncreaseJumpPowerFunction , jumpPurchaseGui 和 jumpButton 包含对需要稍后调用的函数和图形用户界面的引用。
- 定义事件处理器 - onButtonClicked() 定义用户单击升级按钮时的逻辑。它使用 pcall() (保护呼叫) 来调用 RemoteFunction。任何客户端-服务器通信像这样都需要 pcall() 来处理错误或连接问题。
- 将处理器连接到按钮 - 所有平台,包括鼠标、触摸屏或游戏手柄上的 Activated 事件都兼容。当单击 , 触摸 , 或游戏手柄按钮 被释放时触发
游戏测试
你现在应该能够使用升级按钮购买硬币跳级升级。要测试项目:
在工具栏中,单击 播放 按钮。Studio 进入游戏测试模式。
如果你的脚本正常运行,屏幕上会出现购买跳跃力的按钮。尝试在收集任何硬币之前单击按钮以检查它是否没有奖励你额外的跳跃力,然后尝试收集一些硬币并看看升级在你再次单击时是否工作。
现在代码已完成,尝试通过硬币的数量和位置来平衡游戏。如果游戏感觉太慢,请添加更多硬币;如果感觉太快和容易,请减少硬币并将它们放在挑战性的地方。