Menu
CoddyTech

Nện xuống đất

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

Một kỹ năng thứ hai, dùng phím E: cú đập đất đánh trúng mọi người xung quanh bạn. workspace:GetPartBoundsInRadius(position, radius, params) tìm các bộ phận nằm trong một khoảng cách nhất định từ một điểm, giống như vùng hình hộp của cú vung nhưng có dạng tròn:

for _, part in workspace:GetPartBoundsInRadius(root.Position, 6, params) do

Giờ đây, trò chơi có hai cách gây sát thương cho ai đó, và sắp tới sẽ có thêm nhiều cách nữa. Mọi cú đánh đều thông qua một hàm duy nhất, hurt(humanoid, amount), nên quy tắc về sát thương (chặn đòn, sắp có) chỉ cần viết một lần. Hàm này cũng không tác động đến Humanoid đã bị hạ gục.

challenge icon

Thử thách

Trung bình

Thêm đòn đập đất bằng phím E.

  1. Phía trên swing, viết hurt(humanoid, amount): gọi TakeDamage(amount) nếu Health khác 0. Swing gọi hàm này thay vì TakeDamage và lệnh in ra.
  2. Thêm abilities.Slam(player, character, root): mỗi Humanoid (chỉ một lần, không phải của bạn) trong GetPartBoundsInRadius(root.Position, Settings.SlamRadius, params) sẽ nhận hurt(humanoid, Settings.SlamDamage).
  3. Trong BattleClient, gắn "Slam" với phím E và thêm nó vào shown.

Nhấn Chơi rồi nhấn E cạnh hình nộm: thanh máu của nó giảm. 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 = {} -- người chơi -> thời điểm vung kiếm gần nhất

-- Các hoạt ảnh vung kiếm 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: phát 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 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

-- Bài học 10: thêm Ground Slam vào đây

-- Máy khách yêu cầu một kỹ năng bằng 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ó 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 người chơi nhận một thanh kiếm mỗi khi nhân vật xuất hiện
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 còn lại. Khi bị đánh bại,
-- hình nộm sẽ xuất hiện lại sau chốc lát dưới dạng bản sao mới ở cùng vị trí
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)

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

Tự luyện tập: Playground Roblox