שער המדבר
שיעור 16 מתוך 20 בקורס משחק Roblox: סימולטור חיות מחמד של Coddy.
הקיר האדום מאחור הוא השער למדבר, עם בקשת "פתיחה". תשלום של Settings.GatePrice אמור לפתוח אותו, אבל רק עבור השחקן ששילם.
לשם כך דרושים שני הצדדים. השרת גובה את המטבעות ומתעד את פתיחת השער כמאפיין של השחקן, Desert, שכל כלל יכול לבדוק. הלקוח עוקב אחר המאפיין הזה ופותח את השער במסך שלו בלבד: ב-Roblox המכשיר של כל שחקן מזיז את הדמות שלו, ולכן קיר ש-LocalScript הופך ללא מוצק מאפשר לשחקן הזה לעבור דרכו, בעוד שהוא נשאר מוצק עבור כל השאר.
-- לקוח
workspace.Gate.CanCollide = false
workspace.Gate.Transparency = 0.7הסתרת בקשת השער באותה הדרך מונעת ממנו להציע פתיחה נוספת.
אתגר
קשהפתח את שער המדבר עבור השחקן שמשלם.
- ב-
PetServer, בתוךworkspace.Gate.ProximityPrompt.Triggered: עצור אם לשחקן יש את המאפייןDesertאו שיש לו פחות מטבעות מ-Settings.GatePrice; אחרת, גבֵה את המחיר והגדר אתDesertלערך true. - ב-
PetClient, בתוךopenGate(): אםme:GetAttribute("Desert"), הגדר את CanCollide של השער לערך false ואת Transparency לערך 0.7. קרא לפונקציה עכשיו וגם כאשר Desert משתנה.
לחץ על „שחק”, הרוויח 100 מטבעות ופתח את השער: הקיר ייעלם בהדרגה. ואז לחץ על „בדיקה”.
נסו בעצמכם
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 = {} -- כל ערימה -> המקום שעליו היא עומדת
local lastHit = {} -- כל שחקן -> מתי הוא היכה בפעם האחרונה
print("A Meadow pile gives " .. Settings.PileValue .. " coins")
-- Settings.Pets לפי שם
local petInfo = {}
for _, info in Settings.Pets do
petInfo[info.Name] = info
end
-- חיית מחמד: StringValue בתיקיית Pets של השחקן, שמכיל את שמה, עם
-- הנדירות והעוצמה שלה כתכונות
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
-- כמה חיות מחמד פעילות יש לשחקן
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
-- מה חיות המחמד של השחקן מוסיפות לכל מכה
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
-- כל שחקן מקבל Coins בטבלת המובילים
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
-- חיות המחמד שבבעלותם
local pets = Instance.new("Folder")
pets.Name = "Pets"
pets.Parent = player
end)
-- ערימת מטבעות במקום מסוים: עותק של ServerStorage.CoinPile עם כמות הבריאות שלה
-- והערך שלה כתכונות
local function spawnPile(spot)
local pile = ServerStorage.CoinPile:Clone()
pile.Position = spot.Position
pile:SetAttribute("MaxHealth", Settings.PileHealth)
pile:SetAttribute("Health", Settings.PileHealth)
pile:SetAttribute("Value", Settings.PileValue)
pile.HealthGui.Label.Text = pile:GetAttribute("Health") .. "/" .. pile:GetAttribute("MaxHealth")
pileSpot[pile] = spot
pile.Parent = piles
return pile
end
-- מכה מפחיתה 1, בתוספת העוצמה של חיות המחמד של השחקן, מהבריאות של ערימה;
-- כשהערך מגיע ל-0, הערימה נשברת ומעניקה את שווייה
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()
-- ערימה חדשה באותו מקום, כעבור כמה שניות
task.delay(Settings.RespawnTime, spawnPile, spot)
end
-- ערימה בכל נקודה ב-Meadow
for _, spot in workspace.Zones.Meadow.Spawns:GetChildren() do
spawnPile(spot)
end
-- הלקוח מבקש להכות בערימה. לעולם אין לסמוך על הלקוח: כל אחד יכול להפעיל
-- את האירוע המרוחק הזה עם כל דבר, מכל מקום, בתדירות שירצה.
remotes.Hit.OnServerEvent:Connect(function(player, pile)
-- ערימה אמיתית
if typeof(pile) ~= "Instance" or pile.Parent ~= piles then
return
end
-- בטווח
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
-- לא מהר מדי
local now = time()
if lastHit[player] and now - lastHit[player] < Settings.HitCooldown then
return
end
lastHit[player] = now
hitPile(player, pile)
end)
-- הגרלה משוקללת: ה-Chance של כל חיית מחמד (מתוך 100) הוא חלקה בטווח
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
-- בקיעה: הממשק של הביצה, שהתשלום עבורו הוא במטבעות
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()
-- נמצאת בחוץ מיד, אם יש מקום
local pet = givePet(player, name, equippedCount(player) < Settings.MaxEquipped)
print(player.Name .. " hatched a " .. name)
end)
-- חיות מחמד שנמצאות בחוץ עוקבות אחרי בעליהן: לכל אחת יש חלק בעולם, שממוקם
-- בשורה מאחורי השחקן בכל פריים
local petModels = {} -- כל חיית מחמד -> החלק שמייצג אותה בעולם
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)
-- הלקוח מבקש להוציא חיית מחמד או להחזיר אותה. השרת בודק שחיית המחמד
-- שייכת לשחקן, ושלא הוצאו יותר מ-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)
כל השיעורים ביחידה משחק Roblox: סימולטור חיות מחמד
תרגלו בעצמכם: Roblox אונליין