ضربة أرضية
الدرس 9 من 20 في دورة لعبة Roblox: ساحات القتال على Coddy.
قدرة ثانية، على E: ضربة أرضية ساحقة تصيب الجميع من حولك وتقذفهم بعيدًا. تعثر workspace:GetPartBoundsInRadius(position, radius, params) على الأجزاء الواقعة ضمن مسافة معينة، ويمنح ApplyImpulse على الجزء الجذري الجسم كله دفعة. الدفع اللحظي هو التغير في السرعة مضروبًا في الكتلة، لذا فإن الضرب في AssemblyMass يقذف الهياكل الخفيفة والثقيلة بالطريقة نفسها:
theirRoot:ApplyImpulse((away * Settings.SlamKnockback + Vector3.new(0, 40, 0)) * theirRoot.AssemblyMass)أصبح لدى اللعبة الآن طريقتان لإيذاء شخص ما، وهناك المزيد في الطريق. تمر كل ضربة عبر دالة واحدة، hurt(humanoid, amount)، لذا تُكتب قاعدة الضرر (الصدّ، في الدرس التالي) مرة واحدة.
التحدي
متوسط- اكتب
hurt(humanoid, amount)فوقswing: أعد التنفيذ إذا كان الـ Humanoid مهزومًا بالفعل، وإلا فاستدعِTakeDamage(amount). اجعلswingيستدعيها. - أضف
abilities.Slam: كل من يوجد لديه جزء جذر ضمنSettings.SlamRadius(مرة واحدة لكل شخص، وليس أنت) يتلقىSettings.SlamDamageعبرhurt، ويُدفَع بعيدًا عنك باستخدامSettings.SlamKnockbackودفعة للأعلى بمقدار 40. - في
BattleClient، اربط"Slam"بالمفتاح E، وأضفه إلى عرض وقت التهدئة.
اضغط Play، ثم Check.
جرّب بنفسك
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)
local remotes = game.ReplicatedStorage.Remotes
local lastSwing = {} -- player -> وقت آخر ضربة سيف نفّذها
-- حركات السيف الخاصة بـ Roblox
local slash = Instance.new("Animation")
slash.AnimationId = "rbxassetid://522635514"
print("Swords deal " .. Settings.SwordDamage .. " damage")
-- ضربة سيف: تُشغَّل الحركة، ثم يُصاب كل من في الصندوق أمامك
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()
-- الصندوق أمامك، ولا يشمل جسدك أبدًا
local params = OverlapParams.new()
params.FilterDescendantsInstances = { character }
local box = root.CFrame * CFrame.new(0, 0, -3)
local hit = {} -- كل humanoid مرة واحدة في كل ضربة سيف
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)
end
end
end
-- القدرات حسب أسمائها: ما تفعله كل واحدة
local abilities = {}
function abilities.Dash(player, character, root)
root.AssemblyLinearVelocity = root.CFrame.LookVector * Settings.DashSpeed + Vector3.new(0, 15, 0)
end
-- يطلب العميل قدرةً باسمها. يتحقق الخادم من أنها قدرة
-- موجودة، وأن اللاعب على قيد الحياة، وأن فترة انتظارها قد انتهت. وقت جاهزيتها مجددًا
-- هو سمة للاعب، حتى تتمكن شاشته من عرضه.
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)
-- يحصل كل لاعب على Kills في لوحة الصدارة، وعلى سيف في كل حياة
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)
-- دمية التدريب: يتغير شريط صحتها تبعًا لصحتها، وإذا هُزمت
-- تعود بعد قليل بنسخة جديدة في المكان نفسه
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)
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.