Introduksjon til QuickBox2D: Part 2

Introduction til QuickBox2D: Part 2
Del
Del
en
Del

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

Dette er andre del i en tre del tutorial serien om QuickBox2D. Det anbefales at du leser hver del av denne serien i orden. Så hvis du ikke har lest del en, bør du gjøre det nå. Du kan sjekke det ut her.


I denne opplæringen vil vi ta en titt på noen av de mer middels nivå funksjoner i QuickBox2D. Vi får se hvordan du kan lage polygon stive kropper. Vi vil lære å finjustere vår simulering ved hjelp av ekstra param verdier som restitusjon, linearDamping og angularDamping. Vi vil diskutere noen kraftige Box2D metoder som er utsatt av QuickBox2D og vi skal snakke om FRIM (framerate uavhengig bevegelse).

Påminnelse:. Dette bør gå uten å si, men ikke glem å sette Box2D og QuickBox2D bibliotekene enten
ved siden av din FLA-fil eller i classpathen

Denne opplæringen vil lede deg gjennom opprettelsen av en mellomstor simulering laget for å røre på bestemte aspekter av QuickBox2D og Box2D. Sjekk ut demoen og avlaste litt stress ..



Trinn 1: Klargjøre Script

Åpne opp Flash og lim inn følgende kode inn i handlingene for ramme en:
[SWF (width = 800, height = 600, framerate = 60, bakgrunnsfarge = 0x000000)]; import com.actionsnippet.qbox *; Var sim. QuickBox2D = new QuickBox2D (denne); /** ----- ------------------------ - sett variable definisjonene nedenfor denne kommentaren ------------------ ------------ * ///all koden for å bygge stive kropper //er som finnes på dette functionbuildSimulation (); sim.start (); sim.mouseDrag (); funksjon buildSimulation (): void {//satt noen standard farger og skape sceniske vegger sim.setDefault ({fillColor: 0x113366, fillAlpha: 0,5, lineColor: 0x3355AA}); sim.createStageWalls (); /** ----------------------------- - Innsats ridgid kroppen instantiation koden under denne kommentaren -------- ---------------------- * /}

Når du har koden ovenfor i din tidslinje gå videre og teste filmen for å kontrollere at alt er satt opp ordentlig. Ikke mye som skal skje når du kjører denne koden, bare pass på at du ikke har noen feil før du går videre.

Det meste av det du ser i koden ovenfor bør være kjent for deg. Det er imidlertid et par viktige ting å merke seg. Som vi legge ekstra kode til denne filen må vi definere noen variabler. For organisatoriske formål vil du ønsker å legge disse variablene under kommentaren som lyder: Twitter /** --------------------------- - - sett variable definisjonene nedenfor denne kommentaren ------------------------------ * /

For enkelhets skyld, vi ' har også opprettet en funksjon som heter buildSimulation () til å bryte alle våre stiv kropp oppretting. Denne funksjonen kalles før start () og mouseDrag () metoder for QuickBox2D. Den inneholder noen standard fargeinnstillinger for våre stive kropper, samt en oppfordring til createStageWalls (). Mesteparten av koden vi ser på i denne opplæringen må limes direkte under kommentaren som lyder: Twitter /** ---------------------- ------- - insert ridgid kroppen instantiation koden under denne kommentaren ------------------------------ * /< hr>
Trinn 2: polygoner og Points Param

Jeg antar at du vet forskjellen mellom konveks, konkav og komplekse polygoner. Hvis du ikke vet eller ikke husker forskjellen, kan det være lurt å ha et blikk på wikipedia artikkel om emnet.

QuickBox2D lar deg definere polygoner på to måter. Den første måten bruker automatisk polygon triangulering, som lar deg å bare definere x og y-koordinatene for konturen av et polygon. Det er ingen begrensning på antall punkter i konturen. Lim inn følgende kode inn i buildSimulation () -funksjonen og teste filmen:
//trianglesim.addPoly ({x: 3, y: 17 poeng: [0,0, 1,1, 0,1, 0, 0]}); //Konkav polysim.addPoly ({x: 7, y: 17 poeng: [1,0, 2,2, 1,1.2, 0, 2]});

Koden ovenfor definerer to polys. Den første linjen definerer et enkelt rettvinklet trekant som blir posisjonert ved (3,17), og den neste linje definerer en konkav polygon som blir posisjonert ved (7,17). Vi gjør bruk av en param kalt poeng som er et utvalg av x- og y-koordinater. Endimensjonale matriser av xy-koordinater kan være vanskelig, bør det under grafikken oppklare eventuelle misforståelser du
måtte ha om den koden vi nettopp lagt:

Når du oppretter poeng matriser, må du være forsiktig for ikke å ha en kontur som overlapper seg selv, dette vil forvirre triangulering manus og forårsake en feil.

Du vil merke at den andre polygon består av to trekanter. Dette er QuickBox2D er triangulering kode på jobb, i utgangspunktet bryter det din kontur opp i en haug med trekanter. Hvis du ikke ønsker å se hver trekant, bruker du kan den ramme svømme param. Prøv å endre din konkav poly koden som følger:
//konkav polysim.addPoly ({x: 7, y: 17, wireframe: false, påpeker: [1,0, 2,2, 1,1.2, 0, 2 ]});

Hvis du trenger for å lage mer komplekse polygoner bør du nok bygge selv en slags enkel polygon editor. Det er et eksempel på et slikt editor på actionsnippet.com. Det kan være lurt å ta en titt på den i noen minutter før du leser videre. Det burde hjelpe stivne din forståelse av hvordan QuickBox2D triangulerer polygoner.



Trinn 3: polygoner og Verts Param

Det er en annen måte å skape polygoner som bruker QuickBox2D som er litt mer komplisert. Hvis du er veldig opptatt av resultatene av simuleringen kan du vurdere å bruke denne metoden over tidligere diskutert metoden. Du kan også være lurt å bruke denne metoden hvis du trenger for å lage en enkel konveks poly eksempel en trapazoid. Legg til følgende kode inn i buildSimulation () -funksjonen:
sim.addPoly ({x: 13, y: 17, verts: [[- 1, -1, 1, -1, 2, 1, -2, 1 ]]});

Denne koden trekker en trapazoid. Test din film og ta en titt.

Det er noen differenes mellom verts param og poeng param. En åpenbar forskjell er at verts matrisen er en todimensjonal array. Hver nestet matrise inneholder en liste over xy koordinater, kan denne matrisen brukes til å definere opptil åtte hjørnene. Du kan ikke definere en konkav eller kompleks polygon ved hjelp av en enkelt nested array. I stedet må du definere en rekke konvekse polygoner (igjen, hver med maks åtte hjørner). Du bør definere hver konveks polygon i tur og orden, og starter med den øverste punkt og jobber tilbake rundt. Dette kan være vanskelig, men det er enklere enn det høres ut. Legg til følgende kode inn i buildSimulation () -funksjonen og teste filmen:
sim.addPoly ({x: 18, y: 15, verts: [[0, -1, 1,1, -1,1], [1,1, 2,1.5, 1,2], [1,2, 0,3, -1,3, -1,2], [-1.5,2, -1,2.5, -1,3, -2,3,}) -2,2.5]];

Denne koden trekker noen polygoner sammen. Resultatet er en liten gruppe av konvekse polys. Hvis du planlegger å bruke denne funksjonen, kan det være lurt å ta en pause på dette punktet, og prøve å skape noe med verts param. Det er interessant å se hvor sensitiv denne funksjonen er, vil du få rare resultater hvis du ikke overholder restriksjonene nevnt i forrige avsnitt



Trinn 4:. Restitusjon

Restitusjon er som elastisiteten eller bounciness av en stiv kropp. Som standard restitusjon ligger et sted mellom 0-1, men høyere verdier er tillatt. La oss ta en titt på hva som kan gjøres med restitusjon, kopiere følgende kode inn i buildSimulation () -funksjonen og teste filmen:
//perpetually sprettende ball sim.addCircle ({x: 3, y: 13, radius: 1, restitusjon: 1}); //Satt restutution til 1,2 for å skape et springbrett sim.addBox ({x: 24, y: 15, bredde: 3, høyde: 0,25, fillColor: 0xDD0000, lineAlpha: 0, vinkel: 0,1, restitusjon: 1.2, tetthet: 0}); //Normal sirkel sim.addCircle ({x: 24, y: 10, radius: 0,5});

Det første vi lage med denne koden er en sirkel som spretter alltid. Ved å sette restitusjon param til 1 vil det ikke stoppe sprette så lenge det er igjen alene. Det neste vi skaper er en rød boks som er litt rotert, har en tetthet på 0 (statisk) og har en tilbakeføring på 1,2. Restitusjon på 1,2 gjør det slik at ting spretter ut av det vil få litt energi. For å teste dette, legger vi til en sirkel rett ovenfor. Hvis du ser denne sirkelen nøye vil du legge merke til at hver gang den treffer den røde boksen den spretter litt høyere, helt til slutt den treffer taket og spretter ut av den røde boksen helt.

Restitusjon er virkelig første skrittet til å gjøre dine stive legemer oppfører seg som de er laget av forskjellige materialer. En restitusjon av 0 ville være bra for en stiv kropp som er ment å være laget av stein; en tilbakeføring på 0,8 ville være bra for noe som er laget av svært bouncy gummi



Trinn 5:. kantete og lineær Damping

Hvis du ønsker å unngå en stiv kropp fra å oversette eller rotere også rask, kan du dempe sin lineær eller vinkelhastighet. . Legg denne koden til din buildSimuation () funksjon og teste filmen
//grønne boksen sim.addBox ({x: 3, y: 5, bredde: 1, høyde: 1, angularDamping: 5, fillColor: 0x22CC00} ); //Rød boks sim.addBox ({x: 8, y: 5, bredde: 1, høyde: 1, fillColor: 0xff0000}); //Liten plattform sim.addBox ({x: 6, y: 8, bredde: 10, høyde: 0,25, tetthet: 0});

Her kan vi legge til en grønn boks med en angularDamping verdi på 5. Dette vil føre den gren boksen for å slutte å rotere svært raskt når den kastes. Til sammenligning vi legge til en rød boks og forlot sin angularDamping verdi ved mislighold av 0. Siden simuleringen begynner å bli litt rotete, vi har lagt til en liten plattform under disse to boksene, så det er lett å flytte dem rundt og observere Forskjellen mellom dem.

Linear demping er akkurat som angularDamping men for oversettelse. La oss legge angularDamping til den grønne boksen:
//grønne boksen sim.addBox ({x: 3, y: 5, bredde: 1, høyde: 1, angularDamping: 5, linearDamping: 5, fillColor: 0x22CC00});

Hvis du tester filmen, vil du legge merke til at den grønne boksen faller saktere enn den røde boksen og hvis du kaster den rundt litt vil du se at det nesten ser ut til å flyte. Prøv å spille rundt med verdiene litt før du går videre.

Jeg finner jeg liker å ha angularDamping på noe som jeg ønsker å rotere realistisk når kastet. Som standard når du kaster en boks rundt, vil du merke det vil rotere rundt mange mange ganger. Jeg finner meg selv bruker linearDamping litt mindre, men det er bra hvis du ikke vil ha noe å flytte rundt for fort. Det er også bra hvis du ønsker å gjøre noe ser ut som om det blir påvirket av luftmotstanden, for eksempel en deflatert ballong eller et stykke styrofoam.


Det er viktig å merke seg at innstillingen angularDamping eller linearDamping params ovenfor en vil dem til å bli følsomme for timestep. Dette kan ikke bety noe for deg i øyeblikket, men vi vil diskutere det videre senere i denne opplæringen



Trinn 6:. Friksjon

I Box2D, friksjon generelt spenner 0-1. Som standard alle QuickObjects har en friksjon på 0,5. Hvis vi redusere denne verdien ting begynner å se veldig glatte. Legg den under kode til din buildSimulation () -funksjonen og teste filmen:
//grå boks sim.addBox ({x: 3, y: 9, bredde: 1, høyde: 1, friksjon: 1, fillColor: 0xCCCCCC }); //Lyseblå boks sim.addBox ({x: 8, y: 9, bredde: 1, høyde: 1, friksjon: 0, fillColor: 0xCCCCFF, fillAlpha: 1}); //Liten plattform sim.addBox ({x: 6, y: 12, bredde: 10, høyde: 0,25, tetthet: 0});

I koden ovenfor legger vi en grå boks med en friksjon på 1, en lys blå boks med en friksjon på 0 og en annen liten plattform for å gjøre de to bokser lett å observere. Prøv å skyve hver boks langs plattformen. Du vil merke at den grå boksen ikke glir veldig mye, mens den lyseblå boksen virker veldig glatt, som en isbit.

rote rundt med friksjon alltid får meg til å tenke på is nivåer fra de gamle Nintendo sidescrollers ...



Trinn 7: isBullet Param (Continuous Collision Detection CCD)

Box2D har noe som kalles CCD. Dette er en mer nøyaktig, mer cpu intensive form av dueller. Hvis du vil bruke denne type kollisjon på en stiv kropp, må du benytte deg av isBullet param. Som navnet antyder, du ofte bruker CCD for kuler og andre raskt bevegelige stive kropper. Kopier koden nedenfor inn buildSimulation ():
Var bokser: Array = []; bokser [0] = sim.addBox ({x: 1, y: 0, bredde: 2, høyde: 0,25}); bokser [1] = sim.addBox ({x: 1, y: 2, bredde: 2, høyde: 0,25}); bokser [2] = sim.addBox ({x: 0, y: 1, bredde: 0,25, høyde: 2,25}); bokser [3] = sim.addBox ({x: 2, y: 1, bredde: 0,25, høyde: 2,25}); sim.addGroup ({x: 12, y: 6, objekter: bokser}); //Hvis isBullet er falsk, vil sirkler falle ut av boksen for (var i: int = 0; i < 4; i ++) {sim.addCircle ({x: 13, y: 7, radius: 0,2, isBullet: true} ); }

Her skaper vi en hul boks ved hjelp av en gruppeobjekt. Vi deretter sette fire små sirkler inn i hul boks og satt sin isBullet eiendom til sann. Dette hindrer de små sirkler fra skyte ut av hul boks gruppeobjekt. Teste dette ved å kaste hul boks rundt simuleringen så fort du kan. Du vil merke at alle sirklene holde seg innenfor veggene i hul boks. Nå prøve å sette den isBullet param til false og gjøre det samme, nesten umiddelbart vil du se sirklene fly ut over alt.

Det er verdt å merke seg at CCD brukes automatisk på statiske organer. Anmeldelser



Trinn 8: FixedRotation Param

fixedRotation param er veldig lett å forstå. Det er en boolsk at hvis satt til true vil hindre en stiv kropp rotere. Dette er nyttig for å forebygge karakter i et spill fra å falle over. Legg denne koden til din buildSimulation () -funksjonen og teste filmen:
sim.addBox ({x: 19, y: 3, bredde: 1, høyde: 2, fillColor: 0xFFFFFF, fixedRotation: true});

Denne koden skaper en hvit boks (det er litt grått på grunn av mislighold alfa verdi på 0,8) med fixeRotation satt til true. Hvis du prøver å kaste den rundt vil du legge merke til at det ikke roterer. Ganske enkelt ikke sant?

Det er verdt å merke seg at du fortsatt kan stille vinkelen param. Gi dette en sjanse:
sim.addBox ({x: 19, y: 3, bredde: 1, høyde: 2, fillColor: 0xFFFFFF, fixedRotation: true, vinkel: 1});



Trinn 9: isSleeping Param

Box2D stive legemer sovner som standard for å spare CPU. Det handler om å sovne oppstår når et stivt legeme har kommet til hvile. Noen ganger vil du unngå en stiv kropp fra å falle i søvn med allowSleep boolean (vi vil se et godt eksempel på dette senere i opplæringen). Noen ganger ønsker du å starte en stiv kropp off sover. For disse tilfellene du bruke isSleeping param. Det kan ikke være innlysende, men isSleeping kan brukes til å lage knuselig objekter. Legg denne koden til din buildSimulation () -funksjonen og teste filmen: Twitter /* ------------------------------- - - Trinn 10: allowSleep --------------------------------- * ///opprette 10 esker grid formasjon for (i = 0; i < 10; i ++) {sim.addBox ({x: 13 + (i% 2) * 0,5, y: 3 + int (i /2) * 0,5, bredde: 0,5, høyde : 0,5, lineAlpha: 0, fillColor: 0x4444FF, isSleeping: true}); }

Denne koden skaper 10 bokser i et rutenett formasjon, trenger boksene ikke har et hjerneslag og er farget med en mettet blå. Den isSleeping param er satt til sann som standard, noe boksene å ligge på startposisjonen inntil noe annet treff dem og vekker dem opp. Hvis du kaster en annen stiv kropp på denne rutenett av bokser du vil legge merke til at vi har skapt en illusjon av en knuselig stiv kropp.

Hvis du ikke er kjent med teknikken vi bruker til å ordne bokser i et rutenett, kan du lese denne opplæringen om å arrangere Displayobject i rutenett formasjonene over på learningActionScript3.com



Trinn 10: groupIndex Param

groupIndex param kan brukes til å gi deg en bedre kontroll over hvordan kollisjonen håndteres mellom stive kropper. Det er et helt tall som enten er positiv eller negativ. Hvis to stive legemer har den samme negative groupIndex verdi at de ikke vil kollidere med hverandre, hvis de har den samme positive verdi groupIndex de vil kollidere. Legg denne koden til din buildSimulation () -funksjonen:
for (i = 0; i < 4; i ++) {sim.addBox ({x: 2 + i, y: 2, fillColor: 0xFFFF00, bredde: 0,5, høyde : 1,5, groupIndex: -1}); } //Liten plattform sim.addBox ({x: 6, y: 4, bredde: 10, høyde: 0,25, tetthet: 0});

Denne koden skaper fire gule rektangler med groupIndex verdi på -1. Det skaper også en annen liten plattform å gjøre observasjon av groupIndex param lett. Hvis du tester filmen du vil legge merke til at disse rektangler ikke vil kollidere med hverandre.

Jeg finner meg selv å bruke denne groupIndex ganske mye. Det er viktig når du arbeider med komplekse simuleringer. Det finnes to andre relaterte params kalt maskBits og categoryBits. Jeg har ennå til å trenge disse veldig mye, men du kan lese litt mer om dem i Box2D veiledningen hvis du er interessert.



Trinn 11: Klargjøring for nøkkelkontroller

Som nevnt i del 1 av denne opplæringen. Hver opprettelsesmetoden (addBox (), addPoly () osv ...) returnerer en QuickObject. Når du ønsker å begynne å holde styr på elementer i en simulering du vil lagre QuickObject referanser i variabler. Vi kommer til å begynne å sette opp en stiv kropp som skal styres med piltastene. For å gjøre dette må vi gjøre litt forberedelser. Først legger denne variabelen definisjonen til din kode (husk å sette den under variable definisjonen kommentar utsiden av buildSimulation () -funksjonen). Twitter /** ---------------- ------------- - sett variable definisjonene nedenfor denne kommentaren ----------------------------- - * /var tegnet: QuickObject;

Neste legge til følgende kode til din buildSimulation () -funksjonen:
Var charPartA: QuickObject = sim.addBox ({x: 0, y: 0, bredde: 2, høyde: 0,8}); Var charPartB: QuickObject = sim.addBox ({x: 0, y: 0, bredde: 0,8, høyde: 2}); karakter = sim.addGroup ({objekter: [charPartA, charPartB], x: 8 , y: 3, angularDamping: 0,8, linearDamping: 0,8, allowSleep: falsk});

Dette skaper en liten gruppe objekt bygget opp av to bokser. Vi setter lineære og kantete demping egenskaper slik at det ikke vil gå for fort når vi begynne å kontrollere den med tastaturet. Vi bruker også en param kalt allowSleep å sørge for at karakteren stive kroppen ikke sovne (uten at dette nøkkelkontroller vil ikke fungere riktig). Test filmen for å sørge for at karakteren gruppeobjekt har blitt lagt til simulering skikkelig

. ADVARSEL: Disse neste trinnene blir litt vanskelig, så vær nøye med på hver instruksjon. Hvis du begynner å bli bekymret for at du ikke kan følge alle endringer i koden, etter den vanskelige delen er over kan du vurdere å laste ned hele fla å sammenligne



Trinn 12.: Legge Basic Key Control Kode

For enkelte typer nøkkelen kontroll bare bruker KeyboardEvents alene vil ikke klippe det. Normalt vil jeg bruke noe sånt som dette:
Var nøkkel: Object = new Object();stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyPressed);stage.addEventListener(KeyboardEvent.KEY_UP, onKeyReleased), funksjon onKeyPressed (evt: KeyboardEvent): void {key [evt.keyCode] = true;} funksjon onKeyReleased (evt: KeyboardEvent): void {key [evt.keyCode] = false;}

Denne koden skaper en objekt (assosiativ matrise eller et kart) kalt nøkkelen. Når du trykker en tast for første gang, er en eiendom dynamisk opprettet på nøkkelen objekt, er nøkkelkode brukes for navnet på eiendommen, og siden vi er på et KEY_DOWN hendelse eiendommen er satt til true. Når en KEY_UP hendelse inntreffer den nyopprettede eiendommen er satt til false. Du bør kopiere og lime inn denne koden helt ned i bunnen av skriptet på dette punktet.

Hvis du aldri har sett denne teknikken før, kan det virke litt rart for deg. Hvis det er tilfelle, er alt du trenger å vite at denne koden hindrer noen mindre problemer med å bruke KeyboardEvents alene og at hvis vi ønsker å svare på keyboard input, kan vi bare gjøre noe som dette i en sløyfe:
if (nøkkel [Keyboard.UP]) {//gjør tegnet hopp}

Nå, når du bruker en løkke i forbindelse med QuickBox2D du kan lytte til Event.ENTER_FRAME hvis du liker, men senere versjoner av QuickBox2D har en spesiell type arrangement som heter QuickBox2D.STEP. Du bør alltid bruke QuickBox2D.STEP i favør av Event.ENTER_FRAME, vil vi snakke litt mer om dette når vi kommer til frim. Inni buildSimulation () -funksjonen bør du legge til en lytter for dette arrangementet:
sim.addEventListener (QuickBox2D.STEP, onStep);

Vi må også legge til en lytter funksjon rett under vårt buildSimulation () funksjon:
... sim.addEventListener (QuickBox2D.STEP, onStep);} //slutten av vår buildSimulation () -funksjonen //- kopi fra dette punktet på ... //vår lytteren functionfunction onStep (evt: Hendelses) : void {//vil vi legge til noen viktige kontroll ting her snart}

Ok, nå er vi nesten klar til å begynne å gjøre noen viktige kontrollert bevegelse ...



Trinn 13: Key kontroller, Linear Velocity og Body Eiendom

Alle QuickObjects har en egenskap som kalles kroppen. Denne eiendommen inneholder en referanse til en Box2D b2Body eksempel. Ved å utsette dette b2Body eksempel, gir QuickBox2D deg tilgang til en haug med Box2D metoder. Vi kommer til å bruke GetLinearVelocity () og SetLinearVelocity (). For en fullstendig liste over alle b2Body metoder, ta en titt her.

Den lineære hastighet av en stiv kropp er definert av en 2D vektor, x og y verdier av denne vektoren er lagt til x og y stilling av en gitt stivt legeme. Den lineære hastighet av et stivt legeme varierer med tiden på grunn av gravitasjon, kollisjoner med andre gjenstander, friksjon osv ... Box2D har en klasse spesielt utformet for håndtering av vektorer kalles b2Vec2. Den SetLinearVelocity () metoden tar en b2Vec2 som sin første og eneste argument. Vi må importere b2Vec2, så legg til denne linjen under import statement for QuickBox2D:
//du allerede har denne lineimport com.actionsnippet.qbox * //legge denne linjen:.. Import Box2D.Common.Math *; < p> b2Vec2 finnes innenfor matematisk-pakken. Nå la oss ta en titt på SetLinearVelocity (). Vi må legge til noen kode på innsiden av onStep () lytteren funksjon:
//bør du allerede har denne funksjonen defintionfunction onStep (evt: Hendelses): void {//legge denne betinget if (key [Keyboard.RIGHT]) {character.body.SetLinearVeloctiy (ny b2Vec2 (10, 0)); }}

Prøv å teste filmen og treffe riktig tast. Tegnet stivt legeme skal flyte til høyre på skjermen. La oss legge til kode for en venstre tast, legge til følgende kode inni onStep () -funksjonen:
//legge dette: if (key [Keyboard.LEFT]) {character.body.SetLinearVeloctiy (ny b2Vec2 (-10, 0 )); }

Det kan være lurt å prøve å rote rundt med x- og y-verdiene til b2Vec2 å få en følelse for hvordan det fungerer.

Dette er ganske fin, men bevegelsen er ganske robot. Det er et par ting vi kan gjøre for å gjøre disse nøkkelkontroller jobbe litt hyggeligere. Det første vi kan gjøre er å bare organisatorisk. Det er ikke veldig praktisk eller fleksible for å stadig skape nye b2Vec2 tilfeller, så la oss legge til en variabel for å arbeide med karakterens lineære hastighet. Legg denne variabelen definisjonen til koden:
//du allerede har thisvar karakter: QuickObject; //legge denne linevar charVel: b2Vec2 = new b2Vec2 ();

Hvis du ikke passere noe til b2Vec2 konstruktør den x og y egenskaper standard til 0. Deretter endre din onStep () -funksjonen til å se slik ut:
funksjonen onStep (evt: Hendelses): void {charVel = character.body.GetLinearVelocity (); if (key [Keyboard.RIGHT]) {charVel.x + = 0,8; character.body.SetLinearVelocity (charVel); } If (key [Keyboard.LEFT]) {charVel.x - = 0,8; character.body.SetLinearVelocity (charVel); } If (key [Keyboard.UP]) {charVel.y = -10; character.body.SetLinearVelocity (charVel); } If (key [Keyboard.DOWN]) {charVel.y = 0,8; character.body.SetLinearVelocity (charVel); }}

Hvis du teste farten du vil legge merke til at de viktigste kontrollene for karakteren har bedret seg betraktelig.

I begynnelsen av onStep () -funksjonen vi kaller GetLInearVelocity () -metoden. Vi gjør dette slik at vi ikke tvinge lineær hastighet for å endre brått ved å tilbakestille alle verdiene. I stedet leser vi den lineære hastighet og endre i henhold til keyboard input. Når vi ønsker å flytte til høyre eller venstre vi bare endre x eiendommen litt (med 0,8 meter). Når vi beveger oss opp, vi trenger litt mer kraft på grunn av tyngdekraften, så vi endre y eiendom charVel ved -10. Når vi beveger oss ned, er tyngdekraften jobber i vår favør, slik at vi kan bare bruke 0,8 meter igjen.

På dette punktet må vi utføre en liten kode rydde opp. La oss flytte nøkkelen kontrollkoden inn i sin egen funksjon:
funksjon onStep (evt: Hendelses): void {charVel = character.body.GetLinearVelocity (); keyControls ();} funksjons keyControls (): void {if (key [Keyboard.RIGHT]) {charVel.x + = 0.8; character.body.SetLinearVelocity (charVel); } If (key [Keyboard.LEFT]) {charVel.x - = 0,8; character.body.SetLinearVelocity (charVel); } If (key [Keyboard.UP]) {charVel.y = -10; character.body.SetLinearVelocity (charVel); } If (key [Keyboard.DOWN]) {charVel.y = 0,8; character.body.SetLinearVelocity (charVel); }}

Hvis du føler organisert du kan bryte opp -10 og 0,8 verdier i variabler. For enkelheten i denne opplæringen vil jeg la det ut, men gjerne gjøre det hvis du vil.

Som nevnt før, er det en hel haug med andre metoder i b2Body klassen. Det kan være lurt å ta noen minutter og leke seg med noen av de andre. De er alle ganske intuitivt - noen av dem vil bli dekket i del tre av denne opplæringen serien



Trinn 14:. QuickObject x og y Properties

Det er ganske vanlig å trenge å tvinge en stiv kropp for å hoppe fra ett sted til et annet. Du kan gjøre dette ved hjelp av QuickObject x og y egenskaper. Tilsett under teleportCharacter () -funksjonen til koden din og kaller det kontinuerlig i din onStep () -funksjonen:
... teleportCharacter ();} //slutt onStep () methodfunction teleportCharacter (): void {//begrense karakter motion if (char.x < 4 & & char.y > 12) {char.x = 8; char.y = 3; //Null ut tegnene hastighet charVel.SetZero (); char.body.SetLinearVelocity (charVel); }}

Denne koden gjør det slik at når figuren din beveger seg til nedre venstre hjørne av skjermen, teleports den tilbake til sin opprinnelige startposisjon på (8,3). Test din film og jobb deg vei til nedre venstre hjørne av skjermen for å se den i aksjon.

Dette fungerer ved å kontinuerlig sjekke x- og y-egenskapene til vår karakter stiv kropp og deretter tilbakestille dem hvis den gitte tilstanden er oppfylt. Vi også ringe SetZero () metoden b2Vec2 charVel - som navnet tilsier dette setter x og y egenskaper charVel til 0, forårsaker karakterens lineær hastighet settes til null



Trinn 15.: Legge til to plattformer

I dette neste skritt vi kommer til å bruke x, y og vinkel egenskaper QuickObjects lage noen enkle flytende plattformer. Det første vi må gjøre er å legge til noen variable definisjoner:
//du allerede har disse ... Var karakter: QuickObject; Var charVel: b2Vec2 = new b2Vec2 (); //legge disse tre nye varsvar oscillator: QuickObject; Var oscTheta: Antall = 0; Var rotator: QuickObject;

Først vil vi fylle oscillator variabel med et statisk rektangel kroppen. Legg denne koden til din buildSimulation () -funksjonen:
oscillator = sim.addBox ({x: 21, y: 8, bredde: 2,5, høyde: 0,25, fillColor: 0x009965, tetthet: 0});

Dette er ganske rett frem så langt. Vi ønsker å svinge denne plattformen opp og ned - for at vi vil bruke tak i Math.sin (). Tilsett under runOscillator () -funksjonen til koden din og kaller det kontinuerlig i din onStep () -funksjonen. Test din film
... runOscillator ();} //slutt onStep () functionfunction runOscillator (). Void {oscillator.y = 8 + 4 * Math.cos (oscTheta); oscTheta + = 0,01;}

Denne koden oscillerer y eiendom oscillatoren stiv kropp mellom 4 og 16 meter. Hvis du ikke er kjent med sinus og cosinus, kan det være lurt å lese opp litt på noen grunnleggende trigonometri. Hovedpoenget med dette eksemplet er at vi er i stand til å bruke en enkel ligning å endre y tilhører en stiv kropp.

Neste vi skal legge vår rotator plattform. Kopier denne koden på din buildSimulation () -funksjonen:
rotator = sim.addBox ({x: 16, y: 8, bredde: 3, høyde: 0,3, fillColor: 0x009965, tetthet: 0});

Ingenting spesielt som skjer her, vi har bare plassert denne plattformen slik at den ikke forstyrrer andre deler av vår simulering. Nå må det dreie - vil vi legge til en funksjon som heter runRotator () for å gjøre nettopp det:
... runRotator ();} //end of onStep () functionfunction runRotator (): void {rotator.angle + = 0,02;}

Gå videre og teste filmen. Ta en liten stund å flytte stive legemer og på plattformene.

Mens teste har du kanskje lagt merke til at stive legemer kan falle gjennom oscillerende plattformen. Hvis du ikke merke til dette, ta noen stive kroppen med unntak av karakter og plassere den på oscillerende plattformen. Du vil merke at etter en liten stund det faller gjennom oscillerende plattform som dette:

Dette skjer fordi kroppen sitter på oscillerende plattformen har sovnet og Box2D har sluttet å sjekke for kollisjoner på det. Den enkle løsningen er å sette allowSleep param til false på noen stive kropp som kanskje trenger å sitte på oscillerende plattformen. Dette fungerer fint, men er ikke veldig effektivt. En mer elegant løsning ville være om vi kunne fortelle om en kollisjon ble forekommende på oscillerende plattformen og sørge for at ting det er å kollidere med ikke sovne. Dette er mulig ved hjelp av noe som kalles kontaktpunkter. Vi dekker kontaktpunkter i del 3 av denne opplæringen, men hvis du er nysgjerrig kan du se noen eksempler på dem her



Trinn 16:. Brukerdata Eiendom

I Box2D , stive kropper har en egenskap som kalles brukerdata. Dette er bare en utypet variabel beregnet for bruk med egendefinert informasjon om et gitt stiv kropp.

QuickBox2D fylles brukerdata eiendommen med en Displayobject. Så, hvis du ønsker å legge til en MouseEvent til huden av en QuickObject, eller hvis du ønsker å trekke noen ekstra grafikk i en QuickObject hjelp av grafikk eiendom, må du bruke Userdata eiendommen. Vi får se hvordan du gjør begge disse tingene i dette trinnet. Begynn med å definere en variabel kalt shootBox med alle andre variabler:
//du allerede har disse: var oscTheta: Antall = 0; Var rotator: QuickObject; //legge thisvar shootBox: QuickObject;

Nå er vi ' ll skape shootBox og tegne en X inni den. Legg til følgende kode til din buildSimulation () -funksjonen og teste filmen:
shootBox = sim.addBox ({x: 24, y: 17, bredde: 1,5, høyde: 1,5}); //Tegner en X i shootBox userData.graphics shootBox.userData.graphics.lineStyle (0, 0xFFFFFF, 0,5); shootBox.userData.graphics.moveTo (-20, -20); shootBox.userData.graphics.lineTo (20, 20); shootBox.userData.graphics.moveTo (20, -20); shootBox.userData.graphics.lineTo (-20, 20);

Dette vil fungere på samme måte hvis du bruker tilpassede skins

Legge MouseEvents fungerer på akkurat samme måte.. La oss lage en enkel lytteren funksjon for bruk med en MouseEvent, legge denne funksjonen til din kode:
funksjon onShootBoxClick (evt: MouseEvent): void {var currLinearVec: b2Vec2 = shootBox.body.GetLinearVelocity (); currLinearVec.x - = 15; currLinearVec.y - = 15;