記錄並顯示玩家數據

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡


現在您可以檢測玩家何時收集硬幣,您需要計算玩家收集了多少硬幣,並將該數量顯示在排行榜上。

創建模組腳本以記錄硬幣收集

為了處理每個玩家的硬幣收集數據的儲存和管理,您需要創建一個ModuleScript對象來包含一個數據結構和訪問每個玩家的硬幣收集數據的函數。模組腳本是其他腳本可以調用的可重用代碼。在這種情況下,CoinService 需要這個模組腳本,以便在玩家觸摸硬幣時更新硬幣收集數據。

創建 PlayerData

在 ServerStorage 中創建一個名為 PlayerData 的 ModuleScript,並添加以下代碼:
```lua
local PlayerData = {}
PlayerData.COIN_KEY_NAME = "Coins"
local playerData = {
--[[
[userId: string] = {
["Coins"] = coinAmount: number
}
]]
}
local function defaultPlayerData()
return {
[PlayerData.COIN_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表,其中包含零個或多個 playerData表,表示玩家的硬幣收集數據。每個 需要該模組腳本的腳本都會接收到相同的PlayerData表副本,允許多個腳本修改和共享硬幣 收集數據。

聲明數據結構

模組腳本以聲明一個空表PlayerData開始,最後將其返回。它還包含 訪問器方法來獲取和設置表中的值。

playerData表包含描述表結構的註釋,使代碼更易於理解。在這種情況下,一個 playerData表包含一個userId和一個相應的名為 Coins的字段,表示該玩家收集的硬幣數量。


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

定義本地數據訪問器

getData()是一個本地函數,用於檢索特定 playerData表的數據。如果玩家尚未收集硬幣,它將從 defaultPlayerData()函數返回一個表,以確保每個玩家都有一些與之相關聯的數據。常見的慣例是創建簡單的、 面向公眾的函數,將邏輯移交給本地範圍的函數,後者執行繁重的工作。


local function defaultPlayerData()
return {
[PlayerData.COIN_KEY_NAME] = 0
}
end
local function getData(player)
local data = playerData[tostring(player.UserId)] or defaultPlayerData()
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 生成排行榜。

創建 排行榜

在 ServerStorage 中創建一個 ModuleScript,名為 Leaderboard,並添加以下代碼:
```lua
local Leaderboard = {}
-- 創建新的排行榜
local function setupLeaderboard(player)
local leaderstats = Instance.new("Folder")
-- 'leaderstats' 是 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 自動識別名為leaderstats的文件夾作為統計數據的容器,並創建一個 UI 元素來顯示統計數據。它要求 leaderstats中的值以“值”對象(例如 StringValueIntValueNumberValue)的形式存儲。


-- 創建新的排行榜
local function setupLeaderboard(player)
local leaderstats = Instance.new("Folder")
-- 'leaderstats' 是 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()Leaderboard模組中的唯一公共函數。它為指定的玩家或排行榜本身創建統計值,如果尚不存在。

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

集成模組腳本

在兩個模組到位之後,在CoinService腳本中要求它們以管理和顯示玩家的硬幣數據。

更新 CoinService

在 ServerScriptService 中,用以下代碼替換現有的 CoinService 腳本的代碼:
```lua
-- 初始化服務和變數
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 腳本所做的更改包括:

  • 使用 require() 函數導入 PlayerDataLeaderboard 模組。
  • COIN_AMOUNT_TO_ADD 聲明為當玩家收集硬幣時要添加的硬幣數量,並將 COIN_KEY_NAME 聲明為在 PlayerData 中定義的鍵名。
  • 創建幫助函數 updatePlayerCoins() 以更新玩家的硬幣數量和相關的排行榜統計數據。
  • 用對 updatePlayerCoins() 的調用替換 onCoinTouched() 中的佔位符 print() 語句。

測試

從下拉選單中選擇 Test,然後點擊 Play。走進一個硬幣,確認排行榜出現於角落,並且隨著您收集更多的硬幣,您的硬幣數量增加。

©2026 Roblox Corporation、Roblox、Roblox 標誌及 Powering Imagination 是我們在美國及其他國家地區的部分註冊與未註冊商標。