Agora que você pode detectar quando um jogador coletou uma moeda, você precisa contar quantas moedas os jogadores coletaram e tornar essa quantidade visível em um placar.
Crie um script de módulo para gravar a coleta de moedas
Para lidar com o armazenamento e a gestão dos dados de coleta de moedas de cada jogador, você precisa criar um objeto ModuleScript para conter uma estrutura de dados e funções que acessem os dados de coleta de moedas de cada jogador. Scripts de módulo são códigos reutilizáveis que outros scripts podem requisitar. Neste caso, o CoinService requisita este script de módulo para que possa atualizar os dados de coleta de moedas quando os jogadores tocarem nas moedas.
Criar PlayerDataNa ServerStorage, crie um ModuleScript chamado PlayerData com o seguinte código:```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```
O script de módulo define uma tabela PlayerData que contém zero ou mais tabelas playerData, que representam os dados de coleta de moedas de um jogador. Todo script que requisita este script de módulo recebe a mesma cópia da tabela PlayerData, permitindo que múltiplos scripts modifiquem e compartilhem dados de coleta de moedas.
Declare as estruturas de dados
O script de módulo começa com a declaração de uma tabela vazia, PlayerData, que é retornada no final do script. Ele também contém métodos de acesso para obter e definir valores na tabela.
A tabela playerData contém comentários que descrevem a estrutura da tabela, o que torna o código mais fácil de entender. Neste caso, uma tabela playerData contém um userId e um campo correspondente chamado Coins que representa a quantidade de moedas coletadas por aquele jogador.
local PlayerData = {}PlayerData.COIN_KEY_NAME = "Coins"local playerData = {--[[[userId: string] = {["Coins"] = coinAmount: number}]]}...return PlayerData
Defina um acessador de dados local
getData() é uma função local que recupera dados para uma tabela playerData específica. Se um jogador não tiver coletado uma moeda, ela retorna uma tabela da função defaultPlayerData() para garantir que cada jogador tenha alguns dados associados a eles. Uma convenção comum é criar funções simples, voltadas para o público, que delegam a lógica a funções de escopo local que fazem o trabalho 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
end
Defina acessadores de dados pública
getValue() e updateValue() são funções voltadas para o público que outros scripts que requisitam este script de módulo podem chamar. No nosso caso, o CoinService usa essas funções para atualizar os dados de coleta de moedas de um jogador sempre que aquele jogador toca em uma moeda.
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
Implementar um placar
Você pode representar os dados de coleta de moedas visualmente com um placar na tela. O Roblox inclui um sistema embutido que gera automaticamente um placar usando uma interface padrão.
Criar LeaderboardNa ServerStorage, crie um ModuleScript chamado Leaderboard com o seguinte código:```lualocal Leaderboard = {}-- Criando um novo placarlocal function setupLeaderboard(player)local leaderstats = Instance.new("Folder")-- 'leaderstats' é um nome reservado que o Roblox reconhece para criar um placarleaderstats.Name = "leaderstats"leaderstats.Parent = playerreturn leaderstatsend-- Criando um novo valor de estatística no placarlocal function setupStat(leaderstats, statName)local stat = Instance.new("IntValue")stat.Name = statNamestat.Value = 0stat.Parent = leaderstatsreturn statend-- Atualizando o valor da estatística de um jogadorfunction 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```
As seções a seguir descrevem como o placar funciona em mais detalhes.
Criar um placar
A função setupLeaderboard() cria uma nova instância de pasta chamada leaderstats e a define como filha do jogador especificado. O Roblox reconhece automaticamente uma pasta chamada leaderstats como um contêiner de estatísticas e cria um elemento de UI para exibir as estatísticas. Requer que os valores em leaderstats sejam armazenados como objetos "value" (como StringValue, IntValue ou NumberValue).
-- Criando um novo placar
local function setupLeaderboard(player)
local leaderstats = Instance.new("Folder")
-- 'leaderstats' é um nome reservado que o Roblox reconhece para criar um placar
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
return leaderstats
end
-- Criando um novo valor de estatística no placar
local function setupStat(leaderstats, statName)
local stat = Instance.new("IntValue")
stat.Name = statName
stat.Value = 0
stat.Parent = leaderstats
return stat
end
Atualizar estatísticas do jogador
setStat() é a única função pública no módulo Leaderboard. Ela cria valores de estatísticas para um jogador especificado ou para o próprio placar se ainda não existirem.
FindFirstChild() aceita o nome de um objeto e retorna o objeto se existir, ou nil se não existir. É um método comum e seguro para descobrir se um objeto existe antes de usá-lo.
-- Atualizando o valor da estatística de um jogador
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
Integre os scripts de módulo
Com ambos os módulos no lugar, requerê-los no script CoinService para gerenciar e exibir os dados de moedas dos jogadores.
Atualizar CoinServiceNo ServerScriptService, substitua o código existente do script CoinService pelo seguinte:```lua-- Inicializando serviços e variáveislocal Workspace = game:GetService("Workspace")local Players = game:GetService("Players")local ServerStorage = game:GetService("ServerStorage")-- Móduloslocal 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)-- Atualiza a tabela de moedaslocal newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, updateFunction)-- Atualiza o placar de moedasLeaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)end-- Definindo o manipulador de eventoslocal function onCoinTouched(otherPart, coin)if coin:GetAttribute("Enabled") thenlocal character = otherPart.Parentlocal player = Players:GetPlayerFromCharacter(character)if player then-- O jogador tocou em uma moedacoin.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-- Configurando ouvintes de eventosfor _, coin in coins docoin:SetAttribute("Enabled", true)coin.Touched:Connect(function(otherPart)onCoinTouched(otherPart, coin)end)end```
As mudanças no script original CoinService incluem:
- Declaração de COIN_AMOUNT_TO_ADD como o número de moedas a serem adicionadas quando um jogador coleta uma moeda, e COIN_KEY_NAME como o nome da chave definido em PlayerData.
- Criação da função auxiliar updatePlayerCoins() para atualizar a contagem de moedas do jogador e a estatística associada do placar.
- Substituição da declaração de print() no onCoinTouched() por uma chamada para updatePlayerCoins().
Testar
Selecione Teste no menu suspenso e clique em Jogar. Ande até uma moeda e confirme que o placar aparece no canto e que sua contagem de moedas aumenta à medida que você coleta mais moedas.