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.

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

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())

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)

InputMap

O InputMap é a maneira mais flexível de lidar com uma variedade de entradas. Você o utiliza criando ações de entrada nomeadas, às quais você pode atribuir qualquer número de eventos de entrada, como pressões de teclas ou cliques de mouse. Para vê-las e adicionar as suas próprias, abra Projeto -> Configurações do Projeto e selecione a aba Mapa de Entrada:

../../_images/inputs_inputmap.webp

Dica

Um novo projeto Godot inclui uma série de ações padrão já definidas. Para vê-las, ative Show Built-in Actions na caixa de diálogo InputMap.

Embora não seja estritamente necessário, recomenda-se usar a convenção de nomenclatura snake_case para os nomes das ações de entrada.

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!")

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")

Dica

Veja @GlobalScope_Key para uma lista de constantes de códigos de tecla.

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")

Dica

Veja @GlobalScope_Key para uma lista de constantes de códigos de tecla.

Eventos do mouse

Eventos de mouse derivam da classe InputEventMouse e são separados em dois tipos: InputEventMouseButton e InputEventMouseMotion. Observe que isso significa que todos os eventos de mouse conterão uma propriedade position.

Botões do mouse

Capturar botões do mouse é muito semelhante a tratar eventos de teclado. @GlobalScope_MouseButton contém uma lista de constantes MOUSE_BUTTON_* para cada botão possível, que serão reportadas na propriedade button_index do evento. Observe que a roda de rolagem também conta como um botão - dois botões, para ser preciso, com ambos MOUSE_BUTTON_WHEEL_UP e MOUSE_BUTTON_WHEEL_DOWN sendo eventos separados.

func _input(event):
    if event is InputEventMouseButton:
        if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
            print("Left button was clicked at ", event.position)
        if event.button_index == MOUSE_BUTTON_WHEEL_UP and event.pressed:
            print("Wheel up")

Movimentação do mouse

InputEventMouseMotion ocorrem sempre que o mouse se move. Você pode encontrar a distância do movimento com a propriedade relative.

Aqui está um exemplo usando eventos de mouse para arrastar e soltar um nó Sprite2D:

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

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.