En este momento, gran parte de la información del juego está actualmente en la ventana de salida, invisible para los jugadores. Para que los jugadores puedan ser informados de lo que está sucediendo en el juego, crearás una interfaz de usuario gráfica (Interfaz gráfica (o GUI)) y la codificarás.
Mostrando información con una Interfaz gráfica (o GUI)
Para este juego, una etiqueta de texto mostrará el estado actual del juego, así como el número y el tiempo restantes de los jugadores.
Configurando la Interfaz gráfica (o GUI)
Primero, crea un objeto Screen GUI para contener los diferentes elementos de texto. Cuando el jugador mueve la cámara, la GUI de la pantalla permanece en el mismo lugar en su pantalla.
Para asegurarte de que todos los jugadores vean la misma pantalla, coloca la GUI en la carpeta StarterGUI . Al iniciar el juego, esta carpeta se copia a todos los jugadores.
En la carpeta StarterGUI, cree una nueva ScreenGUI. Luego, en ScreenGUI, agregue una nueva etiqueta de texto llamada StatusText.
Para mover la etiqueta, en el Explorador, seleccione StatusText. Luego, en la vista del juego, arrastre la etiqueta donde lo desee. Sus números pueden diferir del video. La etiqueta también se puede cambiar de tamaño utilizando los puntos de anclaje en las esquinas.
Programando la Interfaz gráfica (o GUI)
Para reflejar los cambios en el juego, los scripts tendrán que actualizar los elementos GUI. Por instancia, el estado del juego, ya sea un intermedio o una ronda activa, se almacenará en un StringValue y se actualizará utilizando scripts locales.
En comparación con los scripts y los scripts de módulos que ejecutan los servidores de Roblox, los scripts locales se ejecutan en el dispositivo de un jugador. A menudo se usan para codificar elementos GUI como el temporizador o la entrada del jugador, como las acciones del mouse o del teclado.
Configurando el Script
El script de StatusDisplay se usará para actualizar la GUI del jugador cada vez que el estado del juego cambie.
En ReplicatedStorage , crea una carpeta llamada DisplayValues. En esa carpeta, añade un StringValue llamado Status. Para probar el valor más tarde, dale un valor temporal, como "Bienvenido a la batalla!"
Debido a que los scripts locales solo se ejecutan en el dispositivo de un jugador, no se pueden almacenar en carpetas del servidor como ServerStorage. ReplicatedStorage es una carpeta que está disponible tanto para el cliente (dispositivo) como para el servidor.
En StarterGUI > ScreenGUI > Status, agregue un nuevo script local llamado StatusDisplay. Los scripts que afectan la GUI a menudo están relacionados con ese elemento GUI.
Abre StatusDisplay y define las siguientes variables para el seguir:
Servicio de almacenamiento replicado
Carpeta de valores de visualización
Estado StringValue
Etiqueta de texto - use script.Parent .
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local textLabel = script.Parent
Cambiando la etiqueta de texto
Para cambiar el texto en la etiqueta, use un evento cambiado para que cuando la cadena de estado sea cambiada por otro script, la etiqueta de texto se actualice.
Codifica una nueva función llamada updateText(). En esa función, establece la propiedad Text de textLabel en status.Value.
local textLabel = script.Parent
local function updateText()
textLabel.Text = status.Value
end
Conecta la función al evento Cambiado.
local function updateText()
textLabel.Text = status.Value
end
status.Changed:Connect(updateText)
Para que los jugadores vean el estado más actualizado al iniciar el juego, ejecute updateText() al final del script.
local function updateText()
textLabel.Text = status.Value
end
status.Changed:Connect(updateText)
updateText()
Ejecuta el juego y confirma que ves el valor temporal en la pantalla.
Creando el Administrador de Display
Durante un juego, la etiqueta de texto necesitará obtener información del GameManager, MatchManager y posiblemente otros scripts. Para que estos diferentes scripts puedan actualizar la etiqueta de texto cuando sea necesario, cree un script de módulo llamado DisplayManager.
Configurando el Script
Debido a que DisplayManager necesita comunicarse con otros scripts, será un script de módulo.
En ServerStorage > ModuleScripts , cree un nuevo script de módulo llamado DisplayManager. Renombra la tabla de módulos para que coincida con el nombre del script.
Añade variables locales para lo siguiendo: almacenamiento replicado, carpeta DisplayValues, estado.
local DisplayManager = {}
-- Servicios
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Mostrar valores usados para actualizar la Interfaz gráfica (o GUI)del jugador
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
-- Funciones Locales
-- Funciones del módulo
return DisplayManager
Crea una nueva función de módulo llamada updateStatus() que actualice la cadena en el valor Status. Otros scripts podrán llamar a esta función.
-- Funciones Locales
-- Funciones del módulo
function DisplayManager.updateStatus(newStatus)
status.Value = newStatus
end
Actualizando el estado del texto
Con el Administrador de Display configurado, se puede usar en otros scripts para actualizar la etiqueta de texto GUI. Como primer mensaje en la Interfaz gráfica (o GUI), muestra el comienzo y fin de la pausa a través del script GameManager.
En ServerScriptService > GameManager, crea una variable llamada displayManager y requiere el módulo DisplayManager en ServerStorage.
-- Servicios
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Scripts de módulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local roundManager = require(moduleScripts:WaitForChild("RoundManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
Como la primera línea después de la sentencia while true do, llama a displayManager > updateStatus() y pasa un mensaje sobre esperar a los jugadores.
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
while true do
displayManager.updateStatus("Waiting for Players")
repeat
print("Starting intermission")
task.wait(gameSettings.intermissionDuration)
until #Players:GetPlayers() >= gameSettings.minimumPlayers
task.wait(gameSettings.transitionTime)
matchManager.prepareGame()
matchEnd.Event:Wait()
end
Después del final del bucle de repetición para el intermedio, llama updateStatus() y pasa en una cadena anunciando que la partida está comenzando. Dado que estará probando con la interfaz gráfica de usuario, elimine las dos declaraciones de impresión para notar el comienzo y el final del intermedio.
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()
matchEnd.Event:Wait()
end
Prueba el juego con y sin tus jugadores mínimos. El mensaje debe leer lo siguiendo:
Sin los jugadores mínimos: "Waiting for Players" .
Con el mínimo de jugadores: "Get ready" .
Consejos para solucionar problemas
En este punto, si la etiqueta de texto no muestra el primer mensaje o aún muestra "Etiqueta," intente uno de los siguientes.
Asegúrese en el script local de StatusDisplay que updateText() se llame en la parte inferior del script. Esto garantiza que el jugador reciba el mensaje más actualizado.
Comprueba que el Status StringValue esté en ReplicatedStorage. Debido a la naturaleza única de las relaciones cliente-servidor, si está en ServerStorage, un script local no podrá encontrarlo.
Mostrando el estado de la partida
Durante una coincidir, la GUI mostrará dos números: el número de jugadores restantes y el tiempo. A medida que estos números cambien, la etiqueta de texto también cambiará.
Configurando Valores y Funciones
IntValues se utilizará para almacenar el número de jugadores y el tiempo restante.
En ReplicatedStorage > DisplayValues, crea dos IntValues llamados PlayersLeft y TimeLeft.
En DisplayManager, agregue variables para almacenar los valores de los jugadores restantes y el tiempo restante.
local DisplayManager = {}
-- Servicios
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Mostrar valores usados para actualizar la Interfaz gráfica (o GUI)del jugador
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
local timeLeft = displayValues:WaitForChild("TimeLeft")
Crea una función local llamada updateMatchStatus() . Luego, establece el valor del estado para mostrar el número de jugadores restantes y el tiempo restante.
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Funciones Locales
local function updateRoundStatus()
status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.Value
end
Para ambas variables de IntValue, conecte updateRoundStatus() al evento Changed.
-- Funciones del módulo
function DisplayManager.updateStatus(newStatus)
status.Value = newStatus
end
playersLeft.Changed:Connect(updateRoundStatus)
timeLeft.Changed:Connect(updateRoundStatus)
return DisplayManager
No hagas la prueba todavía. Nada ha actualizado los valores de PlayersLeft o TimeLeft, por lo que el estado no se cambiará una vez que comience una ronda.
Mostrando Jugadores
A continuación, agregue el código para mostrar el número de jugadores al comienzo de un juego. Las lecciones posteriores actualizarán el valor de PlayersLeft a medida que los jugadores sean eliminados del juego.
En PlayerManager, agregue variables locales para el servicio ReplicatedStorage, la carpeta DisplayValues y PlayersLeft IntValue.
local PlayerManager = {}
-- Servicios
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Variables del mapa
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Valores
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
Muestra el número de jugadores iniciales configurando el valor de playersLeft al tamaño del matriz/listade jugadores activos.
Luego, en sendPlayersToMatch() , debajo del bucle para, introducir: playersLeft.Value = #activePlayers
function PlayerManager.sendPlayersToMatch()
local availableSpawnPoints = spawnLocations:GetChildren()
for playerKey, whichPlayer in Players:GetPlayers() do
table.insert(activePlayers, whichPlayer)
local spawnLocation = table.remove(availableSpawnPoints, 1)
preparePlayer(whichPlayer, spawnLocation)
end
playersLeft.Value = #activePlayers
end
Mostrando el temporizador
Recuerda que los scripts de los módulos se usan para centralizar código similar. Dado que el temporizador se rastrea en MatchManager, actualiza el valor de TimeLeft usando funciones del script de Timer. El administrador de visualización escuchará los cambios en el TimeLeft y se actualizará para que coincida con el nuevo valor.
En MatchManager, crea variables para almacenar el servicio ReplicatedStorage , la carpeta DisplayValues y el valor TimeLeft.
local MatchManager = {}
-- Servicios
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Scripts de módulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
-- Valores
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
local myTimer = timer.new()
Encuentra la función startTimer(). Después del evento del temporizador, copia y pega todo, resaltado durante el bucle a continuación. El código ejecuta un bucle para actualizar el valor mientras el temporizador aún esté activo.
while myTimer:isRunning() do
-- Añadir +1 garantiza que la pantalla del temporizador termine en 1 en lugar de 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Al no establecer el tiempo de espera, ofrece un bucle más preciso
task.wait()
end
Cuando se añade, el código debe parecerse a la muestra de abajo.
local function startTimer()
print("Timer started")
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
while myTimer:isRunning() do
-- Añadir +1 garantiza que la pantalla del temporizador termine en 1 en lugar de 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Al no establecer el tiempo de espera, ofrece un bucle más preciso
task.wait()
end
end
Ejecuta el juego con el mínimo de jugadores. Comprueba que el texto de estado se muestre:
La cantidad correcta de jugadores que comienzan. Recuerda, este número no cambiará hasta que se agregue un código adicional en una lección futura.
El tiempo disminuye cada segundo hasta que se detiene en 1.
Scripts completados
A continuación se encuentran los scripts completados para verificar dos veces su trabajo.
Script de GameManager
-- Servicios
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Scripts de módulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Eventos
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()
matchEnd.Event:Wait()
end
Script de DisplayManager
local DisplayManager = {}
-- Servicios
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Mostrar valores usados para actualizar la Interfaz gráfica (o GUI)del jugador
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Funciones Locales
local function updateRoundStatus()
status.Value = "Players Left: " .. playersLeft.Value .. " / Time Left: " .. timeLeft.Value
end
-- Funciones del módulo
function DisplayManager.updateStatus(newStatus)
status.Value = newStatus
end
playersLeft.Changed:Connect(updateRoundStatus)
timeLeft.Changed:Connect(updateRoundStatus)
return DisplayManager
Script del Gerente de Partidas
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Scripts de módulo
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- Eventos
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Valores
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
local myTimer = timer.new()
-- Funciones Locales
local function timeUp()
print("Time is up!")
end
local function startTimer()
print("Timer started")
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
while myTimer:isRunning() do
-- Añadir +1 garantiza que la pantalla del temporizador termine en 1 en lugar de 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Al no establecer el tiempo de espera, ofrece un bucle más preciso
task.wait()
end
end
-- Funciones del módulo
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
return MatchManager
Script de Visualización de Estado
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local status = displayValues:WaitForChild("Status")
local textLabel = script.Parent
local function updateText()
textLabel.Text = status.Value
end
status.Changed:Connect(updateText)
updateText()