This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Tutti gli input dell’utente vengono acquisiti dal motore e inviati sotto forma di azioni ai componenti script e script GUI negli oggetti di gioco (game object) che hanno acquisito il focus dell’input e che implementano la funzione on_input(). Questo manuale spiega come configurare i binding per acquisire l’input e come creare codice che vi risponda.
Il sistema di input si basa su un insieme di concetti semplici e potenti, che ti consentono di gestire l’input nel modo più adatto al tuo gioco.

I binding di input sono una tabella valida per l’intero progetto che consente di specificare come convertire l’input dei dispositivi in azioni con un nome prima di inviarle ai componenti script e agli script GUI. Per creare un nuovo file di binding di input, fai clic con il pulsante destro in una posizione della vista Assets e seleziona New... ▸ Input Binding. Per fare in modo che il motore utilizzi il nuovo file, modifica la voce Game Binding in game.project.

Tutti i modelli di nuovo progetto creano automaticamente un file di binding di input predefinito, quindi in genere non è necessario crearne uno nuovo. Il file predefinito si chiama game.input_binding e si trova nella cartella input nella radice del progetto. Fai doppio clic sul file per aprirlo nell’editor:

Per creare un nuovo binding, fai clic sul pulsante + in fondo alla sezione del tipo di trigger pertinente. Ogni voce ha due campi:
A del gamepad all’azione jump. Tieni presente che, a causa di un bug noto, gli input tattili purtroppo non possono avere gli stessi nomi di azione degli altri input.Puoi creare cinque tipi di trigger specifici per i dispositivi:
Oltre ai cinque tipi di trigger elencati sopra, Defold supporta anche l’input dall’accelerometro nelle applicazioni native Android e iOS. Seleziona la casella Use Accelerometer nella sezione Input del file game.project.
function on_input(self, action_id, action)
if action.acc_x and action.acc_y and action.acc_z then
-- react to accelerometer data
end
end
Per ricevere le azioni di input in un componente script o in uno script GUI, invia il messaggio acquire_input_focus all’oggetto di gioco che contiene il componente:
-- tell the current game object (".") to acquire input focus
msg.post(".", "acquire_input_focus")
Questo messaggio indica al motore di aggiungere allo stack di input i componenti degli oggetti di gioco in grado di gestire l’input (componenti script, componenti GUI e proxy di collezione). I componenti degli oggetti di gioco vengono inseriti in cima allo stack di input; l’ultimo componente aggiunto si troverà in cima allo stack. Tieni presente che, se l’oggetto di gioco contiene più di un componente in grado di gestire l’input, tutti questi componenti verranno aggiunti allo stack:

Se un oggetto di gioco che ha già acquisito il focus dell’input lo acquisisce di nuovo, i suoi componenti vengono spostati in cima allo stack.
Le azioni di input vengono distribuite seguendo lo stack di input, dall’alto verso il basso.

