Porterer ActionScript-spill til iOS med Corona SDK Del 2

Denne opplæringen vil ta en titt på å overføre et Flash / Flex-spill til Corona SDK. Spesielt vil vi overføre fra ActionScript til Lua, med sluttmål å spille tidligere Flash-bare spill på iPhone. I tillegg til å demonstrere språk- og API-forskjeller, vil denne opplæringsserien også ta hensyn til maskinvarebegrensninger som skjermstørrelse og mangel på fysiske knapper på iPhone.

Denne opplæringen henter opp hvor den første begynte.

Skaper skipet

Start med å porttere syntaksen fra kildefilen "de / pixelate / flixelprimer / Ship.as" som beskrevet
i dag ett innlegg. Spesielt må du:

  • Bli kvitt pakke og klassedeklarasjoner.
  • Fjern typeerklæringer.
  • Legg til "lokal" for alle variabler.
  • Bytt de betingede brakettene med "da" og "slutt".
  • Slett alle semikolonene og kommentere alt ut.

Legg til moduldeklarasjonen øverst i filen, slik at vi kan importere filen til PlayState.
Også, gå videre og pakk alle koden sammen med en Ship () -konstruktørfunksjon. Koden din skal nå ordnes slik:

 modul (?, package.seeall) funksjon Ship ()? Alle kommentert kode går her? slutt

Vi har ikke flixel, så bli kvitt importerklæringen for den. Se nå på topplinjene til vår
Skip () -funksjon:

 funksjon Ship () - [Embed (source = "? /? /? /? /assets/png/Ship.png")] private var ImgShip: Klasse - [[funksjon Ship () -: void super , 50, ImgShip) ende -]]? slutt

Den første linjen laster skipets bilde og lagrer det i variabelen ImgShip. De neste linjene er
den gamle konstruktormetoden. Når skipet ble opprettet, tilordnet denne funksjonen bildet ImgShip og koordinatene (50, 50). Vi kan gjøre det samme ved å opprette en skipvariabel som inneholder et bilde. Vi kan laste inn bildet ved hjelp av skjermmodulen vi brukte i leksjon 1. Da kan vi sette variablene x og y egenskaper til 50. Erstatt ovenstående linjer for å gjøre følgende:

 funksjon Ship () local Ship = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50? kommentert kode? slutt

La oss nå gjøre vårt Ship () -funksjon tilbake, slik at PlayState kan bruke den.

 funksjon Ship () local Ship = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50? kommentert kode? retur Skipsendring

I vår ActionScript-kilde er et skip opprettet i PlayState ved å ringe "nytt skip ()". Mens vi er på
det, la oss lage en ny () -funksjon som returnerer Ship ().

 funksjon Ship () local Ship = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50? kommentert kode? retur Skipsendingsfunksjon ny () retur Skips () slutt

Virkelig, det er ingen teknisk behov for dette, men det gjør vår kode litt mer lesbar.

Gå tilbake til PlayState.lua, og krever vår Ship-modul øverst.

 modul (?, package.seeall) local Ship = krever ("Ship") funksjon PlayState ()? 

Nå kan vi skape et nytt skip. Først flytter du alle de kommenterte variabeldeklarasjonene fra toppen av filen til create () -funksjonen.

 modul (?, package.seeall) lokale Ship = krever ("Ship") funksjon PlayState () lokale PlayState = ? en hel masse kommentert kode? funksjon opprette () -: void PlayState._inGame = true - lokal _ship - lokal _aliens - lokal _bullets - lokal _scoreText - lokal _gameOverText - lokal _spawnTimer - lokal _spawnInterval = 2.5 PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125)? kommenterte lage () logikk? end create () end

Hvis du lar dem kommentere, gjør de egenskapene til PlayState. Sett egenskapene uten verdi til null. Mens vi er i det, må vi lage en _bakgrunnsdeklarasjon.

