Bersihkan dan Reset

*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.

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.

  1. Pada PlayerManager, mulai modul baru bernama getWinnerName() .


    function PlayerManager.getWinnerName()
    end
    -- Acara
    Players.PlayerAdded:Connect(onPlayerJoin)
  2. 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 then
    end
    end
  3. Dalam pernyataan if:

    • Kembalikan nama pemain.
    • Untuk yang lain, kembalikan string kesalahan.

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

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.

  1. 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()
    end
    function MatchManager.getEndStatus(endState)
    local statusToReturn
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Tetapkan 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 statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    elseif endState == gameSettings.endStates.TimerUp then
    else
    end
    end
  3. Tambahkan 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 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. Kirim kembali pesan dengan mengetik 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

Menampilkan dan Menguji

Dapatkan pengumuman yang diperbarui di GameManager dan tampilkan kepada para pemain menggunakan DisplayManager.

  1. Buka GameManager . Saat benar-benar berulang, hapus pernyataan cetak terakhir. Kemudian, buat variabel bernama endStatus. Tetapkan sama dengan memanggil 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. Untuk menampilkan pesan yang dikembalikan dalam label GUI, panggil displayManager.updateStatus() dan berikan dalam endStatus .


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
  3. 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)
  4. Mulai server pengujian dan periksa bahwa pemain melihat pesan berikut untuk waktu dan kondisi pemain yang menang.

    Kondisi waktu habis
    Kondisi pemain 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.

  1. 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 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
  2. Mulai modul baru bernama removeAllWeapons() .


    function PlayerManager.removeAllWeapons()
    end
    -- Acara
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  3. Dalam 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 do
    removePlayerWeapon(whichPlayer)
    end
    end

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.

  1. Buka MatchManager. Tambahkan fungsi modul baru bernama cleanupMatch() . Dalam fungsi itu, panggil playerManager.removeAllWeapons() .


    function MatchManager.cleanupMatch()
    playerManager.removeAllWeapons()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. Selanjutnya, 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 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. Mulai server pengujian dan lakukan mencocokkan. Tunggu sampai waktu habis dan konfirmasi bahwa senjata pemain dihapus selama istirahat pertandingan akhir.

    Selama pertandingan
    Setelah pertandingan

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.

  1. 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 do
    respawnPlayerInLobby(whichPlayer)
    end
    end
    -- Acara
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  2. Pastikan 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 do
    respawnPlayerInLobby(whichPlayer)
    end
    activePlayers = {}
    end
  3. Buka MatchManager. Kode fungsi modul baru bernama resetMatch() dan panggil playerManager.resetPlayers().


    function MatchManager.resetMatch()
    playerManager.resetPlayers()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  4. Kembali ke GameManager . Pada akhir waktu sementara benar do loop, panggil 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. Mulai 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


-- Layanan
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Skrip Modul
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Acara
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

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