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 secondiDopo 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.
Sfida
Medio- Ottieni il servizio
Debris. Scrivibeam(from, to): una parte ancorata con materiale Neon, di dimensioni 0.2 per 0.2 e lunga quanto la distanza, impostata conCFrame.lookAt((from + to) / 2, to), rimossa da Debris dopo 0.1 secondi. - Scrivi
shoot(tower, target, info): applicaTakeDamage(info.Damage)all'Humanoid del bersaglio, poi crea un raggio dalla testa al bersaglio. - In
runTower, spara dopo esserti girato, poi attendiinfo.Cooldowninvece di 0.1 (mantieni 0.1 quando non c'è un bersaglio). - 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
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.