Create a Plane slåssespill i Corona: Mer Gameplay 
 22 
 Del 
 en 
 Del 
 
 Dette Cyber mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av 
 Dette innlegget er en del av en serie som heter Opprett en Plane slåssespill i Corona.Create a Plane slåssespill i Corona. GameplayCreate a Plane slåssespill i Corona: Ferdigstilling GameplayWhat du skal lage 
 Innledning 
 
 I forrige tutorial av denne serien, begynte vi å implementere spillets gameplay og allerede rukket å få flyet beveger seg rundt på skjermen. I denne opplæringen, vil vi fortsette å implementere gameplay. La oss hoppe rett inn med startTimers funksjonen. 
 
 1. startTimers 
 
 Som navnet indikerer, starter startTimers funksjon tidtakerne. . Legg til følgende kode i  gamelevel.lua 
 funksjons startTimers () end 
 Påkall denne funksjonen i enterScene metoden som vist nedenfor 
 funksjon scene. EnterScene (hendelse) lokal planeSound = audio.loadStream ("planesound.mp3") planeSoundChannel = audio.play (planeSound, {sløyfer = -1}) Spilletid: addEventListener ("enterframe", gameLoop) startTimers () end 
 2. . firePlayerBullet 
 
 firePlayerBullet funksjonen lager en kule for spilleren 
 funksjon firePlayerBullet () lokal tempBullet = display.newImage ("bullet.png", (player.x + playerWidth /2) - bulletWidth, player.y-bulletHeight) table.insert (playerBullets, tempBullet); planeGroup: innsats (tempBullet) end 
 Her bruker vi Skjerm objektets newImage metode for å lage kule. Vi plasserer det på en slik måte at det er i midten av flyet på x-aksen og på toppen av flyet på y-aksen. Kulen blir deretter satt inn i playerBullets bord for senere referanse og også inn i planeGroup. 
 
 3. Ringe firePlayerBullet 
 
 Vi må ringe firePlayerBullet funksjonen jevne mellomrom for å være sikker på spillerens planet blir automatisk skyte kuler. Legg inn følgende kode i startTimers funksjonen. 
 Funksjons startTimers () firePlayerBulletTimer = timer.performWithDelay (2000, firePlayerBullet, -1) end 
 Som navnet indikerer, kaller Timer er performWithDelay metode en bestemt funksjon etter en periode tid har gått. Tiden er i millisekunder, så her er vi kalle firePlayerBullet fungere hvert sekund. Ved bestått -1 som den tredje argument, vil timeren gjenta alltid. 
 
 Hvis du teste spillet nå, bør du se at annethvert sekund en kule vises. De er imidlertid ennå ikke er i bevegelse. Vi vil ta vare på det i de neste trinnene. 
 
 4. movePlayerBullets 
 
 I movePlayerBullets, vi sløyfe gjennom playerBullets tabellen og endre y koordinat for hver kule. Vi først sjekke at den playerBullets tabellen har kuler i den. Den # før playerBullets kalles  lengde 
 operatør og den returnerer lengden på objektet det er tilkalt. Det er nyttig å vite at # operatør fungerer også på strenger 
 funksjons movePlayerBullets () if (#playerBullets > 0). Deretter for i = 1, # playerBullets gjøre playerBullets [i]. y = playerBullets [i] .Y - 7 slutten Sluttslutt 
 Vi trenger å påberope movePlayerBullets i gameLoop funksjon som vist nedenfor 
 funksjon gameLoop () --SNIP-- numberOfTicks = numberOfTicks + 1 movePlayer () movePlayerBullets (. ) end 
 5. checkPlayerBulletsOutOfBounds 
 
 Når en kule går off-skjermen, er det ikke lenger relevant til spillet. Men de er fortsatt en del av playerBullets bordet og fortsette å bevege seg som alle andre kule i tabellen. Dette er en sløsing med ressurser, og hvis spillet skulle gå på i svært lang tid, vil det resultere i hundrevis eller tusenvis av ubrukte gjenstander. 
 
 For å overvinne dette, overvåker vi kulene, og når de flytte off-screen, fjerner vi dem fra playerBullets bordet samt fra fra displayet. Ta en titt på gjennomføringen av checkPlayerBulletsOutOfBounds 
 funksjons checkPlayerBulletsOutOfBounds () if (#playerBullets > 0). Deretter for i = # playerBullets, 1, -1 gjøre hvis (playerBullets [i] .Y < -18) deretter playerBullets [i]: removeSelf () playerBullets [i] = null table.remove (playerBullets, i) end end Sluttslutt 
 Det er viktig å merke seg at vi er looping gjennom playerBullets tabellen i baklengs. Hvis vi sløyfe gjennom tabellen fremover, da, når vi fjerner en av kulene, det ville kaste looping indeksen av og forårsaker en feil. Ved looping over bordet i omvendt rekkefølge, blir den siste kulen allerede behandlet. Den removeSelf metoden fjerner skjermen objektet og frigjør minnet. Som en beste praksis, bør du sette noen gjenstander til null etter ringer removeSelf. 
 
 Vi benytter denne funksjonen i gameLoop funksjonen. 
 Funksjon gameLoop () --SNIP-- movePlayer () movePlayerBullets () checkPlayerBulletsOutOfBounds () end 
 Hvis du vil se om denne funksjonen fungerer som den skal, kan du midlertidig sette en print ("Fjerne Bullet") uttalelse umiddelbart etter å sette skjermobjekt til null. 
 
 6. generateIsland 
 
 For å gjøre spillet mer interessant, genererer vi en øy hver så ofte, og flytt det ned på skjermen for å gi inntrykk av flyet flyr over øyene. . Legg inn følgende kode for generateIsland funksjon 
 funksjon generateIsland () lokal tempIsland = display.newImage ("island1.png", Math.random (0, display.contentWidth - islandWidth), - islandHeight) table.insert ( øyer, tempIsland) islandGroup: sett (tempIsland) end 
 Vi gjør bruk av newImage metoden igjen og posisjonere øya ved å sette en negativ verdi for islandHeight. For x posisjon, bruker vi Math.random metode for å generere et tall mellom 0 og skjermens contentWidth minus islandWidth. Grunnen til at vi trekker fra bredden av øya er å sørge for at øya er helt på skjermen. Hvis vi ikke ville trekke øyas bredde, ville det være en mulighet for at en del av øya ikke ville være på skjermen. 
 
 Vi må begynne en timer for å generere en øy hver så ofte. Legg til følgende tekstutdraget til startTimers funksjon vi opprettet tidligere. Som du kan se, er vi genererer en øy hver  
 fem sekunder. I neste trinn, vil vi sørge øyene flytte. 
 Funksjons startTimers () firePlayerBulletTimer = timer.performWithDelay (2000, firePlayerBullet, -1) generateIslandTimer = timer.performWithDelay (5000, generateIsland, -1) end 
 7. moveIslands 
 
 Gjennomføringen av moveIslands er nesten identisk med movePlayerBullets funksjonen. Vi sjekker om øyene tabellen inneholder noen øyer, og hvis det gjør det, vi sløyfe gjennom det og gå hver øy litt 
 funksjons moveIslands () if (#islands > 0). Deretter for i = 1 , #islands gjøre øyer [i] .Y = øyer [i] .Y + 3 slutten Sluttslutt 
 8. checkIslandsOutOfBounds 
 
 Akkurat som vi sjekke om spillerens kuler har flyttet off-screen, sjekker vi om noen av øyene hadde flyttet off-screen. Gjennomføringen av checkIslandsOutOfBounds bør derfor se kjent ut for deg. Vi sjekker om øyene y posisjon er større enn display.contentHeight og hvis det er, vet vi øya har flyttet off-screen, og kan derfor fjernes 
 funksjons checkIslandsOutOfBounds () if (#islands > 0). Deretter for I = # øyer, 1, -1 gjøre hvis (øyer [i] .Y > display.contentHeight) så øyene [i]: removeSelf () øyer [i] = null table.remove (øyer, i) end end Sluttslutt 
 9. generateFreeLife 
 
 Hver så ofte, har spilleren en sjanse til å få et fritt liv. Vi først generere et fritt liv image og hvis spilleren kolliderer med bildet de får et ekstra liv. Spilleren kan ha maksimalt seks liv 
 funksjon generateFreeLife () if (numberOfLives > = 6). Deretter tilbake end lokale Freelife = display.newImage ("newlife.png", Math.random (0, display.contentWidth - 40), 0); table.insert (freeLifes, Freelife) planeGroup: sett (Freelife) end 
 Hvis spilleren allerede har seks liv, vi gjør ingenting ved å returnere tidlig fra funksjonen. Hvis ikke, oppretter vi et nytt liv bilde og legge det til skjermen. I likhet med hvordan vi plassert øyene tidligere, setter vi bildet i en negativ y posisjon og generere en tilfeldig verdi for bildets x posisjon. Vi deretter sette den inn i freeLifes bordet for å være i stand til å referere til den senere. 
 
 Vi må kalle denne funksjonen hver så ofte. Legg til følgende tekstutdraget til startTimers funksjonen. 
 Funksjons startTimers () firePlayerBulletTimer = timer.performWithDelay (2000, firePlayerBullet, -1) generateIslandTimer = timer.performWithDelay (5000, generateIsland, -1) generateFreeLifeTimer = timer.performWithDelay (7000, generateFreeLife, - 1) end 
 10. moveFreeLives 
 
 Gjennomføringen av moveFreeLifes bør se kjent. Vi er looping gjennom freeLifes bordet og flytte hvert bilde i det 
 funksjons moveFreeLifes () if (#freeLifes > 0). Deretter for i = 1, # freeLifes gjøre freeLifes [i] .Y = freeLifes [ ,,,0],i] .Y fem slutten Sluttslutt 
 Alt vi trenger å gjøre er å ringe moveFreeLifes i gameLoop funksjonen. 
 funksjon gameLoop () --SNIP-- checkIslandsOutOfBounds () moveFreeLifes () end 
 11. checkFreeLifesOutOfBounds 
 
 Følgende kodebiten bør også se kjent ut for deg nå. Vi sjekker om noen av bildene i freeLifes tabellen har flyttet off-screen og fjerne de som har 
 funksjons checkFreeLifesOutOfBounds () if (#freeLifes > 0). Deretter for i = # freeLifes, 1, -1 do if (freeLifes [i] .Y > display.contentHeight) så freeLifes [i]: removeSelf () freeLifes [i] = null table.remove (freeLifes, i) end end end end 
 Vi kaller denne funksjonen i gameLoop funksjon. 
 funksjon gameLoop () --SNIP-- checkIslandsOutOfBounds () moveFreeLifes () checkFreeLifesOutOfBounds () end 
 12. hasCollided 
 
 Vi må være i stand til å fortelle når spill objekter kolliderer med hverandre, for eksempel spillerens flyet og de frie liv bilder, kuler og flyene, etc. Mens Corona tilbyr en meget robust fysikk motor som kan enkelt håndtere kollisjoner mellom visningsobjekter for oss, gjør dette legger litt av overhead med beregningene motoren har å gjøre hvert eneste bilde. 
 
 I forbindelse med dette spillet, vi skal bruke en enkel markeringsrammen kollisjon deteksjonssystem. Hva denne funksjonen gjør, er å sørge for at rektangler eller markeringsbokser rundt to objekter ikke overlapper hverandre. Hvis de gjør det, blir objektene kolliderer. Denne logikken er implementert i hasCollided funksjonen. 
 Funksjon hasCollided (obj1, obj2) if (obj1 == null) så return false end if (obj2 == null) så return false slutten lokal venstre = obj1.contentBounds.xMin < = obj2.contentBounds.xMin og obj1.contentBounds.xMax > = obj2.contentBounds.xMin lokal høyre = obj1.contentBounds.xMin > = obj2.contentBounds.xMin og obj1.contentBounds.xMin < = obj2.contentBounds. xMax lokal opp = obj1.contentBounds.yMin < = obj2.contentBounds.yMin og obj1.contentBounds.yMax > = obj2.contentBounds.yMin lokal ned = obj1.contentBounds.yMin > = obj2.contentBounds.yMin og obj1. contentBounds.yMin < = obj2.contentBounds.yMax avkastning (venstre eller høyre) og (opp eller ned) end 
 Jeg fant denne kodebiten på CoronaLabs nettstedet. Det fungerer veldig bra, fordi spillobjektene i spillet vårt er rektangulære. Hvis du arbeider med objekt som ikke er rektangulære, så du bedre dra nytte av Corona fysikkmotor som sin dueller er meget godt optimalisert for dette. 
 
 13. checkPlayerCollidesWithFreeLife 
 
 Vi ønsker å sjekke om spillerens fly har kollidert med et fritt liv objekt. Hvis det har, så vi belønne spilleren et fritt liv 
 funksjon checkPlayerCollidesWithFreeLife () if (#freeLifes > 0). Deretter for i = # freeLifes, 1, -1 gjøre hvis (hasCollided (freeLifes [i], spiller )) så freeLifes [i]: removeSelf () freeLifes [i] = null table.remove (freeLifes, i) numberOfLives = numberOfLives + 1 hideLives () showLives () end end Sluttslutt 
 I checkPlayerCollidesWithFreeLife funksjon, vi sløyfe gjennom den freeLives bordet bakover for samme grunn jeg beskrev tidligere. Vi kaller hasCollided funksjon og passere i det aktuelle bildet og spillerens flyet. Hvis de to objekt kolliderer, fjerner vi det frie liv image, øke de numberOfLives variabel, og kaller hideLives og showLives funksjon 
 
 Vi benytter denne funksjonen i gameLoop funksjon 
 funksjon gameLoop ().. - SNIP-- moveFreeLifes () checkFreeLifesOutOfBounds () checkPlayerCollidesWithFreeLife () end 
 14. hideLives 
 
 hideLives funksjon looper gjennom livesImages bordet og setter isVisible tilhører hvert liv bilde til falske. 
 funksjons hideLives () for i = 1, 6 gjøre livesImages [i] .isVisible = false Sluttslutt 
 15. showLives 
 
 showLives funksjon looper gjennom livesImages bordet og setter hvert bildes isVisible eiendom til sann 
 funksjons showLives () for i = 1, numberOfLives gjøre livesImages [i] .isVisible = sant.; Sluttslutt 
 Konklusjon 
 
Dette bringer den tredje delen av denne serien til en avslutning. I neste og siste avdrag av denne serien, vil vi skape fiendtlige fly og avsluttet spillets gameplay. Takk for lesing og se deg der.

