ال Parallax Scrolling طريقة سهلة وفعالة لاضافة العمق الى اللعبة ثنائية الابعاد:
() translation by (you can also view the original English article)
ال Parallax Scrolling هو طريقة بسيطة وفعالة لخلق الوهم بالبعد في اللعبة ثناية الابعاد. فسواءً أكنت تطور لعبة مركبة فضائية عمودية أو تخطي عقبات افقية، فإن ال Parallax Scrolling سيكون جزءً أساسي من اللعب وسيزيد بشكل كبير من التأثير والغمر المرئي الخاص بمشروعك.
في هذا الدرس سأقوم بتغطية أساسيات ال Parallax Scrolling، إلى جانب عدة وسائل لتطبيقه، بطريقة تجعلك قادراَ على ادخال ال Parallax Scrolling ضمن مجموعة مهاراتك بشكل ناجح بغض النظر عن مستوى مهاراتك الحالي.
ديمو
جرب الديمو في الأسفل لكي ترى المراحل التي تستعمل ال Parallax Scrolling بشكل أفقي، عمودي، كلاهما، ومرحلة لم تقم باستعماله. اضغط على الديمو لتفعيلها، ثم استعمل أزرار الأرقام لكي تبدل بين المراحل وأزرار الأسهم لكي تحرك المركبة الفضائية (في المراحل المناسبة).
ملاحظة: لا يمكن تجربة الديمو الا من النسخة الانكليزية الاصلية
ما هو ال Parallax Scrolling؟
ال Parallax تم تعريفه بالتحرك الظاهري (وليس الفعلي) لكائن تتم مشاهدته نتيجة تغير موقع المشاهِد. مع ال Parallax Scrolling ثنائي الابعاد سيتغير موقع المراقِب فقط على محوري ال x وال y. وبالتالي فقط سرعة وموقع الجسم ستتغير مع موقع المراقِب لأن التغير في حجم الكائن سيتطلب تغيرا على المحور z.
وينسب للعبة تاكاشي نيشياما "Moon Patrol"بأنها اول لعبة استخدمت ميزة ال Parallax Scrolling ثنائية الابعاد، لكن التقنية وجدت في مجال التحريك التقليدي بحوالي عام 1933. باستعمال الكاميرا متعددة السطوح كان المحركون قادرين على انشاء تأثير ثلاثي الأبعاد غير مجسم يقوم بعمل وهم بوجود العمق من خلال السماح لعدة طبقات رسومية بالتحرك بسرعات مختلفة تتعلق بالمسافة المدركة بينها وبين عدسة الكاميرا. هذه هي الطريقة التي يتم من خلالها تحقيق ال Parallax Scrolling في ألعاب الفيديو الحديثة، ولكن عوضاً عن الكاميرا متعددة السطوح، فإنه يتم تجميع المراحل من خلال عدة طبقات وكاميرا لعبة واحدة.
من خلال تقسيم العناصر الخلفية والامامية الخاصة باللعبة الى طبقات مختلفة، فإنه من الممكن التحكم بسرعة وموضع هذه العناصر اعتمادا على طبقتهم. في هذه الحالة يكون المشاهد هو اللاعب، وكاميرا اللعبة تبقى مركزة على نقطة أو كائن محدد، بينما تتحرك الطبقات الخلفية والامامية تبعاً لذلك.
هذه النقطة المحورية تتحرك بسرعة ’عادية’، أو بسرعة يحددها نوع اللعبة. كائنات الخلفية تتحرك بشكل أبطئ من النقطة المحورية بينما الكائنات الأمامية تتحرك أسرع من النقطة المحورية. فينتج عن هذا وهم بالعمق يجعل المرحلة الثنائية الابعاد أكثر واقعية وتمكن اللاعب من الانغماس فيها بشكل أكبر.
المثال الأول: Parallax Scrolling افقي
في مثالنا الأول، لدينا مرحلة بسيطة جداً لشارع في الليل تتم فيها حركة افقية بدون وجود عناصر للتفاعل معها. طبقات الخلفية المتعددة تتحرك بسرعة محددة مسبقا على طول المحور x. والآن لنركز على أساسيات ال Parallax Scrolling بدون القلق على أي تحرك للاعب او تغير للمشهد.



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



