Zeit, die letzte Phase des Spiels zu codieren: Aufräumen und zurücksetzen.Code in dieser Phase stellt sicher, dass die Spielschleifen zur Pause gehen und dass zukünftige Spiele für jeden Spieler gleich beginnen.
Aktualisieren Sie die GUI
Bevor Sie aufräumen und zurücksetzen, informieren Sie die Spieler, wie das Spiel mit dem DisplayManager beendet wurde, um den entsprechenden Status anzuzeigen.
Holen Sie sich den Namen des Gewinners
Beginnen Sie damit, den Namen des siegreichen Spielers zu erhalten, wenn es einen gab.Zuvor prüfte der Code, ob die Größe des aktiven Spielertisches auf 1 heruntergefallen war.Um den Namen des verbleibenden Spielers zu erhalten, geben Sie den Namen bei der ersten Indexierung dieser Tabelle zurück.
In PlayerManager starten Sie eine neue Modulfunktion mit dem Namen getWinnerName().
function PlayerManager.getWinnerName()end-- EreignissePlayers.PlayerAdded:Connect(onPlayerJoin)Füge eine if-Anweisung hinzu, die ausgeführt wird, wenn etwas in activePlayers[1] existiert.Obwohl die Tabelle vorher überprüft wurde, könnte der Spieler sich abgemeldet oder das Spiel verlassen haben.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenendendIm if- statement:
- Gib den Namen des Spielers zurück.
- Für den Rest, gib einen Fehlerstring zurück.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
Holen Sie sich den Endstatus
Verwende eine Modulfunktion, um Informationen aus dem korrekten Endzustand zu erhalten, ob der Timer endet oder ein Spieler übrig bleibt.Dann sende diese Zustandsvariable an den DisplayManager, um den Status-GUI mit der entsprechenden Nachricht zu aktualisieren.
In MatchManager , kodieren Sie eine neue Modulfunktion mit dem Namen getEndStatus() mit einem Parameter namens endState .Um die Nachricht zu speichern, die gesendet wird, füge eine leere Variable mit dem Namen statusToReturn hinzu.
function MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()endfunction MatchManager.getEndStatus(endState)local statusToReturnendmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerLeg den Wert von statusToReturn mit if- und elseif-Statements fest.Überprüfen Sie die Endzustandsvariablen: FoundWinner und TimerUp.Für Fehlerprüfungen füge am Ende ein anderes hinzu.
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenelseif endState == gameSettings.endStates.TimerUp thenelseendendFüge Folgendes für jede Bedingung hinzu:
FoundWinner
- Eine Variable für den Gewinner mit der Verwendung von playerManager.getWinnerName().
- Aktualisieren statusToReturn mit einem String, der den Gewinner ankündigt.
TimerUp
- Aktualisieren statusToReturn mit einer Zeichenkette, die verkündet, dass die Zeit abgelaufen ist.
Else
- Aktualisieren statusToReturn mit einer Fehlermeldung, falls es Probleme mit der Erhaltung der Endspielnachricht gibt.
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"endendSenden Sie die Nachricht zurück, indem Sie return statusToReturn tippen.
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
Anzeigen und testen
Hole die aktualisierte Ankündigung im GameManager und zeige sie den Spielern mit dem DisplayManager an.
Öffne Spielmanager .Im While-true-Loop löschen Sie die letzte Druck statement .Dann erstelle eine Variable mit dem Namen endStatus.Setze es gleich mit dem Aufruf von 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)endUm die zurückgegebene Nachricht im GUI-Etikett anzuzeigen, rufe displayManager.updateStatus() auf und gib endStatus ein.
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)Also pausiert das Spiel, damit die Spieler die Nachricht sehen können, und füge einen Wait mit transitionTime hinzu.
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)task.wait(gameSettings.transitionTime)Starte einen Testserver und prüfe, dass Spieler die folgenden Nachrichten für die Zeit bis zum Sieger und die Spielerbedingungen sehen.
Zeit ist um Bedingung Gewinnender Spielerbedingung
Problemlösungstipps
An dieser Stelle können Sie die Nachrichten nicht sehen, versuchen Sie eine der folgenden Optionen.
- Wenn Ihre Endstatusnachricht "Fehler gefunden" ist, war keine der Bedingungen erfolgreich. Überprüfen Sie den Code in MatchManager.getEndStatus() gegen die Codebeispiele.
- Wenn der Endstatus nicht angezeigt wird, überprüfe, ob task.wait(gameSettings.transitionTime) nach dem Versenden der Nachricht an den Anzeigemanager angezeigt wird.
Starte neue Spiele
Bevor ein neues Match beginnt, wird es einen kurzen Übergang geben.Dies gibt den Spielern Zeit, den Endstatus zu sehen, und lässt es weniger plötzlich werden, in die Lobby teleportiert zu werden.
Am Ende der Übergangszeit werden verbleibende Spieler aus der Arena entfernt und der gesamte Code zurückgesetzt.Dies gewährleistet, dass Spieler das nächste Spiel mit einer sauberen Version des Spiels starten.
Übergänge handhaben
Wenn Spieler in den Übergangsstatus wechseln, entferne ihre Waffen.
In PlayerManager finden Sie die lokalen Funktionen.Kopiere und füge den hervorgehobenen Code für removePlayerWeapon() unten ein.Der Code wird die Waffe eines einzelnen Spielers entfernen, wenn sie aktiv ausgerüstet oder im Rucksack des Spielers ist.
local function removePlayerWeapon(whichPlayer)-- Überprüfen Sie, ob ein Spieler existiert, falls er sich abgemeldet oder verlassen hat.if whichPlayer thenlocal character = whichPlayer.Character-- Wenn der Spieler es derzeit auf seinem Charakter hatlocal weapon = character:FindFirstChild("Weapon")if weapon thenweapon:Destroy()end-- Wenn der Spieler die Waffe in seinem Rucksack hatlocal backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")if backpackWeapon thenbackpackWeapon:Destroy()endelseprint("No player to remove weapon")endendStarte eine neue Modulfunktion mit dem Namen removeAllWeapons().
function PlayerManager.removeAllWeapons()end-- EreignissePlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerVerwende in dieser Funktion eine for-Schleife, um durch die aktiven Spieler-Tabelle zu gehen. In der Schleife rufe removePlayerWeapon() auf und übermittle den gefundenen Spieler.
function PlayerManager.removeAllWeapons()for playerKey, whichPlayer in activePlayers doremovePlayerWeapon(whichPlayer)endend
Reinigen zwischen Matches
Die Aufräumung wird seine eigene Funktion im MatchManager sein.Für jetzt wird die Aufräumung nur diese zuvor erstellte Funktion verwenden, um Spielerwaffen zu entfernen.Wenn du das Spiel erweiterst, kann mehr hinzugefügt werden, wie z. B. Funktionen, um eine Karte zurückzusetzen, die während eines Spiels geändert wurde.
Öffne MatchManager. Füge eine neue Modulfunktion mit dem Namen cleanupMatch() hinzu. In dieser Funktion rufe playerManager.removeAllWeapons() auf.
function MatchManager.cleanupMatch()playerManager.removeAllWeapons()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerRufen Sie als Nächstes die Aufräumfunktion auf.Öffne Spielmanager und finde die while-Schleife wahr.Also haben Spieler Waffen während der Endpause entfernt, rufen Sie matchManager.cleanupMatch() vor dem letzten task.wait() an.
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)endStarte einen Testserver und führe ein Match durch. Warte, bis der Timer abläuft, und bestätige, dass die Waffe des Spielers während der Pause am Ende des Spiels entfernt wird.
Während eines Spiels Nach dem Spiel
Matches zurücksetzen
Du hast vielleicht ein paar andere Dinge im Spiel bemerkt, wie Spieler immer noch in der Arena sind, nachdem ein Spiel beendet ist.Nachdem das Spiel gereinigt wurde, setze das Spiel als nächstes zurück.Dazu gehören das Senden von Spielern in die Arena zurück in die Lobby und das Löschen des aktiven Spielertisches.Mit einem Reset vor Ort kann ein Spielschleife unendlich laufen.
Fangen Sie zuerst eine Funktion an, um Spieler in die Lobby zurückzusenden.
Im PlayerManager:
- Erstelle eine Modulfunktion mit dem Namen resetPlayers().
- Füge eine for-Schleife hinzu, um durch aktiveSpieler zu iterieren.
- Im Schleifenruf respawnPlayerInLobby() und übergeben Sie den Spieler als Parameter.
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endend-- EreignissePlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerStelle sicher, dass die activePlayers Tabelle für das nächste Spiel leer ist, indem du sie mit {} gleichstellst, was eine schnelle Möglichkeit ist, auf eine leere Tabelle zurückzusetzen.
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endÖffne MatchManager. Code eine neue Modulfunktion namens resetMatch() und rufe playerManager.resetPlayers() auf.
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerGehe zurück zu GameManager . Am Ende der While-true-Schleife rufe matchManager.resetMatch() auf.
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()endStarte einen Testserver und führe ein Match durch. Bestätige, dass du mindestens durch zwei Spielschleifen gehen kannst, ohne Fehler.
Abgeschlossene Skripte
Im Folgenden sind abgeschlossene Skripte, um deine Arbeit zu überprüfen.
GameManager-Skript
-- Serviceleistungenlocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Modul-Skriptelocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- Ereignisselocal 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
Pass-Manager-Skript
local MatchManager = {}
-- Serviceleistungen
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Modul-Skripte
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"))
-- Ereignisse
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Werte
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Erstellt ein neues Timer-Objekt, das verwendet wird, um die Spielzeit zu verfolgen.
local myTimer = timer.new()
-- Lokale Funktionen
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
-- Das Hinzufügen von +1 stellt sicher, dass die Timeranzeige bei 1 statt bei 0 endet.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- Durch das Nicht festlegen der Zeit für die Wartezeit bietet es genauere Schleifen
task.wait()
end
end
-- Modulfunktionen
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
SpielerManager-Skript
local PlayerManager = {}
-- Serviceleistungen
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Module
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Ereignisse
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Kartenvariablen
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Werte
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Spielervariablen
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()
-- Gib dem Spieler ein Werkzeug
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)
-- Überprüfen Sie, ob ein Spieler existiert, falls er sich abgemeldet oder verlassen hat.
if whichPlayer then
local character = whichPlayer.Character
-- Wenn der Spieler es derzeit auf seinem Charakter hat
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- Wenn der Spieler die Waffe in seinem Rucksack hat
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)
-- Holen Sie sich einen Spawn-Standort und entfernen Sie ihn dann von der Tabelle, damit der nächste Spieler den nächsten Spawn erhält
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
-- Ereignisse
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager