Lær om lineær kinematikk

Å tegne animasjon i vektorer er intuitiv, men forståelse av vektormatematikk er en smerte. I denne opplæringen håper jeg å lette den smerten og gi en løsning på animasjonsproblemer ved å bruke en tilpasset skrevet Vector2D-klasse. Vi vil se på noen grunnleggende begreper lineær kinematikk i den euleriske tilnærmingen: forskyvning, hastighet og akselerasjon. Da skal vi bygge et enkelt program med det.


Endelig resultatforhåndsvisning

La oss se på det endelige resultatet vi skal jobbe for. Klikk på Flash-panelet nedenfor og kontroller pilespissen ved å trykke på de fire retningstastene.


Trinn 1: Vector Mengde

Alle vektormengder har to komponenter: størrelsesorden og retning.


Trinn 2: Endring i vektorgruppe

En endring i vektormengder refererer til ett av disse tilfellene:

  1. Endring i retning
  2. Endring i størrelsesorden
  3. Endre i både størrelse og retning

Trinn 3: Fordeling som vektorgruppe

Forskyvning, hastighet og akselerasjon er vektormengder. Deres definisjoner er som følger:

  • Forskyvning - Vektor av den korteste banen som peker fra opprinnelse til destinasjon. Jeg definerer opprinnelse som punkt (0, 0) og destinasjon som partikkelens plassering i forhold til dette punktet. I utgangspunktet refererer det til det kartesiske koordinatsystemet som implementert av Flash.
  • Hastighet - Hastighet er forandringen av forskyvning over tid.
  • Akselerasjon - Akselerasjon er endring av hastighet over tid.

Animasjonen nedenfor viser forskyvning som vi skal implementere i Flash senere.


Trinn 4: Hastighet som vektorkvantum

Hastigheten er illustrert av animasjonen nedenfor. Merkhastigheten er konstant, noe som betyr at akselerasjon er fraværende i dette scenariet. Hvis hastigheten er null, vil forskyvningen forbli konstant hele tiden.


Trinn 5: akselerasjon som vektorgruppe

Accelerasjon er illustrert av animasjonen nedenfor. Merk: kinematikk innebærer konstant akselerasjon. Hvis akselerasjonen endres over tid, faller den under emnet for dynamikk. Dynamikk er studien av krefter som forårsaker akselerasjon for å variere over tid. En slik kraft er tyngdekraften, og jeg har skrevet et innlegg på å animere det.


Trinn 6: Begynn å bygge et prosjektil

Nå som du har fått en kort forståelse av lineære kinematikkmengder og i stand til å knytte dem til vektorer, kan vi begynne å bygge vår Projectile-klasse. Vi vil at prosjektilet kan fange alle disse mengdene: forskyvning, hastighet og akselerasjon - slik at den kan manipuleres på hver ramme.

Nedenfor er dataene vi skal registrere i vår Projectile-klasse:

 privat var forskyvning: Vector2D; privat var velo: Vector2D; privat var acc: Vector2D;

Trinn 7: Initialiser prosjektil

Ved oppstart av denne prosjektiloklassen skal vi initialisere de nevnte variablene og tegne grafisk representasjon.

 offentlig funksjon Projectile () // tegne grafikk this.draw (); // init alle vektormengder fortrenge = ny Vector2D (this.x, this.y); velo = ny Vector2D (0, 0); acc = ny Vector2D (0, 0);  beskyttet funksjonstegn (): void // tegning av pilespissen var høyde: tall = 30; var bredde: tall = 60; graphics.beginFill (0x0000FF); graphics.moveTo (0, 0); graphics.lineTo (bredde / -3, høyde / -2); graphics.lineTo (bredde / 2, 0); graphics.lineTo (bredde / -3, høyde / 2); graphics.lineTo (0, 0); graphics.endFill (); 

Trinn 8: Tilgangsmidler av vektmengder

Følgende er accessors av våre private variabler - forflytte, velo, acc - i prosjektiloklassen.

 offentlig funksjon setDisp (mag: tall, vinkel: tall): tomrom displace.redefine (mag, vinkel);  offentlig funksjon getDisp (): Vector2D return displace;  offentlig funksjon setVelo (mag: tall, vinkel: tall): void velo.redefine (mag, vinkel);  offentlig funksjon getVelo (): Vector2D return velo;  offentlig funksjon setAcc (mag: tall, vinkel: tall): void acc.redefine (mag, vinkel);  offentlig funksjon getAcc (): Vector2D return acc

Trinn 9: Oppdaterere av vektmengder

