Hit Target med et dødelig Homing Missile

Hit Target med et dødelig Homing Missile
en
Del
Del
Del

Dette Cyber ​​Monday Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av
Dette innlegget er en del av en serie som heter You Do The Math.Gravity i ActionCircular Motion i AS3. Gjør One Moving Object Orbit annen

Denne opplæringen vil veilede
deg gjennom legge dødelige nøyaktige målsøkende raketter til arsenal av din neste kamp.




Endelig resultat Forhåndsvisning

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



Trinn 1: Sett opp FLA Document

Opprett en ny Flash-dokument sett for Actionscript 3.0. Jeg skal bruke dimensjonene på 600x400, og en bildefrekvens på 30 FPS. Lagre filen med et navn du velger



Trinn 2:. Opprett et dokument Class

I tillegg til FLA, trenger vi også å opprette et dokument klasse. Opprett en ny Actionscript-fil, og legg denne koden:
pakke {import flash.display.Sprite; public class Hoved strekker Sprite {offentlig funksjon main () {}}}

Lagre denne filen i samme katalog som vår FLA. Name it Main.as



Trinn 3:. Link Hovedanmeldelser Class med FLA

For å kompilere koden fra Hovedanmeldelser klasse, trenger vi å koble den med FLA. På Egenskaper
panelet til FLA, ved siden av Class
, skriv inn navnet på dokumentet klassen, i dette tilfellet, Hoved
.

Deretter lagrer du endringene på FLA



Trinn 4:. Tegn en Missile

Vi trenger en rakett grafisk som skal vises når du fotograferer. Du kan importere en bitmap eller tegne en figur der på Flash. Jeg skal bruke en liten form på dette eksemplet.

Hva er viktig her er at du må gjøre missilet punkt rett til høyre, siden det er opprinnelsen punkt for rotasjon. Så 0 ° betyr peker rett mot høyre, -90 ° betyr oppover, 90 ° betyr nedover, og 180 ° punktene til venstre. Senere må vi rotere missilet i henhold til sin retning



Trinn 5:. Lag en MovieClip for Missile

Når du har missilet grafikk, velger du den og trykker F8
å skape et filmklipp. Name it "Missile", sørg for at den Registrering Point
er i sentrum, og kryss av "Export for Action" boksen.

Du vil ende opp med en Missile MovieClip i Bibliotek.

Hvis du har en Missile eksempel på scenen, må du slette den. Vi skal legge den Missile MovieClip med kode



Trinn 6:. Mål

Det første en målsøkende rakett trenger å vite er hvor målet befinner seg. Vi kommer til å angi rotasjonen av missilet i henhold til posisjonen av den første markøren. La oss jobbe med enterframe
hendelse for en konstant rotasjon oppdatering.

Legg til en Missile
eksempel på scenen, jeg plassere den i sentrum (300, 200 ). Deretter beregne avstanden fra missilet til musepekeren (jeg oppbevare det i variabler targetX Hotell og targetY
). Til slutt vil missilet vinkel være invers tangens for både poeng ( targetX
, targetY
). Resultatet du får vil være i radianer, men rotasjonen fungerer i grader, så du trenger å gjøre konverteringen ved å multiplisere med 180 /Pi. (For å se hvorfor, sjekk denne artikkelen.)
Import flash.events.Event; public class Hoved strekker Sprite {private Var rakett: Missile = new Missile (); offentlig funksjon main () {addChild (rakett); missile.x = 300; missile.y = 200; addEventListener (Event.ENTER_FRAME, playGame); } Private funksjon playGame (hendelse: Hendelse): void {var targetX: int = mouseX - missile.x; Var targetY: int = mousey - missile.y; missile.rotation = Math.atan2 (targetY, targetX) * 180 /Math.PI; }}

