Limpeza e redefinição

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

Hora de codificar a última fase do jogo: limpar e reiniciar.Código nesta fase garante que os loops do jogo para intermissão e que as partidas futuras comecem igualmente para cada jogador.

Atualize a GUI

Antes de fazer limpeza e redefinir, informe os jogadores como o jogo terminou usando o Gerenciador de Exibição para mostrar o status apropriado.

Obtenha o nome do vencedor

Comece por obter o nome do jogador vencedor se houve um.Anteriormente, o código verificava se o tamanho da tabela de jogadores ativos era reduzido para 1.Para obter o nome do jogador restante, retorne o nome no primeiro índice daquela tabela.

  1. No PlayerManager, inicie uma nova função de módulo chamada getWinnerName().


    function PlayerManager.getWinnerName()
    end
    -- Eventos
    Players.PlayerAdded:Connect(onPlayerJoin)
  2. Adicione uma declaração if que execute se algo existir em activePlayers[1] .Embora a contagem de mesas tenha sido verificada antes, o jogador pode ter se desconectado ou deixado o jogo.


    function PlayerManager.getWinnerName()
    local winningPlayer = activePlayers[1]
    if winningPlayer then
    end
    end
  3. Na declaração if:

    • Retorne o nome do jogador.
    • Para o resto, retorne uma string de erro.

    function PlayerManager.getWinnerName()
    local winningPlayer = activePlayers[1]
    if winningPlayer then
    return winningPlayer.Name
    else
    return "Error: No winning player found"
    end
    end

Obtenha o status final

Use uma função de módulo para obter informações do estado final correto, se o cronômetro termina ou um jogador é deixado.Então, envie essa variável de estado para o Gerenciador de Exibição para atualizar o status GUI com a mensagem apropriada.

  1. Em Gerenciador de Partida , códigue uma nova função de módulo chamada getEndStatus() com um parâmetro chamado endState .Para armazenar a mensagem que será enviada, adicione uma variável vazia chamada statusToReturn.


    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
    function MatchManager.getEndStatus(endState)
    local statusToReturn
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Defina o valor de statusToReturn usando as declarações if e elseif.Verifique as variáveis de estado final: FoundWinner e TimerUp.Para verificação de erros, inclua um else no final.


    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    elseif endState == gameSettings.endStates.TimerUp then
    else
    end
    end
  3. Adicione o seguinte para cada condição:

    FoundWinner

    • Uma variável para o vencedor usando playerManager.getWinnerName() .
    • Atualize statusToReturn com uma string que anuncia o vencedor.

    TimerUp

    • Atualize statusToReturn com uma string que anuncia o tempo acabou.

    Else

    • Atualize statusToReturn com uma mensagem de erro caso haja problemas com a obtenção da mensagem do jogo final.

    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    local winnerName = playerManager.getWinnerName()
    statusToReturn = "Winner is : " .. winnerName
    elseif endState == gameSettings.endStates.TimerUp then
    statusToReturn = "Time ran out!"
    else
    statusToReturn = "Error found"
    end
    end
  4. Envie de volta a mensagem digitando return statusToReturn.


    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    local winnerName = playerManager.getWinnerName()
    statusToReturn = "Winner is : " .. winnerName
    elseif endState == gameSettings.endStates.TimerUp then
    statusToReturn = "Time ran out!"
    else
    statusToReturn = "Error found"
    end
    return statusToReturn
    end

Exibição e teste

Obtenha o anúncio atualizado no Gerenciador de Jogo e exibi-lo para os jogadores usando o Gerenciador de Exibição.

  1. Abra Gerenciador de Jogo .No loop while verdadeiro, exclua a última declaração de impressão.Então, crie uma variável chamada endStatus.Defina-o igual ao chamando matchManager.getEndStatus(endState).


    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()
    local endState = matchEnd.Event:Wait()
    local endStatus = matchManager.getEndStatus(endState)
    end
  2. Para exibir a mensagem retornada no rótulo da GUI, chame displayManager.updateStatus() e passe em endStatus.


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
  3. Então o jogo pára para que os jogadores vejam a mensagem, adicione uma espera usando transitionTime .


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    task.wait(gameSettings.transitionTime)
  4. Inicie um servidor de teste e verifique se os jogadores veem as seguintes mensagens para o tempo até e as condições do jogador vencedor .

    A condição acabou o tempo
    Condição de jogador vencedor

Dicas de solução de problemas

