Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Programming

نصيحة سريعة: إنشاء حركة العدو السلس مع الحركة الجيبية

Difficulty:BeginnerLength:MediumLanguages:

Arabic (العربية/عربي) translation by Aisy Abdullah (you can also view the original English article)

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


أمثلة

أولاً ، دعوني أريكم نوع الحركة المرحة الخلفية التي أعنيها. (الرسومات هي من حزمة sprite المجانية الخاصة بالتصوير والتوزيع).

هذا العدو يتحرك صعودا وهبوطا ، وإطلاق الرصاص على فترات منتظمة لأنها تذهب:

هذا العدو ينسج عبر الشاشة:

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


نهج السذاجة

تتمثل المحاولة الأولى الشائعة لإنشاء حركة ذهاب وإياب في القيام بشيء كالتالي:

بشكل أساسي ، يُخبر هذا العدو أن يتحرك لأسفل بمعدل ثابت (أي نفس عدد البكسل في كل مرة) حتى يصل إلى أدنى نقطة في نطاقه المسموح به ، ثم يرتفع عند نفس المعدل الثابت حتى يصل إلى أعلى نقطة في نطاقه المسموح به مرارًا وتكرارًا.

يمكن جعل العدو يتحرك أفقيًا عن طريق تعيين xSpeed ​​الخاص به إلى أي رقم آخر غير الصفر: الرقم السالب يجعله يتحرك يسارًا ، ورقم موجب يجعله يتحرك بشكل صحيح.

توضح هذه الأمثلة كيف يبدو هذا النوع من الحركة. أولاً ، بدون حركة أفقية:

الآن ، مع الحركة الأفقية:

يحقق هدف الانتقال ذهابًا وإيابًا ، ولكنه بالتأكيد ليس سهلاً كما في المثال السابق.


القضية

السبب في هذه الحركة الوعرة هو أن السرعة العمودي للعدو تحدث تغيرًا مفاجئًا كبيرًا - على الرغم من أن قيمة ufo.ySpeed ​​تبقى كما هي.

افترض أن ufo.ySpeed ​​هو 10. في الطريق إلى أعلى ، يتحرك العدو إلى أعلى بمقدار 10px / tick (بكسل لكل علامة ، حيث يكون 'tick' هو طول حلقة اللعبة الواحدة). وبمجرد أن يصل العدو إلى القمة ، فإنه يعكس الاتجاه ، ويتحرك فجأة عند 10px / tick إلى أسفل. التحول من 10px / tick إلى -10px / tick هو اختلاف في 20px / tick ، ​​وهذا ما هو ملحوظ جدًا.

عندما يتم توضيح السبب من هذا القبيل ، يبدو الحل واضحا: إبطاء العدو بالقرب من أعلى وأعلى النقاط! بهذه الطريقة ، لن يكون التغيير في سرعته كبيرًا جدًا عندما يعكس الاتجاه.

قد تبدو المحاولة الأولى على هذا النحو:

هذا الرمز فوضوي ، لكنك تحصل على الفكرة: إذا كان العدو في حدود 100 بكسل من أعلى أو أدنى الحدود ، فإنه يتحرك عند نصف سرعته العادية.

هذا يعمل ، على الرغم من أنها ليست مثالية. سيظل لدى العدو 'قفزة' في السرعة عندما يغير اتجاهه ، لكن على الأقل لن يكون ملحوظًا. ومع ذلك ، فإن العدو لديه الآن قفزات إضافية في السرعة عندما تتحرك من وتيرة منتظمة إلى سرعة أبطأ! دانغ.

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


الحركة الجيبية

فكر في قطار نموذجي يدور حول مسار دائري بشكل مثالي. القطار يغير الاتجاه باستمرار ، ومع ذلك فهو يتحرك بوتيرة ثابتة ، بدون 'قفزات'.

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

هذا بالضبط ما نريد. ولحسن الحظ ، هناك وظيفة ستعطيناها: وظيفة الجيب. يوضح هذا GIF المتحركة من ويكيبيديا:

