תצוגת זמן המתנה
שיעור 8 מתוך 20 בקורס משחק Roblox: זירות קרב של Coddy.
שחקן צריך לראות מתי יכולת מוכנה. ל־HUD יש מסגרת Cooldowns עם תווית לכל יכולת, והשרת כבר שומר את DashReadyAt אצל השחקן, כך שהלקוח שלו יכול לקרוא אותו.
הספירה לאחור משתנה בכל פריים, לכן הלקוח מצייר אותה מחדש ב־RunService.Heartbeat, שמופעל פעם אחת בכל פריים. string.format שומר ספרה אחת אחרי הנקודה העשרונית:
string.format("%s %.1f", "Dash", 2.345) --> "Dash 2.3"הלקוח רק מציג את זמן ההמתנה. הבדיקה של השרת מהשיעור הקודם עדיין היא שקובעת.
אתגר
בינוניב־BattleClient, קבל את RunService, את local me = Players.LocalPlayer ואת local hud = script.Parent. בכל Heartbeat, עבור כל שם ב־local shown = { "Dash" }, הגדר את hud.Cooldowns[name].Text ל־Dash 2.3 בזמן שהיכולת בהמתנה לסיום זמן הצינון שלה, ול־Dash ready כשהיא מוכנה.
לחץ על Play, לחץ על Q והסתכל בתווית. לאחר מכן לחץ על Check.
נסו בעצמכם
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)
local remotes = game.ReplicatedStorage.Remotes
local lastSwing = {} -- player -> מתי הניף את החרב בפעם האחרונה
-- אנימציות החרב של Roblox עצמה
local slash = Instance.new("Animation")
slash.AnimationId = "rbxassetid://522635514"
print("Swords deal " .. Settings.SwordDamage .. " damage")
-- הנפת חרב: האנימציה מתנגנת, ואז כל מי שנמצא בתיבה שלפניך נפגע
local function swing(player)
local character = player.Character
local root = character and character:FindFirstChild("HumanoidRootPart")
if not root or character.Humanoid.Health <= 0 then
return
end
local now = time()
if lastSwing[player] and now - lastSwing[player] < Settings.SwingCooldown then
return
end
lastSwing[player] = now
character.Humanoid.Animator:LoadAnimation(slash):Play()
-- התיבה שלפניך, לעולם לא הגוף שלך
local params = OverlapParams.new()
params.FilterDescendantsInstances = { character }
local box = root.CFrame * CFrame.new(0, 0, -3)
local hit = {} -- כל humanoid פעם אחת בכל הנפה
for _, part in workspace:GetPartBoundsInBox(box, Settings.HitboxSize, params) do
local humanoid = part.Parent:FindFirstChildOfClass("Humanoid")
if humanoid and not hit[humanoid] then
hit[humanoid] = true
humanoid:TakeDamage(Settings.SwordDamage)
end
end
end
-- היכולות לפי שם: מה כל אחת עושה
local abilities = {}
function abilities.Dash(player, character, root)
root.AssemblyLinearVelocity = root.CFrame.LookVector * Settings.DashSpeed + Vector3.new(0, 15, 0)
end
-- הלקוח מבקש יכולת לפי שם. השרת בודק שזו יכולת אמיתית,
-- שהשחקן חי, ושתקופת ההמתנה שלה הסתיימה. המועד שבו היא תהיה זמינה שוב
-- נשמר כמאפיין של השחקן, כדי שאפשר יהיה להציג אותו על המסך שלו.
remotes.Ability.OnServerEvent:Connect(function(player, name)
if typeof(name) ~= "string" or not abilities[name] then
return
end
local character = player.Character
local root = character and character:FindFirstChild("HumanoidRootPart")
if not root or character.Humanoid.Health <= 0 then
return
end
local now = workspace:GetServerTimeNow()
if now < (player:GetAttribute(name .. "ReadyAt") or 0) then
return
end
player:SetAttribute(name .. "ReadyAt", now + Settings.Cooldowns[name])
abilities[name](player, character, root)
end)
-- כל שחקן מקבל Kills בלוח המובילים, וחרב בכל פעם שהוא נוצר מחדש
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local kills = Instance.new("IntValue")
kills.Name = "Kills"
kills.Parent = leaderstats
player.CharacterAdded:Connect(function()
local sword = ServerStorage.Sword:Clone()
sword.Parent = player.Backpack
sword.Activated:Connect(function()
swing(player)
end)
end)
end)
-- בובת האימון: מד הבריאות שלה משקף את מצב הבריאות שלה, וכשהיא מובסת
-- היא חוזרת כעבור רגע, כעותק חדש באותו מקום
local function setupDummy(dummy)
local humanoid = dummy.Humanoid
humanoid.HealthChanged:Connect(function(health)
dummy.HealthBar.Back.Fill.Size = UDim2.fromScale(health / humanoid.MaxHealth, 1)
end)
humanoid.Died:Connect(function()
local spot = dummy:GetPivot()
task.wait(0.5)
dummy:Destroy()
task.wait(Settings.DummyRespawn)
local fresh = ServerStorage.Dummy:Clone()
fresh:PivotTo(spot)
fresh.Parent = workspace
setupDummy(fresh)
end)
end
setupDummy(workspace.Dummy)
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.