Hora de codificar la última fase del juego: limpieza y reinicio.El código en esta fase garantiza que los bucles del juego pasen a intermedio y que los partidos futuros comiencen igual para cada jugador.
Actualizar la interfaz gráfica
Antes de hacer limpieza y reinicio, informa a los jugadores cómo terminó el juego usando el Administrador de pantalla para mostrar el estado apropiado.
Obtener el nombre del ganador
Comience por obtener el nombre del jugador ganador si hubo uno.Anteriormente, el código verificaba si el tamaño de la tabla de jugadores activos era de 1.Para obtener el nombre del jugador restante, devuelve el nombre en el primer índice de esa tabla.
En PlayerManager, inicia una nueva función de módulo llamada getWinnerName().
function PlayerManager.getWinnerName()end-- EventosPlayers.PlayerAdded:Connect(onPlayerJoin)Añade una declaración if que se ejecuta si algo existe en activePlayers[1] .Aunque el recuento de tablas se verificó antes, el jugador podría haberse desconectado o abandonado el juego.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenendendEn la declaración if:
- Devuelve el nombre del jugador.
- Para lo demás, devuelve una cadena de errores.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
Obtener el estado final
Usa una función de módulo para tomar información del estado final correcto, ya sea que termine el temporizador o se deje a un jugador.Luego, envíe esa variable de estado al gestor de pantalla para actualizar la interfaz de estado con el mensaje apropiado.
En MatchManager , codifica una nueva función de módulo llamada getEndStatus() con un parámetro llamado endState.Para almacenar el mensaje que se enviará, agregue una variable vacía llamada statusToReturn.
function MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()endfunction MatchManager.getEndStatus(endState)local statusToReturnendmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerEstablece el valor de statusToReturn usando las declaraciones if y elseif.Compruebe las variables de estado final: FoundWinner y TimerUp.Para verificación de errores, incluya un else al final.
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 que el tiempo se agotó.
Else
- Actualizar statusToReturn con un mensaje de error en caso de que haya problemas con la obtención del 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íe 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
Mostrar y probar
Obtenga el anuncio actualizado en GameManager y muéstralo a los jugadores usando el DisplayManager.
Abre GameManager .En el bucle while verdadero, elimina la última declaración de impresión.Luego, crea una variable llamada endStatus.Establezca igual a 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, agrega una espera usando transitionTime .
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)task.wait(gameSettings.transitionTime)Inicie un servidor de prueba y verifique que los jugadores vean los siguientes mensajes para el tiempo transcurrido y las condiciones del jugador ganador .
La condición de tiempo ha expirado Condición de jugador ganador
Consejos de solución de problemas
En este punto, no puedes ver los mensajes, prueba uno de los siguientes a continuación.
- Si tu mensaje de estado final es "Error encontrado", ninguna de las condiciones tuvo éxito. Comprueba el código en MatchManager.getEndStatus().
- Si el estado final no se muestra, compruebe que task.wait(gameSettings.transitionTime) está después de enviar el mensaje a displayManager.
Iniciar nuevas partidas
Antes de comenzar una nueva partida, habrá una breve transición.Esto da tiempo a los jugadores para ver el estado final y hace que ser teletransportados al vestíbulo se sienta menos repentino.
Al final de la transición, los jugadores restantes serán eliminados de la arena y todo el código se reiniciará.Esto garantiza que los jugadores inicien la siguiente partida con una versión limpia del juego.
Gestionar transiciones
Cuando los jugadores se mueven al estado de transición, elimina 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á equipado activamente o en la mochila del jugador.
local function removePlayerWeapon(whichPlayer)-- Compruebe si existe un jugador en caso de que se desconectara o se fuera.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 la 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, utilice un bucle for para recorrer la tabla de jugadores activos. En el bucle, llame a removePlayerWeapon() y pase el jugador encontrado.
function PlayerManager.removeAllWeapons()for playerKey, whichPlayer in activePlayers doremovePlayerWeapon(whichPlayer)endend
Limpiar 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 de los jugadores.A medida que expandes el juego, se pueden agregar más, como funciones para restablecer un mapa que cambió durante una partida.
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 MatchManagerA continuación, llame a la función de limpieza.Abre GameManager y encuentra el bucle while verdadero.Así que los jugadores tienen armas eliminadas durante el intermedio del final, llama a 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 ejecuta una partida. Espera a que el temporizador se agote y confirma que la arma del jugador se elimina durante la interrupción del juego final.
Durante una partida Después del partido
Reiniciar coincidencias
Es posible que haya notado algunas otras cosas en el juego, como que los jugadores sigan en la arena después de que termine un partido.Con la coincidencia limpia, reinicie el juego siguiente.Esto incluye enviar a los jugadores en la arena de vuelta al vestíbulo y despejar la tabla de jugadores activos.Con un reinicio en lugar, un bucle de juego puede ejecutarse indefinidamente.
Primero, inicia una función para devolver a los jugadores al vestíbulo.
En PlayerManager:
- Crea una función de módulo llamada resetPlayers().
- Añade un bucle for para iterar a través de jugadores activos.
- En el bucle, llama a respawnPlayerInLobby() y pasa al 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 vacía para la próxima partida al establecerla igual a {}, 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 el administrador de partidos. Codifica 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 MatchManagerVuelve a GameManager . Al final del bucle while verdadero, llama 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 ejecuta una partida. Confirma que puedes pasar por lo menos por dos bucles de juego sin errores.
Guiones completados
A continuación, se completan los scripts para verificar doblemente tu trabajo.
Script del administrador del juego
-- 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 temporizador para usar 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ñadir +1 asegura que la pantalla del temporizador termine en 1 en lugar de 0.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- Al no establecer el tiempo para esperar, ofrece un ciclo más preciso
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 al 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)
-- Compruebe si existe un jugador en caso de que se desconectara o se fuera.
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 la 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 generación y luego la elimina de la tabla para que el próximo jugador obtenga el siguiente punto de generació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