Zeit, die letzte Phase des Spiels zu kodieren: Aufräumen und zurücksetzen. Code in dieser Phase sorgt dafür, dass die Spiel-Loops zur Pause aufrufen und zukünftige Matches für jeden Spieler:indasselbe starten.
Aktualisieren der grafische Benutzeroberfläche
Bevor Sie die Reinigung und den zurücksetzendurchführen, informieren Sie die Spieler darüber, wie das Spiel mit dem DisplayManager beendet wurde, um den richtigen Status anzuzeigen.
Den Namen des Gewinners erhalten
Beginnen Sie, indem Sie den Namen des gewinnerischen Spieler:inerhalten, wenn es einer war. Davor überprüfte der Code, ob die Größe der aktiven Spieler-Tabelle auf 1 reduziert wurde. Um den verbleibenden Spieler:inzu erhalten, geben Sie den Namen zum ersten Index der Tabelle zurück.
In PlayerManager, starten Sie eine neue Modulfunktion namens getWinnerName() .
function PlayerManager.getWinnerName()end-- EreignissePlayers.PlayerAdded:Connect(onPlayerJoin)Fügen Sie eine if-Anweisung hinzu, die ausgeführt wird, wenn etwas in activePlayers[1] existiert. Obwohl die Tabelenzählung vorher überprüft wurde, hat der Spieler möglicherweise die Verbindung getrennt oder das Spiel verlassen.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenendendIn der if-Anweisung:
- Geben Sie den Namen des Spieler:inzurück.
- Für die anderen geben Sie einen Fehler String.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
Endstatus erhalten
Verwenden Sie eine Modul-Funktion, um Informationen vom richtigen Endzustand zu nehmen, ob der Timer endet oder ein Spieler übrig bleibt. Dann senden Sie diese Zustands变수 an DisplayManager, um die Status-GUI mit der passenden Nachricht zu aktualisieren.
In MatchManager , Code eine neue Modulfunktion namens getEndStatus() mit einem Parameter namens endState . Um die Nachricht zu speichern, füge eine leere Variable namens 1> statusToReturn1> hinzu.
function MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()endfunction MatchManager.getEndStatus(endState)local statusToReturnendmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerSet the value of statusToReturn using if andelifft statement. Check for the end state variables: FoundWinner and TimerUp. For error checking, include an else at the beenden.
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenelseif endState == gameSettings.endStates.TimerUp thenelseendendFüge die folgenden für jede Bedingung hinzu:
FoundWinner
- Eine Variable für den Gewinner, der playerManager.getWinnerName() verwendet.
- Update statusToReturn mit einer Zeile, die den Gewinner ankündigt.
TimerUp
- Update statusToReturn mit einer Zeichenanzeige, die die Zeit abgelaufen hat.
Else
- Update statusToReturn mit einem Fehler in der Nachricht, falls es Probleme mit dem Erhalt der Endspiel-Nachricht 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 eingeben.
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
Erhalte die aktualisierte Ankündigung in GameManager und zeige sie den Spielern mit dem DisplayManager an.
Öffnen Sie GameManager . Während der Wiederholung wahr ist, löschen Sie die letzte druckanweisung. Dann erstellen Sie eine Variable namens endStatus. Setzen Sie sie gleich, um aufzurufen 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 in der Beschriftunganzuzeigen, rufen Sie displayManager.updateStatus() auf und übermitteln Sie in endStatus .
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)So wird das Spiel unterbrochen, damit Spieler die Nachricht sehen können, füge einen Warte mit transitionTime hinzu.
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)task.wait(gameSettings.transitionTime)Starten Sie einen Testserver und überprüfen Sie, dass Spieler die folgenden Nachrichten für die Zeit und die Gewinnbedingungen des Spielers sehen.
Troubleshooting-Tipps
An dieser Stelle können Sie die Nachrichten nicht sehen, versuchen Sie es mit einer der folgenden Optionen.
- Wenn Ihre Endstatus-Nachricht "Fehler gefunden" ist, haben keine der Bedingungen Erfolg gehabt. Überprüfen Sie den Code in MatchManager.getEndStatus() gegen die Code-Beispiele.
- Wenn der Endstatus nicht angezeigt wird, überprüfen Sie, dass task.wait(gameSettings.transitionTime) nach dem Senden der Nachricht an den DisplayManager ist.
Neue Spiele starten
Before starting a new übereinstimmen, wird es eine kurze Übergangszeit geben. Dies gibt den Spielern Zeit, den Endstatus zu sehen und das Teleportieren in die Lobby weniger unerwartet zu fühlen.
Am Ende der Übergangszeit werden die verbleibenden Spieler aus der Arena entfernt und der gesamte Code zurücksetzen. Dies stelle sicher, dass Spieler das nächste Spiel mit einer sauberen Version des Spiels starten.
Übergangsverhalten
Wenn Spieler in den Übergangszustand wechseln, entfernen Sie ihre Waffen.
In PlayerManager finden Sie die lokalen Funktionen. Kopieren und fügen Sie den markierten Code für removePlayerWeapon() unten ein. Der Code entfernt die Waffe eines einzelnen Spieler:in, wenn sie aktiv ausgerüstet ist oder in dem Spieler:in's Rucksack ist.
local function removePlayerWeapon(whichPlayer)-- Überprüfen Sie, ob ein Spieler existiert, falls er getrennt wurde 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")endendStarten Sie eine neue Modulfunktion namens removeAllWeapons() .
function PlayerManager.removeAllWeapons()end-- EreignissePlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerIn dieser Funktion verwenden Sie ein for-Loop, um die aktiven Spieler-Tabelle zu durchlaufen. Im Loop rufen Sie removePlayerWeapon() auf und übergeben Sie den Spieler, der gefunden wurde.
function PlayerManager.removeAllWeapons()for playerKey, whichPlayer in activePlayers doremovePlayerWeapon(whichPlayer)endend
Saubere Zwischen Spielen
Die Aufräumen wird in MatchManager seine eigene Funktion sein. Für diezeit wird die Aufräumen nur diese zuvor erstellte Funktion verwenden, um Spielerwaffen zu entfernen. Wenn Sie das Spiel erweitern, können mehr Funktionen hinzugefügt werden, z. B. Funktionen zum Zurücksetzen einer Karte, die während eines übereinstimmengeändert wurde.
Öffnen Sie MatchManager. Fügen Sie eine neue Modulfunktion hinzu, die cleanupMatch() heißt. In dieser Funktion rufen Sie playerManager.removeAllWeapons() auf.
function MatchManager.cleanupMatch()playerManager.removeAllWeapons()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerNächste Aufrufe die Reinigungsfunktion. Öffne GameManager und finde den while true do loop. So haben Spieler während der Endintermission Waffen entfernt, rufe matchManager.cleanupMatch() vor dem letzten task.wait() 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)endStarten Sie einen Test-Server und führen Sie einen übereinstimmen. Warten Sie, bis der Timer abgelaufen ist, und bestätigen Sie, dass die Waffe des Spieler:inwährend der Endspiel-Intermission entfernt wird.
Matchs zurücksetzen
Du hast vielleicht ein paar andere Dinge im Spiel bemerkt, wie Spieler nach einem Match immer noch in der Arena sind. Mit dem Match sauber gemacht, nächste zurücksetzen Sie das Spiel. Dies beinhaltet das Senden von Spielern in die Arena zurück in die Lobby und das Löschen der aktiven Spieler-Tabelle. Mit einem Reset im Ortkann ein Spiel-Loop unendlich laufen.
Zuerst starten Sie eine Funktion, um Spieler zurück in die Lobby zu senden.
In PlayerManager:
- Erstellen Sie eine Modulfunktion namens resetPlayers() .
- Fügen Sie ein for Loop hinzu, um durch aktiveSpieler zu wiederholen.
- In der Loop, call respawnPlayerInLobby() and pass in the player als der Parameter.
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endend-- EreignissePlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerStellen Sie sicher, dass die activePlayers Tabelle für das nächste Match leer ist, indem Sie sie mit {} auf gleich setzen, was ein schneller Weg zum Zurücksetzen zu einer leeren Tabelle ist.
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endÖffnen Sie MatchManager. Code eine neue Modulfunktion namens resetMatch() und rufen Sie playerManager.resetPlayers() auf.
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerGehen Sie zurück zu GameManager . Am Ende der Zeit wahr doLoop, rufen Sie 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()endStarten Sie einen Test-Server und führen Sie ein übereinstimmenaus. Bestätigen Sie, dass Sie mindestens zwei Spielschleifen durchführen können, ohne irgendwelche Fehler.
Abgeschlossene Skripte
Dies sind abgeschlossene Skripte, um deine Arbeit zu überprüfen.
GameManager-Skript
-- Dienstelocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Modul-Scriptslocal 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
MatchManager-Skript
local MatchManager = {}
-- Dienste
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Modul-Scripts
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 Match-Zeit 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
-- Durch das Hinzufügen von +1 wird sichergestellt, dass der Timer-Anzeige 1 statt 0 endet.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Durch das Festlegen der Wartezeit bietet es eine präzisere Loop-Funktion
task.wait()
end
end
-- Modul-Funktionen
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 = {}
-- Dienste
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")
-- Karten- Variablen
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Werte
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Spieler Variables
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()
-- Geben Sie dem Spieler ein Tool
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 getrennt wurde 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)
-- Erzeugt einen Spawn-Standort und entfernt 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