Thời gian để mã hóa giai đoạn cuối cùng của trò chơi: dọn dẹp và đặt lại.Mã trong giai đoạn này đảm bảo rằng vòng lặp trò chơi bị gián đoạn và các trận đấu trong tương lai bắt đầu giống nhau cho mỗi người chơi.
Cập nhật GUI
Trước khi làm sạch và đặt lại, thông báo cho người chơi cách trò chơi kết thúc bằng cách sử dụng DisplayManager để hiển thị trạng thái thích hợp.
Nhận tên của người chiến thắng
Bắt đầu bằng cách lấy tên của người chơi chiến thắng nếu có một.Trước đây, mã kiểm tra xem kích thước bảng người chơi hoạt động đã giảm xuống 1.Để lấy tên của người chơi còn lại, trả lại tên tại chỉ mục đầu tiên của bảng đó.
Trong PlayerManager, bắt đầu chức năng mô-đun mới có tên là getWinnerName().
function PlayerManager.getWinnerName()end-- Sự kiệnPlayers.PlayerAdded:Connect(onPlayerJoin)Thêm một câu lệnh if chạy nếu có thứ gì đó tồn tại trong activePlayers[1] .Mặc dù số lượng bảng đã được kiểm tra trước, người chơi có thể đã mất kết nối hoặc rời khỏi trò chơi.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenendendTrong tuyên bố if:
- Trả lại tên của người chơi.
- Đối với phần còn lại, trả về một chuỗi lỗi.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
Nhận tình trạng cuối cùng
Sử dụng chức năng mô-đun để lấy thông tin từ trạng thái cuối cùng chính xác, cho dù hết giờ hoặc một người chơi bị rời khỏi.Sau đó, gửi biến trạng thái đó đến DisplayManager để cập nhật trạng thái GUI với tin nhắn thích hợp.
Trong MatchManager , mã một chức năng mô-đun mới có tên là getEndStatus() với một tham số có tên là endState .Để lưu tin nhắn sẽ được gửi, thêm một biến trống có tên là statusToReturn .
function MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()endfunction MatchManager.getEndStatus(endState)local statusToReturnendmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerĐặt giá trị của statusToReturn bằng cách sử dụng if và elseif tuyên bố.Kiểm tra các biến trạng thái cuối cùng: FoundWinner và TimerUp.Đối với kiểm tra lỗi, bao gồm một cái khác ở cuối.
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenelseif endState == gameSettings.endStates.TimerUp thenelseendendThê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 sử dụng playerManager.getWinnerName() .
- Cập nhật statusToReturn với một chuỗi thông báo người chiến thắng.
TimerUp
- Cập nhật statusToReturn với một chuỗi thông báo 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ới việc nhận được tin nhắn trò chơi cuối cùng.
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenlocal winnerName = playerManager.getWinnerName()statusToReturn = "Winner is : " .. winnerNameelseif endState == gameSettings.endStates.TimerUp thenstatusToReturn = "Time ran out!"elsestatusToReturn = "Error found"endendGửi lại tin nhắn bằng cách gõ return statusToReturn .
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenlocal winnerName = playerManager.getWinnerName()statusToReturn = "Winner is : " .. winnerNameelseif endState == gameSettings.endStates.TimerUp thenstatusToReturn = "Time ran out!"elsestatusToReturn = "Error found"endreturn statusToReturnend
Hiển thị và kiểm tra
Nhận thông báo được cập nhật trong GameManager và hiển thị nó cho người chơi bằng cách sử dụng DisplayManager.
Mở Quản lý trò chơi .Trong vòng lặp while true, xóa tuyên bố in cuối cùng.Sau đó, tạo một biến có tên là endStatus.Đặt nó bằng với việc gọi matchManager.getEndStatus(endState) .
while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.updateStatus("Get ready!")task.wait(gameSettings.transitionTime)matchManager.prepareGame()local endState = matchEnd.Event:Wait()local endStatus = matchManager.getEndStatus(endState)endĐể hiển thị tin nhắn trả về trong nhãn GUI, hãy gọi displayManager.updateStatus() và truyền endStatus .
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)Vì vậy, trò chơi tạm dừng để cho người chơi xem tin nhắn, thêm một chờ đợi bằng cách sử dụng transitionTime .
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)task.wait(gameSettings.transitionTime)Bắt đầu một máy chủ thử nghiệm và kiểm tra xem người chơi có nhìn thấy các tin nhắn sau cho thời gian lên và điều kiện người chơi thắng hay không .
Điều kiện hết thời gian Điều kiện người chơi thắng
Mẹo khắc phục sự cố
Tại thời điểm này, bạn không thể xem các tin nhắn, hãy thử một trong những điều sau.
- Nếu tin nhắn tình trạng cuối của bạn là "Lỗi được tìm thấy", không có điều kiện nào thành công. Kiểm tra mã trong MatchManager.getEndStatus() chống lại các mẫu mã.
- Nếu tình trạng cuối không hiển thị, hãy kiểm tra xem task.wait(gameSettings.transitionTime) có được sau khi gửi tin nhắn đến displayManager hay không.
Bắt đầu các trận mới
Trước khi bắt đầu một trận đấu mới, sẽ có một sự chuyển tiếp ngắn.Điều này cho người chơi thời gian để xem tình trạng cuối cùng và làm cho việc dịch chuyển đến sảnh cảm thấy ít bất ngờ hơn.
Tại cuối giai đoạn chuyển tiếp, những người chơi còn lại sẽ bị loại bỏ khỏi sân đấu, 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 tiếp theo với phiên bản sạch của trò chơi.
Xử lý chuyển tiếp
Khi người chơi chuyển sang trạng thái chuyển tiếp, hãy loại bỏ vũ khí của họ.
Trong PlayerManager, tìm các chức năng địa phương.Sao chép và dán mã nổi bật cho removePlayerWeapon() bên dưới.Mã sẽ xóa vũ khí của một cá nhân nếu nó được trang bị hoạt động hoặc trong ba lô của người chơi.
local function removePlayerWeapon(whichPlayer)-- Kiểm tra xem có người chơi tồn tại trong trường hợp họ bị tách kết nối hoặc rời không.if whichPlayer thenlocal 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 thenweapon:Destroy()end-- Nếu người chơi có vũ khí trong ba lô của họlocal backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")if backpackWeapon thenbackpackWeapon:Destroy()endelseprint("No player to remove weapon")endendBắt đầu chức năng mô-đun mới có tên là removeAllWeapons().
function PlayerManager.removeAllWeapons()end-- Sự kiệnPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerTrong chức năng đó, sử dụng một vòng lặp để đi qua bảng người chơi hoạt động. Trong vòng lặp, gọi removePlayerWeapon() và chuyền người chơi được tìm thấy.
function PlayerManager.removeAllWeapons()for playerKey, whichPlayer in activePlayers doremovePlayerWeapon(whichPlayer)endend
Làm sạch giữa các trận đấu
Làm sạch sẽ là chức năng riêng của nó trong MatchManager.Bây giờ, dọn dẹp sẽ chỉ sử dụng chức năng đã tạo trước đó để loại bỏ vũ khí của người chơi.Khi bạn mở rộng trò chơi, có thể thêm nhiều hơn, chẳng hạn như chức năng để xóa bỏ bản đồ đã thay đổi trong trận đấu.
Mở MatchManager. Thêm chức năng mô-đun mới có tên là cleanupMatch(). Trong chức năng đó, gọi playerManager.removeAllWeapons().
function MatchManager.cleanupMatch()playerManager.removeAllWeapons()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerTiếp theo, gọi chức năng dọn dẹp.Mở Quản lý trò chơi và tìm vòng lặp while true.Vì vậy, người chơi có vũ khí bị xóa trong khoảng thời gian kết thúc, gọi matchManager.cleanupMatch() trước khi task.wait() cuối cùng.
while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.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)endBắt đầu một máy chủ thử nghiệm và chạy một trận đấu. Chờ cho hết thời gian và xác nhận rằng vũ khí của người chơi đã bị xóa trong khoảng thời gian gián đoạn trò chơi cuối cùng.
Trong một trận đấu Sau trận đấu
Xóa trận phù hợp
Bạn có thể đã nhận thấy một vài điều khác trong trò chơi, như người chơi vẫn còn ở sân sau khi trận đấu kết thúc.Với trận đấu được dọn sạch, tiếp theo hãy xóa lại trò chơi.Điều này bao gồm gửi người chơi trong đấu trường trở lại sảnh và xóa bảng người chơi hoạt động.Với một lần khởi tạo lại, một vòng lặp trò chơi có thể chạy vô cực.
Trước tiên, bắt đầu một chức năng để gửi người chơi trở lại sảnh.
Trong PlayerManager:
- Tạo một chức năng module có tên là resetPlayers().
- Thêm một vòng lặp for để lặp qua các người chơi chủ động.
- Trong vòng lặp, gọi respawnPlayerInLobby() và chuyền người chơi là tham số.
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endend-- Sự kiệnPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerHãy chắc chắn rằng bảng activePlayers trống cho trận đấu tiếp theo bằng cách đặt nó bằng với {}, đây là một cách nhanh chóng để đặt lại sang một bảng trống.
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endMở MatchManager. Mã một chức năng mô-đun mới có tên resetMatch() và gọi playerManager.resetPlayers() .
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerQuay lại GameManager . Ở cuối vòng lặp while true, gọi matchManager.resetMatch() .
while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.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()endBắt đầu một máy chủ thử nghiệm và chạy một trận đấu. Xác nhận rằng bạn có thể ít nhất đi qua hai vòng lặp trò chơi mà không có lỗi.
Hoàn thành các kịch bản
Dưới đây là các kịch bản hoàn thành để kiểm tra lại công việc của bạn.
Tập lệnh GameManager
-- Dịch vụlocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Tập lệnh mô-đunlocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- Sự kiệnlocal events = ServerStorage:WaitForChild("Events")local matchEnd = events:WaitForChild("MatchEnd")while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.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")
-- Tập lệnh 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 đối tượng hẹn giờ mới để được sử dụng để theo dõi thời gian trận đấu.
local myTimer = timer.new()
-- 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 kết thúc tại 1 thay vì 0.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- Bằng cách không đặt thời gian chờ đợi, nó cung cấp lặp lại chính xác hơn
task.wait()
end
end
-- Chức năng mô-đun
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")
-- 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 bản đồ
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 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()
-- Cung cấp công cụ cho người chơi
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 có người chơi tồn tại trong trường hợp họ bị tách kết nối hoặc rời không.
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 ba lô 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 được vị trí spawn và sau đó xóa nó khỏi bảng để người chơi tiếp theo có được spawn tiếp theo
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