Per ogni componente nello stack che contiene una funzione on_input(), questa funzione viene chiamata una volta per ciascuna azione di input durante il fotogramma, con i seguenti argomenti:
selfaction_idnil per il movimento del puntatore e i campioni dell’accelerometro. Usa action.source per distinguere queste azioni senza nome.actionpressed e così via. Consulta on_input() per i dettagli sui campi disponibili dell’azione.function on_input(self, action_id, action)
if action_id == hash("left") and action.pressed then
-- move left
local pos = go.get_position()
pos.x = pos.x - 100
go.set_position(pos)
elseif action_id == hash("right") and action.pressed then
-- move right
local pos = go.get_position()
pos.x = pos.x + 100
go.set_position(pos)
end
end
action.source identifica la categoria del dispositivo di input indipendentemente dal nome dell’azione. È disponibile nei callback on_input() sia degli script sia degli script GUI ed è uno dei seguenti hash:
action.source |
Categoria di input |
|---|---|
hash("keyboard") |
Input dei singoli tasti dai Key Trigger. |
hash("text") |
Input di testo e testo contrassegnato dai Text Trigger, compreso il testo immesso con una tastiera fisica. |
hash("mouse") |
Pulsanti del mouse fisico, input della rotellina e movimento del puntatore. |
hash("touch") |
Input tattile, compresi clic del mouse e movimento del puntatore simulati dal tocco. |
hash("gamepad") |
Input del gamepad, compresi input grezzo ed eventi di connessione. |
hash("accelerometer") |
Campioni dell’accelerometro. |
Confronta action.source con un hash, come hash("touch"), anziché con una stringa. Per esempio, un’azione del pulsante sinistro del mouse può provenire da un mouse fisico o da un tocco. L’origine li distingue anche alla pressione iniziale; consulta Distinguere i clic del mouse dai tocchi.
Quando più dispositivi condividono un’azione denominata, i loro contributi possono essere combinati. Le origini vengono elaborate in questo ordine: tastiera, testo, mouse, poi tocco; viene riportata l’ultima origine che contribuisce all’azione. I rilasci dei tasti e dei pulsanti del mouse mantengono l’origine precedente, a meno che un altro input non contribuisca nello stesso frame. Le azioni dei gamepad rimangono separate per controller. Usa nomi di azione separati quando devi gestire ogni associazione indipendentemente.
Il movimento del puntatore e i campioni dell’accelerometro non hanno un nome di azione, quindi entrambi usano action_id == nil. Arrivano in callback separati: il movimento del puntatore ha coordinate e un’origine mouse o tocco, mentre i campioni dell’accelerometro hanno acc_x, acc_y e acc_z e un’origine accelerometro. Se entrambi si verificano in un frame, ogni callback può essere consumato indipendentemente. I campioni dell’accelerometro vengono consegnati anche se i valori non sono cambiati.
L’esempio seguente gestisce queste azioni senza nome. Configura almeno un Mouse Trigger per ricevere il movimento del puntatore e abilita Use Accelerometer su un dispositivo supportato per ricevere i campioni dell’accelerometro:
function init(self)
msg.post(".", "acquire_input_focus")
end
function on_input(self, action_id, action)
if action_id == nil then
if action.source == hash("mouse") or action.source == hash("touch") then
print("Pointer position:", action.x, action.y)
elseif action.source == hash("accelerometer") then
print("Acceleration:", action.acc_x, action.acc_y, action.acc_z)
end
end
end
Ogni mondo di gioco caricato dinamicamente attraverso un proxy di collezione ha il proprio stack di input. Affinché la distribuzione delle azioni raggiunga lo stack di input del mondo caricato, il componente proxy deve trovarsi nello stack di input del mondo principale. Tutti i componenti nello stack di un mondo caricato vengono gestiti prima che la distribuzione prosegua verso il basso nello stack principale:

Un errore comune è dimenticare di inviare acquire_input_focus all’oggetto di gioco che contiene il componente proxy di collezione. Saltare questo passaggio impedisce all’input di raggiungere qualsiasi componente nello stack di input del mondo caricato.
Per smettere di ricevere le azioni di input, invia un messaggio release_input_focus all’oggetto di gioco. Questo messaggio rimuove dallo stack di input tutti i componenti dell’oggetto di gioco:
-- tell the current game object (".") to release input focus.
msg.post(".", "release_input_focus")
La funzione on_input() di un componente può controllare attivamente se le azioni debbano essere trasmesse ai componenti più in basso nello stack:
on_input() restituisce false, oppure non restituisce esplicitamente un valore (il che equivale a restituire nil, un valore considerato falso in Lua), le azioni di input vengono trasmesse al componente successivo nello stack di input.on_input() restituisce true, l’input viene consumato. Nessun componente più in basso nello stack di input riceverà l’input. Tieni presente che questo vale per tutti gli stack di input. Un componente nello stack di un mondo caricato tramite proxy può consumare l’input, impedendo ai componenti nello stack principale di riceverlo:
In molti casi, il consumo dell’input offre un modo semplice e potente per passare la gestione dell’input da una parte del gioco a un’altra. Ad esempio, se hai bisogno di un menu a comparsa che sia temporaneamente l’unica parte del gioco in ascolto dell’input:

Il menu di pausa è inizialmente nascosto (disabilitato) e viene abilitato quando il giocatore tocca l’elemento PAUSE dell’HUD:
function on_input(self, action_id, action)
if action_id == hash("mouse_press") and action.pressed then
-- Did the player press PAUSE?
local pausenode = gui.get_node("pause")
if gui.pick_node(pausenode, action.x, action.y) then
-- Tell the pause menu to take over.
msg.post("pause_menu", "show")
end
end
end

La GUI del menu di pausa acquisisce il focus dell’input e consuma l’input, impedendo la gestione di qualsiasi input che non sia pertinente al menu a comparsa:
function on_message(self, message_id, message, sender)
if message_id == hash("show") then
-- Show the pause menu.
local node = gui.get_node("pause_menu")
gui.set_enabled(node, true)
-- Acquire input.
msg.post(".", "acquire_input_focus")
end
end
function on_input(self, action_id, action)
if action_id == hash("mouse_press") and action.pressed then
-- do things...
local resumenode = gui.get_node("resume")
if gui.pick_node(resumenode, action.x, action.y) then
-- Hide the pause menu
local node = gui.get_node("pause_menu")
gui.set_enabled(node, false)
-- Release input.
msg.post(".", "release_input_focus")
end
end
-- Consume all input. Anything below us on the input stack
-- will never see input until we release input focus.
return true
end