Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Gestire l'input

Aggiungere al game engine un oggetto che si occupi di gestire l'input dell'utente, vediamo ad esempio come gestire gli eventi da mouse e tastiera.
Aggiungere al game engine un oggetto che si occupi di gestire l'input dell'utente, vediamo ad esempio come gestire gli eventi da mouse e tastiera.
Link copiato negli appunti

Proseguiamo con la creazione del game engine che abbiamo iniziato nelle lezioni precedenti, lavorando ad un oggetto che si occupi di gestire l'input dell'utente.

Creiamo quindi un nuovo file JavaScript "inputs.js" e definiamo delle costanti che ci serviranno successivamente

/* inputs.js
 */
// costanti per gli input
TOUCH_1 = 1;
MOUSE_LEFT   = 1;
MOUSE_MIDDLE = 2;
MOUSE_RIGHT  = 3;
KEY_LEFT  = 37;
KEY_RIGHT = 39;
KEY_UP    = 38;
KEY_DOWN  = 40;
KEY_ENTER = 13;
KEY_ESC   = 27;
KEY_CTRL  = 17;
KEY_SPACE = 32;

Poiché le API JavaScript per gli eventi da tastiera associano a ciascun tasto un keycode numerico, grazie a queste "costanti" possiamo evitare di ricordare il numero corrispondente ad ogni tasto. (In realtà si tratta di variabili: le costanti infatti non sono ancora supportate da tutti i browser).

Per aggiungere altre "costanti" possiamo consultare una lista completa dei keyCode che troviamo qui.

Definiamo quindi il nostro oggetto Inputs e inizializziamo alcune variabili/proprietà:

/* oggetto che gestisce gli input */
Inputs = function() {}
Inputs.mouseX = 0;
Inputs.mouseY = 0;
Inputs.mouseLeft = false;
Inputs.mouseLeftPress = false;
Inputs.mouseLeftRel = false;
Inputs.mouseRight = false;
Inputs.mouseRightPress = false;
Inputs.mouseRightRel = false;
Inputs.key = [];
Inputs.keyPress = [];
Inputs.keyRel= [];

Proprietà Descrizione
mouseX
mouseY
indicano la posizione del puntatore, o dell'ultimo touch, relativamente al game Canvas.
mouseLeft
mouseRight
indicano se il tasto sinistro/destro sono in pressione (l'utente ha premuto il tasto e non l'ha ancora rilasciato).
mouseLeftPress
mouseRightPress
indicano se in questo momento si è premuto il tasto sinistro o destro.
mouseLeftRel
mouseRightRel
invece si riferiscono al rilascio del tasto/touch.

Per la tastiera, definiamo invece 3 array vuoti (key, keyPress, keyRel) , che indicano rispettivamente i tasti in-pressione, premuti e rilasciati.

Gli event listener

Per rilevare l'input dell'utente, utilizzeremo il classico element.addEventListener per associare le funzioni da noi definite a ciascun evento, come la pressione o il rilascio di un tasto.

Quindi aggiungiamo al file inputs.js il seguente codice:

window.addEventListener("keydown", function(e) {
	if(!Inputs.key[e.keyCode]) {
		Inputs.keyPress[e.keyCode] = true;
		Inputs.key[e.keyCode] = true;
	}
}, false);
window.addEventListener("keyup", function(e) {
	Inputs.keyRel[e.keyCode] = true;
	Inputs.key[e.keyCode] = false;
}, false);

Abbiamo agganciato così due event listener all'oggetto window, che si occuperanno di intercettare gli eventi della tastiera e inserire i relativi codici nei nostri array.

L'evento keydown, cui abbiamo associato la prima funzione, viene scatenato quando l'utente preme un tasto della tastiera e viene ripetuto ogni tot millisecondi, finché il tasto rimane premuto. Perciò evitiamo di inserire il valore nell'array keyPress se il keyCode è già nell'array key: il tasto è già stato premuto ed è in pressione e non c'è bisogno di inserirlo nuovamente in keyPress.

L' evento keyup, cui abbiamo associato la seconda callback, viene scatenato quando il tasto viene rilasciato, perciò in questo caso aggiorniamo gli array keyRel e key, anche qui usando come indice il keyCode.

Facciamo qualcosa di simile anche per gli eventi del Mouse e Touch

window.addEventListener("mousedown", function(e) {
	switch (e.which) {
		case 1:
			Inputs.mouseLeft = true;
			Inputs.mouseLeftPress = true;
		break;
		case 2:
			Inputs.mouseMiddle = true;
			Inputs.mouseMiddlePress = true;
		break;
		case 3:
			Inputs.mouseRight = true;
			Inputs.mouseRightPress = true;
		break;
	}
}, false);
window.addEventListener("mouseup", function(e) {
	switch (e.which) {
		case 1:
			Inputs.mouseLeft = false;
			Inputs.mouseLeftRel = true;
		break;
		case 2:
			Inputs.mouseMiddle = false;
			Inputs.mouseMiddleRel = true;
		break;
		case 3:
			Inputs.mouseRight = false;
			Inputs.mouseRightRel = true;
		break;
	}
}, false);

Gli eventi per i tasti del mouse ritornano un numero da 1 a 3, che indica quale sia il tasto premuto/rilasciato (1=sinistro, 2=centrale [o rotellina], 3=destro).

Aggiorniamo quindi le variabili per la posizione:

window.addEventListener("mousemove", function(e) {
	Inputs.mouseX = Math.round(e.pageX - game.canvas.offsetLeft );
	Inputs.mouseY = Math.round(e.pageY - game.canvas.offsetTop );
	Inputs.mouseMoved = true;
}, false);

Tramite l'evento mousemove, aggiorniamo le variabili mouseX e mouseY relativamente al canvas (l'evento ritorna la posizione del mouse rispetto all'intera finestra del browser, quindi sottraiamo la posizione del canvas, così da ottenere coordinate relative).

Infine impostiamo a true la variabile mouseMoved, che potrebbe tornare utile per controllare se il mouse è stato spostato.

Adesso aggiungiamo dei listener per gli eventi touch:

window.addEventListener("touchmove", function(s) {
	Inputs.mouseX = Math.round(s.pageX - game.ctx.canvas.offsetLeft );
	Inputs.mouseY = Math.round(s.pageY - game.ctx.canvas.offsetTop );
}, false);
window.addEventListener("touchstart", function(e) {
	Inputs.mouseLeft = true;
	Inputs.mouseLeftPress = true;
}, false);
window.addEventListener("touchend", function() {
	Inputs.mouseLeft = false;
	Inputs.mouseLeftRel = true;
}, false);

Utilizzeremo mouseLeft per indicare il touch, così da poter utilizzare lo stesso codice anche per i dispositivi touchscreen.

Volendo si possono aggiungere multitouch, doubletap, gestures e altre utilità relative ai dispositivi touchscreen. Se volete espandere questo aspetto, potete trovare molte librerie da utilizzare o semplicemente prendere spunto per espandere inputs.js.

Ora definiamo la funzione Clear, che si occuperà di resettare la pressione/rilascio dei tasti.

Inputs.Clear = function() {
	Inputs.mouseLeftPress = false;
	Inputs.mouseLeftRel   = false;
	Inputs.mouseMiddlePress = false;
	Inputs.mouseMiddleRel   = false;
	Inputs.mouseRightPress = false;
	Inputs.mouseRightRel   = false;
	Inputs.mouseMoved = false;
	Inputs.keyPress = [];
	Inputs.keyRel   = [];
}

Qui non facciamo altro che impostare tutte le variabili del mouse a false e svuotare gli array della tastiera.

Dovremo chiamare questa funzione per ogni frame al termine del gameloop, dopo aver eseguito tutti gli eventi degli altri oggetti. Come si vede non cancelliamo, e non dobbiamo farlo, le variabili e gli array relativi agli input "in pressione" (mouseLeft, mouseMiddle, mouseRight, key), ma solo quelli del press/release che durano solo il tempo di un frame.

/* main.js
 */
function Game() {
	//...
	this.GameLoop = function() {
		//...
		Inputs.Clear();
	}
}

Dopo aver descritto le funzionalità interne, passiamo a definire le funzioni che utilizzeremo durante la programmazione del nostro gioco.

Inputs.GetKeyDown = function(k) {
	if(typeof(k) == "string") {
		k = k.charCodeAt(0);
	}
	return (Inputs.key[k] == true);
}
Inputs.GetKeyPress = function(k) {
	if(typeof(k) == "string") {
		k = k.charCodeAt(0);
	}
	return (Inputs.keyPress[k] == true);
}
Inputs.GetKeyRelease = function(k) {
	if(typeof(k) == "string") {
		k = k.charCodeAt(0);
	}
	return (Inputs.keyRel[k] == true);
}

Queste tre funzioni, prendono come parametro un valore che può essere un numero intero (keyCode) o una stringa (ad esempio Inputs.GetKeyDown("R") convertirà la stringa 'R' nel keyCode corrispondente 82) e verificano se l'elemento dell'array, avente come indice il keyCode, esiste ed è true.

Creiamo delle funzioni simili per gestire Down/Press/Release anche per i tre tasti del mouse

Inputs.GetMouseDown = function(b) {
	if(b == 1) return Inputs.mouseLeft;
	if(b == 2) return Inputs.mouseMiddle;
	if(b == 3) return Inputs.mouseRight;
}
Inputs.GetMousePress = function(b) {
	if(b == 1) return Inputs.mouseLeftPress;
	if(b == 2) return Inputs.mouseMiddlePress;
	if(b == 3) return Inputs.mouseRightPress;
}
Inputs.GetMouseRelease = function(b) {
	if(b == 1) return Inputs.mouseLeftRel;
	if(b == 2) return Inputs.mouseMiddleRel;
	if(b == 3) return Inputs.mouseRightRel;
}

Infine aggiungiamo due funzioni per controllare se il mouse sia all'interno di un rettangolo o un cerchio

Inputs.MouseInsideRect = function(x,y,w,h) {
	return (Inputs.mouseX >= x && Inputs.mouseY &gt;= y && Inputs.mouseX <= x+w && Inputs.mouseY <= y+h);
}
Inputs.MouseInsideCircle = function(x,y,r) {
	var dx = Inputs.mouseX - x;
	var dy = Inputs.mouseY - y;
	return dx*dx+dy*dy <= r*r;
}

In allegato il codice completo di inputs.js.

Ti consigliamo anche