يمكن للاعبين الآن جمع العملات وفقدانها عند موتهم، لكن العملات لا تفعل شيئًا، ومعظم العالم ثلاثي الأبعاد غير متاح بدون القدرة على القفز عاليًا جدًا. تعلمك هذه القسم من البرنامج التعليمي كيفية إنهاء المنطق للعبتك عن طريق إضافة زر على الشاشة ينفق العملات لزيادة قوة القفز.
إنشاء زر الترقية
تتكون واجهات المستخدم ثنائية الأبعاد في Roblox عادةً من مجموعة من مكونات واجهة المستخدم داخل حاوية واجهة المستخدم. في هذه الحالة، تحتاج فقط إلى مكون TextButton الذي يقول "ترقية القفز (5 عملات)" داخل حاوية ScreenGui.
في ReplicatedStorage، أنشئ مجلدًا باسم Instances.
داخل مجلد Instances، أنشئ ScreenGui باسم JumpPurchaseGui مع تعطيل ResetOnSpawn.
داخل JumpPurchaseGui، أنشئ TextButton باسم JumpButton مع الخصائص التالية:
- النص: "ترقية القفز (5 عملات)"
- حجم النص: 25
- نقطة التثبيت: 1، 1
- الموضع: {1، 0}، {1، 0}
أيضًا داخل مجلد Instances، أنشئ RemoteFunction باسم IncreaseJumpPowerFunction.
أخيرًا، في خدمة StarterPlayer، قم بتمكين خاصية CharacterUseJumpPower.تعريف بيانات قوة القفز
حاليًا، يتم تخزين عدد العملات فقط لكل لاعب في نص البرمجة PlayerData. تحتاج أيضًا إلى تخزين وتحديث قوة القفز بنفس الطريقة. نظرًا لأن الدوال في PlayerData غير محددة للبيانات التي يتم تغييرها، كل ما هو مطلوب لتخزين قوة قفز اللاعب هو إضافة مفتاح Jump وتعيين قيمته الأولية في defaultPlayerData().
في ServerStorage، استبدل كود نص البرمجة PlayerData ModuleScript الحالي بالكود التالي:
```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() يتحقق أولاً مما إذا كان لدى اللاعب العدد الفعلي من العملات المطلوبة لشراء الترقية. يجب التحقق من جميع الطلبات من العملاء إلى الخادم لمنع الجهات الفاعلة السيئة من تقديم طلبات زائفة واستغلال لعبتك.
إضافة الزر إلى واجهة اللاعب
لا يظهر كائن ScreenGui على الشاشة إلا إذا كان مرتبطًا بكائن PlayerGui للاعب. بشكل افتراضي، يحتوي هذا على واجهة النظام مثل نافذة الدردشة. تحتاج الآن إلى إنشاء نص في ReplicatedStorage لنسخ زر الترقية إلى واجهة كل لاعب وتنفيذ سلوك عند الضغط على الزر.
في 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 سيكون رسالة الخطأ إذا كانت النتيجة خاطئة
error(purchased)
elseif success and not purchased then
warn("ليس لديك عملات كافية!")
end
end
jumpButton.Activated:Connect(onButtonClicked)
-- أضف JumpPurchaseGui إلى واجهة اللاعب
jumpPurchaseGui.Parent = playerGui
```تصف الأقسام التالية الكود بمزيد من التفصيل.
- الحصول على مراجع لواجهة المستخدم والدالة الخادمة - تحتوي المتغيرات IncreaseJumpPowerFunction وjumpPurchaseGui وjumpButton على مراجع للدالة وواجهة المستخدم التي تستدعي الدالة التي ستحتاجها لاحقًا.
- تعريف معالج الحدث - onButtonClicked() يحدد المنطق عندما ينقر المستخدمون على زر الترقية. يستخدم pcall() (استدعاء محمي) لاستدعاء RemoteFunction. يتطلب أي تواصل بين العميل والخادم مثل هذا استخدام pcall() للتعامل مع الأخطاء أو مشاكل الاتصال.
- ربط المعالج بالزر - حدث Activated متوافق على جميع المنصات، بما في ذلك الماوس، شاشة اللمس، أو سياقات وحدة التحكم. يتم تفعيله عند النقر أو اللمس أو إفراج زر وحدة التحكم.
اختبار اللعبة
اختر Test من القائمة المنسدلة وانقر على Play. يظهر زر ترقية القفز في الزاوية السفلية اليمنى.
حاول النقر على الزر قبل جمع أي عملات للتحقق من أنه لا يمنحك قوة قفز إضافية، ثم حاول جمع بعض العملات وانظر إذا كانت الترقية تعمل عند النقر مرة أخرى.
مع اكتمال الكود، حاول ضبط الصعوبة: أضف عملات إذا كانت الوتيرة تبدو بطيئة، أو أزل القليل منها وضعها في أماكن أصعب إذا كانت الترقيات تأتي بسهولة كبيرة.