? PlayState._background = nil - PlayState._ship = nil - PlayState._aliens = nil - PlayState._bullets = nil - PlayState._scoreText = nil - PlayState._gameOverText = nil - PlayState._spawnTimer = nil - Spillstat ._spawnInterval = 2.5? 

Uncomment _ship variabelen erklæring og opprette et nytt skip som dette:

 funksjon opprette () -: void - variable deklarasjoner PlayState._inGame = true PlayState._background = null PlayState._ship = nil - PlayState._aliens = nil - PlayState._bullets = nil - PlayState._scoreText = null - PlayState._gameOverText = nil - PlayState._spawnTimer = nil - PlayState._spawnInterval = 2.5 - variable oppgaver PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171 , 204, 125) PlayState._ship = Ship.new ()? kommenterte lage () logikk? slutt

Merk her at vi tildeler _background først. Dette skyldes at skjermobjekter i Corona er bestilt
etter når de er opprettet. Vi ville ikke kunne se _ship hvis vi opprettet det før _background.

Hvis du kjører koden, er det nå et skip som vises på (50, 50).

En titt på maskinvarebegrensninger

Vi må være i stand til å flytte skipet for å kunne spille, men hvordan kan vi? Det opprinnelige spillet ble laget for å bli styrt av et tastatur. En iPhone har ikke et tastatur. Hvordan kan vi komme seg rundt dette? Dette er en av de mange faktorene som må tas med i betraktningen når du oppretter en app for en mobilenhet, enten du overfører eksisterende kode eller oppretter en app fra begynnelsen. En annen som vi allerede har å gjøre med, er skjermstørrelse. På en datamaskin kommer programmene i mange forskjellige størrelser. De fleste av dem er til og med resizable. På en iPhone er apper av samme størrelse.

Å løse disse problemene kan være utfordrende. Å komme seg rundt disse restriksjonene krever tenkning
utenfor boksen. Vi kunne for eksempel kontrollere vårt skip med knappene på skjermen. Vi kan også trykke på stedet på skjermen som vi vil at skipet skal flytte til. Vi kunne til og med bruke enhetens
akselerometer for å kontrollere skipet basert på enhetens tilt. Kanskje vi forandrer spillet litt og gjør skipet selv kontroll. Da ville spilleren bare være ansvarlig for skytingen. Som du ser, er det mange muligheter for nye stiler på spill på iPhone.

Opprette virtuelle knapper

Så godt som mange av disse ideene var, skal vi lage knapper på skjermen for å kontrollere skipet. På denne måten vil spillet være mest i tråd med originalen. Jeg forlater de andre alternativene for deg å utforske.

Ansca Mobile har opprettet et åpen kildekode-bibliotek for å lage virtuelle knapper. I stedet for
bygger biblioteket i Corona, de har tatt med det på deres hjemmeside som valgfritt. jeg har
Inkludert den nyeste versjonen av denne skrivingen i kildekoden for denne opplæringen. Legg til
"ui.lua" -filen til prosjektmappen din.

Gå over til Ship.lua-filen din slik at vi kan gjøre noen oppsett. La oss legge til noen få egenskaper i vår Skip-variabel. Litt under koden der vi setter skipets koordinater til (50, 50) legg til dette:

? lokalt skip = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50 Ship._up = false Ship._down = false Ship._left = false Ship._right = false? 

Vi skal bruke disse til å fortelle skipet når de skal flytte. Hvis verdiene endres til ekte, betyr det at de respektive knappene trykkes.

Tilbake i PlayState.lua, må vi opprette en ny funksjon som håndterer å skape knapper. Vi skal håndtere dette utenfor PlayState () fordi det kommer til å bli litt rotete. Før vi går videre,
sørg for at du har alle knappbilder fra kilden som følger med denne opplæringen. Nå lager en knappHandler () -funksjon under PlayState ().

? funksjon PlayState ()? avslutte funksjonsknappHandler (PlayState) slutten

