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,返回该表的第一个索引。
En PlayerManager, inicia una nueva función de módulo llamada getWinnerName() .
function PlayerManager.getWinnerName()end-- EventosPlayers.PlayerAdded:Connect(onPlayerJoin)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 thenendendEn 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 thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
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.
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()endfunction MatchManager.getEndStatus(endState)local statusToReturnendmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerEstablezca 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 statusToReturnif endState == gameSettings.endStates.FoundWinner thenelseif endState == gameSettings.endStates.TimerUp thenelseendendAñ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 statusToReturnif endState == gameSettings.endStates.FoundWinner thenlocal winnerName = playerManager.getWinnerName()statusToReturn = "Winner is : " .. winnerNameelseif endState == gameSettings.endStates.TimerUp thenstatusToReturn = "Time ran out!"elsestatusToReturn = "Error found"endendEnvía de vuelta el mensaje escribiendo return statusToReturn .
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenlocal winnerName = playerManager.getWinnerName()statusToReturn = "Winner is : " .. winnerNameelseif endState == gameSettings.endStates.TimerUp thenstatusToReturn = "Time ran out!"elsestatusToReturn = "Error found"endreturn statusToReturnend
Mostrando y probando
Obtenga el anuncio actualizado en GameManager y muéstralo a los jugadores usando el DisplayManager.
Abre GameManager . Mientras que cierto, elimina last print statement . Luego, crea una variable llamada endStatus. Establece igual que llamar matchManager.getEndStatus(endState) .
while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.updateStatus("Get ready!")task.wait(gameSettings.transitionTime)matchManager.prepareGame()local endState = matchEnd.Event:Wait()local endStatus = matchManager.getEndStatus(endState)endPara mostrar el mensaje devuelto en la etiqueta GUI, llame a displayManager.updateStatus() y pase en endStatus .
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)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)Inicie un servidor de prueba y verifique si los jugadores ven los siguientes mensajes para el tiempo y las condiciones de los jugadores ganadores.
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.
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 thenlocal character = whichPlayer.Character-- Si el jugador lo tiene actualmente en su personajelocal weapon = character:FindFirstChild("Weapon")if weapon thenweapon:Destroy()end-- Si el jugador tiene el arma en su mochilalocal backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")if backpackWeapon thenbackpackWeapon:Destroy()endelseprint("No player to remove weapon")endendInicia una nueva función de módulo llamada removeAllWeapons() .
function PlayerManager.removeAllWeapons()end-- EventosPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerEn 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 doremovePlayerWeapon(whichPlayer)endend
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.
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()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerLuego, 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 dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.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)endInicia 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.
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.
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 dorespawnPlayerInLobby(whichPlayer)endend-- EventosPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerAsegú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 dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endAbre MatchManager. Código una nueva función de módulo llamada resetMatch() y llama playerManager.resetPlayers() .
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerVuelva a GameManager . Al final del tiempo, cuando la verdadera doble ciclo, llame a matchManager.resetMatch() .
while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.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()endInicia 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
-- Servicioslocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Scripts de módulolocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- Eventoslocal events = ServerStorage:WaitForChild("Events")local matchEnd = events:WaitForChild("MatchEnd")while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.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