Når vi forfrisker hver ramme, må vi oppdatere hastighet (ved hjelp av akselerasjon) og oppdatere forskyvning (ved hjelp av hastigheten). Dette kan oppnås ved å bruke følgende funksjoner. For en grundig forklaring på Vector tillegg, besøk dette flotte innlegget fra Daniel Sidhon.

 offentlig funksjon applyVelo (): void this.displace = this.displace.add (velo);  offentlig funksjon applyAcc (): void this.velo = this.velo.add (acc);  // oppdater sprite s posisjon ved forskyvning. offentlig funksjon animate (): void this.x = this.displace.x; this.y = this.displace.y; 

Trinn 10: Updater for Sprite s Orientation

Vi må også oppdatere orienteringen til Sprite. Dette kan oppnås gjennom rotasjon eiendom av Sprite.

 Public Function Orient (): void this.rotation = Math2.degreeOf (velo.getAngle ()); 

Jeg har også implementert en Math2 statisk klasse, der jeg har skrevet en funksjon som enkelt konverterer frem og tilbake fra vinkelenes enheter av grader og radianer.

 offentlig statisk funksjon radianOf (deg: Nummer): Nummer return deg / 180 * Math.PI;  offentlig statisk funksjon degreeOf (rad: Nummer): Nummer return rad / Math.PI * 180; 

Trinn 11: Hovedklassen

Nå som vi har etablert vår Projectile og Math2-klasse, kan vi begynne å kode vår hovedklasse. Vi vil også trenge en Vector2D-klasse, selv om grundig forklaring ikke er inkludert på grunn av den nevnte artikkelen om vektorer av Daniel Sidhon. Jeg antar at leserne forstår Vector2D-klassen etter å ha lest den. Men hvis det er behov for avklaringer, spør meg om dine spørsmål.

Først av alt trenger vi å kjenne private variabler av denne klassen.

 private var b1: prosjektil; // tastetrykkflagger private var UP: Boolean = false; privat var NED: Boolean = false; privat var VENSTRE: Boolsk = false; private var RIGHT: Boolean = false;

Trinn 12: Initialisering av Main

Ved initialisering av Main, funksjon i det vil bli lansert. Denne funksjonen vil skape et nytt prosjektil og sette sin innledende hastighet. Deretter vil lyttere til hendelser bli tildelt.

 privat funksjon init (e: Event = null): void removeEventListener (Event.ADDED_TO_STAGE, init); // inngangspunkt b1 = nytt prosjektil (); stage.addChild (b1); // innstilling av starthastighet b1.setVelo (5, Math2.radianOf (30)); // innstilling hendelseslyttere b1.addEventListener (Event.ENTER_FRAME, proj_enterFrame); stage.addEventListener (KeyboardEvent.KEY_DOWN, handle_keyDown); stage.addEventListener (KeyboardEvent.KEY_UP, handle_keyUp); 

Trinn 13: Hørespillere for tastaturhendelse

Jeg har definert brukerkontroll som tastetrykk på opp, venstre, ned og venstre piltastene. Ved å trykke og slippe disse tastene, vil flaggvariabler av Main (Trinn 11) bli sant og falskt. Basert på disse flaggene vil Vector-kvantumene bli manipulert på hver ramme. Merk også jeg har delt kontroller i horisontale og vertikale akse manipulatorer.

 privat funksjon handle_keyDown (e: KeyboardEvent): void if (e.keyCode == Keyboard.UP) UP = true; ellers hvis (e.keyCode == Keyboard.DOWN) DOWN = true; hvis (e.keyCode == Keyboard.LEFT) LEFT = true; ellers hvis (e.keyCode == Tastatur.RETT) RIGHT = true;  privat funksjon handle_keyUp (e: KeyboardEvent): void if (e.keyCode == Keyboard.UP) OPP = false; ellers hvis (e.keyCode == Keyboard.DOWN) DOWN = false; hvis (e.keyCode == Keyboard.LEFT) VENSTRE = false; ellers hvis (e.keyCode == Tastatur.RETT) RIGHT = false; 

Trinn 14: EnterFrame Event Lyttere

