I distribuere en tank i en isometrisk krigssone lærte du hvordan du lager et objekt for å vende pekeren og bevege seg mot et sted på klikk. I denne Quick Tip, tar vi et generelt blikk på matematikken bak det: trigonometri.
Dette er det endelige resultatet fra min tidligere opplæring. Den benytter seg av de trigonometriske prinsippene vi skal dekke i denne raske tipsen:
Flytt musen for å gjøre tårnet sikte mot det, og klikk hvor som helst for å få tanken til å kjøre til det punktet.
Enhver programmerer, spesielt noen spillprogrammerer, står overfor et behov for å flytte objekter på skjermen før eller senere. Det er en enkel oppgave hvis du trenger å flytte et objekt i en retning, for eksempel langs x- eller y-aksen. Men antar at du vil lage et objekt, følg musepekeren din, uansett hvor du beveger den, eller opprett et racerespill hvor du kontrollerer akselerasjon av en bil ved å trykke på pilknappen og bruk venstre og høyre pil til å styre.
La oss si at du trykker på høyre piltast en gang, og den legger til 10 grader i bilens rotasjonsegenskap, men du vil fortsatt at bilen skal bevege seg fremover (dvs. akselerere) når du trykker på en pil opp, selv om en bil vender mot bunnen av skjermen eller en venstre eller høyre side etc., og du vil ikke at den skal se ut som den skyver sidelengs. Så, hvordan ville du gjøre det? Det er der en liten trigonometri hjelper!
For de som er gode til matte vil det ikke være et problem, men det er mange mennesker som ikke forstår det i det hele tatt, eller er enda redd for det. Jeg vil prøve å bryte den ned så tydelig som mulig i denne Quick Tip.
La oss først huske det kartesiske koordinatsystemet. Lyd komplisert? Hvis ja, bare se på bildet nedenfor, og jeg er sikker på at det blir kjent:
Den har X- og Y-akser; Du kan tydelig se hvor X og Y er positive og negative. Når det gjelder koordinater i Flash, er situasjonen litt annerledes. Flash har også sitt koordinatsystem, men det ser ut som det kartesiske systemet på hovedet:
Det har også X- og Y-akser og Opprinnelsespunktet, den eneste forskjellen er at Y-aksen er positiv under X-aksen.
Ethvert symbol som er opprettet i Flash har sitt eget innebygde koordinatsystem. Hvis du oppretter et nytt symbol, enten det er et filmklipp eller en knapp, ser du kanskje et "registreringspunkt" -egenskap i dialogboksen for symbolopprettelse. Hva er det? Registreringspunktet er et utgangspunkt for et symbol. Poenget med at objektet vil rotere rundt hvis du endrer rotasjonsegenskapen.
Merk: Opprinnelsesstedet til scenen forekommer i venstre øverste hjørne. Dette betyr at alle poeng på scenen har positive X- og Y-koordinater.
I denne Quick Tip ser vi på de tre mest brukte trigonometriske funksjonene i Flash; Sine, Cosine og Atan2. Noen kan spørre hvordan kan vi bruke disse funksjonene i Flash? Vel, la oss se på noen praktiske eksempler, og forstå hvorfor vi trenger dem, og hvordan de kan gjøre livet enklere.
La oss beregne vinkelen mellom to punkter. Opprett en ny Flash-fil (ActionScript 3.0). Velg den første rammen av tidslinjen og trykk F9 for å åpne et Handlingspanel.
La oss nå gjøre noe enkelt på dette punktet. Skriv bare dette inn i handlingspanelet:
stage.addEventListener (MouseEvent.CLICK, calculateAngle) funksjonen calculateAngle (e: MouseEvent): void trace ("scene X" + e.stageX); spor ("stadium Y" + e.stageY)
Dette gir oss posisjonen til musepekeren hver gang vi klikker scenen. Ikke akkurat fascinerende, er det?
Ok, nå antar du at du vil "fortelle" noe objekt musepekerenes koordinater i forhold til dette objektet, så vis det retningen for å reise for å nå pointerens posisjon.
Lukk handlingspanelet og gå til Sett inn> Nytt symbol eller bare trykk Ctrl + F8.
Gi det noe navn (eller la et standardnavn) og trykk OK. Det lille krysset i midten av skjermen er registreringsstedet til symbolet eller opprinnelsesstedet. Dette vil være objektets X- og Y-posisjoner. Ta nå det ovale verktøyet (O-tasten) og tegne en sirkel (med Shift-tasten trykket) hvor som helst på skjermen.
Klikk på sirkelen for å velge den og gå til Egenskaper-panelet> Plassering og størrelse. For W (bredde) type i 20, den samme for H (høyde) og for X og Y posisjon type (-10). Dette vil gjøre sirkelen 20x20 px og presis sentrere den til registreringspunktet. Gå nå av symbolredigeringsmodusen (Klikk på Scene 1 ovenfor), ta dette symbolet i biblioteket ditt og bare dra det til scenen (hvor som helst, vi får den posisjonen dynamisk senere). Når objektet ditt er på scenen, gi det et forekomstnavn på mCircle
.
Nå ønsker vi å beregne retningen fra sirkelens Y- og X-posisjon til musepekerenes Y- og X-posisjon. Den røde linjen i bildet nedenfor er den retningen vi trenger å vite. Det kan bli funnet ved å bruke en standard Math.atan2 ()
funksjon.
La oss gjøre det nå. Slett "spor" -uttrykkene fra koden og opprett en ny variabel i stedet. Spor deretter denne variabelen for å se hva du får:
stage.addEventListener (MouseEvent.CLICK, calculateAngle); var minAtan2: Nummer; funksjon calculateAngle (e: MouseEvent): void myAtan2 = Math.atan2 (e.stageY - mCircle.y, e.stageX - mCircle.x); spor (myAtan2);
Noter det e.stageY - mCircle.y
er den vertikal avstand fra musen til sirkelen, og e.stageX - mCircle.x
er den horisontal avstand.
Du får disse tallene i utgangspanelet:
-2.419017353128333 3.0118660246925346 2.5704959452340326 1.6726588917423932 1.0238847495551058 0.21368467849101092
Dette er de relative vinklene (mellom X-akselinjen og den røde linjen) i radianer. Hvorfor ikke grader? Vel, Flash bruker radianer til å beregne sinus og cosinus, men hvis du vil vite hva disse vinklene er i grader, kan du alltid multiplisere "myAtan2" med 180 og dele det med Math.PI
. Som dette:
spor (myAtan2 * 180 / Math.PI) // gir deg vinkelen i grader;
Redaktør: Som en ekstra ressurs, her er et stort sett med funksjoner for grad / radian-konvertering. Den er lagret som en utdrag på snipplr.com, det siste medlemmet av Envato's nettverk!
Som vi vet vinkelen mellom to punkter, kan vi nå beregne hvor mange piksler vi må legge til sirkelens X- og Y-egenskaper hver ramme til den når klikkpunktet. La oss undersøke hva vi trenger å vite her:
Den blå linjen er vinkelen Cosine, og den oransje er vinkelen sinus. Med andre ord,
Snarere enn å forklare hvordan sinus og cosinus arbeid, vil jeg demonstrere hvordan man bruker dem med noen praktiske eksempler. Blant å si er sinus og cosinus forholdet mellom Y og X i vår vinkel.
Tenk vinkelen mellom to objekter er 45 grader. I dette tilfellet er forholdet mellom sinus og cosinus 1: 1 (se bildet nedenfor), noe som betyr at vi må øke X- og Y-egenskapene til sirkelen vår med samme mengde hver ramme for å nå målet. For eksempel må du legge til 5 piksler til X og 5 piksler til Y hver ramme.
I dette diagrammet har vinkelen endret seg, og forholdet mellom sinus og cosinus har endret seg også. Det er omtrent 1: 2 nå.
I dette tilfellet må vi legge til dobbelt så mange piksler til sirkelens X-egenskap enn til Y. E.g. X + = 10, Y + = 5;
Du vil sannsynligvis spørre hvorfor vi trenger sinus og cosinus hvis vi allerede vet klikkpunktets koordinater - vi kan bare flytte vår mCircle
til dem med en gang? Vel, du kunne ha gjort det på denne måten hvis du ville at sirkelen din (eller et annet objekt) skulle "teleportere" på et klikkpunktskoordinater så snart klikk oppstår. Men hva om du vil at den skal bevege seg gradvis i retning av klikket? For å gjøre dette må du legge til en bestemt mengde piksler til sine X- og Y-egenskaper, for eksempel hver ramme eller hvert sekund.
La oss nå beregne hvor mange piksler vi skal legge til i sine X- og Y-egenskaper basert på sinus og cosinus av vinkelen mellom objektet vårt og et klikkpunkt. Husk, Flash vet vinkelen mellom dem fra denne operasjonen:
myAtan2 = Math.atan2 (e.stageY - mCircle.y, e.stageX - mCircle.x);
For dette formålet bør vi oppdatere koden litt.
stage.addEventListener (MouseEvent.CLICK, calculateAngle); // 2 er den maksimale mengden piksler som skal legges til objektene X og Y egenskaper hver ramme // du kan bruke hvilket som helst nummer du liker var moveAmount: Number = 2; var minAtan2: Nummer; var mouseClickX: Number; var mouseClickY: Nummer; funksjon calculateAngle (e: MouseEvent): void mouseClickX = e.stageX; mouseClickY = e.stageY; myAtan2 = Math.atan2 (mouseClickY - mCircle.y, mouseClickX - mCircle.x); addEventListener (Event.ENTER_FRAME, moveTheCircle); funksjon moveTheCircle (e: Event): void mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount;
Legg merke til hva jeg har gjort her: Jeg forfremmet alle variablene mine utenfor noen funksjoner, for nå har jeg mer enn en funksjon, og jeg vil ha disse variablene til å være tilgjengelige fra alle funksjoner.
var moveAmount: Number = 2; var minAtan2: Nummer; var mouseClickX: Number; var mouseClickY: Nummer;
Scenen har en hendelseslytter for museklikk, så når klikket oppstår, må metoden calculateAngle ()
blir kalt og de neste variablene er instantiated:
mouseClickX = e.stageX; mouseClickY = e.stageY; myAtan2 = Math.atan2 (mouseClickY - mCircle.y, mouseClickX - mCircle.x);
Denne funksjonen legger også til en hendelselytter for å legge inn ramme til scenen, som kaller moveTheCircle ()
Metode hver ramme.
addEventListener (Event.ENTER_FRAME, moveTheCircle);
La oss nå bryte ned vår moveTheCircle ()
metoden selv. For nå gjør det bare to ting:
mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount;
Som du ser, beregner den første linjen hvor mange piksler den skal legge til X-egenskapen, og den andre avtaler med Y. La meg forklare. Math.cos finner cosinus (x-egenskapen) av "myAtan2" -vinkelen, Math.sin gjør det samme med sin sinus (y-egenskap). Hvis vår myAtan2-vinkel er omtrent 0,785 radianer (45 grader), vil cosinus og sinus begge være lik ca 0,707 ... Du kan bruke en kalkulator for å sjekke det ut.
En enkel beregning viser hvor mange piksler koden ovenfor vil legge til i objektets X- og Y-egenskaper hvis vinkelen er 45 grader.
Cosine (45 grader) = 0,707 * 2 = 1,414; Sine (45 grader) = 0,707 * 2 = 1,414; så koden vil utarbeide disse resultatene: mCircle.x + = 1.414 piksler; mCircle.y + = 1.414 piksler;
Hvis vinkelen er for eksempel. 60 grader vil resultatene bli slik:
Cosine (60 grader) = 0,5 * 2 = 1; Sine (60 grader) = 0,866 * 2 = 1,732; Og koden ville fungere på denne måten: mCircle.x + = 1 pixel; mCircle.y + = 1.732 piksler;
Vel, vi er nesten ferdige. Men det er fortsatt et lite problem med koden vår. Du har kanskje lagt merke til at vårt objekt aldri stopper, selv om det når klikkpunktet, fortsetter det å bevege seg. Vi kan løse dette problemet veldig enkelt. Når vårt objekt beveger seg mot klikkpunktet, avkortes avstanden mellom dem slik at absolutte Verdien av avstanden reduseres også. Vi kan holde styr på det slik:
spor (Math.abs (mCircle.x - mouseClickX)); spor (Math.abs (mCircle.y - mouseClickY));
(Math.abs ()
gjør negative tall til positive ved å bare multiplisere dem med -1. Det gjør ikke noe til tall som allerede er positive.)
Du trenger ikke å legge til denne sporerklæringen til koden din, jeg har satt den her bare for å vise deg hvordan du kan se absoluttverdien. I dette tilfellet er begge absolutte verdier mindre enn 3 når objektet når klikkpunktet. Så det vi trenger nå er å legge til en hvis
uttalelse inne i vår moveTheCircle ()
funksjon.
funksjon moveTheCircle (e: Event): void mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount; // Sjekk om de horisontale og vertikale avstandene fra sirkelen til musepunktet er svært nær hvis (Math.abs (mCircle.x - mouseClickX) < 3 && Math.abs(mCircle.y - mouseClickY) < 3) removeEventListener(Event.ENTER_FRAME, moveTheCircle);
Når den absolutte verdien kommer under 3, blir innrammerlisten fjernet. Vi må sjekke både X og Ys absolutte verdier fordi en av dem kan nå 3 selv når den andre ikke har det. Dette betyr at objekter kan stoppe slik:
Bildet over viser versjonen der bare Xs absolutte verdi er merket. X-avstandens absolutte verdi er allerede mindre enn 3, så det stoppet å betale oppmerksomhet til Y-verdien.
Vel, det er det. Jeg håper denne Quick Tip vil hjelpe deg å forstå noen trigonometri som brukes i Flash-utvikling :)