احفظ عند المغادرة
الدرس 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، تعمل DataStores بعد نشر التجربة وتفعيل Enable Studio Access to API Services.
التحدي
صعباحفظ عدد مرات الفوز لكل لاعب عند مغادرته.
- بالقرب من الأعلى، احصل على
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: النجاة من الكوارث
تدرّب بنفسك: Playground لـ Roblox