Menu
CoddyTech

اطلب من الخادم

الدرس 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)
challenge icon

التحدي

متوسط

اجعل Q يطلب من الخادم تنفيذ اندفاع.

  1. في BattleClient، اكتب use(name, state): عند Enum.UserInputState.Begin، استدعِ remotes.Ability:FireServer(name).
  2. اربطه: ContextActionService:BindAction("Dash", use, true, Enum.KeyCode.Q).
  3. في 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