Các trận đấu có thể kết thúc trong một vài điều kiện bao gồm thời gian chạy trống hoặc một người chơi đơn đã bị rời đi.
Quản lý người chơi đã thắng
Ngay bây giờ, những người chơi đã đánh bại được tái sinh trong đấu trường. Thay vào đó, gửi họ trở về sảnh đợi để chờ cho trận tương thíchtiếp theo.
- Trong PlayerManager, tạo một chức năng địa phương có tên là respawnPlayerInLobby() . Trong chức năng đó, thực hiện những gì sau theo dõi:
- Đặt giá trị RespawnLocation của người chơi vào lobbySpawn.
- Làm mới nhân vật với Player:LoadCharacter() . Hãy nhớ rằng, LoadCharacter() tái tạo người chơi ở vị trí người chơi, bỏ qua bất kỳ công cụ nào mà họ có.
Sử dụng các chức năng tàng hình
Các chức năng tàng hình thường được sử dụng trong các tập lệnh nâng cao dưới các tình huống cụ thể. Trước khi định nghĩa chúng, làm hiểu một tình huống mà script của bạn có thể gặp phải là quan trọng.
Hãy xem xét điều này: Để dịch chuyển người chơi đã đánh bại đến sảnh, hành động respawn sẽ phải kết nối với sự kiện Died của người chơi. Có một vấn đề nhưng. Nếu bạn kết nối sự kiện như chúng tôi đã có trong quá khứ
Để nhận tên người chơi mà đã kích hoạt sự kiện Died, hãy sử dụng một hàm chức năng an toàn. Hàm chức năng an toàn không có tên, và có thể được tạo ra trực tiếp trong Connect() thay vì riêng biệt.
Một hàm chức năng an toàn là dưới đó cho thấy cấu trúc.
myPlayer.Died:Connect(function()
print(player)
end)
Lập trình sự kiện đã chết
Đối với chức năng này, mỗi khi nhân vật của một người chơi chết, họ sẽ kích hoạt chức năng tái sinh họ.
Để có được quyền truy cập sự kiện Died của người chơi, trong PlayerManager > preparePlayer() , thêm một biến đổi cho người chơi's hình người.
local function preparePlayer(player, whichSpawn)player.RespawnLocation = whichSpawnplayer:LoadCharacter()local character = player.Character or player.CharacterAdded:Wait()local sword = playerWeapon:Clone()sword.Parent = characterlocal humanoid = character:WaitForChild("Humanoid")endTạo một chức năng anonim mà kết nối với sự kiện Died. Bắt đầu bằng cách nhập humanoid.Died:Connect() . Sau đó, bên trong Connect() , nhập 1> function1> và nhấn 4> Enter4> để hoàn
local humanoid = character:WaitForChild("Humanoid")humanoid.Died:Connect(function()end)Trong chức năng tàng hình, gọi respawnPlayerInLobby() . Điều chuyển player , một biến đổi lưu trữ người chơi đang chuẩn bị tham gia vào một tương thích.
local humanoid = character:WaitForChild("Humanoid")humanoid.Died:Connect(function()respawnPlayerInLobby(player)end)Bắt đầu một máy chủ và chơi một tương thích. Thử nghiệm rằng khi một người chơi chết, họ sẽ xuất hiện lại trong sảnh. Để đánh bại người chơi, hãy đi lên chúng và sử dụng vũ khí của bạn cho đến khi bạn có thể xác nhận rằng họ đã xuất hiện lại trong sả
Ghi chú, đó cũng là một số cách thử nghiệm khác nếu bạn muốn.
- Để giết một người chơi, trong Server >Output Window >Command Bar, sao chép và dán: workspace.Player1.Humanoid.Health = 0 . Nhấn Enter để thi행命令. Để loại bỏ các người chơi khác, hãy sử dụng Player2, Player3, v.v.
- Đặt GameSettings > matchDuration đến một thời gian dài hơn có thể cho bạn nhiều thời gian hơn để tìm và loại bỏ tất cả người chơi.
- Để có được các bài kiểm tra nhanh hơn, thay đổi GameSettings > minimumPlayers đến một số nhỏ hơn, như 2.
Kết thúc trò chơi
Bây giờ khi đánh bại người chơi, hãy bắt đầu làm việc để kết thúc trò chơi. Nhớ tạo sự kiện Kết thúc trận đấu khi thời gian chơi xong hoặc một người chiến thắng được tìm thấy.
Để nói cho các script khác biết điều kiện nào kết thúc trò chơi, hãy tạo một bảng với các biến cho TimerUp và FoundWinner . Khi sự kiện kết thúc trò chơi bắt đầu, nó sẽ được truyền qua một biến để các script khác có thể đáp lại.
Trong GameSettings, tạo một bảng mô-đun trống có tên endStates .
local GameSettings = {}-- Biến trò chơiGameSettings.intermissionDuration = 5GameSettings.matchDuration = 10GameSettings.minimumPlayers = 2GameSettings.transitionTime = 5-- Các cách có thể kết thúclại trò chơi.GameSettings.endStates = {}return GameSettingsTạo hai biến tên là TimerUp và FoundWinner . Set mỗi biến tên với một chuỗi khớp nối tên của họ. Các chuỗi này sẽ được sử dụng để kiểm tra mã.
GameSettings.endStates = {TimerUp = "TimerUp",FoundWinner = "FoundWinner"}
Kết thúc với một Timer
Khi thời gian trình tạo kết thúc, fire the Match End event and send the matching end state variable. That way, other scripts listening for that event can respond accordingly. Nhớ rằng khi các sự kiện kết thúc, các thông số trạng thái được nhận bằng cách lắng nghe các sự kiện có thể được gửi đến như TimerUp hoặc FoundWinner
Trong GameManager , trong khi true do loop, find the line matchEnd.Event:Wait() . Ở đầu dòng, add local 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()endĐể xác nhận rằng đúng trạng thái đã được nhận, hãy thêm một tuyên bố in bao gồm 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()print("Game ended with: " .. endState)endTrong MatchManager, tìm thấy timeUp() và loại bỏ lệnh in. Sau đó, để khởi động sự kiện cuối cùng của trận đấu, hãy nhập matchEnd:Fire() và nhập 1> gameSettings.endSettings.TimerUp1> .
-- 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ươnglocal function timeUp()matchEnd:Fire(gameSettings.endStates.TimerUp)endThử một tương thích. Sau khi thời gian chạy kết thúc, kiểm tra xem tuyên bố in có bao gồm chuỗi được lưu trong biến TimerUp không.
Mẹo dịch vụ
Tại thời điểm này, tin nhắn đã không được hiển thị, hãy thử một trong những lựa chọn dưới đây.
- Xem xét rằng bất kỳ khi nào biến trạng thái cuối cùng được gọi, họ được viết chính xác, như ở đây: gameSettings.endStates.TimerUp .
Mã hóa một Trận Đấu Thắng
Tiếp theo, script cần phải xác định người chiến thắng, loại bỏ người chơi thua và chạy độ tẩy như ngừng thời gian. Trận sẽ kết thúc nếu một người chơi bị lại. Để xem có phù hợp điều kiện FoundWinner không, bạn sẽ cần một hàm kiểm tra số
Kiểm tra số lượng người chơi
Các trận sẽ kết thúc nếu chỉ có một người chơi còn lại. Để kiểm tra điều này, script cần phải theo dõi các người chơi trong một trận. Sau khi một người chơi bị bỏ rơi, một người chiến thắng có thể được giao.
Trong PlayerManager, định nghĩa các biến sau đây:
- Thư mụcModuleScripts
- GameSettings module - Được sử dụng để truy cập biến trạng thái cuối cùng
- Hộp sự kiện và sự kiện Kết thúc - Sự kiện bắt lửa
local PlayerManager = {}-- Dịch Vụlocal Players = game:GetService("Players")local ServerStorage = game:GetService("ServerStorage")local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Các mô-đunlocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))-- Sự kiệnlocal events = ServerStorage:WaitForChild("Events")local matchEnd = events:WaitForChild("MatchEnd")Trên respawnPlayerInLobby() , thêm một chức năng mới tên là checkPlayerCount() .
-- Biến cố người chơilocal activePlayers = {}local playerWeapon = ServerStorage.Weaponlocal function checkPlayerCount()endlocal function respawnPlayerInLobby(player)Trong chức năng đó, sử dụng một if then statement để kiểm tra một người chiến thắng. Trong câu này:
- Kiểm tra kích thước của bảng activePlayers là 1.
- Nếu vậy, fire matchEnd and pass in gameSettings.endStates.FoundWinner .
local function checkPlayerCount()if #activePlayers == 1 thenmatchEnd:Fire(gameSettings.endStates.FoundWinner)endend
Loại bỏ một người chơi
Một đếm chính xác không thể được giữ nếu người chơi không bị loại bỏ. Khi một người chơi bị đánh bại, giữ một đếm chính xác người chơi bằng cách xóa họ khỏi bảng người chơi. Sau đó, kiểm tra kích thước bảng người chơi đang hoạt động để xem có phải là người chiến thắng hay kh
Dưới checkPlayerCount() , tạo một chức năng mới tại chỗ địa phương có tên removeActivePlayer() với một biến player .
local function checkPlayerCount()if #activePlayers == 1 thenmatchEnd:Fire(gameSettings.endStates.FoundWinner)endendlocal function removeActivePlayer(player)endĐể tìm người chơi trong bảng activePlayers, lặp lại nó bằng cách sử dụng một for lượt. Sau đó, thêm một if tuyên bố được thực hiện nếu một người chơi trùng với tên đã được thêm vào chức năng.
local function removeActivePlayer(player)for playerKey, whichPlayer in activePlayers doif whichPlayer == player thenendendendĐể loại bỏ người chơi, trong if statement:
- Gọi table.remove() . Trong dấu ngoặc, truyền activePlayers , bảng để xem, và playerKey - người chơi để xóa khỏi bảng.
- Đặt giá trị của playersLeft đối tượng lên #activePlayers .
- Kiểm tra một người chơi chiến thắng bằng cách chạy checkPlayerCount() .
local function removeActivePlayer(player)for playerKey, whichPlayer in activePlayers doif whichPlayer == player thentable.remove(activePlayers, playerKey)playersLeft.Value = #activePlayerscheckPlayerCount()endendend
Kết Nối Sự Kiện và Thử nghiệm
Để sử dụng chức năng mới tạo, hãy gọi nó từ trong các hàm chức năng anonim kết nối với sự kiện Died của người chơi.
Tìm thấy preparePlayer() . Trong chức năng anonim với kết nối sự kiện Died, gọi removeActivePlayer() . Sau đó, truyền người chơi như một biến.
humanoid.Died:Connect(function()respawnPlayerInLobby(player)removeActivePlayer(player)end)Để xem nếu một người chơi chiến thắng được tìm thấy, bắt đầu một máy chủ kiểm tra . Khi chỉ có một người chơi còn lại, bạn nên thấy FoundWinner trong cửa sổ ra kết quả.
Tiếp tục kiểm tra và để trận đấu kết thúc. Thông báo như một trận đấu mới bắt đầu, một lỗi xảy ra trong Cửa sổ Ra mắt:
Lỗi này là vì thời gian thử nghiệm đã không được dừng, sẽ được sửa chữa trong phần tiếp theo.
Ngưng đồng hồ bấm giờ
Mỗi khi một trận đấu kết thúc với một người chơi chiến thắng, thì thời gian thì cũng nên dừng lại. Để ngừng thời gian trước khi hết thời gian trận đấu, hãy thời gian ngừng khi trận đấu kết thúc để kích hoạt mối quan hệ trượt tuyết và gây ra một số hiệu ứng. Đây
Trong MatchManager, tạo một chức năng mới tên là stopTimer() . Bên trong, hãy nhập myTimer:stop() để ngừng thời gian.
-- 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ươnglocal function stopTimer()myTimer:stop()endlocal function timeUp()matchEnd:Fire(gameSettings.endStates.TimerUp)endĐể ngừng thời gian khi trận đấu kết thúc, kết nối sự kiện ngừngThờiGian đến stopTimer() .
-- Hàm chức năngfunction MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerThử nghiệm rằng lỗi trước đó không còn xuất hiện bằng cách khởi động một máy chủ . Hạ gục tất cả nhưng một người chơi và sau đó chờ đợi vài giây khi kết thúc trận đấu.
Các Bước Tiếp Theo
Khi hai điều kiện chiến thắng đã kết thúc, vẫn còn một số nhiệm vụ để hoàn thành vòng trò chơi. Ví ví dụ / trường hợp, người chơi chiến thắng không bao giờ được dịch chuyển đến sảnh. Trong bài học tiếp theo, bạn sẽ hiển thị cách trận đấu kết thúc cho người chơi và khở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.
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
-- Hàm chức năng địa phương
local function checkPlayerCount()
if #activePlayers == 1 then
matchEnd:Fire(gameSettings.endStates.FoundWinner)
end
end
local function removeActivePlayer(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 onPlayerJoin(player)
player.RespawnLocation = lobbySpawn
end
local function preparePlayer(player, whichSpawn)
player.RespawnLocation = whichSpawn
player:LoadCharacter()
local character = player.Character or player.CharacterAdded:Wait()
local sword = playerWeapon:Clone()
sword.Parent = character
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
respawnPlayerInLobby(player)
removeActivePlayer(player)
end)
end
-- Hàm chức năng
function PlayerManager.sendPlayersToMatch()
local arenaSpawns = spawnLocations:GetChildren()
for playerKey, whichPlayer in Players:GetPlayers() do
table.insert(activePlayers, whichPlayer)
local spawnLocation = table.remove(arenaSpawns, 1)
preparePlayer(whichPlayer, spawnLocation)
end
playersLeft.Value = #activePlayers
end
-- Sự kiện
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager
Script GameSettings
local GameSettings = {}-- Biến trò chơiGameSettings.intermissionDuration = 5GameSettings.matchDuration = 10GameSettings.minimumPlayers = 2GameSettings.transitionTime = 5-- Các cách có thể kết thúclại trò chơi.GameSettings.endStates = {TimerUp = "TimerUp",FoundWinner = "FoundWinner"}return GameSettings
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()print("Game ended with: " .. endState)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 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()
print("Timer started")
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
matchStart.Event:Connect(startTimer)
matchEnd.Event:Connect(stopTimer)
return MatchManager