Portarea jocurilor ActionScript în iOS cu SDK Corona Partea 2

Acest tutorial va arunca o privire asupra portării unui joc Flash / Flex pe SDK-ul Corona. În mod specific, vom porta de la ActionScript la Lua, cu obiectivul final de a juca jocuri de tip Flash numai pe iPhone. Pe lângă demonstrarea limbajului și a diferențelor API, această serie de tutori va explica și restricțiile hardware, cum ar fi dimensiunea ecranului și lipsa butoanelor fizice pe iPhone.

Acest tutorial preia locul unde a început o parte.

Crearea navei

Începeți prin portarea sintaxei din fișierul sursă "de / pixelate / flixelprimer / Ship.as" așa cum este descris
în ziua un mesaj. În mod specific, va trebui să:

  • Scapa de declarațiile de pachete și clase.
  • Eliminați declarațiile de tip.
  • Adăugați "local" la toate variabilele.
  • Înlocuiți parantezele condiționate cu "apoi" și "sfârșit".
  • Ștergeți toate punct și virgulă și comentați totul.

Acum, adăugați declarația modulului în partea superioară a fișierului, astfel încât să putem importa fișierul în PlayState.
De asemenea, continuați și împachetați tot codul cu o funcție constructor Ship (). Codul dvs. trebuie acum aranjat astfel:

 modul (?, package.seeall) funcția Ship ()? tot codul comentat merge aici? Sfârșit

Nu avem flixel, deci eliminați declarația de import pentru aceasta. Acum uita-te la liniile de sus ale noastre
Funcția Ship ():

 Funcția Ship () - [Embed (sursă = "? /? /? /? /assets/png/Ship.png")] vară privată ImgShip: Class - [[ , 50, ImgShip) sfârșitul -]]? Sfârșit

Prima linie încarcă imaginea navei și o stochează în variabila ImgShip. Următoarele linii sunt
vechea metodă a constructorului. Când nava a fost creată, această funcție i-a atribuit imaginea ImgShip și coordonatele (50, 50). Putem face același lucru creând o variabilă de navă care deține o imagine. Putem încărca imaginea utilizând modulul de afișare utilizat în lecția 1. Apoi putem seta proprietățile variabilelor x și y la 50. Înlocuiți liniile de mai sus pentru a face următoarele:

 funcția Ship () navă locală = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50? codul comentat? Sfârșit

Acum să facem funcția Ship () să se întoarcă pe Ship astfel încât PlayState să o folosească.

 funcția Ship () navă locală = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50? codul comentat? întoarcere End of Ship

În sursa noastră ActionScript, o navă este creată în PlayState apelând "new Ship ()". În timp ce suntem
aceasta, să facem o funcție nouă () care returnează Ship ().

 funcția Ship () navă locală = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50? codul comentat? întoarcere Funcția de terminare a navei new () returnare Nava () sfârșit

Într-adevăr, nu există nici o nevoie tehnică pentru acest lucru, dar face codul nostru mai ușor de citit.

Treceți înapoi la PlayState.lua și cereți modulul nostru Ship în partea de sus.

 modul (?, pachet.aspectaj) nava locală = necesită ("navă") funcția PlayState ()? 

Acum putem crea o navă nouă. Mai întâi, mutați toate declarațiile de variabile comentate din partea de sus a fișierului la funcția create ().

 modul (?, package.seeall) navă locală = necesită ("Ship") funcția PlayState () local PlayState = ? o grămadă de cod comentat? create function () -: void PlayState._inGame = true --local _ship --local _aliens --local _bullet --local _scoreText --local _gameOverText --local _spawnTimer --local _spawnInterval = 2.5 PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125)? a comentat crea () logica? end end create ()

Lăsându-le comentate, le fac proprietăți ale PlayState. Setați proprietățile fără valoare la zero. În timp ce ne aflăm în acest sens, trebuie să facem o declarație pe teren.

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

Dezactivați declarația variabilei _ship și creați o navă nouă cum ar fi aceasta:

 () -: void - declarații variabile PlayState._inGame = true PlayState._background = nil PlayState._ship = nil --PlayState._aliens = nil --PlayState._bullets = nil --PlayState._scoreText = nil - PlayState._gameOverText = nil --PlayState._spawnTimer = nil --PlayState._spawnInterval = 2.5 - asignări variabile PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171 , 204, 125) PlayState._ship = Ship.new ()? a comentat crea () logica? Sfârșit

