Ejemplo de Input¶
Introducción¶
En este tutorial, aprenderás a utilizar el sistema InputEvent de Godot para capturar la entrada del reproductor. Hay muchos tipos diferentes de entrada que tu juego puede utilizar - teclado, gamepad, ratón, etc. - y muchas maneras diferentes de convertir esas entradas en acciones en tu juego. Este documento te mostrará algunos de los escenarios más comunes, que puedes usar como puntos de partida para tus propios proyectos.
Nota
Para una visión detallada de cómo funciona el sistema de eventos de entrada de Godot, ver Usando InputEvent.
Eventos vs polling¶
A veces quieres que tu juego responda a un determinado evento de entrada - pulsando el botón de "salto", por ejemplo. En otras situaciones, puede que quieras que algo suceda mientras se presiona una tecla, como el movimiento. En el primer caso, puedes usar la función input()
, que será llamada siempre que ocurra un evento de entrada. En el segundo caso, Godot proporciona el singleton Input, que puedes usar para consultar el estado de una entrada.
Ejemplos:
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 inputEvent)
{
if (inputEvent.IsActionPressed("jump"))
{
Jump();
}
}
public override void _PhysicsProcess(float delta)
{
if (Input.IsActionPressed("move_right"))
{
// Move as long as the key/button is pressed.
position.x += speed * delta;
}
}
Esto le da la flexibilidad de mezclar y combinar el tipo de procesamiento de entrada que hace.
Para el resto de este tutorial, nos centraremos en la captura de eventos individuales en input()
.
Eventos de entrada¶
Los eventos de entrada son objetos que heredan de InputEvent. Dependiendo del tipo de evento, el objeto contendrá propiedades específicas relacionadas con ese evento. Para ver cómo son realmente los eventos, añade un Nodo y adjunta el siguiente script:
extends Node
func _input(event):
print(event.as_text())
using Godot;
using System;
public class Node : Godot.Node
{
public override void _Input(InputEvent inputEvent)
{
GD.Print(inputEvent.AsText());
}
}
A medida que presionas las teclas, mueves el ratón y realizas otras entradas, verás cómo cada evento se desplaza por la ventana de salida. Aquí hay un ejemplo de la salida:
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 puedes ver, los resultados son muy diferentes para los diferentes tipos de entrada. Los eventos clave se imprimen incluso como sus símbolos clave. Por ejemplo, consideremos InputEventMouseButton. Hereda de las siguientes clases:
InputEvent - La clase base para todos los eventos de entrada
InputEventWithModifiers - agrega la habilidad de verificar si algunos modificadores fueron presionados, como Shift o Alt.
InputEventMouse - agrega propiedades de eventos de mouse, como
position
InputEventMouseButton - contiene el índice del botón que fue presionado, si fue un doble clic, etc.
Truco
Es una buena idea mantener la referencia de la clase abierta mientras trabajas con los eventos para que puedas comprobar las propiedades y métodos disponibles del tipo de evento.
Puedes encontrar errores si intentas acceder a una propiedad en un tipo de entrada que no la contiene - llamando position
en InputEventKey
por ejemplo. Para evitar esto, asegúrate de probar primero el tipo de evento:
func _input(event):
if event is InputEventMouseButton:
print("mouse button event at ", event.position)
public override void _Input(InputEvent inputEvent)
{
if (inputEvent is InputEventMouseButton mouseEvent)
{
GD.Print("mouse button event at ", mouseEvent.Position);
}
}
InputMap¶
El InputMap es la forma más flexible de manejar una variedad de entradas. Se utiliza creando acciones de entrada con nombre, a las que se puede asignar cualquier número de eventos de entrada, como pulsaciones de teclas o clics de ratón. Un nuevo proyecto Godot incluye un número de acciones predeterminadas ya definidas. Para verlas, y para añadir las tuyas propias, abre Proyecto -> Configuración del proyecto y selecciona la pestaña InputMap:

