Oczyszczenie i zresetowanie

*Ta zawartość została przetłumaczona przy użyciu narzędzi AI (w wersji beta) i może zawierać błędy. Aby wyświetlić tę stronę w języku angielskim, kliknij tutaj.

Czas na skodowanie ostatniej fazy gry: oczyszczenie i zresetowanie.Kod w tej fazie zapewnia, że pętle gry przejdą do przerwy i że przyszłe mecze rozpoczną się tak samo dla każdego gracza.

Aktualizacja interfejsu

Zanim wyczyścisz i zresetujesz, poinformuj graczy, jak gra się zakończyła, używając DisplayManagera, aby pokazać odpowiedni stan.

Zdobądź nazwę zwycięzcy

Zacznij od uzyskania nazwy zwycięskiego gracza, jeśli była taka.Wcześniej kod sprawdzał, czy rozmiar tabeli aktywnych graczy spadł do 1.Aby uzyskać nazwę pozostałego gracza,返回 nazwę w pierwszym indeksie tej tabeli.

  1. W PlayerManager, rozpocznij nową funkcję modułu o nazwie getWinnerName().


    function PlayerManager.getWinnerName()
    end
    -- Wydarzenia
    Players.PlayerAdded:Connect(onPlayerJoin)
  2. Dodaj oświadczenie if, które uruchamia się, jeśli coś istnieje w activePlayers[1].Chociaż liczba tabel została sprawdzona wcześniej, gracz może być odłączony lub opuścił grę.


    function PlayerManager.getWinnerName()
    local winningPlayer = activePlayers[1]
    if winningPlayer then
    end
    end
  3. W oświadczeniu if:

    • Zwróć nazwę gracza.
    • Dla reszty, zwróć ciąg błędów.

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

Zdobądź status końcowy

Użyj funkcji modułu, aby pobrać informacje z poprawnego stanu końcowego, czy czasomierz się kończy, czy jeden gracz został pozostawiony.Następnie wysyłaj tę zmienną stanu do DisplayManager, aby zaktualizować status GUI za pomocą odpowiedniej wiadomości.

  1. W MatchManager kod nowej funkcji modułu o nazwie getEndStatus() z parametrem o nazwie endState.Aby przechować wiadomość, która zostanie wysłana, dodaj pustą zmienną o nazwie 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. Ustaw wartość statusToReturn za pomocą oświadczeń if i elseif.Sprawdź zmienne stanu końcowego: FoundWinner i TimerUp.Aby sprawdzić błędy, dodaj inne na końcu.


    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    elseif endState == gameSettings.endStates.TimerUp then
    else
    end
    end
  3. Dodaj następujące dla każdego warunku:

    FoundWinner

    • Zmienna dla zwycięzcy za pomocą playerManager.getWinnerName() .
    • Aktualizacja statusToReturn z ciągiem ogłaszającym zwycięzcę.

    TimerUp

    • Aktualizacja statusToReturn z ciągiem ogłaszającym, że skończył się czas.

    Else

    • Aktualizacja statusToReturn z wiadomością o błędzie w przypadku wystąpienia problemów z uzyskaniem wiadomości końcowego meczu.

    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. Wyślij ponownie wiadomość, wpisując 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

Wyświetlanie i testowanie

Zdobądź zaktualizowane ogłoszenie w GameManager i wyświetl je graczom za pomocą DisplayManager.

  1. Otwórz GameManager .W pętle while prawda, usuń ostatnie oświadczenie druku.Następnie utwórz zmienną o nazwie endStatus.Ustaw to równo do wezwania 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. Aby wyświetlić zwróconą wiadomość w etykiecie GUI, wezwij displayManager.updateStatus() i przekaż endStatus.


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
  3. Więc gra wstrzymuje się, aby gracze mogli zobaczyć wiadomość, dodaj oczekiwanie za pomocą transitionTime.


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    task.wait(gameSettings.transitionTime)
  4. Uruchom serwer testowy i sprawdź, czy gracze widzą następujące wiadomości dla czasu up i warunków wygrywającego gracza.

    Warunek wyczerpania czasu
    Warunk wygranej gracza

Wskazówki dotyczące rozwiązywania problemów

W tym momencie nie możesz zobaczyć wiadomości, spróbuj jednej z poniższych.

  • Jeśli twoja wiadomość o stanie końcowym jest "Error Found", żadna z warunków nie powiodła się. Sprawdź kod w MatchManager.getEndStatus() przeciwko próbkom kodu.
  • Jeśli status końcowy nie wyświetla się, sprawdź, czy task.wait(gameSettings.transitionTime) jest po wysłaniu wiadomości do wyświetlacza.

Rozpocznij nowe mecze

Zanim rozpocznie się nowy mecz, nastąpi krótka przejście.Daje to graczom czas na zobaczenie stanu końcowego i czyni teleportację do lobby mniej nagłą.

Pod koniec przejścia pozostali gracze zostaną usunięci z areny, a cały kod zostanie zresetowany.Zapewnia to, że gracze rozpoczną następny mecz z czystą wersją gry.

Ręczne przejścia

