الإطار المعروض وتحول الحاوية في جودو
مقدمة
نتكلّم هنا عن التحول ثنائي الأبعاد الذي يطرأ على العقد من لحظة رسمهم لمحتواهم محليًا إلى وقت رسمهم على الشاشة، ونذكر تفاصيلًا بسيطة جدًا عن المحرك.
هدف هذا الدليل هو تعليمك طريقة لإدخال الأحداث إلى الدخل مع موقعها الصحيح في نظام الإحداثيات.
يوجد شرح موسّع أكثر من ذلك عن كل جمل الإحداثيات والتحول ثنائي الأبعاد في جمل الإحداثيات والتحولات ثنائية الأبعاد.
تحول الحاوية
كما تحدثنا سابقًا، فإن طبقات الحاوية وكل عقدة CanvasItem (تذكر أن Node2D والعقد التي تُستخدم للتحكم يستخدمان CanvasItem كالجذر المشترك) يستقران في طبقة حاوية. لدى كل طبقة حاوية تحول (انتقال، دوران، تغيير حجم، إلخ) يمكن الوصول له كأنه عقدة Transform2D.
كما تحدثنا أيضًا أن العقد تُرسم في الطبقة 0 بشكل افتراضي في الحاوية المضمنة، ويمكن استخدام CanvasLayer لوضع العقد في طبقة أخرى مختلفة.
تحول الحاوية العام
لدى الإطارات المعروضة viewports تحول حاوية عام global canvas transform أيضًا (بالإضافة إلى Transform2D)، وهذا يمثل التحول الشامل الذي يؤثر على كل تحولات طبقة الحاوية. يُستخدم ذلك عادة في محرر CanvasItem الخاص بجودو.
تحول المد
أخيرًا، لدى الإطارات المعروضة تحول مد stretch transform، الذي يُستخدم عند تعديل حجم الشاشة أو مدّها. يُستخدم هذا التحول داخليًا (كما هو مشروح في دِقات متعددة) ولكن يمكن ضبطه يدويًا أيضًا في كل إطار معروض.
تتضاعف أحداث الدخل مع هذا التحول ولكن تفتقر إلى ما أعلاه. أُضيفت دالة CanvasItem.make_input_local() لتحويل إحداثيات InputEvent إلى إحداثيات CanvasItem محلية لتكون أكثر ملائمة.
تحويل النافذة
إن الإطار المعروض الجذر هو كائن من الصنف Window. إذ يحتوي كل Window على تحول نافذة لأجل نقل وتعديل محتوى النافذة كما ذُكر في دِقات متعددة، . وهي مسؤولة مثلًا عن المستطيلات السوداء في أطراف النافذة لكي يكون الإطار المعروض بنسبة أبعاد ثابتة.
ترتيب التحول
لتحويل إحداثيات CanvasItem المحلية إلى إحداثيات الشاشة الفعلية يجب تطبيق السلسلة التالية من التحولات:
IMAGE
دوال التحول
تظهر الصورة السابقة بعض دوال التحول المتوفرة، ويتم توجيه جميع التحولات من اليمين إلى اليسار، هذا يعني أن ضرب التحول بالإحداثيات يُنتج جملة إحداثيات مُتجهة إلى اليسار، وضرب التحويل التآلفي العكسي affine inverse الخاص بالتحول يُنتج جملة احداثيات مُتجهة نحو اليمين
بلغة جي دي سكربت:
# استدعاء من CanvasItem
canvas_pos = get_global_transform() * local_pos
local_pos = get_global_transform().affine_inverse() * canvas_pos
بلغة سي شارب:
// استدعاء من CanvasItem
canvasPos = GetGlobalTransform() * localPos;
localPos = GetGlobalTransform().AffineInverse() * canvasPos;
أخيرًا، لتحويل إحداثيات CanvasItem المحلية إلى إحداثيات الشاشة فقط اضرب بالترتيب التالي: بلغة جي دي سكربت:
var screen_coord = get_viewport().get_screen_transform() * get_global_transform_with_canvas() * local_pos
بلغة سي شارب:
var screenCord = GetViewport().GetScreenTransform() * GetGlobalTransformWithCanvas() * localPos;
تذكر أنه من غير المرغوب العمل باستخدام إحداثيات الشاشة، إذ أن الطريقة الموّصى بها هي استخدام إحداثيات CanvasItem (CanvasItem.get_global_transform()
) للسماح بتغيير دقة الشاشة تلقائيًا للعمل بشكل صحيح.
إضافة أحداث دخل مخصصة
من المحبّذ إضافة أحداث دخل مخصصة استنادًا على المعرفة السابقة، وذلك في في النافذة الفعالة بشكل صحيح، يجب أن إجراء ذلك بالطريقة التالية:
بلغة جي دي سكربت:
var local_pos = Vector2(10, 20) # قيمة محلية إلى عقدة ثنائية الأبعاد/عقدة تحكم
var ie = InputEventMouseButton.new()
ie.button_index = MOUSE_BUTTON_LEFT
ie.position = get_viewport().get_screen_transform() * get_global_transform_with_canvas() * local_pos
Input.parse_input_event(ie)
بلغة سي شارب:
var localPos = new Vector2(10,20); // قيمة محلية إلى عقدة ثنائية الأبعاد/عقدة تحكم
var ie = new InputEventMouseButton()
{
ButtonIndex = MouseButton.Left,
Position = GetViewport().GetScreenTransform() * GetGlobalTransformWithCanvas() * localPos,
};
Input.ParseInputEvent(ie);