שמירה בעת יציאה
שיעור 18 מתוך 20 בקורס משחק Roblox: הישרדות באסונות של Coddy.
כרגע, ניצחונות נעלמים כשהשחקן עוזב. DataStore שומר נתונים בשרתים של Roblox בין ביקורים. כל ערך נשמר תחת מפתח; ה־UserId של השחקן הוא המפתח המקובל, כי הוא לעולם לא משתנה.
local coinsStore = DataStoreService:GetDataStore("Coins")
coinsStore:SetAsync(player.UserId, 40)קריאה ל־DataStore מתבצעת דרך הרשת ועלולה להיכשל, ושגיאה לא צריכה לשבש את המשחק, לכן כל קריאה עטופה ב־pcall, שמריצה פונקציה ומדווחת אם היא הצליחה במקום לגרום לשגיאה:
pcall(function()
coinsStore:SetAsync(player.UserId, 40)
end)שמור את הנתונים כשהשחקן עוזב (Players.PlayerRemoving), וגם ב־game:BindToClose, שפועל כשהשרת נסגר: ייתכן ששרת שעומד להיסגר לא יספיק להשלים את השמירות של PlayerRemoving. ב־Roblox Studio, חנויות הנתונים פועלות לאחר פרסום המקום והפעלת האפשרות Enable Studio Access to API Services.
אתגר
קשהשמור את Wins של כל שחקן כשהוא עוזב.
- בסמוך לחלק העליון, קבל את
DataStoreServiceואתlocal winsStore = DataStoreService:GetDataStore("Wins"). - כתוב את
saveWins(player): בתוךpcall, אתwinsStore:SetAsync(player.UserId, player.leaderstats.Wins.Value). - חבר אותו אל
Players.PlayerRemoving, וקרא לו עבור כל שחקן בתוךgame:BindToClose.
לחץ על "שחק" ושרוד סיבוב: Wins מציג 1, ועזיבה עכשיו שומרת אותו. ואז לחץ על "בדיקה".
נסו בעצמכם
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")
local Settings = require(game.ReplicatedStorage.Settings)
local lobbySpawn = workspace.LobbySpawn
print("Rounds last " .. Settings.RoundLength .. " seconds")
-- כל שחקן מקבל Wins ו-Streak בטבלת המובילים
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local wins = Instance.new("IntValue")
wins.Name = "Wins"
wins.Parent = leaderstats
local streak = Instance.new("IntValue")
streak.Name = "Streak"
streak.Parent = leaderstats
end)
-- שיעור 18: כאן יופיע הקוד לשמירה בעת עזיבה
-- לוח המצב בלובי
local gui = Instance.new("SurfaceGui")
gui.Parent = workspace.StatusBoard
local status = Instance.new("TextLabel")
status.Name = "Status"
status.Size = UDim2.fromScale(1, 1)
status.BackgroundColor3 = Color3.fromRGB(25, 25, 35)
status.TextColor3 = Color3.fromRGB(255, 255, 255)
status.TextScaled = true
status.Text = "Welcome to Disaster Survival!"
status.Parent = gui
local function setStatus(text)
status.Text = text
end
local function teleport(player, target)
local character = player.Character
if character then
character:PivotTo(target.CFrame + Vector3.new(0, 4, 0))
end
end
local function defeat(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid then
humanoid.Health = 0
end
end
-- תג צף עם הכיתוב "Survivor" מעל ראשו של שחקן
local function tagSurvivor(character)
local tag = Instance.new("BillboardGui")
tag.Name = "SurvivorTag"
tag.Size = UDim2.fromOffset(120, 30)
tag.StudsOffset = Vector3.new(0, 2.5, 0)
tag.Parent = character.Head
local label = Instance.new("TextLabel")
label.Size = UDim2.fromScale(1, 1)
label.BackgroundTransparency = 1
label.Text = "Survivor"
label.TextColor3 = Color3.fromRGB(80, 255, 120)
label.TextScaled = true
label.Parent = tag
end
-- האסונות, לפי שם
local Disasters = {}
function Disasters.Flood(map)
local base = map.Base
local water = Instance.new("Part")
water.Name = "Water"
water.Anchored = true
water.CanCollide = false
water.Transparency = 0.3
water.Color = Color3.fromRGB(40, 120, 255)
water.Size = Vector3.new(base.Size.X + 10, 1, base.Size.Z + 10)
water.Position = base.Position - Vector3.new(0, 2, 0)
water.Parent = map
water.Touched:Connect(defeat)
local rise = TweenInfo.new(Settings.RoundLength * 0.8, Enum.EasingStyle.Linear)
TweenService:Create(water, rise, { Position = water.Position + Vector3.new(0, 8, 0) }):Play()
end
function Disasters.Meteors(map)
local base = map.Base
task.spawn(function()
while map.Parent do
local meteor = Instance.new("Part")
meteor.Name = "Meteor"
meteor.Shape = Enum.PartType.Ball
meteor.Size = Vector3.new(3, 3, 3)
meteor.Color = Color3.fromRGB(255, 120, 30)
meteor.Material = Enum.Material.Neon
local x = base.Position.X + math.random(-15, 15)
local z = base.Position.Z + math.random(-15, 15)
meteor.Position = Vector3.new(x, 40, z)
meteor.Parent = map
meteor.Touched:Connect(defeat)
Debris:AddItem(meteor, 4)
task.wait(0.5)
end
end)
end
function Disasters.Shrink(map)
local base = map.Base
local shrink = TweenInfo.new(Settings.RoundLength * 0.7, Enum.EasingStyle.Linear)
TweenService:Create(base, shrink, { Size = Vector3.new(6, base.Size.Y, 6) }):Play()
end
local function pickDisaster()
-- Settings.Disaster מפעיל אסון אחד, אם הוא קיים במשחק
if Settings.Disaster and Disasters[Settings.Disaster] then
return Settings.Disaster
end
local names = {}
for name in Disasters do
table.insert(names, name)
end
table.sort(names)
return names[math.random(1, #names)]
end
local function pickMap()
local maps = ServerStorage.Maps
if Settings.Map then
return maps:FindFirstChild(Settings.Map)
end
local all = maps:GetChildren()
return all[math.random(1, #all)]
end
-- לולאת הסיבובים
while true do
for seconds = Settings.Intermission, 1, -1 do
setStatus("Intermission: " .. seconds)
task.wait(1)
end
local template = pickMap()
local map = template:Clone()
map.Name = "Map"
map.Parent = workspace
setStatus("Map: " .. template.Name)
local survivors = {}
for _, player in Players:GetPlayers() do
local character = player.Character
if character and character.Humanoid.Health > 0 then
teleport(player, map.Spawn)
tagSurvivor(character)
survivors[player] = true
character.Humanoid.Died:Connect(function()
survivors[player] = nil
player.leaderstats.Streak.Value = 0
end)
end
end
task.wait(2)
local disaster = pickDisaster()
Disasters[disaster](map)
for seconds = Settings.RoundLength, 1, -1 do
setStatus(disaster .. "! Time left: " .. seconds)
task.wait(1)
end
local names = {}
for player in survivors do
player.leaderstats.Wins.Value += 1
player.leaderstats.Streak.Value += 1
local tag = player.Character and player.Character.Head:FindFirstChild("SurvivorTag")
if tag then
tag:Destroy()
end
teleport(player, lobbySpawn)
table.insert(names, player.Name)
end
map:Destroy()
if #names > 0 then
setStatus("Winners: " .. table.concat(names, ", "))
else
setStatus("Nobody survived!")
end
task.wait(3)
end
כל השיעורים ביחידה משחק Roblox: הישרדות באסונות
תרגלו בעצמכם: Roblox אונליין