Komme Varmere: Smart Sikter Med Heat

Getting Varmere: Smart Sikter Med varmesøkende missiler
Del
Del
3
Del
Cyber ​​Monday Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

I forrige tutorial hadde vi en målsøkende rakett jage etter et enkelt mål. Denne veiledningen vil vise deg hvordan du kan konvertere homing missiler til varmesøkende missiler til flere mål.


Hvis du ikke har lest den første Homing Missile opplæringen, kan du laste ned denne .zip fil, som inneholder kildekoden vi skal starte med på denne opplæringen



Endelig resultat Forhåndsvisning

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



Trinn 1: Endre Cannon Grafisk

Den eneste filmklipp i Bibliotek vi må endre er Cannon
, siden vi skal gjøre det sikte på det nærmeste målet før skyting. Husk at 0 ° av rotasjon
betyr som peker til høyre, så gjør den grafiske tilsvar



Trinn 2:. Erklærer Avstand Variabler for Cannon

Jeg er m kommer til å gjenbruke targetX Hotell og targetY
variabler for å beregne avstanden på kanonen fra målet, så jeg skal erklære dem i begynnelsen av klassen i stedet for inne i playGame
funksjon, samt en ny variabel til å lagre den beregnede distanse:
private Var rakett: Missile = new Missile (); privat Var hastighet: int = 15; privat Var kanon: kanon = new Cannon ( ); privat Var missileOut: Boolean = false; privat Var letthet: int = 10; privat Var target: Target = new Target (); privat Var etasje: int = 385; privat Var Vekt: Number = 0,5; privat Var targetVY: Antall = 0; //Nåværende vertikal hastighet av targetprivate Var avstand: int; private Var targetX: int; private Var targetY: int;

targetX Kjøpe og targetY
variabler vil bli allerede erklært for playGame
funksjon:
privat 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 {targetX = target.x - missile.x; targetY = 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; }}



Trinn 3: Gjør Cannon Point mot målet

Tidligere i playGame
funksjon var vi bare interessert i å vite om missilet var ute for å ta vare på sin rotasjon og bevegelse. Nå må vi først vite om missilet ikke har blitt skutt ennå og oppdatere kanonen rotasjon
privat funksjon playGame (hendelse: Hendelse):. Void {if (! MissileOut) {targetX = target.x - cannon.x; targetY = target.y - cannon.y; cannon.rotation = Math.atan2 (targetY, targetX) * 180 /Math.PI; } Else {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 {targetX = target.x - missile.x; targetY = 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; }}

Nå kanonen roterer i forhold til målets posisjon



Trinn 4:.. Match Missile rotasjon med Cannons

kanon roterer, men missilet holder å bli skutt opp. Erstatte hardkodet rotasjon med kanonen sin nåværende posisjon i øyeblikket missilet blir skutt
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 = cannon.rotation; }}

Nå missilet vil se ut som det er faktisk kommer ut av kanonen



Trinn 5:. Mer enn ett mål

Akkurat nå homing rakett er program for å gå etter ett mål, men hva hvis vi har flere mål? Hvordan vil det bestemme hvilken du skal gå etter?

Først, la oss bestemme hvor mange mål vil det være, så får vi sette hvert mål i en Array. I dette eksempelet jeg kommer til å si at det er 2 mål, og jeg skal gi hvert mål en tilfeldig posisjon på skjermen
privat Var målet. Target, private Var etasje: int = 385; privat Var Vekt: Number = 0.5; privat Var targetVY: Antall = 0; //Nåværende vertikal hastighet av targetprivate Var avstand: int; private Var targetX: int; private Var targetY: int; private Var numTargets: int = 2; private Var målene: Array = [ ,,,0],]; offentlig funksjon main () {addChild (kanon); cannon.x = 50; cannon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, skyte); for (var i: int = 0; i < numTargets; i ++) {target = new Target (); addChild (mål); target.x = Math.random () * 600; target.y = Math.random () * 400; targets.push (mål); }}

Nå har vi mer enn ett mål på skjermen.

Missilet er fortsatt bare erkjenne eksistensen av ett mål. Vi skal fikse det neste



Trinn 6:. Søke Nærmest Target

Vi har missilet søker på målrette
variabel, så la oss sjekke målene Array og se hvilken som er nærmere. target
variabelen skal registrere den nærmeste på begynnelsen av playGame
funksjon
privat funksjon playGame (hendelse: Hendelse):. Void {for (var i: int = 0; i < targets.length; i ++) {targetX = mål [i] .x - missile.x; targetY = mål [i] .Y - missile.y; Var dist: int = Math.sqrt (targetX * targetX + targetY * targetY); //avstanden fra ett punkt til et annet i en 2D plass. hvis (i == 0 || dist < avstand) {avstand = dist; target = mål [i]; }}

På dette punktet nærmest målet er den eneste bevegelse, men missilet er anerkjenne eksistensen av begge:



Trinn 7: Fest Cannon mål

Du kanskje lagt merke til at mens missilet ikke søker den forventede mål, kanonen er fast peker på det samme målet, uansett om det er nærmere eller lenger enn den andre. Avstanden er satt i forhold til missilet posisjon, så hvis det er ingen rakett på scenen vi trenger å oppdatere sin posisjon for å matche kanon sin slik at den alltid vet hvilken som er nærmere
privat funksjon playGame (hendelse: Hendelse).: void {for (var i: int = 0; i < targets.length; i ++) {targetX = mål [i] .x - missile.x; targetY = mål [i] .Y - missile.y; Var dist: int = Math.sqrt (targetX * targetX + targetY * targetY); hvis (i == 0 || dist < avstand) {avstand = dist; target = mål [i]; }} If (missileOut!) {Missile.x = cannon.x; missile.y = cannon.y; targetX = target.x - cannon.x; targetY = target.y - cannon.y; cannon.rotation = Math.atan2 (targetY, targetX) * 180 /Math.PI; }

Nå kanonen vil alltid sikte på det nærmeste målet



Trinn 8:. Flytt Cannon

Før missilet er skutt, kanonen er allerede peker til nærmeste mål, og vil endre retning når beveget nærmere den andre målet. La oss legge til et par linjer å plassere kanonen med musepekeren
privat funksjon playGame (hendelse: Hendelse):. Void {cannon.x = mouseX; . cannon.y = mousey;

Nå kan du flytte kanonen fritt



Trinn 9: Target Hit, Target Destroyed

For å gjøre ting mer dynamisk her, jeg er kommer til å flytte et mål etter å ha blitt truffet av en rakett, eller erstatte den med en ny en
, og la en Eksplosjon
eksempel på sin plass.
if (missile.hitTestObject ( target)) {var eksplosjon: Eksplosjons = new Explosion (); addChild (eksplosjon); explosion.x = missile.x; explosion.y = missile.y; removeChild (rakett); missileOut = false; eksplosjon = new Explosion (); addChild (eksplosjon); explosion.x = target.x; explosion.y = target.y; explosion.scaleX = explosion.scaleY = 1,5; target.x = Math.random () * 600;}

Dette er hva du får:



Trinn 10: Multiple Missiles

Vi har gjort flere mål, så Nå kan vi lage flere raketter på samme måte. Forskjellen her er at alle raketter må være i bevegelse hele tiden før de treffer, og vi er faktisk kommer til å fjerne de som allerede har eksplodert, så vi trenger å endre noen få linjer med vår kode for at dette skal fungere. Først vil vi trenge en Array for rakettene
private Var raketter. Array = [];

Deretter må vi sørge for at alle rakettene oppføre seg ordentlig:
privat funksjon playGame (event: Hendelses ): void {cannon.x = mouseX; cannon.y = mousey; for (var i: int = 0; I < targets.length; i ++) {targetX = mål [i] .x - missile.x; targetY = mål [i] .Y - missile.y; Var dist: int = Math.sqrt (targetX * targetX + targetY * targetY); hvis (i == 0 || dist < avstand) {avstand = dist; target = mål [i]; }} If (missileOut!) {Missile.x = cannon.x; missile.y = cannon.y; targetX = target.x - cannon.x; targetY = target.y - cannon.y; cannon.rotation = Math.atan2 (targetY, targetX) * 180 /Math.PI; } Else {for (i = 0; i < missiles.length; i ++) //hver rakett må være i bevegelse {rakett = raketter [i]; if (missile.hitTestObject (mål)) {var eksplosjon: Eksplosjons = new Explosion (); addChild (eksplosjon); explosion.x = missile.x; explosion.y = missile.y; removeChild (rakett); missiles.splice (i, 1); //ut av Array if (missiles.length < 1) //bare dersom ingen missilene går ut i det hele tatt missileOut = false; eksplosjon = new Explosion (); addChild (eksplosjon); explosion.x = target.x; explosion.y = target.y; explosion.scaleX = explosion.scaleY = 1,5; target.x = Math.random () * 600; } Else {targetX = target.x - missile.x; targetY = 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; }} privat funksjon shoot (event: MouseEvent): void {rakett = new Missile (); missiles.push (rakett); //inn i Array addChild (rakett); swapChildren (rakett, kanon); //missilet vil komme ut fra bak kanonen missileOut = true; missile.x = cannon.x; missile.y = cannon.y; missile.rotation = cannon.rotation;}

Nå når et mål er ødelagt, vil rakettene søke det neste målet

På dette punktet alle rakettene jakter etter samme mål.. For å gjøre hver rakett søker sitt eget mål, ville det være bedre å lage en egen klasse for rakettene som du bestemmer det nærmeste mål individuelt



Trinn 11:. Lag en Crosshair

På dette punktet du allerede har forstått de viktigste ideen om denne opplæringen, men la oss innse det, en fiende vil ikke flytte avhengig bare på sin avstand til deg eller dine raketter. Du kan bruke en annen indikator, for eksempel et trådkors. Gjør det til en filmklipp og eksportere den til Action



Trinn 12:. Bruk Crosshair

Nå vil det være åpenbart for alle som målet er rettet mot. Bare legg en forekomst av Crosshair
Movie Clip
privat Var trådkors. Crosshair = new Crosshair (); offentlig funksjon main () {addChild (kanon); cannon.x = 50; cannon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, skyte); for (var i: int = 0; i < numTargets; i ++) {target = new Target (); addChild (mål); target.x = Math.random () * 600; target.y = Math.random () * 400; targets.push (mål); } AddChild (trådkors);}

Deretter plasserer den på target
's posisjon som den siste instruksjon i playGame
funksjon
targetVY + = gravitasjon.; target.y + = targetVY; if (target.y > etasje) {target.y = gulvet; targetVY = -18; } Crosshair.x = target.x; crosshair.y = target.y;}

Du vil få et trådkors markerer nærmest målets posisjon



Trinn 13: Flytt Alle Targets

Husk hva jeg sa om. rakettene? Det samme gjelder de målene: De vil se bedre ut i sin egen klasse med et sett med instruksjoner av sine egne. Dette er bare en rask eksempel, men i spillet jeg ikke anbefale koding alle objektene i Hovedanmeldelser klasse. Jo mer komplekse spillet ditt er, jo mindre ting du vil kode inne i Hoved
klasse.

Målene er allerede i en Array, som allerede er sjekket inn en for
loop, så jeg skal flytte de spretter instruksjoner inne i for
loop, slik at alle målene, uansett hvor mange vil flytte den samme hele tiden.
privat funksjon playGame ( hendelse: Hendelse): void {cannon.x = mouseX; cannon.y = mousey; targetVY + = tyngdekraft; for (var i: int = 0; I < targets.length; i ++) {targetX = mål [i] .x - missile.x; targetY = mål [i] .Y - missile.y; Var dist: int = Math.sqrt (targetX * targetX + targetY * targetY); hvis (i == 0 || dist < avstand) {avstand = dist; target = mål [i]; } Mål [i] .Y + = targetVY; if (mål [i] .Y > etasje) mål [i] .Y = gulvet; } If (target.y > = etasje) targetVY = -18; if (missileOut!) {missile.x = cannon.x; missile.y = cannon.y; targetX = target.x - cannon.x; targetY = target.y - cannon.y; cannon.rotation = Math.atan2 (targetY, targetX) * 180 /Math.PI; } Else {for (i = 0; i < missiles.length; i ++) {rakett = raketter [i]; if (missile.hitTestObject (mål)) {var eksplosjon: Eksplosjons = new Explosion (); addChild (eksplosjon); explosion.x = missile.x; explosion.y = missile.y; removeChild (rakett); missiles.splice (i, 1); if (missiles.length < 1) missileOut = false; eksplosjon = new Explosion (); addChild (eksplosjon); explosion.x = target.x; explosion.y = target.y; explosion.scaleX = explosion.scaleY = 1,5; target.x = Math.random () * 600; } Else {targetX = target.x - missile.x; targetY = 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; }}} Crosshair.x = target.x; crosshair.y = target.y;}

Ta en titt:



Konklusjon

målsøkende raketter, varmesøkende raketter, begge er en morsom og nyttig våpen å ha rundt i et skytespill eller kanskje en annen type app. Denne veiledningen viser et eksempel på bruken og algoritmen for å gjøre det, men for beste praksis det anbefales at du har egne klasser for raketter og målene, med mindre din app er så enkel og kort som denne.
< p> Jeg håper du har funnet denne opplæringen nyttig. Takk for lesing!



Next Page: