Sạch và Đặt lại

*Nội dung này được dịch bằng AI (Beta) và có thể có lỗi. Để xem trang này bằng tiếng Anh, hãy nhấp vào đây.

Thời gian để lập trình giai đoạn cuối của trò chơi: làm sạch và thiết lập lại. Mã trong giai đoạn này đảm bảo rằng trò chơi lặp lại cho tiết lập và rằng các trận đấu tương lai bắt đầu giống cho mỗi người chơi.

Cập nhật GUI

Trước khi làm sạch và đặt lại, cung cấp cho người chơi biết game đã kết thúc bằng cách sử dụng DisplayManager để hiển thị trạng thái phù hợp.

Lấy tên người chiến thắng

Bắt đầu bằng cách nhận tên người chơi chiến thắng nếu có một. Trước đó, mã kiểm tra xem kích thước bảng tên người chơi đang tạo đã giảm xuống 1. Để lấy tên người chơi còn lại, hãy trả lại tên ở mục đầu tiên của bảng tên đó.

  1. Trong PlayerManager, bắt đầu một chức năng mới tên là getWinnerName() .


    function PlayerManager.getWinnerName()
    end
    -- Sự kiện
    Players.PlayerAdded:Connect(onPlayerJoin)
  2. Thêm một if statement that runs if something exists in activePlayers[1] . Mặc dù số lượng bảng đã được kiểm tra trước đó, người chơi có thể đã kết nối hoặc rời khỏi trò chơi.


    function PlayerManager.getWinnerName()
    local winningPlayer = activePlayers[1]
    if winningPlayer then
    end
    end
  3. Trong câu if:

    • Trả tên người chơi.
    • Đối với những người khác, trả lại một dòng chuỗi.

    function PlayerManager.getWinnerName()
    local winningPlayer = activePlayers[1]
    if winningPlayer then
    return winningPlayer.Name
    else
    return "Error: No winning player found"
    end
    end

Nhận được tình trạng cuối cùng

Sử dụng một hàm chức năng của module để lấy thông tin từ trạng thái đầu cuối đúng, dù thời gian timer kết thúc hay một người chơi bị rời đi. Sau đó, gửi biến trạng thái đó cho DisplayManager để cập nhật GUI trạng thái với thông tin nhắnphù hợp.

  1. Trong MatchManager , mã một chức năng mới tên là getEndStatus() với một biến tên là endState . Để lưu thông điệp sẽ được gửi, hãy thêm một biến trống tên là 1> statusToReturn1> .


    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
    function MatchManager.getEndStatus(endState)
    local statusToReturn
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Đặt giá trị của statusToReturn bằng cách sử dụng if và if else. Kiểm tra các biến trạng thái cuối cùng: FoundWinnerTimerUp . Để kiểm tra lỗi, bao gồm một else ở kết thúc.


    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    elseif endState == gameSettings.endStates.TimerUp then
    else
    end
    end
  3. Thêm các điều kiện sau cho mỗi điều kiện:

    FoundWinner

    • Một biến cho người chiến thắng bằng cách sử dụng playerManager.getWinnerName() .
    • Cập nhật statusToReturn với một chuỗi tuyên bố người chiến thắng.

    TimerUp

    • Cập nhật statusToReturn với một chuỗi tuyên bố thời gian hết hạn.

    Else

    • Cập nhật statusToReturn với một thông báo lỗi trong trường hợp có vấn đề về việc lấy thông tin nhắnvề trò chơi cuối cùng.

    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    local winnerName = playerManager.getWinnerName()
    statusToReturn = "Winner is : " .. winnerName
    elseif endState == gameSettings.endStates.TimerUp then
    statusToReturn = "Time ran out!"
    else
    statusToReturn = "Error found"
    end
    end
  4. Gửi lại tin nhắn bằng cách nhập return statusToReturn .


    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    local winnerName = playerManager.getWinnerName()
    statusToReturn = "Winner is : " .. winnerName
    elseif endState == gameSettings.endStates.TimerUp then
    statusToReturn = "Time ran out!"
    else
    statusToReturn = "Error found"
    end
    return statusToReturn
    end

Hiển thị và Thử nghiệm

