جولة تلو الأخرى
الدرس 14 من 18 في دورة لعبة Roblox: البرج اللانهائي على Coddy.
الجولة الواحدة عرض توضيحي؛ أما اللعبة فتستمر جولة بعد جولة. ضع العد التنازلي للّوبي والجولة والعد التنازلي لها داخل while true do، وأضف endRound() لترتيب الأمور عند نفاد الوقت:
- يعود اللاعبون الذين ما زالوا على البرج إلى اللوبي،
- يُدمَّر البرج والحمم البركانية، لكي تبني الجولة التالية برجًا جديدًا مكانهما.
تزيل Destroy نسخةً وكل ما بداخلها، لذا فإن تدمير نموذج البرج يزيل جميع مراحله دفعة واحدة. لا تنتهي الحلقة أبدًا، لذا ضعها في نهاية البرنامج النصي تمامًا: لن يُنفَّذ أي شيء بعدها.
التحدي
متوسط- اكتب
endRound(): انقل كل لاعب لم ينتهِ إلى ارتفاع 4 وحدات فوقlobbySpawn، ودمّرtowerوlava، وأفرغtowerStages. - في الأسفل، ضع العد التنازلي في الردهة و
startRound()والعد التنازلي للجولة داخلwhile true do، واستدعِendRound()في نهاية كل دورة.
جولات هذا الدرس قصيرة. اضغط على Play. ثم Check.
جرّب بنفسك
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local Settings = require(game.ReplicatedStorage.Settings)
local stages = ServerStorage.Stages
local lobbySpawn = workspace.Lobby.SpawnLocation
local tower = nil
local towerStages = {}
local lava = nil
local finished = {}
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)
-- اللوحة في منطقة الانتظار
local gui = Instance.new("SurfaceGui")
gui.Parent = workspace.Lobby.Board
local boardLabel = Instance.new("TextLabel")
boardLabel.Name = "Status"
boardLabel.Size = UDim2.fromScale(1, 1)
boardLabel.BackgroundColor3 = Color3.fromRGB(25, 25, 35)
boardLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
boardLabel.TextScaled = true
boardLabel.Text = "Endless Tower"
boardLabel.Parent = gui
local function setBoard(text)
boardLabel.Text = text
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
-- ينزلق الليزر إلى موضع الإزاحة Slide ثم يعود، بلا توقف
local function makeSlide(part)
local info = TweenInfo.new(Settings.SlideTime, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, -1, true)
local goal = { Position = part.Position + part:GetAttribute("Slide") }
TweenService:Create(part, info, goal):Play()
end
-- تقذف منصة الارتداد من يهبط عليها إلى أعلى في الهواء
local function bounce(hit)
local root = hit.Parent:FindFirstChild("HumanoidRootPart")
if root then
root.AssemblyLinearVelocity = Vector3.new(0, Settings.BouncePower, 0)
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
if part:HasTag("Slider") then
makeSlide(part)
end
if part:HasTag("Bounce") then
part.Touched:Connect(bounce)
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 reachTop(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if not player or finished[player] then
return
end
finished[player] = true
player.leaderstats.Wins.Value += 1
print(player.Name .. " reached the top")
hit.Parent:PivotTo(lobbySpawn.CFrame + Vector3.new(0, 4, 0))
end
-- ابنِ برجًا عشوائيًا جديدًا من الأسفل إلى الأعلى
local function buildTower()
tower = Instance.new("Model")
tower.Name = "Tower"
tower.Parent = workspace
towerStages = {}
local top = 0
for i = 1, Settings.StageCount do
local stage, newTop = stack(pickStage(), top)
top = newTop
setupStage(stage)
towerStages[i] = stage
end
local finish = stack(ServerStorage.Finish, top)
finish.FinishPad.Touched:Connect(reachTop)
return top
end
-- ترتفع الحمم البركانية من الأرض حتى أسفل قمة البرج مباشرةً
local function startLava(top)
lava = Instance.new("Part")
lava.Name = "Lava"
lava.Anchored = true
lava.CanCollide = false
lava.Size = Vector3.new(30, 2, 30)
lava.Position = Vector3.new(0, -2, 0)
lava.Color = Color3.fromRGB(255, 90, 20)
lava.Material = Enum.Material.Neon
lava.Parent = workspace
lava.Touched:Connect(killOnTouch)
local info = TweenInfo.new(top / Settings.LavaSpeed, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, Settings.LavaDelay)
TweenService:Create(lava, info, { Position = Vector3.new(0, top - 2, 0) }):Play()
end
local function startRound()
finished = {}
local top = buildTower()
startLava(top)
for _, player in Players:GetPlayers() do
if player.Character then
player.Character:PivotTo(towerStages[1].Start.CFrame + Vector3.new(0, 4, 0))
end
end
end
-- جولة واحدة
for i = Settings.Intermission, 1, -1 do
setBoard("Next tower in " .. i)
task.wait(1)
end
startRound()
for i = Settings.RoundLength, 1, -1 do
setBoard("Climb! " .. i .. " seconds left")
task.wait(1)
end
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.