Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
Exemplos de entrada¶
Introdução¶
Neste tutorial, você aprenderá como usar o sistema InputEvent do Godot para capturar a entrada do jogador. Existem muitos tipos diferentes de entrada que seu jogo pode usar - teclado, gamepad, mouse, etc. - e muitas maneiras diferentes de transformar essas entradas em ações em seu jogo. Este documento mostrará alguns dos cenários mais comuns, que você pode usar como ponto de partida para seus próprios projetos.
Nota
Para uma visão geral detalhada de como o sistema de eventos de entrada do Godot funciona, veja Usando InputEvent.
Eventos versus polling¶
Às vezes, você deseja que seu jogo responda a um determinado evento de entrada - pressionando o botão "pular", por exemplo. Para outras situações, você pode querer que algo aconteça enquanto uma tecla for pressionada, como um movimento. No primeiro caso, você pode usar a função _input()
, que será chamada sempre que ocorrer um evento de entrada. No segundo caso, Godot fornece o singleton Input, que você pode usar para consultar o estado de uma entrada.
Exemplos:
func _input(event):
if event.is_action_pressed("jump"):
jump()
func _physics_process(delta):
if Input.is_action_pressed("move_right"):
# Move as long as the key/button is pressed.
position.x += speed * delta
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed("jump"))
{
Jump();
}
}
public override void _PhysicsProcess(double delta)
{
if (Input.IsActionPressed("move_right"))
{
// Move as long as the key/button is pressed.
position.X += speed * (float)delta;
}
}
Isso lhe dá a flexibilidade de misturar e combinar o tipo de processamento de entrada que você faz.
No restante deste tutorial, focaremos na captura de eventos individuais em _input()
.
Eventos de entrada¶
Eventos de entrada são objetos que herdam de InputEvent. Dependendo do tipo de evento, o objeto conterá propriedades específicas relacionadas a esse evento. Para ver como os eventos realmente se parecem, adicione um Nó e anexe o seguinte script:
extends Node
func _input(event):
print(event.as_text())
using Godot;
public partial class Node : Godot.Node
{
public override void _Input(InputEvent @event)
{
GD.Print(@event.AsText());
}
}
Ao pressionar as teclas, mover o mouse e executar outras entradas, você verá cada evento aparecer na janela de saída. Aqui está um exemplo da saída:
A
Mouse motion at position ((971, 5)) with velocity ((0, 0))
Right Mouse Button
Mouse motion at position ((870, 243)) with velocity ((0.454937, -0.454937))
Left Mouse Button
Mouse Wheel Up
A
B
Shift
Alt+Shift
Alt
Shift+T
Mouse motion at position ((868, 242)) with velocity ((-2.134768, 2.134768))
Como você pode ver, os resultados são muito diferentes para os diferentes tipos de entrada. Os eventos-chave são até impressos como seus símbolos-chave. Por exemplo, vamos considerar InputEventMouseButton. Ele herda das seguintes classes:
InputEvent - a classe base para todos os eventos de entrada
InputEventWithModifiers - adiciona a capacidade de verificar se modificadores foram pressionados, como Shift ou Alt.
InputEventMouse - adiciona propriedades de evento de mouse, como
position
InputEventMouseButton - contém o índice do botão que foi pressionado, se foi um clique duplo, etc.
Dica
É uma boa ideia manter a referência de classe aberta enquanto estiver trabalhando com eventos para que você possa verificar as propriedades e métodos disponíveis do tipo de evento.
Você pode encontrar erros se tentar acessar uma propriedade em um tipo de entrada que não a contém - chamando position
em InputEventKey
, por exemplo. Para evitar isso, teste primeiro o tipo de evento:
func _input(event):
if event is InputEventMouseButton:
print("mouse button event at ", event.position)
public override void _Input(InputEvent @event)
{
if (@event is InputEventMouseButton mouseEvent)
{
GD.Print("mouse button event at ", mouseEvent.Position);
}
}
InputMap¶
The InputMap is the most flexible way to handle a variety of inputs. You use this by creating named input actions, to which you can assign any number of input events, such as keypresses or mouse clicks. To see them, and to add your own, open Project -> Project Settings and select the InputMap tab:
Dica
A new Godot project includes a number of default actions already defined.
To see them, turn on Show Built-in Actions
in the InputMap dialog.
Capturando ações¶
Depois de definir suas ações, você pode processá-las em seus scripts usando is_action_pressed()
e is_action_released()
passando o nome da ação que você está procurando:
func _input(event):
if event.is_action_pressed("my_action"):
print("my_action occurred!")
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed("my_action"))
{
GD.Print("my_action occurred!");
}
}
Eventos de teclado¶
Eventos de teclado são capturados em InputEventKey. Embora seja recomendável usar ações de entrada, pode haver casos em que você queira examinar especificamente os principais eventos. Para este exemplo, vamos verificar o T:
func _input(event):
if event is InputEventKey and event.pressed:
if event.keycode == KEY_T:
print("T was pressed")
public override void _Input(InputEvent @event)
{
if (@event is InputEventKey keyEvent && keyEvent.Pressed)
{
if (keyEvent.Keycode == Key.T)
{
GD.Print("T was pressed");
}
}
}
Dica
See @GlobalScope_Key for a list of keycode constants.
Aviso
Devido ao fantasma do teclado, nem todas as entradas de teclas podem ser registradas em um determinado momento se você pressionar muitas teclas ao mesmo tempo. Devido à sua localização no teclado, certas teclas são mais propensas a serem fantasmas do que outras. Alguns teclados apresentam antighosting no nível do hardware, mas esse recurso geralmente não está presente em teclados de baixo custo e teclados de laptop.
Como resultado, é recomendável usar um layout de teclado padrão projetado para funcionar bem em um teclado sem antighosting. Consulte esta questão do Gamedev Stack Exchange para obter mais informações.
Modificadores de teclado¶
As propriedades do modificador são herdadas de InputEventWithModifiers. Isso permite verificar combinações de modificadores usando propriedades booleanas. Vamos imaginar que você queira que uma coisa aconteça quando o T for pressionado, mas algo diferente quando for Shift + T:
func _input(event):
if event is InputEventKey and event.pressed:
if event.keycode == KEY_T:
if event.shift_pressed:
print("Shift+T was pressed")
else:
print("T was pressed")
public override void _Input(InputEvent @event)
{
if (@event is InputEventKey keyEvent && keyEvent.Pressed)
{
switch (keyEvent.Keycode)
{
case Key.T:
GD.Print(keyEvent.ShiftPressed ? "Shift+T was pressed" : "T was pressed");
break;
}
}
}
Dica
See @GlobalScope_Key for a list of keycode constants.
Eventos do mouse¶
Os eventos de mouse derivam da classe InputEventMouse, e são separados em dois tipos: InputEventMouseButton e InputEventMouseMotion. Note que isto significa que todos os eventos de mouse irão conter uma propriedade position
.
Movimentação do mouse¶
InputEventMouseMotion ocorrem sempre que o mouse se move. Você pode encontrar a distância do movimento com a propriedade relative
.
Here's an example using mouse events to drag-and-drop a Sprite2D node:
extends Node
var dragging = false
var click_radius = 32 # Size of the sprite.
func _input(event):
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
if (event.position - $Sprite2D.position).length() < click_radius:
# Start dragging if the click is on the sprite.
if not dragging and event.pressed:
dragging = true
# Stop dragging if the button is released.
if dragging and not event.pressed:
dragging = false
if event is InputEventMouseMotion and dragging:
# While dragging, move the sprite with the mouse.
$Sprite2D.position = event.position
using Godot;
public partial class MyNode2D : Node2D
{
private bool _dragging = false;
private int _clickRadius = 32; // Size of the sprite.
public override void _Input(InputEvent @event)
{
Sprite2D sprite = GetNodeOrNull<Sprite2D>("Sprite2D");
if (sprite == null)
{
return; // No suitable node was found.
}
if (@event is InputEventMouseButton mouseEvent && mouseEvent.ButtonIndex == MouseButton.Left)
{
if ((mouseEvent.Position - sprite.Position).Length() < _clickRadius)
{
// Start dragging if the click is on the sprite.
if (!_dragging && mouseEvent.Pressed)
{
_dragging = true;
}
}
// Stop dragging if the button is released.
if (_dragging && !mouseEvent.Pressed)
{
_dragging = false;
}
}
else
{
if (@event is InputEventMouseMotion motionEvent && _dragging)
{
// While dragging, move the sprite with the mouse.
sprite.Position = motionEvent.Position;
}
}
}
}
Eventos de toque¶
Se você estiver usando um dispositivo touchscreen, poderá gerar eventos de toque. InputEventScreenTouch é equivalente a um evento de clique do mouse, e InputEventScreenDrag funciona da mesma forma que o movimento do mouse.
Dica
Para testar seus eventos de toque em um dispositivo sem tela sensível ao toque, abra as Configurações do projeto e vá para a seção "Dispositivos de entrada/Apontador". Ative "Emular toque do mouse" e seu projeto interpretará cliques e movimentos do mouse como eventos de toque.