Saatnya untuk menulis fase terakhir dari permainan: membersihkan dan resetulang. Kode dalam fase ini menjamin bahwa gameLoop untuk istirahat dan bahwa pertandingan masa depan dimulai sama untuk setiap pemain.
Memperbarui GUI
Sebelum membersihkan dan resetulang, beritahu pemain bagaimana permainan berakhir menggunakan DisplayManager untuk menunjukkan status yang sesuai.
Mendapatkan Nama Pemenang
Mulai dengan mendapatkan nama pemain yang menang jika ada. Sebelumnya, kode memeriksa apakah ukuran tabel pemain aktif turun ke 1. Untuk mendapatkan nama pemain tersisa, kembalikan nama di indeks pertama tabel itu.
Pada PlayerManager, mulai modul baru bernama getWinnerName() .
function PlayerManager.getWinnerName()end-- AcaraPlayers.PlayerAdded:Connect(onPlayerJoin)Tambahkan if statement yang berlari jika sesuatu ada di activePlayers[1] . Meskipun jumlah tabel diperiksa sebelumnya, pemain mungkin telah terputus atau meninggalkan game.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenendendDalam pernyataan if:
- Kembalikan nama pemain.
- Untuk yang lain, kembalikan string kesalahan.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
Mendapatkan Status Akhir
Gunakan fungsi modul untuk mengambil informasi dari tahap akhir yang benar, apakah timer berakhir atau salah satu pemain tersisa. Kemudian, kirim variabel status tersebut ke DisplayManager untuk menyelesaikan status GUI dengan pesan yang sesuai.
Dalam MatchManager , kode fungsi modul baru bernama getEndStatus() dengan parameter bernama endState. Untuk menyimpan pesan yang akan dikirim, tambahkan variabel kosong bernama 1> statusToReturn1> .
function MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()endfunction MatchManager.getEndStatus(endState)local statusToReturnendmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerTetapkan nilai dari statusToReturn menggunakan pernyataan if dan elif. Periksa variabel status akhir: FoundWinner dan TimerUp. Untuk memeriksa kesalahan, termasuk satu lain di akhiri.
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenelseif endState == gameSettings.endStates.TimerUp thenelseendendTambahkan berikut untuk setiap kondisi:
FoundWinner
- Variabel untuk pemenang menggunakan playerManager.getWinnerName() .
- Update statusToReturn dengan string mengumumkan pemenang.
TimerUp
- Update statusToReturn dengan string mengumumkan waktu berakhir.
Else
- Update statusToReturn dengan pesan kesalahan jika ada masalah mendapatkan pesan akhir.
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"endendKirim kembali pesan dengan mengetik 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
Menampilkan dan Menguji
Dapatkan pengumuman yang diperbarui di GameManager dan tampilkan kepada para pemain menggunakan DisplayManager.
Buka GameManager . Saat benar-benar berulang, hapus pernyataan cetak terakhir. Kemudian, buat variabel bernama endStatus. Tetapkan sama dengan memanggil 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)endUntuk menampilkan pesan yang dikembalikan dalam label GUI, panggil displayManager.updateStatus() dan berikan dalam endStatus .
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)Jadi permainan berhenti untuk membiarkan pemain melihat pesan, tambahkan waktu tunggu menggunakan transitionTime .
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)task.wait(gameSettings.transitionTime)Mulai server pengujian dan periksa bahwa pemain melihat pesan berikut untuk waktu dan kondisi pemain yang menang.
Tips Troubleshoot
Pada titik ini, Anda tidak dapat melihat pesan, coba salah satu dari berikut.
- Jika pesan status akhir Anda adalah "Error Found", tidak satupun dari kondisi tersebut berhasil. Periksa kode di MatchManager.getEndStatus() melawan sampel kode.
- Jika status akhir tidak ditampilkan, periksa bahwa task.wait(gameSettings.transitionTime) adalah setelah mengirim pesan ke显示Manager.
Memulai Pertandingan Baru
Sebelum memulai mencocokkanbaru, akan ada periode transisi singkat. Ini memberi pemain waktu untuk melihat status akhir dan membuat diri di teleport ke lobi merasa kurang tiba-tiba.
Pada akhir transisi, pemain yang tersisa akan dihapus dari arena, dan semua kode akan reset. Ini memastikan bahwa pemain akan memulai pertandingan berikutnya dengan versi bersih dari game.
Penanganan Transisi
Ketika pemain pindah ke status transisi, hapus senjata mereka.
Di PlayerManager, temukan fungsi lokal. Salinan dan pastikan kode yang ditunjukkan di bawah ini. Kode akan menghapus senjata pemain individu jika itu aktif atau di ransel pemain.
local function removePlayerWeapon(whichPlayer)-- Periksa apakah pemain ada dalam kasus mereka terputus atau pergi.if whichPlayer thenlocal character = whichPlayer.Character-- Jika pemain memilikinya saat ini di karakter merekalocal weapon = character:FindFirstChild("Weapon")if weapon thenweapon:Destroy()end-- Jika pemain memiliki senjata di ransel merekalocal backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")if backpackWeapon thenbackpackWeapon:Destroy()endelseprint("No player to remove weapon")endendMulai modul baru bernama removeAllWeapons() .
function PlayerManager.removeAllWeapons()end-- AcaraPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerDalam fungsi itu, gunakan for loop untuk pergi melalui tabel pemain aktif. Dalam fungsi, panggil removePlayerWeapon() dan berikan di pemain yang ditemukan.
function PlayerManager.removeAllWeapons()for playerKey, whichPlayer in activePlayers doremovePlayerWeapon(whichPlayer)endend
Menyimpan Antara Pertandingan
Bersihkan akan menjadi fungsi sendiri di MatchManager. Untuk saat ini, bersihkan hanya akan menggunakan fungsi yang sebelumnya dibuat untuk menghapus senjata pemain. Saat Anda mengekspansi game, lebih banyak dapat ditambahkan, seperti fungsi untuk menghapus peta yang berubah selama mencocokkan.
Buka MatchManager. Tambahkan fungsi modul baru bernama cleanupMatch() . Dalam fungsi itu, panggil playerManager.removeAllWeapons() .
function MatchManager.cleanupMatch()playerManager.removeAllWeapons()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerSelanjutnya, panggil fungsi pembersihan. Buka GameManager dan temukan while true do loop. Jadi pemain memiliki senjata dihapus selama intermission akhir, panggil matchManager.cleanupMatch() sebelum Last 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)endMulai server pengujian dan lakukan mencocokkan. Tunggu sampai waktu habis dan konfirmasi bahwa senjata pemain dihapus selama istirahat pertandingan akhir.
Mengatur Ulang Pertandingan
Anda mungkin pernah melihat beberapa hal lain dalam game, seperti pemain masih berada di arena setelah pertandingan berakhir. Dengan membersihkan pertandingan, setel ulang game. Ini termasuk mengirim pemain ke arena kembali ke lobi dan menghapus tabel pemain aktif. Dengan setel ulang dalam tempat, setel ulang permainan dapat berlangsung secara permanen.
Pertama, mulai fungsi untuk mengirim pemain kembali ke lobi.
Di PlayerManager:
- Buat fungsi modul bernama resetPlayers() .
- Tambahkan for loop untuk beriterasi melalui aktifPlayers.
- Dalam loop, panggil respawnPlayerInLobby() dan pas dalam pemain sebagai parameter.
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endend-- AcaraPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerPastikan tabel activePlayers kosong untuk pertandingan berikutnya dengan menetapkannya sama dengan {}, yang merupakan cara cepat untuk mengatur ulang ke tabel yang kosong.
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endBuka MatchManager. Kode fungsi modul baru bernama resetMatch() dan panggil playerManager.resetPlayers().
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerKembali ke GameManager . Pada akhir waktu sementara benar do loop, panggil 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()endMulai server pengujian dan lakukan mencocokkan. Konfirmasi bahwa Anda setidaknya dapat pergi melalui dua game loop tanpa kesalahan.
Skrip yang Diselesaikan
Di bawah ini adalah script yang selesai untuk memeriksa kembali pekerjaan Anda.
Skrip GameManager
-- Layananlocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Skrip Modullocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- Acaralocal 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
Skrip MatchManager
local MatchManager = {}
-- Layanan
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Skrip Modul
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"))
-- Acara
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Nilai
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Membuat objek timer baru untuk digunakan untuk melacak waktu pertandingan.
local myTimer = timer.new()
-- Fungsi Lokal
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
-- Menambahkan +1 memastikan tampilan timer berakhir pada 1 bukan 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Dengan tidak menetapkan waktu tunggu, itu menawarkan lebih banyak looping yang akurat
task.wait()
end
end
-- Fungsi Modul
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
Skrip Manajer Pemain
local PlayerManager = {}
-- Layanan
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Modul
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Acara
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Variabel Peta
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Nilai
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Variabel Pemain
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()
-- Berikan alat pemain
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)
-- Periksa apakah pemain ada dalam kasus mereka terputus atau pergi.
if whichPlayer then
local character = whichPlayer.Character
-- Jika pemain memilikinya saat ini di karakter mereka
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- Jika pemain memiliki senjata di ransel mereka
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)
-- Mendapatkan lokasi bertelur dan kemudian menghapusnya dari tabel sehingga pemain berikutnya mendapatkan spawn berikutnya
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
-- Acara
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager