Menu
CoddyTech

点击破坏

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 这一行都要删除:用远程事件替代它们。

challenge icon

挑战

中等

通过 RemoteEvent 将点击发送到服务器。

  1. 在 PetClient 中:local remotes = game.ReplicatedStorage:WaitForChild("Remotes");local mouse = me:GetMouse();当 mouse.Button1Down 触发时,如果目标名称是 CoinPile,就将 mouse.Target 通过 remotes.Hit 发送出去。
  2. 在 PetServer 中:local remotes = game.ReplicatedStorage.Remotes;remotes.Hit.OnServerEvent 会调用 hitPile(player, pile)。
  3. 删除 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 在线编辑器