Endspiele

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

Spiele können mit einigen Bedingungen enden, einschließlich der Tatsache, dass Timer ablaufen oder ein einzelner Spieler verlassen wird.

Besiegte Spieler verwalten

Im Moment respawnen besiegte Spieler in der Arena. Stattdessen schicke sie zurück in die Lobby, um auf das nächste übereinstimmenzu warten.

  1. Erstellen Sie in PlayerManager eine lokale Funktion mit dem Namen respawnPlayerInLobby(). In dieser Funktion tun Sie gefolgte Profile:
  • Setze die RespawnLocation-Eigenschaft des Spieler:inauf lobbySpawn.
  • Lade den Charakter mit Player:LoadCharacter() neu. Denke daran, LoadCharacter() erstellt den Spieler bei seinem Spawn und entfernt alle Werkzeuge, die er hatte.

Verwende anonyme Funktionen

Anonyme Funktionen werden häufig in fortgeschrittenen Skripten unter bestimmten Situationen verwendet.Bevor du sie definierst, ist es wichtig, eine Situation zu verstehen, mit der dein Skript konfrontiert werden kann.

Betrachte das: Um besiegte Spieler in die Lobby zu teleportieren, muss die Respawn-Funktion mit dem Died-Ereignis des Spieler:inverbunden sein.Es gibt jedoch ein Problem.Wenn du das Ereignis wie in der Vergangenheit verbindest, gibt es keine Möglichkeit, den Namen des Spielers aus dem Ereignis "Tot" zu erhalten.Das Skript benötigt diesen Namen, um einen besiegelten Spieler von der Tabelle zu entfernen, die aktive Spieler verfolgt.

Um den Namen des Spielers zu erhalten, der das Ereignis Tod ausgelöst hat, verwende eine anonyme Funktion. Anonyme Funktionen haben keine Namen und können direkt innerhalb von Connect() erstellt werden, anstatt separat.

Eine Beispielanonyme Funktion ist unten, die die Syntax zeigt.


myPlayer.Died:Connect(function()
print(player)
end)

Code das verstorbene Ereignis

Für diese Funktion wird immer dann ausgelöst, wenn der Charakter eines Spieler:instirbt, die Funktion, die ihn wiederbelebt.

  1. Um Zugriff auf das Ereignis Died des Spieler:inzu erhalten, in PlayerManager > preparePlayer() , füge eine Variable für den Humanoid des Spieler:inhinzu.


    local function preparePlayer(player, whichSpawn)
    player.RespawnLocation = whichSpawn
    player:LoadCharacter()
    local character = player.Character or player.CharacterAdded:Wait()
    local sword = playerWeapon:Clone()
    sword.Parent = character
    local humanoid = character:WaitForChild("Humanoid")
    end
  2. Erstelle eine anonyme Funktion, die sich mit dem Ereignis Tod verbindet.Beginnen Sie, indem Sie humanoid.Died:Connect() eingeben.Dann, innerhalb Connect() , geben Sie function() ein, drücken Sie Enter , um end automatisch zu vervollständigen, und löschen Sie die zusätzliche Klammer.


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    end)
  3. In der anonymen Funktion rufen Sie respawnPlayerInLobby() auf. Geben Sie player ein, eine Variable, die den Spieler bereit macht, ein übereinstimmenzu betreten.


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    end)
  4. Starte einen Server und spiele ein übereinstimmen.Teste, dass wenn ein Spieler stirbt, er in der Lobby wiederbelebt wird.Um Spieler zu besiegen, gehe auf sie zu und benutze deine Waffe, bis du bestätigen kannst, dass sie in der Lobby respawned sind.

    Angriff auf Spieler2
    Spieler2 in der Lobby nach der Wiederbelebung

Beachten Sie, es gibt auch einige verschiedene Möglichkeiten zum Testen, wenn gewünscht.

  • Um einen Spieler:inzu töten, kopiere und füge im Server > Ausgabe-Fenster > Befehlsleiste ein: workspace.Player1.Humanoid.Health = 0 .Drücken Sie Enter, um den Befehl auszuführen.Um andere Spieler zu entfernen, verwende Player2, Player3 usw.
  • Die Einstellung von GameSettings > zu einer längeren Zeit kann Ihnen mehr Zeit geben, um alle Spieler zu finden und auszuschalten.
  • Um schnellere Tests durchzuführen, ändere GameSettings > minimumPlayers auf kleinere Zahl, wie 2.

Beende das Spiel

Jetzt, da besiegte Spieler respawnen, beginne mit der Arbeit am Beenden des Spiels.Erinnerst du dich an die Erstellung des MatchEnd-Events? Es wird abgefeuert, wenn entweder der Timer abläuft oder ein Gewinner gefunden wird.

Um anderen Skripten mitzuteilen, unter welcher Bedingung das Spiel beendet wurde, erstelle eine Tabelle mit Variablen für TimerUp und FoundWinner.Wenn das Match-End-Ereignis ausgelöst wird, wird es in einer Variable übergeben, damit andere Skripte antworten können.

  1. Erstelle in den GameSettings einen leeren Modul-Tab mit dem Namen endStates.


    local GameSettings = {}
    -- Spielvariablen
    GameSettings.intermissionDuration = 5
    GameSettings.matchDuration = 10
    GameSettings.minimumPlayers = 2
    GameSettings.transitionTime = 5
    -- Mögliche Wege, wie das Spiel beendenkann.
    GameSettings.endStates = {
    }
    return GameSettings
  2. Erstellen Sie zwei Variablen mit den Namen TimerUp und FoundWinner. Setzen Sie jede auf eine Zeichenfolge, die ihrem Namen entspricht. Diese Zeichenfolgen werden zum Testen des Codes verwendet.


GameSettings.endStates = {
TimerUp = "TimerUp",
FoundWinner = "FoundWinner"
}

Beenden mit einem Timer

Wenn der Timer endet, feuere das Match-End-Ereignis ab und sende die passende Endzustandsvariable.So können andere Skripte, die auf dieses Ereignis hören, entsprechend reagieren.Denken Sie daran, dass während Ereignisse Signale abfeuern, dass auch Daten senden kann, die von Listening-Skripten empfangen werden, wie TimerUp oder FoundWinner.

  1. In GameManager , in der while true do Schleife, finden Sie die Zeile matchEnd.Event:Wait(). Am Beginn der Zeile fügen Sie local endState = hinzu.


    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()
    end
  2. Um zu bestätigen, dass der korrekte Zustand empfangen wurde, füge eine Druckausdruck hinzu, der endState enthält.


    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()
    print("Game ended with: " .. endState)
    end
  3. In MatchManager finden Sie timeUp() und entfernen die Druckausgabe.Dann, um das Endereignis des Spiels abzufeuern, geben Sie matchEnd:Fire() ein und übergeben Sie gameSettings.endStates.TimerUp.


    -- 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 timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  4. Teste ein übereinstimmen. Sobald der Timer abgelaufen ist, überprüfe, ob die Druck statement den String enthält, der in der TimerUp Variable gespeichert ist.

Problemlösungstipps

An diesem Punkt wurde die Nachricht nicht angezeigt, versuchen Sie eine der folgenden Optionen.

  • Überprüfe, dass überall, wo die Endzustandsvariablen aufgerufen werden, genau geschrieben werden, wie hier: gameSettings.endStates.TimerUp .
  • Stellen Sie sicher, :(Kolonnenbetreiber) mit dem Fire() anstelle des Punktoпераators zu verwenden, wie in matchEnd:Fire() .

Kodiere ein gewinnendes übereinstimmen

Als Nächstes muss das Skript gewinnende Spieler identifizieren, verlorene Spieler entfernen und Reinigungsaufgaben wie das Beenden des Timers ausführen.Spiele enden auch, wenn ein Spieler übrig bleibt.Um zu sehen, ob die Bedingung FoundWinner erfüllt ist, benötigen Sie eine Funktion, die die in der Tabelle verbleibende Anzahl von Spielern in einem übereinstimmenüberprüft.

Spieleranzahl überprüfen

Spiele enden, wenn nur ein Spieler übrig ist.Um dies zu überprüfen, muss das Skript die Spieler in einer Runde verfolgen.Sobald ein Spieler verlassen ist, kann ein Gewinner zugewiesen werden.

  1. In PlayerManager definieren Sie die folgenden Variablen:

    • Ordner ModulScripts
    • GameSettings-Modul - Wird verwendet, um Endzustandsvariablen zuzugreifen
    • Veranstaltungsordner und das MatchEnd-Ereignis - Feuerevent

    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")
  2. Über respawnPlayerInLobby(), füge eine neue lokale Funktion mit dem Namen checkPlayerCount() hinzu.


    -- Spielervariablen
    local activePlayers = {}
    local playerWeapon = ServerStorage.Weapon
    local function checkPlayerCount()
    end
    local function respawnPlayerInLobby(player)
  3. Innerhalb dieser Funktion verwende ein if dann-Statement, um nach einem Gewinner zu suchen. In dieser Aussage:

    • Überprüfe, ob die Größe der activePlayers Tabelle 1 ist.
    • Wenn ja, feuere matchEnd ab und gib gameSettings.endStates.FoundWinner ein.

    local function checkPlayerCount()
    if #activePlayers == 1 then
    matchEnd:Fire(gameSettings.endStates.FoundWinner)
    end
    end

Spieler:inentfernen

Eine genaue Zählung kann nicht beibehalten werden, es sei denn, Spieler werden entfernt.Wenn ein Spieler besiegt wird, halte eine genaue Spieleranzahl aufrecht, indem du ihn vom Spieler-Tisch entfernst.Überprüfe dann die Größe des aktiven Spielertisches, um zu sehen, ob es einen Gewinner gibt.

  1. Unter checkPlayerCount(), erstelle eine neue lokale Funktion mit dem Namen removeActivePlayer() mit einem Parameter namens player.


    local function checkPlayerCount()
    if #activePlayers == 1 then
    matchEnd:Fire(gameSettings.endStates.FoundWinner)
    end
    end
    local function removeActivePlayer(player)
    end
  2. Um den Spieler in der activePlayers Tabelle zu finden, iteriere durch sie mit einer for Schleife.Füge dann eine if-Aussage hinzu, die ausgeführt wird, wenn ein Spieler mit dem Namen, der in die Funktion übergeben wird, gefunden wird.


    local function removeActivePlayer(player)
    for playerKey, whichPlayer in activePlayers do
    if whichPlayer == player then
    end
    end
    end
  3. Um den Spieler:inzu entfernen, in der if- statement:

    • Rufen Sie table.remove() an. Im Inneren der Klammern geben Sie activePlayers ein, die Tabelle, die angesehen werden soll, und playerKey - den Spieler, den Sie von der Tabelle entfernen müssen.
    • Setze den Wert des playersLeft Objekts auf #activePlayers.
    • Überprüfe einen siegreichen Spieler, indem du checkPlayerCount() ausführst.

    local function removeActivePlayer(player)
    for playerKey, whichPlayer in activePlayers do
    if whichPlayer == player then
    table.remove(activePlayers, playerKey)
    playersLeft.Value = #activePlayers
    checkPlayerCount()
    end
    end
    end

Verbinden von Ereignissen und Testen

Um die gerade erstellte Funktion zu verwenden, rufe sie von der anonymen Funktion aus, die mit dem Died-Ereignis des Spieler:inverbunden ist.

  1. Finde preparePlayer() . In der anonymen Funktion mit der Verbindung zum Ereignis Tod, rufe removeActivePlayer() auf. Dann übermittle den Spieler als Parameter.


    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    removeActivePlayer(player)
    end)
  2. Um zu sehen, ob ein Gewinner gefunden wird, starten Sie einen Testserver .Wenn nur ein Spieler übrig ist, solltest du FoundWinner im Ausgabe-Fenster sehen.

  3. Fortfahren Sie mit den Tests und lassen Sie das Spiel beenden. Beachten Sie, wenn ein neues Spiel beginnt, erscheint ein Fehler im Ausgabe-Fenster:

Dieser Fehler tritt auf, weil der Timer nicht angehalten wurde, was im nächsten Abschnitt behoben wird.

Stoppe den Timer

Wann immer ein Spiel mit einem siegreichen Spieler:inendet, sollte auch die Timer stoppen.Um den Timer zu stoppen, bevor die Zeit abläuft, lass den Timer stoppen, wenn das Match-End-Ereignis ausgelöst wird.Dies ist einer der Vorteile der Erstellung von Ereignissen.Sie können in mehreren Situationen wiederverwendet werden, um Skript-Ursache- und -Wirkungsbeziehungen zu skriptieren.

  1. Erstellen Sie in MatchManager eine neue lokale Funktion mit dem Namen stopTimer(). Im Inneren geben Sie myTimer:stop() ein, um den Timer anzuhalten.


    -- 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
  2. Um den Timer zu stoppen, wenn das Spiel endet, verbinden Sie das matchEnd-Ereignis mit stopTimer().


    -- Modulfunktionen
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  3. Test , dass der vorherige Fehler nicht mehr auftaucht, indem du einen Server startest.Eliminiere alle, aber einen Spieler und warte dann ein paar Sekunden, nachdem das Spiel beendet ist.

Nächste Schritte

Während die beiden Gewinnbedingungen abgeschlossen sind, bleiben noch einige Aufgaben übrig, um die Spielschleife abzuschließen.Zum Instanzwird der gewinnende Spieler niemals in die Lobby teleportiert.In der nächsten Lektion zeigst du an, wie das Spiel für Spieler beendet wurde und setzt das Spiel zurück, um schließlich die gesamte Schleife abzuschließen.

Abgeschlossene Skripte

Im Folgenden sind abgeschlossene Skripte, um deine Arbeit zu überprüfen.

Skript, das. PL: die Skripts


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")
-- 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
-- Lokale Funktionen
local function checkPlayerCount()
if #activePlayers == 1 then
matchEnd:Fire(gameSettings.endStates.FoundWinner)
end
end
local function removeActivePlayer(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 onPlayerJoin(player)
player.RespawnLocation = lobbySpawn
end
local function preparePlayer(player, whichSpawn)
player.RespawnLocation = whichSpawn
player:LoadCharacter()
local character = player.Character or player.CharacterAdded:Wait()
local sword = playerWeapon:Clone()
sword.Parent = character
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
respawnPlayerInLobby(player)
removeActivePlayer(player)
end)
end
-- Modulfunktionen
function PlayerManager.sendPlayersToMatch()
local arenaSpawns = spawnLocations:GetChildren()
for playerKey, whichPlayer in Players:GetPlayers() do
table.insert(activePlayers, whichPlayer)
local spawnLocation = table.remove(arenaSpawns, 1)
preparePlayer(whichPlayer, spawnLocation)
end
playersLeft.Value = #activePlayers
end
-- Ereignisse
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager

Skript, das. PL: die Skripts


local GameSettings = {}
-- Spielvariablen
GameSettings.intermissionDuration = 5
GameSettings.matchDuration = 10
GameSettings.minimumPlayers = 2
GameSettings.transitionTime = 5
-- Mögliche Wege, wie das Spiel beendenkann.
GameSettings.endStates = {
TimerUp = "TimerUp",
FoundWinner = "FoundWinner"
}
return GameSettings

Skript, das. PL: die Skripts


-- Dienste
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Modul-Skripte
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()
print("Game ended with: " .. endState)
end

Skript, das. PL: die Skripts


local MatchManager = {}
-- Dienste
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 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()
print("Timer started")
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
matchStart.Event:Connect(startTimer)
matchEnd.Event:Connect(stopTimer)
return MatchManager