Neste ponto, você não consegue ver as mensagens, tente uma das seguintes abaixo.

  • Se a sua mensagem de status final for "Erro encontrado", nenhuma das condições foi bem-sucedida. Verifique o código em MatchManager.getEndStatus().
  • Se o status final não for exibido, verifique se task.wait(gameSettings.transitionTime) está após enviar a mensagem para o displayManager.

Começar novas partidas

Antes de iniciar uma nova partida, haverá uma breve transição.Isso dá aos jogadores tempo para ver o status final e torna ser teletransportado para o lobby menos repentino.

No final da transição, os jogadores restantes serão removidos da arena e todo o código será redefinido.Isso garante que os jogadores iniciem a próxima partida com uma versão limpa do jogo.

Lidar com transições

Quando os jogadores se movem para o estado de transição, removam suas armas.

  1. No PlayerManager, encontre as funções locais.Copie e cole o código destacado para removePlayerWeapon().O código removerá a arma de um jogador individual se estiver equipada ativamente ou na mochila do jogador.


    local function removePlayerWeapon(whichPlayer)
    -- Verifique se um jogador existe caso ele se desconecte ou saia.
    if whichPlayer then
    local character = whichPlayer.Character
    -- Se o jogador tiver atualmente em seu personagem
    local weapon = character:FindFirstChild("Weapon")
    if weapon then
    weapon:Destroy()
    end
    -- Se o jogador tem a arma em sua mochila
    local backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")
    if backpackWeapon then
    backpackWeapon:Destroy()
    end
    else
    print("No player to remove weapon")
    end
    end
  2. Inicie uma nova função de módulo chamada removeAllWeapons().


    function PlayerManager.removeAllWeapons()
    end
    -- Eventos
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  3. Nessa função, use um ciclo for para percorrer a tabela de jogadores ativos. No ciclo, chame removePlayerWeapon() e passe o jogador encontrado.


    function PlayerManager.removeAllWeapons()
    for playerKey, whichPlayer in activePlayers do
    removePlayerWeapon(whichPlayer)
    end
    end

Limpe entre as partidas

Limpeza será sua própria função no MatchManager.Por enquanto, a limpeza usará apenas a função criada anteriormente para remover as armas do jogador.À medida que você expande o jogo, mais pode ser adicionado, como funções para redefinir um mapa que mudou durante uma partida.

  1. Abra o Gerenciador de Partidas. Adicione uma nova função de módulo chamada cleanupMatch(). Nessa função, chame playerManager.removeAllWeapons().


    function MatchManager.cleanupMatch()
    playerManager.removeAllWeapons()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Em seguida, chame a função de limpeza.Abra Gerenciador de Jogo e encontre o ciclo while verdadeiro.Então, os jogadores têm armas removidas durante a intermissão final, chame matchManager.cleanupMatch() antes da última task.wait().


    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()
    local endState = matchEnd.Event:Wait()
    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    matchManager.cleanupMatch()
    task.wait(gameSettings.transitionTime)
    end
  3. Inicie um servidor de teste e execute uma partida. Espere que o tempo acabe e confirme que a arma do jogador é removida durante a intermissão do jogo final.

    Durante uma partida
    Após a partida

Redefinir partidas

Você pode ter notado algumas outras coisas no jogo, como os jogadores ainda estarem na arena depois que uma partida termina.Com a partida limpa, próximo reinicie o jogo.Isso inclui enviar jogadores na arena de volta ao lobby e limpar a mesa de jogadores ativos.Com um reset em vigor, um ciclo de jogo pode executar indefinidamente.

Primeiro, inicie uma função para enviar os jogadores de volta ao lobby.

  1. No Gerenciador de Jogadores:

    • Crie uma função de módulo chamada resetPlayers().
    • Adicione um loop for para iterar através de jogadores ativos.
    • No loop, chame respawnPlayerInLobby() e passe o jogador como parâmetro.

    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    end
    -- Eventos
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  2. Certifique-se de que a tabela activePlayers vazia para a próxima partida, definindo-a igual a {}, que é uma maneira rápida de redefinir para uma tabela vazia.


    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    activePlayers = {}
    end
  3. Abra o Gerenciador de Partidas. Codifique uma nova função de módulo chamada resetMatch() e chame playerManager.resetPlayers().


    function MatchManager.resetMatch()
    playerManager.resetPlayers()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  4. Volte para Gerenciador de Jogo . No final do loop while verdadeiro, chame matchManager.resetMatch() .


    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()
    local endState = matchEnd.Event:Wait()
    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    matchManager.cleanupMatch()
    task.wait(gameSettings.transitionTime)
    matchManager.resetMatch()
    end
  5. Inicie um servidor de teste e execute uma partida. Confirme que você pode pelo menos passar por dois ciclos de jogo sem erros.

