Informazioni sulla cinematica lineare

Immaginare l'animazione in termini di vettori è intuitiva, ma comprendere la matematica vettoriale è un dolore. In questo tutorial, spero di alleviare quel dolore e di fornire una soluzione ai problemi di animazione usando una classe Vector2D scritta su misura. Vedremo alcuni concetti fondamentali della cinematica lineare nell'approccio Euleriano: spostamento, velocità e accelerazione. Quindi, costruiremo una semplice applicazione con esso.


Anteprima del risultato finale

Diamo un'occhiata al risultato finale su cui lavoreremo. Fai clic sul pannello Flash in basso e controlla la punta della freccia premendo i quattro tasti direzionali.


Passaggio 1: quantità vettoriale

Tutte le quantità di vettori hanno due componenti: grandezza e direzione.


Passaggio 2: modifica della quantità di vettore

Una variazione delle quantità di vettori si riferisce a uno di questi casi:

  1. Cambio di direzione
  2. Cambia in grandezza
  3. Cambiamento sia in grandezza che in direzione

Passaggio 3: spostamento come quantità di vettori

Spostamento, velocità e accelerazione sono quantità vettoriali. Le loro definizioni sono le seguenti:

  • Spostamento - Vettore del percorso più breve che punta dall'origine alla destinazione. Definisco l'origine come punto (0, 0) e destinazione come posizione della particella relativa a questo punto. Fondamentalmente, si riferisce al sistema di coordinate cartesiane implementato da Flash.
  • Velocità - La velocità è il cambiamento di spostamento nel tempo.
  • Accelerazione - L'accelerazione è il cambio di velocità nel tempo.

L'animazione in basso mostra lo spostamento come verrà implementato in Flash in seguito.


Passaggio 4: velocità come quantità vettoriale

La velocità è illustrata dall'animazione sottostante. La velocità nota è costante, il che significa che l'accelerazione è assente in questo scenario. Se la velocità è zero, lo spostamento rimarrà costante per tutto il tempo.


Passaggio 5: accelerazione come quantità di vettori

L'accelerazione è illustrata dall'animazione sottostante. Nota: la cinematica implica costante accelerazione. Se l'accelerazione cambia nel tempo, rientra nell'argomento di dinamica. La dinamica è lo studio delle forze che le cause di accelerazione variano nel tempo. Una tale forza è la gravità, e ho scritto un post su come animarlo.


Passaggio 6: Inizia a costruire un proiettile

Ora che hai ottenuto una breve comprensione delle grandezze cinematiche lineari e sei in grado di collegarle ai vettori, possiamo iniziare a costruire la nostra classe proiettile. Vorremmo che il proiettile fosse in grado di catturare tutte queste quantità: spostamento, velocità e accelerazione - in modo che possa essere manipolato su ogni fotogramma.

Di seguito sono riportati i dati che registreremo nella nostra classe di proiettili:

 private var displace: Vector2D; private var velo: Vector2D; private var acc: Vector2D;

Step 7: Inizializza il proiettile

All'inizio di questa classe proiettile, inizializzeremo le variabili citate e disegneremo la sua rappresentazione grafica.

 public function Projectile () // disegna la grafica this.draw (); // init all vector quantity displace = new Vector2D (this.x, this.y); velo = new Vector2D (0, 0); acc = new Vector2D (0, 0);  funzione protetta draw (): void // che disegna l'altezza var della freccia: Number = 30; var width: Number = 60; graphics.beginFill (0x0000FF); graphics.moveTo (0, 0); graphics.lineTo (larghezza / -3, altezza / -2); graphics.lineTo (width / 2, 0); graphics.lineTo (larghezza / -3, altezza / 2); graphics.lineTo (0, 0); graphics.endFill (); 

Step 8: Accessors of Vector Quantities

Di seguito sono accennati alle nostre variabili private - spostare, velo, acc - nella classe proiettile.

 funzione pubblica setDisp (mag: Number, angle: Number): void displace.redefine (mag, angle);  public function getDisp (): Vector2D return displace;  public function setVelo (mag: Number, angle: Number): void velo.redefine (mag, angle);  public function getVelo (): Vector2D return velo;  public function setAcc (mag: Number, angle: Number): void acc.redefine (mag, angle);  funzione pubblica getAcc (): Vector2D return acc

Passaggio 9: Aggiornatori di quantità vettoriali