Legg merke til at buttonHandler () tar et argument: PlayState. Dette er fordi vi skaper
buttonHandler () utenfor PlayState () -funksjonen. Hvis du husker fra den første leksjonen, betyr dette
den knappenHandler () har ingen anelse om hva PlayState-variabelen er, fordi PlayState er lokal til
PlayState () -funksjonen. Vi vil ringe buttonHandler () fra innsiden av PlayState (). Ved å passere
PlayState til buttonHandler (), lar vi buttonHandler () se og modifisere alle PlayState og dens egenskaper. Siden _ship er en egenskap av PlayState, vil buttonHandler () kunne sette
_ship_up, _ship._down, osv.

Vi skal importere ui.lua-modulen til vår buttonHandler-funksjon i stedet for på toppen av
PlayState.lua. Du vil se hvorfor senere.

? funksjon PlayState ()? sluttfunksjonsknappHandler (PlayState) lokal ui = krever ("ui") slutt

Nå skal det bli litt rotete. Vi skal lage to funksjoner for hver knapp. En
for når knappen trykkes, og en for når knappen slippes ut. Når disse kalles, vil de sette fartøyets egenskaper til sanne eller falske.

 funksjonsknappHandler (PlayState) lokal ui = krever ("ui") -funksjon upPressed () PlayState._ship._up = sann endefunksjon upReleased () PlayState._ship._up = falsk endefunksjon downPressed () PlayState._ship._down = true end funksjon downReleased () PlayState._ship._down = falsk endefunksjon leftPressed () PlayState._ship._left = sann endefunksjon leftReleased () PlayState._ship._left = falsk endefunksjon rightPressed () PlayState._ship._right = sann endefunksjon rightReleased () PlayState._ship._right = falsk slutten

Fordi vi overfører PlayState til buttonHandler (), og _ship og alle dets egenskaper tilhører
PlayState, vi kan forandre dem fra ekte til falsk og omvendt. Nå må vi lage de faktiske knappene. Med den importerte modulen kan vi bruke en av metodene: newButton. Dette har noen interessant syntaks, så hold fast.

 PlayState._upButton = ui.newButton defaultSrc = "up.png", defaultX = "50", defaultY = "50", overSrc = "up.png", overX = "50", overY = "50", onPress = upPressed, onRelease = upReleased, id = "_upButton"

Denne koden kaller newButton og tilordner resultatet til _upButton (en egenskap av PlayState). Først,
du lurer kanskje på hvorfor det er braketter. Dette er ikke et unntak fra reglene for lua syntaks.
Faktisk holder parentesene en rekke parametere som sendes til newButton-metoden. Det er mange parametere her, så la oss gå over dem en om gangen. Den første, standardSrc er plasseringen av bildet som skal brukes når knappen ikke trykkes. defaultX og defaultY er bildens dimensjoner. overSrc er plasseringen av bildet som skal vises når du trykker på knappen. I dette tilfellet skal vi bruke det samme bildet. overX og overY fungerer som standardX og defaultY, men de er dimensjonene for overSrc. onPress er funksjonen som skal ringes når knappen trykkes. Dette er en av funksjonene vi tidligere har gjort. onRelease er det samme som onPress, men det kalles på knappens utgivelse. ID er en navngitt streng for å fortelle denne knappen bortsett fra andre. Hver knapp har en x og en y-egenskap, akkurat som andre visningsobjekter som kan justeres når som helst.

