Angka Kerusakan
Pelajaran 13 dari 20 dalam kursus Game Roblox: Battlegrounds di Coddy.
Serangan harus menunjukkan seberapa besar dampaknya: sebuah angka yang muncul di atas target lalu menghilang sesaat kemudian. Angka ini adalah BillboardGui dengan TextLabel, yang dipasang pada root target, dan Debris menghapusnya setelah 0.8 detik tanpa menghambat game:
Debris:AddItem(tag, 0.8)Tambahkan ini di hurt, setelah aturan pemblokiran, agar serangan yang diblokir tetap menunjukkan damage yang ditimbulkannya. math.round memastikan angkanya bulat.
Tantangan
SedangTulis damageNumber(character, amount) di atas hurt: sebuah BillboardGui bernama Damage (60 kali 30, 4.5 studs di atas root, dipasang padanya) yang berisi TextLabel dengan teks -10 ("-" .. math.round(amount)), diparentkan ke character dan dihapus oleh Debris setelah 0.8 detik. Panggil fungsi ini di hurt setelah damage diberikan.
Tekan Play, lalu Periksa.
Coba sendiri
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)
local remotes = game.ReplicatedStorage.Remotes
local lastSwing = {} -- player -> waktu terakhir mereka mengayunkan pedang
local combo = {} -- player -> { jumlah serangan beruntun, waktu serangan terakhir mengenai sasaran }
-- Animasi pedang bawaan Roblox
local slash = Instance.new("Animation")
slash.AnimationId = "rbxassetid://522635514"
local lunge = Instance.new("Animation")
lunge.AnimationId = "rbxassetid://522638767"
print("Swords deal " .. Settings.SwordDamage .. " damage")
-- Setiap serangan dalam game diproses di sini
local function hurt(humanoid, amount)
if humanoid.Health <= 0 then
return
end
local character = humanoid.Parent
-- blokir menahan sebagian besar serangan
if character:GetAttribute("Blocking") then
amount *= Settings.BlockMultiplier
end
humanoid:TakeDamage(amount)
end
-- Efek stun membuat seseorang tidak bisa bergerak sesaat
local function stun(humanoid)
local character = humanoid.Parent
if character:GetAttribute("Stunned") then
return
end
character:SetAttribute("Stunned", true)
local speed = humanoid.WalkSpeed
humanoid.WalkSpeed = 0
task.delay(Settings.StunTime, function()
if character.Parent then
humanoid.WalkSpeed = speed
character:SetAttribute("Stunned", nil)
end
end)
end
-- Ayunan pedang: animasi dimainkan, lalu semua yang berada dalam kotak di depanmu terkena serangan
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
-- tiga ayunan beruntun membentuk kombo; ayunan ketiga adalah terjangan
local c = combo[player]
if c and now - c.last <= Settings.ComboWindow then
c.count = c.count % 3 + 1
else
c = { count = 1 }
combo[player] = c
end
c.last = now
local finisher = c.count == 3
character.Humanoid.Animator:LoadAnimation(finisher and lunge or slash):Play()
-- kotak di depanmu, tidak pernah mencakup tubuhmu sendiri
local params = OverlapParams.new()
params.FilterDescendantsInstances = { character }
local box = root.CFrame * CFrame.new(0, 0, -3)
local hit = {} -- setiap humanoid hanya sekali per ayunan
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
hurt(humanoid, Settings.ComboDamage[c.count])
if finisher then
stun(humanoid)
end
end
end
end
-- Kemampuan berdasarkan nama: fungsi masing-masing
local abilities = {}
function abilities.Dash(player, character, root)
root.AssemblyLinearVelocity = root.CFrame.LookVector * Settings.DashSpeed + Vector3.new(0, 15, 0)
end
-- semua orang di sekitarmu terkena serangan dan terlempar menjauh darimu
function abilities.Slam(player, character, root)
local params = OverlapParams.new()
params.FilterDescendantsInstances = { character }
local hit = {}
for _, part in workspace:GetPartBoundsInRadius(root.Position, Settings.SlamRadius, params) do
local humanoid = part.Parent:FindFirstChildOfClass("Humanoid")
local theirRoot = part.Parent:FindFirstChild("HumanoidRootPart")
if humanoid and theirRoot and not hit[humanoid] then
hit[humanoid] = true
hurt(humanoid, Settings.SlamDamage)
local away = (theirRoot.Position - root.Position) * Vector3.new(1, 0, 1)
if away.Magnitude > 0 then
away = away.Unit
end
theirRoot:ApplyImpulse((away * Settings.SlamKnockback + Vector3.new(0, 40, 0)) * theirRoot.AssemblyMass)
end
end
end
function abilities.Block(player, character)
character:SetAttribute("Blocking", true)
task.delay(Settings.BlockTime, function()
if character.Parent then
character:SetAttribute("Blocking", nil)
end
end)
end
-- client meminta kemampuan berdasarkan namanya. server memeriksa apakah kemampuannya valid,
-- pemainnya masih hidup, dan waktu tunggunya sudah berakhir. Waktu kemampuan siap kembali
-- disimpan sebagai atribut pemain agar layarnya dapat menampilkannya.
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)
-- Setiap pemain mendapat Kills di papan peringkat dan sebilah pedang setiap kali hidup.
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local kills = Instance.new("IntValue")
kills.Name = "Kills"
kills.Parent = leaderstats
player.CharacterAdded:Connect(function()
local sword = ServerStorage.Sword:Clone()
sword.Parent = player.Backpack
sword.Activated:Connect(function()
swing(player)
end)
end)
end)
-- Boneka latihan: bilah kesehatannya mengikuti kesehatannya, dan boneka yang dikalahkan
-- muncul kembali setelah beberapa saat sebagai salinan baru di tempat yang sama.
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)
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Game Roblox: Battlegrounds
Latihan sendiri: Playground Roblox