Rețineți că atribuim mai întâi spațiul _background. Acest lucru se datorează faptului că sunt comandate obiecte de afișare în Corona
de când sunt create. Nu am fi putut să vedem _ship dacă l-am creat înainte de fund.

Dacă executați codul, există acum o navă afișată la (50, 50).

O privire asupra restricțiilor hardware

Trebuie să putem să mutăm nava pentru a juca, dar cum putem? Jocul original a fost făcut să fie controlat de o tastatură. Un iPhone nu are o tastatură. Cum putem face asta? Acesta este unul dintre numeroșii factori care trebuie luați în considerare atunci când creați o aplicație pentru un dispozitiv mobil, indiferent dacă transferați codul existent sau creați o aplicație de la zero. Un altul cu care ne confruntăm este dimensiunea ecranului. Pe un computer, programele vin în diferite dimensiuni. Cele mai multe dintre ele sunt chiar redimensionabile. Pe un iPhone, aplicațiile au aceeași dimensiune.

Rezolvarea acestor probleme poate fi o provocare. Noțiuni de bază în jurul acestor restricții necesită gândire
în afara casetei. De exemplu, am putea controla nava noastră cu butoane pe ecran. De asemenea, am putut atinge locația de pe ecran la care vrem să se transfere nava. Am putea chiar să folosim dispozitivul
accelerometru pentru a controla nava în funcție de înclinarea dispozitivului. Poate vom schimba puțin modul de joc și vom face controlul navei în sine. Apoi, jucătorul ar fi fost responsabil de fotografiere. După cum puteți vedea, există multe posibilități pentru noi stiluri de joc pe iPhone.

Crearea butoanelor virtuale

Pe măsură ce multe dintre aceste idei au fost îngrijite, vom crea butoane pe ecran pentru a controla nava. În acest fel, jocul va fi cel mai în concordanță cu originalul. Vă las alte opțiuni pentru a explora.

Ansca Mobile a creat o bibliotecă open-source pentru crearea butoanelor virtuale. In loc de
construind biblioteca în Corona, le-au inclus pe site-ul lor ca opțional. eu am
a inclus cea mai recentă versiune a acestei scrieri în codul sursă pentru acest tutorial. Adaugă
"ui.lua" în dosarul proiectului.

Mergeți la fișierul Ship.lua pentru a putea face ceva. Să adăugăm câteva proprietăți variabilei noastre Ship. Chiar sub codul în care am stabilit coordonatele navei la (50, 50) adăugați aceasta:

? navă locală = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50 Ship._up = false Ship._down = false Ship._left = false Ship._right = false? 

Vom folosi aceste pentru a spune navei când să se miște. Dacă valorile se modifică la adevărat, înseamnă că respectivele butoane sunt apăsate.

Înapoi în PlayState.lua, trebuie să creați o funcție nouă pentru a gestiona crearea butoanelor. Vom face acest lucru în afara PlayState (), pentru că va deveni puțin dezordonat. Înainte să mergem mai departe,
asigurați-vă că aveți toate imaginile de buton din sursa incluse în acest tutorial. Acum, creați o funcție buttonHandler () sub PlayState ().

? funcția PlayState ()? butonul de încheiere a butonului funcția HandHandler (PlayState)

Observați că buttonHandler () are un argument: PlayState. Aceasta este pentru că noi creăm
buttonHandler () în afara funcției PlayState (). Dacă vă amintiți din prima lecție, asta înseamnă
că buttonHandler () nu are nicio idee despre ce este variabila PlayState, deoarece PlayState este locală pentru
Funcția PlayState (). Vom apela buttonHandler () din interiorul PlayState (). Trecând
PlayState to buttonHandler (), permitem buttonHandler () să vadă și să modifice toate PlayState și proprietățile sale. Din moment ce _ship este o proprietate a PlayState, buttonHandler () va putea seta
_ship_up, _ship._down, etc.

Vom importa modulul ui.lua în funcția buttonHandler, în locul celui de sus
PlayState.lua. Veți vedea de ce mai târziu.

? funcția PlayState ()? end function buttonHandler (PlayState) local ui = necesită ("ui") sfârșitul

Acum va deveni puțin dezordonat. Vom crea două funcții pentru fiecare buton. unu
pentru când butonul este apăsat și unul pentru când butonul este eliberat. Când vor fi chemați, vor stabili proprietățile navei la adevăr sau la fals.

 () PlayState._ship._up = Funcția finală reală upReleased () PlayState._ship._up = Funcția finală false downPress () PlayState._ship._down = True end funcția downReleased () PlayState._ship._down = funcția finală falsă leftPress () PlayState._ship._left = funcția finală leftReleased () PlayState._ship._left = funcția finală fină rightPressed () PlayState._ship._right = adevărată funcție finală rightReleased () PlayState._ship._right = Sfarsit sfarsit false

Deoarece trecem PlayState la buttonHandler (), și _ship și toate proprietățile aparțin
PlayState, le putem schimba de la adevărat la fals și viceversa. Acum trebuie să creăm butoanele reale. Cu modulul ui importat, putem folosi una dintre metodele sale: newButton. Aceasta are o sintaxă interesantă, așa că închideți-vă bine.

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

Acest cod apelează newButton și atribuie rezultatul la _upButton (o proprietate a PlayState). La început,
poate vă întrebați de ce există paranteze. Aceasta nu este o excepție de la regulile de sintaxă lu.
De fapt, parantezele au o serie de parametri care sunt transmise metodei newButton. Există o mulțime de parametri aici, așa că hai să mergem peste ei unul câte unul. Primul, defaultSrc este locația imaginii pe care să o utilizați când butonul nu este apăsat. defaultX și defaultY sunt dimensiunile imaginii. OverSrc este locația imaginii care va fi afișată atunci când butonul este apăsat. În acest caz, vom folosi aceeași imagine. overX și overY funcționează exact ca defaultX și defaultY, dar acestea sunt dimensiunile pentru overSrc. onPress este funcția de apelare la apăsarea butonului. Aceasta este una dintre funcțiile pe care le-am făcut mai devreme. onRelease este la fel ca onPress, dar se cheamă la eliberarea butonului. id este un șir denumit pentru a spune acest buton în afară de altele. Fiecare buton are proprietăți x și y la fel ca și alte obiecte de afișare care pot fi ajustate oricând.

Acum, că știm cum funcționează butoanele, să le facem pe ceilalți. Adăugați aceasta în partea de jos a paginii
buttonHandler ():

 butonul de funcțiiAlertă ()? PlayState._upButton = ui.newButton defaultSrc = "up.png", defaultX = "50", defaultY = "50", overSrc = "up.png", overX = "50" 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 = "jos.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", implicitX = "50", defaultY = "50", overSrc = .png ", pesteX =" 50 ", pesteY =" 50 ", onPress = leftPressed, onRelease = leftReleased, id =" _leftButton " PlayState._leftButton.x = display.contentWidth - 150 PlayState._leftButton.y = display.contentHeight - 75 PlayState._rightButton = ui.new Butonul defaultSrc = "right.png", implicitX = "50", defaultY = "50", overSrc = "right.png", overX = "50", overY = "50", onResponse = id = "_rightButton" PlayState._rightButton.x = display.contentWidth - 50 PlayState._rightButton.y = display.contentHeight - capăt 75

Dacă adăugăm un apel la buttonHandler () în funcția create () a PlayState (), vom avea patru
săgeți poziționate în partea dreaptă jos a ecranului.

 funcția PlayState ()? funcția create ()? PlayState._ship = Butonul Ship.new () butonulHandler (PlayState)? Sfârșit

Jocul Loop

Acum trebuie să creați o buclă pentru a gestiona modul de joc. În codul original, funcția de actualizare () a fost utilizată în acest scop. Vom face același lucru și cu codul nostru. Așa cum am făcut cu funcția create () funciton, dezarhivați funcția update () și puneți comentariile unei singure linii înaintea tuturor liniilor interioare.

 () -: void --FlxU.overlap (_aliens, _bullets, overlapAlienBullet) --FlxU.overlap (_aliens, _ship, overlapAlienShip) --if (FlxG.keys.justPressed ("SPACE") și _ship.dead == false) apoi - spawnBullet (_ship.getBulletSpawnPosition ()) --end --if (FlxG.keys.ENTER și _ship.dead) apoi - FlxG.state = nou PlayState (); --end --_ spawnTimer = _spawnTimer - FlxG.elapsed --if (_spawnTimer < 0) then -- spawnAlien() -- resetSpawnTimer() --end --super.update() end

Ascultarea pentru evenimente

Pentru a obține funcția update () numită în mod repetat ca în flixel, trebuie să adăugăm un eveniment
ascultător. Această linie de cod va seta update () pentru a fi numit fiecare cadru nou. Adăugați-o în crearea ()
funcţie.

 funcția create () -: void? buttonHandler (PlayState) Durată de execuție: addEventListener ("enterFrame", actualizare)? Sfârșit

Verificarea dacă jocul sa terminat

Să verificăm dacă jocul mai rulează înainte de a lăsa jocul să meargă. Rețineți această variabilă
"PlayState._inGame"? O vom folosi pentru a verifica dacă jocul sa terminat. Încadrați astfel codul de actualizare comentat () cu această instrucțiune.

 update function () -: void daca PlayState._inGame atunci? codul comentat? sfârșitul final

Manipularea mișcării navelor

Pentru ca nava să se mute, trebuie să funcționăm funcția de actualizare () a lui Ship.lua. Ca și înainte, schimbați comentariile astfel încât declarația funcției să nu mai fie comentată, dar orice altceva este. Adăugați același ascultător de eveniment chiar înainte de sfârșitul navei ().

 funcția Ship ()? Durata de execuție: addEventListener ("enterFrame", actualizare) întoarcere Sfârșitul navei

De asemenea, trebuie să verificăm dacă variabila "Ship" există și că nu este zero. Înfășurați comentariul
cod cu această declarație if.

 actualizare funcție () atunci când nava atunci? codul comentat? sfârșitul final

Acum, să începem să lucrăm prin liniile comentate. Primele două au stabilit viteza navei la 0.
Corona nu are viteza ca flixel, așa că vom ajunge să lucrăm cu nava x și y
direct. Următoarele opt linii verifică dacă tastele săgeată stânga sau dreapta sunt împinse pe tastatură. Noi
poate înlocui acest lucru cu verificări pentru variabilele _left și _right. Deoarece nu avem viteza
lucrați cu, vom seta valoarea x a navei la plus sau minus 5.

 dacă (Ship._left), apoi Ship.x = Ship.x - 5 elseif (Ship._right), apoi Ship.x = Ship.x + 5 end

Același lucru se întâmplă și în sus și în jos.

 dacă (Ship._up), apoi Ship.y = Ship.y - 5 elseif (Ship._down), apoi Ship.y = Ship.y + 5 end

Puteți șterge "super.update ()"

Păstrarea jocului într-o limită

Dacă trebuia să conduci acum jocul, nava se va mișca în mod corespunzător. Problema este că va zbura
chiar de pe ecran sau în controale dacă l-am lăsat. Jocul original a avut și această problemă. Asa de,
urmatoarele linii de cod din functia update () pastreaza nava de la a parasi o limita. Aceasta
realizează acest lucru verificând dacă nava se află în afara limitei, după ce se modifică x și y
sunt prin intermediul. În cazul în care nava este în afara, ea devine mutat înapoi la valoarea maximă permisă. Vom face același lucru și putem folosi același display.contentWidth și contentHeight ca și în fundal pentru a găsi dimensiunea ecranului.

 dacă (Ship.x> display.contentWidth-Ship.contentWidth-16), atunci 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), apoi Ship.y = display.contentHeight-Ship.contentHeight-150 elseif (Ship.y < Ship.contentHeight+16) then Ship.y = Ship.contentHeight+16 end

Am schimbat numerele puțin, astfel încât nava să nu se suprapună pe butoane.

Gloanțe și grupuri de afișare

Acum trebuie să facem nava noastră să tragă. Să aruncăm o privire la "de / pixelate / flixelprimer / Bullet.as". Merge
prin procesul de conversie a sintaxei normale. Din fericire, acest lucru este foarte ușor. Ștergeți totul, cu excepția constructorului Bullet (). Adăugați declarația modulului și salvați-o ca Bullet.lua în dosarul proiectului.

Acum avem o funcție Bullet () care are o valoare X și o valoare Y. Creează un dreptunghi verde la acestea
și își stabilește viteza la 1000.

Să creăm dreptunghiul care acționează ca glonț în același mod în care am făcut fundalul în primul
lecţie.

 (x, y) --Super (x, y) --createGraphic (16, 4, 0xFF597137) --velocity.x = 1000 sfârșit

Acest cod creează un pătrat de 16 și 4 pixeli și își stabilește coordonatele X și Y la numerele trimise la Bullet (x, y). Acum, să schimbăm culoarea de umplere a glonțului. # 587137 convertit în RGB este (89, 113, 55).

 (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) Bullet: setFillColor (89, 113, 55) --velocity.x = 1000 capăt

Să adăugăm o funcție nouă () pentru comoditate cum am făcut-o cu Ship.lua.

 (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) Bullet: setFillColor (89, 113, 55) --velocity.x = 1000 întoarcere Funcție terminare bullet nouă (x, y) întoarcere Sfârșitul bulletului (x, y)

Acest cod acceptă doar o valoare X și o Y și returnează un nou glonț în acea locație. Asigura-te ca
adăugați "Return Bullet" la sfârșitul Bullet (), astfel încât PlayState va putea să o folosească.

Acum trebuie să recâștigăm viteza. Să creăm o funcție de actualizare () ca și în cazul navei.

? functie Bullet (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) Bullet: setFillColor (89, 113, 55) + 10 sfârșitul sfârșitului runtime: addEventListener ("enterFrame", actualizare) returnează Sfârșitul bulletului? 

Acum, glonțul va deplasa zece pixeli spre dreapta în fiecare cadru.

Codul butonului de reacție: adăugarea unui buton de incendiu

Acum, vom avea nevoie de o metodă pentru a trage gloanțele. Să adăugăm un alt buton. Mai întâi, avem nevoie de o variabilă pentru a urmări dacă butonul este apăsat sau nu. În loc să manipulați acest lucru în fișierul Ship.lua, permiteți să faceți această variabilă în funcția create () în PlayState.lua din partea de jos a
declarații variabile.

? () -: void - declarații variabile PlayState._inGame = true PlayState._background = nil PlayState._ship = nil --PlayState._aliens = nil --PlayState._bullets = nil --PlayState._scoreText = nil - PlayState._gameOverText = nil --PlayState._spawnTimer = nil --PlayState._spawnInterval = 2.5 PlayState._shoot = zero? Sfârșit? 

Mergeți mai departe și puneți-l la fals sub noua linie de navă din alocările de variabile.

? funcția create () -: void? - misiuni variabile PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125) PlayState._ship = Ship.new () PlayState._shoot = false ? Sfârșit? 

Acum trebuie să adăugăm câteva linii la funcția buttonHandler (). Avem nevoie de alte două funcții pentru a face față apăsării și eliberării noului buton. Adăugați aceste două funcții după rightPressed () și
rightReleased ().

? Butonul de funcții HandHandler (PlayState)? () PlayState._ship._left = funcția finală leftReleased () PlayState._ship._left = funcția finală fină rightPressed () PlayState._ship._right = adevărată funcție finală rightReleased () PlayState._ship._right = () PlayState._shoot = adevărată funcție finală shootReleased () PlayState._shoot = sfarsit false? Sfârșit? 

Încărcați acum butonul ca mai înainte.

? Butonul de funcții HandHandler (PlayState)? PlayState._shootButton = ui.newButton defaultSrc = "shoot.png", implicitX = "100", defaultY = "100", overSrc = "shoot.png", overX = "100" shootReleased, onPress = tragePrint, id = "_shootButton" PlayState._shootButton.x = 75 PlayState._shootButton.y = display.contentHeight - capăt 75? 

Codul nostru de butoane devine puțin dezordonat. Să mutăm toate butoanele buttonHandler () la un nou fișier numit
Buttons.lua. Nu uitați declarerea modulului.

Importați noul modul Button în partea de sus a PlayState. În timp ce suntem acolo, să importăm și Bullet.

 modulul (?, package.seeall) nava locală = necesită ("navă") local Bullet = necesită ("Bullet") local Buttons =? 

Modificați linia buttonHandler () din create () pentru a apela funcția modulului.

 funcția create () -: void? PlayState._ship = Ship.new () PlayState._shoot = fals Buttons.buttonHandler (PlayState)? Sfârșit

Plasarea de gloanțe în raport cu nava

Acum avem nevoie de recrearea unor funcții de manipulare a glonțului. Să ne uităm la getBulletSpawnPosition ()
în Ship.lua.

 --[[function getBulletSpawnPosition () -: FlxPoint local p = nou FlxPoint (x + 36, y + 12) return p end -]]

Funcția inițială a fost o metodă a navei. Acesta a returnat o valoare X și o Y pentru a crea un nou glonț. Deoarece se presupune că este o metodă de instanță, trebuie să o facem să funcționeze ca una. Să facem variabila Ship să o dețină.

 funcția Nave: getBulletSpawnPosition () -: FlxPoint local p = nou FlxPoint (x + 36, y + 12) return p end

Deoarece FlxPoint este un tip exclusiv pentru Flixel, să revenim la o matrice.

 funcția Nave: getBulletSpawnPosition () local p = x = Ship.x + 36, y = Ship.y + 2 retur p p

Acest cod adaugă 36 la valoarea X a navei și 2 (am folosit 2 în loc de 12 pentru a ajusta gloanțele
pentru Corona) la valoarea Y a navei. Acestea sunt stocate într-o matrice asociativă. Acum putem
accesați fiecare număr cu p.x și p.y.

În codul original, o variabilă în PlayState numită _bulleturi a ținut toate instanțele bulletului.
Putem face același lucru cu un grup de afișare. Un grup de afișare din Corona ocupă pur și simplu o grămadă de obiecte de afișare și le afișează. Acest lucru este util pentru a urmări o grămadă de același tip
obiect. Atunci când obiectele sunt adăugate la grupurile de afișare, acestea sunt afișate în ordinea afișării
grupurile sunt create. De exemplu, dacă avem o grămadă de gloanțe și o grămadă de străini și dorim ca toți extratereștrii să fie la vârf, am putea crea un grup de afișare a glonțului și apoi un grup de afișare străin. Dacă adăugăm toate instanțele glonțului și străinilor grupurilor lor, acestea se vor afișa întotdeauna în ordinea corectă. Acest lucru se va întâmpla chiar dacă, de exemplu, un glonț este creat după un străin. Străinul va fi pe primul loc, deoarece grupul de afișare controlează ordinea de afișare.

Descărcați linia "--PlayState._bullets = zero" în funcția create () în PlayState.lua.

 function create () -: void - declaratii variabile PlayState._inGame = true PlayState._background = nil PlayState._ship = nil --PlayState._aliens = nil PlayState._bullets = nil --PlayState._scoreText = nil --PlayState. _gameOverText = nil --PlayState._spawnTimer = nil --PlayState._spawnInterval = 2.5 PlayState._shoot = zero? Sfârșit

Faceți _bulleturi un nou grup de afișare în alocările variabilelor.

 funcția create () -: void? PlayState._ship = Ship.new () PlayState._shoot = false PlayState._bullets = display.newGrup () Buttons.buttonHandler (PlayState)? Sfârșit

Acum aruncați o privire la spawnBullet ().

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

Acest cod este de fapt destul de aproape de ceea ce ne dorim. Faceți-o să arate astfel:

 functionare spawnBullet (p) -: void local _bullet = Bullet.new (p.x, p.y) PlayState._bulleturi: inserați (_bullet) PlayState._shoot = false --FlxG.play (SoundBullet) end

Atunci când se creează gloanțele, trebuie să fie setat _shoot înapoi la false. În acest fel, utilizatorul trebuie să ridice
cu degetul înainte de a le trage din nou.

Manipularea sunetului de bază

Corona are un API de bază pentru redarea efectelor sonore scurte. Pentru a le folosi, trebuie să folosim sunetul .cof
fișiere. Versiunea convertită a efectelor de sunet MP3 originale este inclusă în sursa pentru aceasta
tutorial.

