時間和事件

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

在回合的過程中,需要追蹤時間,並在不同的腳本之間傳送信號。時間使用時間指指令碼來管理時間,而事件是 Roblox 編寫的概念,會發送變更,例如結束一場相符。

使用事件發送信號

現在有玩家在競技場中,玩家可以使用事件來啟用比賽開始和代碼來啟用計時器。稍後,一個事件也可以用來啟用比相符結束,並將玩家重新傳回大廳。

這些事件不是預處理的,因此需要建立 可綁定的事件 。 可綁定的事件通常用於玩家發射的行動,並與 TouchedChanged 類似。

多個脚本可以聆聽相同的可聆聽事件。這使您的代碼有機會排名,並且在需要時更容易添加額外的代碼以啟動或結束比賽。

建立可綁定的事件

從創建結束時和開始時的可綁定事件對象來啟動。綁定的事件不會與客戶端交互,因此可以存儲在伺服器儲存中。

  1. 在 ServerStorage 中,建立名為「Events」的新資料夾。在那個資料夾中,建立兩個名為「MatchStart」和「MatchEnd」的 BindableEvents

使用事件

現在,當玩家進入競技場時,中場休息會繼續重新啟動,而不是開始計時器。主要遊戲循環需要告訴停止並等待 MatchEnd 事件發生,然後才能切換到下一個部分代碼。

事件有兩個內置功能:Connect()Wait()。 而不是使用 Connect() 作為以前使用過的 ,請在 2>MatchEnd2> 上呼叫 5>Wait5> 來暫停遊戲管理員指令直到 MatchEnd 發射。 在這個情況下,等待功能會暫停代碼直到�

  1. GameManager 中,為 Events 文件夾和 MatchEnd 事件建立變數。


    -- 模組指令碼
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    -- 事件
    local events = ServerStorage:WaitForChild("Events")
    local matchEnd = events:WaitForChild("MatchEnd")
  2. 在進行到下一步前,讓指令碼等待發射對應結束事件。在 循環中,在 結束,輸入: 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()
    -- 等待遊戲長度。
    matchEnd.Event:Wait()
    end
  3. 測試 遊戲。確認一旦玩家在競技場中時,中場循環 不會 繼續。 script 現在正在等待 matchEnd 信號發觸發。

排障提示

在這個時候,代碼不像預期般工作,請嘗試以下一些。

  • matchEnd.Event:Wait() 中檢查使用點或空格操作者的使用。
  • 確認 MatchEnd 是 BindableEvent,而不是其他輸入,例如遠端事件。

使用計時器

比賽結束的一個條件是時間器到達,這會通過指令碼處理。

設定計時器

要將計時器添加到遊戲中,請使用下面的步驟中的預製模組指令碼。它包括啟動和結束計時器的功能,以及返回剩餘時間。

  1. 在 ServerStorage > ModuleScripts 中,創建名為 Timer 的新模組腳本。

    將代碼替換為下列代碼。


    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. 在 MatchManager 中,需要 GameSettings 和 Timer 模組。


    local MatchManager = {}
    -- 服務
    local ServerStorage = game:GetService("ServerStorage")
    -- 模組指令碼
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    local timer = require(moduleScripts:WaitForChild("Timer"))
  3. 在變數下,創建一個名為 myTimer 的新計時器對象,與 timer.new() 相等。這個對象將被用來呼叫啟動和停止計時器的函數。


    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    local timer = require(moduleScripts:WaitForChild("Timer"))
    -- 建立一個新的計時器對象,可用來跟蹤比賽時間。
    local myTimer = timer.new()

開始和停止

現在創建了計時器,請在比相符中使用包含的函數start()stop()。以下是每個函數的說明和參數。

  • start(time) - 啟動計時器,以秒為參數時間。
  • finished:Connect(functionName) - 當計時器結束時,運行傳為參數的函數。
  1. 匹配管理器 中,創建名為 timeUp() 的新函數,以便在計時器結束時執行。包括測試打印說明。


    local myTimer = timer.new()
    -- 本地函數
    local function timeUp()
    print("Time is up!")
    end
    -- 模組功能
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    end
    return MatchManager
  2. timeUp() 以下,添加名為 startTimer() 的函數。你稍後會在遊戲中顯示計時器。


    -- 本地函數
    local function timeUp()
    print("Time is up!")
    end
    local function startTimer()
    print("Timer started")
    end
  3. 要啟動和停止計時器,在 startTimer() :

    • 呼叫 myTimer.start()。 過度在 gameSettings.matchDuration
    • 呼叫 myTimer.finished:Connect() . 在 timeUp() 後通過。

    -- 本地函數
    local function startTimer()
    print("Timer started")
    myTimer:start(gameSettings.matchDuration)
    myTimer.finished:Connect(timeUp)
    end

開始計時器

計時器可以在比賽開始時使用比賽開始事件來啟動。

  1. 在 MatchManager 中,在模組變量下,創建變量來儲存事件資料冊、 MatchStart 和 MatchEnd (可能在未來的課程中使用)。


    -- 模組指令碼
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    local timer = require(moduleScripts:WaitForChild("Timer"))
    -- 事件
    local events = ServerStorage:WaitForChild("Events")
    local matchStart = events:WaitForChild("MatchStart")
    local matchEnd = events:WaitForChild("MatchEnd")
    --建立計時器
    local myTimer = timer.new()
  2. return MatchManager 以上,將匹配開始事件連接到 startTimer()


    -- 模組功能
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    end
    matchStart.Event:Connect(startTimer)
    return MatchManager
  3. 要啟動匹配開始事件,在 prepareGame() 裡,請輸入 matchStart:Fire()


    -- 模組功能
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
  4. 測試遊戲。在輸出窗口中,確認您可以看到計時器的開始和停止功能的打印說明。

已完成的指令碼

下面是完成審核您的工作的指令碼。

MatchManager 指令碼


local MatchManager = {}
-- 服務
local ServerStorage = game:GetService("ServerStorage")
-- 模組指令碼
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- 事件
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- 建立一個新的計時器對象,可用來跟蹤比賽時間。
local myTimer = timer.new()
-- 本地函數
local function timeUp()
print("Time is up!")
end
local function startTimer()
print("Timer started")
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
end
-- 模組功能
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
return MatchManager

GameManager 指令碼


-- 服務
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- 模組指令碼
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- 事件
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()
-- 等待遊戲長度。
matchEnd.Event:Wait()
end