إدارة انتقاد في مشروع لعبة على محرك Godot

تحياتي للجميع! أود اليوم أن أتحدث عن كيفية تنفيذ إدارة التمرير السريع في مشروع لعبة للأندرويد على محرك Godot.

صورة

اسمي بيتر ، وأنا أحد المستخدمين النشطين لمحرك ألعاب Godot Engine.
في قسم اللغة الروسية ، هناك نقص كبير في المواد على هذه الأداة ، الأمر الذي يفاجئني كثيرًا ، نظرًا لأنه أحد محركات الألعاب الأسرع نموًا.
بالطبع ، من عدة نواحٍ أدنى من محركات مثل Unity و UE وما شابه ، ولن تصنع لعبة فئة AAA عليها.

ومع ذلك! إنه مجاني (ممتلئ) ، ومنصة عرضية (ممتلئة) ، ويبلغ وزنه حوالي 60 ميغابايت ، على عكس الوحدة نفسها.

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

لقد رأيت بالفعل مقالتين عن حبري عليه ، وهذا صغير جدًا ، نظرًا لأنه ودي للغاية للمطور لدرجة أنه من الصعب تجاوزه وعدم تجربته.

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

كلغة برمجة ، يمكنك مرة أخرى استخدام خيارين: GDScript و C #. سأستخدم الأول.

تبدو واجهة المحرر الرئيسي كما يلي:

صورة

يمكنك من خلالها العمل في وقت واحد مع الأبعاد الثلاثية والثنائية الأبعاد والنصوص وبشكل عام كل ما قد يحتاجه المطور.

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

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

لذا ، المشهد الرئيسي للمظاهرة ، سيكون لدينا لعبة.

يبدو هيكلها كما يلي:

صورة

العقدة الجذرية لمتاجر اللعبة متداخلة داخل نفسها:
- العالم ، - تخزين بيانات المستوى فيها
- - المستوى ، - مجموعة من الكائنات البيئية (الكتل ، الخواتم ، العوائق)
- - اللاعب ، - كائن اللاعب
- - InterpolatedCamera ، - سلس الكاميرا التي تراقب المشغل
- gui - - interface ، لن تكون متورطة.

أسماء الأشياء والهيكل تعسفية وهذه ليست سوى حالة خاصة.
بالقرب من بعض الكائنات ، يمكنك رؤية الرموز التي تقول أن هذا الكائن هو عبارة عن تهيئة مسبقة (مشهد متداخل) ويمكن أيضًا إضافة نص برمجي إليه.

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

صورة

في وضع التشغيل هذا ، يمكنك تحرير سلوك الكائنات. في الواقع ، في هذه الحالة ، هو نص برمجي لكائن العالم ، والذي عند تحميل كائن في اللعبة يضبط كائن الكاميرا (InterpolatedCamera) الهدف للتتبع.

extends Spatial

func _ready():
	$InterpolatedCamera.target = '../player/camera' #  , ,         (  ).   player  "camera"   pivot.   .         .

من الناحية النحوية ، GDScript يشبه Python. يمكنك الحصول على تدريب قصير على GDScript بالروسية هنا: كتاب GDScript

مع وجود كائن عالمي ، من الواضح أنه يحدد هدف الكاميرا للتتبع. الكائن التالي (بالفعل طفل من العالم) هو المستوى. يبدو هيكلها كما يلي:

صورة

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

يعد كائن المشغل أكثر إثارة للاهتمام الآن ، والذي يحتوي على منطق التحكم في التمرير لشاشات اللمس.

يبدو هذا الإعداد المسبق كما يلي:

صورة

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

  • camera, — , , . player.
  • CollisionShape, — . «» . , , . .
  • MeshInstance, — . , . Blender 3D , .
  • Tween, . .

حسنًا ، ضع في اعتبارك الآن البرنامج النصي نفسه في الكائن الجذر. وتبين أنها الأكثر ضخامة في "اللعبة" بأكملها.

صورة

حسنًا ، وصفه وفك ترميزه.


extends KinematicBody #       

#  
const GRAV = 0.5 #   (      Y, ..       ,     )
const SPEED = 2 #  
const SWIPE_SPEED = 30 #       
const JUMP_SPEED = 10 #     

onready var ball = $MeshInstance #        
onready var tween = $Tween #      
var vel = Vector3() #     
var swipe = '' #       


func _ready():
	pass #        ;    


#       (60FPS)  
func _physics_process(delta): # delta -  Delta Time ,  ,    
	vel.y -= GRAV #      (  )
	vel.z = -SPEED #     .   
	ball.rotate_x(-delta * SPEED * 2) #     ,   ""

	if swipe && swipe != 'swiped': #         
		if swipe == 'up' && is_on_floor(): #        ()
			vel.y = JUMP_SPEED #     ,   -  
		elif swipe == 'left' || swipe == 'right': #     
			tween.interpolate_property(self, "translation", #      
				translation, translation+Vector3(-2 if swipe == 'left' else 2,0,0), 0.2, #    ,         X.      . -2  ,  2
				Tween.TRANS_CUBIC, Tween.EASE_IN_OUT) #     "" 
			tween.start() #   
		swipe = 'swiped' #   ,   

	vel = move_and_slide(vel, Vector3.UP) #       ,                  

#       
func _input(e):
	if e is InputEventScreenDrag: # ,       
		if !swipe: #       
			if e.relative.y < -SWIPE_SPEED: #       Y
				swipe = 'up' #     (     )    ( ,          ),     " (UP)"
			elif e.relative.x < -SWIPE_SPEED: #      ,     X.     -  
				swipe = 'left'
			elif e.relative.x > SWIPE_SPEED: #  ,
				swipe = 'right' #  

	elif e is InputEventScreenTouch: #     
		if !e.pressed: #      
			swipe = '' #   

وصفت كل سطر ، آمل ، مع نصوص كل شيء زائد أو ناقص واضح.

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

لم أتخذ أسهل طريقة لتنفيذ التمرير السريع ، ولكنه موثوق للغاية ويعمل في معظم الحالات. بالطبع ، هذا يعتمد على نوع اللعبة ونوعها.

نتيجة للعمل المنجز ، نحصل على مثال عن مدى سهولة تنفيذ إدارة التمرير السريع في عشر دقائق.

في المجموع ، استغرق الأمر مني حوالي 30 دقيقة ، وهذا يأخذ في الاعتبار إنشاء نماذج في Blender.

حسنًا ، وفقًا للتقاليد ...

فيديو التنمية


مصدر الرمز

All Articles