Scripts concluídos

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

Script do Gerenciador de Jogo


-- 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()
local endState = matchEnd.Event:Wait()
local endStatus = matchManager.getEndStatus(endState)
displayManager.updateStatus(endStatus)
matchManager.cleanupMatch()
task.wait(gameSettings.transitionTime)
matchManager.resetMatch()
end

Script do Gerenciador de Partida


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 displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
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")
-- Cria um novo objeto de cronômetro para ser usado para acompanhar o tempo da partida.
local myTimer = timer.new()
-- Funções Locais
local function stopTimer()
myTimer:stop()
end
local function timeUp()
matchEnd:Fire(gameSettings.endStates.TimerUp)
end
local function startTimer()
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
while myTimer:isRunning() do
-- Adicionar +1 garante que a exibição do tempo termine em 1 ao invés de 0.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- Ao não definir o tempo para espera, oferece um looping mais preciso
task.wait()
end
end
-- Funções de Módulo
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
function MatchManager.getEndStatus(endState)
local messageToReturn
if endState == gameSettings.endStates.FoundWinner then
local winnerName = playerManager.getWinnerName()
messageToReturn = "Winner is : " .. winnerName
elseif endState == gameSettings.endStates.TimerUp then
messageToReturn = "Time ran out!"
else
messageToReturn = "Error found"
end
return messageToReturn
end
function MatchManager.cleanupMatch()
playerManager.removeAllWeapons()
end
function MatchManager.resetMatch()
playerManager.resetPlayers()
end
matchStart.Event:Connect(startTimer)
matchEnd.Event:Connect(stopTimer)
return MatchManager

Script do Gerenciador de Jogadores


local PlayerManager = {}
-- Serviços
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Móveis
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- 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")
-- Variáveis do Jogador
local activePlayers = {}
local playerWeapon = ServerStorage.Weapon
local function checkPlayerCount()
if #activePlayers == 1 then
matchEnd:Fire(gameSettings.endStates.FoundWinner)
print("Found winner")
end
end
local function removeActivePlayer(player)
print("removing player")
for playerKey, whichPlayer in activePlayers do
if whichPlayer == player then
table.remove(activePlayers, playerKey)
playersLeft.Value = #activePlayers
checkPlayerCount()
end
end
end
local function respawnPlayerInLobby(player)
player.RespawnLocation = lobbySpawn
player:LoadCharacter()
end
local function preparePlayer(player, whichSpawn)
player.RespawnLocation = whichSpawn
player:LoadCharacter()
local character = player.Character or player.CharacterAdded:Wait()
-- Dê uma ferramenta ao jogador
local sword = playerWeapon:Clone()
sword.Parent = character
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
respawnPlayerInLobby(player)
removeActivePlayer(player)
end)
end
local function onPlayerJoin(player)
player.RespawnLocation = lobbySpawn
end
local function removePlayerWeapon(whichPlayer)
-- Verifique se um jogador existe caso ele se desconecte ou saia.
if whichPlayer then
local character = whichPlayer.Character
-- Se o jogador tiver atualmente em seu personagem
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- Se o jogador tem a arma em sua mochila
local backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")
if backpackWeapon then
backpackWeapon:Destroy()
end
else
print("No player to remove weapon")
end
end
function PlayerManager.sendPlayersToMatch()
local availableSpawnPoints = spawnLocations:GetChildren()
for playerKey, whichPlayer in Players:GetPlayers() do
table.insert(activePlayers,whichPlayer)
-- Obtém um local de spawn e depois remove-o da tabela para que o próximo jogador obtenha o próximo spawn
local spawnLocation = table.remove(availableSpawnPoints, 1)
preparePlayer(whichPlayer, spawnLocation)
end
playersLeft.Value = #activePlayers
end
function PlayerManager.getWinnerName()
local winningPlayer = activePlayers[1]
if winningPlayer then
return winningPlayer.Name
else
return "Error: No player found"
end
end
function PlayerManager.removeAllWeapons()
for playerKey, whichPlayer in activePlayers do
removePlayerWeapon(whichPlayer)
end
end
function PlayerManager.resetPlayers()
for playerKey, whichPlayer in activePlayers do
respawnPlayerInLobby(whichPlayer)
end
activePlayers = {}
end
-- Eventos
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager