نظرة عامة على الحركة ثنائية الأبعاد في جودو

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث

مرّ كل مبتدئ بهذه المرحلة: "كيف يمكنني تحريك شخصيتي؟" قد يكون لديك متطلبات خاصة اعتمادًا على أسلوب اللعبة التي تصنعها، ولكن بشكل عام تعتمد الحركة في معظم الألعاب ثنائية الأبعاد على عدد محدود من التصاميم.

سنستخدم CharacterBody2D لهذه الأمثلة، ولكن المبادئ تنطبق على أنواع العقد الأخرى (Area2D، RigidBody2D) أيضًا.

إعداد البيئة

يستخدم كل مثال أدناه نفس إعداد المشهد. ابدأ بعقدة CharacterBody2D مع ابنين: Sprite2D وCollisionShape2D. يمكنك استخدام أيقونة جودو icon.png لملمس Sprite2D أو استخدام أي صورة ثنائية الأبعاد أخرى لديك.

اذهب إلى المشروع Project > إعدادات المشروع Project Settings وحدد التبويبة "خريطة الإدخال Input Map". أضف إجراءات الإدخال التالية (راجع InputEvent للحصول على التفاصيل):

movement inputs.png

حركة في 8 اتجاهات

نريد من المستخدم في مثالنا الحالي أن يضغط على مفاتيح الاتجاهات الأربعة (أعلى/يسار/أسفل/يمين أو W/A/S/D) ويتحرك في الاتجاه المحدد. يأتي اسم "الحركة ذات 8 اتجاهات" من حقيقة أن اللاعب يمكنه التحرك قطريًا بالضغط على مفتاحين في نفس الوقت.

ezgif-5-1e2c30f747.gif

أضف سكربت إلى محتوى الشخصية وأضف الشيفرة برمجية التالي:

بلغة جي دي سكربت:

extends CharacterBody2D

@export var speed = 400

func get_input():
	var input_direction = Input.get_vector("left", "right", "up", "down")
	velocity = input_direction * speed

func _physics_process(delta):
	get_input()
	move_and_slide()

بلغة سي شارب:

using Godot;

public partial class Movement : CharacterBody2D
{
    [Export]
    public int Speed { get; set; } = 400;

    public void GetInput()
    {

        Vector2 inputDirection = Input.GetVector("left", "right", "up", "down");
        Velocity = inputDirection * Speed;
    }

    public override void _PhysicsProcess(double delta)
    {
        GetInput();
        MoveAndSlide();
    }
}

في الدالة get_input()‎، نستخدم دالة get_vector()‎ الخاصة بالصنف Input للتحقق من الأحداث الرئيسية الأربعة وجمعها الذي يعيد شعاع اتجاهي. يمكننا بعد ذلك ضبط سرعتنا عن طريق ضرب الشعاع الاتجاهي، الذي يبلغ طوله 1 بالسرعة المطلوبة.

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

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

الدوران مع الحركة

يُطلق على هذا النوع من الحركة أحيانًا اسم "نمط الكويكبات" لأنه يشبه طريقة عمل لعبة الآركيد arcade الكلاسيكية. يؤدي الضغط على اليسار/اليمين إلى تدوير الحرف، بينما يؤدي الضغط على أعلى/أسفل إلى تحريكها للأمام والخلف في أي اتجاه يواجهه.

ezgif-5-e62c403f34.gif

بلغة جي دي سكربت:

extends CharacterBody2D

@export var speed = 400
@export var rotation_speed = 1.5

var rotation_direction = 0

func get_input():
	rotation_direction = Input.get_axis("left", "right")
	velocity = transform.x * Input.get_axis("down", "up") * speed

func _physics_process(delta):
	get_input()
	rotation += rotation_direction * rotation_speed * delta
	move_and_slide()

بلغة سي شارب:

using Godot;

public partial class Movement : CharacterBody2D
{
    [Export]
    public int Speed { get; set; } = 400;

    [Export]
    public float RotationSpeed { get; set; } = 1.5f;

    private int _rotationDirection;

    public void GetInput()
    {
        _rotationDirection = Input.GetAxis("left", "right");
        Velocity = Transform.X * Input.GetAxis("down", "up") * Speed;
    }

    public override void _PhysicsProcess(double delta)
    {
        GetInput();
        Rotation += _rotationDirection * RotationSpeed * (float)delta;
        MoveAndSlide();
    }
}

أضفنا متغيرَين لتتبع اتجاه الدوران والسرعة، يُطبَّق الدوران مباشرةً على محتوى الخاصية rotation.

نستخدم محتوى الخاصية transform.x لضبط السرعة وهو شعاع موجه باتجاه الأمام ويُضرب بمقدار السرعة.

الدوران مع الحركة (الفأرة)

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

movement rotate2.gif

بلغة جي دي سكربت:

extends CharacterBody2D

@export var speed = 400

func get_input():
	look_at(get_global_mouse_position())
	velocity = transform.x * Input.get_axis("down", "up") * speed

func _physics_process(delta):
	get_input()
	move_and_slide()

بلغة سي شارب:

using Godot;

public partial class Movement : CharacterBody2D
{
    [Export]
    public int Speed { get; set; } = 400;

    public void GetInput()
    {
        LookAt(GetGlobalMousePosition());
        Velocity = Transform.X * Input.GetAxis("down", "up") * Speed;
    }

    public override void _PhysicsProcess(double delta)
    {
        GetInput();
        MoveAndSlide();
    }
}

نحن هنا نستخدم تابع ()look_at الخاص بالعقدة Node2D لتوجيه اللاعب نحو موضع الفأرة. يمكنك الحصول على التأثير ذاته بدون هذه الدالة عن طريق ضبط الزاوية كما يلي: بلغة جي دي سكربت:

rotation = get_global_mouse_position().angle_to_point(position)

بلغة سي شارب:

var rotation = GetGlobalMousePosition().AngleToPoint(Position);

انقر وحرّك

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

ezgif-5-e5633f4ad1.gif

بلغة جي دي سكربت:

extends CharacterBody2D

@export var speed = 400

var target = position

func _input(event):
	if event.is_action_pressed("click"):
		target = get_global_mouse_position()

func _physics_process(delta):
	velocity = position.direction_to(target) * speed
	# look_at(target)
	if position.distance_to(target) > 10:
		move_and_slide()

بلغة سي شارب:

using Godot;

public partial class Movement : CharacterBody2D
{
    [Export]
    public int Speed { get; set; } = 400;

    private Vector2 _target;

    public override void _Input(InputEvent @event)
    {
        if (@event.IsActionPressed("click"))
        {
            _target = GetGlobalMousePosition();
        }
    }

    public override void _PhysicsProcess(double delta)
    {
        Velocity = Position.DirectionTo(_target) * Speed;
        // LookAt(target);
        if (Position.DistanceTo(_target) > 10)
        {
            MoveAndSlide();
        }
    }
}

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

نصيحة: يمكن أيضًا استخدام هذه التقنية كأساس للشخصية "التابعة". يمكن أن يكون الموضع target هو موضع أي كائن تريد الانتقال إليه.

ملخص

قد تجد نماذج التعليمات البرمجية هذه مفيدة كنقاط بداية لمشاريعك الخاصة. لا تتردد في استخدامها وتجربتها لمعرفة ما يمكنك صنعه.

يمكنك تحميل هذا المشروع التجريبي من هنا: 2d_movement_starter.zip

مصادر