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.
W PlayerManager, rozpocznij nową funkcję modułu nazwaną getWinnerName() .
function PlayerManager.getWinnerName()end-- WydarzeniaPlayers.PlayerAdded:Connect(onPlayerJoin)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 thenendendW if statement:
- Wróć nazwę gracza.
- Dla innych zwróć błąd ciąg.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
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ść.
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()endfunction MatchManager.getEndStatus(endState)local statusToReturnendmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerUstaw 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 statusToReturnif endState == gameSettings.endStates.FoundWinner thenelseif endState == gameSettings.endStates.TimerUp thenelseendendDodaj 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 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 powiadomienie, 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
Pokazywanie i testowanie
Zdobądź aktualizowaną informację w GameManager i wyświetl ją dla graczy używając DisplayManager.
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 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ć otrzymany komunikat w etykiecie GUI, wezwij displayManager.updateStatus() i przekaż endStatus.
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)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)Uruchom serwer testowy i sprawdź, czy gracze widzą następujące wiadomości dotyczące czasu i warunków wygrywania gracza.
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ń.
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 thenlocal character = whichPlayer.Character-- Jeśli gracz ma go obecnie na swoim charakterzelocal weapon = character:FindFirstChild("Weapon")if weapon thenweapon:Destroy()end-- Jeśli gracz ma broń w ich plecakulocal backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")if backpackWeapon thenbackpackWeapon:Destroy()endelseprint("No player to remove weapon")endendZacznij nową funkcję modułu nazwaną removeAllWeapons() .
function PlayerManager.removeAllWeapons()end-- WydarzeniaPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerW 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 doremovePlayerWeapon(whichPlayer)endend
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ć.
Otwórz MatchManager. Dodaj nową funkcję modułu nazyającą się 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ę 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 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ź dopasowywać. Poczekaj, aż skończy się odliczanie, a potwierdź, że broń gracza została usunięta podczas przerwy na końcu gry.
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.
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 dorespawnPlayerInLobby(whichPlayer)endend-- WydarzeniaPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerUpewnij 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 dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endOtwórz MatchManager. Wpisz nową funkcję modułu nazwaną resetMatch() i wezwij playerManager.resetPlayers().
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerWróć do GameManager . At the end of the while true do loop, call 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ź 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ługilocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Skripty modułulocal 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 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