Nå som vi vet hvordan knapper fungerer, la oss gjøre resten av dem. Legg dette til bunnen av
buttonHandler ():

 funksjon knappHandler ()? PlayState._upButton = ui.newButton defaultSrc = "up.png", defaultX = "50", defaultY = "50", overSrc = "up.png", overX = "50", overY = "50", onPress = upPressed, onRelease = upReleased, id = "_upButton" PlayState._upButton.x = display.contentWidth - 100 PlayState._upButton.y = display.contentHeight - 100 PlayState._downButton = ui.newButton defaultSrc = "down.png" defaultX = "50", defaultY = "50", overSrc = "down.png", overX = "50", overY = "50", onPress = downPressed, onRelease = downReleased, id = "_downButton" PlayState._downButton. x = display.contentWidth - 100 PlayState._downButton.y = display.contentHeight - 50 PlayState._leftButton = ui.newButton defaultSrc = "left.png", defaultX = "50", defaultY = "50", overSrc = "venstre .png ", overX =" 50 ", overY =" 50 ", onPress = leftPressed, onRelease = leftReleased, id =" _leftButton " PlayState._leftButton.x = display.contentWidth - 150 PlayState._leftButton.y = display.contentHeight - 75 PlayState._rightButton = ui.new Knapp defaultSrc = "right.png", defaultX = "50", defaultY = "50", overSrc = "right.png", overX = "50", overY = "50", onPress = rightPressed, onRelease = rightReleased, id = "_rightButton" PlayState._rightButton.x = display.contentWidth - 50 PlayState._rightButton.y = display.contentHight - 75 slutten

Hvis vi legger til et anrop til buttonHandler () i create () -funksjonen til PlayState (), har vi fire
piler plassert nederst til høyre på skjermen.

 funksjon PlayState ()? funksjon opprett ()? PlayState._ship = Ship.new () buttonHandler (PlayState)? slutt

The Game Loop

Nå må vi lage en løkke for å håndtere spillingen. I den opprinnelige koden ble funksjonen oppdatering () brukt til dette formålet. Vi vil gjøre det samme med vår kode. Akkurat som vi gjorde med create () funciton, uncomment oppdateringen () -funksjonen og sett enkeltlinjebeskrivelser før alle de innvendige linjene.

 funksjonsoppdatering () -: void --FlxU.overlap (_aliens, _bullets, overlapAlienBullet) --FlxU.overlap (_aliens, _ship, overlappingAlienShip) --if (FlxG.keys.justPressed ("SPACE") og _ship.dead == false) da - spawnBullet (_ship.getBulletSpawnPosition ()) --end --if (FlxG.keys.ENTER og _ship.dead) deretter - FlxG.state = new PlayState (); --end --_ spawnTimer = _spawnTimer - FlxG.elapsed --if (_spawnTimer < 0) then -- spawnAlien() -- resetSpawnTimer() --end --super.update() end

Lytt til hendelser

For å få oppdateringen () -funksjonen kalt gjentatte ganger som i flixel, må vi legge til en hendelse
lytteren. Denne linjen med kode vil angi oppdatering () som skal kalles hver ny ramme. Legg til det i create ()
funksjon.

 funksjon opprette () -: ugyldig? buttonHandler (PlayState) Runtime: addEventListener ("enterFrame", oppdatering)? slutt

Kontrollerer om spillet er over

La oss sjekke om spillet fortsatt kjører før vi lar spillsløyfen gå. Husk denne variabelen
"PlayState._inGame"? Vi skal bruke den for å sjekke om spillet er over. Så omgir den kommenterte oppdateringen () -koden med denne setningen.

 funksjonsoppdatering () -: ugyldig hvis PlayState._inGame da? kommentert kode? slutten

Håndtering av skipets bevegelse

For å få skipet til å flytte, må vi få Ship.luas oppdatering () -funksjon som fungerer. Som før, endre kommentarene slik at funkliske deklarasjonen ikke lenger er kommentert, men alt annet er. Legg til samme hendelseslytter rett før slutten av Ship ().

 Fungerer Ship ()? Runtime: addEventListener ("enterFrame", oppdatering) returnere Ship end

Vi må også sjekke at variabelen "Ship" eksisterer, og at den ikke er null. Wrap kommentert
kode med dette hvis erklæring.

 funksjon oppdatering () hvis Ship da? kommentert kode? slutten

Nå, la oss begynne å jobbe gjennom kommentert linjer. De to første satte fartøyets hastighet til 0.
Corona har ikke hastighet som flixel gjør, så vi vil ende opp med å jobbe med skipets x og y
direkte. De neste åtte linjene kontrollerer om venstre eller høyre piltastene trykkes på tastaturet. Vi
Kan erstatte dette med sjekker for variablene _left og _right. Siden vi ikke har hastighet til
arbeid med, vi vil bare sette skipets x-verdi til pluss eller minus 5.

 hvis (Ship._left) så Ship.x = Ship.x - 5 elseif (Ship._right) deretter Ship.x = Ship.x + 5 end

