Menu
CoddyTech

Checkpoint

Lezione 16 di 18 del corso Gioco Roblox: Torre infinita di Coddy.

Morire cadendo al livello 5 e ripartire dal fondo è dura. Con i checkpoint, un giocatore che muore ricomincia dall'ultimo livello raggiunto, che Stage già conosce.

Ogni nuovo personaggio attiva CharacterAdded del giocatore. Roblox lo colloca prima su un punto di spawn, quindi aspetta un momento e poi spostalo:

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)

Prima che un giocatore raggiunga un qualsiasi livello, towerStages[0] è nil, quindi appare nella lobby come al solito. I vincitori tornano nella lobby e dovrebbero restarci.

La lava cambia una cosa. Un livello che ha coperto non è un checkpoint: un giocatore riportato lì muore di nuovo subito, ancora e ancora, finché la lava non supera il livello successivo. Confronta lo Start del livello con la sommità della lava e lascia nella lobby fino al round successivo un giocatore il cui checkpoint si trovi sotto di essa:

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

Sfida

Difficile

In PlayerAdded, dopo aver creato le leaderstats, collega CharacterAdded del giocatore. Attendi un momento con task.wait(), poi, se towerStages[stage.Value] esiste, la lava non ha coperto il suo Start e il giocatore non ha ancora terminato questo round, sposta il personaggio a 4 stud sopra lo Start di quella fase.

Premi Play, sali di una fase e buttati giù. Poi resta su quella fase finché non arriva la lava. Quindi premi Check.

Provalo tu

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

-- Ogni giocatore riceve Wins e Stage nella classifica
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)

-- Il tabellone nella lobby
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

-- Qualsiasi cosa con il tag Kill fa perdere una vita
local function killOnTouch(hit)
	local humanoid = hit.Parent:FindFirstChild("Humanoid")
	if humanoid then
		humanoid.Health = 0
	end
end

-- Una piattaforma che scompare svanisce poco dopo che qualcuno ci atterra sopra, poi riappare
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

-- Un laser scorre fino allo spostamento Slide e torna indietro, all'infinito
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

-- Una piattaforma rimbalzante lancia in aria chiunque ci atterri sopra
local function bounce(hit)
	local root = hit.Parent:FindFirstChild("HumanoidRootPart")
	if root then
		root.AssemblyLinearVelocity = Vector3.new(0, Settings.BouncePower, 0)
	end
end

-- Gli ostacoli rotanti ruotano un po' a ogni fotogramma
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)

-- Attiva tutti gli ostacoli di una fase in base ai loro tag
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
	-- Raggiungere Start di una fase viene registrato nella classifica
	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

-- Una fase qualsiasi, scelta a caso
local function pickStage()
	local all = stages:GetChildren()
	return all[math.random(1, #all)]
end

-- Posiziona una copia di un modello in cima alla torre; restituisce la copia e la nuova altezza della cima
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

-- La cima della torre: una vittoria e ritorno alla lobby
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

-- Costruisce una nuova torre casuale, dal basso verso l'alto
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

-- La lava sale dal suolo fino a poco sotto la cima della torre
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

-- Il ciclo dei round
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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Gioco Roblox: Torre infinita