Transformações de janela de exibição e tela
Introdução
This is an overview of the 2D transforms going on for nodes from the moment they draw their content locally to the time they are drawn onto the screen. This overview discusses very low-level details of the engine.
O objetivo deste tutorial é ensinar uma maneira de alimentar eventos de entrada com uma posição no sistema de coordenadas correto.
Uma descrição mais extensa de todos os sistemas de coordenadas e transformações 2D está disponível em 2D coordinate systems and 2D transforms.
Transformação de tela
Como mencionado no tutorial anterior, Camadas de canvas, cada nó CanvasItem (lembre-se que os nós baseados em Node2D e Control usam CanvasItem como sua raiz comum) residirão em uma Canvas Layer. Cada camada de canvas tem uma transformação (translação, rotação, escala, etc.) que pode ser acessada como Transform2D.
Também abordado no tutorial anterior, os nós são desenhados por padrão na Camada 0, na tela embutida. Para colocar nós em uma camada diferente, um nó CanvasLayer pode ser usado.
Transformação global de canvas
Viewports also have a Global Canvas transform (also a Transform2D). This is the master transform and affects all individual Canvas Layer transforms. Generally, this is primarily used in Godot's CanvasItem Editor.
Transformação de alongamento
Finalmente, as viewports possuem uma Stretch Transform, que é usada ao redimensionar ou esticar a tela. Esta transformação é usada internamente (conforme descrito em Resoluções múltiplas), mas também pode ser configurada manualmente em cada viewport.
Input events are multiplied by this transform, but lack the ones above. To convert InputEvent coordinates to local CanvasItem coordinates, the CanvasItem.make_input_local() function was added for convenience.
Window transform
A viewport raiz é um node do tipo Window. Para dimensionar e posicionar o conteúdo da Window conforme descrito em Resoluções múltiplas, cada Window contém uma transformação da janela (window transform). Ela é responsável, por exemplo, pelas barras pretas nas laterais da Window para que a Viewport seja exibida com uma proporção fixa.
Ordem de transformação
To convert a CanvasItem local coordinate to an actual screen coordinate, the following chain of transforms must be applied:
Funções de transformação
A imagem acima mostra algumas funções de transformação disponíveis. Todas as transformações são aplicadas da direita para a esquerda, o que significa que multiplicar uma transformação por uma coordenada resulta em um sistema de coordenadas mais à esquerda, enquanto multiplicar o inverso afim de uma transformação resulta em um sistema de coordenadas mais à direita:
# 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;
Finalmente, para converter as coordenadas locais de um CanvasItem em coordenadas de tela, basta multiplicar na seguinte ordem:
var screen_coord = get_viewport().get_screen_transform() * get_global_transform_with_canvas() * local_pos
var screenCoord = GetViewport().GetScreenTransform() * GetGlobalTransformWithCanvas() * localPos;
Tenha em mente, no entanto, que geralmente não é desejável trabalhar com coordenadas de tela. A abordagem recomendada é simplesmente trabalhar nas coordenadas do Canvas (CanvasItem.get_global_transform()), para permitir que o redimensionamento automático da resolução da tela funcione corretamente.
Alimentando eventos de entrada personalizados
It is often desired to feed custom input events to the game. With the above knowledge, to correctly do this in the focused window, it must be done the following way:
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);