Menu
CoddyTech
flag Ar iconالعربيةdown icon

عرض فترة الانتظار

الدرس 8 من 20 في دورة لعبة Roblox: ساحات القتال على Coddy.

ينبغي أن يرى اللاعب متى تصبح القدرة جاهزة. تحتوي واجهة HUD على إطار Cooldowns مع تسمية لكل قدرة، ويحتفظ الخادم بالفعل بـ DashReadyAt على اللاعب، حيث يمكن للعميل قراءته.

يتغير العد التنازلي مع كل إطار، لذلك يعيد العميل رسمه عند RunService.Heartbeat، الذي يُطلَق مرة واحدة في كل إطار. تحافظ string.format على منزلة عشرية واحدة:

string.format("%s %.1f", "Dash", 2.345) --> "Dash 2.3"

يعرض العميل فترة الانتظار فقط. أما التحقق الذي يجريه الخادم من الدرس السابق، فيظل هو الذي يحسم الأمر.

challenge icon

التحدي

متوسط

في BattleClient، احصل على RunService وlocal me = Players.LocalPlayer وlocal hud = script.Parent. عند كل Heartbeat، ولكل اسم في local shown = { "Dash" }، عيّن hud.Cooldowns[name].Text إلى Dash 2.3 أثناء فترة التهدئة، وإلى Dash ready عندما يصبح جاهزًا.

اضغط Play، ثم اضغط Q وراقب التسمية. بعد ذلك اضغط 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)
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس لعبة Roblox: ساحات القتال