ผู้เล่นสามารถเก็บเหรียญและสูญเสียมันเมื่อพวกเขาตาย แต่เหรียญเหล่านั้นไม่ทำอะไร และส่วนใหญ่ของโลก 3D ไม่สามารถเข้าถึงได้หากไม่มีความสามารถในการกระโดดสูงมาก ในส่วนนี้ของบทเรียนจะสอนวิธีการทำให้ตรรกะของเกมของคุณเสร็จสมบูรณ์โดยการเพิ่มปุ่มบนหน้าจอที่ใช้เหรียญเพื่อเพิ่มพลังการกระโดด
สร้างปุ่มอัปเกรด
อินเทอร์เฟซ 2D ใน Roblox มักประกอบด้วยการรวบรวมส่วนประกอบ GUI ภายในคอนเทนเนอร์ GUI ในกรณีนี้ คุณต้องการเพียง TextButton ที่เขียนว่า อัปเกรดกระโดด (5 เหรียญ) ภายในคอนเทนเนอร์ ScreenGui
ใน ReplicatedStorage สร้างโฟลเดอร์ชื่อ Instances
ภายในโฟลเดอร์ Instances สร้าง ScreenGui ชื่อ JumpPurchaseGui โดยปิดการใช้งาน ResetOnSpawn
ภายใน JumpPurchaseGui สร้าง TextButton ชื่อ JumpButton โดยมีคุณสมบัติดังต่อไปนี้:
- Text: "อัปเกรดกระโดด (5 เหรียญ)"
- TextSize: 25
- AnchorPoint: 1, 1
- Position: {1, 0}, {1, 0}
นอกจากนี้ภายในโฟลเดอร์ Instances สร้าง RemoteFunction ชื่อ IncreaseJumpPowerFunction
สุดท้ายในบริการ StarterPlayer ให้เปิดใช้งานคุณสมบัติ CharacterUseJumpPowerกำหนดข้อมูลพลังการกระโดด
ขณะนี้มีเพียงจำนวนเหรียญที่ถูกเก็บไว้สำหรับผู้เล่นแต่ละคนในสคริปต์โมดูล PlayerData คุณต้องเก็บและอัปเดตพลังการกระโดดในลักษณะเดียวกัน เนื่องจากฟังก์ชันใน PlayerData ไม่เฉพาะเจาะจงกับข้อมูลที่ถูกเปลี่ยนแปลง สิ่งที่ต้องทำเพื่อเก็บพลังการกระโดดของผู้เล่นคือการเพิ่มคีย์ Jump และเริ่มค่าตั้งต้นใน defaultPlayerData()
ใน ServerStorage ให้แทนที่โค้ดของโมดูล PlayerData ที่มีอยู่ด้วยโค้ดต่อไปนี้:
```lua
local PlayerData = {}
PlayerData.COIN_KEY_NAME = "Coins"
PlayerData.JUMP_KEY_NAME = "Jump"
local playerData = {
--[[
[userId: string] = {
["Coins"] = coinAmount: number,
["Jump"] = jumpPower: number
}
--]]
}
local function defaultPlayerData()
return {
[PlayerData.COIN_KEY_NAME] = 0,
[PlayerData.JUMP_KEY_NAME] = 0,
}
end
local function getData(player)
local data = playerData[tostring(player.UserId)] or defaultPlayerData()
playerData[tostring(player.UserId)] = data
return data
end
function PlayerData.getValue(player, key)
return getData(player)[key]
end
function PlayerData.updateValue(player, key, updateFunction)
local data = getData(player)
local oldValue = data[key]
local newValue = updateFunction(oldValue)
data[key] = newValue
return newValue
end
return PlayerData
```อัปเดตข้อมูลพลังการกระโดด
ตอนนี้ PlayerData สามารถติดตามพลังการกระโดดได้ คุณต้องดำเนินการตรรกะบนเซิร์ฟเวอร์เพื่ออัปเกรดพลังการกระโดดจากคำขอของลูกค้า
เซิร์ฟเวอร์และลูกค้าสามารถสื่อสารผ่าน RemoteEvents หรือ RemoteFunctions อีเวนต์ระยะไกลจะไม่หยุดชะงักเมื่อถูกเรียกใช้และสามารถใช้สำหรับการสื่อสารแบบทางเดียว ฟังก์ชันระยะไกลในทางกลับกันจะหยุดชะงักจนกว่าจะได้รับการตอบกลับ ซึ่งช่วยให้สามารถสื่อสารแบบสองทางได้
สำหรับบทเรียนนี้ ลูกค้าต้องรู้ว่าเซิร์ฟเวอร์ได้อัปเกรดพลังการกระโดดของผู้เล่นสำเร็จหรือไม่ ดังนั้นคุณควรใช้ฟังก์ชันระยะไกล
ใน ServerScriptService สร้างสคริปต์ชื่อ JumpService โดยมีโค้ดดังต่อไปนี้:
```lua
-- Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Modules
local Leaderboard = require(ServerStorage.Leaderboard)
local PlayerData = require(ServerStorage.PlayerData)
-- Events
local IncreaseJumpPowerFunction = ReplicatedStorage.Instances.IncreaseJumpPowerFunction
local JUMP_KEY_NAME = PlayerData.JUMP_KEY_NAME
local COIN_KEY_NAME = PlayerData.COIN_KEY_NAME
local JUMP_POWER_INCREMENT = 30
local JUMP_COIN_COST = 5
local function updateJumpPower(player, updateFunction)
-- อัปเดตตารางพลังการกระโดด
local newJumpPower = PlayerData.updateValue(player, JUMP_KEY_NAME, updateFunction)
-- อัปเดตพลังการกระโดดของผู้เล่น
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
humanoid.JumpPower = newJumpPower
-- อัปเดตกระดานผู้นำการกระโดด
Leaderboard.setStat(player, JUMP_KEY_NAME, newJumpPower)
end
end
local function onPurchaseJumpIncrease(player)
local coinAmount = PlayerData.getValue(player, COIN_KEY_NAME)
if coinAmount < JUMP_COIN_COST then
return false
end
-- เพิ่มพลังการกระโดดของผู้เล่น
updateJumpPower(player, function(oldJumpPower)
oldJumpPower = oldJumpPower or 0
return oldJumpPower + JUMP_POWER_INCREMENT
end)
-- อัปเดตตารางเหรียญ
local newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, function(oldCoinAmount)
return oldCoinAmount - JUMP_COIN_COST
end)
-- อัปเดตกระดานผู้นำเหรียญ
Leaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)
return true
end
local function onCharacterAdded(player)
-- รีเซ็ตพลังการกระโดดของผู้เล่นเมื่อมีการเพิ่มตัวละคร
updateJumpPower(player, function(_)
return 0
end)
end
-- เริ่มต้นผู้เล่นใด ๆ ที่ถูกเพิ่มก่อนที่จะเชื่อมต่อกับเหตุการณ์ PlayerAdded
for _, player in Players:GetPlayers() do
onCharacterAdded(player)
end
-- การเริ่มต้นปกติของผู้เล่นจากเหตุการณ์ PlayerAdded
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function()
onCharacterAdded(player)
end)
end
local function onPlayerRemoved(player)
updateJumpPower(player, function(_)
return nil
end)
end
IncreaseJumpPowerFunction.OnServerInvoke = onPurchaseJumpIncrease
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoved)
```ส่วนต่อไปนี้จะอธิบายโค้ดในรายละเอียดมากขึ้น
อัปเดตข้อมูลพลังการกระโดด - updateJumpPower() อัปเดตพลังการกระโดดของผู้เล่นและกระดานผู้นำเพื่อให้มีการตอบสนองทางภาพ ฟังก์ชันนี้มีลักษณะคล้ายกับโค้ดที่ทำให้ผู้เล่นได้รับความเสียหายใน สร้างอันตรายให้กับผู้เล่น หากมีโมเดล Character และ Humanoid สำหรับผู้เล่นที่กำลังอัปเกรด ฟังก์ชันจะอัปเดตคุณสมบัติ JumpPower เป็นค่าที่ใหม่ที่เก็บไว้โดย PlayerData โดยเพิ่มขึ้น 30 หากคุณต้องการให้เกมของคุณใช้เวลานานขึ้นเล็กน้อย คุณสามารถลดตัวเลขนี้ได้
ตรวจสอบคำขอจากเซิร์ฟเวอร์ - onPurchaseJumpIncrease() จะตรวจสอบก่อนว่าผู้เล่นมีจำนวนเหรียญที่จำเป็นในการซื้อการอัปเกรดหรือไม่ คำขอทั้งหมด จากลูกค้าไปยังเซิร์ฟเวอร์ควร ได้รับการตรวจสอบ เพื่อป้องกันไม่ให้ผู้ไม่หวังดีส่งคำขอปลอมและใช้ประโยชน์จากเกมของคุณ
เพิ่มปุ่มลงใน GUI ของผู้เล่น
วัตถุ ScreenGui จะแสดงบนหน้าจอได้ก็ต่อเมื่อมันถูกจัดอยู่ในวัตถุ PlayerGui ของผู้เล่น โดยค่าเริ่มต้นจะมี GUI ระบบเช่นหน้าต่างแชท คุณต้องสร้างสคริปต์ใน ReplicatedStorage เพื่อคัดลอกปุ่มอัปเกรดไปยัง GUI ของผู้เล่นแต่ละคนและดำเนินการเมื่อปุ่มถูกกด
ใน ReplicatedStorage สร้างสคริปต์ชื่อ JumpButtonClickHandler โดยตั้งค่า RunContext เป็น Client และโค้ดดังต่อไปนี้:
```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local playerGui = player.PlayerGui
local IncreaseJumpPowerFunction = ReplicatedStorage.Instances.IncreaseJumpPowerFunction
local jumpPurchaseGui = ReplicatedStorage.Instances.JumpPurchaseGui
local jumpButton = jumpPurchaseGui.JumpButton
local function onButtonClicked()
local success, purchased = pcall(IncreaseJumpPowerFunction.InvokeServer, IncreaseJumpPowerFunction)
if not success then
-- purchased จะเป็นข้อความแสดงข้อผิดพลาดหาก success เป็น false
error(purchased)
elseif success and not purchased then
warn("เหรียญไม่เพียงพอ!")
end
end
jumpButton.Activated:Connect(onButtonClicked)
-- เพิ่ม JumpPurchaseGui ลงใน Gui ของผู้เล่น
jumpPurchaseGui.Parent = playerGui
```ส่วนต่อไปนี้จะอธิบายโค้ดในรายละเอียดมากขึ้น
- รับการอ้างอิงไปยัง GUI และฟังก์ชันเซิร์ฟเวอร์ - ตัวแปร IncreaseJumpPowerFunction, jumpPurchaseGui, และ jumpButton จะเก็บการอ้างอิงไปยังฟังก์ชันและ GUI ที่เรียกฟังก์ชันที่คุณจะต้องใช้ในภายหลัง
- กำหนดตัวจัดการเหตุการณ์ - onButtonClicked() กำหนดตรรกะเมื่อผู้ใช้คลิกปุ่มอัปเกรด มันใช้ pcall() (การเรียกที่ป้องกัน) เพื่อเรียกใช้ RemoteFunction การสื่อสารระหว่างลูกค้าและเซิร์ฟเวอร์เช่นนี้ต้องการ pcall() เพื่อจัดการข้อผิดพลาดหรือปัญหาการเชื่อมต่อ
- เชื่อมต่อตัวจัดการกับปุ่ม - เหตุการณ์ Activated สามารถใช้งานได้ในทุกแพลตฟอร์ม รวมถึงเมาส์, หน้าจอสัมผัส, หรือบริบทของเกมแพด มันจะถูกเรียกใช้เมื่อมีการ คลิก, สัมผัส, หรือ ปล่อยปุ่มเกมแพด
ทดสอบการเล่น
เลือก Test จากเมนูดรอปดาวน์และคลิก Play ปุ่ม อัปเกรดกระโดด จะปรากฏขึ้นที่มุมล่างขวา
ลองคลิกปุ่มก่อนที่คุณจะเก็บเหรียญใด ๆ เพื่อตรวจสอบว่ามันไม่มอบพลังการกระโดดเพิ่มเติมให้คุณ จากนั้นลองเก็บเหรียญและดูว่าการอัปเกรดทำงานเมื่อคุณคลิกอีกครั้ง
เมื่อโค้ดเสร็จสมบูรณ์ ลองปรับความยาก: เพิ่มเหรียญหากจังหวะรู้สึกช้า หรือเอาออกและซ่อนในจุดที่ยากขึ้นหากการอัปเกรดมาง่ายเกินไป