Los jugadores ahora pueden recolectar monedas y perderlas cuando mueren, pero las monedas no hacen nada y la mayor parte del mundo 3D es inaccesible sin la capacidad de saltar muy alto. Esta sección del tutorial te enseña cómo completar la lógica de tu experiencia añadiendo un botón en pantalla que gasta monedas para aumentar el poder de salto.
Crear el botón de mejora
Las interfaces 2D en Roblox generalmente están compuestas por una colección de componentes de GUI dentro de un contenedor de GUI. En este caso, solo necesitas un componente TextButton que diga Mejorar Salto (5 Monedas) dentro de un contenedor ScreenGui.
Configurar la GUI de mejoraEn ReplicatedStorage, crea una carpeta llamada Instances.Dentro de la carpeta Instances, crea una ScreenGui llamada JumpPurchaseGui con ResetOnSpawn deshabilitado.Dentro de JumpPurchaseGui, crea un TextButton llamado JumpButton con las siguientes propiedades:- Text: "Mejorar Salto (5 Monedas)"- TextSize: 25- AnchorPoint: 1, 1- Position: {1, 0}, {1, 0}También dentro de la carpeta Instances, crea una RemoteFunction llamada IncreaseJumpPowerFunction.Finalmente, en el servicio StarterPlayer, habilita la propiedad CharacterUseJumpPower.
Definir los datos de poder de salto
Actualmente, solo se almacena el número de monedas para cada jugador en el script del módulo PlayerData. También necesitas almacenar y actualizar el poder de salto de la misma manera. Debido a que las funciones en PlayerData no son específicas para los datos que se están cambiando, lo único que se requiere para almacenar el poder de salto del jugador es agregar una clave Jump e inicializar su valor inicial en defaultPlayerData().
Actualizar PlayerData con poder de saltoEn ServerStorage, reemplaza el código existente del módulo PlayerData con lo siguiente:```lualocal PlayerData = {}PlayerData.COIN_KEY_NAME = "Coins"PlayerData.JUMP_KEY_NAME = "Jump"local playerData = {--[[[userId: string] = {["Coins"] = coinAmount: number,["Jump"] = jumpPower: number}--]]}local function defaultPlayerData()return {[PlayerData.COIN_KEY_NAME] = 0,[PlayerData.JUMP_KEY_NAME] = 0,}endlocal function getData(player)local data = playerData[tostring(player.UserId)] or defaultPlayerData()playerData[tostring(player.UserId)] = datareturn dataendfunction PlayerData.getValue(player, key)return getData(player)[key]endfunction PlayerData.updateValue(player, key, updateFunction)local data = getData(player)local oldValue = data[key]local newValue = updateFunction(oldValue)data[key] = newValuereturn newValueendreturn PlayerData```
Actualizar los datos de poder de salto
Ahora que PlayerData puede rastrear el poder de salto, necesitas implementar lógica en el servidor para mejorar el poder de salto a partir de una solicitud del cliente.
El servidor y el cliente pueden comunicarse a través de RemoteEvents o RemoteFunctions. Los eventos remotos no esperan cuando se activan y se pueden utilizar para comunicación unidireccional. Las funciones remotas, por otro lado, esperan hasta que reciben una respuesta, lo que permite la comunicación bidireccional.
Para este tutorial, el cliente necesita saber si el servidor actualizó con éxito el poder de salto del jugador, por lo que deberías usar una función remota.
Crear JumpServiceEn ServerScriptService, crea un Script llamado JumpService con el siguiente código:```lua-- Servicioslocal ReplicatedStorage = game:GetService("ReplicatedStorage")local ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Móduloslocal Leaderboard = require(ServerStorage.Leaderboard)local PlayerData = require(ServerStorage.PlayerData)-- Eventoslocal IncreaseJumpPowerFunction = ReplicatedStorage.Instances.IncreaseJumpPowerFunctionlocal JUMP_KEY_NAME = PlayerData.JUMP_KEY_NAMElocal COIN_KEY_NAME = PlayerData.COIN_KEY_NAMElocal JUMP_POWER_INCREMENT = 30local JUMP_COIN_COST = 5local function updateJumpPower(player, updateFunction)-- Actualiza la tabla de poder de saltolocal newJumpPower = PlayerData.updateValue(player, JUMP_KEY_NAME, updateFunction)-- Actualiza el poder de salto del jugadorlocal character = player.Character or player.CharacterAdded:Wait()local humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.JumpPower = newJumpPower-- Actualiza el leaderboard de saltoLeaderboard.setStat(player, JUMP_KEY_NAME, newJumpPower)endendlocal function onPurchaseJumpIncrease(player)local coinAmount = PlayerData.getValue(player, COIN_KEY_NAME)if coinAmount < JUMP_COIN_COST thenreturn falseend-- Aumenta el poder de salto del jugadorupdateJumpPower(player, function(oldJumpPower)oldJumpPower = oldJumpPower or 0return oldJumpPower + JUMP_POWER_INCREMENTend)-- Actualiza la tabla de monedaslocal newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, function(oldCoinAmount)return oldCoinAmount - JUMP_COIN_COSTend)-- Actualiza el leaderboard de monedasLeaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)return trueendlocal function onCharacterAdded(player)-- Restablece el poder de salto del jugador cuando se añade el personajeupdateJumpPower(player, function(_)return 0end)end-- Inicializa a cualquier jugador añadido antes de conectar al evento PlayerAddedfor _, player in Players:GetPlayers() doonCharacterAdded(player)end-- Inicialización normal de jugadores a partir del evento PlayerAddedlocal function onPlayerAdded(player)player.CharacterAdded:Connect(function()onCharacterAdded(player)end)endlocal function onPlayerRemoved(player)updateJumpPower(player, function(_)return nilend)endIncreaseJumpPowerFunction.OnServerInvoke = onPurchaseJumpIncreasePlayers.PlayerAdded:Connect(onPlayerAdded)Players.PlayerRemoving:Connect(onPlayerRemoved)```
Las siguientes secciones describen el código con más detalle.
Actualizar los datos de poder de salto - updateJumpPower() actualiza el poder de salto del jugador y el leaderboard para proporcionar retroalimentación visual. Esta función se asemeja al código que daña a los jugadores en Crear peligros para jugadores. Proporcionando un modelo de Character y Humanoid que existen para el jugador que se va a mejorar, la función actualiza la propiedad JumpPower al nuevo valor almacenado por PlayerData, aumentándolo en 30. Si deseas que tu juego dure un poco más, puedes disminuir este número.
Validar solicitudes del servidor - onPurchaseJumpIncrease() primero verifica que el jugador realmente tenga la cantidad de monedas requeridas para comprar la mejora. Todas las solicitudes de clientes al servidor deben ser validadas para evitar que actores malintencionados envíen solicitudes falsas y exploten tu juego.
Agregar el botón a la GUI del jugador
Un objeto ScreenGui solo se muestra en la pantalla si está parentado al objeto PlayerGui de un jugador. Por defecto, este contiene la GUI del sistema, como la ventana de chat. Ahora necesitas crear un script en ReplicatedStorage para copiar el botón de mejora en la GUI de cada jugador e implementar el comportamiento para cuando se presiona el botón.
Crear JumpButtonClickHandlerEn ReplicatedStorage, crea un Script llamado JumpButtonClickHandler con RunContext configurado como Client y el siguiente código:```lualocal ReplicatedStorage = game:GetService("ReplicatedStorage")local Players = game:GetService("Players")local player = Players.LocalPlayerlocal playerGui = player.PlayerGuilocal IncreaseJumpPowerFunction = ReplicatedStorage.Instances.IncreaseJumpPowerFunctionlocal jumpPurchaseGui = ReplicatedStorage.Instances.JumpPurchaseGuilocal jumpButton = jumpPurchaseGui.JumpButtonlocal function onButtonClicked()local success, purchased = pcall(IncreaseJumpPowerFunction.InvokeServer, IncreaseJumpPowerFunction)if not success then-- purchased será el mensaje de error si el éxito es falsoerror(purchased)elseif success and not purchased thenwarn("¡No hay suficientes monedas!")endendjumpButton.Activated:Connect(onButtonClicked)-- Añadir la JumpPurchaseGui a la GUI del jugadorjumpPurchaseGui.Parent = playerGui```
Las siguientes secciones describen el código con más detalle.
- Obtener referencias a la GUI y la función del servidor - Las variables IncreaseJumpPowerFunction, jumpPurchaseGui y jumpButton contienen referencias a la función y GUI que llama a la función que necesitarás más adelante.
- Definir el manejador de eventos - onButtonClicked() define la lógica para cuando los usuarios hacen clic en el botón de mejora. Usa pcall() (llamada protegida) para invocar la RemoteFunction. Cualquier comunicación cliente-servidor como esta requiere que pcall() maneje errores o problemas de conexión.
- Conectar el manejador al botón - El evento Activated es compatible en todas las plataformas, incluyendo contextos de mouse, pantalla táctil o gamepad. Se activa cuando se hace clic, se toca o se libera un botón de gamepad.
Probar
Selecciona Test del menú desplegable y haz clic en Play. El botón Mejorar Salto aparece en la esquina inferior derecha.
Intenta hacer clic en el botón antes de recolectar monedas para verificar que no te otorgue poder de salto adicional, luego intenta recolectar algunas monedas y ve si la mejora funciona al volver a hacer clic.
Con el código completo, intenta ajustar la dificultad: añade monedas si el ritmo se siente lento, o quita algunas y escóndelas en lugares más difíciles si las mejoras llegan demasiado fácilmente.