الأحزمة الناقلة
الدرس 7 من 18 في دورة لعبة Roblox: البرج اللانهائي على Coddy.
تحتوي مرحلة Conveyor على حزام داكن، موسوم بـ Conveyor، يدفعك إلى الخلف من حيث أتيت. الجزء المثبّت لا يتحرك أبدًا، لكن أعطه AssemblyLinearVelocity وسيُحمَل كل ما يقف عليه معه، كما يحدث على حزام حقيقي.
في أي اتجاه؟ لكل جزء واجهة، ويمثل part.CFrame.LookVector متجهًا من النوع Vector3 بطول وحدة واحدة يشير إلى الخارج منه. أُدير الحزام بحيث تواجه واجهته الجزء الخلفي من الممشى:
part.AssemblyLinearVelocity = part.CFrame.LookVector * Settings.BeltSpeedيعني استخدام اتجاه الجزء نفسه أن بإمكان المنشئ تدوير الحزام ليواجه أي اتجاه وسيظل يعمل، دون تغيير النص البرمجي.
التحدي
متوسطفي setupStage، امنح كل جزء يحمل الوسم Conveyor قيمة AssemblyLinearVelocity تساوي CFrame.LookVector مضروبة في Settings.BeltSpeed.
اضغط على 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
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()
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.