Menu
CoddyTech

Cho ra ba thú cưng

Bài học 12 trên 20 trong khóa học Trò chơi Roblox: mô phỏng thú cưng của Coddy.

Thú cưng cần xếp thành hàng và chỉ có thể đưa ra ngoài tối đa Settings.MaxEquipped (3) con cùng lúc. Thú cưng mới chỉ được đưa ra ngoài khi số thú cưng đang ở ngoài ít hơn mức đó; những con còn lại chờ trong thư mục Pets.

Để đếm số thú cưng đang ở ngoài, hãy lặp qua thư mục:

local count = 0
for _, pet in player.Pets:GetChildren() do
	if pet:GetAttribute("Equipped") then
		count += 1
	end
end

Để xếp chúng thành hàng, hãy đánh số các thú cưng đang ở ngoài theo thứ tự khi đặt chúng, 1, 2, 3, rồi chuyển số đó thành độ lệch sang ngang: với (slot - 2) * 5, slot 1 nằm lệch 5 studs sang trái và slot 3 lệch 5 sang phải.

challenge icon

Thử thách

Trung bình

Xếp tối đa ba thú cưng thành một hàng phía sau bạn.

  1. Viết equippedCount(player), hàm đếm số thú cưng của người chơi đang được trang bị.
  2. Ấp trứng bằng givePet(player, name, equippedCount(player) < Settings.MaxEquipped).
  3. Trong Heartbeat, đếm slot lần lượt là 1, 2, 3 cho các thú cưng đang đi theo, rồi đặt từng thú cưng tại root.CFrame * CFrame.new((slot - 2) * 3, -1.5, 4).

Nhấn Chơi rồi ấp bốn thú cưng: ba thú cưng sẽ đi thành hàng phía sau bạn, cạnh nhau. Sau đó nhấn Kiểm tra.

Tự làm thử

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 = {} -- mỗi đống xu -> vị trí đặt đống xu đó
local lastHit = {} -- mỗi người chơi -> thời điểm đánh gần nhất

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

-- Settings.Pets được tra cứu theo tên
local petInfo = {}
for _, info in Settings.Pets do
	petInfo[info.Name] = info
end

-- Một thú cưng: StringValue trong thư mục Pets của người chơi, lưu tên cùng
-- độ hiếm và sức mạnh dưới dạng thuộc tính
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

-- Bài học 12: Three Pets Out sẽ đặt ở đây

-- Mỗi người chơi có Coins trên bảng xếp hạng
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

	-- những thú cưng họ sở hữu
	local pets = Instance.new("Folder")
	pets.Name = "Pets"
	pets.Parent = player
end)

-- Một đống xu tại một vị trí: bản sao của ServerStorage.CoinPile, lưu lượng máu
-- và giá trị dưới dạng thuộc tính
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

-- Mỗi lần đánh làm đống xu mất 1 máu;
-- khi máu về 0, đống xu vỡ và trao số xu tương ứng với giá trị của nó
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()
	-- Vài giây sau, một đống xu mới xuất hiện ở cùng vị trí
	task.delay(Settings.RespawnTime, spawnPile, spot)
end

-- Mỗi vị trí trong Meadow có một đống xu
for _, spot in workspace.Zones.Meadow.Spawns:GetChildren() do
	spawnPile(spot)
end

-- Client yêu cầu đánh đống xu. Đừng tin client: bất kỳ ai cũng có thể kích hoạt
-- remote này với dữ liệu bất kỳ, từ bất kỳ đâu, nhanh tùy ý.
remotes.Hit.OnServerEvent:Connect(function(player, pile)
	-- đống xu có thật
	if typeof(pile) ~= "Instance" or pile.Parent ~= piles then
		return
	end
	-- trong tầm với
	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
	-- không quá nhanh
	local now = time()
	if lastHit[player] and now - lastHit[player] < Settings.HitCooldown then
		return
	end
	lastHit[player] = now
	hitPile(player, pile)
end)

-- Quay ngẫu nhiên theo trọng số: Chance của mỗi thú cưng là phần tương ứng trong tổng 100
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

-- Ấp trứng: dùng lời nhắc của quả trứng và trả bằng xu
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()
	-- xuất hiện ngay và đi theo chủ
	givePet(player, name, true)
	print(player.Name .. " hatched a " .. name)
end)

-- Thú cưng được mang ra sẽ đi theo chủ: mỗi con có một bộ phận trong thế giới, luôn ở
-- phía sau người chơi trong mỗi khung hình
local petModels = {} -- mỗi thú cưng -> bộ phận tương ứng trong thế giới
RunService.Heartbeat:Connect(function()
	for _, player in Players:GetPlayers() do
		local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		local pets = player:FindFirstChild("Pets")
		for _, pet in pets and pets:GetChildren() or {} do
			local model = petModels[pet]
			if pet:GetAttribute("Equipped") and root then
				if not model then
					model = ServerStorage.PetModels[pet.Value]:Clone()
					model.Parent = petParts
					petModels[pet] = model
				end
				model.CFrame = root.CFrame * CFrame.new(0, -1.5, 4)
			end
		end
	end
end)

Tất cả bài học trong Trò chơi Roblox: mô phỏng thú cưng

Tự luyện tập: Playground Roblox