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.
W PlayerManager, rozpocznij nową funkcję modułu o nazwie getWinnerName().
function PlayerManager.getWinnerName()end-- WydarzeniaPlayers.PlayerAdded:Connect(onPlayerJoin)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 thenendendW oświadczeniu if:
- Zwróć nazwę gracza.
- Dla reszty, zwróć ciąg błędów.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
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.
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()endfunction MatchManager.getEndStatus(endState)local statusToReturnendmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerUstaw 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 statusToReturnif endState == gameSettings.endStates.FoundWinner thenelseif endState == gameSettings.endStates.TimerUp thenelseendendDodaj 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 statusToReturnif endState == gameSettings.endStates.FoundWinner thenlocal winnerName = playerManager.getWinnerName()statusToReturn = "Winner is : " .. winnerNameelseif endState == gameSettings.endStates.TimerUp thenstatusToReturn = "Time ran out!"elsestatusToReturn = "Error found"endendWyślij ponownie wiadomość, wpisując 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
Wyświetlanie i testowanie
Zdobądź zaktualizowane ogłoszenie w GameManager i wyświetl je graczom za pomocą DisplayManager.
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 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)endAby wyświetlić zwróconą wiadomość w etykiecie GUI, wezwij displayManager.updateStatus() i przekaż endStatus.
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)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)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ń.
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 thenlocal character = whichPlayer.Character-- Jeśli gracz ma to obecnie na swojej postacilocal weapon = character:FindFirstChild("Weapon")if weapon thenweapon:Destroy()end-- Jeśli gracz ma broń w swoim plecakulocal backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")if backpackWeapon thenbackpackWeapon:Destroy()endelseprint("No player to remove weapon")endendRozpocznij nową funkcję modułu o nazwie removeAllWeapons().
function PlayerManager.removeAllWeapons()end-- WydarzeniaPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerW 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 doremovePlayerWeapon(whichPlayer)endend
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.
Otwórz MatchManager. Dodaj nową funkcję modułu o nazwie cleanupMatch(). W tej funkcji wezwij playerManager.removeAllWeapons().
function MatchManager.cleanupMatch()playerManager.removeAllWeapons()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerNastę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 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)endUruchom 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.
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 dorespawnPlayerInLobby(whichPlayer)endend-- WydarzeniaPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerUpewnij 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 dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endOtwórz Menadżera meczów. Napisz nową funkcję modułu o nazwie resetMatch() i wezwij playerManager.resetPlayers().
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerWróć do GameManager . Na końcu pętli while true wezwij 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()endUruchom 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ługilocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Skrypty modułowelocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- Wydarzenialocal 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
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