Tu lista de mascotas
Lección 13 de 18 del curso Juego de Roblox: simulador de mascotas de Coddy.
Los jugadores necesitan ver a sus mascotas. El HUD tiene un ScrollingFrame Inventory con un UIListLayout dentro, que apila todo lo que se coloca en él, uno debajo del otro, según LayoutOrder. Cada mascota obtiene un TextButton ahí. Su AutomaticCanvasSize es Y, así que el lienzo crece con la lista y los jugadores con muchas mascotas pueden desplazarse por ella.
El cliente crea la lista a partir de la carpeta Pets que el servidor mantiene en el jugador, y la vuelve a crear cuando esta cambia: ChildAdded cuando nace una mascota, y GetAttributeChangedSignal("Equipped") de cada mascota cuando se equipa o se deja de equipar.
pet:GetAttributeChangedSignal("Equipped"):Connect(showPets)Volver a crearla significa eliminar primero los botones anteriores, para que la lista nunca muestre dos veces a la misma mascota.
Desafío
IntermedioEn PetClient:
- Espera a que aparezca
Petsen el jugador. - Escribe
showPets(): destruye los TextButtons dehud.Inventory, luego añade uno por mascota (LayoutOrder indica su posición, anchoUDim2.new(1, -12, 0, 30), texto blanco escalado), mostrandoCat (out)para una mascota que está fuera yCatpara una que no lo está; verde cuando está fuera. - Llámalas ahora, cuando se añade una mascota y cuando cambia el
Equippedde cualquier mascota.
Pulsa Play y eclosiona un huevo. Después, Check.
Pruébalo tú mismo
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local RunService = game:GetService("RunService")
local Settings = require(game.ReplicatedStorage.Settings)
local remotes = game.ReplicatedStorage.Remotes
local piles = workspace.Piles
local petParts = workspace.PetParts
local pileSpot = {} -- cada pila -> el lugar donde se encuentra
local lastHit = {} -- cada jugador -> cuándo golpeó por última vez
print("A Meadow pile gives " .. Settings.PileValue .. " coins")
-- Settings.Pets por nombre
local petInfo = {}
for _, info in Settings.Pets do
petInfo[info.Name] = info
end
-- Una mascota: un StringValue en la carpeta Pets del jugador que contiene su nombre, con
-- su rareza y poder como atributos
local function givePet(player, name, equipped)
local info = petInfo[name]
local pet = Instance.new("StringValue")
pet.Name = "Pet"
pet.Value = name
pet:SetAttribute("Rarity", info.Rarity)
pet:SetAttribute("Power", info.Power)
pet:SetAttribute("Equipped", equipped)
pet.Parent = player.Pets
return pet
end
-- cuántas mascotas tiene desplegadas un jugador
local function equippedCount(player)
local count = 0
for _, pet in player.Pets:GetChildren() do
if pet:GetAttribute("Equipped") then
count += 1
end
end
return count
end
-- lo que las mascotas de un jugador añaden a cada golpe
local function petPower(player)
local power = 0
for _, pet in player.Pets:GetChildren() do
if pet:GetAttribute("Equipped") then
power += pet:GetAttribute("Power")
end
end
return power
end
-- Cada jugador recibe Coins en la tabla de clasificación
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Parent = leaderstats
-- las mascotas que posee
local pets = Instance.new("Folder")
pets.Name = "Pets"
pets.Parent = player
end)
-- Una pila de monedas en un lugar: una copia de ServerStorage.CoinPile con su salud
-- y valor como atributos
local function spawnPile(spot)
local pile = ServerStorage.CoinPile:Clone()
pile.Position = spot.Position
pile:SetAttribute("MaxHealth", Settings.PileHealth)
pile:SetAttribute("Health", Settings.PileHealth)
pile:SetAttribute("Value", Settings.PileValue)
pile.HealthGui.Label.Text = pile:GetAttribute("Health") .. "/" .. pile:GetAttribute("MaxHealth")
pileSpot[pile] = spot
pile.Parent = piles
return pile
end
-- Un golpe resta 1, más el poder de las mascotas del jugador, a la salud de una pila;
-- al llegar a 0, la pila se rompe y entrega su valor
local function hitPile(player, pile)
local health = pile:GetAttribute("Health") - (1 + petPower(player))
if health > 0 then
pile:SetAttribute("Health", health)
pile.HealthGui.Label.Text = health .. "/" .. pile:GetAttribute("MaxHealth")
return
end
player.leaderstats.Coins.Value += pile:GetAttribute("Value")
local spot = pileSpot[pile]
pileSpot[pile] = nil
pile:Destroy()
-- una nueva pila en el mismo lugar, unos segundos después
task.delay(Settings.RespawnTime, spawnPile, spot)
end
-- Una pila en cada lugar de Meadow
for _, spot in workspace.Zones.Meadow.Spawns:GetChildren() do
spawnPile(spot)
end
-- El cliente solicita golpear una pila. Nunca confíes en el cliente: cualquiera puede activar
-- este evento remoto con cualquier cosa, desde cualquier lugar y tan rápido como quiera.
remotes.Hit.OnServerEvent:Connect(function(player, pile)
-- una pila real
if typeof(pile) ~= "Instance" or pile.Parent ~= piles then
return
end
-- al alcance
local character = player.Character
local root = character and character:FindFirstChild("HumanoidRootPart")
if not root or (root.Position - pile.Position).Magnitude > Settings.Reach then
return
end
-- no demasiado rápido
local now = time()
if lastHit[player] and now - lastHit[player] < Settings.HitCooldown then
return
end
lastHit[player] = now
hitPile(player, pile)
end)
-- Una selección ponderada: el Chance de cada mascota (de 100) representa su proporción de la línea
local function rollPet()
local roll = math.random() * 100
for _, info in Settings.Pets do
roll -= info.Chance
if roll <= 0 then
return info.Name
end
end
return Settings.Pets[1].Name
end
-- Eclosión: el indicador del huevo, que se paga con monedas
workspace.Egg.ProximityPrompt.Triggered:Connect(function(player)
local coins = player.leaderstats.Coins
if coins.Value < Settings.EggPrice then
return
end
coins.Value -= Settings.EggPrice
local name = rollPet()
-- sale de inmediato, si hay espacio
local pet = givePet(player, name, equippedCount(player) < Settings.MaxEquipped)
print(player.Name .. " hatched a " .. name)
end)
-- Las mascotas que están fuera siguen a su dueño: cada una tiene una pieza en el mundo, situada en una
-- en fila detrás del jugador en cada fotograma
local petModels = {} -- cada mascota -> su pieza en el mundo
RunService.Heartbeat:Connect(function()
for _, player in Players:GetPlayers() do
local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
local pets = player:FindFirstChild("Pets")
local slot = 0
for _, pet in pets and pets:GetChildren() or {} do
local model = petModels[pet]
if pet:GetAttribute("Equipped") and root then
slot += 1
if not model then
model = ServerStorage.PetModels[pet.Value]:Clone()
model.Parent = petParts
petModels[pet] = model
end
model.CFrame = root.CFrame * CFrame.new((slot - 2) * 3, -1.5, 4)
elseif model then
model:Destroy()
petModels[pet] = nil
end
end
end
end)
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Juego de Roblox: simulador de mascotas
3Huevos y mascotas
Incuba un huevo