تتكون مرحلتنا من أربع طبقات. وفي هذا المثال، رقم الطبقة يحدد الترتيب الذي سيتم فيه عرض المكونات على الشاشة بالإضافة الى سرعة حركتها. إذا كانت هذه المرحلة هي لعبة تخطي عقبات تعتمد على التحرك الجانبي، فمن ثم سيتوضع كائن اللاعب في اعلى الطبقة الثالثة. هذه الطبقة ستكون النقطة المحورية للمشاهد، وأيضا ستفرض السرعة الخاصة لكل من الطبقات الخلفية والامامية.
الطبقة 2 تتحرك ابطء من الطبقة 3، والطبقة 1 تتحرك ابطء من الطبقة 2. الطبقة 4 هي الطبقة الامامية، لذا فهي تتحرك أسرع من النقطة المحورية على الطبقة 3.
يوجد العديد من الطرق لتطبيق هذا النوع من ال Parallax Scrolling. في مثالنا كانت الطبقات تتحرك بسرعات محددة مسبقاً بدون الرجوع الى سرعات بعضها البعض. ولكن في حال خططت لامتلاك عدة مراحل مع كميات متنوعة من الطبقات الخلفية والامامية، فانه من الأفضل تحديد سرعات الطبقة من خلال قراءة السرعة الحالية للطبقة التي هي النقطة المحورية. على سبيل المثال، إذا كانت النقطة المحورية هي الطبقة 3 وهي تتحرك بسرعة 5
فمن ثم كل طبقة خلفية تتبعها يجب ان تتحرك بسرعة أقل من 5
. وأي طبقة أمامية يجب ان تتحرك بسرعة أكبر من 55
.
1 |
//Variables متغيرات
|
2 |
focal_point_speed = 5; |
3 |
layer_difference = 1; |
4 |
|
5 |
//Focal point layer طبقة النقطة المحورية
|
6 |
layer3.hspeed = focal_point_speed; |
7 |
|
8 |
//Background layers الطبقات الخلفية
|
9 |
layer2.hspeed = layer3.hspeed + layer_difference; |
10 |
layer1.hspeed = layer2.hspeed + layer_difference; |
11 |
|
12 |
//Foreground layers الطبقات الامامية
|
13 |
layer4.hspeed = layer3.hspeed + layer_difference; |
14 |
layer5.hspeed = layer4.hspeed + layer_difference; |
المثال الثاني: Parallax Scrolling عامودي
فيما يعد الاستخدام الأكثر شيوعاً لل Parallax Scrolling هو مع الخلفيات الافقية، فإنه من الممكن استخدامه أيضا مع الخلفيات الافقية، كما في مثال المركبة الفضائية المقاتلة. وربما هنالك طرق فعالة أكثر لإنشاء حقل النجوم، لكن ال Parallax Scrolling ينجز هذه المهمة بشكل جيد.
أهم شيء لتلاحظه في هذا المثال عامودي هو ان ال Parallax Scrolling يعمل في الاتجاهات الأربعة على طول المحور x والمحور y. (سنرى كم من المهم ذلك في مثالنا الثالث والأخير.)



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



