Criando uma Interface gráfica do usuário

*Este conteúdo é traduzido por IA (Beta) e pode conter erros. Para ver a página em inglês, clique aqui.

Agora, muita da informação do jogo está na Janela de Saída, invisível para os jogadores. Para que os jogadores possam ser informados de o que está acontecendo no jogo, você criará uma interface gráfica de usuário (Interface gráfica do usuário) e o codificará.

Exibindo informações com uma Interface gráfica do usuário

Para este jogo, uma etiqueta de texto exibirá o status de jogo atual, bem como o número de jogadores restantes e o tempo.

Durante o Intervalo
Durante uma Partida

Configurando o Interface gráfica do usuário

Primeiro, crie um objeto GUI da Tela para armazenar os diferentes elementos de texto. Quando o jogador mover a Câmera, o GUI da Tela fica no mesmo lugar na tela deles.

Para garantir que todos os jogadores vejam o mesmo display, coloque o GUI no StarterGui pasta. No momento do jogo, esta pasta é copiada para todos os jogadores.

  1. Na pasta StarterGui, crie um novo ScreenGUI. Em seguida, na pasta ScreenGUI, adicione um novo TextLabel chamado StatusText.

  2. Para mover a etiqueta / rótulo, no Explorador, selecione StatusText. Em seguida, na janela de visualização do jogo, arraste a etiqueta onde você gostaria que ela estivesse. Seus números podem diferir do vídeo. A etiqueta também pode ser reposicionada usando os pontos de ancoragem nas pontas.

Programando a Interface gráfica do usuário

Para refletir as alterações no jogo, scripts precisarão atualizar os elementos da GUI. Por instância, o status do jogo, se for uma intermissão ou uma rodada ativa, será armazenado em um StringValue e atualizado usando scripts locais.

Configurando o Script

O script StatusDisplay será usado para atualizar a GUI do jogador sempre que o estado do jogo mudar.

  1. Em Armazenamento Replicado , crie um pasta chamado DisplayColors. Neste pasta, adicione um valor chamado Status. Para testar o valor mais tarde, dê um valor temporário, como "Bem-vindo à Batalha!".

  2. In StarterGui > ScreenGUI > Status, adicione um novo script local chamado StatusDisplay. Scripts que afetam o GUI geralmente são vinculados a esse elemento GUI.

  3. Abra o StatusDisplay e defina as seguintes variáveis para o seguir:

    • Serviço de armazenamento replicado

    • Pasta DisplayValues

    • Valor de Status

    • TextLabel - use script.Parent.


      local ReplicatedStorage = game:GetService("ReplicatedStorage")
      local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
      local status = displayValues:WaitForChild("Status")
      local textLabel = script.Parent

Mudando a Etiqueta de Texto

Para alterar o texto na etiqueta / rótulo, use um evento alterado para que, sempre que a string Status for alterada por outro script, a etiqueta de texto seja atualizada.

  1. Código uma nova função chamada updateText() . Nesta função, configure a propriedade de texto de textLabel para status.Value .


    local textLabel = script.Parent
    local function updateText()
    textLabel.Text = status.Value
    end
  2. Conecte a função ao evento Alterado.


    local function updateText()
    textLabel.Text = status.Value
    end
    status.Changed:Connect(updateText)
  3. Para que os jogadores vejam o status mais recente quando iniciar o jogo, execute updateText() no final do script.


    local function updateText()
    textLabel.Text = status.Value
    end
    status.Changed:Connect(updateText)
    updateText()
  4. Execute o jogo e confirme que você vê o valor temporário na exibição.

Criando o Gerenciador de Exibição

Durante um jogo, a etiqueta de texto precisará obter informações do GameManager, MatchManager e, possivelmente, de outros scripts. Para que esses diferentes scripts possam atualizar a etiqueta de texto quando necessário, crie um script de módulo chamado DisplayManager.

Configurando o Script

Como o DisplayManager precisa se comunicar com outros scripts, será um script de módulo.

  1. Em ServerStorage > ModuleScripts , crie um novo script de módulo chamado DisplayManager. Renomeie a tabela de módulo para corresponder ao nome do script.

  2. Adicionar variáveis locais para o seguindo: Replicated Storage, DisplayValues pasta, Status.


    local DisplayManager = {}
    -- Serviços
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    -- Exibir Valores usados para atualizar a Interface gráfica do usuáriodo Jogador
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local status = displayValues:WaitForChild("Status")
    -- Funções Locais
    -- Funções de Modulo
    return DisplayManager
  3. Crie uma nova função de módulo chamada updateStatus() que atualiza a string no valor Status. Outros scripts poderão chamar essa função.


    -- Funções Locais
    -- Funções de Modulo
    function DisplayManager.updateStatus(newStatus)
    status.Value = newStatus
    end

Atualizando o Status do Texto

Com o Gerenciador de Display configurado, ele pode ser usado em outros scripts para atualizar a etiqueta / rótulode texto GUI. Como a primeira mensagem na Interface gráfica do usuário, mostre o início e o fim da intermissão através do script Gerenciador de Jogo.

  1. In ServerScriptService > GameManager, create a variable named displayManager and require the DisplayManager module in ServerStorage.


    -- Serviços
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local ServerStorage = game:GetService("ServerStorage")
    local Players = game:GetService("Players")
    -- Scripts de Módulo
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local roundManager = require(moduleScripts:WaitForChild("RoundManager"))
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
  2. Como a primeira linha depois da declaração while true, chame displayManager > updateStatus() e passe em uma mensagem sobre a espera por jogadores.


    -- Eventos
    local events = ServerStorage:WaitForChild("Events")
    local matchEnd = events:WaitForChild("MatchEnd")
    while true do
    displayManager.updateStatus("Waiting for Players")
    repeat
    print("Starting intermission")
    task.wait(gameSettings.intermissionDuration)
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    task.wait(gameSettings.transitionTime)
    matchManager.prepareGame()
    matchEnd.Event:Wait()
    end
  3. Após o fim do loop de repetição para a intermissão, chame updateStatus() e passe em uma string anunciando que a partida está começando. Como você estará testando com o Interface gráfica do usuário, exclua as duas declarações de print para notar o começo e o fim da intermissão.


    while true do
    displayManager.updateStatus("Waiting for Players")
    repeat
    task.wait(gameSettings.intermissionDuration)
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    displayManager.updateStatus("Get ready!")
    task.wait(gameSettings.transitionTime)
    matchManager.prepareGame()
    matchEnd.Event:Wait()
    end
  4. Teste o jogo com e sem seus jogadores mínimos. A mensagem deve ler o seguindo:

    • Sem os jogadores mínimos: "Waiting for Players" .
    • Com os jogadores mínimos: "Get ready".

Dicas de solução de problemas

Neste ponto, se a etiqueta de texto não exibir a primeira mensagem ou ainda exibir "Label", tente um dos seguintes abaixo.

  • Certifique-se no script local StatusDisplay que updateText() é chamado na parte inferior do script. Isso garante que o jogador receba a mensagem mais recente.
  • Verifique se o Valor de Status está em ReplicatedStorage. Devido à natureza única das relações cliente-servidor, se estiver em ServerStorage, um script local não será capaz de encontrá-lo.

Exibindo Status de Partida

Durante uma conferir, a GUI exibirá dois números: o número de jogadores restantes e o tempo. À medida que esses números mudam, a etiqueta de texto também será alterada.

Configurando Valores e Funções

Os valores Int serão usados para armazenar o número de jogadores e o tempo restante.

  1. Em ReplicatedStorage > DisplayValues, crie dois IntValues chamados PlayersLeft e TimeLeft.

  2. No DisplayManager, adicione variáveis para armazenar os valores esquerdos e de tempo restantes.


    local DisplayManager = {}
    -- Serviços
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    -- Exibir Valores usados para atualizar a Interface gráfica do usuáriodo Jogador
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local status = displayValues:WaitForChild("Status")
    local playersLeft = displayValues:WaitForChild("PlayersLeft")
    local timeLeft = displayValues:WaitForChild("TimeLeft")
  3. Crie uma função local chamada updateMatchStatus() . Em seguida, configure o valor do status para exibir o número de jogadores restantes e o tempo restante.


    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local status = displayValues:WaitForChild("Status")
    local playersLeft = displayValues:WaitForChild("PlayersLeft")
    local timeLeft = displayValues:WaitForChild("TimeLeft")
    -- Funções Locais
    local function updateRoundStatus()
    status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.Value
    end
  4. Para ambas as variáveis INTValue , conecte updateRoundStatus() ao evento Alterado.


    -- Funções de Modulo
    function DisplayManager.updateStatus(newStatus)
    status.Value = newStatus
    end
    playersLeft.Changed:Connect(updateRoundStatus)
    timeLeft.Changed:Connect(updateRoundStatus)
    return DisplayManager

Exibindo Jogadores

Em seguida, adicione o código para exibir o número de jogadores no início de um jogo. As aulas posteriores atualizarão o valor PlayersLeft à medida que os jogadores são eliminados do jogo.

  1. In PlayerManager, adicione variáveis locais para o serviço ReplicatedStorage, pasta DisplayValues e PlayersLeft IntValue.


    local PlayerManager = {}
    -- Serviços
    local Players = game:GetService("Players")
    local ServerStorage = game:GetService("ServerStorage")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    -- Variáveis de Mapa
    local lobbySpawn = workspace.Lobby.StartSpawn
    local arenaMap = workspace.Arena
    local spawnLocations = arenaMap.SpawnLocations
    -- Valores
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local playersLeft = displayValues:WaitForChild("PlayersLeft")
  2. Mostre o número inicial de jogadores ao definir o valor de playersLeft para o tamanho da matriz / listade jogadores ativos.

    Então, em sendPlayersToMatch() , sob o for loop, digitar: playersLeft.Value = #activePlayers


    function PlayerManager.sendPlayersToMatch()
    local availableSpawnPoints = spawnLocations:GetChildren()
    for playerKey, whichPlayer in Players:GetPlayers() do
    table.insert(activePlayers, whichPlayer)
    local spawnLocation = table.remove(availableSpawnPoints, 1)
    preparePlayer(whichPlayer, spawnLocation)
    end
    playersLeft.Value = #activePlayers
    end

Exibindo o Temporizador

Lembre-se de que scripts de módulo são usados para centralizar código semelhante. Como o tempo é rastreado no MatchManager, atualize o valor TimeLeft usando funções do script Timer. O gerenciador de exibição ouvirá alterações no TimeLeft e atualizará para corresponder ao novo valor.

  1. In MatchManager, crie variáveis para armazenar o serviço Armazenamento Replicado , o diretório DisplayColors e o valor TimeLeft.


    local MatchManager = {}
    -- Serviços
    local ServerStorage = game:GetService("ServerStorage")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    -- Scripts de Módulo
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    local timer = require(moduleScripts:WaitForChild("Timer"))
    -- Eventos
    local events = ServerStorage:WaitForChild("Events")
    local matchStart = events:WaitForChild("MatchStart")
    -- Valores
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local timeLeft = displayValues:WaitForChild("TimeLeft")
    local myTimer = timer.new()
  2. Encontre a função startTimer(). Depois do evento Finished do timer, copie e cole todo o evento Finished abaixo. O código executa um loop para atualizar o valor 1> timeLeft1> enquanto o timer ainda está ativo.


    while myTimer:isRunning() do
    -- Adicionar +1 garante que o display do timer termine em 1 em vez de 0.
    timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
    -- Ao não definir o tempo para esperar, ele oferece mais precisão de looping
    task.wait()
    end

    Quando adicionado, o código deve ser semelhante ao exemplo abaixo.


    local function startTimer()
    print("Timer started")
    myTimer:start(gameSettings.matchDuration)
    myTimer.finished:Connect(timeUp)
    while myTimer:isRunning() do
    -- Adicionar +1 garante que o display do timer termine em 1 em vez de 0.
    timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
    -- Ao não definir o tempo para esperar, ele oferece mais precisão de looping
    task.wait()
    end
    end
  3. Execute o jogo com os jogadores mínimos. Verifique se o texto de status é exibido:

    • A quantidade correta de jogadores de partida iniciais. Lembre-se, esse número não vai mudar até que mais código seja adicionado em uma futura lição.
    • O tempo diminui a cada segundo até chegar em 1.

Scripts Concluídos

Abaixo estão scripts concluídos para verificar duas vezes seu trabalho.

Script do GameManager


-- Serviços
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Scripts de Módulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
while true do
displayManager.updateStatus("Waiting for Players")
repeat
task.wait(gameSettings.intermissionDuration)
until #Players:GetPlayers() >= gameSettings.minimumPlayers
displayManager.updateStatus("Get ready!")
task.wait(gameSettings.transitionTime)
matchManager.prepareGame()
matchEnd.Event:Wait()
end

Script do Gerenciador de Exibição


local DisplayManager = {}
-- Serviços
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Exibir Valores usados para atualizar a Interface gráfica do usuáriodo Jogador
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Funções Locais
local function updateRoundStatus()
status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.Value
end
-- Funções de Modulo
function DisplayManager.updateStatus(newStatus)
status.Value = newStatus
end
playersLeft.Changed:Connect(updateRoundStatus)
timeLeft.Changed:Connect(updateRoundStatus)
return DisplayManager

Script do MatchManager


local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Scripts de Módulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Valores
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
local myTimer = timer.new()
-- Funções Locais
local function timeUp()
print("Time is up!")
end
local function startTimer()
print("Timer started")
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
while myTimer:isRunning() do
-- Adicionar +1 garante que o display do timer termine em 1 em vez de 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Ao não definir o tempo para esperar, ele oferece mais precisão de looping
task.wait()
end
end
-- Funções de Modulo
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
return MatchManager

Exibir Status


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local textLabel = script.Parent
local function updateText()
textLabel.Text = status.Value
end
status.Changed:Connect(updateText)
updateText()