Mai întâi trebuie să creăm variabile pentru a ține sunetele. Există trei linii în partea de sus a PlayState.
Mutați-le la declarațiile de variabile din create ().

 function create () -: void - declaratii variabile PlayState._inGame = true PlayState._background = nil PlayState._ship = nil --PlayState._aliens = nil PlayState._bullets = nil --PlayState._scoreText = nil --PlayState. _gameOverText = nil --PlayState._spawnTimer = nil --PlayState._spawnInterval = 2.5 PlayState._shoot = nil - [Embed (sursa = "? /? /? /? /assets/mp3/ExplosionShip.mp3" SoundExplosionShip: Clasa - [Embed (sursa = "? /? /? /? /Assets/mp3/ExplosionAlien.mp3")] private var SoundExplosionAlien: Class - [Embed assets / mp3 / Bullet.mp3 ")] private var SoundBullet: Clasa? Sfârșit

Vrem doar ca numele să fie la fel. Faceți-le proprietățile PlayState și le setați la zero.
Dezactivați ultima linie.

 function create () -: void - declaratii variabile PlayState._inGame = true PlayState._background = nil PlayState._ship = nil --PlayState._aliens = nil PlayState._bullets = nil --PlayState._scoreText = nil --PlayState. _gameOverText = nil --PlayState._spawnTimer = nil --PlayState._spawnInterval = 2.5 PlayState._shoot = nil --PlayState.SoundExplosionShip = nil --PlayState.SoundExplosionAlien: Class = nil PlayState.SoundBullet = nil? Sfârșit

Acum vom folosi modulul media pentru a încărca un sunet nou. Puneți acest lucru în partea de jos a sarcinilor:

 funcția create () -: void? PlayState._ship = Ship.new () PlayState._shoot = fals PlayState._bullets = display.newGroup () PlayState.SoundBullet = media.newEventSound ("Bullet.caf") Buttons.buttonHandler (PlayState)? Sfârșit

Reveniți la spawnBullet (). Putem înlocui ultima linie pentru a reda noul nostru sunet.

 funcția spawnBullet (p) -: void local _bullet = Bullet.new (p.x, p.y) PlayState._bulleturi: inserați (_bullet) PlayState._shoot = false media.playEventSound (PlayState.SoundBullet)

Acum trebuie doar să modificăm funcția de actualizare () pentru a obține câteva gloanțe. Verificați dacă este _shoot
adevărat și dacă există. Dacă da, apelați metoda noastră pentru getBulletSpawnPosition () pentru nava noastră
și spawnBullet () în acea locație.

 () dacă PlayState._inGame atunci dacă PlayState._shoot == true și PlayState._ship atunci local p = PlayState._ship: getBulletSpawnPosition () spawnBullet (p) final? sfârșitul final

Gestionarea memoriei de bază

În Flixel, am avut grijă de memorie pentru noi. În Corona, vom fi nevoiți să curățăm obiectele pe care le avem
sunt terminate cu. Să adăugăm o metodă instanță kill () la fiecare glonț pentru a ne ajuta. kill () este
funcția pe care apelatorul automat o apelează atunci când un obiect nu mai este necesar. Adăugați acest lucru la Bullet.lua:

 funcția Bullet (x, y)? funcția de actualizare ()? end function Bullet: kill () Bullet.parent: eliminați (Bullet) Bullet = sfârșitul nilului? Sfârșit

Aceasta este modalitatea corectă de a curăța un obiect din Corona. În primul rând, am eliminat toate legăturile prin eliminarea
din grupul de afișare. Apoi am setat variabila Bullet la zero. Să facem același lucru pentru Ship.
Adăugați aceasta mai jos getBulletSpawnPosition () în Ship.lua:

 functionare Nave: kill () Nave: removeSelf () Ship = nil Durata de executie: removeEventListener ("enterFrame", update) end

Observați că am oprit actualizarea de la a fi apelată la fiecare cadru (deoarece nava nu există
mai).

Manipularea gloanțelor off-screen

Înapoi în Bullet.lua, să adăugăm un cec la fiecare cadru pentru a vedea dacă glonțul este în afara ecranului.
În prezent, codul nostru continuă să deseneze gloanțe chiar dacă nu pot fi văzute. Aceasta este o pierdere a resurselor limitate ale dispozitivului. Înlocuiți actualizarea () cu aceasta:

 function update () daca Bullet atunci daca (Bullet.x < display.contentWidth) then Bullet.x = Bullet.x + 10 else Bullet:kill() end end end

Acum, glonțul se va deplasa spre dreapta numai dacă se poate vedea. În caz contrar, se va numi la îndemână
kill () funcție.

Colectarea gunoiului

Lua are un colector de gunoi automat care manipulează coșurile de gunoi ca variabilele neutilizate, obiectele de afișare care au fost eliminate de pe ecran și orice altceva care nu mai este necesar. Putem să-i spunem lui Lua să adune gunoi adăugând această linie la sfârșitul creării în PlayState:

 funcția create ()? collectgarbage ("colecta") sfârșitul

Concluzie

Aceasta începe să arate ca un joc acum. Nava noastră se poate deplasa pe ecran și gloanțe de foc.
gloanțele se ocupă de ele însele atunci când nu mai sunt necesare. Acum avem nevoie doar de niște dușmani.

Cod