Menu
CoddyTech

Salva la costruzione

Lezione 21 di 22 del corso Gioco Roblox: Tycoon della fabbrica di Coddy.

Tornare a un appezzamento vuoto dopo aver costruito un'intera fabbrica sarebbe doloroso. Il salvataggio del proprietario può anche elencare ciò che ha costruito. Le istanze non possono essere inserite in un DataStore, ma i loro nomi sì, in una lista che ne mantiene l'ordine:

data.Pets = {}
for _, pet in pets:GetChildren() do
	table.insert(data.Pets, pet.Name)
end

Solo il proprietario ha una fabbrica, quindi solo il salvataggio del proprietario contiene la lista.

challenge icon

Sfida

Difficile

Salva anche ciò che ha costruito il proprietario.

  1. In saveFactory, prima del salvataggio, se player == owner, imposta data.Built = {}.
  2. Inserisci al suo interno, nell’ordine, il Name di ogni elemento in tycoon.Built.

Premi «Gioca»: il gioco funziona come prima e la lezione successiva ricostruisce ciò che questa salva. Poi premi «Verifica».

Provalo tu

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")
local DataStoreService = game:GetService("DataStoreService")
local Settings = require(game.ReplicatedStorage.Settings)

local tycoon = workspace.Tycoon
local items = ServerStorage.TycoonItems
local rebirthPad = ServerStorage.RebirthPad
local factoryStore = DataStoreService:GetDataStore("Factory")
local owner = nil
local headline = "Step on the green pad to claim this factory"
local earned = 0

print("Ore is worth " .. Settings.OreValue .. " Cash")

-- Ogni giocatore riceve Cash e Rebirths nella classifica
Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local cash = Instance.new("IntValue")
	cash.Name = "Cash"
	cash.Parent = leaderstats

	local rebirths = Instance.new("IntValue")
	rebirths.Name = "Rebirths"
	rebirths.Parent = leaderstats

	-- quello che questo giocatore aveva l'ultima volta
	local ok, saved = pcall(function()
		return factoryStore:GetAsync(player.UserId)
	end)
	if ok and saved then
		cash.Value = saved.Cash or 0
		rebirths.Value = saved.Rebirths or 0
	end
end)

-- Il cartello sopra la fabbrica
local gui = Instance.new("SurfaceGui")
gui.Parent = tycoon.Sign

local signLabel = Instance.new("TextLabel")
signLabel.Name = "Status"
signLabel.Size = UDim2.fromScale(1, 1)
signLabel.BackgroundColor3 = Color3.fromRGB(25, 25, 35)
signLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
signLabel.TextScaled = true
signLabel.Text = "Step on the green pad to claim this factory"
signLabel.Parent = gui

local function setSign(text)
	signLabel.Text = text
end

-- Ore: una piccola parte che vale Cash, rilasciata sotto un dropper
local function dropOre(dropper)
	local ore = Instance.new("Part")
	ore.Name = "Ore"
	ore.Size = Vector3.new(1, 1, 1)
	ore.Color = Color3.fromRGB(150, 150, 160)
	ore.Position = dropper.Position - Vector3.new(0, 2.5, 0)
	ore:SetAttribute("Value", Settings.OreValue)
	if math.random() < Settings.GoldChance then
		ore.Color = Color3.fromRGB(255, 200, 40)
		ore.Material = Enum.Material.Neon
		ore:SetAttribute("Value", Settings.OreValue * 5)
	end
	ore.Parent = workspace
	Debris:AddItem(ore, 20)
end

-- Un dropper esegue un solo ciclo, indipendentemente da quante volte viene avviato
local function startDropper(dropper)
	if dropper:GetAttribute("Running") then
		return
	end
	dropper:SetAttribute("Running", true)
	task.spawn(function()
		while dropper:IsDescendantOf(workspace) do
			dropOre(dropper)
			task.wait(Settings.DropInterval)
		end
		dropper:SetAttribute("Running", nil)
	end)
end

-- Il nastro trasportatore trasporta tutto ciò che vi si trova sopra
tycoon.Conveyor.AssemblyLinearVelocity = Vector3.new(Settings.BeltSpeed, 0, 0)

-- Il raccoglitore trasforma Ore in Cash
tycoon.Collector.Touched:Connect(function(hit)
	if hit.Name == "Ore" then
		local value = hit:GetAttribute("Value")
		hit:Destroy()
		if owner then
			value = math.floor(value * (1 + owner.leaderstats.Rebirths.Value * Settings.RebirthBonus))
			owner.leaderstats.Cash.Value += value
			earned += value
		end
	end
end)

-- L'upgrader raddoppia una sola volta il valore di ogni Ore che lo attraversa
items.Upgrader.Touched:Connect(function(hit)
	if hit.Name == "Ore" and not hit:GetAttribute("Upgraded") then
		hit:SetAttribute("Upgraded", true)
		hit:SetAttribute("Value", hit:GetAttribute("Value") * 2)
		hit.Color = Color3.fromRGB(155, 89, 182)
	end
end)

-- Pedane che aspettano che venga prima costruito un oggetto
local waiting = Instance.new("Folder")
waiting.Name = "WaitingPads"
waiting.Parent = ServerStorage

-- Pedane già acquistate, conservate per la prossima rinascita
local bought = Instance.new("Folder")
bought.Name = "BoughtPads"
bought.Parent = ServerStorage

-- Una nuova parte sale fino a raggiungere la sua posizione
local function riseIn(part)
	local goal = part.Position
	local transparency = part.Transparency
	part.Position = goal - Vector3.new(0, 8, 0)
	part.Transparency = 1
	TweenService:Create(part, TweenInfo.new(1), { Position = goal, Transparency = transparency }):Play()
