Menu
CoddyTech

Đặt tháp

Bài học 8 trên 22 trong khóa học Trò chơi Roblox: phòng thủ tháp của Coddy.

Một lần nhấp vào một trong các bệ màu xám sẽ dựng tháp đã chọn tại đó. Máy khách nhận biết lần nhấp chuột: me:GetMouse(), sự kiện Button1Down của nó và Target, bộ phận nằm dưới con trỏ. Nhưng máy khách không thể tự dựng gì cả: các tháp nằm trên máy chủ. Máy khách gửi yêu cầu thông qua RemoteEvent Remotes.Place:

-- Máy khách
remotes.Place:FireServer(workspace.Pads.Pad4, "Frost")
-- Máy chủ: Roblox thêm người chơi trước
remotes.Place.OnServerEvent:Connect(function(player, pad, kind)
end)

Các mô hình tháp chờ trong ServerStorage.Towers; máy chủ tạo một bản sao đặt lên bệ, nâng cao thêm nửa chiều cao của bệ cộng với 1 để tháp đứng trên mặt bệ.

challenge icon

Thử thách

Trung bình

Xây tháp đã chọn trên ô bạn nhấp.

  1. Trong DefenseClient, lấy remotes (bằng WaitForChild) và me, tức LocalPlayer.
  2. Khi me:GetMouse().Button1Down xảy ra, nếu mouse.Target nằm trong workspace.Pads và selected đã có giá trị, hãy gọi remotes.Place:FireServer(target, selected).
  3. Trong DefenseServer, remotes.Place.OnServerEvent gọi placeTower(pad, kind): sao chép ServerStorage.Towers[kind] lên ô đó, trong workspace.Towers.

Nhấn Chơi, chọn Archer rồi nhấp vào một ô màu xám: một Archer sẽ đứng trên đó. Sau đó nhấn Kiểm tra.

Tự làm thử

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")

-- Các điểm mốc theo thứ tự (tên của chúng là 1, 2, 3...)
local waypoints = workspace.Path.Waypoints:GetChildren()
table.sort(waypoints, function(a, b)
	return tonumber(a.Name) < tonumber(b.Name)
end)

-- Máu của căn cứ là một thuộc tính của workspace: mọi client đều có thể đọc
workspace:SetAttribute("BaseHealth", Settings.BaseHealth)

-- Mỗi người chơi nhận Money 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 money = Instance.new("IntValue")
	money.Name = "Money"
	money.Value = Settings.StartMoney
	money.Parent = leaderstats
end)

-- Một kẻ địch đã đến căn cứ
local function damageBase(amount)
	local health = math.max(0, workspace:GetAttribute("BaseHealth") - amount)
	workspace:SetAttribute("BaseHealth", health)
	print("Base: " .. health)
end

-- Cho kẻ địch đi theo đường đi. MoveTo dừng sau 8 giây và báo lại
-- (MoveToFinished với false), nên tiếp tục ra lệnh cho kẻ địch chậm di chuyển đến khi nó tới nơi.
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
	-- Nó đã đến căn cứ
	damageBase(Settings.Enemies[enemy.Name].Damage)
	enemy:Destroy()
end

-- Một kẻ địch mới ở cổng, đang đi theo đường đi
local function spawnEnemy(kind)
	local enemy = ServerStorage.Enemies[kind]:Clone()
	-- Xuất hiện ngay phía trên điểm mốc đầu tiên
	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

-- Một đợt: cho từng kẻ địch xuất hiện, rồi chờ đến khi không còn kẻ nào
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

-- Các đợt, mỗi đợt bắt đầu sau một khoảng nghỉ
for i, list in Settings.Waves do
	task.wait(Settings.WaveBreak)
	runWave(list)
end

Tất cả bài học trong Trò chơi Roblox: phòng thủ tháp

Tự luyện tập: Playground Roblox