Menu
CoddyTech

孵化一颗蛋

Coddy Roblox 游戏:宠物模拟器 课程的第 9 课,共 20 课。

出生点附近的白色蛋有一个 ProximityPrompt:走到它旁边,Roblox 就会显示“孵化”,并提示你按住一个键(E,或在手机上轻触)。当玩家按住的时间足够长时,提示会在服务器上触发 Triggered,并传入玩家:

workspace.Egg.ProximityPrompt.Triggered:Connect(function(player)
end)

服务器会检查价格、扣除金币并送给玩家一只宠物。宠物是一个保存其名称的 StringValue,位于玩家内部的 Pets 文件夹中。服务器放入玩家对象中的所有内容都会复制到该玩家的客户端,这样后续课程中的宠物列表就知道要显示什么了。

challenge icon

挑战

中等

在蛋旁花费 25 枚金币孵化一只猫。

  1. 在 PlayerAdded 中,向玩家添加一个名为 Pets 的文件夹。
  2. 编写 givePet(player, name):在 Pets 中创建一个名为 Pet、值为 name 的 StringValue,并返回它。
  3. 当 workspace.Egg.ProximityPrompt.Triggered 触发时:如果金币不少于 Settings.EggPrice,就扣除这些金币,调用 givePet(player, "Cat"),并打印 player.Name .. " hatched a Cat"。

按“开始”,赚取 25 枚金币,然后在蛋旁按住 E:金币会减少 25 枚。然后按“检查”。

亲手试试

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 = {} -- 每个金币堆对应它所在的位置
local lastHit = {} -- 每个玩家对应上次击打的时间

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

-- 每个玩家的排行榜上都有 Coins
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
end)

-- 位置上的金币堆:ServerStorage.CoinPile 的副本,生命值
-- 和值都存为属性
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

-- 每次击打让金币堆的生命值减少 1;
-- 降到 0 时,金币堆会破碎,并发放对应的金币
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()
	-- 几秒后,在同一位置生成新的金币堆
	task.delay(Settings.RespawnTime, spawnPile, spot)
end

-- Meadow 的每个位置都有一个金币堆
for _, spot in workspace.Zones.Meadow.Spawns:GetChildren() do
	spawnPile(spot)
end

-- 客户端请求击打金币堆。绝不能信任客户端:任何人都能
-- 从任何地方,用任何内容,以任意频率触发这个远程事件。
remotes.Hit.OnServerEvent:Connect(function(player, pile)
	-- 确实是金币堆
	if typeof(pile) ~= "Instance" or pile.Parent ~= piles then
		return
	end
	-- 在可触及范围内
	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
	-- 操作不能太快
	local now = time()
	if lastHit[player] and now - lastHit[player] < Settings.HitCooldown then
		return
	end
	lastHit[player] = now
	hitPile(player, pile)
end)

-- 第 9 课:在这里添加 Hatch an Egg 的代码

Roblox 游戏:宠物模拟器中的所有课

自己练习: Roblox 在线编辑器