Panel Menara
Pelajaran 13 dari 22 dalam kursus Game Roblox: Tower Defense di Coddy.
Sebuah menara menjadi lebih kuat dengan level. Level adalah atribut pada model menara, Level, yang dimulai dari 1. Setiap peningkatan memerlukan sebagian dari harga menara, Settings.UpgradeCost, dikalikan dengan levelnya saat ini, dan math.floor membulatkannya ke bawah menjadi bilangan bulat. Biaya peningkatan berikutnya untuk menara Frost level 2 adalah:
math.floor(90 * 0.75 * 2) --> 135Mengeklik menara akan membuka Panel pada HUD, yang menampilkan nama, level, dan harganya. Klik mengenai salah satu bagian menara, jadi target:FindFirstAncestorOfClass("Model") mencari model menara tempat bagian itu berada.
Tantangan
SedangKlik menara untuk membuka panelnya.
- Di
placeTower, atur atributLevelmenara menjadi 1. - Di
DefenseClient, tulisshowPanel(): untuk menarachosen, teksArcher level 1dihud.Panel.TitledanUpgrade $45dihud.Panel.Upgrade; tampilkan panelnya. - Di
Button1Down, klik menara diworkspace.Towersakan memilihnya.
Tekan tombol “Main” dan klik Archer yang kamu bangun: panelnya akan terbuka. Lalu tekan tombol “Periksa”.
Coba sendiri
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Debris = game:GetService("Debris")
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")
-- Waypoint berurutan (dinamai 1, 2, 3...)
local waypoints = workspace.Path.Waypoints:GetChildren()
table.sort(waypoints, function(a, b)
return tonumber(a.Name) < tonumber(b.Name)
end)
-- Nyawa markas disimpan sebagai atribut workspace: setiap client dapat membacanya
workspace:SetAttribute("BaseHealth", Settings.BaseHealth)
-- Setiap pemain mendapat Money di papan peringkat
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)
-- Musuh mencapai markas
local function damageBase(amount)
local health = math.max(0, workspace:GetAttribute("BaseHealth") - amount)
workspace:SetAttribute("BaseHealth", health)
print("Base: " .. health)
end
-- Gerakkan musuh menyusuri jalur. MoveTo berhenti mencoba setelah 8 detik dan memberi tahu
-- (MoveToFinished dengan false), jadi musuh yang lambat digerakkan lagi sampai tiba.
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
-- Musuh mencapai markas
damageBase(Settings.Enemies[enemy.Name].Damage)
enemy:Destroy()
end
-- Musuh baru di gerbang, menyusuri jalur
local function spawnEnemy(kind)
local enemy = ServerStorage.Enemies[kind]:Clone()
-- Ditempatkan tepat di atas waypoint pertama
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
enemy.Humanoid.Died:Connect(function()
-- Setiap pemain mendapat hadiah
for _, player in Players:GetPlayers() do
player.leaderstats.Money.Value += info.Reward
end
enemy:Destroy()
end)
task.spawn(walkPath, enemy)
return enemy
end
-- Musuh hidup terdekat dalam jangkauan suatu titik, atau 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
-- Kilatan cahaya dari menara menuju targetnya
local function beam(from, to)
local ray = Instance.new("Part")
ray.Anchored = true
ray.CanCollide = false
ray.CanTouch = false
ray.Material = Enum.Material.Neon
ray.Color = Color3.fromRGB(255, 240, 150)
ray.Size = Vector3.new(0.2, 0.2, (to - from).Magnitude)
ray.CFrame = CFrame.lookAt((from + to) / 2, to)
ray.Parent = workspace
Debris:AddItem(ray, 0.1)
end
-- Tembakan: berikan kerusakan pada target
local function shoot(tower, target, info)
local damage = info.Damage
local at = target.HumanoidRootPart.Position
target.Humanoid:TakeDamage(damage)
beam(tower.Head.Position, at)
end
-- Rutinitas tower: bidik musuh terdekat dalam jangkauan, tembak, lalu tunggu cooldown-nya
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)
shoot(tower, target, info)
task.wait(info.Cooldown)
else
task.wait(0.1)
end
end
end
-- Bangun tower di atas pad
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
pad:SetAttribute("Used", true)
task.spawn(runTower, tower)
end
-- client meminta tower di atas pad. Periksa semuanya: pad yang valid dan belum terpakai,
-- tower yang valid, dan uang yang cukup untuk membayarnya.
remotes.Place.OnServerEvent:Connect(function(player, pad, kind)
if typeof(pad) ~= "Instance" or pad.Parent ~= workspace.Pads or pad:GetAttribute("Used") then
return
end
local info = typeof(kind) == "string" and Settings.Towers[kind]
if not info then
return
end
local money = player.leaderstats.Money
if money.Value < info.Price then
return
end
money.Value -= info.Price
placeTower(pad, kind)
end)
-- Satu gelombang: munculkan musuhnya satu per satu, lalu tunggu hingga semuanya hilang
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
-- Gelombang demi gelombang, masing-masing setelah jeda
for i, list in Settings.Waves do
task.wait(Settings.WaveBreak)
runWave(list)
end
Semua pelajaran di Game Roblox: Tower Defense
Latihan sendiri: Playground Roblox