(Ikke sikker på hva Math.atan2 () er for? Sjekk ut denne artikkelen om trigonometri.

Hvis du Publiser plakater (Ctrl + Enter) dokumentet på dette punktet, bør du få noe sånt som dette:

Beveg musen nær missilet å se det rotere



Trinn 7:. Seek

Vi fikk rotasjon, nå trenger vi bevegelsen. Missilet har til å søke målet, uansett om det er en jevn eller et bevegelig mål. Det vi vil gjøre er å beregne bevegelsen i henhold til gjeldende rotasjon av missilet. La oss sette en verdi for hastighet, og gjør missilet jage etter musepekeren.

Vi har et par nye variabler for å beregne hastighet ( vx
, vy
). Når missilet peker mot høyre, er vinkelen mindre enn 90 ° og høyere enn -90 °, slik at det alltid er lavere enn den absolutte verdi av 90 °. Når den peker mot venstre , har en absolutt verdi høyere enn 90 ° sin vinkel. Dette vil avgjøre vx
i henhold til hastighet
, deretter vy
vil være forskjellen på hastighet Hotell og vx
privat Var hastighet. int = 10; offentlig funksjon main () {addChild (rakett); missile.x = 300; missile.y = 200; addEventListener (Event.ENTER_FRAME, playGame);} private funksjon playGame (hendelse: Hendelse): void {var targetX: int = mouseX - missile.x; Var targetY: int = mousey - missile.y; missile.rotation = Math.atan2 (targetY, targetX) * 180 /Math.PI; //Velocity i x er i forhold til vinkelen, når det er 90 & grader; eller -90 & grader;, vx bør være 0. Var vx: Number = fart * (90 - Math.abs (missile.rotation)) /90; Var vy: Number; //Velocity i y er forskjellen på fart og vx. if (missile.rotation < 0) vy = speed + Math.abs (VX); //Går oppover. annet vy = hastighet - Math.abs (VX); //Går nedover. missile.x + = vx; missile.y + = vy;}

Du vil få en rakett jage markøren

Du kan bruke en annen hastighet hvis du ønsker



Trinn 8: Opprett.. en Missile Launcher

Missiles kommer ikke ut av løse luften, blir de skutt ut av rakettkastere. La oss lage en MovieClip representerer en kanon (Jeg skal bruke en enkel rektangel), og gi den navnet Cannon
. Jeg kommer til å legge en Cannon
forekomst av kode, så jeg kommer til å holde scenen tom



Trinn 9:. Skyt

Nå stedet for å legge en rakett, jeg bare kommer til å legge en kanon, og en rakett vil bli lagt på kanonen posisjon når jeg klikker på scenen. . Vi skal legge en boolsk å sjekke om missilet har blitt skutt, og også en ny funksjon for å skyte etter klikket
import flash.events.MouseEvent; public class Hoved strekker Sprite {private Var rakett: Missile = new Missile (); private Var hastighet: int = 10; private Var kanon: kanon = new Cannon (); private Var missileOut: Boolean = false; //Har missilet blitt skutt? offentlig funksjon main () {addChild (kanon); cannon.x = 50; cannon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, skyte); } Private funksjon playGame (hendelse: Hendelse): void {if (missileOut) {var targetX: int = mouseX - missile.x; Var targetY: int = mousey - missile.y; missile.rotation = Math.atan2 (targetY, targetX) * 180 /Math.PI; Var vx: Number = fart * (90 - Math.abs (missile.rotation)) /90; Var vy: Number; if (missile.rotation < 0) vy = speed + Math.abs (vx); annet vy = hastighet - Math.abs (vx); missile.x + = vx; missile.y + = vy; }} Privat funksjon shoot (event: MouseEvent): void {if (! MissileOut) {addChild (rakett); swapChildren (rakett, kanon); //missilet vil komme ut fra bak kanonen missileOut = true; missile.x = cannon.x; missile.y = cannon.y; }}

Dette er hva du får:

Dette ser ikke fint. Vi må enten gjøre kanonen roterer også, eller tvinge missilet å gå oppover rett etter å ha blitt skutt. Siden alternativ 1 er den enkleste tilnærmingen, vil vi ta alternativ # 2



Trinn 10:. Mindre Precision for bedre utseende

Hvis kanonen er vertikal, vi forventer rakett lansere oppover og deretter komme på sporet mot sitt mål. Tilnærmingen jeg skal bruke for å oppnå dette er å gi missilet en startvinkel på -90 ° (peker oppover), og jevnt rotere for å komme på sporet til musepekeren. Vi vil legge til et lette
variabel for å avgjøre glatthet eller skarpheten i rotasjon. Deretter vil vi lage en annen variabel for å holde oversikt over den faktiske rotasjonen som peker rett til målet, mens missilet rotasjon vil endres i henhold til lette
vi satt ( lette
= 1 vil oppfører seg på samme måte som før, noe høyere vil få en jevnere omdreining).

Siden halvparten av rotasjons verdiene er negative, i noen tilfeller vi må regne dem mot 360 for å få den faktiske forskjell mellom målvinkelen . og missilet rotasjon
private Var letthet: int = 10; offentlig funksjon main () {addChild (kanon); cannon.x = 50; cannon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, skyte);} private funksjon playGame (hendelse: Hendelse): void {if (missileOut) {var targetX: int = mouseX - missile.x; Var targetY: int = mousey - missile.y; Var rotasjon: int = Math.atan2 (targetY, targetX) * 180 /Math.PI; if (Math.abs (rotasjon - missile.rotation) > 180) {if (rotasjon > 0 & & missile.rotation < 0) missile.rotation - = (360 - rotasjon + missile.rotation) /letthet; else if (missile.rotation > 0 & & rotasjon < 0) missile.rotation + = (360 - rotasjon + missile.rotation) /enkel; } Else if (rotasjon < missile.rotation) missile.rotation - = Math.abs (missile.rotation - rotasjon) /enkel; annet missile.rotation + = Math.abs (rotasjon - missile.rotation) /enkel; Var vx: Number = fart * (90 - Math.abs (missile.rotation)) /90; Var vy: Number; if (missile.rotation < 0) vy = speed + Math.abs (vx); annet vy = hastighet - Math.abs (vx); missile.x + = vx; missile.y + = vy; }} privat funksjon shoot (event: MouseEvent): void {if (! missileOut) {addChild (rakett); swapChildren (rakett, kanon); //missilet vil komme ut fra bak kanonen missileOut = true; missile.x = cannon.x; missile.y = cannon.y; missile.rotation = -90; //missilet vil begynne å peke oppover}}

Sjekk det ut:

Legg merke til hva som skjer når du beveger musen ut av SWF, og hvordan dette er forskjellig fra den forrige . eksempel



Trinn 11: Missile Hits, Missile eksploderer

I tillegg til Missile
filmklipp, trenger vi en eksplosjon animasjon. I mitt tilfelle, vil jeg lage en egen MovieClip med en enkel tween av en sirkel som utvides. Jeg eksportere den som Explosion
. Trykk O
å velge Oval Tool
, og hold Shift
mens du tegner det ovale for å få en sirkel.

For en bedre visuell effekt, Jeg skal sette sirkelen inne i en annen filmklipp av sine egne, og gi den en Bevel
filter for å få en mørkere farge i bunnen og en lysere farge på toppen. Deretter vil jeg gå å ramme 10 og trykk på F6
å skape en Keyframe
, høyreklikk mellom ramme 1 og 10, og skape en Classic Tween
. Tilbake på ramme 10, trykker du Q
å velge Free Transform Tool
og forstørre sirkelen.

Deretter oppretter du en annen Classic Tween
å ramme 20, vil jeg legge til en Blur
filter effekt.

Til slutt, gjør det forsvinner i en siste Classic Tween å ramme 30 med en Alpha
fargeeffekt kommer til 0 .



Trinn 12: Rydd opp scenen

Eksplosjonen animasjon må fjernes etter at den er ferdig, eller det vil sløyfe på ubestemt tid. Legg et nytt lag, og trykk på F6
på det siste bildet, og trykk deretter på F9
å åpne Handlinger
panel, og legger denne koden:
stop (); < br />parent.removeChild(this);

This vil gjøre Eksplosjons
eksempel fjerne seg etter at animasjonen er gjort



Trinn 13: eksplodere.

Nå når rakett
møter markøren, vil vi erstatte den med en Eksplosjons
eksempel. Vi trenger bare å legge til en ny betinget i playGame () -funksjonen
privat funksjon playGame (hendelse: Hendelse):. Void {if (missileOut) {if (missile.hitTestPoint (mouseX, mousey)) {var eksplosjon: Eksplosjons = new Explosion (); addChild (eksplosjon); explosion.x = missile.x; explosion.y = missile.y; removeChild (rakett); missileOut = false; } Else {var targetX: int = mouseX - missile.x; Var targetY: int = mousey - missile.y; Var rotasjon: int = Math.atan2 (targetY, targetX) * 180 /Math.PI; if (Math.abs (rotasjon - missile.rotation) > 180) {if (rotasjon > 0 & & missile.rotation < 0) missile.rotation - = (360 - rotasjon + missile.rotation) /letthet; else if (missile.rotation > 0 & & rotasjon < 0) missile.rotation + = (360 - rotasjon + missile.rotation) /enkel; } Else if (rotasjon < missile.rotation) missile.rotation - = Math.abs (missile.rotation - rotasjon) /enkel; annet missile.rotation + = Math.abs (rotasjon - missile.rotation) /enkel; Var vx: Number = fart * (90 - Math.abs (missile.rotation)) /90; Var vy: Number; if (missile.rotation < 0) vy = speed + Math.abs (vx); annet vy = hastighet - Math.abs (vx); missile.x + = vx; missile.y + = vy; }}}

Ta en titt:



Trinn 14: Noe annet å blåse opp

Chasing etter musepekeren var underholdende, men det er meningsløst i et spill; vi trenger for å lage et mål. Jeg kommer til å trekke en haug med sirkler for å danne en Target
Movie Clip



Trinn 15:. Skyte målet

Nå vil vi legge til en Target
eksempel for missilet å ha en mer konkret målsetting. Så vi vil erstatte noen referanse musepekeren for målets posisjon. Dessuten vil vi ikke være testing for en hit punkt, men et objekt
privat Var målet. Target = new Target (); offentlig funksjon main () {addChild (kanon); cannon.x = 50; cannon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, skyte); addChild (mål); target.x = 550; target.y = 50;} private funksjon playGame (hendelse: Hendelse): void {if (missileOut) {if (missile.hitTestObject (mål)) {var eksplosjon: Eksplosjons = new Explosion (); addChild (eksplosjon); explosion.x = missile.x; explosion.y = missile.y; removeChild (rakett); missileOut = false; } Else {var targetX: int = target.x - missile.x; Var targetY: int = target.y - missile.y; Var rotasjon: int = Math.atan2 (targetY, targetX) * 180 /Math.PI; if (Math.abs (rotasjon - missile.rotation) > 180) {if (rotasjon > 0 & & missile.rotation < 0) missile.rotation - = (360 - rotasjon + missile.rotation) /letthet; else if (missile.rotation > 0 & & rotasjon < 0) missile.rotation + = (360 - rotasjon + missile.rotation) /enkel; } Else if (rotasjon < missile.rotation) missile.rotation - = Math.abs (missile.rotation - rotasjon) /enkel; annet missile.rotation + = Math.abs (rotasjon - missile.rotation) /enkel; Var vx: Number = fart * (90 - Math.abs (missile.rotation)) /90; Var vy: Number; if (missile.rotation < 0) vy = speed + Math.abs (vx); annet vy = hastighet - Math.abs (vx); missile.x + = vx; missile.y + = vy; }}} Privat funksjon shoot (event: MouseEvent): void {if (! MissileOut) {addChild (rakett); swapChildren (rakett, kanon); //rakett vil komme ut fra bak kanonen missileOut = true; missile.x = cannon.x; missile.y = cannon.y; missile.rotation = -90; //missilet vil begynne å peke oppover}}

De hitTestObject () metoden faktisk bare sjekker for en overlapping mellom markeringsrammene til de to objektene (dvs. de blå boksene som vises når du klikker på et forekomst av objektet i scenen), så se opp for det; det er ikke pixel-perfekt dueller. Men det gjør jobben helt fint her

Du kan prøve å plassere målet på forskjellige steder, samt kanonen



Trinn 16:.. Moving Target
< p> Vi har allerede sett at missilet vil jage et bevegelig mål, som for eksempel musepekeren, så nå la oss gjøre det Target
eksempel flytte litt.

Dette er ikke realistisk fysikk, Jeg kommer bare til å gjøre målet sprett vertikalt. Jeg henter et referansepunkt som bakkenivå, og legge til en tyngdekraft verdi å påvirke målet. Og for å gjøre den mer dynamisk, jeg vil øke missilet hastigheten til 15.
private Var etasje: int = 385; privat Var Vekt: Number = 0,5; privat Var targetVY: Antall = 0; //Nåværende vertikal hastighet av den targetpublic funksjonen main () {addChild (kanon); cannon.x = 50; cannon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, skyte); addChild (mål); target.x = 550; target.y = 50;} private funksjon playGame (hendelse: Hendelse): void {if (missileOut) {if (missile.hitTestObject (mål)) {var eksplosjon: Eksplosjons = new Explosion (); addChild (eksplosjon); explosion.x = missile.x; explosion.y = missile.y; removeChild (rakett); missileOut = false; } Else {var targetX: int = target.x - missile.x; Var targetY: int = target.y - missile.y; Var rotasjon: int = Math.atan2 (targetY, targetX) * 180 /Math.PI; if (Math.abs (rotasjon - missile.rotation) > 180) {if (rotasjon > 0 & & missile.rotation < 0) missile.rotation - = (360 - rotasjon + missile.rotation) /letthet; else if (missile.rotation > 0 & & rotasjon < 0) missile.rotation + = (360 - rotasjon + missile.rotation) /enkel; } Else if (rotasjon < missile.rotation) missile.rotation - = Math.abs (missile.rotation - rotasjon) /enkel; annet missile.rotation + = Math.abs (rotasjon - missile.rotation) /enkel; Var vx: Number = fart * (90 - Math.abs (missile.rotation)) /90; Var vy: Number; if (missile.rotation < 0) vy = speed + Math.abs (vx); annet vy = hastighet - Math.abs (vx); missile.x + = vx; missile.y + = vy; }} TargetVY + = tyngdekraft; target.y + = targetVY; if (target.y > etasje) {target.y = gulvet; targetVY = -18; }}

Hvis du Publiser
dette nå, du bør få et bevegelig mål.



Konklusjon

Enten du ønsker en nøyaktig homing rakett, eller du foretrekker en jevn animasjon, kan du få både resultater basert på dette eksempelet. Nå har du fått et nytt våpen for å legge i arsenalet ditt, kanskje du kan prøve å lage en Worms-lignende spill, eller til og med bruke algoritmen på noe annet enn en rakett, som noen rare mygg som følger karakteren din.
< p> Jeg håper du har funnet denne opplæringen nyttig. Takk for lesing!