Lưu khi rời đi
Bài học 18 trên 20 trong khóa học Trò chơi Roblox: sinh tồn trước thảm họa của Coddy.
Hiện tại, Wins sẽ biến mất khi người chơi rời đi. DataStore lưu dữ liệu trên máy chủ Roblox giữa các lần ghé chơi. Mỗi giá trị được lưu dưới một khóa; UserId của người chơi thường được dùng làm khóa vì nó không bao giờ thay đổi.
local coinsStore = DataStoreService:GetDataStore("Coins")
coinsStore:SetAsync(player.UserId, 40)Lệnh gọi DataStore truyền dữ liệu qua mạng nên có thể thất bại, và lỗi không được làm hỏng trò chơi. Vì vậy, mỗi lệnh gọi được bọc trong pcall, hàm này chạy một hàm và báo cho biết hàm đó có chạy thành công hay không, thay vì báo lỗi:
pcall(function()
coinsStore:SetAsync(player.UserId, 40)
end)Hãy lưu dữ liệu khi người chơi rời đi (Players.PlayerRemoving) và cả trong game:BindToClose, hàm này chạy khi máy chủ tắt: máy chủ đang đóng có thể không hoàn tất việc lưu dữ liệu trong PlayerRemoving. Trong Roblox Studio, DataStore sẽ hoạt động khi địa điểm đã được xuất bản và tùy chọn Enable Studio Access to API Services được bật.
Thử thách
KhóLưu Wins của mỗi người chơi khi họ rời đi.
- Ở gần đầu đoạn code, lấy
DataStoreServicevàlocal winsStore = DataStoreService:GetDataStore("Wins"). - Viết
saveWins(player): bên trongpcall, gọiwinsStore:SetAsync(player.UserId, player.leaderstats.Wins.Value). - Kết nối hàm này với
Players.PlayerRemoving, rồi gọi hàm đó cho mọi người chơi bên tronggame:BindToClose.
Nhấn Chơi và sống sót qua một vòng: Wins hiển thị 1, và giờ đây khi bạn rời đi, giá trị đó sẽ được lưu. Sau đó nhấn Kiểm tra.
Tự làm thử
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")
-- Mỗi người chơi có Wins và Streak trên bảng xếp hạng
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)
-- Bài học 18: Thêm phần lưu khi rời trò chơi vào đây
-- Bảng trạng thái ở sảnh chờ
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
-- Nhãn "Survivor" lơ lửng trên đầu người chơi
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
-- Các thảm họa theo tên
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 kích hoạt một thảm họa nếu trò chơi có thảm họa đó
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
-- Vòng lặp (loop) các lượt chơi
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
Tất cả bài học trong Trò chơi Roblox: sinh tồn trước thảm họa
4Biến mọi thứ thành trò chơi
Hai bản đồ2Bản đồ và người chơi
Tải bản đồTự luyện tập: Playground Roblox