دروس تعليمية متوسطة

إنشاء لوحة متصدرين مخصصة باستخدام متاجر البيانات المرتبة

*This content is translated using AI (Beta) and may contain errors. To view this page in English, click here.

متاجر البيانات هي خدمة يمكنك استخدامها لحفظ وتحميل بيانات اللاعب الدائمة عبر مختلف جلسات اللاعبين. إنها تخزن معلومات مهمة، مثل تقدم اللاعب أو مخزونه، وتسمح لك باسترجاعها للاعب في المرة القادمة التي ينضم فيها إلى لعبتك. بدون متاجر البيانات، سيفقد اللاعب كل تقدمه في كل مرة يترك فيها اللعبة.

هناك نوعان من متاجر البيانات: القياسية والمرتبة. يستخدم هذا البرنامج التعليمي متاجر البيانات المرتبة، والتي تخزن البيانات التي يمكنك ترتيبها وفرزها عدديًا واسترجاعها بترتيب تصاعدي أو تنازلي بناءً على القيم العددية المخزنة.

باستخدام برنامج Gold Rush لإنشاء لوحة المتصدرين - البداية .rbxl كقاعدة البداية وبرنامج Gold Rush لإنشاء لوحة المتصدرين - المكتملة .rbxl كمرجع، يوفر لك هذا البرنامج التعليمي الأساس الذي تحتاجه لإنشاء لوحة متصدرين مخصصة للاعبين، بما في ذلك الإرشادات حول:

  • تخزين درجات الذهب في متجر بيانات مرتبة.
  • استرجاع وترتيب أعلى الدرجات عالميًا عبر جميع الخوادم.
  • عرض أعلى الدرجات في لوحة متصدرين مخصصة في واجهة المستخدم.
  • تحديث لوحة المتصدرين المخصصة تلقائيًا كل بضع ثوانٍ.

بنهاية هذا البرنامج التعليمي، ينبغي أن يكون لديك ما يلي:

  1. تحت ServerScriptService:
    1. نص GoldManager مُحدث يحفظ درجة اللاعب في متجر بيانات مرتبة للوحة المتصدرين.
    2. نص وحدة LeaderboardRemoteHandler جديد يسترجع ويعيد قائمة مرتبة من أعلى الدرجات من لوحة المتصدرين.
    3. نص LeaderboardManager جديد يستجيب لطلبات بيانات لوحة المتصدرين من العميل، acting كحلقة وصل بين العميل في LeaderboardGuiScript والخادم في LeaderboardManager.
  2. تحت StarterGui، نص محلي جديد LeaderboardGuiScript يقوم بعرض واجهة لوحة المتصدرين للاعب.

تمكين الوصول إلى خدمات API في الاستوديو

لا يتم تخزين متاجر البيانات محليًا على جهازك، لذا تعتمد لعبتك على التواصل بين الخادم والخادم مع البنية التحتية لـ Roblox لاستخدامها. بشكل افتراضي، يقيّد الاستوديو هذا التواصل لمنع إساءة الاستخدام أو الاستخدام العرضي. يعد الوصول إلى خدمات API في الاستوديو معطلاً حتى تقوم بتمكينه صراحةً للتأكد من أن الألعاب الموثوقة فقط يمكنها القراءة من وكتابة إلى خوادم Roblox الخلفية.

لتمكين الوصول إلى خدمات API في الاستوديو حتى تتمكن من استخدام متاجر البيانات:

  1. افتح برنامج Gold Rush لإنشاء لوحة المتصدرين - البداية في الاستوديو. يحتوي ملف بداية هذا بالفعل على الكود من البرنامج التعليمي حفظ بيانات اللاعب والهيكل العظمي لواجهة الاستخدام للوحة المتصدرين للاعب.
  2. العودة إلى الاستوديو، انتقل إلى ملفإعدادات التجربةالأمان.
  3. قم بتشغيل تمكين وصول الاستوديو إلى خدمات API.
  4. احفظ تغييراتك.

إنشاء متجر بيانات مرتبة

