Menu
CoddyTech

Dung nham dâng lên

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

Đứng chờ ở dưới cùng không nên an toàn. Một tấm dung nham bắt đầu bên dưới tháp và, sau Settings.LavaDelay giây, dâng đều cho đến khi còn cách đỉnh 2 stud, vì vậy mọi người phải tiếp tục leo lên.

Một tween có thể chờ trước khi bắt đầu: tham số thứ sáu của TweenInfo.new là thời gian chờ tính bằng giây. Để dung nham dâng đều, thời gian của tween bằng khoảng cách chia cho tốc độ:

-- 60 studs với tốc độ 3 studs mỗi giây, sau 4 giây
local info = TweenInfo.new(60 / 3, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 4)

Dung nham không rắn (CanCollide là false), nên không ai có thể đứng trên đó. Sự kiện Touched của nó sử dụng killOnTouch, cùng hàm với các khối dung nham gây chết người. Dung nham bắt đầu ở độ cao -2 và dâng lên đến top - 2, đúng bằng top stud.

challenge icon

Thử thách

Trung bình

Dung nham dâng lên bên dưới tháp.

  1. Cho buildTower trả về top, rồi kết thúc tập lệnh bằng startLava(buildTower()).
  2. Viết startLava(top): đặt lava ở cấp ngoài thành một Part được neo tên là Lava, đặt CanCollide thành false, ở vị trí (0, -2, 0), rồi kết nối Touched với killOnTouch.
  3. Tạo tween để nó di chuyển đến (0, top - 2, 0) trong top / Settings.LavaSpeed giây, dùng Linear và trì hoãn Settings.LavaDelay.

Nhấn Chơi: sau 10 giây, dung nham bắt đầu dâng lên bên dưới bạn. 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 TweenService = game:GetService("TweenService")
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 đều 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)

-- Vật thể nào gắn thẻ Kill cũng khiến người chạm vào 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 mờ dần 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

-- Tia laser trượt đến vị trí lệch theo Slide rồi quay lại, lặp mãi
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

-- Tấm bật nhảy hất người đáp xuống lên không trung
local function bounce(hit)
	local root = hit.Parent:FindFirstChild("HumanoidRootPart")
	if root then
		root.AssemblyLinearVelocity = Vector3.new(0, Settings.BouncePower, 0)
	end
end

-- Các vật thể quay xoay 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 tầng 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
		if part:HasTag("Slider") then
			makeSlide(part)
		end
		if part:HasTag("Bounce") then
			part.Touched:Connect(bounce)
		end
	end
end

-- Chọn ngẫu nhiên một tầng bất kỳ
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

-- Xây một tháp mới ngẫu nhiên 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

-- Bài học 11: Rising Lava nằm ở đây

buildTower()
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

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