Image from Wikimedia Commons. Thanks, Lucas!
صورة من ويكيميديا ​​كومنز. شكرا ، لوكاس!

الخط الأحمر هو منحنى y = sin (x). لذا ، الخطيئة (0.5 * pi) هي 1 ، sin (pi) هي 0 ، وهكذا.

من المريح أن pi (π) هي الوحدة الأساسية المستخدمة لهذه الوظيفة ، ولكن يمكننا أن نديرها. يمكننا استخدامه على النحو التالي:

ترى ما الذي يحدث هنا؟ بعد علامة واحدة ، سيتم تعيين ufo.y على الخطيئة (1 * pi) ، والتي هي 0. بعد اثنين من علامات التجزئة ، سيتم تعيين ufo.y على الخطيئة (2 * pi) ، وهو ... 0 ، مرة أخرى. يا. تشبث.

الآن ، بعد علامة واحدة ، سيتم ضبط ufo.y على الخطيئة (0.5 * pi) ، وهي 1. بعد اثنين من علامات التجزئة ، سيتم تعيين ufo.y على الخطيئة (1 * pi) ، والتي هي 0. بعد ثلاث علامات ، سيتم ضبط ufo.y على الخطيئة (1.5 * pi) ، والتي هي -1 ، وهكذا. (تتكرر وظيفة الجيب ، لذلك الخطيئة (أ) == الخطيئة (أ (2 * pi)) ، دائمًا - لا داعي للقلق بشأن التأكد من وجود أقل من رقم معين!)

من الواضح أن الانتقال من 1 إلى 0 إلى -1 وهكذا ليس ما نريده. أولاً ، نريد أن تكون القيم الحدودية شيئًا آخر عند 1 و -1. هذا سهل - نحن فقط نضاعف وظيفة الخطيئة بالكامل من خلال الحد الأقصى المطلوب:

الآن سوف يذهب العدو من ص = 250 إلى ص = -250. إذا أردنا أن نذهب من 100 إلى 600 ، يمكننا فقط إضافة 350 إضافية إلى هذه القيمة (منذ 250 + 350 = 600 و -250 + 350 = 100):

ولكن القيمة لا تزال تقفز من 100 إلى 350 إلى 600 ، لأن الخطيئة (numberOfTicks * 0.5 * pi) لا تزال تقفز من -1 إلى 0 إلى 1.

ولكن ، هيك ، نحن نعرف لماذا يحدث ذلك: لأن قيمة numberOfTicks * 0.5 * pi تقفز من 0.5 * pi إلى 1 * pi إلى 1.5 * pi. انظر إلى GIF مرة أخرى إذا كنت لا ترى السبب الذي من شأنه أن يسبب ذلك:

Image from Wikimedia Commons. Thanks, Lucas!

لذلك كل ما نحتاجه هو اختيار فجوة مختلفة بين العدد الذي نقوم بتغذيته إلى الدالة sin () ، بدلاً من numberOfTicks * 0.5 * pi. إذا كنت تريد أن تستغرق الحركة ذهابًا وإيابًا عشرة أضعاف ، استخدم numberOfTicks * 0.5 * pi / 10. إذا كنت تريد أن تستغرق 25 مرة ، استخدم numberOfTicks * 0.5 * pi / 25 ، وهكذا.

يمكنك استخدام هذه القاعدة لجعل الحركة تستمر تمامًا كما تريدها. إذا كانت حلقة اللعبة تعمل مرة واحدة كل 25 مللي ثانية (40 مرة في الثانية) ، فيمكنك استخدام numberOfTicks * 0.5 * pi / 40 لجعل العدو ينتقل من المركز إلى الأعلى بدقة مرة واحدة في الثانية ، أو numberOfTicks * 0.5 * pi / (40 * 2) لجعله يتحرك من الأعلى إلى الأسفل بدقة مرة واحدة في الثانية.

بالطبع ، يمكنك فقط أن تنسى كل ذلك وتجربة الأرقام المختلفة لترى ما الذي تشعر به. يستخدم هذا العرض التوضيحي الخطيئة (numberOfTicks / 50) ، وأحب النتيجة:

تجربة والمتعة!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.