Introduksjon til Box2D for Flash og AS3

Introduction å Box2D for Flash og AS3
en
Del
to
Del

Dette Cyber ​​mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

Box2D er et populært fysikkmotor med en solid Flash-port, som ble brukt til å opprette utmerket spill Fantastic Contraption. I denne opplæringen, den første av en serie, får du tak i det grunnleggende Box2D 2.1a for Flash og AS3




Trinn 1:. Den Boring Setup

Jeg skal anta at du allerede vet hvordan du setter opp en grunnleggende Flash prosjekt ved hjelp redaktør og arbeidsflyten til valg, enten det betyr å skape en FLA med et dokument klasse, en ren AS3 prosjekt i et annet program, eller hva. Jeg bruker FlashDevelop, men du bør bruke hva du føler deg komfortabel med.

Lag ditt prosjekt, og navngi den viktigste klassen Main.as. Gi det noen standardtekst kode; min ser slik ut:
pakke {import flash.display.Sprite; import flash.events.Event; [Frame (factoryClass = "Preloader")] public class Hoved strekker Sprite {offentlig funksjon main (): void {if (scene) init (); annet addEventListener (Event.ADDED_TO_STAGE, init); } Private funksjon init (e: Hendelses = null): void {removeEventListener (Event.ADDED_TO_STAGE, init); kom i gang(); } Private funksjon getStarted (): void {}}}

Ikke bekymre deg om [Frame] metakode - det er bare hvordan FlashDevelop skaper en preloader. Alt du trenger å vite er at getStarted () kjøres når SWF har fullastet. Lag en funksjon med samme navn som kjøres når din viktigste klassen er lastet inn.

jeg også kommer til å anta at du er komfortabel med å bruke et eget bibliotek eller API i prosjektet. Last ned Box2DFlash 2.1a fra denne siden (jeg bruker Flash 9 versjon), og pakke ut zip dit du normalt sette APIer. Deretter legger en CLASSPATH å peke på \\ Source \\ mappe fra zip. Alternativt kan du bare pakke ut innholdet i den \\ Source \\ mappe til samme katalog som din viktigste klassen.

Great! Det var lett. La oss begynne å bruke Box2D



Trinn 2:. A Whole New b2World

"Hvis du ønsker å lage en eplekake fra bunnen av, må du først opprette universet», skrev Carl Sagan; hvis vi ønsker å gjøre noen fysikk objekter, vi trenger bare å skape en verden

I Box2D, er en verden ikke en planet eller et økosystem.; det er bare navnet som er gitt for objektet som styrer den generelle fysikk simulering. Det setter også styrken av tyngdekraften - ikke bare hvor raskt objekter akselerere, men også i hvilken retning de faller

Vi vil opprette en vektor for å stille alvoret før du oppretter selve verden.
Import Box2D .Common.Math.b2Vec2; //... privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10);}

En b2Vec2 er en Box2D vektor (de andre 2 står for 2D igjen, fordi det er mulig å ha en 3D vektor). Daniel Sidhion skrev en utmerket tutorial forklarer hva euklidske vektorer er (de er ingenting å gjøre med Vector klassen i AS3), så sjekk det ut hvis du ikke er sikker. Men kort, tenke på en vektor som en pil:

Denne pilen viser b2Vec2 (4, 9); den peker ned og til høyre. Vår gravitasjonsvektoren, da vil peke rett ned. Jo lenger pilen, jo sterkere tyngdekraften, så senere i opplæringen kan du prøve å endre gravitasjonsvektoren å b2Vec (0, 2) for å simulere en mye svakere tyngdekraft, mye sånt på månen.

Nå vil vi lage selve verden:
importere Box2D.Dynamics.b2World; //... offentlig Var verden: b2World; //... privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true);}

Den andre parameteren vi passerer til b2World () forteller det at det kan stoppe simulere objekter som det ikke trenger å simulere noe mer, noe som bidrar til å øke hastigheten på simuleringen, men er helt irrelevant for oss i øyeblikket.

Kjør SWF å sjekke det ikke er noen feil. Du vil ikke være i stand til å se noe ennå, though. Verden er i dag helt tomt



Trinn 3: gjenoppfinne hjulet

La oss lage en enkel sirkelformet objekt; dette kunne representere en stein, en basketball, eller en potet, men jeg kommer til å se det som et hjul

Jeg vil gjerne si at du gjør dette er så enkelt som:.
Var hjul : b2CircularObject = new b2CircularObject ();

... men det ville være en stor feit løgn. Saken om Box2D er, tilsynelatende enkle ting kan kreve ganske mye kode for å få sortert. Denne ekstra kompleksitet er svært nyttig for å gjøre avansert arbeid, men det ganske kommer i vår vei for enkle ting som hva vi prøver å gjøre for øyeblikket. Jeg kommer til å gå fort over hva vi må gjøre for å gjøre dette hjulet; vi kan undersøke det nærmere i senere tutorials

For å lage et enkelt "fysikk objekt." - det vil si et objekt med en form og en masse som Box2D kan simulere i en verden - vi må konstruere den ved hjelp av fem ulike klasser:

En kroppen definisjon
, som er som en mal for å lage ...

En kroppen
, som har en masse og en stilling, men har ikke ...

A
form, som kan være så enkelt som en sirkel, som må være koplet til et legeme ved hjelp av .. .

En ligaen
, som er opprettet ved hjelp av ...

En ligaen definisjon
som er en annen mal, som kroppen definisjon.

Puh. Her er hva som alt ser ut i kode:
importere Box2D.Dynamics.b2BodyDef, import Box2D.Dynamics.b2Body, import Box2D.Collision.Shapes.b2CircleShape, import Box2D.Dynamics.b2Fixture, import Box2D.Dynamics.b2FixtureDef; //...private funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef);}

Argumentet om at vi passerer til b2CircleShape () angir sirkelens radius. Alt annet bør være fornuftig basert på listen ovenfor, selv om begrunnelsen bak denne strukturen gir ingen mening

Merk at vi aldri skrive ny b2Body () eller ny b2Fixture (.); verden brukes til å lage legemet fra kroppen definisjon, og legemet blir brukt til å skape den fiksturen fra fiksturen definisjonen. Dette betyr at verden vet om alle de organer som er opprettet i det, og kroppen vet om alle kamper som er opprettet som kobler figurer til det.

Den faktiske fysikk objekt som vi har laget er wheelBody; alt annet er bare en del av en oppskrift for å danne det en gjenstand. Så, for å sjekke at vi har vært vellykket, la oss se om wheelBody finnes:
privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); trace (wheelBody);}

Resultat: product: [objekt b2Body]

God



Trinn 4: Flytte kroppen din

Vet du hva jeg mener. når jeg snakker om "spillet loop" og en "tick"? Hvis ikke, gå lese min korte artikkelen, forstå spillet Loop, akkurat nå, fordi det er veldig viktig for det vi gjør.

Box2D verden objekt har en metode, Step (), som driver simulering . Du angir en liten periode (en brøkdel av et sekund), og trinn () simulerer bevegelse og kollisjoner av hvert objekt i verden; når funksjonen har kjørt, vil alle kroppens objekter har blitt oppdatert med sine nye posisjoner.

La oss se dette i aksjon. I stedet for å spore wheelBody seg selv, vil vi spore sin posisjon. Deretter vil vi kjøre b2World.Step (), og spore hjulet posisjon igjen:
privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); trace (. wheelBody.GetPosition () x, wheelBody.GetPosition () y.); world.Step (0,025, 10, 10); trace (wheelBody.GetPosition () x, wheelBody.GetPosition () y..);}

(The GetPosition () metoden av en kropp returnerer en b2Vec2, så vi trenger å spore de enkelte x- og y-egenskaper heller enn bare ringer trace (wheelBody.GetPosition ().)

Den første parameteren vi passerer til trinn () er antall sekunder for å simulere bestått i Box2D verden. De to andre parametre spesifisere hvor mye nøyaktighet Box2D bør bruke alle matematiske beregninger den bruker til å simulere bestått av tiden ikke bry deg om disse akkurat nå,. bare vet at større tall kan gjøre Box2D ta mer tid å simulere verden - hvis du setter disse for høy, kan det også ta lenger enn 0,025 sekunder å kjøre Step (), så vi vil være å få ut av sync med den virkelige verden

Test SWF, og se på din utgang vinduet!
0 00 0

Det er litt deprimerende Hjulet har ikke flyttet i det hele tatt -. og likevel, verden har tyngdekraften, så du skulle tro det ville ha falt litt Hva skjer



Step.? 5: Å være Dynamic

Som standard alle Box2D kropper er statisk
, noe som betyr at de ikke kan bevege seg. Tenk på de faktiske plattformer i et plattformspill; de er faste gjenstander, men er ikke påvirket av tyngdekraften, og kan ikke bli dyttet rundt.

Vi trenger vår hjulet for å være dynamisk
, slik at den kan bevege seg. Gjett hvor vi definere
denne eiendommen av kroppen
? ! Hjelp av kroppen definisjon
, selvfølgelig
privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); trace (. wheelBody.GetPosition () x, wheelBody.GetPosition () y.); world.Step (0,025, 10, 10); trace (wheelBody.GetPosition () x, wheelBody.GetPosition () y..);}

Prøv SWF nå, og se hva du får:
0 00 0,00625

Det har flyttet! Hvor spennende



Trinn 6: Keep on Moving

Vi kan ikke kalle dette et spill sløyfe ennå, men fordi det er bare å kjøre en gang;! vi trenger det for å kjøre om og om og om igjen. Vi kan gjøre dette skje ved hjelp av en tidtaker og en hendelse lytteren:
import flash.utils.Timer, import flash.events.TimerEvent; //... privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); Var stepTimer: Timer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); trace (. wheelBody.GetPosition () x, wheelBody.GetPosition () y.); stepTimer.start ();} private funksjon onTick (a_event: Timerevent): void {world.Step (0,025, 10, 10); trace (wheelBody.GetPosition () x, wheelBody.GetPosition () y..);}

(Legg merke til at jeg har gitt timeren en periode på 0,025 sekunder i tillegg, slik at den holder seg oppdatert med verdens trinn . Du trenger ikke å gjøre dette - faktisk, hvis du gjør de to periodene annerledes, kan du få noen virkelig kule tidsrelaterte effekter, som slow-motion)

Men, oops, det. koden vil ikke fungere; vi trenger wheelBody å være tilgjengelig i onTick () -funksjonen. Mens vi er i gang, kan vi like godt gjøre timeren tilgjengelig overalt, også:
offentlig Var verden: b2World; offentlig Var wheelBody: b2Body; offentlig Var stepTimer: Timer; //... privat funksjon getStarted () : void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; wheelBody = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); trace (. wheelBody.GetPosition () x, wheelBody.GetPosition () y.); stepTimer.start ();}

Merk at linjene 14 og 20, ovenfor, har endret seg, nå som hjulet kroppen og timer er definert andre steder

Prøv det nå:
0 00 0,006250 0,0187500000000000030. 0,0375000000000000060 0,06250 0,093750 0,131250 ,175000000000000020 0,225000000000000030 0,281250000000000060 0,343750000000000060 0,41250000000000010 ,48750000000000010 ,5687500000000001

Hurra, den faller alltid! Ok, det er nok å analysere tallene; la oss gjøre noe visuelt



Trinn 7:.! Tegn

Vi har fått alle disse koordinatene, så hvorfor ikke bli med prikkene

Sett spor med? koden for å trekke en linje fra hjulet gamle stilling til sin nye:
privat funksjon onTick (a_event: Timerevent): void {graphics.moveTo (.. wheelBody.GetPosition () x, wheelBody.GetPosition () y); world.Step (0,025, 10, 10); graphics.lineTo (wheelBody.GetPosition () x, wheelBody.GetPosition () y..);}