Ved oppdatering av hver ramme vil følgende kode bli utført. Det er lenge, men ikke bekymre deg; bare les videre.

 privat funksjon proj_enterFrame (e: Event): void // definere akselerasjon var accMag: Number = 0.1; hvis (UP) b1.setAcc (accMag, Math2.radianOf (-90)); b1.applyAcc ();  ellers hvis (NED) b1.setAcc (accMag, Math2.radianOf (90)); b1.applyAcc ();  hvis (VENSTRE) b1.setAcc (accMag, Math2.radianOf (180)); b1.applyAcc ();  annet hvis (RIGHT) b1.setAcc (accMag, Math2.radianOf (0)); b1.applyAcc ();  // decelerate som nothng er presset for å simulere friksjon. hvis (OPP + NED + VENSTRE + RIGHT == 0) var currentVeloMag: Number = b1.getVelo (). getMagnitude (); var currentVeloAng: Number = b1.getVelo (). getAngle (); hvis (currentVeloMag> 1) b1.setAcc (accMag * -1, currentVeloAng); b1.applyAcc ();  b1.applyVelo (); // begrenser sprite til grenser av scenen 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 (); 

Trinn 15: Oppdater Motion

Oppdatere bevegelsen skal gjøres i følgende rekkefølge:

  1. Definer ny akselerasjon i henhold til brukerens tastetrykk.
  2. Ved hjelp av akselerasjon, oppdater gjeldende hastighet.
  3. Bruk gjeldende hastighet, oppdater gjeldende forskyvning.
  4. Avgrense forskyvning for å holde objekt innenfor grenser.

Jeg har fremhevet kodene for enkel identifisering av disse trinnene.

 privat funksjon proj_enterFrame (e: Event): void // definere akselerasjon var accMag: Number = 0.1; hvis (UP) b1.setAcc (accMag, Math2.radianOf (-90)); b1.applyAcc ();  ellers hvis (NED) b1.setAcc (accMag, Math2.radianOf (90)); b1.applyAcc ();  hvis (VENSTRE) b1.setAcc (accMag, Math2.radianOf (180)); b1.applyAcc ();  annet hvis (RIGHT) b1.setAcc (accMag, Math2.radianOf (0)); b1.applyAcc ();  // decelerere da ingenting blir presset for å simulere friksjon. hvis (OPP + NED + VENSTRE + RIGHT == 0) var currentVeloMag: Number = b1.getVelo (). getMagnitude (); var currentVeloAng: Number = b1.getVelo (). getAngle (); hvis (currentVeloMag> 1) b1.setAcc (accMag * -1, currentVeloAng); b1.applyAcc ();  b1.applyVelo (); // begrenser sprite til grenser av scenen 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 (); 

Trinn 16: Senke ned bevegelse

Det kan hende du finner at det finnes andre funksjoner som er slått inn mellom disse uthevede kodene. Hva er de? Den ene er å bruke en annen vektor for å redusere prosjektilet, siden brukeren ikke trykker på noen nøkler. Dette brukes før vi legger fart på vår forskyvning.

 // decelerere ettersom nothng er presset for å simulere friksjon. hvis (OPP + NED + VENSTRE + RIGHT == 0) var currentVeloMag: Number = b1.getVelo (). getMagnitude (); var currentVeloAng: Number = b1.getVelo (). getAngle (); hvis (currentVeloMag> 1) b1.setAcc (accMag * -1, currentVeloAng); b1.applyAcc (); 

Trinn 17: Hold deg inne

Den neste er å begrense vår prosjektil for alltid å være på scenen, ellers vil den flyve ut av skjermen. En gang til, implementBound er en funksjon jeg har tatt med i statisk klasse Math2. Gitt en øvre grense, lavere bundet og en tilfeldig verdi, implementBound vil returnere en verdi som ligger innenfor grensene.

Etter å ha brukt disse begrensningene på vår forskyvning (og først etter det) oppdaterer vi Sprite posisjon med denne forskyvningsverdien.

 // begrenser sprite til grenser av scenen b1.getDisp (). x = Math2.implementBound (0, stage.stageWidth, b1.getDisp (). x); b1.getDisp (). y = Math2.implementBound (0, stage.stageHeight, b1.getDisp (). y);

Trinn 18: Orient Sprite

Før vi forlater dette sprite som det er, bør vi orientere det slik at det alltid peker i den posisjonen det er på vei med funksjon orient.


Trinn 19: Få sett og gå!

Nå er alt satt til å gå. Når du starter dette stykket ved å trykke på Ctrl + Enter, vil du se en pil som gradvis bremser ned mens den hoder diagonalt nedover skjermen. Trykk på de fire retningstastene for å flytte pilen om. Ikke bekymre deg for å miste pilen din; det kommer til å ligge innenfor visningen din.


Konklusjon

Denne artikkelen skal gjøre deg kjent med bruk av vektorer for å animere bevegelse. Når du har forstått kinematikk, fortsett å lese opp på innlegget mitt på dynamikk. La meg vite hvordan det går. Terima Kasih.