Menu
CoddyTech

Разместить башню

Урок 8 из 22 курса Игра в Roblox: Защита башнями на Coddy.

Щелчок по одной из серых площадок размещает на ней выбранную башню. Клиент считывает щелчок мыши: me:GetMouse(), её событие Button1Down и её свойство Target — деталь под указателем. Но сам он ничего построить не может: башни находятся на сервере. Он отправляет запрос через RemoteEvent Remotes.Place:

-- клиент
remotes.Place:FireServer(workspace.Pads.Pad4, "Frost")
-- сервер: Roblox сначала добавляет игрока
remotes.Place.OnServerEvent:Connect(function(player, pad, kind)
end)

Модели башен хранятся в ServerStorage.Towers; сервер клонирует одну из них на площадку, приподняв её на половину высоты площадки плюс 1, чтобы она стояла сверху.

challenge icon

Задание

Средне

Построй выбранную башню на площадке, по которой ты щёлкнешь.

  1. В DefenseClient получи remotes (с помощью WaitForChild) и me — LocalPlayer.
  2. При событии me:GetMouse().Button1Down, если mouse.Target находится в workspace.Pads и задано значение selected, вызови remotes.Place:FireServer(target, selected).
  3. В DefenseServer обработчик remotes.Place.OnServerEvent вызывает placeTower(pad, kind): клонирует ServerStorage.Towers[kind] на площадку, в workspace.Towers.

Нажми «Играть», выбери Archer и щёлкни по серой площадке: на ней появится Archer. Затем нажми «Проверить».

Попробуйте сами

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Settings = require(game.ReplicatedStorage.Settings)

local enemies = workspace.Enemies

print("The base can take " .. Settings.BaseHealth .. " hits")

-- Путевые точки по порядку (они названы 1, 2, 3...)
local waypoints = workspace.Path.Waypoints:GetChildren()
table.sort(waypoints, function(a, b)
	return tonumber(a.Name) < tonumber(b.Name)
end)

-- Здоровье базы — атрибут workspace: каждый клиент может его прочитать
workspace:SetAttribute("BaseHealth", Settings.BaseHealth)

-- Каждый игрок получает Money в таблице лидеров
Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local money = Instance.new("IntValue")
	money.Name = "Money"
	money.Value = Settings.StartMoney
	money.Parent = leaderstats
end)

-- Враг добрался до базы
local function damageBase(amount)
	local health = math.max(0, workspace:GetAttribute("BaseHealth") - amount)
	workspace:SetAttribute("BaseHealth", health)
	print("Base: " .. health)
end

-- Провести врага по пути. MoveTo прекращает попытку через 8 секунд и сообщает об этом
-- (MoveToFinished со значением false), поэтому медленного врага отправляют снова, пока он не доберётся до цели.
local function walkPath(enemy)
	local humanoid = enemy.Humanoid
	for i = 2, #waypoints do
		repeat
			humanoid:MoveTo(waypoints[i].Position)
		until humanoid.MoveToFinished:Wait() or not enemy.Parent
		if not enemy.Parent then
			return
		end
	end
	-- он добрался до базы
	damageBase(Settings.Enemies[enemy.Name].Damage)
	enemy:Destroy()
end

-- Новый враг у ворот, идущий по пути
local function spawnEnemy(kind)
	local enemy = ServerStorage.Enemies[kind]:Clone()
	-- появляется прямо над первой путевой точкой
	enemy:PivotTo(waypoints[1].CFrame + Vector3.new(0, 5, 0))
	local info = Settings.Enemies[kind]
	enemy.Humanoid.MaxHealth = info.Health
	enemy.Humanoid.Health = info.Health
	enemy.Humanoid.WalkSpeed = info.Speed
	enemy.Parent = enemies
	task.spawn(walkPath, enemy)
	return enemy
end

-- Одна волна: её враги появляются по одному, затем ждём, пока все они не исчезнут
local function runWave(list)
	for _, kind in list do
		spawnEnemy(kind)
		task.wait(Settings.SpawnGap)
	end
	while #enemies:GetChildren() > 0 do
		task.wait(0.2)
	end
end

-- Волны, каждая после перерыва
for i, list in Settings.Waves do
	task.wait(Settings.WaveBreak)
	runWave(list)
end

Все уроки раздела Игра в Roblox: Защита башнями

Потренируйтесь самостоятельно: Песочница Roblox