Czyszczenie i Resetowanie

*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 kodowanie ostatniej fazy gry: czyszczenie i resetować. Kod w tej fazie zapewnia, że pętli gry do przerwy i że przyszłe mecze zaczynają się tego samego dla każdego gracza.

Aktualizacja interfejsu

Zanim wykonasz czyszczenie i resetować, poinformuj graczy, jak gra zakończyła się używając DisplayManager, aby pokazać odpowiedni status.

Zdobywanie imienia zwycięzcy

Rozpocznij, uzyskując imię zwycięzcy, jeśli było jakieś. Wcześniej kod sprawdzał, czy rozmiar aktywnych tablicy graczy wynosi 1. Aby uzyskać imię pozostałego gracza, powróć imię w pierwszym indeksie tej tablicy.

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


    function PlayerManager.getWinnerName()
    end
    -- Wydarzenia
    Players.PlayerAdded:Connect(onPlayerJoin)
  2. Dodaj oświadczenie if, które będzie wykonane, jeśli coś istnieje w activePlayers[1]. Mimo że liczba tabel była sprawdzana przedtem, gracz mógł się odłączyć lub opuścić grę.


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

    • Wróć nazwę gracza.
    • Dla innych zwróć błąd ciąg.

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

Zdobycie stanu końcowego

Użyj funkcji modułu, aby odebrać informacje z poprawnego stanu końcowego, czy zegar kończy się lub jeden gracz zostaje opuszczony. Następnie wysyłaj zmienne stanu do DisplayManager, aby aktualizować GUI statusu z odpowiednim wiadomość.

  1. W MatchManager , kod nową funkcję modułu nazwaną getEndStatus() z parametrem nazwanym endState . Aby zapisać wiadomość, która zostanie wysłana, dodaj pustą zmienną nazwaną 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. Ustaw wartość statusToReturn używając if i clause. Sprawdź zmienne końcowe: FoundWinner i TimerUp. Dla sprawdzenia błędów włącz inny element na kończyć.


    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

    • Zmienne dla zwycięzcy używającego playerManager.getWinnerName() .
    • Aktualizuj statusToReturn za pomocą strzyngi ogłaszającej zwycięzcę.

    TimerUp

    • Aktualizuj statusToReturn za pomocą strzymającej się aktualizacji.

    Else

    • Aktualizuj statusToReturn z błędem w przypadku problemów z otrzymaniem końcowej wiadomość.

    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 powiadomienie, 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

Pokazywanie i testowanie

Zdobądź aktualizowaną informację w GameManager i wyświetl ją dla graczy używając DisplayManager.

  1. Otwórz GameManager . W czasie prawdziwy pętelę, usuń ostatnie stwierdzenie drukowania. Następnie utwórz zmienne nazyjące się endStatus. Ustaw go równy z wzywaniem 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ć otrzymany komunikat w etykiecie GUI, wezwij displayManager.updateStatus() i przekaż endStatus.


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
  3. Tak więc gra wstrzyma się, aby gracze mogli zobaczyć wiadomość, dodaj czekanie używając 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 dotyczące czasu i warunków wygrywania gracza.

    Kondycja czasowa jest skończona
    Warunki gracza zwycięzcy

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

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

  • Jeśli Twoje wiadomości statusu końca są "Error Found", żadne z warunków nie były udane. Sprawdź kod w MatchManager.getEndStatus() przeciwko próbkom kodu.
  • Jeśli status końcowy nie zostanie wyświetlony, sprawdź, czy task.wait(gameSettings.transitionTime) po wysłaniu wiadomości do Managera wyświetlenia.

Począwszy Nowe Rozgrywki

Przed rozpoczęciem nowego dopasowywać, będzie to krótki przejście. Daje to graczom czas, aby zobaczyć stan końcowy i sprawić, że bycie teleportowane do lobby czuje się mniej niespodziewane.

Pod koniec przejścia pozostałe gracze zostaną usunięte z aren, a cały kod zostanie zresetowany. To gwarantuje, że gracze rozpoczną następny mecz z czystą wersją gry.