Capturando acciones¶
Una vez que hayas definido tus acciones, puedes procesarlas en tus scripts usando is_action_pressed()
y is_action_released()
pasando el nombre de la acción que estás buscando:
func _input(event):
if event.is_action_pressed("my_action"):
print("my_action occurred!")
public override void _Input(InputEvent inputEvent)
{
if (inputEvent.IsActionPressed("my_action"))
{
GD.Print("my_action occurred!");
}
}
Eventos de teclado¶
Los eventos de teclado son capturados en InputEventKey. Aunque se recomienda usar acciones de entrada en su lugar, puede haber casos en los que quieras mirar específicamente los eventos de teclado. Para este ejemplo, busquemos el T:
func _input(event):
if event is InputEventKey and event.pressed:
if event.scancode == KEY_T:
print("T was pressed")
public override void _Input(InputEvent inputEvent)
{
if (inputEvent is InputEventKey keyEvent && keyEvent.Pressed)
{
if ((KeyList)keyEvent.Keycode == KeyList.T)
{
GD.Print("T was pressed");
}
}
}
Truco
Ver @GlobalScope_KeyList para una lista de constantes del código de escaneado.
Advertencia
Due to keyboard ghosting, not all key inputs may be registered at a given time if you press too many keys at once. Due to their location on the keyboard, certain keys are more prone to ghosting than others. Some keyboards feature antighosting at a hardware level, but this feature is generally not present on low-end keyboards and laptop keyboards.
As a result, it's recommended to use a default keyboard layout that is designed to work well on a keyboard without antighosting. See this Gamedev Stack Exchange question for more information.
Modificadores de teclado¶
Modifier properties are inherited from InputEventWithModifiers. This allows you to check for modifier combinations using boolean properties. Let's imagine you want one thing to happen when the T is pressed, but something different when it's 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")
public override void _Input(InputEvent inputEvent)
{
if (inputEvent is InputEventKey keyEvent && keyEvent.Pressed)
{
switch ((KeyList)keyEvent.Scancode)
{
case KeyList.T:
GD.Print(keyEvent.Shift ? "Shift+T was pressed" : "T was pressed");
break;
}
}
}
Truco
Ver @GlobalScope_KeyList para una lista de constantes del código de escaneado.
Eventos del ratón¶
Los eventos del ratón se derivan de la clase InputEventMouse, y se separan en dos tipos: InputEventMouseButton y InputEventMouseMotion. Ten en cuenta que esto significa que todos los eventos del ratón contendrán una propiedad de position
.
Movimiento del mouse¶
InputEventMouseMotion los eventos ocurren cada vez que el ratón se mueve. Puedes encontrar la distancia del movimiento con la propiedad relative
.
Aquí hay un ejemplo usando eventos de ratón para arrastrar y soltar un nodo 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
using Godot;
using System;
public class Node2D : Godot.Node2D
{
private bool dragging = false;
private int clickRadius = 32; // Size of the sprite.
public override void _Input(InputEvent inputEvent)
{
Sprite sprite = GetNodeOrNull<Sprite>("Sprite");
if (sprite == null)
{
return; // No suitable node was found.
}
if (inputEvent is InputEventMouseButton mouseEvent && (ButtonList)mouseEvent.ButtonIndex == ButtonList.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 (inputEvent is InputEventMouseMotion motionEvent && dragging)
{
// While dragging, move the sprite with the mouse.
sprite.Position = motionEvent.Position;
}
}
}
}
Eventos de toque¶
Si usas un dispositivo de pantalla táctil, puedes generar eventos táctiles. InputEventScreenTouch equivale a un evento de clic de ratón, y InputEventScreenDrag funciona de manera muy similar al movimiento del ratón.
Truco
Para probar los eventos táctiles en un dispositivo sin pantalla táctil, abra Configuración del proyecto y vaya a la sección "Dispositivos de entrada/punto". Habilita "Emular el toque del ratón" y tu proyecto interpretará los clics y el movimiento del ratón como eventos táctiles.