Pulizia e Reset

*Questo contenuto è tradotto usando AI (Beta) e potrebbe contenere errori. Per visualizzare questa pagina in inglese, clicca qui.

È ora di codificare l'ultima fase del Gioco: la pulizia e il Ripristina. Il codice in questa fase garantisce che i giochi si svolgono ininterrotti e che le future partite iniziano lo stesso per ogni Giocatore.

Aggiornamento della GUI or Intefaccia grafica utente

Prima di fare pulizia e Ripristina, informa i giocatori come il gioco è finito usando il DisplayManager per mostrare lo Statoappropriato.

Ottenere il nome del vincitore

Inizia ottenendo il nome del Giocatorevincitore se c'era uno. In precedenza, il codice controllava se la dimensione della tabella dei giocatori attivi era inferiore a 1. Per ottenere il nome del Giocatorerimanente, restituisci il nome all'indice di primo della tabella.

  1. In PlayerManager, inizia una nuova funzione del modulo chiamata getWinnerName() .


    function PlayerManager.getWinnerName()
    end
    -- Eventi
    Players.PlayerAdded:Connect(onPlayerJoin)
  2. Aggiungi una dichiarazione if che viene eseguita se esiste qualcosa in activePlayers[1] . Anche se il numero di tabelle è stato controllato prima, il giocatore potrebbe essere disconnesso o uscito dal Gioco.


    function PlayerManager.getWinnerName()
    local winningPlayer = activePlayers[1]
    if winningPlayer then
    end
    end
  3. Nella dichiarazione if:

    • Restituisci il nome del Giocatore.
    • Per gli altri, restituisci una Stringadi errore.

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

Ottenere lo stato finale

Usa una funzione del modulo per ottenere informazioni dallo stato corretto, che il timer finisca o che un giocatore venga lasciato. Quindi, invia quella variabile di stato a DisplayManager per aggiornare la GUI di stato con il Messaggioappropriato.

  1. In MatchManager , codice una nuova funzione del modulo chiamata getEndStatus() con un parametro chiamato endState . Per memorizzare il messaggio che verrà inviato, aggiungi una variabile vuota chiamata 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. Imposta il valore di statusToReturn utilizzando if e elif statement. Controlla le variabili di stato alla fine: FoundWinner e TimerUp . Per il controllo degli errori, includi un altro alla Terminare.


    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    elseif endState == gameSettings.endStates.TimerUp then
    else
    end
    end
  3. Aggiungi quanto segue per ciascuna condizione:

    FoundWinner

    • Una variabile per il vincitore usando playerManager.getWinnerName() .
    • Aggiorna statusToReturn con una stringa che annuncia il vincitore.

    TimerUp

    • Aggiorna statusToReturn con una stringa che annuncia il tempo scaduto.

    Else

    • Aggiorna statusToReturn con un messaggio di errore in caso di problemi con l'ottenimento del Messaggiodi fine partita.

    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. Invia il messaggio facendo clic su 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

Visualizzazione e Test

Ottieni l'annuncio aggiornato in GameManager e mostralo ai giocatori usando il DisplayManager.

  1. Apri GameManager . In while true do loop, delete l'ultima dichiarazione di stampa. Quindi, crea una variabile chiamata endStatus. Impostarla uguale a chiamare 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. Per visualizzare il messaggio restituito nell'EtichettaGUI, chiama displayManager.updateStatus() e passa in endStatus .


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
  3. Quindi il gioco si ferma per consentire ai giocatori di vedere il Messaggio, aggiungi un'attesa usando transitionTime .


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    task.wait(gameSettings.transitionTime)
  4. Avvia un test server e controlla che i giocatori visualizzino i seguenti messaggi per il tempo up e le condizioni di vincitore.

    condizione di tempo scaduto
    Condizione del giocatore vincitore

Risolvere i problemi

Al momento, non sei in grado di visualizzare i messaggi, prova uno dei seguenti sotto.

  • Se il tuo messaggio di stato finale è "Errore trovato", nessuna delle condizioni è riuscita. Controlla il codice in MatchManager.getEndStatus() contro gli esempi di codice.
  • Se lo stato di fine non viene visualizzato, controlla che task.wait(gameSettings.transitionTime) sia dopo l'invio del messaggio a displayManager.

Inizio Nuove Partite

Prima di iniziare una nuova Corrisponde, ci sarà una breve transizione. Ciò dà ai giocatori il tempo di vedere lo stato di fine e rendere il teletrasporto alla lobby meno improvviso.

Alla fine della transizione, i giocatori rimanenti dall'arena saranno rimossi e tutto il codice verrà Ripristina. Ciò garantisce che i giocatori inizieranno la prossima partita con una versione pulita del Gioco.

Trattamento delle transizioni

