Таймери та події
Під час раунду сценарії повинні будуть відстежувати час і надсилати сигнали між різними сценаріями. Час керуватиметься за допомогою сценарію часу, тоді як події, концепція кодування Roblox, сигналізуватимуть про зміни, наприклад про закінчення матчу.Створення прив'язуваних подій
Почніть із створення зв’язуваних об’єктів подій для початку та кінця матчу. Оскільки зв’язувані події не взаємодіють із клієнтом, їх можна зберігати в серверному сховищі.У ServerStorage створіть нову папку під назвою Events. У цій папці створіть два BindableEvents з іменами MatchStart і MatchEnd.

Використання таймера
Однією з умов, яка призведе до закінчення матчу, є закінчення таймера, яке буде оброблено через скрипт.Налаштування таймера
Щоб додати таймер у гру, скористайтеся готовим сценарієм модуля, виконавши наведені нижче дії. Він містить функції запуску та завершення таймера, а також повернення часу, що залишився.У ServerStorage > ModuleScripts створіть новий сценарій модуля під назвою Timer.

Замініть код на код нижче.
Створення GUI
Зараз велика частина інформації про гру знаходиться у вікні виводу, невидимому для гравців. Щоб гравці могли бути поінформовані про те, що відбувається в грі, ви створите графічний інтерфейс користувача (GUI) і закодуєте його.Відображення інформації за допомогою графічного інтерфейсу користувача
Для цієї гри текстова мітка відображатиме поточний статус гри, а також кількість гравців і час, що залишився.

Налаштування GUI
По-перше, створіть об’єкт графічного інтерфейсу користувача Screen для зберігання різних текстових елементів. Коли гравець переміщує камеру, графічний інтерфейс користувача на екрані залишається на тому самому місці.Щоб переконатися, що всі гравці бачать однаковий дисплей, помістіть GUI у папку StarterGUI . Під час запуску гри ця папка копіюється для всіх гравців.
У папці StarterGUI створіть новий ScreenGUI. Потім у ScreenGUI додайте нову TextLabel під назвою StatusText.

Налаштування сценарію
Сценарій StatusDisplay використовуватиметься для оновлення графічного інтерфейсу гравця щоразу, коли змінюється стан гри.У ReplicatedStorage створіть папку під назвою DisplayValues. У цю папку додайте StringValue під назвою Status. Щоб перевірити значення пізніше, дайте йому тимчасове значення, наприклад «Ласкаво просимо до битви!».

Оскільки локальні сценарії запускаються лише на пристрої гравця, їх не можна зберігати в папках сервера, як-от ServerStorage. ReplicatedStorage — це папка, яка доступна як клієнту (пристрою), так і серверу.
У StarterGUI > ScreenGUI > Status додайте новий локальний сценарій під назвою StatusDisplay. Сценарії, які впливають на графічний інтерфейс користувача, часто пов’язані з цим елементом графічного інтерфейсу користувача.

Створення менеджера дисплеїв
Налаштування сценарію DisplayManager
Оскільки DisplayManager має спілкуватися з іншими сценаріями, це буде сценарій модуля.У ServerStorage > ModuleScripts створіть новий сценарій модуля під назвою DisplayManager. Перейменуйте таблицю модулів відповідно до назви сценарію.
Додайте наступний код:
Відображення статусу відповідності
Під час матчу графічний інтерфейс відображає два числа: кількість гравців, що залишилися, і час. Із зміною цих чисел зміниться також і текстова мітка.Налаштування значень і функцій
IntValues буде використовуватися для зберігання кількості гравців і часу, що залишився.У ReplicatedStorage > DisplayValues створіть два IntValue з іменами PlayersLeft і TimeLeft.

Завершені сценарії
Нижче наведено завершені сценарії.Скрипт GameSettings
Скрипт GameManager
Скрипт MatchManager
-- Services
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Module 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"))
-- Events
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Values
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Creates a new timer object to be used to keep track of match time.
local myTimer = timer.new()
-- Local Functions
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
-- Adding +1 makes sure the timer display ends at 1 instead of 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- By not setting the time for wait, it offers more accurate looping
task.wait()
end
end
-- Module Functions
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
Скрипт PlayerManager
-- Services
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Modules
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Events
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Map Variables
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Values
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Player 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()
-- Give the player a 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)
-- Check to see if a player exist in case they disconnected or left.
if whichPlayer then
local character = whichPlayer.Character
-- If the player has it currently on their character
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- If the player has the weapon in their backpack
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)
-- Gets a spawn location and then removes it from the table so the next player gets the next spawn
local spawnLocation = availableSpawnPoints[1]
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
-- Events
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager