Movimento della tastiera fluido e facile in AS3 con la classe di input

Ci sono molti giochi là fuori con movimenti a scatti e irrealistici e che possono fare solo una cosa per il tuo prodotto: renderlo poco attraente per il pubblico. Ma non è difficile ottenere un movimento fluido - mettiamoci al lavoro!


Anteprima del risultato finale

Diamo un'occhiata al risultato finale su cui lavoreremo:


Passaggio 1: impostare l'ambiente

Questo è un tutorial semplice, quindi l'impostazione sarà anche semplice.

Creare un nuovo progetto Flash ActionScript 3.0. Le dimensioni e il colore dello stage non contano, basta usare ciò con cui ti senti a tuo agio.

Io uso FlashDevelop per la codifica, ma anche questo potrebbe essere fatto in qualsiasi editor AS, come Flash Pro (o qualsiasi editor di testo, magari Notepad;)). Quindi, crea un file di classe, assicurati che il tuo codice sia simile al mio; vedi sotto. Ho chiamato il mio "Movimento". (Se utilizzi Flash Pro, consulta questa guida per creare una classe.)

 pacchetto import flash.display.Sprite; Movimento di classe pubblica estende Sprite public function Movement (): void 

Al termine, assicurati che la tua Classe sia collegata al progetto Flash come Main Class.


Passaggio 2: crea il quadrato e le variabili

Quindi, dopo aver collegato la classe di movimento al tuo documento, definisci le variabili come ho fatto di seguito

 pacchetto import flash.display.Sprite; import flash.events.Event; Movimento di classe pubblica estende Sprite // L'oggetto che si sposterà in privato var square: Sprite; // La velocità massima private var _max: Number = 10; // Le variabili che verranno applicate per spostare il quadrato privato var dx: Number = 0; private var dy: Number = 0; public function Movement (): void // Listen per aggiunto all'evento stage addEventListener (Event.ADDED_TO_STAGE, init);  funzione privata init (e: Event): void removeEventListener (Event.ADDED_TO_STAGE, init); // Creare un nuovo Sprite e disegnare all'interno di un quadrato quadrato = new Sprite (); square.graphics.beginFill (0x333333); square.graphics.drawRect (0, 0, 30, 30); square.x = stage.stageWidth / 2 - square.width / 2; square.y = stage.stageHeight / 2 - square.height / 2; addChild (quadrato); 

Questo è praticamente tutto ciò che faremo per creare l'oggetto. Puoi usare il tuo oggetto ma per questo semplice tutorial sul movimento ho usato questo semplice quadrato.


Passaggio 3: Introduzione alla classe Input.as

Ciao ragazzi, questa è la classe Input.as; Input.as Class questi sono i ragazzi di cui ti ho parlato - sii gentile con loro! :)

Allora, di cosa parla questa classe, potresti chiederti. Fondamentalmente fa il tuo lavoro di gestione delle chiavi per te. Aggiunge un ascoltatore agli eventi ENTER_FRAME - con priorità bassa - e un listener di chiavi che riempie alcuni dizionari privati. Inoltre usa un'altra classe per i codici chiave. Puoi dare un'occhiata dentro e vedere di persona come funziona.

Nota: la classe Input.as non mi appartiene. È stato creato da Matthew Bush, che ha portato Box2D in Flash.

 // Esempio di Input.as Uso della classe // Devi sempre inizializzarlo come questo con il parametro stage Input.initialize (stage); // Dopo l'inizializzazione, puoi usare i metodi kd (), kp () o ku (), che // restituiscono un valore booleano se le condizioni sono soddisfatte. // Questi metodi accettano più argomenti, // quindi per un evento è possibile utilizzare più chiavi. // Questo rende molto più facile dare una spinta di accessibilità alla tua app. //e.g Vedi sotto mentre uso una chiamata per rilevare la freccia UP o W per salire. Input.kd ("UP", "W");

Passaggio 4: importazione delle classi