For å se linjen, må vi sette sin linestyle:
privat funksjon getStarted (): void {//... stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); graphics.lineStyle (3, 0xff0000); stepTimer.start ();}

Nå kjører SWF. Du vil se en rød linje akselererer nedover venstre kant. Jeg har lagt noen lureri til min SWF det betyr at det ikke vil gjøre noe før du klikker på den, slik at du kan sjekke den ut nedenfor:

Great! Så, er hjulet fritt fall, og blir raskere på grunn av tyngdekraften, slik det skal være. Vi bør la sin vertikal hastighet alene slik at tyngdekraften kan gjøre sitt arbeid, men vi kan manuelt endre sin opprinnelige horisontal hastighet å gjøre linjen form litt mer interessant:
privat funksjon getStarted (): void {//... Var startingVelocity: b2Vec2 = new b2Vec2 (50, 0); wheelBody.SetLinearVelocity (startingVelocity); stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); graphics.lineStyle (3, 0xff0000); stepTimer.start ();}

Husk at en b2Vec2 ser ut som en pil, så i dette tilfellet, er starthastigheten kommer til å se ut som en pil som peker direkte til høyre, som om vi nettopp hadde skutt den ut av en kanon fra toppen av en klippe. Vår verden har ingen luftmotstand (fordi det er ingen luft!) Så det er absolutt ingenting å roe det ned -. Skjønt, takket være tyngdekraften, er det påskynde vertikalt

Høres forvirrende, men det bør være klart en gang du kjører SWF:

Vi har nettopp utilsiktet trukket en parabel. Så ... det er ryddig, antar jeg



Trinn 9: The Illusion of Movement

Ok, ok, kanskje du ikke er så begeistret for å se en buet rød linje som Jeg er. Hvis vi kommer til å simulere en verden, bør vi gjøre objektene ser ut som, vel, objekter, ikke sant? Så i stedet for å se en linje som sporer hjulet posisjon gjennom verdensrommet, bør vi gjøre det se ut som om hjulet er faktisk beveger seg gjennom rommet.

Vi kan gjøre dette ved gjentatte ganger å tegne og slette en sirkel, sentrert på hjulet beliggenhet:
privat funksjon onTick (a_event: Timerevent): void {graphics.clear (); graphics.lineStyle (3, 0xff0000); world.Step (0,025, 10, 10); graphics.drawCircle (.. wheelBody.GetPosition () x, wheelBody.GetPosition () y, 5);}

Vi må spesifisere linjestil i onTick () nå, fordi graphics.clear () tilbakestiller det, som samt slette all grafikken fra skjermen. Legg merke til at jeg har satt radiusen av sirkelen til 5, som er det samme som radius av circleShape vi opprettet tidligere

Prøv denne SWF.

Jeg tror det er ganske opplagt hva neste skritt bør være ...



Trinn 10: Jordet

Dette uendelig verden av intet ikke egner seg til mange spennende situasjoner. Jada, vi kan legge til nye hjul, men uten noen bakken eller vegger, ville de aldri gjøre noe interessant.

Vi skal lage noen faste gjenstander at hjulet kan kollidere med, og starter med en stor flat stykke bakke. For dette, vil vi bruke et rektangel.

Husk objektene vi trenger for å lage en kropp?

  • En kroppen definisjon
    , som er som en mal for å skape ...

    En kroppen
    , som har en masse og en stilling, men har ikke ...

    En form Anmeldelser , som kan være så enkelt som en sirkel, som må kobles til en kropp ved hjelp ...

    En ligaen
    , som er opprettet ved hjelp av ...

    A ligaen definisjon
    som er en annen mal, som kroppen definisjonen

    Du vet hvordan du gjør dette for en sirkulær kroppen.; Nå må vi lage en rektangulær en:
    privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; wheelBody = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); Var groundBodyDef: b2BodyDef = new b2BodyDef (); Var groundBody: b2Body = world.CreateBody (groundBodyDef); Var groundShape: b2PolygonShape = new b2PolygonShape (); groundShape.SetAsBox (stage.stageWidth, 1); Var groundFixtureDef: b2FixtureDef = new b2FixtureDef (); groundFixtureDef.shape = groundShape; Var groundFixture: b2Fixture = groundBody.CreateFixture (groundFixtureDef); Var startingVelocity: b2Vec2 = new b2Vec2 (50, 0); wheelBody.SetLinearVelocity (startingVelocity); stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); graphics.lineStyle (3, 0xff0000); stepTimer.start ();}

    Det er stort sett det samme, bortsett fra at der i å skape en sirkulær kropp vi passert ønsket radius til b2CircleShape () konstruktør, her vi må passere den ønskede bredden og høyden på rektangelet på b2PolygonShape.SetAsBox () -funksjonen. (Egentlig passerer vi ønsket halv-
    bredde og halv
    høyde, slik at boksen vil være dobbelt så bred som scene og to piksler høyt, men det er fint.) Husk at alle kropper er statisk
    som standard, slik at vi ikke trenger å bekymre deg for bakken faller bort. Du må importere Box2D.Collision.Shapes.b2PolygonShape for at dette skal fungere.

    Som standard eventuell ny form vil bli opprettet på (0, 0)
    , så vi trenger å spesifisere at bakken skal opprettes ved bunnen av scenen. Vi kunne manuelt endre plasseringen av bakken kroppen når den er blitt opprettet, akkurat som vi manuelt endret hastigheten på hjulet kroppen, men det er penere hvis vi setter posisjonen som en del av bakken kropp definisjon:
    privat funksjon getStarted ( ): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; wheelBody = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); Var groundBodyDef: b2BodyDef = new b2BodyDef (); groundBodyDef.position.Set (0, stage.stageHeight); Var groundBody: b2Body = world.CreateBody (groundBodyDef); Var groundShape: b2PolygonShape = new b2PolygonShape (); groundShape.SetAsBox (stage.stageWidth, 1); Var groundFixtureDef: b2FixtureDef = new b2FixtureDef (); groundFixtureDef.shape = groundShape; Var groundFixture: b2Fixture = groundBody.CreateFixture (groundFixtureDef); Var startingVelocity: b2Vec2 = new b2Vec2 (50, 0); wheelBody.SetLinearVelocity (startingVelocity); stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); graphics.lineStyle (3, 0xff0000); stepTimer.start ();}

    Pass på at du setter dette før
    passerer kroppen definisjonen til world.CreateBody (), eller endringene vil bli ignorert

    Nå teste SWF. :

    Vi kan ikke se bakken fordi vi ikke har trukket det, men Box2D fortsatt simulerer det, så vi se effekten. hjulet kolliderer med det og ruller til side



    Trinn 11: Sett noen grenser

    Vi kommer til å legge til flere hjul i neste trinn, men først, la oss gjøre dette til en helt lukket rom, med en bakken, et tak, og to vegger .

    Jeg vil at du skal ha en gå på dette selv; opprette tre mer rektangulære likene av de riktige størrelser og i de riktige posisjonene. Det vil være lettest å starte med en på høyre, siden hjulet kommer til å kollidere med den. For å teste de andre, fikle med den innledende hastighet.

    Du må skifte hjul opprinnelige posisjon, eller det vil overlappe venstre veggen og taket når de er opprettet. Du kan gjøre dette på samme måte som du angir plasseringen av rektangulære objekter, gjennom position.Set () -metoden av kroppen definisjonen.

    Lykke til! Hvis du får problemer, sjekk ut min koden under:
    privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; wheelBodyDef.position.Set (10, 10); wheelBody = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); Var groundBodyDef: b2BodyDef = new b2BodyDef (); groundBodyDef.position.Set (0, stage.stageHeight); Var groundBody: b2Body = world.CreateBody (groundBodyDef); Var groundShape: b2PolygonShape = new b2PolygonShape (); groundShape.SetAsBox (stage.stageWidth, 1); Var groundFixtureDef: b2FixtureDef = new b2FixtureDef (); groundFixtureDef.shape = groundShape; Var groundFixture: b2Fixture = groundBody.CreateFixture (groundFixtureDef); Var rightWallBodyDef: b2BodyDef = new b2BodyDef (); rightWallBodyDef.position.Set (stage.stageWidth, 0); Var rightWallBody: b2Body = world.CreateBody (rightWallBodyDef); Var rightWallShape: b2PolygonShape = new b2PolygonShape (); rightWallShape.SetAsBox (1, stage.stageHeight); Var rightWallFixtureDef: b2FixtureDef = new b2FixtureDef (); rightWallFixtureDef.shape = rightWallShape; Var rightWallFixture: b2Fixture = rightWallBody.CreateFixture (rightWallFixtureDef); Var leftWallBodyDef: b2BodyDef = new b2BodyDef (); leftWallBodyDef.position.Set (0, 0); Var leftWallBody: b2Body = world.CreateBody (leftWallBodyDef); Var leftWallShape: b2PolygonShape = new b2PolygonShape (); leftWallShape.SetAsBox (1, stage.stageHeight); Var leftWallFixtureDef: b2FixtureDef = new b2FixtureDef (); leftWallFixtureDef.shape = leftWallShape; Var leftWallFixture: b2Fixture = leftWallBody.CreateFixture (leftWallFixtureDef); Var ceilingBodyDef: b2BodyDef = new b2BodyDef (); ceilingBodyDef.position.Set (0, 0); Var ceilingBody: b2Body = world.CreateBody (ceilingBodyDef); Var ceilingShape: b2PolygonShape = new b2PolygonShape (); ceilingShape.SetAsBox (stage.stageWidth, 1); Var ceilingFixtureDef: b2FixtureDef = new b2FixtureDef (); ceilingFixtureDef.shape = ceilingShape; Var ceilingFixture: b2Fixture = ceilingBody.CreateFixture (ceilingFixtureDef); Var startingVelocity: b2Vec2 = new b2Vec2 (50, 0); wheelBody.SetLinearVelocity (startingVelocity); stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); graphics.lineStyle (3, 0xff0000); stepTimer.start ();}

    Og resultatet.

    Nice arbeid



    Trinn 12: Lag en Array

    Nå er vi klare til å legge til flere organer, smelle dem sammen, og se hva som skjer.

    Vi kan lage dem alle invididually, som jeg gjorde med rektangler, men det ville være penere å bruke en matrise for å holde dem alle, og en enkelt funksjon for å lage dem

    Så, først, la oss lage denne matrisen, med ett enkelt element: den eksisterende hjulet
    offentlig Var verden: b2World; //offentlig Var wheelBody:.. b2Body; < - slette denne linepublic Var wheelArray: Array, offentlige Var stepTimer: Timer; //... privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); wheelArray = new Array (); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; wheelBodyDef.position.Set (10, 10); Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); wheelArray.push (wheelBody); //... Var startingVelocity: b2Vec2 = new b2Vec2 (50, 0); wheelBody.SetLinearVelocity (startingVelocity); stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); graphics.lineStyle (3, 0xff0000); stepTimer.start ();} private funksjon onTick (a_event: Timerevent): void {graphics.clear (); graphics.lineStyle (3, 0xff0000); world.Step (0,025, 10, 10); for hver (var wheelBody: b2Body i wheelArray) {graphics.drawCircle (.. wheelBody.GetPosition () x, wheelBody.GetPosition () y, 5); }}

    Hvis dette fungerer, SWF vil handle akkurat det samme som det gjorde før



    Trinn 13:. Legg One More Wheel

    For å teste ut dette på riktig måte, vi kan legge en ekstra hjulet - bare én for nå! Kopier og lim inn koden for å lage hjulet og endre deler av det slik at hjulene er ikke akkurat det samme:
    privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); wheelArray = new Array (); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; wheelBodyDef.position.Set (10, 10); Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); wheelArray.push (wheelBody); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; wheelBodyDef.position.Set (100, 200); Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); wheelArray.push (wheelBody); //... Skape grenser her Var startingVelocity: b2Vec2 = new b2Vec2 (50, 0); wheelBody.SetLinearVelocity (startingVelocity); stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); graphics.lineStyle (3, 0xff0000); stepTimer.start ();}

    Du vil få en haug med advarsler om dupliserte variable definisjoner, men det bør likevel kompilere, avhengig av innstillingene:

    Den første hjulet faller rett ned, uten en innledende sidelengs hastighet. Dette gir mening når du ser på koden; vi kaller wheelBody.SetLinearVelocity () på feil sted. Flytte den opp:
    privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); wheelArray = new Array (); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; wheelBodyDef.position.Set (10, 10); Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); Var startingVelocity: b2Vec2 = new b2Vec2 (50, 0); wheelBody.SetLinearVelocity (startingVelocity); wheelArray.push (wheelBody); Var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; wheelBodyDef.position.Set (100, 200); Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (5); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); Var startingVelocity: b2Vec2 = new b2Vec2 (-100, 0); wheelBody.SetLinearVelocity (startingVelocity); wheelArray.push (wheelBody); //... Skape grenser her stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); graphics.lineStyle (3, 0xff0000); stepTimer.start ();}

    OK! Det fungerer godt. Vi kan pakke inn alt som hjulet skapelse kode opp i en funksjon, nå



    Trinn 14:. Wheel Generator

    For å lage dette hjulet generasjon funksjonen, kan du i utgangspunktet kopiere og lime inn hele koden vi har brukt. Her er mine:
    privat funksjon createWheel (radius: Antall, startx: Antall, starty: Antall, velocityX: Antall, velocityY: Number): void {var wheelBodyDef: b2BodyDef = new b2BodyDef (); wheelBodyDef.type = b2Body.b2_dynamicBody; wheelBodyDef.position.Set (startx, starty); Var wheelBody: b2Body = world.CreateBody (wheelBodyDef); Var circleShape: b2CircleShape = new b2CircleShape (radius); Var wheelFixtureDef: b2FixtureDef = new b2FixtureDef (); wheelFixtureDef.shape = circleShape; Var wheelFixture: b2Fixture = wheelBody.CreateFixture (wheelFixtureDef); Var startingVelocity: b2Vec2 = new b2Vec2 (velocityX, velocityY); wheelBody.SetLinearVelocity (startingVelocity); wheelArray.push (wheelBody);}

    Jeg har lagt noen parametere slik at vi kan angi passelig egenskapene til hjulene. Mens vi er i gang, foreslår jeg at vi flytte alle grense etableringen koden til en egen funksjon, bare for å holde ting ryddig:
    privat funksjons createBoundaries (): void {//setter du grensen kode her}

    Nå kan vi omskrive hele getStarted () -funksjonen som så:
    privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); wheelArray = new Array (); createWheel (5, 10, 10, 50, 0); createWheel (5, 100, 200, -25, 0); createBoundaries (); stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); graphics.lineStyle (3, 0xff0000); stepTimer.start ();}

    Prøv det ut! Igjen, bør SWF fungere på samme måte som det gjorde før



    Trinn 15:. Automatic Wheels

    Nå som vi har forenklet hjulet generasjon, kan vi gjøre mange av dem uten mye problemer eller rotet:
    privat funksjon getStarted (): void {var Vekt: b2Vec2 = new b2Vec2 (0, 10); verden = new b2World (gravitasjon, true); wheelArray = new Array (); for (var i: int = 0; i < 20; i ++) {createWheel (Math.random () * 10, Math.random () * (stage.stageWidth - 20) + 10, Math.random () * ( stage.stageHeight - 20) + 10, (Math.random () * 100) - 50, 0); } CreateBoundaries (); stepTimer = new Timer (0,025 * 1000); stepTimer.addEventListener (TimerEvent.TIMER, onTick); graphics.lineStyle (3, 0xff0000);