بدأنا في مقال سابق بإنشاء لعبة إلكترونية باستخدام محرك الألعاب جودو، وحان الوقت اﻵن لضم كل شيء معًا وإنشاء مشهد كامل للعبتنا، لهذا سنبدأ في مقال اليوم باستكمال العمل على اللعبة وإنشاء مشهدها الأساسي وإعداده بالطريقة المناسبة.
إنشاء عقدة المشهد الرئيسي للعبة
لإنشاء مشهد جديد في محرك ألعاب جودو علينا إنشاء عقدة اسمها Main من النوع Node ولا حاجة أن تكون من النوع Node2D لأنها مجرد حاوية لمنطق اللعبة ولن تحتاج فعلًا إلى وظائف هذا النوع من العقد.
انقر على زر إنشاء نسخة (أيقونة السلسلة في نافذة المشهد) ثم اختر المشهد "Player.tscn".
أضف بعد ذلك العقد التالية كأبناء للعقدة Main وفق اﻷسماء التالية:
-
مؤقت
TimerباسمMobTimerللتحكم بمعدل تكاثر الزواحف، واضبط الخاصيةWait Timeله على0.5 -
مؤقت
TimerباسمScoreTimerلزيادة النتيجة كل ثانية، واضبط الخاصيةWait Timeله على1 -
مؤقت
TimerباسمStartTimerلإضافة تأخير بسيط قبل بدء اللعبة، واضبط الخاصيةWait Timeله على2 -
عقدة من النوع
Marker2DاسمهاStartPositionلتحديد موقع البداية بالنسبة للاعب
إضافة إلى ذلك، اضبط الخاصية One Shot للمؤقت StartTimer على "فعّال On" و الخاصية Position للعقدة StartPosition على
القيمة التالية(450,240).
توليد شخصيات الأعداء
نستخدم المشهد الرئيسي Main في توليد شخصيات الأعداء ونريدهم أن يظهروا في أماكن عشوائية على حواف الشاشة، لهذا أضف عقدة من النوع Path2D باسم MobPath كابن للعقدة الرئيسية. سترى عدة أزرار إضافية في أعلى المحرر عند اختيار اﻷيقونة Path2D:
اختر الزر الموجود في المنتصف "إضافة عقدة في مساحة خالية" ثم ارسم مسارًا بالنقر ضمن المحرر في النقاط التي يعرضها الشكل التالي. ولكي يكون تحديد النقاط دقيقًا فعّل الخيارين "استخدام المحاذاة للشبكة Use Grid Snap" و "استخدم المحاذاة الذكية Use Smart Snap"، وستجدهما إلى يمين أيقونة"القفل على شكل مغناطيس بجوار عدة نقاط وآخر بجوار شبكة كما توضح الصورة التالية:
ملاحظة: ارسم المنحني باتجاه عقارب الساعة وإلا ستتكاثر الزواحف إلى الخارج بدلًا من الداخل.
بعد تحديد أربع نقاط، انقر على أيقونة "إغلاق المنحني" وسيكتمل هذا المنحني. أضف بعد الانتهاء من رسم المنحني العقدة PathFollow2D كابن للعقدة MobPath وسمها MobSpawnLocation. ستدور هذه العقدة وتتبع المسار عندما تتحرك وبالتالي يمكن استخدامها لاختيار مواقع واتجاهات عشوائية على طول المسار.
سيبدو المشهد الرئيسي اﻵن كما يلي:
السكربت الرئيسي
أضف نص برمجي إلى المشهد Main ثم أضف له العبارة export var mob_scene: PackedScene@ التي تسمح لنا باختيار مشهد اﻷعداء الذي نريد صنع نسخة عنه:
extends Node @export var mob_scene: PackedScene var score
انقر على العقدة Main وستجد الخاصية Mob Scene ضمن الفاحص في لوحة "متغيرات السكربت"، وﻹسناد قيمة إلى هذه الخاصية يمكنك اتباع إحدى الطريقتين التاليتين:
-
اسحب المشهد من حاوية نظام الملفات وأفلته ضمن الخاصية
Mob Scene. -
انقر على زر السهم المجاور للخاصية
Mob Sceneوانقر "تحميل" ثم اخترmob.tscn.
اختر نسخة العقدة Player الموجودة ضمن العقدة Main ثم انقر على حاوية "عقدة" إلى جوار "الفاحص" في الشريط الجانبي لترى قائمة تضم جميع اﻹشارات للعقدة Player. جد اﻹشارة hit وانقر عليها نقرة مزدوجة (أو انقر عليها بالزر الأيمن واختر "توصيل"). ستفتح هذه العملية نافذة جديدة نريد فيها إنشاء دالة جديدة ندعوها game_over تعالج ما نريد فعله عند انتهاء اللعبة.
اكتب "game_over" في المربع النصي "الدالة المتلقية Receiver Method" أسفل النافذة ثم انقر زر "وصل Connect". وما سيحدث اﻵن أن اﻹشارة hit التي بثها اللاعب Player سيعالجها السكربت اﻷساسي "Main". أضف اﻵن الشيفرة التالية إلى الدالة الجديدة، وأضف أيضًَا الدالة new_game التي تحضّر كل شيء عند بداية اللعبة:
func game_over(): $ScoreTimer.stop() $MobTimer.stop() func new_game(): score = 0 $Player.start($StartPosition.position) $StartTimer.start()
صل اﻵن اﻹشارة ()timeout العائدة إلى كل عقدة مؤقت (StartTimer و ScoreTimer و MobTimer) إلى السكربت الرئيسي. وسيشغل المؤقت StartTimer المؤقتين الآخرين ويزيد المؤقت ScoreTimer النتيجة بمقدار 1.
func _on_score_timer_timeout(): score += 1 func _on_start_timer_timeout(): $MobTimer.start() $ScoreTimer.start()
سننشئ ضمن الدالة نسخة عن العدو (الزواحف)، لهذا، سنختار مكانًا عشوائيًا للبدء على المسار Path2D ونضبط حركة العدو. تدور العقدة تلقائيًا عندما تلحق بالمسار، لهذا سنستفيد منها في اختيار جهة حركة الزاحف وموقعه. وعندما تتكاثر الزواحف سنختار قيمة عشوائية لسرعة حركتها بين 150 و 250. وانتبه إلى أن إضافة نسخة جديدة إلى المشهد تكون من خلال التعليمة add_child:
func _on_mob_timer_timeout(): # mob scene أنشئ نسخة من مشهد الزاحف var mob = mob_scene.instantiate() # Path2D اختر مكانًا عشوائيًا على المسار. var mob_spawn_location = get_node("MobPath/MobSpawnLocation") mob_spawn_location.progress_ratio = randf() # اجعل اتجاه الزاحف عمودًا على اتجاه المسار var direction = mob_spawn_location.rotation + PI / 2 # اختر موقعًا عشوائيًًًًًًًًًا للزاحف mob.position = mob_spawn_location.position # أضف بعض العشوائية إلى المسار direction += randf_range(-PI / 4, PI / 4) mob.rotation = direction # اختر سرعة الزاحف var velocity = Vector2(randf_range(150.0, 250.0), 0.0) mob.linear_velocity = velocity.rotated(direction) # إجعل الزواحف تتكاثر بإضافتها إلى الشاشةالرئيسية add_child(mob)
ملاحظة هامة: قد تتساءل لماذا نستخدم العدد PI في الدوال التي تتعامل مع الزوايا؟ لأن جودو يستخدم الراديان لقياس الزوايا. تمثّل PI نصف دوره كما يمكن استعمال TAU التي تمثّل دورة كاملة. لكن إن كنت تفضّل العمل مع الدرجات ستحتاج إلى الدالتين ()rad_to_deg و ()deg_to_rad للتحويل بين الدرجات والراديان.
اختبار المشهد
نختبر اﻵن إذا كانت كل شيء على ما يرام حتى اللحظة، لهذا استدعي الدالة new_game ضمن الدالة ()ready_:
func _ready(): new_game()
لنجعل أيضًا المشهد Main المشهد الرئيسي في اللعبة، وهو المشهد الذي يعمل تلقائيًا. انقر على زر التشغيل واختر main.tscn عندما يُطلب ذلك.
اقتباستلميح:
إن كنت قد اخترت سابقًا مشهدًا آخر ليكون المشهد اﻷساسي يمكنك النقر على الملف
main.tscnفي نظام الملفات وتحديد "Set As Main Scene"
من المفترض أن تكون قادرًا على تحريك اللاعب في جميع الاتجاهات وترى الزواحف تتحرك وتتكاثر، وسترى كيف يختفي اللاعب عندما يصطدم بالعدو.
عندما تتأكد أن كل شيء يعمل جيدًا أزل الدالة new_game من الدالة ()ready_.
الخلاصة
تعلمنا في مقال اليوم كيف ننشئ المشهد الأساسي للعتبنا الإلكترونية وسنكتفي في هذا المقال بهذه المرحلة، ومع ذلك لا تزال اللعبة غير مكتملة وتنقصها بعض اللمسات النهائية وإنشاء واجهة مناسبة للعبة، لذا سنشرح خطوات تعزيز اللعبة بواجهة تتضمن تأثيرات صوتية واختصارات لوحة المفاتيح وغيرها من الخيارات وهذا ما سنراه في المقال التالي من هذه السلسلة.
ترجمة -وبتصرف- للمقال: The main game scene

أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.