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.
Checking the stable version of the documentation...
Esempi di Input
Introduzione
In questo tutorial, imparerai come utilizzare il sistema InputEvent di Godot per acquisire l'input del giocatore. Esistono molti tipi diversi di input che il tuo gioco può utilizzare (tastiera, gamepad, mouse, ecc.) e molti modi diversi per convertire questi input in azioni nel tuo gioco. Questo documento mostrerà alcuni degli scenari più comuni, che puoi utilizzare come punti di partenza per i tuoi progetti.
Nota
Per una panoramica dettagliata di come funziona il sistema di eventi di input in Godot, consulta Utilizzo di InputEvent.
Events versus polling
A volte si desidera che il gioco risponda a un determinato evento di input, ad esempio premendo il pulsante "salta". In altre situazioni, si potrebbe volere che qualcosa accada finché un tasto viene premuto, come ad esempio il movimento. Nel primo caso, è possibile utilizzare la funzione _input(), che verrà chiamata ogni volta che si verifica un evento di input. Nel secondo caso, Godot fornisce il singleton Input, che è possibile utilizzare per interrogare lo stato di un input.
Esempi:
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;
}
}
This gives you the flexibility to mix-and-match the type of input processing you do.
Per il resto di questo tutorial, ci concentreremo sulla cattura dei singoli eventi in _input().
Eventi di input
Gli eventi di input sono oggetti che ereditano da InputEvent. A seconda del tipo di evento, l'oggetto conterrà proprietà specifiche relative a tale evento. Per vedere come sono effettivamente gli eventi, aggiungi un nodo e allega il seguente 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());
}
}
Mentre premi i tasti, muovi il mouse ed effettui altri input, vedrai ogni evento scorrere nella finestra di output. Ecco un esempio dell'output:
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))
Come puoi vedere, i risultati sono molto diversi a seconda del tipo di input. Gli eventi dai tasti sono persino stampati con i relativi simboli. Ad esempio, consideriamo InputEventMouseButton. Eredita dalle seguenti classi:
InputEvent - la classe base per tutti gli eventi di input
InputEventWithModifiers - aggiunge l'abilità di verificare se sono premuti i modificatori, come Shift o Alt.
InputEventMouse - aggiunge proprietà di eventi del mouse, come
positionInputEventMouseButton - contiene l'indice del pulsante del mouse che è stato premuto, se è un doppio clic, ecc.
Suggerimento
È consigliabile tenere aperto il riferimento classi mentre si lavora con gli eventi, in modo da poter consultare le proprietà e i metodi disponibili per il tipo di evento.
Potrebbero verificarsi errori se si tenta di accedere a una proprietà su un tipo di input che non la contiene, ad esempio chiamando position su InputEventKey. Per evitare ciò, assicurarsi di testare prima il tipo di 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
L'InputMap è il modo più flessibile per gestire una varietà di input. Si utilizza creando azioni denominate di input, alle quali è possibile assegnare un numero qualsiasi di eventi di input, come la pressione di tasti o i clic del mouse. Per visualizzarle e aggiungerne di proprie, apri Progetto -> Impostazioni del progetto e seleziona la scheda Mappa di input:
Suggerimento
Un nuovo progetto Godot include una serie di azioni predefinite già definite. Per visualizzarle, attiva l'opzione nella finestra Mappa di input.
Sebbene non sia strettamente necessario, si consiglia di usare la convenzione di denominazione snake_case per i nomi delle azioni di input.
Catturare le azioni
Una volta definite le azioni, è possibile elaborarle negli script tramite le funzioni is_action_pressed() e is_action_released(), passando il nome dell'azione che si sta cercando:
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!");
}
}
Eventi da tastiera
Gli eventi da tastiera sono catturati in InputEventKey. Sebbene sia consigliabile utilizzare le azioni di input, potrebbero esserci casi in cui si desidera esaminare specificamente gli eventi da tasti. Per questo esempio, verifichiamo il tasto 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");
}
}
}
Suggerimento
Consulta @GlobalScope_Key per un elenco delle costanti di codici di tasti.
Avvertimento
A causa di ghosting per le tastiere, non tutti gli input dai tasti potrebbero registrarsi se si premono troppi tasti nello stesso momento. A causa della loro posizione sulla tastiera, alcuni tasti sono più soggetti al ghosting rispetto ad altri. Alcune tastiere dispongono di una funzionalità anti-ghosting a livello hardware, ma questa è generalmente assente nelle tastiere di fascia bassa e in quelle dei laptop.
Di conseguenza, si consiglia di utilizzare un layout di tastiera predefinito progettato per funzionare correttamente su una tastiera senza anti-ghosting. Consultare questa domanda su Gamedev Stack Exchange per ulteriori informazioni.
Modificatori di tastiera
Le proprietà dei modificatori sono ereditate da InputEventWithModifiers. Questo permette di verificare le combinazioni di modificatori attraverso proprietà booleane. Immaginiamo di volere che accada una cosa quando si preme T, ma qualcosa di diverso quando si preme 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;
}
}
}
Suggerimento
Consulta @GlobalScope_Key per un elenco delle costanti di codici di tasti.
Eventi del mouse
Gli eventi dal mouse derivano dalla classe InputEventMouse e sono suddivisi in due tipi: InputEventMouseButton e InputEventMouseMotion. Si noti che ciò significa che tutti gli eventi del mouse conterranno una proprietà position.
Movimento del mouse
Gli eventi InputEventMouseMotion avvengono ogni volta che il mouse si muove. È possibile trovare la distanza del movimento con la proprietà relative.
Ecco un esempio che utilizza gli eventi dal mouse per trascinare e rilasciare un nodo 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
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;
}
}
}
}
Eventi di tocco
Se si utilizza un dispositivo touchscreen, è possibile generare eventi di tocco. InputEventScreenTouch è equivalente a un evento di clic del mouse, e InputEventScreenDrag funziona in modo molto simile a un evento del movimento del mouse.
Suggerimento
Per testare gli eventi di tocco su un dispositivo non touchscreen, aprire le Impostazioni del progetto e andare alla sezione "Dispositivi d'input/Puntamento". Abilita "Emula tocco con il mouse" e il progetto interpreterà i clic e i movimenti del mouse come eventi di tocco.