点击破坏
Coddy Roblox 游戏:宠物模拟器 课程的第 6 课,共 20 课。
按钮用 ClickDetector 没问题,但大多数模拟器会在客户端读取点击,因此你点击时游戏就能立即做出反应(播放声音、抖动),不用等服务器响应。客户端的鼠标知道你点击了什么:
local mouse = me:GetMouse()
mouse.Button1Down:Connect(function()
print(mouse.Target) -- 点击位置下的部件,或者 nil
end)客户端不能自行打碎一堆物品:这些物品和金币都由服务器管理。客户端通过 RemoteEvent 向服务器发出请求。RemoteEvent 是专门用于客户端和服务器之间传递消息的对象:
-- 客户端
remotes.Hit:FireServer(pile)
-- 服务器:Roblox 会把发送请求的玩家作为第一个参数
remotes.Hit.OnServerEvent:Connect(function(player, pile)
end)远程事件会稍后才到达,就像消息通过网络传输一样。在手机上,轻点和点击的效果相同。ClickDetector 和第 3 课中的 local hitPile 这一行都要删除:用远程事件替代它们。
挑战
中等通过 RemoteEvent 将点击发送到服务器。
- 在
PetClient中:local remotes = game.ReplicatedStorage:WaitForChild("Remotes");local mouse = me:GetMouse();当mouse.Button1Down触发时,如果目标名称是CoinPile,就将mouse.Target通过remotes.Hit发送出去。 - 在
PetServer中:local remotes = game.ReplicatedStorage.Remotes;remotes.Hit.OnServerEvent会调用hitPile(player, pile)。 - 删除 ClickDetector 相关代码行和
local hitPile;改写为local function hitPile。
按下“开始”并点击一堆金币:它会像之前一样破碎。然后点击“检查”。
亲手试试
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)
local piles = workspace.Piles
local pileSpot = {} -- 每个钱币堆对应它所在的位置
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)
-- 点击钱币堆时需要用到 hitPile,它写在 spawnPile 后面:先在
-- 这里声明它,再定义这两个函数
local hitPile
-- 位置上的钱币堆: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)
-- 点击钱币堆即可击打它
local detector = Instance.new("ClickDetector")
detector.Parent = pile
pileSpot[pile] = spot
pile.Parent = piles
detector.MouseClick:Connect(function(player)
hitPile(player, pile)
end)
return pile
end
-- 每次击打都会让钱币堆的生命值减少 1;
-- 降到 0 时,钱币堆破碎,玩家获得它对应的值
function hitPile(player, pile)
local health = pile:GetAttribute("Health") - 1
if health > 0 then
pile:SetAttribute("Health", health)
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
Roblox 游戏:宠物模拟器中的所有课
自己练习: Roblox 在线编辑器