Menu
CoddyTech

Tia laser trượt

Bài học 9 trên 21 trong khóa học Trò chơi Roblox: Tháp bất tận của Coddy.

Phần Lasers có hai bức tường đỏ, được gắn thẻ Slider và Kill, trượt qua lại trên lối đi. Mỗi bức tường có một thuộc tính, Slide, là một Vector3 cho biết nó di chuyển đến đâu so với vị trí ban đầu.

Một tween có thể lặp lại. TweenInfo.new nhận thời gian, kiểu easing, hướng, số lần lặp lại (-1 nghĩa là lặp mãi mãi) và liệu có phát ngược lại hay không:

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 giữ tốc độ đều để người chơi có thể căn thời điểm. Kiểu easing mặc định (Quad, Out) làm chậm khi đến nơi, khiến việc căn thời điểm trở nên khó khăn.

challenge icon

Thử thách

Trung bình

Khiến các tia laser trượt ngang qua lối đi rồi quay lại.

  1. Ở gần đầu đoạn code, lấy TweenService.
  2. Viết makeSlide(part): tạo chuyển động nội suy cho Position của part đến vị trí Position cộng với thuộc tính Slide, mất Settings.SlideTime giây, theo kiểu Linear, lặp vô hạn (-1) và đảo chiều.
  3. Trong setupStage, gọi hàm này cho mọi part có thẻ Slider.

Nhấn Chơi: hai bức tường đỏ trượt ngang qua rồi quay lại với tốc độ đều. Sau đó nhấn Kiểm tra.

Tự làm thử

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")

-- Mỗi người chơi có Wins trên bảng xếp hạng
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)

-- Chạm vào bất cứ thứ gì gắn thẻ Kill sẽ mất một mạng
local function killOnTouch(hit)
	local humanoid = hit.Parent:FindFirstChild("Humanoid")
	if humanoid then
		humanoid.Health = 0
	end
end

-- Bậc thang biến mất sẽ mờ đi ngay sau khi có người đáp xuống, rồi xuất hiện trở lại
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

-- Bài học 9: Thêm laser trượt vào đây

-- Các vật xoay quay một chút sau mỗi khung hình
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)

-- Kích hoạt mọi chướng ngại vật trong một màn theo thẻ của chúng
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

-- Chọn ngẫu nhiên một màn
local function pickStage()
	local all = stages:GetChildren()
	return all[math.random(1, #all)]
end

-- Đặt bản sao của một mô hình lên đỉnh tháp; trả về bản sao và độ cao đỉnh mới
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

-- Tạo một tháp ngẫu nhiên mới từ dưới lên
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()

Tất cả bài học trong Trò chơi Roblox: Tháp bất tận

Tự luyện tập: Playground Roblox