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
InputEventMouseMotion : button_mask=0, position=(108, 108), relative=(26, 1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)
InputEventMouseButton : button_index=BUTTON_LEFT, pressed=true, position=(108, 107), button_mask=1, doubleclick=false
InputEventMouseButton : button_index=BUTTON_LEFT, pressed=false, position=(108, 107), button_mask=0, doubleclick=false
S
F
Alt
InputEventMouseMotion : button_mask=0, position=(108, 107), relative=(0, -1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)

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ê usa isso criando ações de entrada nomeadas, às quais você pode atribuir qualquer número de eventos de entrada, como pressionamentos de tecla ou cliques do mouse. Um novo projeto Godot inclui uma série de ações padrão já definidas. Para vê-los e adicionar o seu próprio, abra Projeto -> Configurações do Projeto e selecione a aba InputMap:

../../_images/inputs_inputmap.png

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.scancode == KEY_T:
            print("T was pressed")

Dica

Ver @GlobalScope_KeyList para uma lista de constantes de scancode.

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.scancode == KEY_T:
            if event.shift:
                print("Shift+T was pressed")
            else:
                print("T was pressed")

Dica

Ver @GlobalScope_KeyList para uma lista de constantes de scancode.

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.

Botões do mouse

A captura de botões do mouse é muito semelhante à manipulação de eventos-chave. @GlobalScope_ButtonList contém uma lista de constantes BUTTON_* para cada botão possível, que serão relatados 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 BUTTON_WHEEL_UP e BUTTON_WHEEL_DOWN sendo eventos separados.

func _input(event):
    if event is InputEventMouseButton:
        if event.button_index == BUTTON_LEFT and event.pressed:
            print("Left button was clicked at ", event.position)
        if event.button_index == 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ó Sprite:

extends Node


var dragging = false
var click_radius = 32 # Size of the sprite.


func _input(event):
    if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
        if (event.position - $Sprite.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.
        $Sprite.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.