الجانب الأهم من هذا المثال هو حركة اللاعب ومشهد اللعبة. فبسبب كون خلفيتنا غير مقيدة بسرعة محددة مسبقاً أو مكان على الشاشة، فإن علينا حساب سرعة كل طبقة وموقعها بالرجوع الى نافذة المشهد بما ان اللاعب يتحرك في عدة اتجاهات.
ان مبدأ نافذة العرض الخاصة بنا هو في الزاوية العلوية في اليسار عند (X, Y). كل مبدأ لطبقة في الخلفية موجود في الزاوية اليسارية العلية للصورة المستخدمة (Sprite) عند (0, 0). من خلال إيجاد احداثيات ال x وال y الحاليين لنافذة العرض بالنسبة لعالم اللعبة، أمكننا انجاز حساب لتحديد أين يجب ان يتوضع مبدأ طبقة الخلفية في المرحلة. وهذا الموقع يتغير حيث ان نافذة العرض تتحرك بعدة اتجاهات اعتمادا على هذا الحساب.
من خلال استعمال قيم مختلفة في الحساب الخاص بكل طبقة، أصبحنا قادرين على تحريك كل طبقة بسرعات مختلفة اعتمادا على سرعة تحرك اللاعب.
الكود المستخدم في عرض الطبقة التي تتوضع تماما خلف لاعبنا هو بالصيغة التالية: draw_background_tiled_horizontal(layer, x, y)
حيث ان draw_background_tiled_horizontal()
هي دالة بسيطة لرسم مكونات فنية متتالية في موقع محدد، و bg_ex_3_2
هو المكون الفني الخاص بطبقتنا (الصورة المستخدمة).
1 |
//Layer 3
|
2 |
draw_background_tiled_horizontal( |
3 |
bg_ex_3_2, |
4 |
view_xview[view_current] / 2.5, |
5 |
(view_yview[view_current] / 10) + 300 |
6 |
); |
قيمة ال X لهذه الطبقة يتم تحديدها بقيمة ال X للمشهد الحالي (موقع الكاميرا او الناظر) مقسمة على 2.5، مكونة حركة افقية تتحرك ابطء قليلا من حركة المشهد
وبشكل مشابه فإن قيمة ال Y للطبقة محددة بقيمة ال Y للمشهد الحالي ومقسمة على 10
. قيمة ال Y لاحقاً تتم زيادتها بالمقدار 300
لوضعها في المكان الصحيح بالنسبة لعالم اللعبة. فبدون هذه الزيادة لظهرت الطبقة قريبة من أعلى عالم اللعبة بدلاً من الأسفل حيث يجب ان تكون.
هذه القيم بدون شك ستختلف في مشروعك، لكن الشيء الأهم لتتذكره هو ان سرعة الطبقة ستزداد بازدياد عدد القسمة، لكن الى حد معين فقط. من خلال استعمال القسمة يمكن للطبقة التحرك بنفس السرعة أو أبطء من سرعة اللاعب.
الطبقتان اللتان تقعان خلف هذه الطبقة تتحركان بسرعة أقل، لذا فإن رقم القسمة يصبح أصغر.
1 |
//Layer 1
|
2 |
draw_background_tiled_horizontal( |
3 |
bg_ex_3_0, |
4 |
view_xview[view_current] / 1.5, |
5 |
(view_yview[view_current] / 2.5) + 175 |
6 |
); |
7 |
|
8 |
//Layer 2
|
9 |
draw_background_tiled_horizontal( |
10 |
bg_ex_3_1, |
11 |
view_xview[view_current] / 2, |
12 |
(view_yview[view_current] / 5) +250 |
13 |
); |
لجعل طبقة تتحرك أسرع من النقطة المحورية، مثل طبقة امامية، فإن الامر يتطلب تعديلا بسيطا. في هذا المثال لا يوجد لدينا طبقة امامية، وطبقة النقطة المحورية فعلياً مرئية فقط في أسفل الشاشة. اللاعب قادر على التحرك فوق النقطة المحورية، والتي هي الأرض، لذا المركبة بحد ذاتها تصبح النقطة المحورية. نشير الى الأرض كنقطة محورية في هذا المثال لأن الأرض هي الطبقة الوحيدة التي تتحرك بنفس سرعة السفينة الفضائية. وفي هذا المكان نحصل على الشعور الحقيقي بالسرعة في المرحلة.
طبقة الأرض تتحرك بسرعة أكبر من المشهد نفسه، لذا فإن الكود الذي يقوم بعرضها مختلف قليلاً عن طبقات الخلفية الأخرى:
1 |
//Focal point layer (ground)
|
2 |
draw_background_tiled_horizontal( |
3 |
bg_ex_3_3, |
4 |
-view_xview[view_current] * 1.5, |
5 |
-view_yview[view_current] + 700 |
6 |
); |
مع الطبقات التي تتحرك أسرع من المشهد، فإننا نأخذ قيم ال X وال Y المعكوسة للمشهد الحالي ونضربهم ببعض القيم. فلا يوجد تضمين للقسمة في حساب سرعة الطبقات الامامية. في هذا المثال، طبقة الأرض تتحرك بسرعة افقية أسرع بمرة ونصف من سرعة نافذة العرض. لا يوجد ضرب في السرعة العامودية للطبقة، لذا فإنها تتحرك بنفس سرعة المشهد. تضاف القيمة 700
الى ال Y الخاص بالطبقة لوضعها في المكان المناسب اسفل عالم اللعبة
خاتمة
ال Parallax Scrolling هو طريقة سهلة ولكن فعالة جداً لإضافة الإحساس بوجود العمق في لعبة ثنائية الأبعاد. وأتمنى ان تكون الأمثلة في الديمو قد اثبتت كم انه من الممكن له ان يكون مؤثرا، وأتمنى أيضا ان يكون الدرس بحد ذاته اثبت كم من السهل تطبيقه.
مراجع
- صورة خلفية الشارع لMindChamber
- السفينة الفضائية لJerom
- اعمال فنية إضافية لSonnyBone