Samme gjelder for opp og ned.

 hvis (Ship._up) så Ship.y = Ship.y - 5 elseif (Ship._down) deretter Ship.y = Ship.y + 5 end

Du kan slette "super.update ()"

Holde spillet i et grense

Hvis du skulle kjøre spillet nå, ville skipet bevege seg riktig. Problemet er at det skal fly
rett utenfor skjermen eller inn i kontrollene hvis vi lar det gå. Det opprinnelige spillet hadde også dette problemet. Så,
De neste kodelinjene i oppdateringen () -funksjonen holder skipet fra å forlate en grense. Den
oppnår dette ved å sjekke om skipet er utenfor grensen etter alt er det x og y endringer
er gjennom. Hvis skipet er ute, blir det flyttet tilbake til maksimal tillatt verdi. Vi vil gjøre det samme, og vi kan bruke samme display.contentWidth og contentHeight som med bakgrunnen for å finne skjermstørrelsen.

 hvis (Ship.x> display.contentWidth-Ship.contentWidth-16) så Ship.x = display.contentWidth-Ship.contentWidth-16 elseif (Ship.x < Ship.contentWidth+16) then Ship.x = Ship.contentWidth+16 end if(Ship.y > display.contentHeight-Ship.contentHeight-150), deretter Ship.y = display.contentHeight-Ship.contentHeight-150 elseif (Ship.y < Ship.contentHeight+16) then Ship.y = Ship.contentHeight+16 end

Jeg endret tallene litt, slik at skipet ikke ville overlappe knappene.

Kuler og skjermgrupper

Nå må vi gjøre skipsskytingen vår. La oss ta en titt på "de / pixelate / flixelprimer / Bullet.as". Gå
gjennom normal syntaks konverteringsprosessen. Heldigvis er dette veldig enkelt. Slett alt annet enn Bullet () konstruktøren. Legg til moduldeklarasjonen, og lagre den som Bullet.lua i prosjektmappen din.

Vi har nå en Bullet () -funksjon som tar en X og en Y-verdi. Det skaper et grønt rektangel på de
koordinater, og den setter sin hastighet til 1000.

La oss lage rektangelet som fungerer som kulen på samme måte som vi gjorde bakgrunnen i den første
lekse.

 modul (?, package.seeall) funksjon Bullet (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) --super (x, y) --createGraphic (16, 4, 0xFF597137) --velocity.x = 1000 ende

Denne koden oppretter en firkant på 16 til 4 piksler og setter sine X- og Y-koordinater til tallene som sendes til Bullet (x, y). La oss nå endre kulens fyllfarge. # 587137 konvertert til RGB er (89, 113, 55).

 modul (?, package.seeall) funksjon Bullet (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) Bullet: setFillColor (89, 113, 55) --velocity.x = 1000 ende

La oss legge til en ny () funksjon for enkelhets skyld som vi gjorde med Ship.lua.

 modul (?, package.seeall) funksjon Bullet (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) Bullet: setFillColor (89, 113, 55) --velocity.x = 1000 retur Bullet end-funksjon ny (x, y) retur Bullet (x, y) ende

Den koden aksepterer bare en X- og en Y-verdi og returnerer en ny kule på den plasseringen. Sørg for å
legg til "return Bullet" på slutten av Bullet (), slik at PlayState vil kunne bruke det.

Nå må vi gjenskape hastigheten. La oss lage en oppdatering () -funksjon som vi gjorde for skipet.

? funksjon Bullet (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) Bullet: setFillColor (89, 113, 55) funksjonsoppdatering () hvis Bullet Bullet.x = Bullet.x + 10 slutten Runtime: addEventListener ("enterFrame", oppdatering) returner Bullet end? 

Nå vil kulen flytte ti piksler til høyre hver ramme.

Refactoring-knappkode: Legge til en brannknap

Nå skal vi trenge en metode for å skyte kulene. La oss legge til en annen knapp. Først må vi ha en variabel for å holde styr på om knappen trykkes eller ikke. I stedet for å håndtere dette i Ship.lua-filen, la oss gjøre denne variabelen i create () -funksjonen i PlayState.lua nederst på siden
variable deklarasjoner.

? funksjon opprette () -: void - variable deklarasjoner PlayState._inGame = true PlayState._background = null PlayState._ship = nil - PlayState._aliens = nil - PlayState._bullets = nil - PlayState._scoreText = null - PlayState._gameOverText = nil - PlayState._spawnTimer = nil - PlayState._spawnInterval = 2.5 PlayState._shoot = null? slutt? 

Gå videre og sett den til falsk under den nye skiplinjen i de variable oppgavene.

? funksjon opprette () -: ugyldig? - variable oppgaver PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125) PlayState._ship = Ship.new () PlayState._shoot = false ? slutt? 

Nå må vi legge til noen linjer i vår knappHandler () -funksjon. Vi trenger to funksjoner for å håndtere å trykke og slippe den nye knappen. Legg til disse to funksjonene etter rightPressed () og
rightReleased ().

? funksjon knappHandler (PlayState)? funksjon leftPressed () PlayState._ship._left = sann endefunksjon leftReleased () PlayState._ship._left = falsk endefunksjon rightPressed () PlayState._ship._right = sann endefunksjon rightReleased () PlayState._ship._right = falsk sluttfunksjon shootPressed () PlayState._shoot = sann sluttfunksjon shootReleased () PlayState._shoot = false end? slutt? 

Last inn knappen som før.

? funksjon knappHandler (PlayState)? PlayState._shootButton = ui.newButton defaultSrc = "shoot.png", defaultX = "100", defaultY = "100", overSrc = "shoot.png", overX = "100", overY = "100", onRelease = shootReleased, onPress = shootPressed, id = "_shootButton" PlayState._shootButton.x = 75 PlayState._shootButton.y = display.contentHight - 75 slutten? 

Vår knappekode blir litt rotete. La oss flytte hele buttonHandler () til en ny fil som heter
Buttons.lua. Ikke glem moduldeklarasjonen.

Importer den nye knappmodulen øverst på PlayState. Mens vi er der, la oss importere Bullet også.

 modul (?, package.seeall) lokale Skip = krever ("Ship") lokale Bullet = krever ("Bullet") lokale knapper = krever ("knapper") funksjon PlayState? 

Endre knappen buttonHandler () i opprett () for å ringe til modulens funksjon.

 funksjon opprette () -: ugyldig? PlayState._ship = Ship.new () PlayState._shoot = falske Buttons.buttonHandler (PlayState)? slutt

Plasser kuler i forhold til skipet

Nå trenger vi å gjenskape noen av kulehåndteringsfunksjonene. La oss se på getBulletSpawnPosition ()
i Ship.lua.

 --[[funksjon getBulletSpawnPosition () -: FlxPoint lokal p = ny FlxPoint (x + 36, y + 12) return p end -]]

Den opprinnelige funksjonen var en instansmetode for skip. Den returnerte en X og en Y-verdi for å lage en ny kule. Siden det skal være en instansmetode, må vi få det til å fungere som en. La oss gjøre skipvariabelen eier den.

 funksjon Ship: getBulletSpawnPosition () -: FlxPoint local p = ny FlxPoint (x + 36, y + 12) return p end

Siden FlxPoint er en type eksklusiv til Flixel, la vi returnere en matrise i stedet.

 funksjon Ship: getBulletSpawnPosition () local p = x = Ship.x + 36, y = Ship.y + 2 retur p end

Denne koden legger til 36 i skipets X-verdi og 2 (jeg brukte 2 i stedet for 12 for å justere kulen
posisjon for Corona) til skipets Y-verdi. Disse er lagret i en assosiativ array. Vi kan nå
få tilgang til hvert tall med p.x og p.y.

I den opprinnelige koden holdt en variabel i PlayState-navnet _bullets alle bulletinstansene.
Vi kan gjøre det samme med en skjermgruppe. En skjermgruppe i Corona holder bare en haug med skjermobjekter og viser dem. Dette er nyttig for å holde oversikt over en haug av samme type
gjenstand. Når objekter blir lagt til for å vise grupper, vises de i rekkefølgen som displayet
grupper er opprettet. For eksempel, hvis vi har en masse kuler og en mengde romvesener, og vi vil at alle romvesener skal være på toppen, kan vi lage en kuleutstillingsgruppe og deretter en fremmed visningsgruppe. Hvis vi legger til alle kulene og fremmede forekomster til gruppene, vises de alltid i riktig rekkefølge. Dette vil skje, selv om en kule er opprettet etter en fremmed. Utlendingen vil være på topp fordi skjermgruppen styrer skjermordren.

Uvanlig linjen "--PlayState._bullets = nil" i create () -funksjonen i PlayState.lua.

 funksjon opprette () -: void - variable deklarasjoner PlayState._inGame = true PlayState._background = null PlayState._ship = nil - PlayState._aliens = null PlayState._bullets = nil - PlayState._scoreText = null - Spillstat. _gameOverText = nil - PlayState._spawnTimer = nil - PlayState._spawnInterval = 2.5 PlayState._shoot = null? slutt

Lag _bullets en ny skjermgruppe i variabeloppgavene.

 funksjon opprette () -: ugyldig? PlayState._ship = Ship.new () PlayState._shoot = false PlayState._bullets = display.newGroup () Buttons.buttonHandler (PlayState)? slutt

Ta en titt på spawnBullet ().

 --[[function spawnBullet (p) -: void local bullet = ny Bullet (p.x, p.y) _bullets.add (bullet) FlxG.play (SoundBullet) end -]]

Denne koden er faktisk ganske nær hva vi vil. Få det til å se slik ut:

 funksjon spawnBullet (p) -: void local _bullet = Bullet.new (p.x, p.y) PlayState._bullets: sett inn (_bullet) PlayState._shoot = false --FlxG.play (SoundBullet) end

Når kulen er opprettet, må _shoot settes tilbake til falsk. På den måten må brukeren løfte
fingeren før de brann igjen.

Håndtere grunnleggende lyder

Corona har en grunnleggende API for å spille kort lydeffekter. For å kunne bruke det, må vi bruke .caf lyd
filer. Den konverterte versjonen av de opprinnelige MP3-lydeffekter er inkludert i kilden til dette
opplæringen.

Først må vi opprette variabler for å holde lydene. Det er tre linjer øverst på PlayState.
Flytt dem til de variable deklarasjonene i create ().

 funksjon opprette () -: void - variable deklarasjoner PlayState._inGame = true PlayState._background = null PlayState._ship = nil - PlayState._aliens = null PlayState._bullets = nil - PlayState._scoreText = null - Spillstat. _gameOverText = nil - PlayState._spawnTimer = nil - PlayState._spawnInterval = 2.5 PlayState._shoot = nil - [Embed (kilde = "? /? /? /? /assets/mp3/ExplosionShip.mp3")] private var SoundExplosionShip: Class - [Embed (kilde = "? /? /? /? /Assets/mp3/ExplosionAlien.mp3")] private var SoundExplosionAlien: Klasse - [Embed (source = "? /? /? /? / eiendeler / mp3 / Bullet.mp3 ")] private var SoundBullet: Klasse? slutt

