إعادة استخدام الكود

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

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

يمكنك وضع نصوص الوحدة في أي مكان تضع فيه النصوص، ولكن ReplicatedStorage هو موقع شائع؛ تخزين نصوص الوحدة هنا يتيح لك إعادة استخدام الكود بين الخادم والعملاء.

بنية نص الوحدة

في Roblox Studio، أضف نص وحدة إلى ReplicatedStorage وأعد تسميته إلى PickupManager. يبدأ كل ModuleScript بالشيفرة التالية:


local module = {}
return module

تخلق هذه الشيفرة جدولًا فارغًا بلغة لوا table وتعيده إلى أي نص يتطلب نص الوحدة.

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

المثال التالي يعيد جدولاً يحتوي على دالة واحدة تسمى getPickupBonus. قم بلصقها في نص الوحدة الجديد:


-- ModuleScript في ReplicatedStorage
local PickupManager = {}
local defaultMultiplier = 1.25
local rarityMultipliers = {
common = 10,
uncommon = 20,
rare = 50,
legendary = 100
}
-- إضافة دالة getPickupBonus إلى جدول PickupManager
PickupManager.getPickupBonus = function(rarity)
local bonus = rarityMultipliers[rarity] * defaultMultiplier
return bonus
end
return PickupManager

إضافة الدالة إلى جدول ليست ضرورة صارمة - يمكنك فقط إرجاع الدالة نفسها - لكن من الجيد اتباع هذه النمط؛ فهو يمنحك تركيبًا سهل الفهم عند استدعاء الدالة من نص آخر ويسمح لك بسهولة إضافة المزيد من الدوال إلى نص الوحدة بمرور الوقت.

تطلب نصوص الوحدة

لتحميل نص الوحدة، تستدعي دالة require(). في ReplicatedStorage، أضف نصًا جديدًا، وغيّر RunContext إلى Client. ثم أضف الشيفرة التالية لاستدعاء الدالة PickupManager.getPickupBonus:

Client script in ReplicatedStorage

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- الحصول على القيمة التي تعيدها ModuleScript
local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))
-- استدعاء دالة ModuleScript
local bonus = PickupManager.getPickupBonus("legendary")
print(bonus) --> 125

تخزين نصوص الوحدة في ReplicatedStorage يتيح لك مشاركة الكود بين الخادم والعميل، بحيث يمكنك استخدام نفس الكود للمطالبة بالنص من ServerScriptService:

Script in ServerScriptService

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))

عندما تستدعي require() على ModuleScript، يتم تنفيذها مرة واحدة وتعيد عنصرًا واحدًا كمرجع. استدعاء require() مرة أخرى يعيد نفس المرجع بالضبط، مما يعني أنه إذا قمت بتعديل جدول أو Instance المعاد، فإن استدعاءات require() اللاحقة تعيد ذلك المرجع المعدل. لا يتم تشغيل الوحدة نفسها عدة مرات.

إذا كنت تطلب ModuleScript من كلا الجانبين من حدود العميل والخادم، كما في المثال أعلاه، فإن ModuleScript يعيد مرجعًا فريدًا لكل جانب.

الأنماط

توجد بعض الأنماط الشائعة لنصوص الوحدة التي يمكنك استخدامها لتبسيط كودك وتجنب الفخاخ مع نمو لعبتك في الحجم والتعقيد.

مشاركة البيانات

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

إذا كنت ترغب في تعديل نفس البيانات لنسخ متعددة من نفس العنصر أو إعادة استخدام نفس البيانات لعناصر مختلفة، قم بتخزين البيانات في ModuleScripts. إنها طريقة أسهل لإعادة استخدام البيانات في نصوص أخرى، ويمكنك تخزين الجداول والدوال.

المثال التالي ModuleScript في ReplicatedStorage يخزن القيم التكوينية لمدفع عام:

ModuleScript in ReplicatedStorage

local GunConfig = {}
GunConfig.MagazineSize = 20
GunConfig.AmmoCount = 100
GunConfig.Firerate = 600
GunConfig.Damage = {
["Head"] = 50;
["Torso"] = 40;
["Body"] = 25;
}
return GunConfig

الأحداث المخصصة

تمكّن الأحداث المخصصة النصوص من التواصل مع بعضها البعض، ولكن من الصعب تتبع المراجع الفردية لأشياء BindableEvent يمكن أن تزدحم كودك.

يمكنك استخدام ModuleScripts لتخزين BindableEvents وتوفير معالجات أحداث مخصصة ترتبط مباشرة بأساليب ModuleScript.

المثال التالي ModuleScript في ReplicatedStorage يحتوي على حدث مخصص يتم إطلاقه عندما يتغير حالة المفتاح:

ModuleScript in ReplicatedStorage

local Switch = {}
-- إنشاء قابل للاستجابة بحيث يمكن لأي نص الاستماع عندما يتغير المفتاح
local bindableEvent = Instance.new("BindableEvent")
Switch.Changed = bindableEvent.Event
local state = false
function Switch.flip()
state = not state
bindableEvent:Fire(state)
end
return Switch

المثال التالي نص عميل في ReplicatedStorage يقوم بتوصيل دالة للاستدعاء عندما يتم إطلاق حدث Switch.Changed.

Script in ReplicatedStorage

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Switch = require(ReplicatedStorage:WaitForChild("Switch"))
Switch.Changed:Connect(function(newState)
print("حالة المفتاح الآن", newState)
end)
-- اختبار غالبًا ما يتم التبديل
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()

التغليف

التغليف هو ممارسة إنشاء طبقة من التجريد حول الكائنات أو منطق البرمجة لإخفاء التعقيد. يمكنك استخدام ModuleScripts لتغليف الكائنات في روبلوكس مع دوال لوا مخصصة لتبسيط الكود.

على سبيل المثال، يمكنك استخدام التغليف لـ:

  • تبسيط التواصل عبر الشبكة باستخدام كائن RemoteEvent واحد.
  • لفّ كود معالجة الأخطاء حول خدمات حساسة مثل DataStoreService.
  • تعريف أساليب مخصصة للتحكم أو توسيع ميزات كائنات روبلوكس.

من الصعب تتبع عشرات من كائنات RemoteEvent الفردية لتنفيذ الشبكات في لعبة. يمكنك استخدام ModuleScript لتغليف كائن RemoteEvent واحد للمساعدة في تبسيط هذه المشكلة. من خلال تضمين حجة id فريدة، يمكنك تشغيل رسائل الشبكة المختلفة بينما تستخدم فقط واحدًا من RemoteEvent.

في المثال أدناه، يقوم ModuleScript المسمى NetworkManagerClient بتغليف دالة RemoteEvent:FireServer() لتضمين هذه الحجة الإضافية id. بالإضافة إلى ذلك، يشير هذا ModuleScript إلى كائن RemoteEvent نفسه بحيث لا تحتاج إلى الإشارة إليه في أجزاء أخرى من كودك. تحتاج فقط إلى مطالبة هذا ModuleScript لإرسال رسائل الشبكة ولا تحتاج إلى التعامل مع كائنات RemoteEvent في بقية قاعدة كودك.

المثال التالي ModuleScript في ReplicatedFirst يوفر دالة مغلفة يمكنك استدعاؤها في نصوص العميل الخاصة بك لإرسال رسالة شبكة:

Network Module

-- ModuleScript في ReplicatedFirst يسمى NetworkManagerClient
local NetworkManagerClient = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
-- تغليف دالة FireServer الخاصة بكائن remote
function NetworkManagerClient.FireServer(id, ...)
remoteEvent:FireServer(id, ...)
end
return NetworkManagerClient

المثال التالي ModuleScript في ServerScriptService يستخدم BindableEvents لكل نص للاتصال بمعرّف محدد. عندما يرسل العميل رسالة شبكة، يتم تشغيل كل BindableEvent المرتبطة بالمعرف المحدد.


-- ModuleScript في ServerScriptService يسمى NetworkManagerServer
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- ربط BindableEvent الجديد بالمعرف
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- الاتصال بـ
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- إيجاد كل حدث قابل للاستجابة الذي يتطابق مع معرف الحدث عن بعد
for _, signal in networkSignalList do
if signal.id == id then
signal.bindableEvent:Fire(player, ...)
end
end
end)
return NetworkManagerServer

المثال التالي LocalScript يرسل رسالة بالمعرف RequestA مع حجة اختيارية Hello.


-- LocalScript في ReplicatedFirst
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))
NetworkManagerClient.FireServer("RequestA", "Hello")

المثال التالي Script يتصل بمعرف رسالة الشبكة RequestA ويطبع بيانًا مع أي معلمات إضافية عندما يتلقى الطلب.


-- Script في ServerScriptService
local ServerScriptService = game:GetService("ServerScriptService")
local NetworkManagerServer = require(ServerScriptService:WaitForChild("NetworkManagerServer"))
NetworkManagerServer.GetServerEventSignal("RequestA"):Connect(function(player, ...)
print("تم استلام RequestA من", player, ...)
end)
©2026 شركة Roblox Corporation. تُعد منصّة Roblox، وشعار Roblox وشعار "توسيع حدود المخيلة"، من ضمن علاماتنا التجارية المسجّلة وغير المسجّلة في الولايات المتحدة وبلدان أخرى.