שדרוג
שיעור 11 מתוך 18 בקורס משחק Roblox: הגנת מגדלים של Coddy.
מגדל מתחזק עם רמות. הרמה היא מאפיין של מודל המגדל, Level, שמתחיל ב-1; כל רמה מוסיפה שוב את הנזק של המגדל, כך שקשת ברמה 3 פוגע בעוצמה 12.
כל שדרוג עולה יותר מהקודם: חלק ממחיר המגדל, Settings.UpgradeCost, כפול הרמה הנוכחית שלו. math.floor שומר על מספר שלם:
local cost = math.floor(Settings.Towers[tower.Name].Price * Settings.UpgradeCost * level)בצד הלקוח, לחיצה על מגדל פותחת את ה-Panel של ה-HUD עם השם שלו, הרמה והמחיר של השדרוג הבא. הלחיצה פוגעת באחד החלקים של המגדל, ולכן target:FindFirstAncestorOfClass("Model") מוצא את המגדל שהחלק שייך אליו. הלוח מציג את הרמה שהשרת קבע: הוא מאזין למאפיין Level של המגדל ומצייר מחדש כשהוא משתנה.
אתגר
בינוניב־DefenseServer:
- ב־
placeTower, הגדירו את מאפייןLevelשל המגדל ל־1. - ב־
shoot, הנזק הואinfo.Damage * tower:GetAttribute("Level"). - חברו את
remotes.Upgrade.OnServerEvent(player, tower): דחו כל דבר שאינו Instance שנמצא ב־towers, חשבו את העלות, דחו את הבקשה אם אין מספיק כסף, ואז גבו את הכסף והוסיפו 1 לרמה.
ב־DefenseClient: כתבו את showPanel() (כותרת Archer level 1, לחצן Upgrade $45, החלונית גלויה; מוסתרת כשלא נבחר דבר) ואת choose(tower); לחיצה על מגדל בוחרת אותו, ולחצן Upgrade בחלונית מפעיל את remotes.Upgrade איתו.
לחצו על Play, ואז על Check.
נסו בעצמכם
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")
-- נקודות הציון, לפי הסדר (הן נקראות 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
enemy.Humanoid.Died:Connect(function()
-- כל שחקן מקבל את הפרס
for _, player in Players:GetPlayers() do
player.leaderstats.Money.Value += info.Reward
end
enemy:Destroy()
end)
task.spawn(walkPath, enemy)
return enemy
end
-- האויב החי הקרוב ביותר בטווח מנקודה מסוימת, או 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
-- הבזק אור ממגדל אל המטרה שלו
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
-- ירייה: פגעו במטרה
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
-- מחזור הפעולה של מגדל: כוונו לאויב הקרוב ביותר בטווח, ירו, והמתינו לסיום זמן ההמתנה בין יריות
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
-- בנו מגדל על משטח הצבה
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
-- הלקוח מבקש להציב מגדל על משטח הצבה. בדקו הכול: שהמשטח קיים ופנוי,
-- שהמגדל קיים ושיש מספיק כסף לשלם עליו.
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)
-- גל אחד: האויבים שלו מופיעים בזה אחר זה, ואז ממתינים עד שכולם נעלמים
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
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה משחק Roblox: הגנת מגדלים
תרגלו בעצמכם: Roblox אונליין