Ahora que puedes detectar cuando un jugador ha recogido una moneda, necesitas contar cuántas monedas han recogido los jugadores y hacer que esa cantidad sea visible en un tablero de líderes.
Crea un script de módulo para registrar la recolección de monedas
Para manejar el almacenamiento y la gestión de los datos de recolección de monedas de cada jugador, necesitas crear un objeto ModuleScript que contenga una estructura de datos y funciones que accedan a los datos de recolección de monedas para cada jugador. Los scripts de módulo son código reutilizable que otros scripts pueden requerir. En este caso, el CoinService requiere este script de módulo para que pueda actualizar los datos de recolección de monedas cuando los jugadores toquen monedas.
En ServerStorage, crea un ModuleScript llamado PlayerData con el siguiente código:
```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
```El script de módulo define una tabla PlayerData que contiene cero o muchas tablas playerData, que representan los datos de recolección de monedas para un jugador. Cada script que requiere este script de módulo recibe la misma copia de la tabla PlayerData, lo que permite que múltiples scripts modifiquen y compartan los datos de recolección de monedas.
Declarar las estructuras de datos
El script de módulo comienza con una declaración de una tabla vacía, PlayerData, que se devuelve al final del script. También contiene métodos de acceso para obtener y establecer valores en la tabla.
La tabla playerData contiene comentarios que describen la estructura de la tabla, lo que hace que el código sea más fácil de entender. En este caso, una tabla playerData contiene un userId y un campo correspondiente llamado Coins que representa la cantidad de monedas recolectadas para ese jugador.
local PlayerData = {}
PlayerData.COIN_KEY_NAME = "Coins"
local playerData = {
--[[
[userId: string] = {
["Coins"] = coinAmount: number
}
]]
}
...
return PlayerDataDefinir un acceso a datos local
getData() es una función local que recupera datos para una tabla playerData específica. Si un jugador no ha recolectado una moneda, devuelve una tabla de la función defaultPlayerData() para asegurar que cada jugador tenga algunos datos asociados con ellos. Una convención común es crear funciones simples y de cara al público que descarguen la lógica a funciones de ámbito local que realicen el trabajo pesado.
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
endDefinir accesores de datos públicos
getValue() y updateValue() son funciones de cara al público que otros scripts que requieren este script de módulo pueden llamar. En nuestro caso, el CoinService utiliza estas funciones para actualizar los datos de recolección de monedas de un jugador cada vez que ese jugador toca una moneda.
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
endImplementar un tablero de líderes
Puedes representar los datos de recolección de monedas visualmente con un tablero de líderes en pantalla. Roblox incluye un sistema integrado que genera automáticamente un tablero de líderes utilizando una interfaz de usuario predeterminada.
En ServerStorage, crea un ModuleScript llamado Leaderboard con el siguiente código:
```lua
local Leaderboard = {}
-- Creando un nuevo tablero de líderes
local function setupLeaderboard(player)
local leaderstats = Instance.new("Folder")
-- 'leaderstats' es un nombre reservado que Roblox reconoce para crear un tablero de líderes
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
return leaderstats
end
-- Creando un nuevo valor de estadística del tablero de líderes
local function setupStat(leaderstats, statName)
local stat = Instance.new("IntValue")
stat.Name = statName
stat.Value = 0
stat.Parent = leaderstats
return stat
end
-- Actualizando el valor de estadística de un jugador
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
```Las siguientes secciones describen cómo funciona el tablero de líderes con más detalle.
Crear un tablero de líderes
La función setupLeaderboard() crea una nueva instancia de carpeta llamada leaderstats y la establece como un hijo del jugador especificado. Roblox reconoce automáticamente una carpeta llamada leaderstats como un contenedor de estadísticas y crea un elemento de interfaz de usuario para mostrar las estadísticas. Requiere que los valores en leaderstats se almacenen como objetos "value" (como StringValue, IntValue o NumberValue).
-- Creando un nuevo tablero de líderes
local function setupLeaderboard(player)
local leaderstats = Instance.new("Folder")
-- 'leaderstats' es un nombre reservado que Roblox reconoce para crear un tablero de líderes
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
return leaderstats
end
-- Creando un nuevo valor de estadística del tablero de líderes
local function setupStat(leaderstats, statName)
local stat = Instance.new("IntValue")
stat.Name = statName
stat.Value = 0
stat.Parent = leaderstats
return stat
endActualizar estadísticas de jugadores
setStat() es la única función pública en el módulo Leaderboard. Crea valores de estadística para un jugador especificado o para el tablero de líderes en sí si aún no existe.
FindFirstChild() toma el nombre de un objeto y devuelve el objeto si existe, o nil si no existe. Es un método común y seguro para averiguar si un objeto existe antes de usarlo.
-- Actualizando el valor de estadística de un jugador
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
endIntegrar los scripts de módulo
Con ambos módulos en su lugar, requiérelo en el script de CoinService para gestionar y mostrar los datos de monedas de los jugadores.
En ServerScriptService, reemplaza el código del script CoinService existente con el siguiente:
```lua
-- Inicializando servicios y variables
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
-- Módulos
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)
-- Actualizar la tabla de monedas
local newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, updateFunction)
-- Actualizar el tablero de líderes de monedas
Leaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)
end
-- Definiendo el manejador de eventos
local function onCoinTouched(otherPart, coin)
if coin:GetAttribute("Enabled") then
local character = otherPart.Parent
local player = Players:GetPlayerFromCharacter(character)
if player then
-- El jugador tocó una moneda
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
-- Configurando oyentes de eventos
for _, coin in coins do
coin:SetAttribute("Enabled", true)
coin.Touched:Connect(function(otherPart)
onCoinTouched(otherPart, coin)
end)
end
```Los cambios en el script original de CoinService incluyen:
- Declarar COIN_AMOUNT_TO_ADD como el número de monedas a agregar cuando un jugador recolecta una moneda, y COIN_KEY_NAME como el nombre de clave definido en PlayerData.
- Crear la función auxiliar updatePlayerCoins() para actualizar la cantidad de monedas del jugador y la estadística asociada del tablero de líderes.
- Reemplazar la declaración de marcador de posición print() en onCoinTouched() con una llamada a updatePlayerCoins().
Prueba de juego
Selecciona Test en el menú desplegable y haz clic en Play. Camina hacia una moneda y confirma que el tablero de líderes aparece en la esquina y que tu cuenta de monedas aumenta a medida que recolectas más monedas.