Menu
CoddyTech

Hiển thị thời gian chờ

Bài học 9 trên 25 trong khóa học Trò chơi Roblox: Đấu trường của Coddy.

Người chơi cần biết khi nào một kỹ năng sẵn sàng. HUD có một khung Cooldowns với một nhãn cho mỗi kỹ năng, và máy chủ đã lưu DashReadyAt trên người chơi để client có thể đọc.

Thời gian đếm ngược thay đổi theo từng khung hình, nên client vẽ lại nội dung trên RunService.Heartbeat, sự kiện này chạy một lần mỗi khung hình. string.format giữ lại một chữ số thập phân:

string.format("%s %.1f", "Dash", 2.345) --> "Dash 2.3"

Client chỉ hiển thị thời gian hồi chiêu. Phần kiểm tra của máy chủ từ bài học trước vẫn quyết định.

challenge icon

Thử thách

Trung bình

Hiển thị thời gian hồi chiêu của từng kỹ năng trên HUD.

  1. Trong BattleClient: RunService và local hud = script.Parent.
  2. Ở mỗi RunService.Heartbeat, với từng name trong local shown = { "Dash" }: left = (me:GetAttribute(name .. "ReadyAt") or 0) - workspace:GetServerTimeNow().
  3. Đặt hud.Cooldowns[name].Text thành string.format("%s %.1f", name, left) khi left > 0, nếu không thì đặt thành name .. " ready".

Nhấn Chơi rồi nhấn Q: nhãn đếm ngược đến Dash ready. 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 lastSwing = {} -- player -> thời điểm vung kiếm gần nhất

-- Hoạt ảnh vung kiếm có sẵn của Roblox
local slash = Instance.new("Animation")
slash.AnimationId = "rbxassetid://522635514"

print("Swords deal " .. Settings.SwordDamage .. " damage")

-- Một lần vung kiếm: chạy hoạt ảnh, rồi đánh trúng mọi người trong vùng phía trước bạn
local function swing(player)
	local character = player.Character
	local root = character and character:FindFirstChild("HumanoidRootPart")
	if not root or character.Humanoid.Health <= 0 then
		return
	end
	local now = time()
	if lastSwing[player] and now - lastSwing[player] < Settings.SwingCooldown then
		return
	end
	lastSwing[player] = now
	character.Humanoid.Animator:LoadAnimation(slash):Play()
	-- Vùng phía trước bạn, không bao gồm cơ thể bạn
	local params = OverlapParams.new()
	params.FilterDescendantsInstances = { character }
	local box = root.CFrame * CFrame.new(0, 0, -3)
	local hit = {} -- Mỗi humanoid chỉ trúng đòn một lần trong mỗi lần vung kiếm
	for _, part in workspace:GetPartBoundsInBox(box, Settings.HitboxSize, params) do
		local humanoid = part.Parent:FindFirstChildOfClass("Humanoid")
		if humanoid and not hit[humanoid] then
			hit[humanoid] = true
			humanoid:TakeDamage(Settings.SwordDamage)
			print(humanoid.Parent.Name .. " is at " .. humanoid.Health)
		end
	end
end

-- Các kỹ năng theo tên và tác dụng của từng kỹ năng
local abilities = {}

-- Thiết bị của người chơi điều khiển nhân vật, nên thao tác lướt diễn ra trên thiết bị đó
function abilities.Dash(player)
	remotes.Ability:FireClient(player, "Dash")
end

-- Máy khách yêu cầu kỹ năng theo tên. Máy chủ kiểm tra: kỹ năng có tồn tại,
-- người chơi còn sống và thời gian hồi chiêu đã hết. Thời điểm kỹ năng sẵn sàng trở lại
-- là một thuộc tính của người chơi, để màn hình của họ có thể hiển thị.
remotes.Ability.OnServerEvent:Connect(function(player, name)
	if typeof(name) ~= "string" or not abilities[name] then
		return
	end
	local character = player.Character
	local root = character and character:FindFirstChild("HumanoidRootPart")
	if not root or character.Humanoid.Health <= 0 then
		return
	end
	local now = workspace:GetServerTimeNow()
	if now < (player:GetAttribute(name .. "ReadyAt") or 0) then
		return
	end
	player:SetAttribute(name .. "ReadyAt", now + Settings.Cooldowns[name])
	abilities[name](player, character, root)
end)

-- Mỗi lần hồi sinh, người chơi nhận một thanh kiếm
Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function()
		local sword = ServerStorage.Sword:Clone()
		sword.Parent = player.Backpack
		sword.Activated:Connect(function()
			swing(player)
		end)
	end)
end)

-- Hình nộm tập luyện: thanh máu thay đổi theo lượng máu, và khi bị đánh bại,
-- Hình nộm xuất hiện lại sau chốc lát, với bản sao mới ở đúng vị trí cũ
local function setupDummy(dummy)
	local humanoid = dummy.Humanoid
	humanoid.HealthChanged:Connect(function(health)
		dummy.HealthBar.Back.Fill.Size = UDim2.fromScale(health / humanoid.MaxHealth, 1)
	end)
	humanoid.Died:Connect(function()
		local spot = dummy:GetPivot()
		task.wait(0.5)
		dummy:Destroy()
		task.wait(Settings.DummyRespawn)
		local fresh = ServerStorage.Dummy:Clone()
		fresh:PivotTo(spot)
		fresh.Parent = workspace
		setupDummy(fresh)
	end)
end
setupDummy(workspace.Dummy)
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Trò chơi Roblox: Đấu trường

Tự luyện tập: Playground Roblox