الدوّار
الدرس 5 من 18 في دورة لعبة Roblox: البرج اللانهائي على Coddy.
تحتوي مرحلة Spinner على ذراع حمراء تمرّ عبر الممر. وهو Model يحمل الوسم Spinner، ومحوره هو مركزه. يؤدي تدوير Model بالكامل قليلًا في كل إطار إلى جعله يدور.
يُطلَق RunService.Heartbeat مرة واحدة في كل إطار، ويمرّر dt، وهو عدد الثواني منذ الإطار السابق (حوالي 1/60). يؤدي التدوير بمقدار speed * dt في كل إطار إلى إضافة ما يصل إلى speed كل ثانية، مهما كانت سرعة تشغيل اللعبة.
CFrame هو موضع بالإضافة إلى دوران. يؤدي الضرب في CFrame.Angles إلى تدويره، والزوايا بوحدة الراديان، لذا حوّل الدرجات باستخدام math.rad:
spinner:PivotTo(spinner:GetPivot() * CFrame.Angles(0, math.rad(90) * dt, 0))تسرد CollectionService:GetTagged("Spinner") كل ما يحمل هذا الوسم، بما في ذلك القوالب في ServerStorage، لذا لا تدوّر إلا العناصر الموجودة في مساحة العمل. يحمل الذراع الوسم Kill، لذا فهو ينهي حياةً بالفعل. في هذا الدرس، كل مرحلة هي Spinner.
التحدي
متوسط- بالقرب من أعلى النص، احصل على
CollectionServiceوRunServiceباستخدامgame:GetService. - اربط
RunService.Heartbeat. في كل إطار، ولكل Model يحمل الوسمSpinnerوموجود في مساحة العمل، حرّكه حول محوره باستخدامCFrame.Angles(0, math.rad(Settings.SpinSpeed) * dt, 0).
اضغط Play واضبط توقيت ركضك لتجاوز الذراع، أو اقفز فوقه. ثم اضغط Check.
جرّب بنفسك
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
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 setupStage(stage)
for _, part in stage:GetDescendants() do
if part:HasTag("Kill") then
part.Touched:Connect(killOnTouch)
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()
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.