Pulizia e ripristino

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

È tempo di codificare l'ultima fase del gioco: pulizia e ripristino.Il codice in questa fase garantisce che i cicli di gioco passino all'intermissione e che le partite future inizino allo stesso modo per ogni giocatore.

Aggiorna la GUI

Prima di fare pulizia e ripristino, informa i giocatori su come è finito il gioco utilizzando il DisplayManager per mostrare lo stato appropriato.

Ottieni il nome del vincitore

Inizia ottenendo il nome del giocatore vincitore se c'era uno.In precedenza, il codice controllava se la dimensione della tabella dei giocatori attivi fosse ridotta a 1.Per ottenere il nome del giocatore rimanente, restituisci il nome nell'indice iniziale di quella tabella.

  1. In PlayerManager, avvia 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 qualcosa esiste in activePlayers[1] .Anche se il conteggio della tabella è stato controllato prima, il giocatore potrebbe essere disconnesso o aver lasciato il gioco.


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

    • Restituisci il nome del giocatore.
    • Per il resto, restituisci una stringa di errore.

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

Ottieni lo stato finale

Usa una funzione del modulo per prendere le informazioni dallo stato finale corretto, sia che il timer finisca o che un giocatore venga lasciato.Quindi, invia quella variabile di stato a DisplayManager per aggiornare lo stato GUI con il messaggio appropriato.

  1. In MatchManager , codifica una nuova funzione del modulo con il nome getEndStatus() con un parametro chiamato endState.Per archiviare il messaggio che verrà inviato, aggiungi una variabile vuota chiamata 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. Imposta il valore di statusToReturn usando le dichiarazioni if e elseif.Controlla le variabili di stato finale: FoundWinner e TimerUp.Per il controllo degli errori, includi un else alla fine.


    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 ogni condizione:

    FoundWinner

    • Una variabile per il vincitore utilizzando 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 messaggio di gioco finale.

    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 nuovamente il messaggio 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

Mostra e test

Ottieni l'annuncio aggiornato in GameManager e visualizzalo ai giocatori utilizzando il DisplayManager.

  1. Apri GameManager .Nel while true do loop, elimina l'ultima dichiarazione di stampa.Quindi, crea una variabile chiamata endStatus.Impostalo 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'etichetta GUI, 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 vedano i seguenti messaggi per il tempo fino e le condizioni del giocatore vincitore.

    La condizione è scaduta nel tempo
    Condizione del giocatore vincitore

Suggerimenti per la risoluzione dei problemi

A questo punto, non è possibile visualizzare i messaggi, prova uno dei seguenti.

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

Inizia nuove partite

Prima di iniziare una nuova partita, ci sarà una breve transizione.Questo dà ai giocatori il tempo di vedere lo stato finale e rende il teletrasporto nella lobby meno improvviso.

Alla fine della transizione, i giocatori rimanenti verranno rimossi dall'arena e tutto il codice verrà ripristinato.Questo garantisce che i giocatori inizieranno la prossima partita con una versione pulita del gioco.

Gestire le transizioni

Quando i giocatori si muovono nello stato di transizione, rimuovi 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 singolo giocatore se è attivamente equipaggiata o nel suo zaino.


    local function removePlayerWeapon(whichPlayer)
    -- Controlla se un giocatore esiste nel caso in cui si sia disconnesso o se ne sia andato.
    if whichPlayer then
    local character = whichPlayer.Character
    -- Se il giocatore lo ha attualmente sul 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. Avvia una nuova funzione del modulo chiamata removeAllWeapons() .


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


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

Pulisci tra le partite

La pulizia sarà una propria funzione in MatchManager.Per ora, la pulizia utilizzerà solo la funzione precedentemente creata per rimuovere le armi del giocatore.Mentre espandi il gioco, possono essere aggiunti ulteriori elementi, come funzioni per ripristinare una mappa che è cambiata durante una partita.

  1. Apri MatchManager. Aggiungi una nuova funzione del modulo chiamata cleanupMatch(). In quella funzione, chiama 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 ciclo while true.Quindi i giocatori hanno le armi rimosse durante l'intervallo finale, chiama prima dell'ultimo >.


    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 partita. Attendi che il timer finisca e conferma che l'arma del giocatore viene rimossa durante l'intervallo della partita finale.

    Durante una partita
    Dopo la partita

Ripristina le partite

Potresti aver notato alcune altre cose nel gioco, come i giocatori che sono ancora nell'arena dopo una partita finita.Con la partita pulita, ripristina il gioco successivamente.Questo include l'invio dei giocatori nell'arena indietro nella lobby e la pulizia del tavolo dei giocatori attivi.Con un reset in atto, un ciclo di gioco può essere eseguito indefinitamente.

Prima, avvia una funzione per inviare i giocatori indietro alla lobby.

  1. Nel PlayerManager:

    • Crea una funzione del modulo chiamata resetPlayers().
    • Aggiungi un ciclo while per iterare attraverso i giocatori attivi.
    • Nel ciclo, chiama respawnPlayerInLobby() e passa nel giocatore come parametro.

    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 la prossima partita impostandola uguale a {}, che è un modo rapido per ripristinare una tabella vuota.


    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    activePlayers = {}
    end
  3. Apri MatchManager. Codifica 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 . Al termine del ciclo while true, 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. Avvia un server di prova e esegui una partita. Conferma che puoi almeno passare attraverso due cicli di gioco senza errori.

Script completati

Di seguito sono completati gli script per controllare due volte il tuo lavoro.

Script di 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 di 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 da utilizzare per tenere traccia del tempo di 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
-- Aggiungere +1 assicura che la visualizzazione del timer finisca a 1 invece di 0.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- Non impostando l'ora 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 di PlayerManager


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")
-- Variable 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 nel caso in cui si sia disconnesso o se ne sia andato.
if whichPlayer then
local character = whichPlayer.Character
-- Se il giocatore lo ha attualmente sul 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 il prossimo 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
-- Eventi
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager