Temporizadores e Eventos

*Este conteúdo é traduzido por IA (Beta) e pode conter erros. Para ver a página em inglês, clique aqui.

Durante o tempo de uma rodada, os scripts precisarão rastrear o tempo e enviar sinais entre diferentes scripts. O tempo será gerenciado usando um script de tempo, enquanto os eventos, um conceito no código do Roblox, enviarão sinais de mudanças, como o fim de uma conferir.

Enviando sinais com eventos

Com os jogadores agora na arena, eventos podem ser usados para sinalizar o início do match e o código para o timer pode começar. Depois, um evento também pode ser usado para sinalizar o fim do conferir, e que é hora de fazer com que os jogadores retornem ao lobby.

Esses eventos não são pré-construídos, então os objetos de evento personalizados chamados objetos de evento vinculáveis precisarão ser criados. Os eventos vinculáveis são frequentemente usados para ações de jogadores e são semelhantes a eventos como Touched ou Changed.

Múltiplos scripts podem ouvir os mesmos eventos vinculáveis. Isso mantém seu código organizado e facilita adicionar código adicional para o início ou fim do match mais tarde, se necessário.

Criando Eventos Vinculáveis

Comece criando objetos de evento vinculáveis para o início e o fim da conferir. Como objetos de evento vinculáveis não interagem com o cliente, eles podem ser armazenados no armazenamento do servidor.

  1. In ServerStorage, create a new folder named Events. In that folder, create two BindableEvents named MatchStart and MatchEnd.

Usando Eventos

Agora, quando os jogadores entram na arena, a intermissão continua reiniciando em vez de iniciar o cronômetro. O loop principal de jogos precisa ser dito para parar e esperar até o evento MatchEnd iniciar antes de seguir para a próxima parte do código.

Os eventos têm duas funções incorporadas: Connect() e Wait(). Em vez de usar Connect() como antes, chame 2>Wait()2> no MatchEnd para pausar o script do gerenciador de jogos até que o MatchEnd seja executado. Neste caso, a função de espera pausa o código até que o gerenciador de jogos receba um sinal que o match terminou.

  1. In GameManager , create variables for the Events夹 and MatchEnd event.


    -- Scripts de Módulo
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    -- Eventos
    local events = ServerStorage:WaitForChild("Events")
    local matchEnd = events:WaitForChild("MatchEnd")
  2. Tenha o script esperando pelo evento de fim de match para disparar antes de seguir. No loop , no end , digitar: matchEnd.Event:Wait()


    while true do
    repeat
    task.wait(gameSettings.intermissionDuration)
    print("Restarting intermission")
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    print("Intermission over")
    task.wait(gameSettings.transitionTime)
    matchManager.prepareGame()
    -- O placeholder espera pela longura do jogo.
    matchEnd.Event:Wait()
    end
  3. Teste o jogo. Confirme que, uma vez que os jogadores estão na arena, o loop de intermissão não continua. O script agora está esperando o sinal de matchEnd para Iniciar / executar.

Dicas de solução de problemas

Neste ponto, o código não funciona como deveria, tente um dos seguintes abaixo.

  • Verifique duas vezes a utilização dos operadores de ponto ou vírgula em matchEnd.Event:Wait() .
  • Verifique se MatchEnd é um BindableEvent, e não outro digitar, como um RemoteEvent.

Usando um Temporizador

Uma das condições que causarão o fim da partida é um temporizador que expira, que será tratado através do script.

Configurando o Temporizador

Para adicionar um timer no jogo, use o script de módulo prêmade nas etapas abaixo. Ele inclui funções para iniciar e terminar um timer, bem como retornar o tempo restante.

  1. In ServerStorage >ModuleScripts, crie um novo script de módulo chamado Timer.

    Substitua o código com o código abaixo.


    local Timer = {}
    Timer.__index = Timer
    function Timer.new()
    local self = setmetatable({}, Timer)
    self._finishedEvent = Instance.new("BindableEvent")
    self.finished = self._finishedEvent.Event
    self._running = false
    self._startTime = nil
    self._duration = nil
    return self
    end
    function Timer:start(duration)
    if not self._running then
    task.spawn(function()
    self._running = true
    self._duration = duration
    self._startTime = tick()
    while self._running and tick() - self._startTime < duration do
    task.wait()
    end
    local completed = self._running
    self._running = false
    self._startTime = nil
    self._duration = nil
    self._finishedEvent:Fire(completed)
    end)
    else
    warn("Warning: timer could not start again as it is already running.")
    end
    end
    function Timer:getTimeLeft()
    if self._running then
    local now = tick()
    local timeLeft = self._startTime + self._duration - now
    if timeLeft < 0 then
    timeLeft = 0
    end
    return timeLeft
    else
    warn("Warning: could not get remaining time, timer is not running.")
    end
    end
    function Timer:isRunning()
    return self._running
    end
    function Timer:stop()
    self._running = false
    end
    return Timer
  2. No MatchManager, requer os módulos GameSettings e Timer.


    local MatchManager = {}
    -- Serviços
    local ServerStorage = game:GetService("ServerStorage")
    -- Scripts de Módulo
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    local timer = require(moduleScripts:WaitForChild("Timer"))
  3. Abaixo das variáveis, crie um novo objeto de timer definindo uma variável chamada myTimer igual a timer.new() . Este objeto será usado para chamar funções que iniciam e param o timer.


    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    local timer = require(moduleScripts:WaitForChild("Timer"))
    -- Cria um novo objeto de relógio para ser usado para rastrear o tempo da partida.
    local myTimer = timer.new()

Iniciando e Parando

Agora que um cronômetro é criado, use as funções incluídas start() e stop() durante uma conferir. Abaixo está uma descrição de cada função e o parâmetro que ela aceita.

  • start(time) - Inicia o timer, com o tempo em segundos como o parâmetro.
  • finished:Connect(functionName) - Quando o tempo acabar, executa a função passada como um parâmetro.
  1. In MatchManager , crie uma nova função chamada timeUp() para ser executada sempre que o temporizador terminar. Incluir uma declaração de teste.


    local myTimer = timer.new()
    -- Funções Locais
    local function timeUp()
    print("Time is up!")
    end
    -- Funções de Modulo
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    end
    return MatchManager
  2. Below timeUp() , adicione uma função chamada startTimer() com uma declaração de impressão. Você exibirá o timer no jogo depois.


    -- Funções Locais
    local function timeUp()
    print("Time is up!")
    end
    local function startTimer()
    print("Timer started")
    end
  3. Para iniciar e parar o timer, em startTimer() :

    • Chame myTimer.start() . Passe em gameSettings.matchDuration .
    • Chame myTimer.finished:Connect() . Passe em timeUp() .

    -- Funções Locais
    local function startTimer()
    print("Timer started")
    myTimer:start(gameSettings.matchDuration)
    myTimer.finished:Connect(timeUp)
    end

Iniciando o Temporizador

O relógio pode ser iniciado no começo de uma partida usando o evento Início de Partida.

  1. No MatchManager, sob as variáveis de módulo, crie variáveis para armazenar as pastas Evento, Início de Partida e Fim de Partida (que é usado em uma futura aula).


    -- Scripts de Módulo
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    local timer = require(moduleScripts:WaitForChild("Timer"))
    -- Eventos
    local events = ServerStorage:WaitForChild("Events")
    local matchStart = events:WaitForChild("MatchStart")
    local matchEnd = events:WaitForChild("MatchEnd")
    --Cria um cronômetro
    local myTimer = timer.new()
  2. Acima de return MatchManager, conecte o evento de início da partida ao startTimer() .


    -- Funções de Modulo
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    end
    matchStart.Event:Connect(startTimer)
    return MatchManager
  3. Para disparar o evento de início da partida, em prepareGame(), digite matchStart:Fire().


    -- Funções de Modulo
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
  4. Teste o jogo. Na janela de saída, confirme que você pode ver as declarações de saída para as funções de inicialização e parada do timer.

Scripts Concluídos

Abaixo estão scripts concluídos para verificar duas vezes seu trabalho.

Script do MatchManager


local MatchManager = {}
-- Serviços
local ServerStorage = game:GetService("ServerStorage")
-- Scripts de Módulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Cria um novo objeto de relógio para ser usado para rastrear o tempo da partida.
local myTimer = timer.new()
-- Funções Locais
local function timeUp()
print("Time is up!")
end
local function startTimer()
print("Timer started")
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
end
-- Funções de Modulo
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
return MatchManager

Script do GameManager


-- Serviços
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Scripts de Módulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
while true do
repeat
task.wait(gameSettings.intermissionDuration)
print("Restarting intermission")
until #Players:GetPlayers() >= gameSettings.minimumPlayers
print("Intermission over")
task.wait(gameSettings.transitionTime)
matchManager.prepareGame()
-- O placeholder espera pela longura do jogo.
matchEnd.Event:Wait()
end