Quando i giocatori entrano in stato di transizione, rimuovono le loro armi.

  1. In PlayerManager, trova le funzioni locali. Copia e pasta il codice evidenziato per removePlayerWeapon() sotto. Il codice rimuoverà l'arma di un Giocatoreindividuale se è attivamente equipaggiato o nello zaino del Giocatore.


    local function removePlayerWeapon(whichPlayer)
    -- Controlla se un giocatore esiste in caso di loro disconnessione o uscita.
    if whichPlayer then
    local character = whichPlayer.Character
    -- Se il giocatore lo ha attualmente nel suo personaggio
    local weapon = character:FindFirstChild("Weapon")
    if weapon then
    weapon:Destroy()
    end
    -- Se il giocatore ha l'arma nel suo zaino
    local backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")
    if backpackWeapon then
    backpackWeapon:Destroy()
    end
    else
    print("No player to remove weapon")
    end
    end
  2. Inizia una nuova funzione del modulo chiamata removeAllWeapons() .


    function PlayerManager.removeAllWeapons()
    end
    -- Eventi
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  3. In quella funzione, usa un for loop per passare attraverso la tabella dei giocatori attivi. In loop, chiama removePlayerWeapon() e passa nel giocatore trovato.


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

Pulizia tra le partite

Il pulire sarà la sua funzione in MatchManager. Per ora, il pulire utilizzera solo la funzione precedentemente creata per rimuovere le armi del giocatore. Man mano che espandi il Gioco, puoi aggiungere ulteriori funzioni, come funzioni per ripristinare una mappa che è cambiata durante una Corrisponde.

  1. Apri MatchManager. Aggiungi una nuova funzione del modulo chiamata cleanupMatch() . In quella funzione, chiami playerManager.removeAllWeapons() .


    function MatchManager.cleanupMatch()
    playerManager.removeAllWeapons()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Successivamente, chiama la funzione di pulizia. Apri GameManager e trova il while true do loop. Quindi i giocatori hanno le armi rimosse durante l'intervallo di finzione, chiama matchManager.cleanupMatch() prima dell'ultimo 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. Avvia un server di prova e esegui una Corrisponde. Attendi che il timer finisca e conferma che l'arma del Giocatoresia rimossa durante l'interruzione della partita di fine gioco.

    Durante una partita
    Dopo la partita

Ripristinare le Partite

Potresti aver notato alcune altre cose nel Gioco, come i giocatori che vengono ancora nell'arena dopo la fine di una partita. Con la partita pulita, quindi ripristina il Gioco. Ciò include l'invio dei giocatori nell'arena nel lobby e la pulizia della tabella dei giocatori attivi. Con un reset in Posto, un ciclo di gioco può essere eseguito indefinitamente.

Per prima cosa, inizia una funzione per inviare i giocatori alla lobby.

  1. In PlayerManager:

    • Crea una funzione del modulo chiamata resetPlayers() .
    • Aggiungi un for loop per itere attraverso i giocatori attivi.
    • In loop, call respawnPlayerInLobby() and pass in the player as the parameter.

    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    end
    -- Eventi
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  2. Assicurati che la tabella activePlayers sia vuota per il prossimo match impostandola uguale a {} , che è un modo rapido per resettare a una tabella vuota.


    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    activePlayers = {}
    end
  3. Apri MatchManager. Codice una nuova funzione del modulo chiamata resetMatch() e chiama playerManager.resetPlayers() .


    function MatchManager.resetMatch()
    playerManager.resetPlayers()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  4. Torna a GameManager . Alla fine del while true do loop, chiama 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. Inizia un server di prova e esegui una Corrisponde. Conferma che puoi almeno passare attraverso due loop di gioco senza errori.

Script completati

Di seguito sono gli script completati per il doppio controllo del tuo lavoro.

Script del GameManager


-- Servizi
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Script del modulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Eventi
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 del MatchManager


local MatchManager = {}
-- Servizi
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Script del modulo
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"))
-- Eventi
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Valori
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Crea un nuovo oggetto timer per essere utilizzato per tracciare il tempo della partita.
local myTimer = timer.new()
-- Funzioni locali
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
-- L'aggiunta di +1 assicura che il timer finisca a 1 invece di 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Impostando il tempo di attesa, offre un looping più preciso
task.wait()
end
end
-- Funzioni del modulo
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 del lettore


local PlayerManager = {}
-- Servizi
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Moduli
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Eventi
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Variabili di mappa
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Valori
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Variabili del giocatore
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()
-- Dai al giocatore uno strumento
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)
-- Controlla se un giocatore esiste in caso di loro disconnessione o uscita.
if whichPlayer then
local character = whichPlayer.Character
-- Se il giocatore lo ha attualmente nel suo personaggio
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- Se il giocatore ha l'arma nel suo zaino
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)
-- Ottiene una posizione di spawn e poi la rimuove dalla tabella in modo che il prossimo giocatore ottenga la prossima Rigenerare
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
-- Eventi
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager