Menu
CoddyTech

כוון

שיעור 7 מתוך 18 בקורס משחק Roblox: הגנת מגדלים של Coddy.

מגדל מגן על הקרקע שנמצאת בטווח ה־Range שלו. כל מגדל מפעיל לולאה משלו בתהליכון משלו: למצוא את האויב החי הקרוב ביותר שבטווח, ולסובב את ה־Head שלו כדי לפנות אליו.

מציאת האויב הקרוב ביותר היא לולאה קלאסית: מתחילים בלי כלום ועם הטווח כמרחק הטוב ביותר, ושומרים כל אויב שקרוב יותר מהטוב ביותר עד כה.

local best, bestDistance = nil, range
for _, enemy in enemies:GetChildren() do
	-- קרוב יותר מהטוב ביותר עד כה? שמור אותו
end
return best

CFrame.lookAt(from, at) הוא CFrame שנמצא ב־from ומביט אל at, ולכן הוא מסובב את הראש בלי להזיז אותו:

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

לולאה שרצה לנצח חייבת להמתין בכל איטרציה, אחרת היא תקפיא את המשחק: יש להמתין 0.1 שניות בין אם נמצא יעד ובין אם לא.

challenge icon

אתגר

בינוני
  1. כתוב/כתבי את nearestEnemy(position, range): האויב החי (יש לו HumanoidRootPart ו-Health > 0) הקרוב ביותר אל position, בתוך range, או nil.
  2. כתוב/כתבי את runTower(tower): כל עוד המגדל נמצא במשחק, מצא/מצאי את האויב הקרוב ביותר לראש שלו בתוך Settings.Towers[tower.Name].Range, סובב/סובבי את הראש כדי שיפנה אליו, והפעל/הפעילי את task.wait(0.1).
  3. הפעל/הפעילי אותו בסוף placeTower באמצעות task.spawn(runTower, tower).

לחץ/לחצי על Play, בנה/בני קשת ליד נקודת ההתחלה וצפה/צפי בו עוקב אחר המטרה. לאחר מכן לחץ/לחצי על Check.

נסו בעצמכם

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

-- נקודות הציון, לפי הסדר (הן נקראות 1, 2, 3...)
local waypoints = workspace.Path.Waypoints:GetChildren()
table.sort(waypoints, function(a, b)
	return tonumber(a.Name) < tonumber(b.Name)
end)

-- החיים של הבסיס, כתכונה של workspace: כל לקוח יכול לקרוא אותה
workspace:SetAttribute("BaseHealth", Settings.BaseHealth)

-- כל שחקן מקבל Money בלוח המובילים
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)

-- אויב הגיע לבסיס
local function damageBase(amount)
	local health = math.max(0, workspace:GetAttribute("BaseHealth") - amount)
	workspace:SetAttribute("BaseHealth", health)
end

-- הולך עם אויב לאורך המסלול. MoveTo מוותר אחרי 8 שניות ומדווח על כך
-- (MoveToFinished עם false), לכן שולחים אויב איטי שוב עד שהוא מגיע.
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
	-- הוא הגיע לבסיס
	damageBase(Settings.Enemies[enemy.Name].Damage)
	enemy:Destroy()
end

-- אויב חדש בשער, הולך לאורך המסלול
local function spawnEnemy(kind)
	local enemy = ServerStorage.Enemies[kind]:Clone()
	-- מוצב ממש מעל נקודת הציון הראשונה
	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

-- בנה מגדל על משטח
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

-- הלקוח מבקש להציב מגדל על משטח
remotes.Place.OnServerEvent:Connect(function(player, pad, kind)
	placeTower(pad, kind)
end)

-- גל אחד: האויבים שלו בזה אחר זה, ואז ממתינים עד שכולם נעלמים
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

-- הגלים, כל אחד לאחר הפסקה
for i, list in Settings.Waves do
	task.wait(Settings.WaveBreak)
	runWave(list)
end
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה משחק Roblox: הגנת מגדלים