Menu
CoddyTech

Um Pet Segue Você

Lição 11 de 18 do curso Jogo Roblox: Simulador de Pets da Coddy.

Os pets devem seguir você. Um novo pet aparece imediatamente se houver menos de Settings.MaxEquipped (3) em exibição, marcado com um atributo Equipped.

Cada pet em exibição recebe uma peça no mundo, uma cópia do modelo dele de ServerStorage.PetModels, e, a cada quadro, o servidor o coloca atrás do dono. RunService.Heartbeat é acionado uma vez por quadro, e multiplicar CFrames posiciona um em relação ao outro:

model.CFrame = root.CFrame * CFrame.new(0, -1.5, 4) -- 4 studs atrás, um pouco mais abaixo

Uma tabela registra qual peça pertence a cada pet, para que um pet guardado perca sua peça.

challenge icon

Desafio

Médio
  1. Escreva equippedCount(player). Dê a givePet um terceiro argumento, equipped, armazenado como o atributo Equipped, e choque com equippedCount(player) < Settings.MaxEquipped.
  2. Obtenha RunService e local petParts = workspace.PetParts. No Heartbeat, para cada jogador e cada pet: se ele estiver equipado (e o jogador tiver um personagem), garanta que ele tenha uma parte (um clone de ServerStorage.PetModels[pet.Value] em petParts) e posicione-a em root.CFrame * CFrame.new((slot - 2) * 3, -1.5, 4), contando os espaços 1, 2, 3; se ele estiver guardado, destrua sua parte.

Pressione Play, choque um ovo e caminhe. Depois, Check.

Experimente você mesmo

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)

local remotes = game.ReplicatedStorage.Remotes
local piles = workspace.Piles
local pileSpot = {} -- cada pilha -> o local onde ela está
local lastHit = {} -- cada jogador -> quando acertou pela última vez

print("A Meadow pile gives " .. Settings.PileValue .. " coins")

-- Settings.Pets por nome
local petInfo = {}
for _, info in Settings.Pets do
	petInfo[info.Name] = info
end

-- Um pet: um StringValue na pasta Pets do jogador que armazena seu nome, com
-- sua raridade e poder como atributos
local function givePet(player, name)
	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.Parent = player.Pets
	return pet
end

-- Todo jogador recebe Coins no placar
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

	-- os pets que eles possuem
	local pets = Instance.new("Folder")
	pets.Name = "Pets"
	pets.Parent = player
end)

-- Uma pilha de moedas em um local: uma cópia de ServerStorage.CoinPile com sua vida
-- e seu 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

-- Um golpe reduz a vida de uma pilha em 1;
-- ao chegar a 0, a pilha se desfaz e concede seu valor
local function hitPile(player, pile)
	local health = pile:GetAttribute("Health") - 1
	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()
	-- uma nova pilha no mesmo local, alguns segundos depois
	task.delay(Settings.RespawnTime, spawnPile, spot)
end

-- Uma pilha em cada ponto de Meadow
for _, spot in workspace.Zones.Meadow.Spawns:GetChildren() do
	spawnPile(spot)
end

-- O cliente pede para atingir uma pilha. Nunca confie no cliente: qualquer pessoa pode disparar
-- esse remote com qualquer coisa, de qualquer lugar, tão rápido quanto quiser.
remotes.Hit.OnServerEvent:Connect(function(player, pile)
	-- uma pilha de verdade
	if typeof(pile) ~= "Instance" or pile.Parent ~= piles then
		return
	end
	-- ao 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
	-- não rápido demais
	local now = time()
	if lastHit[player] and now - lastHit[player] < Settings.HitCooldown then
		return
	end
	lastHit[player] = now
	hitPile(player, pile)
end)

-- Um sorteio ponderado: a Chance de cada pet (de um total de 100) é sua parte da faixa
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

-- Chocagem: o prompt do ovo, pago com moedas
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()
	givePet(player, name)
	print(player.Name .. " hatched a " .. name)
end)
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Jogo Roblox: Simulador de Pets