Kiedy gracze przechodzą do stanu przejściowego, usuń ich broń.

  1. W PlayerManager znajdź lokalne funkcje.Skopiuj i wklej wyświetlony kod dla removePlayerWeapon() poniżej.Kod usunie broń pojedynczego gracza, jeśli jest aktywnie wyposażona lub w plecaku gracza.


    local function removePlayerWeapon(whichPlayer)
    -- Sprawdź, czy gracz istnieje w przypadku, gdy się odłączył lub odszedł.
    if whichPlayer then
    local character = whichPlayer.Character
    -- Jeśli gracz ma to obecnie na swojej postaci
    local weapon = character:FindFirstChild("Weapon")
    if weapon then
    weapon:Destroy()
    end
    -- Jeśli gracz ma broń w swoim plecaku
    local backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")
    if backpackWeapon then
    backpackWeapon:Destroy()
    end
    else
    print("No player to remove weapon")
    end
    end
  2. Rozpocznij nową funkcję modułu o nazwie removeAllWeapons().


    function PlayerManager.removeAllWeapons()
    end
    -- Wydarzenia
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  3. W tej funkcji użyj pętli for, aby przejść przez tabelę aktywnych graczy. W pętli wezwij removePlayerWeapon() i przekaż znalezionego gracza.


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

Czysto między meczami

Oczyszczenie będzie jego własną funkcją w MatchManager.Na razie sprzątanie będzie wykorzystywać wcześniej utworzoną funkcję do usuwania broni gracza.W miarę rozszerzania gry można dodać więcej, takich jak funkcje do zresetowania mapy, która zmieniła się podczas meczu.

  1. Otwórz MatchManager. Dodaj nową funkcję modułu o nazwie cleanupMatch(). W tej funkcji wezwij playerManager.removeAllWeapons().


    function MatchManager.cleanupMatch()
    playerManager.removeAllWeapons()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Następnie wezwij funkcję sprzątania.Otwórz GameManager i znajdź pętelę while prawda, gdy prawda.Więc gracze mają broń usuniętą podczas przerwy końcowej, zadzwoń przed ostatnią >.


    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. Uruchom serwer testowy i przeprowadź mecz. Poczekaj, aż skończy się czas, i potwierdź, że broń gracza zostanie usunięta podczas przerwy w grze końcowej.

    Podczas meczu
    Po meczu

Zresetuj mecze

Być może zauważyłeś kilka innych rzeczy w grze, takich jak gracze nadal są na arenie po zakończeniu meczu.Po oczyszczeniu meczu następnie zresetuj grę.Obejmuje to wysyłanie graczy na arenę z powrotem do lobby i oczyszczenie stołu aktywnych graczy.Po zresetowaniu pętla gry może działać bez końca.

Najpierw uruchom funkcję, aby wysłać graczy z powrotem do lobby.

  1. W menedżerze graczy:

    • Stwórz funkcję modułu o nazwie resetPlayers().
    • Dodaj pętli for do iterowania przez aktywnych graczy.
    • W pętli wezwij respawnPlayerInLobby() i przekaż gracza jako parametr.

    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    end
    -- Wydarzenia
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  2. Upewnij się, że tabela activePlayers jest pusta na następny mecz, ustawiając ją równą {}, co jest szybkim sposobem na zresetowanie do pustej tabeli.


    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    activePlayers = {}
    end
  3. Otwórz Menadżera meczów. Napisz nową funkcję modułu o nazwie resetMatch() i wezwij playerManager.resetPlayers().


    function MatchManager.resetMatch()
    playerManager.resetPlayers()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  4. Wróć do GameManager . Na końcu pętli while true wezwij 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. Uruchom serwer testowy i przeprowadź mecz. Potwierdź, że możesz przejść przez co najmniej dwa pętle gry bez żadnych błędów.

Zakończone skrypty

Poniżej są ukończone skrypty do sprawdzenia podwójnego swojej pracy.

Skrypt Menadżera gry


-- Usługi
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Skrypty modułowe
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Wydarzenia
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

Skrypt Menadżera meczów


local MatchManager = {}
-- Usługi
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Skrypty modułowe
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"))
-- Wydarzenia
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Wartości
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Tworzy nowy obiekt minutnika, który ma być używany do śledzenia czasu meczu.
local myTimer = timer.new()
-- Lokalne funkcje
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
-- Dodanie +1 sprawia, że wyświetlanie czasu kończy się na 1 zamiast na 0.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- Nie ustawiając czasu oczekiwania, oferuje dokładniejsze pętle
task.wait()
end
end
-- Funkcje modułu
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

Skrypt menedżera graczy


local PlayerManager = {}
-- Usługi
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Moduły
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Wydarzenia
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Zmienne mapy
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Wartości
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Zmienne gracza
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()
-- Daj graczowi narzędzie
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)
-- Sprawdź, czy gracz istnieje w przypadku, gdy się odłączył lub odszedł.
if whichPlayer then
local character = whichPlayer.Character
-- Jeśli gracz ma to obecnie na swojej postaci
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- Jeśli gracz ma broń w swoim plecaku
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)
-- Otrzymuje lokalizację spawnu i następnie usuwa ją z tabeli, aby następny gracz otrzymał następne 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
-- Wydarzenia
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager