Fin des matchs

*Ce contenu est traduit en utilisant l'IA (Beta) et peut contenir des erreurs. Pour consulter cette page en anglais, clique ici.

Les matchs peuvent se terminer dans quelques conditions, y compris le temps écoulé ou un seul joueur laissé.

Gérer les joueurs vaincus

En ce moment, les joueurs vaincus réapparaissent dans l'arène. Au lieu de cela, envoie-les dans le lobby pour attendre le prochain correspondre.

  1. Dans PlayerManager, créez une fonction locale nommée respawnPlayerInLobby(). Dans cette fonction, faites ce qui suivre:
  • Définissez la propriété RespawnLocation du joueur sur le lobbySpawn.
  • Rechargez le personnage avec Player:LoadCharacter() . Souvenez-vous, LoadCharacter() recrée le joueur à leur régénération, apparition, en supprimant tous les outils qu'il avait.

Utiliser des fonctions anonymes

Les fonctions anonymes sont couramment utilisées dans des scripts avancés dans des situations spécifiques.Avant de les définir, il est important de comprendre une situation que votre script peut rencontrer.

Considérez ceci : Pour téléporter les joueurs vaincus dans le lobby, la fonction de réapparition devra être connectée à l'événement mort du joueur.Il y a un problème cependant.Si vous connectez l'événement comme nous l'avons fait dans le passé, il n'y a aucun moyen d'obtenir le nom du joueur de l'événement Décédé.Le script a besoin de ce nom pour supprimer un joueur vaincu de la table qui suit les joueurs actifs.

Pour obtenir le nom du joueur qui a déclenché l'événement Décédé, utilisez une fonction anonyme. Les fonctions anonymes n'ont pas de noms et peuvent être créées directement dans Connect() au lieu de séparément.

Une fonction anonyme d'échantillon est ci-dessous qui montre la syntaxe.


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

Codez l'événement mort

Pour cette fonction, chaque fois que le personnage d'un joueur meurt, il déclenchera la fonction qui le réapparaît.

  1. Pour accéder à l'événement Died du joueur, dans PlayerManager > preparePlayer(), ajoutez une variable pour le humanoïde du joueur.


    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. Créer une fonction anonyme qui se connecte à l'événement Died.Commencez par taper humanoid.Died:Connect().Ensuite, à l'intérieur de Connect() , tapez function() , appuyez sur Enter pour autocompléter end et supprimez la parenthèse supplémentaire.


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    end)
  3. Dans la fonction anonyme, appelez respawnPlayerInLobby() . Passer en player , une variable qui stocke le joueur se préparant à entrer dans une correspondre.


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    end)
  4. Démarrez un serveur et jouez à un correspondre.Testez que lorsqu'un joueur meurt, il réapparaît dans le lobby.Pour vaincre les joueurs, marchez jusqu'à eux et utilisez votre arme jusqu'à ce que vous puissiez confirmer qu'ils ont réapparu dans le lobby.

    Attaquer le joueur 2
    Joueur2 dans le lobby après réapparition

Notez qu'il existe également différentes façons de tester si vous le souhaitez.

  • Pour tuer un joueur, dans la fenêtre Serveur > Sortie > Barre de commande, copiez et collez : workspace.Player1.Humanoid.Health = 0 .Appuyez sur Enter pour exécuter la commande.Pour supprimer d'autres joueurs, utilisez Player2, Player3, etc.
  • Définir GameSettings > à une plus longue période peut vous donner plus de temps pour trouver et éliminer tous les joueurs.
  • Pour avoir des tests plus rapides, modifiez GameSettings > minimumPlayers à un nombre plus petit, comme 2.

Finir le jeu

Maintenant que les joueurs vaincus sont réapparus, commencez à travailler sur la fin du jeu.Vous vous souvenez de la création de l'événement MatchEnd ? Il sera déclenché lorsque le minuteur expire ou qu'un gagnant est trouvé.

Pour dire aux autres scripts quelle condition a terminé le jeu, créez une table avec des variables pour TimerUp et FoundWinner.Lorsque l'événement de fin du match se déclenche, il passera dans une variable afin que d'autres scripts puissent répondre.

  1. Dans GameSettings, créez une table de module vide nommée endStates.


    local GameSettings = {}
    -- Variables de jeu
    GameSettings.intermissionDuration = 5
    GameSettings.matchDuration = 10
    GameSettings.minimumPlayers = 2
    GameSettings.transitionTime = 5
    -- Les façons possibles dont le jeu peut se terminer.
    GameSettings.endStates = {
    }
    return GameSettings
  2. Créez deux variables nommées TimerUp et FoundWinner. Définissez chacune d'entre elles sur une chaîne correspondant à leur nom. Ces chaînes seront utilisées pour tester le code.


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

Se terminer avec un minuterie

Lorsque le minuteur se termine, déclenchez l'événement de fin du match et envoyez la variable d'état de fin correspondante.De cette façon, d'autres scripts qui écoutent cet événement peuvent répondre en conséquence.Rappelez-vous que, bien que les événements envoient des signaux d'incendie, ils peuvent également envoyer des données reçues par des scripts d'écoute, comme TimerUp ou FoundWinner.

  1. Dans GameManager , dans la boucle while true, trouvez la ligne matchEnd.Event:Wait(). Au début de la ligne, ajoutez local 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()
    end
  2. Pour confirmer que l'état correct a été reçu, ajoutez une déclaration d'impression comprenant 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()
    print("Game ended with: " .. endState)
    end
  3. Dans MatchManager, trouvez timeUp() et supprimer la déclaration d'impression.Ensuite, pour déclencher l'événement de fin du match, tapez matchEnd:Fire() et passez en gameSettings.endStates.TimerUp.


    -- Valeurs
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local timeLeft = displayValues:WaitForChild("TimeLeft")
    -- Crée un nouvel objet de minuterie à utiliser pour suivre le temps du match.
    local myTimer = timer.new()
    -- Fonctions locales
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  4. Testez un correspondre. Une fois que le temps est écoulé, vérifiez que la déclaration d'impression inclut la chaîne stockée dans la variable TimerUp.

Conseils de dépannage

À ce stade, le message n'a pas été affiché, essayez l'une des options suivantes.

  • Vérifiez que partout où les variables d'état final sont appelées, elles sont écrites exactement, comme ici : gameSettings.endStates.TimerUp .
  • Assurez-vous d'utiliser : (opérateur colonne) avec le à la place du point d'opérateur, comme dans .

Coder un correspondregagnant

Ensuite, le script doit identifier les joueurs gagnants, éliminer les joueurs perdants et exécuter le nettoyage, comme l'arrêt du minuteur.Les matchs s'arrêteront également si un joueur est laissé.Pour voir si la condition FoundWinner est satisfaite, vous aurez besoin d'une fonction qui vérifie le nombre laissé dans la table qui suit les joueurs dans un correspondre.

Vérifier le nombre de joueurs

Les matchs se termineront s'il ne reste qu'un seul joueur.Pour vérifier cela, le script doit suivre les joueurs dans une ronde.Une fois qu'un joueur est parti, un gagnant peut être attribué.

  1. Dans PlayerManager, définissez les variables suivantes :

    • Dossier des modulesScripts
    • Module GameSettings - Utilisé pour accéder aux variables d'état final
    • Dossier d'événements et l'événement MatchEnd - Événement de feu

    local PlayerManager = {}
    -- Services
    local Players = game:GetService("Players")
    local ServerStorage = game:GetService("ServerStorage")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    -- Moduleurs
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    -- Événements
    local events = ServerStorage:WaitForChild("Events")
    local matchEnd = events:WaitForChild("MatchEnd")
  2. Au-dessus de respawnPlayerInLobby(), ajoutez une nouvelle fonction locale nommée checkPlayerCount().


    -- Variables du joueur
    local activePlayers = {}
    local playerWeapon = ServerStorage.Weapon
    local function checkPlayerCount()
    end
    local function respawnPlayerInLobby(player)
  3. Dans cette fonction, utilisez une déclaration if then pour vérifier un gagnant. Dans cette déclaration :

    • Vérifiez si la taille de la table activePlayers est de 1.
    • Si c'est le cas, tirez matchEnd et passez en gameSettings.endStates.FoundWinner.

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

Supprimer un joueur

Un comptage précis ne peut pas être maintenu à moins que les joueurs soient retirés.Lorsqu'un joueur est vaincu, garde un nombre précis de joueurs en le retirant de la table des joueurs.Ensuite, vérifiez la taille de la table des joueurs actifs pour voir s'il y a un gagnant.

  1. Sous checkPlayerCount(), créez une nouvelle fonction locale nommée removeActivePlayer() avec un paramètre nommé player .


    local function checkPlayerCount()
    if #activePlayers == 1 then
    matchEnd:Fire(gameSettings.endStates.FoundWinner)
    end
    end
    local function removeActivePlayer(player)
    end
  2. Pour trouver le joueur dans la table activePlayers, itérer à travers elle en utilisant une boucle for.Ensuite, ajoutez une déclaration if qui s'exécute si un joueur correspondant au nom passe dans la fonction est trouvé.


    local function removeActivePlayer(player)
    for playerKey, whichPlayer in activePlayers do
    if whichPlayer == player then
    end
    end
    end
  3. Pour supprimer le joueur, dans la déclaration if :

    • Appellez table.remove() . À l'intérieur des parenthèses, passez activePlayers , la table à regarder, et playerKey - le joueur à supprimer de la table.
    • Définissez la valeur de l'objet playersLeft à #activePlayers.
    • Vérifiez un joueur gagnant en exécutant checkPlayerCount() .

    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

Connecter les événements et tester

Pour utiliser la fonction vient d'être créée, appelez-la à partir de la fonction anonyme connectée à l'événement Died du joueur.

  1. Trouvez preparePlayer() . Dans la fonction anonyme avec la connexion événement Died, appelez removeActivePlayer() . Ensuite, passez le joueur en tant que paramètre.


    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    removeActivePlayer(player)
    end)
  2. Pour voir si un joueur gagnant est trouvé, lancez un serveur de test test .Lorsqu'il ne reste qu'un seul joueur, vous devez voir FoundWinner dans la fenêtre de sortie.

  3. Continuez à tester et laissez le match se terminer. Remarquez comme un nouveau match commence, une erreur apparaît dans la fenêtre de sortie :

Cette erreur est due au fait que le minuteur n'a pas été arrêté, ce qui sera corrigé dans la section suivante.

Arrêter le minuteur

Chaque fois qu'un match se termine avec un joueur gagnant, le minuteur doit s'arrêter également.Pour arrêter le minuteur avant la fin du temps, faites en sorte que le minuteur s'arrête chaque fois que l'événement de fin du match se déclenche.C'est l'un des avantages de la création d'événements.Ils peuvent être réutilisés dans plusieurs situations pour script les relations de cause et d'effet.

  1. Dans MatchManager, créez une nouvelle fonction locale nommée stopTimer() . À l'intérieur, saisissez myTimer:stop() pour arrêter le minuterie.


    -- Crée un nouvel objet de minuterie à utiliser pour suivre le temps du match.
    local myTimer = timer.new()
    -- Fonctions locales
    local function stopTimer()
    myTimer:stop()
    end
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  2. Pour arrêter le minuteur lorsque le match se termine, connectez l'événement matchEnd à stopTimer() .


    -- Fonctions de module
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  3. Tester que l'erreur précédente n'apparaît plus en démarrant un serveur .Éliminez tous sauf un joueur puis attendez quelques secondes une fois le match terminé.

Prochaines étapes

Bien que les deux conditions de victoire soient terminées, il reste encore quelques tâches pour terminer la boucle de jeu.Par instance, le joueur gagnant n'est jamais téléporté dans le lobby.Dans la leçon suivante, vous afficherez comment le match s'est terminé pour les joueurs et réinitialiserez le jeu, terminant enfin la boucle entière.

Scripts terminés

Ci-dessous, les scripts terminés pour vérifier à nouveau votre travail.

scriptPlayerManager


local PlayerManager = {}
-- Services
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Moduleurs
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Événements
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Variables de carte
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Valeurs
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Variables du joueur
local activePlayers = {}
local playerWeapon = ServerStorage.Weapon
-- Fonctions locales
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
-- Fonctions de module
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
-- Événements
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager

scriptdes paramètres de jeu


local GameSettings = {}
-- Variables de jeu
GameSettings.intermissionDuration = 5
GameSettings.matchDuration = 10
GameSettings.minimumPlayers = 2
GameSettings.transitionTime = 5
-- Les façons possibles dont le jeu peut se terminer.
GameSettings.endStates = {
TimerUp = "TimerUp",
FoundWinner = "FoundWinner"
}
return GameSettings

scriptdu gestionnaire de jeu


-- Services
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Scripts de module
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Événements
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

scriptde MatchManager


local MatchManager = {}
-- Services
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Scripts de module
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- Événements
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Valeurs
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Crée un nouvel objet de minuterie à utiliser pour suivre le temps du match.
local myTimer = timer.new()
-- Fonctions locales
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
-- Ajouter +1 garantit que l'affichage du temps se termine à 1 au lieu de 0.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- En ne définissant pas l'heure d'attente, il offre une boucle plus précise
task.wait()
end
end
-- Fonctions de module
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
matchEnd.Event:Connect(stopTimer)
return MatchManager