Menu
CoddyTech

Titik Pemeriksaan

Pelajaran 16 dari 18 dalam kursus Game Roblox: Menara Tanpa Akhir di Coddy.

Jatuh hingga mati di tahap 5 dan harus mulai lagi dari bawah terasa berat. Dengan titik pemeriksaan, pemain yang mati memulai lagi dari tahap terakhir yang mereka capai, yang sudah diketahui oleh Stage.

Setiap karakter baru memicu CharacterAdded milik pemain. Roblox menempatkannya di titik spawn terlebih dahulu, jadi tunggu sebentar, lalu pindahkan:

player.CharacterAdded:Connect(function(character)
	task.wait()
	local checkpoint = towerStages[stage.Value]
	if checkpoint then
		character:PivotTo(checkpoint.Start.CFrame + Vector3.new(0, 4, 0))
	end
end)

Sebelum pemain mencapai tahap mana pun, towerStages[0] bernilai nil, jadi mereka spawn di lobi seperti biasa. Para pemenang kembali ke lobi dan sebaiknya tetap di sana.

Lava mengubah satu hal. Tahap yang telah tertutup lava bukan titik pemeriksaan: pemain yang dikembalikan ke sana akan langsung mati lagi, berulang kali, sampai lava melewati tahap berikutnya. Bandingkan Start tahap itu dengan bagian atas lava, lalu biarkan pemain yang titik pemeriksaannya berada di bawah lava tetap di lobi sampai babak berikutnya:

local covered = checkpoint and lava and checkpoint.Start.Position.Y < lava.Position.Y + lava.Size.Y / 2
challenge icon

Tantangan

Sulit

Di PlayerAdded, setelah membuat leaderstats, hubungkan CharacterAdded milik pemain. Tunggu sebentar dengan task.wait(), lalu, jika towerStages[stage.Value] ada, lava belum menutupi Start-nya, dan pemain belum menyelesaikan ronde ini, pindahkan karakter ke titik 4 stud di atas Start tahap tersebut.

Tekan Play, naiki satu tahap, lalu lompat turun. Setelah itu, tetaplah di sana sampai lava datang. Kemudian tekan Check.

Coba sendiri

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

-- Setiap pemain mendapat Wins dan Stage di papan peringkat
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

	local stage = Instance.new("IntValue")
	stage.Name = "Stage"
	stage.Parent = leaderstats
end)

-- Papan di lobi
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

-- Apa pun yang diberi tag Kill mengakhiri nyawa
local function killOnTouch(hit)
	local humanoid = hit.Parent:FindFirstChild("Humanoid")
	if humanoid then
		humanoid.Health = 0
	end
end

-- Pijakan yang menghilang memudar sesaat setelah seseorang mendarat di atasnya, lalu muncul kembali
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

-- Laser bergeser ke posisi sesuai offset Slide, lalu kembali, terus-menerus
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

-- Papan pelontar melempar siapa pun yang mendarat di atasnya ke udara
local function bounce(hit)
	local root = hit.Parent:FindFirstChild("HumanoidRootPart")
	if root then
		root.AssemblyLinearVelocity = Vector3.new(0, Settings.BouncePower, 0)
	end
end

-- Spinner berputar sedikit setiap frame
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)

-- Aktifkan setiap rintangan dalam stage berdasarkan tag-nya
local function setupStage(stage, index)
	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
	-- Mencapai Start pada suatu stage dihitung di papan peringkat
	stage.Start.Touched:Connect(function(hit)
		local player = Players:GetPlayerFromCharacter(hit.Parent)
		if player and player.leaderstats.Stage.Value < index then
			player.leaderstats.Stage.Value = index
		end
	end)
end

-- Pilih stage secara acak
local function pickStage()
	local all = stages:GetChildren()
	return all[math.random(1, #all)]
end

-- Letakkan salinan model di puncak menara; kembalikan salinan dan posisi puncak yang baru
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

-- Puncak menara: menang, lalu kembali ke lobi
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

-- Bangun menara acak baru dari bawah ke atas
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, i)
		towerStages[i] = stage
	end
	local finish = stack(ServerStorage.Finish, top)
	finish.FinishPad.Touched:Connect(reachTop)
	return top
end

-- Lava naik dari tanah hingga tepat di bawah puncak menara
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 = {}
	for _, player in Players:GetPlayers() do
		player.leaderstats.Stage.Value = 0
	end
	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

local function endRound()
	for _, player in Players:GetPlayers() do
		if player.Character and not finished[player] then
			player.Character:PivotTo(lobbySpawn.CFrame + Vector3.new(0, 4, 0))
		end
		player.leaderstats.Stage.Value = 0
	end
	tower:Destroy()
	lava:Destroy()
	towerStages = {}
end

-- Perulangan ronde
while true do
	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
	endRound()
end
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Game Roblox: Menara Tanpa Akhir

Latihan sendiri: Playground Roblox