end

local function checkComplete()
	if #tycoon.Buttons:GetChildren() == 0 and #waiting:GetChildren() == 0 then
		headline = "Factory complete! Step on the purple pad to rebirth"
		setSign(headline)
		rebirthPad.Parent = tycoon
	end
end

-- Posiziona un oggetto acquistato nella fabbrica
local function build(item)
	item.Parent = tycoon.Built
	if item:IsA("BasePart") then
		riseIn(item)
	end
	for _, part in item:GetDescendants() do
		if part:IsA("BasePart") then
			riseIn(part)
		end
	end
	if item:HasTag("Dropper") then
		-- inizia a rilasciare minerale quando è in posizione
		task.delay(1, startDropper, item)
	end
	for _, pad in waiting:GetChildren() do
		if pad:GetAttribute("After") == item.Name then
			pad.Parent = tycoon.Buttons
		end
	end
	checkComplete()
end

-- Acquisto: la piattaforma scompare e il relativo oggetto viene costruito
local function buy(pad, player)
	if player ~= owner or pad.Parent ~= tycoon.Buttons then
		return
	end
	local cash = player.leaderstats.Cash
	local price = pad:GetAttribute("Price")
	if cash.Value < price then
		return
	end
	cash.Value -= price
	pad.Parent = bought
	build(items:FindFirstChild(pad:GetAttribute("Item")))
end

for _, pad in tycoon.Buttons:GetChildren() do
	pad.Touched:Connect(function(hit)
		local player = Players:GetPlayerFromCharacter(hit.Parent)
		if player then
			buy(pad, player)
		end
	end)
end

-- Un cartellino con il prezzo compare sopra ogni piattaforma
for _, pad in tycoon.Buttons:GetChildren() do
	local tag = Instance.new("BillboardGui")
	tag.Name = "PriceTag"
	tag.Size = UDim2.fromOffset(160, 40)
	tag.StudsOffset = Vector3.new(0, 3, 0)
	tag.Parent = pad

	local label = Instance.new("TextLabel")
	label.Size = UDim2.fromScale(1, 1)
	label.BackgroundColor3 = Color3.fromRGB(25, 25, 35)
	label.BackgroundTransparency = 0.2
	label.TextColor3 = Color3.fromRGB(255, 255, 255)
	label.TextScaled = true
	label.Text = pad:GetAttribute("Label") .. ": $" .. pad:GetAttribute("Price")
	label.Parent = tag
end

-- All'inizio sono visibili solo le prime piattaforme
for _, pad in tycoon.Buttons:GetChildren() do
	if pad:GetAttribute("After") then
		pad.Parent = waiting
	end
end

-- Ritorno a una fabbrica vuota: gli oggetti tornano nel deposito e le piattaforme nelle posizioni iniziali
local function resetFactory()
	rebirthPad.Parent = ServerStorage
	for _, item in tycoon.Built:GetChildren() do
		item.Parent = items
	end
	for _, pad in bought:GetChildren() do
		if pad:GetAttribute("After") then
			pad.Parent = waiting
		else
			pad.Parent = tycoon.Buttons
		end
	end
end

rebirthPad.Touched:Connect(function(hit)
	local player = Players:GetPlayerFromCharacter(hit.Parent)
	if player and player == owner and rebirthPad.Parent == tycoon then
		resetFactory()
		player.leaderstats.Rebirths.Value += 1
		player.leaderstats.Cash.Value = 0
		headline = player.Name .. "'s Factory"
		setSign(headline)
	end
end)

-- Salvataggio: Cash e Rebirths
local function saveFactory(player)
	local data = {
		Cash = player.leaderstats.Cash.Value,
		Rebirths = player.leaderstats.Rebirths.Value,
	}
	-- Lezione 21: qui va Save the Build
	pcall(function()
		factoryStore:SetAsync(player.UserId, data)
	end)
end

-- Quando il proprietario se ne va, la fabbrica viene salvata e può essere rivendicata di nuovo
Players.PlayerRemoving:Connect(function(player)
	saveFactory(player)
	if player == owner then
		owner = nil
		resetFactory()
		tycoon.ClaimPad.Color = Color3.fromRGB(46, 204, 113)
		tycoon.ClaimPad.Material = Enum.Material.Neon
		headline = "Step on the green pad to claim this factory"
		setSign(headline)
	end
end)

game:BindToClose(function()
	for _, player in Players:GetPlayers() do
		saveFactory(player)
	end
end)

-- Il cartello mostra i guadagni del proprietario ogni 5 secondi
task.spawn(function()
	while true do
		task.wait(5)
		if owner then
			setSign(headline .. "\n$" .. math.floor(earned / 5) .. " a second")
		end
		earned = 0
	end
end)

-- Rivendicazione: il primo giocatore che sale sulla piattaforma diventa proprietario della fabbrica
local claimPad = tycoon.ClaimPad
claimPad.Touched:Connect(function(hit)
	local player = Players:GetPlayerFromCharacter(hit.Parent)
	if player and not owner then
		owner = player
		claimPad.Color = Color3.fromRGB(120, 120, 120)
		claimPad.Material = Enum.Material.SmoothPlastic
		headline = player.Name .. "'s Factory"
		setSign(headline)
		for _, dropper in CollectionService:GetTagged("Dropper") do
			if dropper:IsDescendantOf(workspace) then
				startDropper(dropper)
			end
		end
	end
end)

Tutte le lezioni di Gioco Roblox: Tycoon della fabbrica

Esercitati da solo: Playground Roblox