Oyunun son aşamasını kodlamak için zaman: temizleme ve sıfırlama.Bu aşamadaki kod, oyun döngülerinin duraklamasını ve gelecekteki maçların her oyuncu için aynı olmasını sağlar.
GUI'yi güncelle
Temizlik ve sıfırlama yapmadan önce, oyunculara uygun durumu göstermek için DisplayManager'ı kullanarak oyunun nasıl sona erdiğini bilgilendirin.
Kazananın adını al
Bir varsa kazanan oyuncunun adını alarak başlayın.Daha önce, kod aktif oyuncu tablosunun boyutunun 1'e düştüğünü kontrol etti.Kalan oyuncunun adını almak için, adı bu tablonun ilk indeksinde geri gönderin.
Oyun Yöneticisinde, getWinnerName() adlı yeni bir modül işlevi başlatın.
function PlayerManager.getWinnerName()end-- EtkinliklerPlayers.PlayerAdded:Connect(onPlayerJoin)Bir şey varsa çalışan bir if ifadesi ekleyin activePlayers[1] .Tablo sayısı daha önce kontrol edilmiş olsa da, oyuncu bağlantıyı kestirmiş veya oyundan ayrılmış olabilir.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenendendEğer ifadesinde:
- Oyuncunun adını geri ver.
- Diğer için, bir hata dizesi döndürün.
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
Son durumu alın
Zamanlayıcı bitiyor veya bir oyuncu kalıyor olsa da doğru son durumdan bilgi almak için bir modül işlevini kullanın.Sonra, bu durum değişkenini GUI'nin durumunu güncellemek için uygun mesajla DisplayManager'a gönderin.
In Maç Yöneticisi , getEndStatus() adlı yeni bir modül işlevini bir parametre ile kodlayın endState .Gönderilecek mesajı depolamak için, statusToReturn adlı boş bir değişken ekleyin.
function MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()endfunction MatchManager.getEndStatus(endState)local statusToReturnendmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerif ve elseif ifadelerini kullanarak statusToReturn.Son durum değişkenlerini kontrol edin: FoundWinner ve TimerUp.Hata kontrolü için, sonunda başka bir şey dahil edin.
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenelseif endState == gameSettings.endStates.TimerUp thenelseendendHer koşul için şu ekleyin:
FoundWinner
- Kazananı kullanan bir değişken playerManager.getWinnerName() .
- Kazananı duyuran bir dize ile güncelle statusToReturn ile güncelle.
TimerUp
- Güncelleme statusToReturn ile süre dolduğunu duyuran bir dize ile güncellenir.
Else
- Son oyun mesajını almakla ilgili sorunlar varsa statusToReturn ile bir hata mesajı güncelleştirin.
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"endendMesajı return statusToReturn yazarak geri gönderin.
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
Göster ve test et
Oyun Yöneticisinde güncellenmiş duyuruyu al ve Oyun Yöneticisi kullanarak oyunculara göster.
Aç Oyun Yöneticisi .While gerçek do döngüsünde, silin son yazım ifadesini.Sonra, endStatus adlı bir değişken oluşturun.Bunu matchManager.getEndStatus(endState) eşit olarak ayarlayın.
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)endDöndürülen mesajı GUI etiketinde görüntülemek için displayManager.updateStatus() 'yi arayın ve endStatus geçirin.
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)Bu nedenle oyun, oyuncuların mesajı görmesine izin vermek için duraklar ve transitionTime kullanarak bir bekleme ekler.
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)task.wait(gameSettings.transitionTime)Bir test sunucusu başlatın ve oyuncuların aşağıdaki mesajları gördüğünden emin olun zaman aşırı ve kazanan oyuncu koşulları için.
Süre doldu koşulu Kazanan oyuncu koşulu
Sorun giderme ipuçları
Bu noktada, mesajları göremiyorsunuz, aşağıdan birini deneyin.
- Son durum mesajınız "Hata Bulundu" ise, koşullardan hiçbiri başarılı değildi. Kod örneklerine karşı MatchManager.getEndStatus() kodu kontrol edin.
- Son durum görüntülenmiyorsa, iletişim yöneticisine göndermeden önce task.wait(gameSettings.transitionTime) 'nin olduğundan emin olun.
Yeni maçlar başlat
Yeni bir maç başlamadan önce, kısa bir geçiş olacak.Bu, oyuncuların son durumu görmeye vakit verir ve lobiye ışınlanmanın daha az ani hissetmesini sağlar.
Geçişin sonunda, kalan oyuncular arenadan kaldırılacak ve tüm kod sıfırlanacaktır.Bu, oyuncuların bir sonraki maçı temiz bir versiyonla başlatacağını garanti eder.
Geçişleri ele al
Oyuncular geçiş durumuna geçtiğinde, silahlarını kaldırın.
PlayerManager'da, yerel işlevleri bulun.Vurgulanan kodu removePlayerWeapon().Kod, bir oyuncunun silahını kaldıracak, eğer aktif olarak donatılmışsa veya oyuncunun sırt çantasında bulunuyorsa.
local function removePlayerWeapon(whichPlayer)-- Bir oyuncu bağlantıyı kesti veya ayrıldıysa var olup olmadığını kontrol edin.if whichPlayer thenlocal character = whichPlayer.Character-- Oyuncu şu anda karakterinde buna sahipselocal weapon = character:FindFirstChild("Weapon")if weapon thenweapon:Destroy()end-- Oyuncunun sırt çantasında silahı varsalocal backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")if backpackWeapon thenbackpackWeapon:Destroy()endelseprint("No player to remove weapon")endendYeni bir modül işlevi olan removeAllWeapons() adlı yeni bir işlev başlatın.
function PlayerManager.removeAllWeapons()end-- EtkinliklerPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerBu işlevde, aktif oyuncu tablosunu gezmek için bir döngü kullanın. Döngüde, removePlayerWeapon() 'yi çağırın ve bulunan oyuncuyu geçirin.
function PlayerManager.removeAllWeapons()for playerKey, whichPlayer in activePlayers doremovePlayerWeapon(whichPlayer)endend
Maçlar arasında temizle
Temizlik, MatchManager'de kendi işlevi olacaktır.Şimdilik, temizlik yalnızca daha önce oluşturulan işlevi kullanarak oyuncu silahlarını kaldıracak.Oyunu genişlettikçe, bir maç sırasında değişen bir haritayı sıfırlayan işlevler gibi daha fazlası eklenebilir.
Maç Yöneticisini aç. cleanupMatch() adlı yeni bir modül işlevi ekleyin. Bu işlevde playerManager.removeAllWeapons() çağırın.
function MatchManager.cleanupMatch()playerManager.removeAllWeapons()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerSonra temizleme işlevini çağırın.Aç Oyun Yöneticisi ve while true do döngüsünü bulun.Dolayısıyla oyuncuların bitiş arasında silahı kaldırılır, son task.wait() önce matchManager.cleanupMatch() çağırın.
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)endBir test sunucusu başlatın ve bir maç yapın. Zamanlayıcının tükenmesini bekleyin ve oyuncunun silahının son oyun arasında kaldırıldığını onaylayın.
Bir maç sırasında Maçtan sonra
Maçları sıfırla
Oyunda birkaç şey fark etmiş olabilirsiniz, oyuncuların bir maçtan sonra hala arenada olması gibi.Maç temizlendikten sonra, bir sonraki sıfırlama oyunu yeniden başlatın.Buna, oyuncuları arenaya geri göndermek ve aktif oyuncu masasını temizlemek dahildir.Yerinde bir sıfırlama ile, bir oyun döngüsü süresiz olarak çalışabilir.
Öncelikle, oyuncuları lobiye geri göndermek için bir işlev başlatın.
Oyun Yöneticisinde:
- Bir modül işlevi oluştur resetPlayers() . adında.
- Aktif oyuncular arasında dolaşmak için bir for döngüsü ekleyin.
- Döngüde, respawnPlayerInLobby() 'yi arayın ve oyuncuyu parametre olarak geçirin.
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endend-- EtkinliklerPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerBir sonraki maç için activePlayers tablosunun boş olduğundan emin olmak için, boş bir tabloya sıfırlamak için kullanılan {} ile eşit olarak ayarlayın, bu da boş bir tabloya sıfırlamanın hızlı bir yoludur.
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endMaç Yöneticisini aç. resetMatch() adlı yeni bir modül işlevi kodlayın ve playerManager.resetPlayers() çağırın.
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerGeri dönün Oyun Yöneticisine . While gerçek do döngüsünün sonunda, çağır 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()endBir test sunucusu başlatın ve bir maç yürütün. En azından herhangi bir hata olmadan iki oyun döngüsünden geçebileceğinizi onaylayın.
Tamamlanmış senaryolar
Aşağıda, çalışmanızı kontrol etmek için bitmiş senaryolar bulunmaktadır.
GameManager senaryosu
-- Hizmetlerlocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Modül Kodlarılocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- Etkinliklerlocal 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
MaçYöneticisi skripti
local MatchManager = {}
-- Hizmetler
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Modül Kodları
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"))
-- Etkinlikler
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Değerler
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Maç süresini izlemek için kullanılacak yeni bir zamanlayıcı nesnesi oluşturur.
local myTimer = timer.new()
-- Yerel Fonksiyonlar
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
-- +1 eklemek, zamanlayıcının 0 yerine 1'de sona ermesini sağlar.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- Bekleme süresini ayarlamayarak, daha doğru döngüleme sağlar
task.wait()
end
end
-- Modül İşlevleri
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
Oyuncu Yöneticisi senaryosu
local PlayerManager = {}
-- Hizmetler
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Modüller
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Etkinlikler
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Harita Değişkenleri
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Değerler
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Oyuncu Değişkenleri
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()
-- Oyuncuya bir araç ver
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)
-- Bir oyuncu bağlantıyı kesti veya ayrıldıysa var olup olmadığını kontrol edin.
if whichPlayer then
local character = whichPlayer.Character
-- Oyuncu şu anda karakterinde buna sahipse
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- Oyuncunun sırt çantasında silahı varsa
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)
-- Bir oluşturma konumu alır ve ardından masadan kaldırır, böylece bir sonraki oyuncu bir sonraki oluşumu alır
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
-- Etkinlikler
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager