Nesting loops cho phép bạn lặp lại các tác vụ theo từng nhóm. Ví dụ, nướng ba mẻ sáu chiếc bánh cupcake, hoặc phân bổ vũ khí cho người chơi trên hai đội.
Cách thức hoạt động của vòng lặp lồng nhau
Khi các vòng lặp được lồng nhau, các script sẽ đi từng dòng mã cho đến khi gặp vòng lặp tiếp theo. Vòng lặp bên trong sẽ chạy cho đến khi điều kiện của nó được đáp ứng trước khi trở lại vòng lặp bên ngoài.
Logic vòng lặp lồng nhau
Sơ đồ dưới đây cho thấy các bước mà một vòng lặp thực hiện.
| ![]() |
Ví dụ về vòng lặp lồng nhau
Các vòng lặp lồng nhau có thể có vẻ hơi trừu tượng, vì vậy một ví dụ trực quan có thể giúp ích. Đối với bài tập này, hãy sao chép và dán một script mẫu và chạy nó trong Studio. Script này sẽ tạo ra các tháp của các phần. Vòng lặp bên ngoài sẽ điều khiển số lượng phần cần tạo, trong khi vòng lặp bên trong sẽ tạo ra mẻ thực tế.
Tạo một script mới trong ServerScriptService có tên PartMaker. Sao chép mã bên dưới.
local numberOfBatches = 7local partsPerBatch = 5local partsMade = 0-- Tạo một khối lập phương đơnlocal function createPart()local part = Instance.new("Part")part.Size = Vector3.new(2, 2, 2)part.CFrame = CFrame.new(20, 0, 20)part.Color = currentColorpart.Parent = workspaceend-- Vòng lặp ngoàifor partBatch = 1, numberOfBatches doprint("Vòng lặp ngoài: mẻ phần " .. partBatch)currentColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))-- Vòng lặp bên trongfor partNumber = 1, partsPerBatch docreatePart()print("Vòng lặp bên trong: phần " .. partNumber)partsMade += 1task.wait(0.5)endprint("Vòng lặp dưới: " .. partsMade .. " phần được tạo cho đến nay.")task.wait(2)endHãy xem script khi nó sinh ra một mẻ phần có màu sắc khác nhau. Sau khi hoàn thành một mẻ, nó sẽ dừng lại trong 2 giây. Câu lệnh in trong vòng lặp ngoài sẽ chỉ chạy một lần cho mỗi vòng lặp bên trong đã hoàn thành.
Tháp vòng lặp lồng nhau
Mỗi vòng lặp có một tập hợp các đoạn mã riêng, vì vậy chúng có thể chịu trách nhiệm cho các tác vụ khác nhau. Một điều mà các vòng lặp lồng nhau có thể làm là thay đổi vị trí mà một đối tượng xuất hiện để tạo ra một tháp giống như trong video này. Có ba vòng lặp khác nhau, một cái cho việc kiểm soát vị trí theo chiều rộng, chiều dài và chiều cao của tháp mà khối lập phương xuất hiện.
Lập trình một script tạo khối lập phương
Để thực hành vòng lặp lồng nhau, bạn sẽ tạo một script tạo ra một tháp khối lập phương. Đối với script tháp khối lập phương, trước tiên hãy lập trình một hàm tạo ra một khối lập phương duy nhất. Tháp sẽ được xây dựng bằng cách gọi hàm này nhiều lần.
Thiết lập script
Đối với script tháp khối lập phương, trước tiên hãy lập trình một hàm tạo ra một khối lập phương duy nhất. Tháp sẽ được xây dựng bằng cách gọi hàm này nhiều lần.
Xóa script PartMaker hoặc vô hiệu hóa nó (trong thuộc tính script, chọn Disabled). Nếu không làm vậy, sẽ có hai script tạo phần tại cùng một thời điểm ở cùng một vị trí.
Tạo một script mới có tên TowerBuilder. Thêm các biến cho kích thước tháp và kích thước khối lập phương ở trên cùng.
local TOWER_SIZE = 4local CUBE_SIZE = 2Thêm một hàm cục bộ có tên makeCube() tạo ra một khối lập phương vuông duy nhất bằng cách sử dụng CUBE_SIZE.
local TOWER_SIZE = 4local CUBE_SIZE = 2-- Tạo các khối lập phương riêng lẻlocal function makeCube()local cube = Instance.new("Part")cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)endĐặt màu sắc của khối lập phương vào một biến sẽ được cập nhật trong các vòng lặp lồng nhau.
local function makeCube()local cube = Instance.new("Part")cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)cube.Color = currentColorendCuối cùng, cha mẹ khối lập phương mới vào không gian làm việc để nó xuất hiện.
local function makeCube()local cube = Instance.new("Part")cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)cube.Color = currentColorcube.Parent = workspaceend
Xuất hiện theo các hướng khác nhau
Để tạo một tháp, hãy xuất hiện các khối lập phương tại các điểm cụ thể bằng cách thiết lập các thuộc tính X, Y, Z của mỗi khối lập phương mới. X và Z là chiều ngang. Y là chiều cao.
Trong makeCube(), thêm các tham số cho spawnX, spawnY, và spawnZ. Những số này sẽ thiết lập vị trí xuất hiện của mỗi khối lập phương mới.
-- Tạo các khối lập phương riêng lẻlocal function makeCube(spawnX, spawnY, spawnZ)local cube = Instance.new("Part")cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)cube.Color = currentColorcube.Parent = workspaceendBên trong hàm, đặt thuộc tính CFrame của khối lập phương sang một CFrame mới sử dụng các tham số spawnX, spawnY, spawnZ.
local function makeCube(spawnX, spawnY, spawnZ)local cube = Instance.new("Part")cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)cube.Color = currentColorcube.CFrame = CFrame.new(spawnX, spawnY, spawnZ)cube.Parent = workspaceend
Xuất hiện với vòng lặp lồng nhau
Script sẽ có tổng cộng ba vòng lặp, một cho chiều dài, một cho chiều rộng, và một cho chiều cao của tháp. Để hoàn thành một tầng đầy đủ trước khi đi lên, hãy bắt đầu với việc thiết lập tọa độ Y trong vòng lặp đầu tiên, vòng lặp ngoài cùng.
Dưới hàm makeCube(), tạo một vòng lặp for để thiết lập độ cao mà mỗi khối lập phương xuất hiện.
- Biến điều khiển: heightIndex = 1
- Điểm kết thúc: TOWER_SIZE
- Bên trong vòng lặp, thêm: local spawnY = (heightIndex - 1) * CUBE_SIZE
-- Xây dựng thápfor heightIndex = 1, TOWER_SIZE dolocal spawnY = (heightIndex - 1) * CUBE_SIZEendVới vòng lặp đầu tiên cho chiều cao đã hoàn thành, bắt đầu vào vòng lặp thứ hai. Bên trong vòng lặp for đầu tiên, thêm một vòng lặp for mới cho việc đặt vị trí của khối lập phương theo chiều dài của tháp.
- Biến điều khiển: lengthIndex = 1
- Điểm kết thúc: TOWER_SIZE
- Bên trong vòng lặp đó thêm: local spawnX = lengthIndex * CUBE_SIZE
for heightIndex = 1, TOWER_SIZE dolocal spawnY = (heightIndex - 1) * CUBE_SIZEfor lengthIndex = 1, TOWER_SIZE dolocal spawnX = lengthIndex * CUBE_SIZEendendBên trong vòng lặp thứ hai, thêm một vòng lặp for thứ ba cho chiều rộng của tháp. Trong vòng lặp cuối cùng này, gọi makeCube() và truyền vào các tham số X, Y, Z.
- Biến điều khiển: widthIndex = 1
- Điểm kết thúc: TOWER_SIZE
- Bên trong vòng lặp thêm:
- local spawnZ = widthIndex * CUBE_SIZE
- makeCube(spawnX, spawnY, spawnZ)
- Một thời gian chờ 0.25 để bạn có thể xem tháp được xây dựng.
-- Xây dựng thápfor heightIndex = 1, TOWER_SIZE dolocal spawnY = (heightIndex - 1) * CUBE_SIZEfor lengthIndex = 1, TOWER_SIZE dolocal spawnX = lengthIndex * CUBE_SIZEfor widthIndex = 1, TOWER_SIZE dolocal spawnZ = widthIndex * CUBE_SIZEmakeCube(spawnX, spawnY, spawnZ)task.wait(0.25)endendendĐể mỗi tầng có màu ngẫu nhiên, hãy thay đổi currentColor thành các số RGB ngẫu nhiên trong cùng một vòng lặp trong đó bạn tạo ra một tầng mới.
for heightIndex = 1, TOWER_SIZE dolocal spawnY = (heightIndex - 1) * CUBE_SIZEcurrentColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))for lengthIndex = 1, TOWER_SIZE dolocal spawnX = lengthIndex * CUBE_SIZEfor widthIndex = 1, TOWER_SIZE dolocal spawnZ = widthIndex * CUBE_SIZEmakeCube(spawnX, spawnY, spawnZ)task.wait(0.25)endendendChạy dự án và chờ xem một tháp hoàn chỉnh đã được tạo ra mà không có lỗi nào trong cửa sổ Output.
Thử thách tùy chọn
Dưới đây là các thử thách tự định hướng khác nhau sử dụng các vòng lặp lồng nhau theo những cách khác nhau. Hãy thử lập trình một mình trước khi xem giải pháp.
Làm mờ các phần
Khi tháp được xây dựng, hãy để các phần chuyển màu từ trái sang phải.

Giải pháp mã bên dưới.
local TOWER_SIZE = 6
local CUBE_SIZE = 2
-- Tạo các khối lập phương riêng lẻ
local function makeCube(spawnX, spawnY, spawnZ)
local cube = Instance.new("Part")
cube.Size = Vector3.new(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE)
cube.Color = currentColor
cube.Transparency = cubeTransparency -- Đặt độ trong suốt
cube.CFrame = CFrame.new(spawnX, spawnY, spawnZ)
cube.Parent = workspace
end
-- Xây dựng tháp
for heightIndex = 1, TOWER_SIZE do
local spawnY = (heightIndex - 1) * CUBE_SIZE
currentColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
for lengthIndex = 1, TOWER_SIZE do
local spawnX = lengthIndex * CUBE_SIZE
cubeTransparency = (lengthIndex - 1) * 0.10 -- Cập nhật mỗi vòng lặp bắt đầu từ 0
for widthIndex = 1, TOWER_SIZE do
local spawnZ = widthIndex * CUBE_SIZE
makeCube(spawnX, spawnY, spawnZ)
task.wait(0.05)
end
end
end
Rơi các đối tượng
Thay vì các phần, hãy thử sinh ra một đối tượng thực sự. Ví dụ ở đây sử dụng bánh cupcake.
Tự mình xem liệu bạn có thể:
- Tạo một đối tượng từ các phần cơ bản. Đảm bảo hàn tất cả các phần lại với nhau để đối tượng không bị rời ra.
- Đặt đối tượng vào ServerStorage
- Chỉnh sửa PartMaker nằm trong Ví dụ về vòng lặp lồng nhau để sử dụng đối tượng của bạn thay vì các phần.
Một mẫu được hiển thị ở đây.
Một giải pháp mã sử dụng bánh cupcake được đính kèm.
local numberOfBatches = 30
local cupcakesPerBatch = 6
local cupcakesBaked = 0
--Tạo một bánh cupcake đơn
local function makeCupcake()
local ServerStorage = game:GetService("ServerStorage")
local cupcake = ServerStorage.Cupcake:Clone()
local cup = cupcake.Cup
local frosting = cupcake.Frosting
cupcake:SetPrimaryPartCFrame(CFrame.new(0, 20, 0) * CFrame.Angles(0, 0, -90))
frosting.Color = frostingColor
cup.Color = cupColor
cupcake.Parent = workspace
end
-- Vòng lặp ngoài
for cupcakeBatch = 1, numberOfBatches do
print("Vòng lặp trên: mẻ cupcake " .. cupcakeBatch)
frostingColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
cupColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
-- Vòng lặp bên trong
for cupcakeNumber = 1, cupcakesPerBatch do
makeCupcake()
print("Vòng lặp bên trong: cupcake " .. cupcakeNumber)
-- Theo dõi số cupcake đã nướng
cupcakesBaked += 1
task.wait(0.5)
end
print("Vòng lặp dưới: " .. cupcakesBaked .. " cupcake đã được nướng cho đến nay.")
end
Tóm tắt
Để thực hiện những tác vụ phức tạp hơn, các lập trình viên sẽ thấy việc kết hợp nhiều vòng lặp, và thậm chí là các loại vòng lặp khác nhau rất hữu ích. Tất cả các vòng lặp đều có thể được lồng nhau, có nghĩa là một vòng lặp nằm bên trong vòng lặp khác. Các vòng lặp lồng nhau theo cùng một logic như bất kỳ vòng lặp nào khác. Nó bắt đầu từ vòng lặp ngoài cùng, thực hiện các tác vụ qua các vòng lặp bên trong, và sau đó quay lại vòng lặp đầu tiên nếu có thể.
