Menu
CoddyTech

Spara

Lezione 8 di 18 del corso Gioco Roblox: Tower Defense di Coddy.

Affrontare il nemico è metà del lavoro. shoot danneggia il bersaglio con Humanoid:TakeDamage e crea un breve lampo di luce dalla testa al bersaglio: una sottile parte al neon che Debris rimuove un decimo di secondo dopo.

Debris:AddItem(ray, 0.1) -- distrutto in 0.1 secondi

Dopo un colpo, la torre attende il suo Cooldown prima di poter sparare di nuovo; è questo che rende un arciere veloce e un cannone lento.

Quando la salute di un Humanoid raggiunge 0, si attiva il suo evento Died. Un nemico sconfitto dovrebbe lasciare subito il gioco, quindi spawnEnemy collega Died alla sua distruzione: poi walkPath lo vede scomparire e si ferma.

challenge icon

Sfida

Medio
  1. Ottieni il servizio Debris. Scrivi beam(from, to): una parte ancorata con materiale Neon, di dimensioni 0.2 per 0.2 e lunga quanto la distanza, impostata con CFrame.lookAt((from + to) / 2, to), rimossa da Debris dopo 0.1 secondi.
  2. Scrivi shoot(tower, target, info): applica TakeDamage(info.Damage) all'Humanoid del bersaglio, poi crea un raggio dalla testa al bersaglio.
  3. In runTower, spara dopo esserti girato, poi attendi info.Cooldown invece di 0.1 (mantieni 0.1 quando non c'è un bersaglio).
  4. In spawnEnemy, distruggi il nemico quando il suo Humanoid muore.

Premi Gioca, poi Verifica.

Provalo tu

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)

local remotes = game.ReplicatedStorage.Remotes
local enemies = workspace.Enemies
local towers = workspace.Towers

print("The base can take " .. Settings.BaseHealth .. " hits")

-- I punti di passaggio, in ordine (si chiamano 1, 2, 3...)
local waypoints = workspace.Path.Waypoints:GetChildren()
table.sort(waypoints, function(a, b)
	return tonumber(a.Name) < tonumber(b.Name)
end)

-- La salute della base, come attributo di workspace: ogni client può leggerla
workspace:SetAttribute("BaseHealth", Settings.BaseHealth)

-- Ogni giocatore riceve Money nella classifica
Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local money = Instance.new("IntValue")
	money.Name = "Money"
	money.Value = Settings.StartMoney
	money.Parent = leaderstats
end)

-- Un nemico ha raggiunto la base
local function damageBase(amount)
	local health = math.max(0, workspace:GetAttribute("BaseHealth") - amount)
	workspace:SetAttribute("BaseHealth", health)
end

-- Fai avanzare un nemico lungo il percorso. MoveTo rinuncia dopo 8 secondi e lo segnala
-- (MoveToFinished con false), quindi il comando viene ripetuto per un nemico lento finché non arriva.
local function walkPath(enemy)
	local humanoid = enemy.Humanoid
	for i = 2, #waypoints do
		repeat
			humanoid:MoveTo(waypoints[i].Position)
		until humanoid.MoveToFinished:Wait() or not enemy.Parent
		if not enemy.Parent then
			return
		end
	end
	-- ha raggiunto la base
	damageBase(Settings.Enemies[enemy.Name].Damage)
	enemy:Destroy()
end

-- Un nuovo nemico al cancello, che percorre il tragitto
local function spawnEnemy(kind)
	local enemy = ServerStorage.Enemies[kind]:Clone()
	-- posizionato appena sopra il primo punto di passaggio
	enemy:PivotTo(waypoints[1].CFrame + Vector3.new(0, 5, 0))
	local info = Settings.Enemies[kind]
	enemy.Humanoid.MaxHealth = info.Health
	enemy.Humanoid.Health = info.Health
	enemy.Humanoid.WalkSpeed = info.Speed
	enemy.Parent = enemies
	task.spawn(walkPath, enemy)
	return enemy
end

-- Il nemico vivo più vicino entro la portata di un punto, oppure nil
local function nearestEnemy(position, range)
	local best, bestDistance = nil, range
	for _, enemy in enemies:GetChildren() do
		local root = enemy:FindFirstChild("HumanoidRootPart")
		if root and enemy.Humanoid.Health > 0 then
			local distance = (root.Position - position).Magnitude
			if distance <= bestDistance then
				best, bestDistance = enemy, distance
			end
		end
	end
	return best
end

-- Il ciclo di vita di una torre: mira al nemico più vicino entro la sua portata
local function runTower(tower)
	local info = Settings.Towers[tower.Name]
	while tower.Parent do
		local target = nearestEnemy(tower.Head.Position, info.Range)
		if target then
			tower.Head.CFrame = CFrame.lookAt(tower.Head.Position, target.HumanoidRootPart.Position)
			task.wait(0.1)
		else
			task.wait(0.1)
		end
	end
end

-- Costruisci una torre su una piattaforma
local function placeTower(pad, kind)
	local tower = ServerStorage.Towers[kind]:Clone()
	tower:PivotTo(pad.CFrame + Vector3.new(0, pad.Size.Y / 2 + 1, 0))
	tower.Parent = towers
	task.spawn(runTower, tower)
end

-- Il client richiede una torre su una piattaforma
remotes.Place.OnServerEvent:Connect(function(player, pad, kind)
	placeTower(pad, kind)
end)

-- Un'ondata: i suoi nemici uno alla volta, poi attendi finché non sono tutti scomparsi
local function runWave(list)
	for _, kind in list do
		spawnEnemy(kind)
		task.wait(Settings.SpawnGap)
	end
	while #enemies:GetChildren() > 0 do
		task.wait(0.2)
	end
end

-- Le ondate, ciascuna dopo una pausa
for i, list in Settings.Waves do
	task.wait(Settings.WaveBreak)
	runWave(list)
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: Tower Defense