Dopo aver aggiornato ogni frame, è necessario aggiornare la velocità (usando l'accelerazione) e aggiornare lo spostamento (usando la velocità indicata). Questo può essere ottenuto usando le seguenti funzioni. Per una spiegazione approfondita sull'aggiunta di Vector, visita questo fantastico post di Daniel Sidhon.

 funzione pubblica applyVelo (): void this.displace = this.displace.add (velo);  public function applyAcc (): void this.velo = this.velo.add (acc);  // aggiorna la posizione dello sprite per spostamento. public function animate (): void this.x = this.displace.x; this.y = this.displace.y; 

Step 10: Updater per l'orientamento di Sprite

Dovremo anche aggiornare l'orientamento dello Sprite. Questo può essere raggiunto attraverso il rotazione proprietà di Sprite.

 public function orient (): void this.rotation = Math2.degreeOf (velo.getAngle ()); 

Ho anche implementato a math2 classe statica, in cui ho scritto una funzione per convertire facilmente avanti e indietro dalle unità di gradi e radianti dell'angolo.

 funzione statica pubblica radianOf (deg: Number): Number return deg / 180 * Math.PI;  public static function degreeOf (rad: Number): Number return rad / Math.PI * 180; 

Step 11: The Main Class

Ora che abbiamo stabilito la nostra classe Projectile e Math2, possiamo iniziare a codificare la nostra classe Main. Avremo bisogno anche di una lezione di Vector2D anche se la spiegazione approfondita non è inclusa a causa del summenzionato articolo su Vettori di Daniel Sidhon. Presumo che i lettori capiscano la classe Vector2D dopo averla letta. Tuttavia, se sono necessari chiarimenti, chiedimi le tue domande.

Prima di tutto, abbiamo bisogno di conoscere le variabili private di questa classe.

 private var b1: proiettile; // keypress flags private var UP: Boolean = false; private var DOWN: Boolean = false; private var LEFT: Boolean = false; private var RIGHT: Boolean = false;

Passaggio 12: Inizializzazione principale

All'inizializzazione di Main, funzione dentro sarà lanciato. Questa funzione creerà un nuovo proiettile e stabilirà la sua velocità iniziale. Quindi, verranno assegnati gli ascoltatori agli eventi.

 funzione privata init (e: Event = null): void removeEventListener (Event.ADDED_TO_STAGE, init); // entry point b1 = new Projectile (); stage.addChild (b1); // impostazione iniziale velocity b1.setVelo (5, Math2.radianOf (30)); // impostazione dei listener di eventi b1.addEventListener (Event.ENTER_FRAME, proj_enterFrame); stage.addEventListener (KeyboardEvent.KEY_DOWN, handle_keyDown); stage.addEventListener (KeyboardEvent.KEY_UP, handle_keyUp); 

Passaggio 13: ascoltatori di eventi della tastiera

Ho definito il controllo utente come tasti premuti dei tasti freccia Su, Sinistra, Giù e Sinistra. Premendo e rilasciando quei tasti, le variabili flag di Main (Step 11) saranno rese vere e false. Sulla base di questi flag, le quantità Vector verranno manipolate su ogni frame. Nota anche che ho diviso i controlli in manipolatori di assi orizzontali e verticali.

 funzione privata handle_keyDown (e: KeyboardEvent): void if (e.keyCode == Keyboard.UP) UP = true; else if (e.keyCode == Keyboard.DOWN) DOWN = true; if (e.keyCode == Keyboard.LEFT) LEFT = true; else if (e.keyCode == Keyboard.RIGHT) RIGHT = true;  private function handle_keyUp (e: KeyboardEvent): void if (e.keyCode == Keyboard.UP) UP = false; else if (e.keyCode == Keyboard.DOWN) DOWN = false; if (e.keyCode == Keyboard.LEFT) LEFT = false; else if (e.keyCode == Keyboard.RIGHT) RIGHT = false; 

Passaggio 14: ascoltatori di eventi EnterFrame

All'aggiornamento di ciascun frame verrà eseguito il codice seguente. È lungo, ma non preoccuparti; continua a leggere.

 funzione privata proj_enterFrame (e: Event): void // define acceleration var accMag: Number = 0.1; if (UP) b1.setAcc (accMag, Math2.radianOf (-90)); b1.applyAcc ();  else if (DOWN) b1.setAcc (accMag, Math2.radianOf (90)); b1.applyAcc ();  if (LEFT) b1.setAcc (accMag, Math2.radianOf (180)); b1.applyAcc ();  else if (RIGHT) b1.setAcc (accMag, Math2.radianOf (0)); b1.applyAcc ();  // decelera quando viene premuto nothng per simulare l'attrito. if (UP + DOWN + LEFT + RIGHT == 0) var currentVeloMag: Number = b1.getVelo (). getMagnitude (); var currentVeloAng: Number = b1.getVelo (). getAngle (); if (currentVeloMag> 1) b1.setAcc (accMag * -1, currentVeloAng); b1.applyAcc ();  b1.applyVelo (); // limitazione dello sprite ai bordi dello stage b1.getDisp (). x = Math2.implementBound (0, stage.stageWidth, b1.getDisp (). x); b1.getDisp (). y = Math2.implementBound (0, stage.stageHeight, b1.getDisp (). y); b1.animate (); b1.orient (); 

Passaggio 15: Aggiorna movimento

L'aggiornamento del movimento dovrebbe essere eseguito nel seguente ordine:

  1. Definire una nuova accelerazione in base alla pressione del tasto dell'utente.
  2. Usando l'accelerazione, aggiorna la velocità attuale.
  3. Usando la velocità attuale, aggiorna lo spostamento attuale.
  4. Affina lo spostamento per mantenere l'oggetto all'interno dei confini.

Ho evidenziato i codici per una facile identificazione di questi passaggi.

 funzione privata proj_enterFrame (e: Event): void // define acceleration var accMag: Number = 0.1; if (UP) b1.setAcc (accMag, Math2.radianOf (-90)); b1.applyAcc ();  else if (DOWN) b1.setAcc (accMag, Math2.radianOf (90)); b1.applyAcc ();  if (LEFT) b1.setAcc (accMag, Math2.radianOf (180)); b1.applyAcc ();  else if (RIGHT) b1.setAcc (accMag, Math2.radianOf (0)); b1.applyAcc ();  // decelera quando non viene premuto nulla per simulare l'attrito. if (UP + DOWN + LEFT + RIGHT == 0) var currentVeloMag: Number = b1.getVelo (). getMagnitude (); var currentVeloAng: Number = b1.getVelo (). getAngle (); if (currentVeloMag> 1) b1.setAcc (accMag * -1, currentVeloAng); b1.applyAcc ();  b1.applyVelo (); // limitazione dello sprite ai bordi dello stage b1.getDisp (). x = Math2.implementBound (0, stage.stageWidth, b1.getDisp (). x); b1.getDisp (). y = Math2.implementBound (0, stage.stageHeight, b1.getDisp (). y); b1.animate (); b1.orient (); 

Passaggio 16: Rallentamento del movimento

Potresti scoprire che ci sono altre funzioni inserite tra questi codici evidenziati. Quali sono? Uno è quello di applicare un altro vettore per rallentare il nostro proiettile in quanto l'utente non preme alcun tasto. Questo è applicato prima di aggiungere velocità al nostro spostamento.

 // decelera quando viene premuto nothng per simulare l'attrito. if (UP + DOWN + LEFT + RIGHT == 0) var currentVeloMag: Number = b1.getVelo (). getMagnitude (); var currentVeloAng: Number = b1.getVelo (). getAngle (); if (currentVeloMag> 1) b1.setAcc (accMag * -1, currentVeloAng); b1.applyAcc (); 

Step 17: Stay Inside

Il prossimo è di limitare il nostro proiettile a rimanere sempre sul palco, altrimenti volerà fuori dallo schermo. Ancora, implementBound è una funzione che ho incluso nella classe statica Math2. Dato un limite superiore, un limite inferiore e un valore casuale, implementBound restituirà un valore che rientra nei limiti.

Dopo aver applicato questi vincoli sul nostro spostamento (e solo dopo), aggiorniamo la posizione dello Sprite con questo valore di spostamento.

 // limitazione dello sprite ai bordi dello stage b1.getDisp (). x = Math2.implementBound (0, stage.stageWidth, b1.getDisp (). x); b1.getDisp (). y = Math2.implementBound (0, stage.stageHeight, b1.getDisp (). y);

Passaggio 18: Orient Sprite

Prima di lasciare questo sprite così com'è, dovremmo orientarlo in modo che punti sempre nella posizione in cui sta andando usando la funzione Oriente.


Passaggio 19: imposta Set and Go!

Ora tutto è pronto per partire. Mentre avvii questo pezzo premendo Ctrl + Invio, vedrai una freccia che rallenta gradualmente mentre scende in diagonale lungo lo schermo. Premere sui quattro tasti direzionali per spostare la freccia. Non preoccuparti di perdere la tua freccia; rimarrà nella tua vista.


Conclusione

Questo articolo dovrebbe familiarizzare con l'utilizzo di vettori per animare il movimento. Una volta che hai capito la cinematica, procedi a leggere il mio post sulla dinamica. Fammi sapere come va. Terima Kasih.