اطلب من الخادم
الدرس 6 من 25 في دورة لعبة Roblox: ساحة القتال على Coddy.
تبدأ القدرات على جهاز اللاعب. BattleClient هو LocalScript داخل HUD. يربط ContextActionService إجراءً بالمفاتيح، ومع true بوصفها الوسيطة الثالثة، يضيف أيضًا زرًا لهذا الإجراء على شاشة الهاتف:
ContextActionService:BindAction("Wave", use, true, Enum.KeyCode.T)تتلقى الدالة اسم الإجراء وحالة الإدخال، وهي Begin عندما يُضغط المفتاح. يتحكم الخادم بالقواعد، لذا لا يطلب العميل سوى تنفيذها عبر RemoteEvent Remotes.Ability. على الخادم، يستقبل OnServerEvent الحدث، ويمرر Roblox اللاعب الذي أطلقه أولًا:
remotes.Ability.OnServerEvent:Connect(function(player, name)
print(name .. " from " .. player.Name)
end)التحدي
متوسطاجعل Q يطلب من الخادم تنفيذ اندفاع.
- في
BattleClient، اكتبuse(name, state): عندEnum.UserInputState.Begin، استدعِremotes.Ability:FireServer(name). - اربطه:
ContextActionService:BindAction("Dash", use, true, Enum.KeyCode.Q). - في
BattleServer، اربطremotes.Ability.OnServerEventبـprint(player.Name .. " asked for " .. name).
اضغط «العب» ثم اضغط Q: سيظهر في نافذة الإخراج Player1 asked for Dash. ثم اضغط «تحقق».
جرّب بنفسك
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)
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
-- يحصل كل لاعب على سيف في كل حياة
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