청소 및 초기화

*이 콘텐츠는 AI(베타)를 사용해 번역되었으며, 오류가 있을 수 있습니다. 이 페이지를 영어로 보려면 여기를 클릭하세요.

게임의 마지막 단계를 코딩하는 시간: 청소 및 초기화. 이 단계의 코드는 게임 루프를 중지하고 각 플레이어에게 동일한 시작을 보장합니다.

GUI 업데이트

정리하고 재설정하기 전에 플레이어에게 DisplayManager를 사용하여 게임이 어떻게 종료되었는지 알려주어 적절한 상태를 표시합니다.

승자 이름 얻기

승리자 플레이어의 이름을 가져오면 시작합니다. 이전에는 코드가 활성 플레이어 테이블의 크기가 1로 줄어든지 확인했습니다. 남은 플레이어의 이름을 가져오려면 해당 테이블의 첫 번째 인덱스에서 이름을 반환합니다.

  1. PlayerManager에서 getWinnerName()라는 이름의 새로운 모듈 기능을 시작합니다.


    function PlayerManager.getWinnerName()
    end
    -- 이벤트
    Players.PlayerAdded:Connect(onPlayerJoin)
  2. activePlayers[1] 에 있는 경우 이면 if 문을 추가하여 실행합니다. 테이블 수가 이전에 확인된 경우에도 플레이어가 연결을 해제하거나 게임을 종료했을 수 있습니다.


    function PlayerManager.getWinnerName()
    local winningPlayer = activePlayers[1]
    if winningPlayer then
    end
    end
  3. if 문에서:

    • 플레이어의 이름을 반환합니다.
    • 다른 경우 오류 문자열을 반환합니다.

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

종료 상태 가져오기

타이머가 끝나든 플레이어가 남든 상태 변수를 가져와 DisplayManager에 보내고 상태 GUI를 업데이트하려면 module 함수를 사용하십시오.

  1. In MatchManager , code a new module function named getEndStatus() with a parameter named endState . To store the message that will be sent, add an empty variable named 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. 이 식을 if 및 else 문을 사용하여 설정합니다. end state 변수를 확인하십시오. statusToReturnFoundWinner . 오류 검사를 위해 종료다시 포함하십시오.


    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    elseif endState == gameSettings.endStates.TimerUp then
    else
    end
    end
  3. 다음을 각 조건에 대해 추가합니다:

    FoundWinner

    • 승자를 위한 변수 playerManager.getWinnerName() 을 사용합니다.
    • 승자를 발표하는 문자열 statusToReturn 업데이트.

    TimerUp

    • Update statusToReturn 문자열을 사용하여 시간이 다 됐음을 발표합니다.

    Else

    • 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
    end
  4. 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

표시 및 테스트

GameManager에서 업데이트된 공지를 가져와 플레이어에게 DisplayManager를 사용하여 표시하십시오.

  1. Open GameManager 를 엽니다. 루프가 진행되는 동안 진실로 print 마지막 프린트 문을 삭제합니다. 그런 다음, endStatus라는 변수를 만듭니다. 그것을 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. displayManager.updateStatus()를 호출하여 반환된 메시지를 GUI 레이블에 표시하고 endStatus를 전달합니다.


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
  3. 게임이 일시 중지되어 플레이어가 메시지를 볼 수 있도록 합니다, transitionTime 을 사용하여 대기 시간을 추가합니다.


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    task.wait(gameSettings.transitionTime)
  4. 테스트 서버를 시작하고 플레이어가 시간 제한 및 승리 플레이어 조건을 위해 다음 메시지를 볼 수 있는지 확인하십시오.

    시간이 끝난 조건
    승리한 플레이어 상태

문제 해결 팁

이 시점에서는 메시지를 볼 수 없습니다. 다음 중 하나를 시도해 보세요.

  • 종료 상태 메시지가 "오류 발견"인 경우 조건 중 하나가 성공하지 않았습니다. MatchManager.getEndStatus() 에서 코드를 검사하십시오.
  • 종료 상태가 표시되지 않으면 task.wait(gameSettings.transitionTime) 이 메시지를 표시 관리자에게 보낸 후에 표시됩니다.

새로운 매치 시작

새로운 일치를 시작하기 전에 간단한 전환이 있습니다. 이렇게 하면 플레이어가 종료 상태를 확인할 수 있고 로비로 순간이동하는 것이 덜 놀라워 느낍니다.

전환이 끝나면 남은 플레이어가 아레나에서 제거되고 모든 코드가 재설정됩니다. 이를 통해 플레이어가 클린한 버전의 게임으로 다음 경기를 시작할 수 있습니다.

전환 처리

플레이어가 전환 상태에 이르면 그들의 무기를 제거합니다.

  1. PlayerManager에서 로컬 함수를 찾습니다. 하이라이트된 코드를 복사하고 아래에 붙여넣습니다. 코드는 플레이어의 장비에 액티브하게 장비되거나 플레이어의 배낭에 있는 경우 개별 플레이어의 무기를 제거합니다.


    local function removePlayerWeapon(whichPlayer)
    -- 플레이어가 연결을 해제하거나 떠났는지 확인하십시오.
    if whichPlayer then
    local character = whichPlayer.Character
    -- 플레이어가 현재 그들의 캐릭터에 있다면
    local weapon = character:FindFirstChild("Weapon")
    if weapon then
    weapon:Destroy()
    end
    -- 플레이어가 배낭에 무기를 가지고 있는 경우
    local backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")
    if backpackWeapon then
    backpackWeapon:Destroy()
    end
    else
    print("No player to remove weapon")
    end
    end
  2. RemoveAllWeapons()라는 이름의 새로운 모듈 기능을 시작합니다.


    function PlayerManager.removeAllWeapons()
    end
    -- 이벤트
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  3. 이 함수에서 활성 플레이어 테이블을 순환하려면 for 반복문을 사용합니다. 순환에서 removePlayerWeapon()를 호출하고 찾은 플레이어를 패스합니다.


    function PlayerManager.removeAllWeapons()
    for playerKey, whichPlayer in activePlayers do
    removePlayerWeapon(whichPlayer)
    end
    end

매치 사이 청소

MatchManager의 클리어는 MatchManager의 자체 함수입니다. 지금은 클리어가 이전에 생성된 함수를 사용하여 플레이어 무기를 제거합니다. 게임을 확장함에 따라 더 많은 기능이 추가될 수 있습니다, 예를 들어, 일치중에 변경된 맵을 재설정하는 함수와 같이.

  1. Open MatchManager. Add a new module function named cleanupMatch() . In that function, call playerManager.removeAllWeapons() .


    function MatchManager.cleanupMatch()
    playerManager.removeAllWeapons()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. 다음으로 청소 함수를 호출합니다. GameManager를 열고 matchManager.cleanupMatch()트루를 찾습니다. 플레이어가 결승 휴식 시간 동안 무기를 제거하므로 마지막 task.wait() 전에 2>5>matchManager.cleanMatch5>를 호출하십시오.


    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. 테스트 서버를 시작하고 매치를 실행합니다. 타이머가 종료되고 플레이어의 무기가 종료 게임 중간에 제거되었는지 확인하십시오.

    매치 중에
    매치 후에

매치 초기화

게임에서 몇 가지 다른 것을 알고 있을 수 있습니다. 예를 들어, 플레이어가 매치가 끝난 후에도 아레나에 있는 경우가 있습니다. 매치를 정리하면 게임을 다시 설정합니다. 여기에는 플레이어를 아레나로 다시 보내고 활성 플레이어 테이블을 지우는 것이 포함됩니다. 새로운 게임 로드를 사용하면

먼저, 함수를 시작하여 플레이어를 로비로 다시 보내십시오.

  1. PlayerManager:

    • resetPlayers()라는 이름의 모듈 함수를 생성합니다.
    • ActivePlayers를 반복하려는 for 루프를 추가합니다.
    • 루프에서 respawnPlayerInLobby() 를 호출하고 플레이어를 매개 변수로 전달합니다.

    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    end
    -- 이벤트
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  2. 다음 경기에 대해 activePlayers 테이블을 빠르게 재설정하려면 같이 설정하십시오. 를 사용하여 빠르게 재설정할 수 있습니다.


    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    activePlayers = {}
    end
  3. Open MatchManager. 새로운 모듈 기능을 코드로 resetMatch() 를 호출하고 playerManager.resetPlayers() 를 호출합니다.


    function MatchManager.resetMatch()
    playerManager.resetPlayers()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  4. 게임 관리자로 돌아갑니다. 시간이 끝날 때 게임 관리자 를 호출합니다.


    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. 테스트 서버를 시작하고 매치를 실행하십시오. 오류가 없는 최소 두 게임 루프를 통과할 수 있는지 확인하십시오.

완료된 스크립트

아래에는 작업을 확인하기 위해 완료된 스크립트가 있습니다.

GameManager 스크립트


-- 서비스
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- 모듈 스크립트
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- 이벤트
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

MatchManager 스크립트


local MatchManager = {}
-- 서비스
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 모듈 스크립트
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"))
-- 이벤트
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- 값
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- 매치 타임을 추적하기 위해 새로운 타이머 개체를 생성합니다.
local myTimer = timer.new()
-- 로컬 함수
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을 추가하면 타이머가 0이 아닌 1로 표시됩니다.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- 대기 시간을 설정하지 않으면 더 정확한 루프를 제공합니다.
task.wait()
end
end
-- 모듈 함수
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

PlayerManager 스크립트


local PlayerManager = {}
-- 서비스
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- 모듈
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- 이벤트
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- 맵 변수
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- 값
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- 플레이어 변수
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()
-- 플레이어에게 도구 제공
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)
-- 플레이어가 연결을 해제하거나 떠났는지 확인하십시오.
if whichPlayer then
local character = whichPlayer.Character
-- 플레이어가 현재 그들의 캐릭터에 있다면
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- 플레이어가 배낭에 무기를 가지고 있는 경우
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)
-- 생성 위치를 가져오고 다음 플레이어가 다음 생성을 가질 수 있도록 테이블에서 제거합니다.Gets a spawn location and then removes it from the table so the next player gets the next spawn
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
-- 이벤트
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager