Преобразование области просмотра и холста

Введение

Это обзор 2D-преобразований, происходящих для узлов с момента, когда они рисуют свое содержимое локально, до момента, когда они рисуются на экране. В этом обзоре обсуждаются очень низкоуровневые детали движка.

Цель этого руководства - научить Вас способу передачи событий ввода в Input с позицией в правильной системе координат.

Более подробное описание всех систем координат и 2D-преобразований доступно в 2D coordinate systems and 2D transforms.

Преобразования холста

Как упоминалось в предыдущем руководстве Слои холста, каждый узел CanvasItem (помните, что узлы на основе Node2D и Control используют CanvasItem в качестве общего корня) будет находиться в Canvas Layer. Каждый слой холста имеет преобразование (перемещение, поворот, масштаб и т.д.), к которому можно получить доступ как Transform2D.

Как было сказано в предыдущем уроке, узлы по умолчанию рисуются на 0-ом слое на встроенном холсте. Для того, чтобы поместить узлы на другой слой, можно воспользоваться узлом CanvasLayer.

Глобальное преобразование холста

У вьюпортов также есть Global Canvas transform (Глобальное преобразование Холста) (также Transform2D). Это главное преобразование, которое влияет на все отдельные преобразования Canvas Layer. Как правило, оно в основном используется в редакторе CanvasItem редактора Godot.

Преобразования растяжения

Наконец, в видовых экранах есть функция Stretch Transform, которая используется при изменении размера или растягивании экрана. Это преобразование используется внутренне (как описано в Multiple resolutions), но также может быть вручную установлено для каждого видового экрана.

События ввода умножаются на это преобразование, но не имеют тех, что выше. Для преобразования координат InputEvent в локальные координаты CanvasItem для удобства была добавлена функция CanvasItem.make_input_local().

Трансформация окна

Корневое окно просмотра представляет собой Окно. Чтобы масштабировать и позиционировать содержимое окна в соответствии с описанным в Multiple resolutions, каждое окно содержит оконное преобразование. Оно, например, отвечает за черные полосы по краям окна, чтобы Окно просмотра отображалось с фиксированным соотношением сторон.

Порядок преобразований

Чтобы преобразовать локальную координату CanvasItem в фактическую экранную координату, необходимо применить следующую цепочку преобразований:

../../_images/viewport_transforms3.webp

Функции преобразования

График выше показывает некоторые доступные функции преобразования. Все преобразования выполняются справа налево, что означает: умножение преобразования на координату смещает систему координат влево, а умножение аффинного обратного преобразования смещает систему координат вправо:

# Called from a CanvasItem.
canvas_pos = get_global_transform() * local_pos
local_pos = get_global_transform().affine_inverse() * canvas_pos

Наконец, чтобы преобразовать локальные координаты CanvasItem в экранные координаты, просто умножьте в следующем порядке:

var screen_coord = get_viewport().get_screen_transform() * get_global_transform_with_canvas() * local_pos

Однако имейте в виду, что обычно нежелательно работать с экранными координатами. Рекомендуемый подход - просто работать в координатах холста (CanvasItem.get_global_transform ()), чтобы автоматическое изменение размера разрешения экрана работало правильно.

Передача пользовательских событий ввода

Часто требуется передавать пользовательские события ввода в игру. С учетом вышеизложенных знаний, чтобы правильно сделать это в сфокусированном окне, это должно быть сделано следующим образом:

var local_pos = Vector2(10, 20) # Local to Control/Node2D.
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)