عند إنشاء متجر بيانات، يجب عليك دائمًا استدعاء DataStoreService من Script على جانب الخادم. يعد ذلك مهمًا لأن:

  • يقوم Roblox بحظر جميع الوصول إلى متجر البيانات من العميل بحيث لا يكون للخادم إذن للوصول إلى البيانات الدائمة للاعبين وتعديلها.
  • تعمل النصوص على جانب الخادم في بيئة مركزية، مما يضمن أن البيانات المقروءة والمكتوبة إلى متجر البيانات الخاص بك دقيقة وصحيحة.
  • نظرًا لأن النصوص على جانب العميل تعمل على جهاز اللاعب، يمكن لأي لاعب استغلال اللعبة وسرقة أو الكتابة فوق بيانات لاعبين آخرين إذا كان العميل لديه وصول إلى متاجر البيانات الخاصة بك.

يجب عليك أيضًا إعطاء متجر البيانات الخاص بك اسمًا فريدًا للحفاظ على تنظيم بياناتك ومنعها من التداخل أو التعارض في متاجر بيانات مختلفة. في هذا البرنامج التعليمي، يسمى متجر البيانات للوحة المتصدرين GlobalLeaderboard.

لإنشاء متجر بيانات مرتبة GlobalLeaderboard:

  1. افتح نص GoldManager الموجود تحت ServerScriptService.

  2. تحت متجر البيانات PlayerGold الموجود، استدعِ GetOrderedDataStore مع السلسلة "GlobalLeaderboard". هذا ينشئ متجر بيانات مرتب لحفظ درجة اللاعب عندما يحصل على الذهب.


    local leaderboardStore = DataStoreService:GetOrderedDataStore("GlobalLeaderboard")

بعد إنشاء متجر بيانات، يمكنك الإشارة إلى هذا المتجر عبر نصوص مختلفة. على سبيل المثال، يمكنك استدعاء GetOrderedDataStore في كل من نص GoldManager ونص وحدة LeaderboardManager الذي ستقوم بإنشائه لاحقًا في هذا البرنامج التعليمي. الإشارة إلى نفس متجر البيانات في مكانين لا تعني أنك تقوم بإنشاء بيانات مكررة؛ بل تعني أن نصين يقومان بالوصول إلى نفس التخزين المركزي، مثل اثنين من زملاء العمل الذين يستخدمون مجلدًا واحدًا لمشاركة المعلومات.

إرسال بيانات اللاعب إلى لوحة المتصدرين

تتكون متاجر البيانات من مفاتيح، تحدد البيانات، وقيم، تقوم بتخزين البيانات. على عكس متاجر البيانات القياسية، تسمح لك متاجر البيانات المرتبة بفرز البيانات حسب القيمة، مما يجعلها مثالية لإنشاء أشياء مثل لوحات المتصدرين.

يتم تخزين كل إدخال في متجر بيانات مرتب تحت مفتاح فريد يمكنك ترتيبه وفرزه عدديًا، ثم استرجاعه بترتيب تصاعدي أو تنازلي بناءً على القيم العددية المخزنة. وهذا يعني أنه يمكنك استخدام متاجر البيانات المرتبة لإظهار قائمة أفضل 3 تتحديث في الوقت الفعلي كما يجمع اللاعبون في لعبتك المزيد من الذهب.

المفتاحالقيمة
الوصفالمفتاح هو معرف سلسلة فريد يمكنك استخدامه للوصول إلى جزء معين من البيانات، مثل معرف مستخدم اللاعب.

تتيح لك المفاتيح تنظيم بياناتك بحيث يمكنك إدارتها وتصحيحها بسهولة.
القيمة هي البيانات العددية الفعلية التي تريد حفظها أو تحميلها، مثل درجة اللاعب.

تمكنك القيم من حفظ التقدم بين الجلسات، بالإضافة إلى استرجاع بيانات اللاعب في المرة القادمة التي ينضم فيها إلى لعبتك.
الأشكال المسموح بهايمكن أن تكون فقط سلاسل. إذا كنت تستخدم أرقامًا، مثل معرف مستخدم، قم بتحويلها إلى سلسلة باستخدام tostring().يمكن أن تكون فقط أرقامًا.
أمثلة"Player_A", "TopScore", "123456" (معرف المستخدم كسلسلة)100, 3.14, 0, -25

الآن بعد أن قمت بإنشاء متجر البيانات المرتب الخاص بك GlobalLeaderboard، قم بتحديث وظيفة saveGold الموجودة في نص GoldManager لإرسال درجة الذهب الخاصة باللاعب إلى لوحة المتصدرين الخاصة بك باستخدام SetAsync:


local function saveGold(player, value)
local userId = player.UserId
local success, err = pcall(function()
goldStore:SetAsync(userId, value)
leaderboardStore:SetAsync(tostring(userId), value)
end)
if not success then
warn("لم يتمكن من حفظ الذهب لـ", player.Name, ":", err)
end
end

يمكنك التفكير في متجر البيانات المرتب GlobalLeaderboard مثل مجلد مشترك: SetAsync يضيف محتوى إلى المجلد، بينما GetSortedAsync (الذي ستقوم بإنشائه لاحقًا في نص وحدة LeaderboardManager) يقرأ محتوى المجلد ويقوم بترتيبه حسب الدرجة.

استرجاع درجات لوحة المتصدرين

لاسترجاع درجات لوحة المتصدرين، يجب عليك استخدام ModuleScript. تتيح لك نصوص الوحدة تنظيم وإعادة استخدام التعليمات البرمجية الخاصة بك عبر نصوص متعددة. بدلاً من نسخ نفس المنطق إلى أماكن مختلفة، يمكنك كتابة ذلك مرة واحدة في نص الوحدة واستدعاؤه من أي مكان يحتاجه.

عندما تقوم بتخزين منطق لوحة المتصدرين الخاصة بك في وحدة، يمكن لكل من معالج واجهة المستخدم ونصوص الخادم استخدام نفس الوظيفة لاسترجاع أعلى درجات اللاعبين. إذا كنت بحاجة إلى تحديث كيفية استرجاع أسماء المستخدمين أو كيفية فرز الدرجات، سيكون عليك تغيير الشفرة في مكان واحد فقط. بعد تحديث الوحدة، تحصل جميع النصوص التي تستخدمها تلقائيًا على السلوك المحدث.

تستخدم لوحة المتصدرين المخصصة الخاصة بك الطرق التالية لمتجر البيانات المرتب لمشاركة البيانات عبر خوادم مختلفة:

  • SetAsync (من نص GoldManager) لإرسال درجات اللاعبين إلى متجر البيانات المرتب GlobalLeaderboard.
  • GetSortedAsync (في نص الوحدة) لاسترجاع أعلى الدرجات من جميع الخوادم من نفس متجر البيانات. طريقة GetSortedAsync خاصة بمتاجر البيانات المرتبة ويمكنها استرجاع مفاتيح مرتبة متعددة بناءً على ترتيب فرز معين، وحجم الصفحة، والقيم الدنيا والقصوى.

لاسترجاع درجات لوحة المتصدرين:

  1. تحت ServerScriptService، أنشئ نصًا جديدًا من نوع ModuleScript يسمى LeaderboardManager.

  2. في أعلى نص الوحدة، استدعِ GetOrderedDataStore مع السلسلة "GlobalLeaderboard". سيتيح الإشارة إلى نفس متجر البيانات المرتب الذي أنشأته في نص GoldManager لواجهة المستخدم للوحة المتصدرين استرجاع وترتيب أعلى درجات اللاعبين لاحقًا.


    local DataStoreService = game:GetService("DataStoreService")
    local Players = game:GetService("Players")
    local leaderboardStore = DataStoreService:GetOrderedDataStore("GlobalLeaderboard")
  3. أعد إعداد جدول وحدة لتخزين جميع الوظائف والبيانات التي تريد عرضها على النصوص الأخرى.


    local leaderboardManager = {}
  4. أنشئ وظيفة تسمى GetTopScores للحصول على أعلى درجات اللاعبين. هذه الوظيفة:

    • تستدعي GetSortedAsync لاسترجاع عدد محدد من أعلى الدرجات بترتيب تنازلي. إذا فشلت المكالمة، يتم إرجاع قائمة فارغة لمنع بقية الكود لديك من الانهيار.
    • تتكرر عبر لوحة المتصدرين للحصول على جدول من الإدخالات باستخدام GetCurrentPage وأسماء مستخدمين اللاعبين باستخدام GetNameFromUserIdAsync.
    • تضيف كل نتيجة إلى قائمة نهائية وتبني جدول لوحة المتصدرين مع أسماء مستخدمي اللاعبين ودرجاتهم.
    • تعيد القائمة النهائية من اللاعبين وتعيد بيانات لوحة المتصدرين إلى أي نص يستدعي هذه الوظيفة leaderboardManager.GetTopScores.

    function leaderboardManager.GetTopScores(limit)
    local success, pages = pcall(function()
    return leaderboardStore:GetSortedAsync(false, limit)
    end)
    if not success or not pages then
    return {}
    end
    local results = {}
    for _, entry in ipairs(pages:GetCurrentPage()) do
    local userId = tonumber(entry.key)
    local score = entry.value
    local username = "غير معروف"
    local ok, name = pcall(function()
    return Players:GetNameFromUserIdAsync(userId)
    end)
    if ok then
    username = name
    end
    table.insert(results, {
    Username = username,
    Score = score
    })
    end
    return results
    end
  5. اجعل الوحدة قابلة للاستخدام من خلال إرجاع جدول الوحدة الذي أنشأته سابقًا. كلما قمت بإنشاء نص وحدة، يجب عليك إرجاع جدول الوحدة بحيث يمكن للنصوص الأخرى الوصول إليه واستدعاء الوظائف الموجودة بداخله.


    return leaderboardManager

طلب بيانات لوحة المتصدرين من الخادم

لكي تعرض واجهة العميل درجات لوحة المتصدرين، يجب أن يستجيب الخادم عندما يطلب العميل البيانات. يسمح RemoteFunction للعميل بطلب معلومات من الخادم والانتظار لرد.

لطلب بيانات لوحة المتصدرين من الخادم:

  1. تحت ReplicatedStorage، أدخل RemoteFunction جديدة تُسمى LeaderboardRemote. تعمل هذه الوظيفة البعيدة كجسر بين نص واجهة المستخدم على العميل ومنطق لوحة المتصدرين على الخادم.
  2. تحت ServerScriptService، أنشئ نصًا يسمى LeaderboardRemoteHandler. في هذا النص:
    1. استدعِ ReplicatedStorage (المساحة المشتركة بين العميل والخادم)، وServerScriptService (الذي يحتوي على وحدة لوحة المتصدرين)، وleaderboardRemote (الوظيفة البعيدة التي سيقوم العميل باستدعائها لطلب بيانات لوحة المتصدرين).


      local ReplicatedStorage = game:GetService("ReplicatedStorage")
      local ServerScriptService = game:GetService("ServerScriptService")
      local leaderboardRemote = ReplicatedStorage:WaitForChild("LeaderboardRemote")
    2. قم بتحميل وحدة LeaderboardManager التي أنشأتها سابقًا، والتي تحتوي على الوظيفة التي تحصل على أعلى الدرجات من متجر البيانات المرتب.


      local leaderboardManager = require(ServerScriptService:WaitForChild("LeaderboardManager"))
    3. قم بتعيين السلوك عندما يستدعي العميل InvokeServer. يستجيب الخادم عن طريق استرجاع أعلى 3 درجات وإرسال النتيجة مرة أخرى إلى العميل.


      leaderboardRemote.OnServerInvoke = function(player)
      return leaderboardManager.GetTopScores(3)
      end

عرض البيانات في واجهة لوحة المتصدرين المخصصة

بعد إعداد النصوص على جانب الخادم، قم بإنشاء نص محلي لجلب أفضل 3 لاعبين كل 3 ثوانٍ وعرض النتائج في واجهة مستخدم لوحة متصدرين عالمية داخل اللعبة.

لعرض البيانات في لوحة المتصدرين المخصصة الخاصة بك:

  1. تحت StarterGuiLeaderboardGui، أنشئ نصًا محليًا يسمى LeaderboardGuiScript.

  2. في أعلى النص، اتصل بالوظيفة البعيدة. استدعِ ReplicatedStorage للحصول على الوصول إلى الكائنات المشتركة بين العميل والخادم، ثم استدعِ leaderboardRemote للسماح للعميل بطلب بيانات لوحة المتصدرين من الخادم.


    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local leaderboardRemote = ReplicatedStorage:WaitForChild("LeaderboardRemote")
  3. قم بالإشارة إلى عناصر واجهة المستخدم الموجودة تحت LeaderboardGui.


    local gui = script.Parent
    local leaderboardFrame = gui:WaitForChild("LeaderboardFrame")
    local entriesFrame = leaderboardFrame:WaitForChild("EntriesFrame")
    local template = entriesFrame:WaitForChild("LeaderboardEntry")
  4. أنشئ وظيفة تسمى clearEntries لمسح إدخالات لوحة المتصدرين القديمة. تقوم هذه الوظيفة بالإفراط في جميع الأطفال في entriesFrame، والذي يحتوي على صفوف لوحة المتصدرين، وتتأكد من تحديث لوحة المتصدرين بالكامل قبل عرض بيانات جديدة.


    local function clearEntries()
    for _, child in ipairs(entriesFrame:GetChildren()) do
    if child:IsA("TextLabel") and child.Name:match("^Row%d+$") then
    child:Destroy()
    end
    end
    end
  5. أنشئ وظيفة تسمى renderLeaderboard لإدراج وعرض بيانات اللاعبين في صفوف لوحة المتصدرين. كائن data هو جدول تم إرجاعه من الخادم يحتوي على إدخالات مع أسماء مستخدمي اللاعبين ودرجاتهم.


    local function renderLeaderboard(data)
    clearEntries()
    for i, entry in ipairs(data) do
    local row = template:Clone()
    row.Name = "Row" .. i
    row.Visible = true
    row.LayoutOrder = i
    row.Text = string.format("%d%s place: %s - %d",
    i, i == 1 and "st" or i == 2 and "nd" or i == 3 and "rd" or "th",
    entry.Username, entry.Score)
    row.Parent = entriesFrame
    end
    end
  6. أنشئ حلقة لجلب بيانات لوحة المتصدرين دوريًا. كل 3 ثوانٍ، تعمل الحلقة وتستدعي الخادم باستخدام وظيفة InvokeServer التي أنشأتها سابقًا في نص LeaderboardRemoteHandler. إذا كانت المكالمة ناجحة، تُنتعش واجهة المستخدم مع الدرجات المحدثة.


    while true do
    local success, data = pcall(function()
    return leaderboardRemote:InvokeServer()
    end)
    if success and data then
    renderLeaderboard(data)
    end
    task.wait(3)
    end

الكود النهائي

انظر إلى مقتطفات الكود التالية للشفرة الكاملة لنصوص GoldManager و LeaderboardManager و LeaderboardRemoteHandler و LeaderboardGuiScript. يمكنك لصقها وتشغيلها مباشرة في برنامج Gold Rush لإنشاء لوحة المتصدرين - البداية .rbxl في الاستوديو.

GoldManager

نص GoldManager ينشئ متجر بيانات مرتب لإدارة تحديثات لوحة المتصدرين.


-- الحصول على الخدمات
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local DataStoreService = game:GetService("DataStoreService")
-- حدث بعيد لتحديث واجهة المستخدم
local uiEvent = ReplicatedStorage:WaitForChild("UIEvent")
-- متجر البيانات لحفظ قطع الذهب الخاصة باللاعب
local goldStore = DataStoreService:GetDataStore("PlayerGold")
-- متجر البيانات المرتب لحفظ الذهب في لوحة المتصدرين
local leaderboardStore = DataStoreService:GetOrderedDataStore("GlobalLeaderboard")
-- إنشاء مولد أرقام عشوائية لتحديد موضع قطع الذهب
local random = Random.new()
-- جدول لتخزين قطع الذهب للاعب في جلسة واحدة
local playerGold = {}
-- الثوابت
local GOLD_VALUE = 10 -- مقدار قيمة كل قطعة ذهب
local GOLD_REGENERATION_BOUNDS = { -- حدود المنطقة المستخدمة لإعادة تحديد موضع قطع الذهب عشوائيًا
minX = -72,
maxX = 72,
minZ = -72,
maxZ = 72
}
local GOLD_REGEN_DELAY = 2 -- الفترة الزمنية قبل إعادة ظهور قطعة الذهب (بالثواني)
local AUTOSAVE_INTERVAL = 30 -- مدى تكرار حفظ قطع الذهب الخاصة باللاعب (بالثواني)
-- وظيفة للتعامل مع جمع اللاعب لقطعة ذهب
local function processGoldTouch(chunk, player)
-- إخفاء القطعة عندما يجمعها اللاعب
chunk.Parent = nil
-- إضافة القطعة إلى درجة الذهب الحالية للاعب
local userId = player.UserId
playerGold[userId] = (playerGold[userId] or 0) + GOLD_VALUE
print(player.Name, "الآن لديه", playerGold[userId], "ذهب")
-- تحديث شريط درجات واجهة المستخدم ليعكس درجة الذهب الجديدة لهذه الجلسة
uiEvent:FireClient(player, {
gold = playerGold[userId],
doTween = true,
showAlert = false
})
-- انتظر قليلاً ثم أعد ظهور قطعة الذهب التي تمت جمعها للتو في مكان عشوائي
task.delay(GOLD_REGEN_DELAY, function()
-- إعادة ظهور قطعة الذهب في موقع عشوائي جديد
local nextPositionX = random:NextInteger(GOLD_REGENERATION_BOUNDS.minX, GOLD_REGENERATION_BOUNDS.maxX)
local nextPositionZ = random:NextInteger(GOLD_REGENERATION_BOUNDS.minZ, GOLD_REGENERATION_BOUNDS.maxZ)
chunk.CFrame = CFrame.new(nextPositionX, 50, nextPositionZ) -- نقل القطعة إلى الموقع الجديد
chunk:SetAttribute("DropCollided", false) -- إعادة تعيين أي علامات تصادم
chunk.Parent = workspace.GoldChunks
end)
end
-- حلقة عبر جميع الأجزاء المعنونة بـ "Gold" وربطها باكتشاف اللمس
for _, chunk in ipairs(CollectionService:GetTagged("Gold")) do
chunk.Touched:Connect(function(otherPart)
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if player then
processGoldTouch(chunk, player)
end
end)
end
-- وظيفة لحفظ ذهب اللاعب في كل من متاجر البيانات القياسية والمرتبة
local function saveGold(player, value)
local userId = player.UserId
local success, err = pcall(function()
goldStore:SetAsync(userId, value)
leaderboardStore:SetAsync(tostring(userId), value)
end)
if not success then
warn("لم يتمكن من حفظ الذهب لـ", player.Name, ":", err)
end
end
-- وظيفة للتعامل مع انضمام اللاعب إلى اللعبة
local function onPlayerAdded(player)
local userId = player.UserId
print(player.Name, "قد انضم إلى اللعبة")
-- حاول تحميل ذهب اللاعب من متجر البيانات
local success, storedGold = pcall(function()
return goldStore:GetAsync(userId)
end)
-- تعيين درجة الذهب الحالية للجلسة باستخدام قيمة متجر البيانات للاعب
local currentGold = if success and storedGold then storedGold else 0
playerGold[userId] = currentGold
-- تحديث واجهة المستخدم بقيمة متجر البيانات للاعب
uiEvent:FireClient(player, {
gold = currentGold,
doTween = false,
showAlert = not success
})
if success then
print("تم تحميل", currentGold, "ذهب لـ", player.Name)
else
-- إبلاغ اللاعب بأن ذهبه لم يتم تحميله
uiEvent:FireClient(player, { showAlert = true })
warn("لم يتمكن من تحميل الذهب لـ", player.Name)
end
-- ابدأ الرحلة التلقائية لحفظ ذهب اللاعب every 30 seconds
coroutine.wrap(function()
while player.Parent do
task.wait(AUTOSAVE_INTERVAL)
if playerGold[userId] then
saveGold(player, playerGold[userId])
print("حفظ تلقائي", playerGold[userId], "ذهب لـ", player.Name)
end
end
end)()
end
-- وظيفة للتعامل مع مغادرة اللاعب اللعبة
local function onPlayerRemoving(player)
local userId = player.UserId
print(player.Name, "قد غادر اللعبة")
-- تحقق مما إذا كان ذهب اللاعب قد تم تتبعه
if playerGold[userId] then
-- حفظ ذهب اللاعب في متجر البيانات قبل مغادرتهم
saveGold(player, playerGold[userId])
end
end
-- ربط أحداث انضمام ومغادرة اللاعب
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoving)

LeaderboardManager

نص وحدة LeaderboardManager:

  • يستدعي GetSortedAsync() على متجر البيانات المرتب GlobalLeaderboard.
  • يقوم بتحويل معرفات المستخدمين إلى أسماء مستخدمين باستخدام GetNameFromUserIdAsync.
  • يعيد قائمة من جداول { Username, Score } لأعلى اللاعبين تصنيفًا.
  • يتم استدعاؤه بواسطة LeaderboardRemoteHandler كلما طلب عميل بيانات لوحة المتصدرين.

-- الحصول على الخدمات
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
-- متجر بيانات مرتب لحفظ درجات لوحة المتصدرين
local leaderboardStore = DataStoreService:GetOrderedDataStore("GlobalLeaderboard")
-- جدول لتخزين درجات لوحة المتصدرين
local leaderboardManager = {}
-- وظيفة لإرجاع أعلى الدرجات
function leaderboardManager.GetTopScores(limit)
-- حاول استرجاع صفحة مرتبة من إدخالات لوحة المتصدرين من متجر البيانات
local success, pages = pcall(function()
-- false = تنازلي (أعلى الدرجات أولاً)
return leaderboardStore:GetSortedAsync(false, limit)
end)
-- إذا فشلت المكالمة أو لم ترجع شيئًا، قم بتسجيل تحذير وأعد جدولًا فارغًا
if not success or not pages then
warn("فشل في الحصول على بيانات لوحة المتصدرين")
return {}
end
-- إنشاء جدول لتخزين بيانات أعلى اللاعبين
local topPlayers = {}
-- حلقة عبر كل إدخال في الصفحة الحالية من نتائج لوحة المتصدرين
for _, entry in ipairs(pages:GetCurrentPage()) do
local userId = tonumber(entry.key) -- تحويل مفتاح الإدخال إلى رقم (كان معرف المستخدم مخزنًا كسلسلة)
local score = entry.value -- القيمة هي درجة اللاعب (كمية الذهب)
local username = "غير معروف" -- اسم افتراضي في حال فشل البحث
-- حاول الحصول على اسم اللاعب من معرفه
local ok, name = pcall(function()
return Players:GetNameFromUserIdAsync(userId)
end)
-- إذا كانت عملية البحث ناجحة، احفظ الاسم الحقيقي
if ok then
username = name
end
-- أضف هذا اللاعب ودرجته إلى القائمة
table.insert(topPlayers, {
Username = username,
Score = score
})
end
-- أعد القائمة الكاملة لأعلى اللاعبين بأسمائهم ودرجاتهم
return topPlayers
end
-- أعد وحدة LeaderboardManager حتى تتمكن النصوص الأخرى من استخدامها
return leaderboardManager

LeaderboardRemoteHandler

نص LeaderboardRemoteHandler يسترجع ويعيد أعلى 3 درجات للعميل الذي يستدعيها.


-- الحصول على الخدمات
local ServerScriptService = game:GetService("ServerScriptService") -- الوصول إلى الوحدات على جانب الخادم
local ReplicatedStorage = game:GetService("ReplicatedStorage") -- كائنات التواصل بين العميل والخادم المشتركة
-- انتظر حتى الوظيفة البعيدة التي يستخدمها العميل لطلب بيانات لوحة المتصدرين
local leaderboardRemote = ReplicatedStorage:WaitForChild("LeaderboardRemote")
-- تحميل وحدة LeaderboardManager التي تحتوي على وظيفة GetTopScores
local leaderboardManager = require(ServerScriptService:WaitForChild("LeaderboardManager"))
-- إعداد معالج عندما يستدعي العميل الوظيفة البعيدة للوحة المتصدرين
leaderboardRemote.OnServerInvoke = function(player)
-- استدعِ وحدة لوحة المتصدرين للحصول على أعلى 3 درجات وأعدها إلى العميل
return leaderboardManager.GetTopScores(3)
end

LeaderboardGuiScript

نص LeaderboardGuiScript المحلي:

  • يطلب بيانات لوحة المتصدرين من الخادم كل 3 ثوانٍ باستخدام Class.RemoteHandler.InvokeServer|InvokeServer.
  • يستخدم قالب LeaderboardEntry المخفي لعرض كل صف في لوحة المتصدرين.
  • يقوم بتنسيق كل صف على أنه "المركز الأول: اسم المستخدم - الدرجة".
  • يدير إنشاء وعرض وتخطيط صفوف لوحة المتصدرين باستخدام UIListLayout.

-- الحصول على التخزين المشترك للوصول إلى الوظيفة البعيدة
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- الحصول على الوظيفة البعيدة المستخدمة لطلب بيانات لوحة المتصدرين من الخادم
local leaderboardRemote = ReplicatedStorage:WaitForChild("LeaderboardRemote")
-- مراجع واجهة المستخدم
local gui = script.Parent -- النص المحلي تحت واجهة المستخدم
local leaderboardFrame = gui:WaitForChild("LeaderboardFrame") -- الحاوية الرئيسية للوحة المتصدرين
local entriesFrame = leaderboardFrame:WaitForChild("EntriesFrame") -- الإطار الذي تظهر فيه إدخالات لوحة المتصدرين
local template = entriesFrame:WaitForChild("LeaderboardEntry") -- نص العلامة المخفية المستخدم لإنشاء الصفوف
-- وظيفة لمسح صفوف لوحة المتصدرين القديمة (لكن ليس القالب)
local function clearEntries()
for _, child in ipairs(entriesFrame:GetChildren()) do
-- فقط دمر العلامات المسماة "Row1"، "Row2"، وما إلى ذلك (اترك القالب بعيدًا عن اللمس)
if child:IsA("TextLabel") and child.Name:match("^Row%d+$") then
child:Destroy()
end
end
end
-- وظيفة لعرض بيانات لوحة المتصدرين على الشاشة
local function renderLeaderboard(data)
-- إزالة الصفوف القديمة أولاً
clearEntries()
for i, entry in ipairs(data) do
local row = template:Clone() -- استنساخ القالب المخفي
row.Name = "Row" .. i -- إعطائه اسمًا فريدًا
row.Visible = true -- جعله مرئيًا
row.LayoutOrder = i -- دع قائمة UI تقوم بترتيبه بشكل صحيح
-- تنسيق لوحة المتصدرين: "المركز الأول: اسم المستخدم - 123"
row.Text = string.format("%d%s place: %s - %d",
i,
i == 1 and "st" or i == 2 and "nd" or i == 3 and "rd" or "th",
entry.Username,
entry.Score
)
-- إضافة البيانات إلى واجهة المستخدم
row.Parent = entriesFrame
end
end
-- حلقة رئيسية: تحديث لوحة المتصدرين كل 3 ثوانٍ
while true do
-- اسأل الخادم عن بيانات لوحة المتصدرين
local success, data = pcall(function()
return leaderboardRemote:InvokeServer()
end)
if success and data then
-- عرض النتائج على لوحة المتصدرين
renderLeaderboard(data)
else
warn("فشل في جلب بيانات لوحة المتصدرين")
end
-- انتظر 3 ثوانٍ قبل التحديث مرة أخرى
task.wait(3)
end
©2026 شركة Roblox Corporation. تُعد منصّة Roblox، وشعار Roblox وشعار "توسيع حدود المخيلة"، من ضمن علاماتنا التجارية المسجّلة وغير المسجّلة في الولايات المتحدة وبلدان أخرى.