هياكل التحكم هي عبارات تدير تدفق تنفيذ كود لواء. هناك أربعة أنواع رئيسية من هياكل التحكم:
- عبارة if then else تنفذ الكود فقط إذا كانت الحالة المحددة true. لا يتكرر تنفيذ الكود.
- حلقة repeat تنفذ الكود، وتكرر التنفيذ إذا كانت الحالة true.
- حلقة for تنفذ الكود عدد محدد من المرات اعتمادًا على مدخلات محددة.
يمكن أن تكون الحالة في عبارات if، وحلقات while، وحلقات repeat تعبير أو قيمة من لواء. إذا لم تكن القيمة false أو nil، فإن لواء يقيمها على أنها true في العبارات الشرطية. على عكس اللغات النصية الأخرى، يعتبر لواء كلًا من الصفر والسلسلة الفارغة كـ true.
عبارات if
تختبر عبارة if الأساسية حالتها. إذا كانت الحالة صحيحة، فإن لواء ينفذ الكود بين then و end.
يمكنك استخدام عبارة elseif لاختبار حالات إضافية إذا كانت حالة if غير صحيحة. يمكنك استخدام عبارة else لتنفيذ الكود إذا فشلت جميع حالات if و elseif. أجزاء elseif و else كلاهما اختياري، لكن لا يمكنك استخدام أي منهما بدون عبارة if أولية.
في سلسلة من حالات if و elseif و else، يختبر لواء الحالات من الأعلى إلى الأسفل، ويتوقف عند أول حالة صحيحة، وينفذ الكود الذي يليها.
if 2 + 2 == 5 thenprint("اثنان زائد اثنان يساوي خمسة") -- لا يطبع لأن الحالة خاطئةelseif 2 + 3 == 5 thenprint("اثنان زائد ثلاثة يساوي خمسة") -- اثنان زائد ثلاثة يساوي خمسةelseprint("فشلت جميع الحالات") -- لا يطبع لأن الحالة السابقة صحيحةend
حلقات while
تقيم حلقة while—do ما إذا كانت الحالة المحددة صحيحة أو خاطئة. إذا كانت الحالة false أو nil، تنتهي الحلقة، ويتجاوز لواء الكود في الحلقة. إذا كانت الحالة true، ينفذ لواء الكود في الحلقة ويكرر العملية.
local timeRemaining = 10while timeRemaining > 0 doprint("ثوانٍ متبقية: " .. timeRemaining)task.wait(1)timeRemaining -= 1endprint("وصل المؤقت للصفر!")--[[ النتيجة الناتجة:ثوانٍ متبقية: 10ثوانٍ متبقية: 9ثوانٍ متبقية: 8ثوانٍ متبقية: 7ثوانٍ متبقية: 6ثوانٍ متبقية: 5ثوانٍ متبقية: 4ثوانٍ متبقية: 3ثوانٍ متبقية: 2ثوانٍ متبقية: 1وصل المؤقت للصفر!]]
الحلقات اللانهائية
يمكنك استخدام حلقة while—do لكتابة حلقات ألعاب لانهائية عن طريق تعيين true كالحالة.
while true doprint("أقوم بالتكرار...")task.wait(0.5)end--[[ النتيجة الناتجة:أقوم بالتكرار...أقوم بالتكرار...أقوم بالتكرار...أقوم بالتكرار......]]
حلقات repeat
حلقة repeat—until تتكرر حتى تكون حالة صحيحة. يتم تقييم الاختبار الشرطي بعد تشغيل كتلة الكود، لذا تضمن كتلة الكود التشغيل مرة واحدة على الأقل. على عكس اللغات الأخرى، يشمل نطاق لواء متغير محلي تم إعلانه داخل حلقة repeat—until الحالة.
local currentGoblinCount = 18-- استنساخ الأقزام حتى الحد الأقصى البالغ 25 في اللعبةrepeatspawnGoblin()currentGoblinCount += 1print("عدد الأقزام الحالي: " .. currentGoblinCount)until currentGoblinCount == 25print("تم إعادة تكوين الأقزام!")--[[ النتيجة الناتجة:عدد الأقزام الحالي: 19عدد الأقزام الحالي: 20عدد الأقزام الحالي: 21عدد الأقزام الحالي: 22عدد الأقزام الحالي: 23عدد الأقزام الحالي: 24عدد الأقزام الحالي: 25تم إعادة تكوين الأقزام!]]
حلقات for
تقوم حلقة for بتنفيذ الكود عدد محدد من المرات، سواء بناءً على عداد رقمي أو عدد العناصر في مجموعة.
حلقات for العددية
تحدد حلقة for—do عدد مرات تنفيذ الحلقة باستخدام عداد. يتم إعلان الحلقة بقيمة بداية، قيمة نهاية، وزيادة اختيارية.
تقوم لواء بتعيين العداد على القيمة الابتدائية، وتنفيذ كتلة الكود في حلقة for، ثم تضيف الزيادة إلى العداد. إذا كانت الزيادة موجبة، تتكرر العملية حتى يكون العداد مساويًا أو أكبر من القيمة النهائية. إذا كانت الزيادة سالبة، تتكرر العملية حتى يكون العداد مساويًا أو أقل من القيمة النهائية.
الزيادة الاختيارية الافتراضية هي 1. لا تحتاج لأن تكون عددًا صحيحًا.
for counter = 1, 3 doprint(counter)end--[[ النتيجة الناتجة:123]]for counter = 1, 6, 2 doprint(counter)end--[[ النتيجة الناتجة:135]]for counter = 2, 0, -0.5 doprint(counter)end--[[ النتيجة الناتجة:21.510.50]]
حلقات for العامة
تقوم حلقة for العامة بالتكرار عبر العناصر في مجموعة بدلاً من تسلسل الأرقام. مع حلقات for العامة، يمكنك تنفيذ الكود لكل عنصر في المجموعة، ويمكنك بسهولة استخدام كل عنصر في الكود.
تحتاج حلقات for إلى دالة، أو مؤشر، للتكرار عبر أنواع مختلفة من المجموعات. ترجع الدالة العالمية ipairs() مؤشرًا للمصفوفات، وترجع الدالة العالمية pairs() مؤشرًا للقواميس. توفر مكتبة string الدالة string.gmatch() للتكرار عبر السلاسل.
التكرار العام
في لواء، يمكنك التكرار عبر جدول باستخدام الكلمة المفتاحية in مباشرةً على الجدول، بدلاً من استخدام دالة مؤشر مثل ipairs():
for i, v in {1, 2, 3, 4, 5} doprint(i, v)end
يسمح لك التكرار العام أيضًا باستخدام طريقة التحول __iter لإنشاء دالة مؤشر مخصصة. هذه المثال المصنعة تتكرر عبر مصفوفة بترتيب عكسي، من عنصرها الأخير إلى الأول:
local myTable = {1, 2, 3, 4, 5}
myMetatable = {
__iter = function(t)
local i = #t + 1
return function()
i -= 1
if i > 0 then
return i, t[i]
end
end
end,
}
setmetatable(myTable, myMetatable)
for i, v in myTable do
print(i, v)
end
--[[ النتيجة الناتجة:
5 5
4 4
3 3
2 2
1 1
]]
المصفوفات
ترجع دالة ipairs() مؤشرًا يتكرر عبر الفهارس الرقمية في جدول وترجع index و value لكل عنصر. وهذا يجعلها مناسبة للمصفوفات، حيث تكون جميع الفهارس رقمية.
local array = {"a", "b", "c", "d", "e"}for index, value in ipairs(array) doprint(index, value)end--[[ النتيجة الناتجة:1 a2 b3 c4 d5 e]]
القواميس
ترجع دالة pairs() مؤشرًا يتكرر عبر جميع الفهارس (بما في ذلك الفهارس الرقمية) في جدول وترجع key و value لكل إدخال في القاموس. يتم تحديد ترتيب العناصر التي يتم التكرار عليها في جدول القاموس بشكل عشوائي. وهذا يجعلها مناسبة للتكرار عبر القواميس، حيث يتم تخزين العناصر خارج الترتيب مع فهارس غير رقمية.
local dictionary = {[1] = "a",["Hello"] = "b",[5] = "c",[true] = "d",["World"] = "f",[false] = "e"}for key, value in pairs(dictionary) doprint(key, value)end--[[ النتيجة الناتجة:Hello btrue dfalse eWorld f5 c1 a]]
كسر الحلقات
لإجبار حلقة على الانتهاء، استخدم الكلمة المفتاحية break. يظهر المثال البرمجي التالي كيفية كسر حلقة while—do اللانهائية.
local secondsElapsed = 0local timeout = 5while true dotask.wait(1)secondsElapsed += 1print("الثواني المنقضية:", secondsElapsed)if secondsElapsed == timeout thenbreakendendprint("مرت خمس ثوانٍ. حان الوقت للمضي قدمًا!")--[[ النتيجة الناتجة:12345مرت خمس ثوانٍ. حان الوقت للمضي قدمًا!]]
مواصلة الحلقات
لإجبار حلقة على التكرار وبدء التشغيل مرة أخرى، استخدم الكلمة المفتاحية continue. ستقوم حلقة for بتكرار العداد؛ بينما ستتحقق حلقات while و repeat—until من شرط الحلقة قبل الاستمرار. يظهر المثال البرمجي التالي كيفية الحصول على جميع الأطفال من Instance من نوع معين ClassName.
local function GetChildrenOfClass(parent: Instance, className: string): {Instance}
local children = {}
for _, child in parent:GetChildren() do
if child.ClassName ~= className then continue end -- يقوم بتكرار الحلقة
table.insert(children, child)
end
return children
end