اندفع عند Q
الدرس 7 من 25 في دورة لعبة Roblox: ساحة القتال على Coddy.
الاندفاع دفعة: إن ضبط AssemblyLinearVelocity للجذر يقذف الشخصية. لكن Roblox يتيح لجهاز كل لاعب تشغيل فيزياء شخصيته، لذا فإن الدفعة التي يضبطها الخادم لا تحركه إلا قليلًا. الخادم هو من يقرر، بينما تنفذ LocalScript الخاصة باللاعب الدفعة.
يحتفظ الخادم بقدراته في جدول، حسب الاسم، وعند الموافقة على الاندفاع تُرسل الموافقة إلى عميل ذلك اللاعب باستخدام FireClient، حيث يستقبلها OnClientEvent:
remotes.Ability.OnClientEvent:Connect(function(name)
if name == "Hop" then
root.AssemblyLinearVelocity = Vector3.new(0, 50, 0)
end
end)التحدي
متوسطاجعل الاندفاع على Q: يوافق الخادم، فيدفع جهازك شخصيتك.
- في
BattleServer، استبدل الطباعة بجدولabilities: يستدعيabilities.Dash(player)الدالةremotes.Ability:FireClient(player, "Dash"). - يستدعي المعالج
abilities[name](player, character, root)عند وجودها. - في
BattleClient، عندremotes.Ability.OnClientEventمع"Dash"، اضبط سرعة الجذر علىroot.CFrame.LookVector * Settings.DashSpeed + Vector3.new(0, 15, 0).
اضغط «العب» ثم اضغط Q: ستندفع إلى الأمام. ثم اضغط «تحقق».
جرّب بنفسك
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)
print(humanoid.Parent.Name .. " is at " .. humanoid.Health)
end
end
end
-- يطلب العميل قدرةً باسمها
remotes.Ability.OnServerEvent:Connect(function(player, name)
print(player.Name .. " asked for " .. name)
end)
-- يحصل كل لاعب على سيف في كل حياة
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)
-- دمية التدريب: يتبع شريط صحتها مستوى صحتها، وإذا هُزمت
-- تعود الدمية بعد لحظة، بنسخة جديدة في المكان نفسه
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)
جميع دروس لعبة Roblox: ساحة القتال
تدرّب بنفسك: Playground لـ Roblox