現在您可以檢測玩家何時收集硬幣,您需要計算玩家收集了多少硬幣,並將該數量顯示在排行榜上。
創建模組腳本以記錄硬幣收集
為了處理每個玩家的硬幣收集數據的儲存和管理,您需要創建一個ModuleScript對象來包含一個數據結構和訪問每個玩家的硬幣收集數據的函數。模組腳本是其他腳本可以調用的可重用代碼。在這種情況下,CoinService 需要這個模組腳本,以便在玩家觸摸硬幣時更新硬幣收集數據。
創建 PlayerData在 ServerStorage 中創建一個名為 PlayerData 的 ModuleScript,並添加以下代碼:```lualocal PlayerData = {}PlayerData.COIN_KEY_NAME = "Coins"local playerData = {--[[[userId: string] = {["Coins"] = coinAmount: number}]]}local function defaultPlayerData()return {[PlayerData.COIN_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表,其中包含零個或多個 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,並添加以下代碼:```lualocal Leaderboard = {}-- 創建新的排行榜local function setupLeaderboard(player)local leaderstats = Instance.new("Folder")-- 'leaderstats' 是 Roblox 認可的保留名稱,用於創建排行榜leaderstats.Name = "leaderstats"leaderstats.Parent = playerreturn leaderstatsend-- 創建新的排行榜統計值local function setupStat(leaderstats, statName)local stat = Instance.new("IntValue")stat.Name = statNamestat.Value = 0stat.Parent = leaderstatsreturn statend-- 更新玩家的統計值function Leaderboard.setStat(player, statName, value)local leaderstats = player:FindFirstChild("leaderstats")if not leaderstats thenleaderstats = setupLeaderboard(player)endlocal stat = leaderstats:FindFirstChild(statName)if not stat thenstat = setupStat(leaderstats, statName)endstat.Value = valueendreturn Leaderboard```
以下部分更詳細地描述了排行榜的運作方式。
創建排行榜
setupLeaderboard()函數創建一個名為 leaderstats的新文件夾實例,並將其設置為指定玩家的子項。Roblox 自動識別名為leaderstats的文件夾作為統計數據的容器,並創建一個 UI 元素來顯示統計數據。它要求 leaderstats中的值以“值”對象(例如 StringValue、IntValue或NumberValue)的形式存儲。
-- 創建新的排行榜
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.Coinslocal coins = coinsFolder:GetChildren()local COIN_KEY_NAME = PlayerData.COIN_KEY_NAMElocal COOLDOWN = 10local COIN_AMOUNT_TO_ADD = 1local 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") thenlocal character = otherPart.Parentlocal player = Players:GetPlayerFromCharacter(character)if player then-- 玩家觸摸了一個硬幣coin.Transparency = 1coin:SetAttribute("Enabled", false)updatePlayerCoins(player, function(oldCoinAmount)oldCoinAmount = oldCoinAmount or 0return oldCoinAmount + COIN_AMOUNT_TO_ADDend)task.wait(COOLDOWN)coin.Transparency = 0coin:SetAttribute("Enabled", true)endendend-- 設置事件監聽器for _, coin in coins docoin:SetAttribute("Enabled", true)coin.Touched:Connect(function(otherPart)onCoinTouched(otherPart, coin)end)end```
對原有的 CoinService 腳本所做的更改包括:
- 將 COIN_AMOUNT_TO_ADD 聲明為當玩家收集硬幣時要添加的硬幣數量,並將 COIN_KEY_NAME 聲明為在 PlayerData 中定義的鍵名。
- 創建幫助函數 updatePlayerCoins() 以更新玩家的硬幣數量和相關的排行榜統計數據。
- 用對 updatePlayerCoins() 的調用替換 onCoinTouched() 中的佔位符 print() 語句。
測試
從下拉選單中選擇 Test,然後點擊 Play。走進一個硬幣,確認排行榜出現於角落,並且隨著您收集更多的硬幣,您的硬幣數量增加。