Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Перетворення вікна перегляду та полотна
Вступ
Це огляд двовимірних перетворень, що відбуваються для вузлів від моменту, коли вони малюють свій вміст локально, до моменту, коли вони малюються на екрані. У цьому огляді розглядаються деталі двигуна дуже низького рівня.
Мета цього навчального посібника — навчити способу передачі вхідних подій у Input із положенням у правильній системі координат.
Детальніший опис усіх систем координат і двовимірних перетворень доступний у 2D системи координат і 2D перетворення,'.
Перетворення полотна
Як уже згадувалося в попередньому посібнику Полотняні шари, кожен вузол CanvasItem (пам’ятайте, що вузли на основі Node2D та Control використовують CanvasItem як загальний корінь) буде знаходитись у Шарі Полотна. Кожен шар полотна має перетворення (переміщення, обертання, масштаб тощо), до якого можна отримати доступ як Transform2D.
Також в попередньому посібнику говорилося, що вузли за замовчуванням малюються на рівні 0 на вбудованому полотні. Щоб розмістити вузли в іншому шарі, можна використовувати вузол CanvasLayer.
Глобальне перетворення полотна
Окна перегляду також мають глобальне перетворення Canvas (також Transform2D). Це головне перетворення, яке впливає на всі окремі перетворення Canvas Layer. Як правило, це в основному використовується в Godot's CanvasItem Editor.
Перетворення розтягування
Нарешті, у вікна перегляду є Перетворення Розтягування, яке використовується при зміні розміру або розтягуванні екрана. Це перетворення використовується внутрішньо (як описано в розділі Кілька дозволів), але його також можна встановити вручну для кожного вікна перегляду.
Вхідні події множаться цим перетворенням, але відсутні ті, що описані вище. Щоб конвертувати координати InputEvent у локальні координати CanvasItem, для зручності було додано функцію CanvasItem.make_input_local().
Трансформація вікна
Кореневим вікном перегляду є Вікно. Щоб масштабувати та позиціонувати вміст Window, як описано в Кілька дозволів, кожне Window містить перетворення вікна. Він, наприклад, відповідає за чорні смуги з боків вікна, щоб вікно перегляду відображалося з фіксованим співвідношенням сторін.
Порядок перетворень
Щоб перетворити локальну координату CanvasItem у фактичну координату екрана, необхідно застосувати такий ланцюжок перетворень:
Функції перетворення
На зображенні вище показано деякі доступні функції перетворення. Усі перетворення спрямовані справа наліво, це означає, що множення перетворення на координату призводить до системи координат далі ліворуч, множення affine inverse перетворення призводить до системи координат далі від праворуч:
# Called from a CanvasItem.
canvas_pos = get_global_transform() * local_pos
local_pos = get_global_transform().affine_inverse() * canvas_pos
// Called from a 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 screenCoord = GetViewport().GetScreenTransform() * GetGlobalTransformWithCanvas() * localPos;
Однак майте на увазі, що, як правило, не бажано працювати з координатами екрану. Рекомендований підхід полягає в тому, щоб просто працювати в координатах Полотна (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)
var localPos = new Vector2(10,20); // Local to Control/Node2D.
var ie = new InputEventMouseButton()
{
ButtonIndex = MouseButton.Left,
Position = GetViewport().GetScreenTransform() * GetGlobalTransformWithCanvas() * localPos,
};
Input.ParseInputEvent(ie);