Quindi, ora che conosci la classe Input.as, la importeremo nella nostra classe di movimento e inizializzeremo.

 pacchetto import flash.display.Sprite; import flash.events.Event; input di importazione; Movimento di classe pubblica estende Sprite // L'oggetto che si sposterà in privato var square: Sprite; // La velocità massima private var _max: Number = 10; // Le variabili che verranno applicate per spostare il quadrato privato var dx: Number = 0; private var dy: Number = 0; public function Movement (): void // Listen per aggiunto all'evento stage addEventListener (Event.ADDED_TO_STAGE, init);  funzione privata init (e: Event): void removeEventListener (Event.ADDED_TO_STAGE, init); // Creare un nuovo Sprite e disegnare all'interno di un quadrato quadrato = new Sprite (); square.graphics.beginFill (0x333333); square.graphics.drawRect (0, 0, 30, 30); square.x = stage.stageWidth / 2 - square.width / 2; square.y = stage.stageHeight / 2 - square.height / 2; addChild (quadrato); // Inizializza la classe Input.as con il gestore sullo stage Input.initialize (stage); // Aggiungi il ciclo di aggiornamento addEventListener (Event.ENTER_FRAME, refresh);  aggiornamento funzione privata (e: Event): void 

Passaggio 5: Gestione degli ingressi chiave

Io uso un loop basato su ENTER_FRAME per rilevare gli input chiave; di seguito è il ricaricare() metodo che è la funzione di gestore per questo evento.

 refresh della funzione privata (e: Event): void // Key Handler if (Input.kd ("A", "LEFT")) // Sposta a sinistra if (Input.kd ("D", "RIGHT ")) // Sposta a destra if (! Input.kd (" A "," LEFT "," D "," RIGHT ")) // Se non viene premuto left / right if (Input .kd ("W", "UP")) // Move up if (Input.kd ("S", "DOWN")) // Move down if (! Input.kd ("W", "SU", "S", "GIÙ")) // Se non ci sono azioni su / giù

Passaggio 6: spiegazione dei calcoli: gestione della velocità

Questo è piuttosto semplice. Rileva se uno qualsiasi dei tasti è premuto, quindi agisci di conseguenza.

Io uso molto l'operatore ternario: valore = condizione? vero falso;
Questa è fondamentalmente un'istruzione if che è stata condensata su una singola riga.

Per ogni rilevamento di chiavi, utilizzo questo metodo: se il valore è maggiore di _max quindi impostalo uguale a _max; altrimenti, incrementare o decrementare quel particolare valore come appropriato. In questo modo, è mantenuto entro certi limiti. Semplice, giusto?

Di seguito puoi studiare le condizioni:

 refresh della funzione privata (e: Event): void // Key Handler if (Input.kd ("A", "LEFT")) // Sposta a sinistra dx = dx < 0.5 - _max ? _max * -1 : dx - 0.5;  if (Input.kd("D", "RIGHT"))  //Move to the right dx = dx > _max - 0.5? _max: dx + 0.5;  if (! Input.kd ("A", "LEFT", "D", "RIGHT")) // Se non viene premuto left / right if (dx> 0.5) dx = dx < 0.5 ? 0 : dx - 0.5;  else  dx = dx > -0,5? 0: dx + 0,5;  if (Input.kd ("W", "UP")) // Sposta su dy = dy < 0.5 - _max ? _max * -1 : dy - 0.5;  if (Input.kd("S", "DOWN"))  //Move down dy = dy > _max - 0.5? _max: dy + 0.5;  if (! Input.kd ("W", "UP", "S", "DOWN")) // Se non c'è azione su / giù se (dy> 0.5) dy = dy < 0.5 ? 0 : dy - 0.5;  else  dy = dy > -0,5? 0: dy + 0,5;  // Dopo tutto ciò, applicate questi all'oggetto square.x + = dx; square.y + = dy; 

Se non conosci l'operatore ternario, prendi un pezzo di carta e una penna e scrivi alcuni di essi nel formato if ... else; è un ottimo esercizio per fare i conti con quello che sta succedendo.

Tieni presente che manipolo il dx e dy variabili, e solo impostare i valori attuali x e y alla fine. Questo ci aiuta a rendere fluido il movimento; non è un sussulto, poiché alteriamo i loro valori direttamente attraverso la funzione ...

Vai avanti, provalo! Guarda come si sta muovendo?


Passaggio 7: Gestione delle collisioni al contorno

Va bene. Tutto è giusto, muovendosi fluidamente - ma fuori dal palco! Di seguito ho aggiunto le condizioni di rilevamento delle collisioni.

 refresh della funzione privata (e: Event): void // Key Handler if (Input.kd ("A", "LEFT")) // Sposta a sinistra dx = dx < 0.5 - _max ? _max * -1 : dx - 0.5;  if (Input.kd("D", "RIGHT"))  //Move to the right dx = dx > _max - 0.5? _max: dx + 0.5;  if (! Input.kd ("A", "LEFT", "D", "RIGHT")) // Se non viene premuto left / right if (dx> 0.5) dx = dx < 0.5 ? 0 : dx - 0.5;  else  dx = dx > -0,5? 0: dx + 0,5;  if (Input.kd ("W", "UP")) // Sposta su dy = dy < 0.5 - _max ? _max * -1 : dy - 0.5;  if (Input.kd("S", "DOWN"))  //Move down dy = dy > _max - 0.5? _max: dy + 0.5;  if (! Input.kd ("W", "UP", "S", "DOWN")) // Se non c'è azione su / giù se (dy> 0.5) dy = dy < 0.5 ? 0 : dy - 0.5;  else  dy = dy > -0,5? 0: dy + 0,5;  // Rilevamento del confine if (square.x - dx < 0 || square.x + dx + square.width > stage.stageWidth) // rilevamento dell'asse x if (square.y - dy < 0 || square.y + dy + square.height > stage.stageHeight) // y rilevamento asse // Dopo tutto ciò, applicate questi all'oggetto square.x + = dx; square.y + = dy; 

Sta cercando i confini in modo più preciso, controllando se i bordi del quadrato colpiscono i confini (prima di questo, era solo controllando il centro del quadrato contro i confini).

Grande. Ora dobbiamo aggiungere il codice per far rimbalzare il quadrato dai confini. Quello che faccio per questo è moltiplicare per -1 il valore dell'asse dx o dy. Ma non è abbastanza! Se la velocità è abbastanza veloce, il quadrato supererà i margini o impazzirà. Quindi, prima di moltiplicare, è necessario impostare la xey dell'oggetto per essere uguale al limite che incontra.

Quindi se x object.x = 0; e quindi moltiplica il dx di -1.

 // Rilevamento del margine se (square.x - dx < -dx || square.x + dx + square.width > stage.stageWidth) // rilevamento dell'asse x square.x = square.x - dx < -dx ? 0 : stage.stageWidth - square.width; dx *= -1;  if (square.y - dy < -dy || square.y + dy + square.height > stage.stageHeight) // y detection axis square.y = square.y - dy < -dy ? 0 : stage.stageHeight - square.height; dy *= -1; 

Provalo subito! Bouncy giusto? :)

Per renderlo ancora migliore, continua a sperimentare valori diversi: come invece di moltiplicare per -1, prova -0.7 e guarda i risultati.


Conclusione

Quindi hai incontrato la classe Input.as, hai imparato come lavorarci e hai fatto un bel movimento fluido in pochi minuti. Penso che questo sia un grande momento!

Si prega di lasciare i vostri commenti qui sotto e qualsiasi altra domanda, sarò lieto di rispondere.

Ma se incontri qualche problema controlla due volte il tuo codice, confrontalo con il file sorgente e poi se non riesci a farlo funzionare, sentiti libero di postare una domanda.