Roblox · Захват флага · урок 6

Победа

В конце раунда сервер считает флаги каждой команды и показывает всем победителя.

Структура

Синим — что добавляем на этом уроке.

ReplicatedStorage
└─ WinEvent (RemoteEvent)
ServerScriptService
└─ TimerServer (Script) — добавили подсчёт
StarterGui
└─ WinnerGui (ScreenGui) — Enabled выкл., ResetOnSpawn выкл.
   ├─ WinLabel (TextLabel) — крупно по центру
   └─ WinLocal (LocalScript)

Шаги

  1. ReplicatedStorage → RemoteEvent «WinEvent».
  2. В TimerServer — функция Winner: складывает Flags игроков каждой команды. Равный счёт — ничья (в методичке ничья отдавала победу первой команде).
  3. FireAllClients отправляет всем текст и цвет команды-победителя.
  4. WinnerGui (Enabled выкл.) → TextLabel «WinLabel» крупно по центру, LocalScript «WinLocal» — показывает на 5 секунд и прячет.
  5. Счёт обнуляется в начале каждой игры, а не в конце: в лобби по Tab видно результат прошлого раунда.

Скрипты

TimerServer

Где: ServerScriptService · Script
Зачем: Раунды и подсчёт победителя.

-- игроки
local Players = game:GetService("Players")
-- общее хранилище
local RS = game:GetService("ReplicatedStorage")
-- идёт лобби?
local lobby = RS:WaitForChild("Lobby")
-- сколько секунд осталось
local timeLeft = RS:WaitForChild("TimeLeft")
-- команды
local Teams = game:GetService("Teams")
-- объявить победителя
local winEvent = RS:WaitForChild("WinEvent")
-- секунд в лобби
local LOBBY_TIME = 30
-- секунд игры (5 минут)
local GAME_TIME = 300

-- всех игроков с командой — на точки своей команды
local function SendAll(folder)
    -- каждый игрок
    for _, player in ipairs(Players:GetPlayers()) do
        -- команда выбрана
        if player.Team then
            -- точка команды в этой папке
            player.RespawnLocation = folder:FindFirstChild(player.Team.Name)
            -- возрождаем там (флаг сам вернётся)
            player:LoadCharacter()
        -- конец проверки
        end
    -- конец перебора
    end
-- конец функции
end

-- обратный отсчёт
local function Countdown(seconds)
    -- от seconds до 0
    for t = seconds, 0, -1 do
        -- игроки видят время
        timeLeft.Value = t
        -- секунда
        task.wait(1)
    -- конец цикла
    end
-- конец функции
end

-- какая команда принесла больше флагов
local function Winner()
    -- лучшая, её счёт, ничья ли
    local bestTeam, bestScore, draw = nil, -1, false
    -- каждая команда
    for _, team in ipairs(Teams:GetTeams()) do
        -- сумма флагов
        local score = 0
        -- игроки команды
        for _, player in ipairs(team:GetPlayers()) do
            -- таблица
            local stats = player:FindFirstChild("leaderstats")
            -- прибавляем
            if stats then score += stats.Flags.Value end
        -- конец перебора
        end
        -- больше всех
        if score > bestScore then
            -- новый лидер
            bestTeam, bestScore, draw = team, score, false
        -- столько же
        elseif score == bestScore then
            -- ничья
            draw = true
        -- конец проверки
        end
    -- конец перебора
    end
    -- белым
    if not bestTeam or draw then return "Ничья!", Color3.new(1, 1, 1) end
    -- цветом команды
    return "Победили " .. bestTeam.Name .. "! Флагов: " .. bestScore, bestTeam.TeamColor.Color
-- конец функции
end

-- раунды по кругу
while true do
    -- лобби
    lobby.Value = true
    -- все в лобби
    SendAll(workspace.LobbySpawn)
    -- ждём
    Countdown(LOBBY_TIME)
    -- игра
    lobby.Value = false
    -- обнуляем счёт
    for _, player in ipairs(Players:GetPlayers()) do
        -- таблица
        local stats = player:FindFirstChild("leaderstats")
        -- с нуля
        if stats then stats.Flags.Value = 0 end
    -- конец перебора
    end
    -- все на поле
    SendAll(workspace.GameSpawn)
    -- играем
    Countdown(GAME_TIME)
    -- показываем победителя всем
    winEvent:FireAllClients(Winner())
    -- пока читают
    task.wait(5)
-- конец цикла
end

WinLocal

Где: StarterGui → WinnerGui · LocalScript
Зачем: Надпись о победе.

-- общее хранилище
local RS = game:GetService("ReplicatedStorage")
-- событие победы
local winEvent = RS:WaitForChild("WinEvent")
-- WinnerGui
local gui = script.Parent
-- надпись
local label = gui:WaitForChild("WinLabel")
-- сколько секунд показывать
local SHOW_TIME = 5

-- сервер объявил победителя
winEvent.OnClientEvent:Connect(function(text, color)
    -- текст
    label.Text = text
    -- цвет команды
    label.TextColor3 = color
    -- показываем
    gui.Enabled = true
    -- ждём
    task.wait(SHOW_TIME)
    -- прячем
    gui.Enabled = false
-- конец функции
end)

Проверка

Запусти Play (или Run) и убедись: