Menu
CoddyTech

Thú cưng đi theo bạn

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

Thú cưng sẽ đi theo bạn. Thú cưng vừa nở ra sẽ xuất hiện ngay, có thuộc tính Equipped và có một bộ phận trong thế giới: bản sao mô hình của nó từ ServerStorage.PetModels.

Mỗi khung hình, máy chủ đặt bộ phận đó phía sau chủ nhân. RunService.Heartbeat chạy một lần mỗi khung hình, còn phép nhân CFrame đặt một vị trí tương đối với vị trí khác:

part.CFrame = root.CFrame * CFrame.new(0, 2, 6) -- lùi 6 stud, lên 2 stud

Một bảng dùng thú cưng làm khóa sẽ ghi nhớ bộ phận của nó, vì vậy mỗi thú cưng có một bộ phận được tạo một lần:

if not petModels[pet] then
	petModels[pet] = ServerStorage.PetModels[pet.Value]:Clone()
	petModels[pet].Parent = petParts
end
challenge icon

Thử thách

Trung bình

Thú cưng mới nở sẽ đi theo bạn.

  1. Thêm đối số thứ ba equipped vào givePet, lưu đối số này thành thuộc tính Equipped; khi thú cưng nở, gọi givePet(player, name, true).
  2. Thêm RunService, local petParts = workspace.PetParts, local petModels = {}.
  3. Trong sự kiện RunService.Heartbeat, tạo một bản sao của ServerStorage.PetModels[pet.Value] trong petParts cho mỗi thú cưng có thuộc tính Equipped (lưu trong petModels[pet]) và đặt CFrame của bản sao thành root.CFrame * CFrame.new(0, -1.5, 4).

Nhấn Chơi, cho thú cưng nở rồi đi bộ: thú cưng sẽ đi theo bạn. Sau đó nhấn Kiểm tra.

Tự làm thử

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 = {} -- mỗi đống xu -> vị trí của đống xu đó
local lastHit = {} -- mỗi người chơi -> thời điểm họ đánh lần cuối

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

-- Settings.Pets 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 thú cưng, với
-- độ hiếm và sức mạnh là các thuộc tính
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

-- Mỗi người chơi đều 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, với lượng máu
-- và giá trị là các 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 còn 0, đống xu vỡ và người chơi nhận được 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 tại 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 vào một đố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 cứ đâ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)

-- Chọn ngẫu nhiên theo trọng số: Chance của mỗi thú cưng (trên 100) là phần cơ hội của nó
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()
	givePet(player, name)
	print(player.Name .. " hatched a " .. name)
end)

-- Bài học 11: Thú cưng đi theo bạn sẽ nằm ở đây

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