الليزر المنزلق
الدرس 8 من 18 في دورة لعبة Roblox: البرج اللانهائي على Coddy.
تحتوي مرحلة Lasers على جدارين أحمرين، يحملان الوسمين Slider وKill، وينزلقان عبر الممر ثم يعودان. يحمل كل منهما سمةً هي Slide، وهي قيمة من نوع Vector3 تحدد المكان الذي ينتقل إليه انطلاقًا من موضعه.
يمكن تكرار الحركة الانتقالية. تأخذ TweenInfo.new الزمن، ونمط التيسير، والاتجاه، وعدد مرات التكرار (-1 يعني إلى الأبد)، وما إذا كان التشغيل سيُعكس:
local info = TweenInfo.new(2.5, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, -1, true)
TweenService:Create(part, info, { Position = part.Position + part:GetAttribute("Slide") }):Play()يحافظ Linear على سرعة ثابتة، ما يتيح للاعب تقديرها. أما نمط التيسير الافتراضي فيبطئ عند كل طرف، فيبدو سلسًا لكن يصعب توقيت الحركة.
التحدي
متوسط- بالقرب من الأعلى، احصل على
TweenService. - اكتب
makeSlide(part): حرّك Position للجزء إلى Position زائد السمةSlideالخاصة به، واستغرق في ذلكSettings.SlideTimeثانية، بأسلوب Linear، مع التكرار إلى الأبد والعكس. - في
setupStage، استدعِها لكل جزء يحمل الوسمSlider.
اضغط على Play وتجاوز أشعة الليزر. ثم اضغط على Check.
جرّب بنفسك
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local Settings = require(game.ReplicatedStorage.Settings)
local stages = ServerStorage.Stages
local tower = nil
print("Each tower has " .. Settings.StageCount .. " stages")
-- يحصل كل لاعب على Wins في لوحة المتصدرين
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local wins = Instance.new("IntValue")
wins.Name = "Wins"
wins.Parent = leaderstats
end)
-- أي شيء يحمل الوسم Kill ينهي حياة اللاعب
local function killOnTouch(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid then
humanoid.Health = 0
end
end
-- تتلاشى الخطوة المختفية بعد وقت قصير من هبوط أحدهم عليها، ثم تعود
local function makeVanish(part)
part.Touched:Connect(function(hit)
if part:GetAttribute("Gone") or not hit.Parent:FindFirstChild("Humanoid") then
return
end
part:SetAttribute("Gone", true)
task.wait(Settings.VanishDelay)
part.Transparency = 0.8
part.CanCollide = false
task.wait(Settings.VanishTime)
part.Transparency = 0
part.CanCollide = true
part:SetAttribute("Gone", nil)
end)
end
-- تدور العناصر الدوّارة قليلًا في كل إطار
RunService.Heartbeat:Connect(function(dt)
for _, spinner in CollectionService:GetTagged("Spinner") do
if spinner:IsDescendantOf(workspace) then
spinner:PivotTo(spinner:GetPivot() * CFrame.Angles(0, math.rad(Settings.SpinSpeed) * dt, 0))
end
end
end)
-- فعّل كل عقبة في المرحلة وفقًا لوسومها
local function setupStage(stage)
for _, part in stage:GetDescendants() do
if part:HasTag("Kill") then
part.Touched:Connect(killOnTouch)
end
if part:HasTag("Vanish") then
makeVanish(part)
end
if part:HasTag("Conveyor") then
part.AssemblyLinearVelocity = part.CFrame.LookVector * Settings.BeltSpeed
end
end
end
-- اختر مرحلة عشوائيًا
local function pickStage()
local all = stages:GetChildren()
return all[math.random(1, #all)]
end
-- ضع نسخة من نموذج فوق البرج؛ وأعِد النسخة والقمة الجديدة
local function stack(template, bottom)
local copy = template:Clone()
local box, size = copy:GetBoundingBox()
local lift = bottom - (box.Position.Y - size.Y / 2)
copy:PivotTo(copy:GetPivot() + Vector3.new(0, lift, 0))
copy.Parent = tower
return copy, bottom + size.Y
end
-- ابنِ برجًا عشوائيًا جديدًا من الأسفل إلى الأعلى
local function buildTower()
tower = Instance.new("Model")
tower.Name = "Tower"
tower.Parent = workspace
local top = 0
for i = 1, Settings.StageCount do
local stage, newTop = stack(pickStage(), top)
top = newTop
setupStage(stage)
end
stack(ServerStorage.Finish, top)
end
buildTower()
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.