الحركة والتصادمات
أنشئ مشهدًا قابلًا للعب
الحركة والتصادمات درس مجاني في Lua Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Lua Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Lua Academy 4 دروس في المجموع.
الموضع والسرعة المتجهة
تعني الحركة في LÖVE تغيير موضع كائن بمرور الوقت. خزّن x وy، ثم أضف السرعة المتجهة في love.update بعد تحجيمها باستخدام dt.
إن الاحتفاظ بالسرعة المتجهة على شكل dx وdy لكل ثانية يجعل الحركة القطرية والفيزياء واضحة ومستقلة عن معدل الإطارات.
function love.update(dt)
player.x = player.x + player.dx * dt
player.y = player.y + player.dy * dt
endالحركة المعتمدة على الإدخال
اجمع بين الاستطلاع والسرعة المتجهة لتوجيه كائن. اقرأ مفاتيح الاتجاه داخل love.update وطبّق السرعة مضروبة في dt.
وبما أن love.keyboard.isDown يُفحَص في كل إطار، يتحرك اللاعب بسلاسة ما دام المفتاح مضغوطًا.
function love.update(dt)
if love.keyboard.isDown('left') then player.x = player.x - player.speed*dt end
if love.keyboard.isDown('right') then player.x = player.x + player.speed*dt end
endتطبيع السرعة القطرية
يؤدي الضغط على مفتاحي اتجاه في آن واحد إلى جعل الحركة القطرية أسرع، لأن كلا المحورين يضيف السرعة الكاملة. ولإصلاح ذلك، طبّع متجه الحركة.
اقسم الاتجاه على طوله حتى يصبح مقداره 1، ثم اضربه في السرعة. وهكذا تصبح الحركة القطرية مساوية للحركة في خط مستقيم.
local dx, dy = ix, iy
local len = math.sqrt(dx*dx + dy*dy)
if len > 0 then
player.x = player.x + (dx/len) * player.speed * dt
endإبقاء العناصر داخل الشاشة
قيّد الموضع حتى تبقى الكائنات داخل الشاشة. اقرأ حجم النافذة باستخدام love.graphics.getWidth وgetHeight، ثم حدّد نطاق الإحداثيات.
يعمل math.max وmath.min معًا على تقييد قيمة بين حد أدنى وحد أقصى بطريقة واضحة.
local w = love.graphics.getWidth()
player.x = math.max(0, math.min(player.x, w - player.size))صناديق الإحاطة المحاذية للمحاور
تستخدم أبسط تصادمات المستطيلات، وتُسمى AABB، أي صناديق الإحاطة المحاذية للمحاور. يمتلك كل كائن قيم x وy والعرض والارتفاع.
يتداخل صندوقان عندما يتقاطعان على المحورين الأفقي والرأسي في الوقت نفسه. وهذا الاختبار سريع وكافٍ لمعظم الألعاب ثنائية الأبعاد.
-- box: { x, y, w, h }اختبار تداخل AABB
يتداخل مستطيلان عندما لا توجد بينهما فجوة على أي من المحورين. يجمع الاختبار التقليدي أربع مقارنات.
إذا كانت المقارنات الأربع صحيحة، يتقاطع الصندوقان. وهذا الشرط الواحد هو الأساس في اكتشاف التصادمات ثنائية الأبعاد.
function overlaps(a, b)
return a.x < b.x + b.w and
b.x < a.x + a.w and
a.y < b.y + b.h and
b.y < a.y + a.h
endالاستجابة للتصادم
بمجرد أن تعيد overlaps القيمة true، حدّد ما سيحدث: التقط عملة، أو تلقَّ ضررًا، أو أوقف الحركة. افحص التصادمات داخل love.update بعد التحرك.
بالنسبة إلى العناصر القابلة للجمع، أزل العنصر ببساطة أو زد النتيجة. أما الجدران الصلبة، فأعد دفع اللاعب إلى الخارج.
function love.update(dt)
movePlayer(dt)
if overlaps(player, coin) then
score = score + 1
coin.dead = true
end
endتصادمات الدوائر
بالنسبة إلى الكائنات الدائرية، يكون التصادم المعتمد على المسافة أكثر دقة. تتصادم دائرتان عندما تكون المسافة بين مركزيهما أقل من مجموع نصفي قطريهما.
يؤدي مقارنة مربعات المسافات إلى تجنب حساب الجذر التربيعي المكلف، وهو تحسين شائع عند فحص عدد كبير من الكائنات.
function circlesHit(a, b)
local dx, dy = a.x - b.x, a.y - b.y
local rsum = a.r + b.r
return dx*dx + dy*dy < rsum*rsum
endمعالجة تصادمات الجدران
لإيقاف اللاعب عند جدار، تتمثل إحدى الطرق البسيطة في التحرك على كل محور على حدة، ثم التراجع عن الخطوة التي تسبب التداخل.
حرّك x ثم اختبره؛ وإذا حدث تصادم، أعد x إلى قيمته السابقة. كرر الأمر مع y. وتمنع هذه المعالجة المنفصلة حسب المحور الالتصاق بالزوايا.
player.x = player.x + vx * dt
if overlaps(player, wall) then player.x = player.x - vx * dt end
player.y = player.y + vy * dt
if overlaps(player, wall) then player.y = player.y - vy * dt endتطبيق الجاذبية
تضيف ألعاب المنصات تسارعًا ثابتًا نحو الأسفل. زد السرعة الرأسية بمقدار الجاذبية مضروبة في dt في كل إطار، ثم طبّق السرعة على الموضع.
عندما يهبط اللاعب على الأرض، اجعل السرعة الرأسية تساوي صفرًا حتى يتوقف عن السقوط. ويضبط القفز السرعة الرأسية على قيمة سالبة.
function love.update(dt)
player.dy = player.dy + GRAVITY * dt
player.y = player.y + player.dy * dt
endإزالة الكائنات المنتهية
غالبًا ما تزيل الكائنات بعد التصادمات. كرر على قائمة من نهايتها إلى بدايتها واستدعِ table.remove حتى تظل الفهارس صالحة أثناء الحذف.
يُعد التكرار من الخلف إلى الأمام الأسلوب الاصطلاحي الآمن في Lua لإزالة العناصر أثناء الحلقة، إذ يتجنب تخطي العناصر الذي قد يسببه التكرار من الأمام.
for i = #coins, 1, -1 do
if coins[i].dead then
table.remove(coins, i)
end
endاختبار سريع
اختبر فهمك للحركة والتصادمات في LÖVE.
مراجعة
تجمع الحركة بين الموضع والسرعة المتجهة وdt، مع تطبيع الحركة القطرية لتحقيق سرعة عادلة، وتقييد الموضع لإبقاء الكائنات داخل الشاشة. تبدأ التصادمات باختبارات تداخل AABB، مع استخدام فحوصات المسافة للدوائر.
عالج الجدران بالتراجع عن الحركة على كل محور، وأضف الجاذبية لألعاب المنصات، وأزل الكائنات المنتهية بالتكرار من الخلف إلى الأمام باستخدام table.remove.
الأسئلة الشائعة
هل درس «الحركة والتصادمات» مجاني؟
نعم — نص درس «الحركة والتصادمات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Lua Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Lua Academy 4 دروس في المجموع.
ماذا ستتعلم في «الحركة والتصادمات»؟
أنشئ مشهدًا قابلًا للعب تتمرن على Lua Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Lua Academy؟
لا تُشترط خبرة سابقة. Lua Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «الحركة والتصادمات»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Lua Academy هذا؟
نعم. كل درس في Lua Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- حلقة لعبة LOVE
- رسم الأشكال والصور
- التعامل مع الإدخال
- الحركة والتصادمات