الآن بعد أن يمكنك اكتشاف متى جمع اللاعب عملة، تحتاج إلى حساب عدد العملات التي جمعها اللاعبون وجعل هذا المبلغ مرئيًا على لوحة المتصدرين.
إنشاء نص برمجي للوحدة لتسجيل جمع العملات
للتعامل مع تخزين وإدارة بيانات جمع العملات لكل لاعب، تحتاج إلى إنشاء كائن ModuleScript يحتوي على هيكل بيانات ووظائف للوصول إلى بيانات جمع العملات لكل لاعب. نصوص الوحدات هي كود قابل لإعادة الاستخدام يمكن أن تتطلبه نصوص أخرى. في هذه الحالة، يتطلب CoinService هذا النص البرمجي للوحدة حتى يتمكن من تحديث بيانات جمع العملات عندما يلمس اللاعبون العملات.
في ServerStorage، أنشئ ModuleScript باسم PlayerData مع الكود التالي:
```lua
local PlayerData = {}
PlayerData.COIN_KEY_NAME = "Coins"
local playerData = {
--[[
[userId: string] = {
["Coins"] = coinAmount: number
}
]]
}
local function defaultPlayerData()
return {
[PlayerData.COIN_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 الذي يحتوي على صفر أو العديد من جداول playerData، والتي تمثل بيانات جمع العملات للاعب. كل نص برمجي يتطلب هذا النص البرمجي للوحدة يتلقى نفس نسخة جدول PlayerData، مما يسمح لعدة نصوص برمجية بتعديل ومشاركة بيانات جمع العملات.
إعلان هياكل البيانات
يبدأ نص البرمجة للوحدة بإعلان جدول فارغ، PlayerData، والذي يتم إرجاعه في نهاية النص. كما يحتوي على طرق وصول للحصول على القيم وتعيينها في الجدول.
يحتوي جدول playerData على تعليقات تصف هيكل الجدول، مما يجعل الكود أسهل في الفهم. في هذه الحالة، يحتوي جدول playerData على userId وحقل مطابق يسمى Coins الذي يمثل كمية العملات المجمعة لذلك اللاعب.
local PlayerData = {}
PlayerData.COIN_KEY_NAME = "Coins"
local playerData = {
--[[
[userId: string] = {
["Coins"] = coinAmount: number
}
]]
}
...
return PlayerDataتعريف دالة وصول بيانات محلية
getData() هي دالة محلية تسترجع البيانات لجدول playerData معين. إذا لم يكن اللاعب قد جمع عملة، فإنها ترجع جدولًا من دالة defaultPlayerData() لضمان أن كل لاعب لديه بعض البيانات المرتبطة به. من الشائع إنشاء دوال بسيطة، واجهتها عامة، تقوم بتفريغ المنطق إلى دوال محلية النطاق تقوم بالعمل الشاق.
local function defaultPlayerData()
return {
[PlayerData.COIN_KEY_NAME] = 0
}
end
local function getData(player)
local data = playerData[tostring(player.UserId)] or defaultPlayerData()
playerData[tostring(player.UserId)] = data
return data
endتعريف دوال وصول بيانات عامة
getValue() و updateValue() هما دالتان واجهتهما عامة يمكن أن تستدعيهما نصوص برمجية أخرى تتطلب هذا النص البرمجي للوحدة. في حالتنا، يستخدم CoinService هذه الدوال لتحديث بيانات جمع العملات للاعب كلما لمس ذلك اللاعب عملة.
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تنفيذ لوحة المتصدرين
يمكنك تمثيل بيانات جمع العملات بصريًا من خلال لوحة المتصدرين على الشاشة. يتضمن Roblox نظامًا مدمجًا يقوم تلقائيًا بإنشاء لوحة متصدرين باستخدام واجهة مستخدم افتراضية.
في ServerStorage، أنشئ ModuleScript باسم Leaderboard مع الكود التالي:
```lua
local Leaderboard = {}
-- إنشاء لوحة متصدرين جديدة
local function setupLeaderboard(player)
local leaderstats = Instance.new("Folder")
-- 'leaderstats' هو اسم محجوز يتعرف عليه Roblox لإنشاء لوحة متصدرين
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
return leaderstats
end
-- إنشاء قيمة إحصائية جديدة للوحة المتصدرين
local function setupStat(leaderstats, statName)
local stat = Instance.new("IntValue")
stat.Name = statName
stat.Value = 0
stat.Parent = leaderstats
return stat
end
-- تحديث قيمة إحصائية للاعب
function Leaderboard.setStat(player, statName, value)
local leaderstats = player:FindFirstChild("leaderstats")
if not leaderstats then
leaderstats = setupLeaderboard(player)
end
local stat = leaderstats:FindFirstChild(statName)
if not stat then
stat = setupStat(leaderstats, statName)
end
stat.Value = value
end
return Leaderboard
```الأجزاء التالية تصف كيفية عمل لوحة المتصدرين بمزيد من التفصيل.
إنشاء لوحة المتصدرين
تقوم دالة setupLeaderboard() بإنشاء مثيل مجلد جديد يسمى leaderstats وتعيينه كطفل للاعب المحدد. يتعرف Roblox تلقائيًا على مجلد يسمى leaderstats كحاوية للإحصائيات وينشئ عنصر واجهة مستخدم لعرض الإحصائيات. يتطلب تخزين القيم في leaderstats ككائنات "قيمة" (مثل StringValue، IntValue أو NumberValue).
-- إنشاء لوحة متصدرين جديدة
local function setupLeaderboard(player)
local leaderstats = Instance.new("Folder")
-- 'leaderstats' هو اسم محجوز يتعرف عليه Roblox لإنشاء لوحة متصدرين
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
return leaderstats
end
-- إنشاء قيمة إحصائية جديدة للوحة المتصدرين
local function setupStat(leaderstats, statName)
local stat = Instance.new("IntValue")
stat.Name = statName
stat.Value = 0
stat.Parent = leaderstats
return stat
endتحديث إحصائيات اللاعب
setStat() هي الدالة العامة الوحيدة في وحدة Leaderboard. تقوم بإنشاء قيم إحصائية للاعب المحدد أو للوحة المتصدرين نفسها إذا لم تكن موجودة بالفعل.
تأخذ FindFirstChild() اسم كائن وتعيد الكائن إذا كان موجودًا، أو nil إذا لم يكن موجودًا. إنها طريقة شائعة وآمنة لمعرفة ما إذا كان الكائن موجودًا قبل استخدامه.
-- تحديث قيمة إحصائية للاعب
function Leaderboard.setStat(player, statName, value)
local leaderstats = player:FindFirstChild("leaderstats")
if not leaderstats then
leaderstats = setupLeaderboard(player)
end
local stat = leaderstats:FindFirstChild(statName)
if not stat then
stat = setupStat(leaderstats, statName)
end
stat.Value = value
endدمج نصوص الوحدات
مع وجود كلا الوحدتين في مكانهما، قم بتطلبهما في نص CoinService لإدارة وعرض بيانات عملات اللاعب.
في ServerScriptService، استبدل كود نص CoinService الحالي بالكود التالي:
```lua
-- تهيئة الخدمات والمتغيرات
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
-- الوحدات
local Leaderboard = require(ServerStorage.Leaderboard)
local PlayerData = require(ServerStorage.PlayerData)
local coinsFolder = Workspace.World.Coins
local coins = coinsFolder:GetChildren()
local COIN_KEY_NAME = PlayerData.COIN_KEY_NAME
local COOLDOWN = 10
local COIN_AMOUNT_TO_ADD = 1
local function updatePlayerCoins(player, updateFunction)
-- تحديث جدول العملات
local newCoinAmount = PlayerData.updateValue(player, COIN_KEY_NAME, updateFunction)
-- تحديث لوحة المتصدرين للعملات
Leaderboard.setStat(player, COIN_KEY_NAME, newCoinAmount)
end
-- تعريف معالج الحدث
local function onCoinTouched(otherPart, coin)
if coin:GetAttribute("Enabled") then
local character = otherPart.Parent
local player = Players:GetPlayerFromCharacter(character)
if player then
-- لمس اللاعب لعملة
coin.Transparency = 1
coin:SetAttribute("Enabled", false)
updatePlayerCoins(player, function(oldCoinAmount)
oldCoinAmount = oldCoinAmount or 0
return oldCoinAmount + COIN_AMOUNT_TO_ADD
end)
task.wait(COOLDOWN)
coin.Transparency = 0
coin:SetAttribute("Enabled", true)
end
end
end
-- إعداد مستمعي الأحداث
for _, coin in coins do
coin:SetAttribute("Enabled", true)
coin.Touched:Connect(function(otherPart)
onCoinTouched(otherPart, coin)
end)
end
```تشمل التغييرات على نص CoinService الأصلي:
- إعلان COIN_AMOUNT_TO_ADD كعدد العملات التي ستضاف عندما يجمع اللاعب عملة، و COIN_KEY_NAME كاسم المفتاح المحدد في PlayerData.
- إنشاء دالة المساعدة updatePlayerCoins() لتحديث عدد العملات للاعب والإحصائية المرتبطة بلوحة المتصدرين.
- استبدال عبارة print() النمطية في onCoinTouched() باستدعاء لـ updatePlayerCoins().
اختبار اللعبة
اختر اختبار من القائمة المنسدلة وانقر على تشغيل. امشِ إلى عملة وتأكد من ظهور لوحة المتصدرين في الزاوية وأن عدد العملات لديك يزيد كلما جمعت المزيد من العملات.