Vi vil bare at navnene skal være de samme. Lag dem egenskapene til PlayState og sett dem til null.
Uvanlig den siste linjen.

 funksjon opprette () -: void - variable deklarasjoner PlayState._inGame = true PlayState._background = null PlayState._ship = nil - PlayState._aliens = null PlayState._bullets = nil - PlayState._scoreText = null - Spillstat. _gameOverText = nil - PlayState._spawnTimer = nil - PlayState._spawnInterval = 2.5 PlayState._shoot = nil - PlayState.SoundExplosionShip = nil - PlayState.SoundExplosionAlien: Class = nil PlayState.SoundBullet = null? slutt

Nå vil vi bruke mediemodulen til å laste inn en ny lyd. Sett dette på bunnen av oppgavene:

 funksjon opprette () -: ugyldig? PlayState._ship = Ship.new () PlayState._shoot = false PlayState._bullets = display.newGroup () PlayState.SoundBullet = media.newEventSound ("Bullet.caf") Buttons.buttonHandler (PlayState)? slutt

Overskrift tilbake til spawnBullet (). Vi kan erstatte den siste linjen for å spille vår nye lyd.

 funksjon spawnBullet (p) -: void local _bullet = Bullet.new (p.x, p.y) PlayState._bullets: sett inn (_bullet) PlayState._shoot = false media.playEventSound (PlayState.SoundBullet) slutten

Nå må vi bare endre vår oppdateringsfunksjon () for å få noen skytingskuler. Sjekk om _shoot er
sant og hvis det eksisterer. I så fall, ring vår getBulletSpawnPosition () -metode for vårt skip
og spawnBullet () på den aktuelle plasseringen.

 funksjon oppdatering () hvis PlayState._inGame deretter hvis PlayState._shoot == true og PlayState._ship deretter lokalt p = PlayState._ship: getBulletSpawnPosition () spawnBullet (p) avslutte? slutten

Grunnleggende minnehåndtering

I Flixel ble minnet tatt vare på for oss. I Corona må vi rydde opp gjenstander vi
er ferdig med. La oss legge til en kill () forekomstmetode for hver kule for å hjelpe oss. drepe () er
funksjon som flixel automatisk ringer når et objekt ikke lenger er nødvendig. Legg dette til Bullet.lua:

 funksjon Bullet (x, y)? funksjon oppdatering ()? sluttfunksjon Bullet: kill () Bullet.parent: remove (Bullet) Bullet = null end? slutt

Dette er den riktige måten å rydde opp et objekt i Corona. Først fjernet vi alle båndene til det ved å fjerne
det fra skjermgruppen. Så setter vi Bullet-variabelen til null. La oss gjøre det samme for Ship.
Legg til dette under getBulletSpawnPosition () i Ship.lua:

 funksjon Ship: kill () Ship: removeSelf () Ship = null Runtime: removeEventListener ("enterFrame", update) end

Legg merke til at vi stoppet oppdateringen fra å bli kalt hver ramme (siden skipet ikke eksisterer
lenger).

Håndtering av skjermkuler

Tilbake i Bullet.lua, la oss legge til en sjekk hver ramme for å se om kulen er utenfor skjermen.
For tiden fortsetter koden vår å tegne kuler, selv om de ikke kan ses. Dette er sløsing med enhetens begrensede ressurser. Erstatt oppdatering () med dette:

 funksjon oppdatering () hvis Bullet deretter hvis (Bullet.x < display.contentWidth) then Bullet.x = Bullet.x + 10 else Bullet:kill() end end end

Nå vil kula bare bevege seg til høyre hvis det kan sees. Ellers vil det ringe vår hendig
drepe () -funksjonen.

Innsamling av søppel

Lua har en automatisk søppelkollektor som håndterer søppel som ubrukte variabler, viser objekter som er fjernet fra skjermen, og alt annet som ikke lenger er nødvendig. Vi kan fortelle Lua å samle søppel ved å legge til denne linjen på slutten av opprettelsen i PlayState:

 funksjon opprett ()? collectgarbage ("collect") slutten

Konklusjon

Dette begynner å se ut som et spill nå. Vårt skip kan bevege seg rundt på skjermen og brannkuler. De
kuler tar seg av seg selv når de ikke lenger er nødvendig. Nå trenger vi bare noen fiender.