Selamatkan Hewan Peliharaanmu
Pelajaran 18 dari 18 dalam kursus Game Roblox: Simulator Hewan Peliharaan di Coddy.
Koin, Desert, dan setiap pet harus tetap ada saat pemain bergabung lagi nanti. DataStore menyimpan sebuah tabel untuk setiap pemain, berdasarkan UserId-nya. Pet adalah instance yang tidak dapat disimpan oleh DataStore, jadi simpan tabel biasa berisi nama setiap pet dan apakah pet itu sedang dikeluarkan, lalu buat kembali pet tersebut saat pemain bergabung:
{ Coins = 120, Desert = true, Pets = { { Name = "Fox", Equipped = true } } }Simpan data saat pemain keluar (PlayerRemoving) dan saat server ditutup (game:BindToClose), lalu muat data di PlayerAdded. Kedua pemanggilan bisa gagal di sisi Roblox, jadi bungkus dengan pcall. Di Roblox Studio, DataStore berfungsi setelah place dipublikasikan dan Enable Studio Access to API Services diaktifkan.
Tantangan
Sulit- Dapatkan
DataStoreServicedan DataStore bernamaPets. - Tulis
save(player): simpanCoins,Desert, dan list berisi{ Name, Equipped }untuk setiap pet, dengan UserId pemain sebagai kunci, di dalam pcall. Panggil fungsi ini saatPlayerRemovingdan untuk setiap pemain digame:BindToClose. - Di
PlayerAdded, setelah membuat folder, muat data simpanan (di dalam pcall) dan pulihkan koin, atribut Desert, serta pet (lewati nama yang tidak ada dipetInfo).
Tekan Play, tetaskan pet, tekan Stop lalu Play lagi: pet-mu akan kembali. Lalu tekan Check.
Coba sendiri
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local RunService = game:GetService("RunService")
local Settings = require(game.ReplicatedStorage.Settings)
local remotes = game.ReplicatedStorage.Remotes
local piles = workspace.Piles
local petParts = workspace.PetParts
local pileSpot = {} -- setiap tumpukan -> lokasi tempatnya berada
local lastHit = {} -- setiap pemain -> waktu terakhir mereka memukul
print("A Meadow pile gives " .. Settings.PileValue .. " coins")
-- Settings.Pets berdasarkan nama
local petInfo = {}
for _, info in Settings.Pets do
petInfo[info.Name] = info
end
-- Seekor hewan peliharaan: StringValue dalam folder Pets milik pemain yang menyimpan namanya, dengan
-- kelangkaan dan kekuatannya sebagai atribut
local function givePet(player, name, equipped)
local info = petInfo[name]
local pet = Instance.new("StringValue")
pet.Name = "Pet"
pet.Value = name
pet:SetAttribute("Rarity", info.Rarity)
pet:SetAttribute("Power", info.Power)
pet:SetAttribute("Equipped", equipped)
pet.Parent = player.Pets
return pet
end
-- berapa banyak hewan peliharaan yang dikeluarkan pemain
local function equippedCount(player)
local count = 0
for _, pet in player.Pets:GetChildren() do
if pet:GetAttribute("Equipped") then
count += 1
end
end
return count
end
-- tambahan kekuatan dari hewan peliharaan pemain pada setiap pukulan
local function petPower(player)
local power = 0
for _, pet in player.Pets:GetChildren() do
if pet:GetAttribute("Equipped") then
power += pet:GetAttribute("Power")
end
end
return power
end
-- Setiap pemain mendapat Coins di papan peringkat
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Parent = leaderstats
-- hewan peliharaan yang mereka miliki
local pets = Instance.new("Folder")
pets.Name = "Pets"
pets.Parent = player
end)
-- Tumpukan koin di suatu lokasi: salinan ServerStorage.CoinPile dengan kesehatan
-- dan nilai sebagai atribut
local function spawnPile(spot)
local desert = spot.Parent.Parent.Name == "Desert"
local health = desert and Settings.DesertHealth or Settings.PileHealth
local pile = ServerStorage.CoinPile:Clone()
pile.Position = spot.Position
pile:SetAttribute("MaxHealth", health)
pile:SetAttribute("Health", health)
pile:SetAttribute("Value", desert and Settings.DesertValue or Settings.PileValue)
pile:SetAttribute("Zone", spot.Parent.Parent.Name)
pile.HealthGui.Label.Text = pile:GetAttribute("Health") .. "/" .. pile:GetAttribute("MaxHealth")
pileSpot[pile] = spot
pile.Parent = piles
return pile
end
-- Satu pukulan mengurangi kesehatan tumpukan sebesar 1 ditambah kekuatan hewan peliharaan pemain;
-- Saat mencapai 0, tumpukan hancur dan memberikan nilai koinnya
local function hitPile(player, pile)
local health = pile:GetAttribute("Health") - (1 + petPower(player))
if health > 0 then
pile:SetAttribute("Health", health)
pile.HealthGui.Label.Text = health .. "/" .. pile:GetAttribute("MaxHealth")
return
end
player.leaderstats.Coins.Value += pile:GetAttribute("Value")
local spot = pileSpot[pile]
pileSpot[pile] = nil
pile:Destroy()
-- tumpukan baru muncul di tempat yang sama beberapa detik kemudian
task.delay(Settings.RespawnTime, spawnPile, spot)
end
-- Satu tumpukan di setiap tempat, di setiap zona
for _, zone in workspace.Zones:GetChildren() do
for _, spot in zone.Spawns:GetChildren() do
spawnPile(spot)
end
end
-- client meminta untuk memukul tumpukan. Jangan pernah memercayai client: siapa pun bisa mengirim
-- remote ini dengan apa pun, dari mana pun, secepat yang mereka mau.
remotes.Hit.OnServerEvent:Connect(function(player, pile)
-- tumpukan yang benar-benar ada
if typeof(pile) ~= "Instance" or pile.Parent ~= piles then
return
end
-- dalam jangkauan
local character = player.Character
local root = character and character:FindFirstChild("HumanoidRootPart")
if not root or (root.Position - pile.Position).Magnitude > Settings.Reach then
return
end
-- tidak terlalu cepat
local now = time()
if lastHit[player] and now - lastHit[player] < Settings.HitCooldown then
return
end
lastHit[player] = now
-- di zona yang sudah dibuka pemain
if pile:GetAttribute("Zone") == "Desert" and not player:GetAttribute("Desert") then
return
end
hitPile(player, pile)
end)
-- Pengundian berbobot: Chance setiap pet (dari 100) menentukan bagiannya pada garis
local function rollPet()
local roll = math.random() * 100
for _, info in Settings.Pets do
roll -= info.Chance
if roll <= 0 then
return info.Name
end
end
return Settings.Pets[1].Name
end
-- Menetaskan: prompt telur, dibayar dengan koin
workspace.Egg.ProximityPrompt.Triggered:Connect(function(player)
local coins = player.leaderstats.Coins
if coins.Value < Settings.EggPrice then
return
end
coins.Value -= Settings.EggPrice
local name = rollPet()
-- langsung dikeluarkan jika masih ada tempat
local pet = givePet(player, name, equippedCount(player) < Settings.MaxEquipped)
print(player.Name .. " hatched a " .. name)
-- semua pemain mendapat kabar tentang peliharaan paling langka
if pet:GetAttribute("Rarity") == "Legendary" then
remotes.Announce:FireAllClients(player.Name, name)
end
end)
-- Peliharaan yang dikeluarkan mengikuti pemiliknya: masing-masing memiliki bagian di dunia, tersusun dalam
-- barisan di belakang pemain pada setiap frame
local petModels = {} -- setiap peliharaan -> bagiannya di dunia
RunService.Heartbeat:Connect(function()
for _, player in Players:GetPlayers() do
local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
local pets = player:FindFirstChild("Pets")
local slot = 0
for _, pet in pets and pets:GetChildren() or {} do
local model = petModels[pet]
if pet:GetAttribute("Equipped") and root then
slot += 1
if not model then
model = ServerStorage.PetModels[pet.Value]:Clone()
model.Parent = petParts
petModels[pet] = model
end
model.CFrame = root.CFrame * CFrame.new((slot - 2) * 3, -1.5, 4)
elseif model then
model:Destroy()
petModels[pet] = nil
end
end
end
end)
-- client meminta agar peliharaan dikeluarkan atau disimpan. server memeriksa apakah peliharaan itu
-- milik pemain tersebut dan jumlah yang dikeluarkan tidak melebihi MaxEquipped.
remotes.Equip.OnServerEvent:Connect(function(player, pet)
if typeof(pet) ~= "Instance" or pet.Parent ~= player.Pets then
return
end
if pet:GetAttribute("Equipped") then
pet:SetAttribute("Equipped", false)
elseif equippedCount(player) < Settings.MaxEquipped then
pet:SetAttribute("Equipped", true)
end
end)
-- Gerbang Desert: bayar sekali untuk membukanya, hanya bagi pemain tersebut
workspace.Gate.ProximityPrompt.Triggered:Connect(function(player)
local coins = player.leaderstats.Coins
if player:GetAttribute("Desert") or coins.Value < Settings.GatePrice then
return
end
coins.Value -= Settings.GatePrice
player:SetAttribute("Desert", true)
end)
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Game Roblox: Simulator Hewan Peliharaan
Latihan sendiri: Playground Roblox