Limpiar y restablecer

*Este contenido se traduce usando la IA (Beta) y puede contener errores. Para ver esta página en inglés, haz clic en aquí.

Es hora de codificar la última fase del juego: limpiar y restablecer. El código en esta fase garantiza que los ciclos del juego se interrumpan y que las futuras partidas se inicien para cada jugador.

Actualizar la Interfaz gráfica (o GUI)

Antes de limpiar y restablecer, informa a los jugadores cómo terminó el juego usando el DisplayManager para mostrar el estado apropiado.

Obtener el nombre del ganador

Comience con el nombre del jugador ganador si hubiera uno. Antes, el código verificó si el tamaño de la tabla de jugadores activos era menor a 1. Para obtener el nombre del jugador restante,返回该表的第一个索引。

  1. En PlayerManager, inicia una nueva función de módulo llamada getWinnerName() .


    function PlayerManager.getWinnerName()
    end
    -- Eventos
    Players.PlayerAdded:Connect(onPlayerJoin)
  2. Agregue una declaración if que se ejecuta si algo existe en activePlayers[1] . Aunque el recuento de tablas se verificó antes, el jugador puede haberse desconectado o salido del juego.


    function PlayerManager.getWinnerName()
    local winningPlayer = activePlayers[1]
    if winningPlayer then
    end
    end
  3. En la declaración if:

    • Devuelve el nombre del jugador.
    • Para el resto, returna una cadena de error.

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

Obteniendo el estado final

Usa una función de módulo para tomar información del estado correcto, sea que el temporizador termine o se deje a un jugador. Luego, envía esa variable de estado a DisplayManager para actualizar la GUI de estado con el mensaje apropiado.

  1. En MatchManager , código una nueva función de módulo llamada getEndStatus() con un parámetro llamado endState . Para almacenar el mensaje que se enviará, agrega una variable vacía llamada 1> statusToReturn1> .


    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. Establezca el valor de statusToReturn con el uso de if yelif declaraciones. Compruebe las variables de estado final: FoundWinner y TimerUp . Para la detección de errores, incluya un else en el finalizar.


    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    elseif endState == gameSettings.endStates.TimerUp then
    else
    end
    end
  3. Añade lo siguiente para cada condición:

    FoundWinner

    • Una variable para el ganador usando playerManager.getWinnerName() .
    • Actualizar statusToReturn con una cadena que anuncia al ganador.

    TimerUp

    • Actualizar statusToReturn con una cadena que anuncia el tiempo que ha corrido.

    Else

    • Actualizar statusToReturn con un mensaje de error en caso de que haya problemas para obtener el mensaje del juego 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. Envía de vuelta el mensaje escribiendo 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

Mostrando y probando

Obtenga el anuncio actualizado en GameManager y muéstralo a los jugadores usando el DisplayManager.

  1. Abre GameManager . Mientras que cierto, elimina last print statement . Luego, crea una variable llamada endStatus. Establece igual que llamar 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 mostrar el mensaje devuelto en la etiqueta GUI, llame a displayManager.updateStatus() y pase en endStatus .


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
  3. Así que el juego se detiene para que los jugadores vean el mensaje, añade un tiempo de espera usando transitionTime .


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    task.wait(gameSettings.transitionTime)
  4. Inicie un servidor de prueba y verifique si los jugadores ven los siguientes mensajes para el tiempo y las condiciones de los jugadores ganadores.

    condición de tiempo de caducidad
    Condición del jugador ganador

Consejos de solución de problemas

En este momento, no puedes ver los mensajes, intenta uno de los siguientes abajo.

  • Si el mensaje de estado de tu final es "Error encontrado", ninguna de las condiciones fue exitosa. Comprueba el código en MatchManager.getEndStatus() contra los ejemplos de código.
  • Si el estado final no se muestra, asegúrese de que task.wait(gameSettings.transitionTime) esté después de enviar el mensaje a显示管理器。

Comenzando Nuevas Partidas

Antes de comenzar una nueva coincidir, habrá una breve transición. Esto le da a los jugadores tiempo para ver el estado final y hace que ser teletransportado al lobby se sienta menos sorpresivo.

Al finalizar la transición, los jugadores restantes serán eliminados de la arena y todo el código se restablecerá. Esto asegura que los jugadores comienzen la próxima partida con una versión limpia del juego.

Manipulando transiciones

Cuando los jugadores se muevan al estado de transición, quítales sus armas.

  1. En PlayerManager, encuentra las funciones locales. Copia y pega el código resaltado para removePlayerWeapon() abajo. El código eliminará el arma de un jugador individual si está activamente equipada o en la mochila del jugador.


    local function removePlayerWeapon(whichPlayer)
    -- Revise si un jugador existe en caso de que se hayan desconectado o salido.
    if whichPlayer then
    local character = whichPlayer.Character
    -- Si el jugador lo tiene actualmente en su personaje
    local weapon = character:FindFirstChild("Weapon")
    if weapon then
    weapon:Destroy()
    end
    -- Si el jugador tiene el arma en su mochila
    local backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")
    if backpackWeapon then
    backpackWeapon:Destroy()
    end
    else
    print("No player to remove weapon")
    end
    end
  2. Inicia una nueva función de módulo llamada removeAllWeapons() .


    function PlayerManager.removeAllWeapons()
    end
    -- Eventos
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  3. En esa función, usa un for loop para pasar por la tabla de jugadores activos. En el loop, llama a removePlayerWeapon() y pásalo en el jugador encontrado.


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

Limpiando entre partidos

La limpieza será su propia función en MatchManager. Por ahora, la limpieza solo usará esa función previamente creada para eliminar las armas del jugador. A medida que expande el juego, se agregarán más, como funciones para restablecer un mapa que cambió durante una coincidir.

  1. Abre el administrador de partidos. Añade una nueva función de módulo llamada cleanupMatch() . En esa función, llama playerManager.removeAllWeapons() .


    function MatchManager.cleanupMatch()
    playerManager.removeAllWeapons()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Luego, llame a la función de limpieza. Abre GameManager y encuentra el mientras que cierto doble. Así que los jugadores tienen armas eliminadas durante el intermedio de la finalización, llama matchManager.cleanupMatch() antes del último 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. Inicia un servidor de prueba y realiza una coincidir. Espera a que el temporizador se acabe y confirma que el arma del jugador se elimina durante el intermedio del juego final.

    Durante una partida
    Después de la igualdad

Restableciendo Partidos

Tal vez te hayas dado cuenta de algunas otras cosas en el juego, como que los jugadores todavía estén en la arena después de que termine un partido. Con el partido limpiado, reinicia el juego. Esto incluye enviar jugadores en la arena de vuelta al lobby y limpiar la tabla de jugadores activos. Con un reinicio en el lugar, un bucle de juego puede ejecutarse indefinidamente.

Primero, inicia una función para enviar jugadores de vuelta al lobby.

  1. En PlayerManager:

    • Crea una función de módulo llamada resetPlayers() .
    • Añade un for para repetición a través de los jugadores activos.
    • En el bucle, llama a respawnPlayerInLobby() y pasa el jugador como parámetro.

    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    end
    -- Eventos
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  2. Asegúrese de que la tabla activePlayers esté vacía para la próxima partida al establecerla igual a 5> , lo que es una manera rápida de restablecer a una tabla vacía.


    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    activePlayers = {}
    end
  3. Abre MatchManager. Código una nueva función de módulo llamada resetMatch() y llama playerManager.resetPlayers() .


    function MatchManager.resetMatch()
    playerManager.resetPlayers()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  4. Vuelva a GameManager . Al final del tiempo, cuando la verdadera doble ciclo, llame a 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. Inicia un servidor de prueba y realiza una coincidir. Confirma que puedes al menos pasar por dos ciclos de juego sin ningún error.

Scripts Completados

A continuación, están los scripts completados para revisar tu trabajo.

Script de GameManager


-- Servicios
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

Guión de MatchManager


local MatchManager = {}
-- Servicios
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")
-- Crea un nuevo objeto de tiempo para usarlo para rastrear el tiempo de la partida.
local myTimer = timer.new()
-- Funciones locales
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
-- Añadiendo +1 asegura que la pantalla de tiempo muestre 1 en lugar de 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Al no configurar el tiempo para esperar, ofrece más preciso flujo
task.wait()
end
end
-- Funciones 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 de PlayerManager


local PlayerManager = {}
-- Servicios
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Módulos
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Variables 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")
-- Variables del jugador
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()
-- Darle a un jugador una herramienta
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)
-- Revise si un jugador existe en caso de que se hayan desconectado o salido.
if whichPlayer then
local character = whichPlayer.Character
-- Si el jugador lo tiene actualmente en su personaje
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- Si el jugador tiene el arma en su 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)
-- Obtiene una ubicación de spawn y luego la elimina de la tabla para que el próximo jugador obtenga la siguiente regeneración
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