Gravity i Action

Gravity in Action
Del
Del
5
Del

Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.
Dette innlegget er en del av en serie som heter du gjøre Math.Euclidean Vektorer i FlashHit Target med et dødelig Homing Missile

Studiet av styrkene er av sentral interesse for dynamikk, studiet av årsaker til bevegelse og endringer i bevegelse. Gravitasjonskraft
er ett eksempel; det er dette som fører til satellitter til å dreie seg om planeter og oss å bo på bakken.

I denne opplæringen, vil vi bygge en simulering av et slikt fenomen, og være i stand til å observere, eksperimentere og leke med partikler på scenen.


Blant alle partikler som genereres, vil en hoved partikkel tiltrekke andre. Som disse partiklene beveger seg mot den viktigste, kan brukerne klikke på denne hoved partikkel til å dra den rundt, forårsaker disse partiklene til å omdirigere sine kurs. Disse partiklene vil slutte å bevege seg som de kolliderer med kanten av hoved ball, men de vil ikke overlapper hverandre.

Strukturen av denne veiledningen er anordnet på en måte hvor et kort teori i Physics in levert før innføring gjennomføring av simuleringen. Nyt



Endelig resultat Forhåndsvisning

La oss ta en titt på det endelige resultatet vi skal jobbe mot:

Klikk og dra den store grønne sirkelen for å flytte den rundt, og se hvordan de små blå sirklene reagere



Trinn 1:. gravitasjonskraft, Formula

Først en fysikk forord. Den attraktive gravitasjonskraften mellom to objekter uttrykkes gjennom følgende formel:
offentlig funksjon getMagnitude (): Antall {var lengthX: Number = this._x; Var Lange: Number = this._y; returnere Math.sqrt (lengthX * lengthX + lange * lange);} offentlig funksjon getAngle (): Antall {var lengthX: Number = this._x; Var Lange: Number = this._y; returnere Math.atan2 (lang, lengthX);} offentlig funksjon getVectorDirection (): Vector2D {var vectorDirection: Vector2D = new Vector2D (this._x /this.getMagnitude (), this._y /this.getMagnitude ()); returnere Vector2D (vectorDirection);} offentlig funksjon minusVector (Vektor2: Vector2D): void {this._x - = vector2.vecX; this._y - = vector2.vecY;} offentlig funksjon addVector (Vektor2: Vector2D): void {this._x + = vector2.vecX; this._y + = vector2.vecY;} offentlig funksjon multiplisere (skalar: Number): void {this._x * = skalar; this._y * = skalar;}



Trinn 8: Ball.as Tegning

The Ball klassen er der alle de interessante operasjonene foregår. Til å begynne vår animasjon, må vi trekke en ball og satt flere kinematics- og dynamikk-relaterte variabler. Funksjonen for å tegne en ball er som følger:
privat funksjon uavgjort (radius: Antall, farge: uint): void {graphics.beginFill (farge, 1); graphics.drawCircle (0, 0, radius); graphics.endFill ();}



Trinn 9: Ball.as Private Variabler

De nevnte flere kinematikk og dynamikk relaterte variabler er angitt som nedenfor:
privat Var _disp: Vector2D; //forskyvningsvektor, i forhold til originprivate Var _velo: Vector2D; //hastighet vectorprivate Var _acc: Vector2D; //akselerasjon vectorprivate Var _attractive_coeff: Nummer = 500; privat Var _mass: Number;



Trinn 10: Ball.as Initiation

Som konstruktøren av Ball klassen kalles, grafikk er trukket. Når trekkes, vil ballen bli plassert på scenen tilfeldig. Vi vil også sette private variabler. . Alle mengder vektor vil også bli initialisert ved 0, med unntak av den forskyvning som er målt i forhold til origo
offentlig funksjon Ball (radius: Nummer = 20, farge: UINT = 0x0000FF) {this.draw (radius, farge); this._mass = radius /2; //forutsatt at massen er halvparten av radius this.x = Math2.randomiseBetween (0, 550); this.y = Math2.randomiseBetween (0, 400); this._disp = new Vector2D (this.x, this.y); //satt innledende forskyvning this._velo = new Vector2D (0, 0); this._acc = new Vector2D (0, 0);}



Trinn 11: Ball.as Beregn Attraktiv Force

Vi må beregne underliggende kraft som fører til at våre partikler å animere. Gjett hva, det er tyngdekraften. Funksjonen nedenfor vil hjelpe på å beregne denne styrken. Legg merke til at et hetten påføres på akselerasjonen ved 5. De horisontale og vertikale komponenter av kraften er utledet ved hjelp av trigonometri; animasjonen over kan bidra til å forstå matematikk av denne
offentlig funksjon får masse (): Antall {return _mass;} privat funksjon getForceAttract. (m1: Antall, m2: Antall, vec2Center: Vector2D): Vector2D {/* beregne tiltrekningskraft basert på følgende formel: * F = K * m1 * m2 /r * r * /var teller: Number = this._attractive_coeff * m1 * m2; Var evner: Number = vec2Center.getMagnitude () * vec2Center.getMagnitude (); Var forceMagnitude: Number = teller /nevner; Var forceDirection: Number = vec2Center.getAngle (); //sette en cap if (forceMagnitude > 0) forceMagnitude = Math.min (forceMagnitude, 5); //utlede kraftkomponent, horisontale, vertikale Var forceX: Number = forceMagnitude * Math.cos (forceDirection); Var forceY: Number = forceMagnitude * tak i Math.sin (forceDirection); Var kraft: Vector2D = new Vector2D (forceX, forceY); returnere kraft;}



Trinn 12: Ball.as Beregn Acceleration

Når kraftvektoren er oppnådd, kan vi beregne den resulterende akselerasjon. Husk, F = ma, så a = F /m
offentlig funksjon getAcc (vecForce: Vector2D): Vector2D {//sette akselerasjon på grunn av force Var vecAcc. Vector2D = vecForce.multiply (1 /this._mass); returnere veccAcc;}



Trinn 13: Ball.as Beregn Displacement

Med akselerasjon beregnes, vi effektivt kan beregne den resulterende forskyvning

Husk at makt beregnet er faktisk basert på. forskyvning mellom sentrum av ballene
privat funksjon getDispTo (ball: Ball): Vector2D {var currentVector: Vector2D = new Vector2D (ball.x, ball.y);. currentVector.minusVector (this._disp); returnere currentVector;} offentlig funksjon attractedTo (ball: Ball): void {var toCenter: Vector2D = this.getDispTo (ball); Var currentForceAttract: Vector2D = this.getForceAttract (ball.mass, this._mass, toCenter); this._acc = this.getAcc (currentForceAttract); this._velo.addVector (this._acc); this._disp.addVector (this._velo);}



Trinn 14: Ball.as Implementere Displacement

Så er vi i stand til å flytte vår ball til den nye plasseringen, gjennom funksjonen nedenfor . Merk at forskyvning beregnes aldri implementert på ballen nåværende plassering straks. Slike design er å tillate kontroll gjøres: dueller mellom ballene
offentlig funksjon setPosition (vecDisp: Vector2D): void {this.x = Math.round (vecDisp.vecX);. this.y = Math.round (vecDisp.vecY);}

Husk at kraften er basert på avstanden mellom sentrene. Derfor vil kulene trenge inn og fortsetter å bevege seg på grunn av tiltrekningskraft være høyere når de er nærmere. Vi må nullstille akselerasjon og hastighet til 0 når ballene berøre hverandre kanten. Men trenger vi å få et middel til å oppdage kollisjonen mellom to baller



Trinn 15:. Ball.as Collision Detection

Kollisjon lett kan kontrolleres. Separasjon mellom hvilke som helst to kuler bør ikke være mindre enn summen av deres radier. Her er den dueller funksjon:
offentlig funksjon collisionInto (ball: Ball): Boolean {var hit: Boolean = false; Var minDist: Number = (ball.width + this.width) /2; if (this.getDispTo (ball) .getMagnitude () < minDist) {hit = true; } Retur hit;}



Trinn 16: Ball.as Beregn Forskyving å frastøte

Vanligvis når kollisjonen har blitt oppdaget mellom to baller, deres tilstand er overlapper hverandre. Vi må sørge for at de vil bare sitte pent på kanten og ikke overlapper hverandre. Hvordan? Vi kan forskyve en av ballene bort fra den andre, men må vi beregne riktig forskyvning for å justere første. Her er den forskyvning beregningen:
offentlig funksjon getRepel (ball: Ball): Vector2D {var minDist: Number = (ball.width + this.width) /2; //beregne avstanden til frastøte Var Toball: Vector2D = this.getDispTo (ball); Var directToBall: Vector2D = toBall.getVectorDirection (); directToBall.multiply (minDist); directToBall.minusVector (Toball); directToBall.multiply (1); returnere directToBall;}



Trinn 17: Ball.as Implementere Displacement å frastøte

Etter at vi har beregnet riktig forskyvning, må vi gjennomføre det. Handlingen er som frastøter en av ballene. I tillegg må vi gjøre en annen to ekstra kommandoer. Husk, har vi å gjøre med et dynamisk miljø. Selv etter at vi har satt forskyvning en av ballen til kanten, til akselerasjon på grunn tvinge og den resulterende hastigheten vil animere den, forårsaker en uønsket bevegelse av krampetrekninger inn og ut. Vi må nullstille disse verdiene av akselerasjon og hastighet til null
offentlig funksjon repelledBy (ball: Ball):. Void {this._acc.reset (); this._velo.reset (); Var repelDisp: Vector2D = getRepel (ball); this._disp.addVector (repelDisp);}



Trinn 18: Ball.as Animate

Til slutt, vi kan animere (gjengi) vår ball som om det ble tiltrukket av en annen. Ved kollisjon blir oppdaget, vil forskyvning justeres slik at det ikke vil trenge inn i kanten. Dette vil skje først etter ballene når de kolliderer med sentrum, og deretter for ballene når de kolliderer med hverandre
offentlig funksjon animere (senter: Ball, alle: Array):. Void {this.attractedTo (i midten); if (collisionInto (midten)) this.repelledBy (i midten); for (var i: int = 0; i < all.length; i ++) {var current_ball: Ball = all [i] som Ball; if (collisionInto (current_ball) & amp; & amp; current_ball.name = this.name!) this.repelledBy (current_ball); } This.setPosition (this._disp);}



Trinn 19: Main.as Private Variabler

Flytte til vår siste klasse, Main. Hoved class genereres ved starten av prosjektet. Private variabler vil omfatte en ball som tiltrekker alle de andre og antall baller i våre Flash presentasjon
privat Var mainBall. Ball, private Var totalBalls: int = 10;



Trinn 20: Main. som Draw Balls

Først av alt, bør vi initial baller. Det vil være en hoved ball som tiltrekker alle de andre. . De andre er navngitt slik at referering kan enkelt gjøres senere
private funksjons createBalls (): void {mainBall = new Ball (50, 0x00FF00); this.addChild (mainBall); for (var i: int = 0; i < this.totalBalls; i ++) {var currentBall: Ball = new Ball (); currentBall.name = "ball" + i; this.addChild (currentBall); }}



Trinn 21:. Main.as Implementere Ball Interaksjon

Deretter tilordner hendelser til hoved ballen til å gjøre det flyttbare når klikket og stoppe når den slippes
privat funksjon init (e : Hendelses = null): void {removeEventListener (Event.ADDED_TO_STAGE, init); //Entry point createBalls (); mainBall.addEventListener (MouseEvent.MOUSE_DOWN, onMouseDown); stage.addEventListener (MouseEvent.MOUSE_UP, onMouseUp); animateAll ();} private funksjon onMouseUp (e: MouseEvent): void {stopdrag ();} private funksjon onMouseDown (e: MouseEvent): void {e.target.startDrag ();}



Trinn 22: Main.as Animer Balls

Animere baller som blir tiltrukket av det viktigste. En enterframe hendelsen er tildelt hver ball
privat funksjon animateAll (): void {for. (Var i: uint = 0; i < totalBalls; i ++) {//hver ball blir trukket av main_ball Var current_ball: Ball = this.getChildByName ("ball" + i) som Ball; current_ball.addEventListener (Event.ENTER_FRAME, enterframe); }} privat funksjon enterframe (e: Hendelses): void {var allObj: Array = new Array (); for (var i: int = 0; i < = totalBalls, jeg ++) {var current_ball: Ball = this.getChildAt (i) som Ball; allObj.push (current_ball); } E.target.animate (mainBall, allObj);}



Trinn 23:. Test Movie

Til slutt, trykk Ctrl + Enter for å forhåndsvise animasjonen



Konklusjon

For å få denne opplæringen ett skritt videre, kan leserne utvide dette prosjektet ved å implementere andre lineære krefter.

I alle fall, simuleringer tjene som et flott verktøy i å levere ideer vanskelige å forklare ved vanlig tekst og bilde i en fysikk klasserom miljø, særlig når staten endrer seg over tid.

Jeg håper denne lille opplæringen hjelper deg på noen måte. Terima kasih (det vil si "takk" i Malaysia) for å ta tid til å lese og ser frem til å høre kommentarer fra andre lesere.



Next Page: