Menu
CoddyTech

Bidik

Pelajaran 7 dari 18 dalam kursus Game Roblox: Tower Defense di Coddy.

Sebuah menara menjaga area di dalam Range-nya. Setiap menara menjalankan perulangannya sendiri di thread-nya sendiri: cari musuh hidup terdekat dalam jangkauan, lalu putar Head-nya agar menghadap musuh itu.

Mencari yang terdekat adalah perulangan klasik: mulai tanpa target dan gunakan jangkauan sebagai jarak terbaik, lalu pilih musuh mana pun yang lebih dekat daripada jarak terbaik sejauh ini.

local best, bestDistance = nil, range
for _, enemy in enemies:GetChildren() do
	-- Lebih dekat daripada yang terbaik sejauh ini? Simpan.
end
return best

CFrame.lookAt(from, at) adalah CFrame yang berada di from dan menghadap ke at, jadi ini memutar kepala tanpa memindahkannya:

tower.Head.CFrame = CFrame.lookAt(tower.Head.Position, target.HumanoidRootPart.Position)

Perulangan yang berjalan selamanya harus menunggu di setiap putaran, jika tidak, game akan membeku: tunggu 0.1 detik, baik saat target ditemukan maupun tidak.

challenge icon

Tantangan

Sedang
  1. Tulis nearestEnemy(position, range): musuh hidup (memiliki HumanoidRootPart dan Health > 0) yang paling dekat dengan position, berada dalam jangkauan range, atau nil.
  2. Tulis runTower(tower): selama tower berada di dalam game, cari musuh terdekat dari kepalanya dalam jangkauan Settings.Towers[tower.Name].Range, arahkan kepalanya ke musuh itu, lalu jalankan task.wait(0.1).
  3. Jalankan fungsi ini di akhir placeTower dengan task.spawn(runTower, tower).

Tekan Mainkan, bangun Archer di dekat awal, lalu lihat tower itu membidik musuh. Setelah itu, tekan Periksa.

Coba sendiri

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

-- Waypoint secara 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 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)
end

-- Gerakkan musuh menyusuri jalur. MoveTo berhenti mencoba setelah 8 detik dan memberi tahu
-- (MoveToFinished dengan false), jadi musuh yang lambat diarahkan 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
	task.spawn(walkPath, enemy)
	return enemy
end

-- Bangun menara di atas landasan
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
end

-- client meminta menara di atas landasan
remotes.Place.OnServerEvent:Connect(function(player, pad, kind)
	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-gelombang, masing-masing setelah jeda
for i, list in Settings.Waves do
	task.wait(Settings.WaveBreak)
	runWave(list)
end
quiz iconUji dirimu

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

Semua pelajaran di Game Roblox: Tower Defense

Latihan sendiri: Playground Roblox