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 đó.
Trong PlayerManager, bắt đầu một chức năng mới tên là getWinnerName() .
function PlayerManager.getWinnerName()end-- Sự kiệnPlayers.PlayerAdded:Connect(onPlayerJoin)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 thenendendTrong 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 thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
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.
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()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à if else. Kiểm tra các biến trạng thái cuối cùng: FoundWinner và TimerUp . Để kiểm tra lỗi, bao gồm một else ở kết thúc.
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 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 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 nhập 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à 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.
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 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 đã được hiển thị trong GUI label, call displayManager.updateStatus() và pass in endStatus .
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)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)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.
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ọ.
Ở 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 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 kho trang bị của họlocal backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")if backpackWeapon thenbackpackWeapon:Destroy()endelseprint("No player to remove weapon")endendBắt đầu một chức năng mới có tên là removeAllWeapons() .
function PlayerManager.removeAllWeapons()end-- Sự kiệnPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerTrong 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 doremovePlayerWeapon(whichPlayer)endend
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ộ
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()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerTiế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 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 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.
Đ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.
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 dorespawnPlayerInLobby(whichPlayer)endend-- Sự kiệnPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerĐả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 dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endMở MatchManager. Code một chức năng mới tên là resetMatch() và gọi playerManager.resetPlayers() .
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerQuay 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 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 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ô-đ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")
-- 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