记录和显示玩家数据

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处


现在您可以检测玩家是否收集了硬币,该教程的此部分教您如何计算玩家收集的硬币数量,并使该数量可见在排行榜上。

创建模块脚本来记录硬币收集

要处理每个玩家的硬币收集数据的存储和管理,您需要创建一个 ModuleScript 对象,包含访问硬币收集数据的每个玩家的数据结构和函数。模块脚本是其他脚本可能1) 必填 2)需要的代码重用。在这个例子中, CoinService 需要这个模块脚本,以便当玩家触摸硬币时更新硬币收集数据。

要创建模块脚本:

  1. Explorer 窗口中,将鼠标悬停在 ServerStorage 上,然后单击 按钮。一个上下文菜单显示。

  2. 从上下文菜单中,选择 ModuleScript 。 一个新的模块脚本显示在 ServerStorage 下。 您正在将模块脚本放置在 ServerStorage ,因为您想要在服务器上管理硬币收集逻辑。

    Studio's Explorer window with both the ServerScriptService's plus icon and ModuleScript object highlighted.
  3. 将模块脚本重命名为 PlayerData

    Studio's Explorer window with the PlayerData script highlighted under ServerStorage.
  4. 将以下代码替换为默认代验证码:


    local PlayerData = {}
    PlayerData.COIN_KEY_NAME = "Coins"
    local playerData = {
    -- [[
    [userId: string] = {
    ["Coins"] = coinAmount: number
    }
    ]]
    }
    local DEFAULT_PLAYER_DATA = {
    [PlayerData.COIN_KEY_NAME] = 0
    }
    local function getData(player)
    local data = playerData[tostring(player.UserId)] or DEFAULT_PLAYER_DATA
    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 表,该表包含零或多个 playerData 表,代表玩家的硬币收集数据。每个需要此模块脚本的脚本都收到相同的 PlayerData 表,允许多个脚本修改和共享硬币收集数据。

    声明数据结构

    模块脚本从一个空表的宣言开始, PlayerData ,它在脚本结束时返回。它还包含配件方法来获取和设置值在表中。

    playerData 表包含评论,描述表的结构,这使代码更容易理解。在这种情况下,playerData 表包含一个名为 userId 的字段,代表该玩家收集的硬币数量。


    local PlayerData = {}
    PlayerData.COIN_KEY_NAME = "Coins"
    local playerData = {
    -- [[
    [userId: string] = {
    ["Coins"] = coinAmount: number
    }
    ]]
    }
    ...
    return PlayerData

    定义本地数据访问器

    getData() 是一个本地函数,它为特定 playerData 表恢复数据。如果玩家还没有收集硬币,它将返回一个 DEFAULT_PLAYER_DATA 表,以确保每个玩家都有与他们相关的一些数据。一个常见的做法是创建一个简单、公开面向的函数,它将逻辑从本地到访问本地的函数转


    local DEFAULT_PLAYER_DATA = {
    [PlayerData.COIN_KEY_NAME] = 0
    }
    local function getData(player)
    local data = playerData[tostring(player.UserId)] or DEFAULT_PLAYER_DATA
    playerData[tostring(player.UserId)] = data
    return data
    end

    定义公共数据访问器

    getValue()updateValue() 是其他需要此模块脚本的脚本可以调用的公面函数。在我们的例子中, CoinService 使用这些函数更新玩家每次触摸硬币时的硬币收藏数据。


    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

实现排行榜

您可以使用屏幕排行榜来视觉表示硬币收集数据。Roblox 包括一个内置系统,它会自动使用默认 UI 生成排行榜。

要创建排行榜:

  1. Explorer 窗口中,在 ServerStorage 中创建一个 ModuleScript 在 1>Leaderboard1> 。

    Studio's Explorer window with the Leaderboard script highlighted under ServerStorage.
  2. 将以下代码替换为默认代验证码:


    local Leaderboard = {}
    -- 创建一个新的排行榜
    local function setupLeaderboard(player)
    local leaderstats = Instance.new("Folder")
    -- ‘leaderstat’ 是 Roblox 为创建排行榜而使用的保留名称
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player
    return leaderstats
    end
    -- 创建一个新的排行榜统计值
    local function setupStat(leaderstats, statName)
    local stat = Instance.new("IntValue")
    stat.Name = statName
    stat.Value = 0
    stat.Parent = leaderstats
    return stat
    end
    -- 更新玩家的统计值
    function Leaderboard.setStat(player, statName, value)
    local leaderstats = player:FindFirstChild("leaderstats")
    if not leaderstats then
    leaderstats = setupLeaderboard(player)
    end
    local stat = leaderstats:FindFirstChild(statName)
    if not stat then
    stat = setupStat(leaderstats, statName)
    end
    stat.Value = value
    end
    return Leaderboard

    以下部分描述排行榜的工作方式更加详细。

    创建排行榜

    setupLeaderboard() 函数创建了一个名为 leaderstats 的新文件夹实例,并将其作为指定玩家的子文件夹。 Roblox 会自动将 leader


    -- 创建一个新的排行榜
    local function setupLeaderboard(player)
    local leaderstats = Instance.new("Folder")
    -- ‘leaderstat’ 是 Roblox 为创建排行榜而使用的保留名称
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player
    return leaderstats
    end
    -- 创建一个新的排行榜统计值
    local function setupStat(leaderstats, statName)
    local stat = Instance.new("IntValue")
    stat.Name = statName
    stat.Value = 0
    stat.Parent = leaderstats
    return stat
    end

    更新玩家统计

    setStat()排行榜 模块中唯一的公共函数。它创建特定玩家或排行榜自身的统计值,如果它尚未存在,它会创建排行榜自身的统计值。

    FindFirstChild() 取一个对象的名称,并且如果对象存在,返回对象,或者如果对象不存在,nil 就是一个普通、安全的方法来查看是否存在对象。


    -- 更新玩家的统计值
    function Leaderboard.setStat(player, statName, value)
    local leaderstats = player:FindFirstChild("leaderstats")
    if not leaderstats then
    leaderstats = setupLeaderboard(player)
    end
    local stat = leaderstats:FindFirstChild(statName)
    if not stat then
    stat = setupStat(leaderstats, statName)
    end
    stat.Value = value
    end

集成模块脚本

PlayerData排行榜 模块脚本完成时,需要它们在 CoinService 脚本中才能管理和显示玩家的硬币数据。要更新 1>CoinService1> :

  1. Explorer 窗口中,打开 CoinService 脚本。

  2. 将现有代码替换为以下验证码:


    -- 初始化服务和变量
    local Workspace = game:GetService("Workspace")
    local Players = game:GetService("Players")
    local ServerStorage = game:GetService("ServerStorage")
    -- 模块
    local Leaderboard = require(ServerStorage.Leaderboard)
    local PlayerData = require(ServerStorage.PlayerData)
    local coinsFolder = Workspace.World.Coins
    local coins = coinsFolder:GetChildren()
    local COIN_KEY_NAME = PlayerData.COIN_KEY_NAME
    local COOLDOWN = 10
    local COIN_AMOUNT_TO_ADD = 1
    local function updatePlayerCoins(player, updateFunction)
    -- 更新硬币桌
    local newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, updateFunction)
    -- 更新硬币排行榜
    Leaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)
    end
    -- 定义事件处理器
    local function onCoinTouched(otherPart, coin)
    if coin:GetAttribute("Enabled") then
    local character = otherPart.Parent
    local player = Players:GetPlayerFromCharacter(character)
    if player then
    -- 玩家触摸了一个硬币
    coin.Transparency = 1
    coin:SetAttribute("Enabled", false)
    updatePlayerCoins(player, function(oldCoinAmount)
    oldCoinAmount = oldCoinAmount or 0
    return oldCoinAmount + COIN_AMOUNT_TO_ADD
    end)
    task.wait(COOLDOWN)
    coin.Transparency = 0
    coin:SetAttribute("Enabled", true)
    end
    end
    end
    -- 设置事件听取者
    for _, coin in coins do
    coin:SetAttribute("Enabled", true)
    coin.Touched:Connect(function(otherPart)
    onCoinTouched(otherPart, coin)
    end)
    end

    对原始 CoinService 脚本的更改包括:

    • 导入 PlayerData排行榜 模块,使用 require() 函数。
    • COIN_AMOUNT_TO_ADD 定义为玩家收集硬币时添加的硬币数量,和 COIN_KEY_NAME 作为 PlayerData 中的钥匙名称。
    • 创建帮助函数 updatePlayerCoins() 来更新玩家的硬币数量和关联排行榜统计。
    • print() 声明替换为 onCoinTouched() 中的 updatePlayerCoins()

游戏测试

是时候看看金币收集是否如预期般运行。当您触摸并收集一枚金币在游戏中时,您应该能够看到您收集的金币在排行榜 UI 上的数量。要测试您的体验:

  1. 在菜单栏中,单击 播放 按钮。Studio进入播放测试模式。

    Studio's Home tab with the Play button highlighted in the menu bar.
  2. 移动您的角色触摸一个硬币。如果您的脚本正常运行,排行榜 UI 会显示,并随着您收集更多硬币增加您的硬币数量。