Sauber machen und zurücksetzen

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

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.

  1. In PlayerManager, starten Sie eine neue Modulfunktion namens getWinnerName() .


    function PlayerManager.getWinnerName()
    end
    -- Ereignisse
    Players.PlayerAdded:Connect(onPlayerJoin)
  2. 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 then
    end
    end
  3. In 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 then
    return winningPlayer.Name
    else
    return "Error: No winning player found"
    end
    end

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.

  1. 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()
    end
    function MatchManager.getEndStatus(endState)
    local statusToReturn
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Set 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 statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    elseif endState == gameSettings.endStates.TimerUp then
    else
    end
    end
  3. Fü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 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. Senden Sie die Nachricht zurück, indem Sie return statusToReturn eingeben.


    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

Anzeigen und Testen

Erhalte die aktualisierte Ankündigung in GameManager und zeige sie den Spielern mit dem DisplayManager an.

  1. Ö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 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. Um 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)
  3. 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)
  4. Starten Sie einen Testserver und überprüfen Sie, dass Spieler die folgenden Nachrichten für die Zeit und die Gewinnbedingungen des Spielers sehen.

    Zeit ist abgelaufen Bedingung
    Spielergewinnbedingung

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.

  1. 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 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
  2. Starten Sie eine neue Modulfunktion namens removeAllWeapons() .


    function PlayerManager.removeAllWeapons()
    end
    -- Ereignisse
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  3. In 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 do
    removePlayerWeapon(whichPlayer)
    end
    end

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.

  1. Ö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()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Nä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 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. Starten 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.

    Während eines Matches
    Nach dem Match

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.

  1. 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 do
    respawnPlayerInLobby(whichPlayer)
    end
    end
    -- Ereignisse
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  2. Stellen 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 do
    respawnPlayerInLobby(whichPlayer)
    end
    activePlayers = {}
    end
  3. Öffnen Sie MatchManager. Code eine neue Modulfunktion namens resetMatch() und rufen Sie playerManager.resetPlayers() auf.


    function MatchManager.resetMatch()
    playerManager.resetPlayers()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  4. Gehen Sie zurück zu GameManager . Am Ende der Zeit wahr doLoop, rufen Sie 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. Starten 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


-- Dienste
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Modul-Scripts
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Ereignisse
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

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