Nhận thông báo cập nhật trong GameManager và hiển thị nó cho người chơi bằng cách sử dụng DisplayManager.

  1. Mở GameManager . Trong khi true do loop, xóa last print statement. Sau đó, tạo một biến tên là endStatus. Đặt nó bằng cách gọi matchManager.getEndStatus(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()
    local endStatus = matchManager.getEndStatus(endState)
    end
  2. Để hiển thị tin nhắn đã được hiển thị trong GUI label, call displayManager.updateStatus() và pass in endStatus .


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
  3. Vì vậy, trò chơi tạm dừng để cho phép người chơi xem thông tin nhắn, thêm thời gian chờ bằng cách sử dụng transitionTime .


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    task.wait(gameSettings.transitionTime)
  4. Bắt đầu một máy chủ thử nghiệm và kiểm tra người chơi có thấy các thông điệp sau đây cho thời gian và điều kiện người chiến thắng.

    Điều kiện hết thời gian
    Điều kiện người chơi chiến thắng

Mẹo dịch vụ

Tại thời điểm này, bạn không thể xem các thông báo, hãy thử một trong những lựa chọn dưới đây.

  • Nếu thông điệp cuối cùng của bạn là "Error Found", không có điều kiện nào thành công. Xem mã trong MatchManager.getEndStatus() chống lại mẫu mã.
  • Nếu trạng thái cuối cùng không hiển thị, kiểm tra rằng task.wait(gameSettings.transitionTime) đã được gửi sau khi gửi thông báo đến điều khiển.

Bắt đầu các trận đấu mới

Trước khi bắt đầu một tương thíchmới, sẽ có một giai đoạn chuyển tiếp ngắn. Điều này cho phép người chơi thời gian để xem trạng thái cuối cùng và làm cho việc được dịch chuyển đến sảnh khách sạn cảm thấy mượt hơn.

Vào cuối mùa bóng chuyển đổi, các người chơi còn lại sẽ bị loại bỏ khỏi đấu trường, và tất cả mã sẽ được đặt lại. Điều này đảm bảo rằng người chơi sẽ bắt đầu trận đấu tiếp theo với một phiên bản sạch của trò chơi.

Xử lý các chuyển động

Khi người chơi chuyển sang giai đoạn chuyển tiếp, hãy xóa vũ khí của họ.

  1. Ở PlayerManager, tìm các chức năng địa phương. Sao chép và dán mã được xác định cho removePlayerWeapon() dưới đây. Mã sẽ loại bỏ vũ khí của một người chơi nếu nó đang hoạt động hoặc trong trang phục người chơi.


    local function removePlayerWeapon(whichPlayer)
    -- Kiểm tra để xem apakah một người chơi tồn tại trong trường hợp họ bị mất kết nối hoặc rời đi.
    if whichPlayer then
    local character = whichPlayer.Character
    -- Nếu người chơi hiện đang có nó trên nhân vật của họ
    local weapon = character:FindFirstChild("Weapon")
    if weapon then
    weapon:Destroy()
    end
    -- Nếu người chơi có vũ khí trong kho trang bị của họ
    local backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")
    if backpackWeapon then
    backpackWeapon:Destroy()
    end
    else
    print("No player to remove weapon")
    end
    end
  2. Bắt đầu một chức năng mới có tên là removeAllWeapons() .


    function PlayerManager.removeAllWeapons()
    end
    -- Sự kiện
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  3. Trong chức năng đó, hãy sử dụng for loop để đi qua bảng người chơi đang chạy. Trong chức năng, gọi removePlayerWeapon() và truyền trong người chơi được tìm thấy.


    function PlayerManager.removeAllWeapons()
    for playerKey, whichPlayer in activePlayers do
    removePlayerWeapon(whichPlayer)
    end
    end

Làm sạch giữa các trận đấu

Sạch sẽ sẽ là chức năng của riêng nó trong MatchManager. Hiện tại, sạch sẽ chỉ sử dụng chức năng đã tạo trước đó để xóa vũ khí của người chơi. Khi bạn mở rộng trò chơi, nhiều hơn có thể được thêm, chẳng hạn như các chức năng để thiết lập lại một bản đồ mà đã thay đổi trong mộ

  1. Mở MatchManager. Thêm một chức năng mới tên là cleanupMatch() . Trong chức năng đó, gọi playerManager.removeAllWeapons() .


    function MatchManager.cleanupMatch()
    playerManager.removeAllWeapons()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Tiếp theo, gọi chức năng dọn dẹp. Mở GameManager và tìm kiếm trong khi thực hiện true do loop. Vì vậy, người chơi có vũ khí được loại bỏ trong giờ giải laoim kết thúc, gọi matchManager.cleanupMatch() trước khi người cuối cùng task.wait() .


    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()
    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    matchManager.cleanupMatch()
    task.wait(gameSettings.transitionTime)
    end
  3. Bắt đầu một máy chủ thử nghiệm và chạy một tương thích. Đợi cho thời gian thử nghiệm hết và xác nhận rằng vũ khí của người chơi đã được loại bỏ trong giờ nhiệm vụ cuối cùng.

    Trong một trận đấu
    Sau trận đấu

Đang đặt lại trận đấu

Bạn có thể đã nhận thấy một vài điều khác trong trò chơi, chẳng hạn như người chơi vẫn đang ở trong đấu trường sau khi một trận đấu kết thúc. Với trận đấu được làm sạch, tiếp theo thiết lập lại trò chơi. Điều này bao gồm gửi người ch

Đầu tiên, bắt đầu một hàm để gửi người chơi trở về sảnh.

  1. Trong PlayerManager:

    • Tạo một chức năng module có tên là resetPlayers() .
    • Thêm một for lặp để lặp qua các người chơi đang chơi.
    • Trong vòng lặp, gọi respawnPlayerInLobby() và truyền người chơi như một tham số.

    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    end
    -- Sự kiện
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  2. Đảm bạo bảng activePlayers được rỗi cho trận đấu tiếp theo bằng cách đặt nó bằng cách = >, là một cách nhanh chóng để đặt lại bảng trống.


    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    activePlayers = {}
    end
  3. Mở MatchManager. Code một chức năng mới tên là resetMatch() và gọi playerManager.resetPlayers() .


    function MatchManager.resetMatch()
    playerManager.resetPlayers()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  4. Quay lại đến GameManager . Khi kết thúc thời gian thực hiện true do loop, gọi matchManager.resetMatch() .


    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()
    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    matchManager.cleanupMatch()
    task.wait(gameSettings.transitionTime)
    matchManager.resetMatch()
    end
  5. Bắt đầu một máy chủ thử nghiệm và chạy một tương thích. Xác nhận rằng bạn ít nhất có thể đi qua hai vòng trò chơi mà không có lỗi.

Các Kịch Bản Đã Hoàn Thành

Dưới đây là các script đã hoàn thành để kiểm tra lại công việc của bạn.

Script GameManager


-- Dịch Vụ
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Script Mô-đun
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Sự kiện
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()
local endStatus = matchManager.getEndStatus(endState)
displayManager.updateStatus(endStatus)
matchManager.cleanupMatch()
task.wait(gameSettings.transitionTime)
matchManager.resetMatch()
end

Tập lệnh MatchManager


local MatchManager = {}
-- Dịch Vụ
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Script Mô-đun
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"))
-- Sự kiện
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Giá trị
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Tạo một thời gian mới để được sử dụng để theo dõi thời gian trận đấu.
local myTimer = timer.new()
-- Hàm chức năng địa phương
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
-- Thêm +1 đảm bảo hiển thị thời gian cuối cùng ở 1 thay vì 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Bằng cách không thiết lập thời gian chờ, nó cung cấp lặp lại chính xác hơn
task.wait()
end
end
-- Hàm chức năng
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

Tập lệnh PlayerManager


local PlayerManager = {}
-- Dịch Vụ
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Các mô-đun
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Sự kiện
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Biến map
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Giá trị
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Biến cố người chơi
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()
-- Đưa người chơi một công cụ
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)
-- Kiểm tra để xem apakah một người chơi tồn tại trong trường hợp họ bị mất kết nối hoặc rời đi.
if whichPlayer then
local character = whichPlayer.Character
-- Nếu người chơi hiện đang có nó trên nhân vật của họ
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- Nếu người chơi có vũ khí trong kho trang bị của họ
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)
-- Nhận một vị trí đẻ trứng và sau đó loại bỏ nó khỏi bảng để người chơi tiếp theo nhận trứng
local spawnLocation = 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
-- Sự kiện
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager