孵化一颗蛋
Coddy Roblox 游戏:宠物模拟器 课程的第 9 课,共 20 课。
出生点附近的白色蛋有一个 ProximityPrompt:走到它旁边,Roblox 就会显示“孵化”,并提示你按住一个键(E,或在手机上轻触)。当玩家按住的时间足够长时,提示会在服务器上触发 Triggered,并传入玩家:
workspace.Egg.ProximityPrompt.Triggered:Connect(function(player)
end)服务器会检查价格、扣除金币并送给玩家一只宠物。宠物是一个保存其名称的 StringValue,位于玩家内部的 Pets 文件夹中。服务器放入玩家对象中的所有内容都会复制到该玩家的客户端,这样后续课程中的宠物列表就知道要显示什么了。
挑战
中等在蛋旁花费 25 枚金币孵化一只猫。
- 在
PlayerAdded中,向玩家添加一个名为Pets的文件夹。 - 编写
givePet(player, name):在 Pets 中创建一个名为Pet、值为name的 StringValue,并返回它。 - 当
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 在线编辑器