Przyczepność

Gdy gracze przechodzą w stan przejściowy, usuń ich broń.

  1. W PlayerManager znajdź lokalne funkcje. Kopiuj i wklej zaznaczony kod dla removePlayerWeapon() poniżej. Kod usunie broń jednego gracza, jeśli jest aktywnie wyposażony lub w plecaku gracza.


    local function removePlayerWeapon(whichPlayer)
    -- Sprawdź, czy gracz istnieje w przypadku, gdy został odłączony lub opuścił.
    if whichPlayer then
    local character = whichPlayer.Character
    -- Jeśli gracz ma go obecnie na swoim charakterze
    local weapon = character:FindFirstChild("Weapon")
    if weapon then
    weapon:Destroy()
    end
    -- Jeśli gracz ma broń w ich plecaku
    local backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")
    if backpackWeapon then
    backpackWeapon:Destroy()
    end
    else
    print("No player to remove weapon")
    end
    end
  2. Zacznij nową funkcję modułu nazwaną removeAllWeapons() .


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


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

Czyszczenie między meczami

Czyszczenie będzie jego własną funkcją w MatchManager. Na razie czyszczenie tylko używa tego wcześniej stworzonego funkcji, aby usunąć broń gracza. W miarę rozbudowy gry więcej można dodać, takich jak funkcje do zresetowania mapy, która zmieniła się podczas dopasowywać.

  1. Otwórz MatchManager. Dodaj nową funkcję modułu nazyającą się 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ę czyszczenia. Otwórz GameManager i znajdź czas prawdziwy do pętli. W ten sposób gracze mają usunięte broń podczas przerwy na końcu, wezwij matchManager.cleanupMatch() przed ostatnim 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. Uruchom serwer testowy i przeprowadź dopasowywać. Poczekaj, aż skończy się odliczanie, a potwierdź, że broń gracza została usunięta podczas przerwy na końcu gry.

    Podczas meczu:
    Po meczu:

Resetowanie meczów

Zauważyłeś kilka innych rzeczy w grze, takich jak nadal znajdujący się na arenie gracz po meczu. Po wyczyszczeniu meczu następnie zresetuj grę. To obejmuje wysyłanie graczy na arenę i czyszczenie stolika aktywnych graczy. Po zresetowaniu w grze pętla może być uruchomiona w nieskończoność.

Najpierw uruchom funkcję wysyłania graczy do lobby.

  1. W PlayerManager:

    • Utwórz funkcję modułu nazwaną resetPlayers() .
    • Dodaj for pętli do cyklu poprzez aktywnychGraczy.
    • W pętli, wezwij respawnPlayerInLobby() i przekaż parametr jako gracz.

    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 dla następnego mecze ustawiając ją równą do {}, 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 MatchManager. Wpisz nową funkcję modułu nazwaną 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 . At the end of the while true do loop, call 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ź dopasowywać. Potwierdź, że możesz przynajmniej przejść przez dwa gry bez błędów.

Ukończone Skrypcity

Poniżej znajdują się zakończone skrypty, aby podwoić sprawdzenie swojej pracy.

Skrypt GameManager


-- Usługi
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Skripty modułu
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 MatchManager


local MatchManager = {}
-- Usługi
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Skripty modułu
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 timer, aby używać 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 upewnia się, że ekran zlicznika kończy się na 1, a nie na 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Nie ustawiając czasu na czekanie, oferuje ono bardziej dokładne pętlenie
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 PlayerManager


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")
-- Zróżnicowane 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")
-- Zróżnicowane zmienne
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 został odłączony lub opuścił.
if whichPlayer then
local character = whichPlayer.Character
-- Jeśli gracz ma go obecnie na swoim charakterze
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- Jeśli gracz ma broń w ich 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)
-- Dostarcza lokalizację spawn i następnie usuwa ją z tabeli, aby następny gracz otrzymał następny 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