اذهب إلى المحتوى

بناء لعبة ثنائية البعد عبر محرك الألعاب Godot - الجزء الثالث: إنشاء المشهد الرئيسي في اللعبة


ابراهيم الخضور

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

إنشاء عقدة المشهد الرئيسي للعبة

لإنشاء مشهد جديد في محرك ألعاب جودو علينا إنشاء عقدة اسمها Main من النوع Node ولا حاجة أن تكون من النوع Node2D لأنها مجرد حاوية لمنطق اللعبة ولن تحتاج فعلًا إلى وظائف هذا النوع من العقد.

انقر على زر إنشاء نسخة (أيقونة السلسلة في نافذة المشهد) ثم اختر المشهد "Player.tscn".

01 create instance

أضف بعد ذلك العقد التالية كأبناء للعقدة 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:

02 path buttons

اختر الزر الموجود في المنتصف "إضافة عقدة (في مساحة خالية)" ثم ارسم مسارًا بالنقر ضمن المحرر في النقاط التي يعرضها الشكل التالي. ولكي يكون تحديد النقاط دقيقًا فعّل الخيارين "استخدام المحاذاة للشبكة Use Grid Snap" و "استخدم المحاذاة الذكية Use Smart Snap"، وستجدهما إلى يمين أيقونة "القفل" على شكل مغناطيس بجوار عدة نقاط وآخر بجوار شبكة كما توضح الصورة التالية:

03 path snaps

ملاحظة مهمة: ارسم المنحني باتجاه عقارب الساعة وإلا ستتكاثر الزواحف إلى الخارج بدلًا من الداخل.

04_draw_path2d.gif

بعد تحديد أربع نقاط، انقر على أيقونة "إغلاق المنحني" وسيكتمل هذا المنحني. أضف بعد الانتهاء من رسم المنحني العقدة PathFollow2D كابن للعقدة MobPath وسمها MobSpawnLocation. ستدور هذه العقدة وتتبع المسار عندما تتحرك وبالتالي يمكن استخدامها لاختيار مواقع واتجاهات عشوائية على طول المسار.

سيبدو المشهد الرئيسي اﻵن كما يلي:

05 main scene

السكربت الرئيسي

أضف سكربت (نص برمجي) إلى المشهد 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

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

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

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...