Construiește un joc fără sfârșit de la zero Obstacole și dușmani

Bine ați venit în a șasea parte din seria noastră de instruire Endless Runner! Jocul nostru începe să se formeze și se simte mai lustruit. După ce ați finalizat pașii de astăzi, va fi mult mai interactiv și mai distractiv să jucați. Vom adăuga încă două evenimente care vor crea noi provocări interesante pentru jucători. Mai întâi, vom adăuga capacitatea eroului nostru de a trage un mic bolț pentru a elimina obstacolele care vin spre el. Rețineți că imaginea mică "albastră" este declanșată de monstrul nostru. Imaginile cu care lucrăm nu sunt deosebit de profesioniste, deoarece sunt doar pentru practică. După ce monstrul are capacitatea de a trage niște șuruburi, vom adăuga și evenimente care vor trimite obstacole care se vor întoarce spre el. După aceea, vom crea două tipuri de obstacole: primul este un zid spike care va sta pe pământ și va călători la aceeași viteză ca solul, iar al doilea este o fantomă care va zbura din partea dreaptă sus ecranul spre player.

Deci sa începem! Primul lucru pe care trebuie să-l facem este să ne asigurăm că avem toate bunurile în locul potrivit. Descărcați fișierul atașat la acest tutorial, iar în folderul "nou" veți găsi trei elemente noi. De asemenea, puteți să faceți clic dreapta pe imagini și să le salvați în dosarul corect. Imaginile trebuie numite spikeBlock.png, ghost.png și blast.png.

Deschideți fișierul principal.lua care poate fi găsit în dosarul "vechi" al descărcărilor tutorial. Vom începe prin a da jucătorilor noștri capacitatea de a trage, pentru că nu vrem să-i lăsăm fără apărare, deoarece sunt bombardați cu noi provocări! Putem adăuga această abilitate în trei etape. Primul va fi instantierea a 5 bolți și punerea lor într-un grup. Mai degrabă decât să creați și să distrugeți obiecte de fiecare dată când vrem să le folosim, putem fi mai eficienți prin pregătirea lor și stocarea lor în afara ecranului până când trebuie să le folosim. De fapt, vom face același lucru pentru fiecare dintre cele trei imagini diferite, deci mergeți mai departe și adăugați acest cod între unde declarăm viteza variabilă și unde creăm blocurile noastre.

 --creați fantome și setați poziția lor în afara ecranului pentru a = 1, 3, 1 ghost = display.newImage ("ghost.png") ghost.name = ("fantomă" ... a) ghost.id = o fantomă. x = 800 ghost.y = 600 ghost.speed = 0 - variabilă utilizată pentru a determina dacă acestea sunt în joc sau nu ghost.isAlive = false - face fantome transparente și mai mult ... fantomă! ghosts.ropha = .5 fantome: inserați (fantomă) end - crează spikes pentru a = 1, 3, 1 spike = display.newImage ("spikeBlock.png") spike.name = .id = spike.x = 900 spike.y = 500 spike.isAlive = vârfuri false: introduceți (spike) end - creați blasturi pentru a = 1, 5, 1 blast = display.newImage ("blast.png" ) blast.name = ("blast" ... a) blast.id = a blast.x = 800 blast.y = 500 blast.isAlive = explozii false: introduceți (blast) sfârșitul

Observați că toate au caracteristici comune. Trebuie să mergem și să le numim în cazul în care vreți să le referim individual. Le oferim un id, care ne oferă și mai multe opțiuni de referință viitoare. Le oferim coordonatele lor x și y offscreen (se pun imagini similare pe ele). Un alt lucru pe care le oferim tuturor este variabila "viu". Acest lucru este setat la fals în mod prestabilit, deoarece acestea vor sta pe ecran. Oferind sprites această variabilă ne va permite să verificăm rapid dacă sprite este în uz sau nu. Singurul sprite care are ceva diferit este sprite-fantoma. Pentru sprite-uri fantomatice vom adăuga o variabilă de viteză astfel încât să putem avea fantome care se mișcă la viteze aleatorii. De asemenea, vom seta alfa al fantomelor la .5, astfel încât să apară mai mult, să spunem, fantomă!

Următoarele două lucruri pe care trebuie să le facem sunt crearea de grupuri de afișare respective, apoi adăugarea acelor grupuri în grupul de afișare a ecranului astfel încât să le putem vedea în joc. Adăugați-le imediat sub instanțierea celorlalte grupuri de display.

 ghosts locale = display.newGroup () spikes local = display.newGroup () locale blasts = display.newGroup ()

Apoi, mergeți la secțiunea în care adăugăm totul la ecran. Adăugați aceste grupuri de afișare împreună cu restul. Aș face ca noua comandă să pară așa:

 --cea mai mare parte a ordinului aici nu contează atâta timp cât fundalul - în spate și fantomele și monstrul sunt la sfârșitul ecranului: inserați (backbackground) ecran: inserați (backgroundfar) ecran: inserați (backgroundnear1) ecran: insert ) ecran: inserați (blocuri) ecran: introduceți (vârfuri) ecran: inserați (blasts) ecran: inserați (fantome) ecran: inserați (monstru)

Odată ce ai totul înăuntru, ar trebui să arate ceva de genul ăsta, dacă ar fi să îl conduci în perspectiva iPhone 4:

După ce am reușit să adăugăm funcția care actualizează toate șuruburile pe care monstrul nostru le împușcă. Adăugați următoarea funcție sub funcția checkCollisions ().

 function updateBlasts () - pentru fiecare explozie pe care am instantiat-o pentru a vedea ce face pentru a = 1, blasts.numChildren, 1 da - daca explozia nu este in joc, nu trebuie sa verificam nimic daca ( blasts [a] .isAlive == true) apoi (blasts [a]): traduce (5, 0) - dacă explozia sa deplasat de pe ecran, apoi o omorâți și o readuceți la locul său inițial dacă [ a] .x> 550), apoi blasts [a] .x = 800 blasturi [a] .y = 500 blasts [a] .isAlive = sfarsit sfarsit -check pentru coliziuni intre blasts si piroane pentru b = 1, spikes.numChildren, 1 do if (spikes [b] .isAlive == true) atunci dacă (blasts [a] .y - 25> vârfuri [b] .y - 120 și blasts [a] .y + 25 < spikes[b].y + 120 and spikes[b].x - 40 < blasts[a].x + 25 and spikes[b].x + 40 > [a] .x - 25), atunci blasturile [a] .x = 800 blasturi [a] .y = 500 blasturi [a] .isAlive = vârfuri false [b] .x = 900 spikes [b] spikes [b] .isAlive = end end end end -check pentru coliziuni între explozii și fantome pentru b = 1, ghosts.numChildren, 1 do if (fantome [b] .isAlive == true), atunci dacă (blasts [ a] .y - 25> fantome [b] .y - 120 și explozii [a] .y + 25 < ghosts[b].y + 120 and ghosts[b].x - 40 < blasts[a].x + 25 and ghosts[b].x + 40 > [a] .x - 25), apoi blasturile [a] .x = 800 blasturi [a] .y = 500 blasturi [a] .isAlive = fantome false [b] .x = 800 fantome [b] fantome [b] .isAlive = false fantome [b] .speed = 0 end end end end end

Funcția de mai sus va avea două responsabilități principale. Primul este să actualizați poziția exploziei și să verificați dacă s-a ciocnit cu ceva. Puteți vedea că atunci când se ciocnește cu ceva, modul în care îl distrugem este să-l mutăm din ecran și să setăm isAlive la false. Aceasta va face șurubul gata de a fi folosit din nou. Altceva pe care ați fi observat-o este că numai instanțiăm cinci șuruburi. Deci, ce se întâmplă dacă toate cele cinci șuruburi sunt deja în joc și utilizatorul încearcă să declanșeze o altă explozie? Nimic! Cu modul în care este setat chiar acum, utilizatorul este limitat la doar cinci explozii active la un moment dat. Acest lucru este ușor de schimbat prin instanțierea mai mult la începutul jocului, dar vă arată cum să setați limite jucătorilor. Aceasta este, de asemenea, o metodă pe care o vom folosi pentru a ne asigura că 50 de fantome nu generează aleatoriu pe ecran o singură dată, ucigând imediat jucătorul.

Apoi trebuie să mergem la funcția atinsă pentru a oferi jucătorului posibilitatea de a trage. Modificați funcția atinsă pentru a se potrivi cu următoarele:

 --singura diferență în funcția atinsă este acum dacă atingeți partea dreaptă a ecranului, monstrul va declanșa o mică funcție albastră a bolțului atins (eveniment) dacă (event.phase == "a început") și apoi dacă (event. X < 241) then if(onGround) then monster.accel = monster.accel + 20 end else for a=1, blasts.numChildren, 1 do if(blasts[a].isAlive == false) then blasts[a].isAlive = true blasts[a].x = monster.x + 50 blasts[a].y = monster.y break end end end end end

În cele din urmă, asigurați-vă că adăugați updateBlasts () la funcția principală de actualizare și că ar trebui să fiți gata să mergeți. Dă-i o încercare și vezi puterea grozavă pe care o are acum monstrul nostru! După ce ați rulat, ar trebui să vedeți ceva de genul:

Acum că jucătorii se pot apăra, să mergem mai departe și să le oferim unele provocări. Ambele evenimente următoare vor fi depășite prin simpla împușcare a acestora o dată. După ce acestea sunt la locul lor, cu toate acestea, vă va fi ușor să le schimbați pentru a se potrivi propriului proiect. Vom începe cu zidul spiralat.

Zidul cu zăbrele va fi pur și simplu plasat pe partea de sus a terenului curent și se va deplasa la aceeași viteză constantă ca și solul din jurul acestuia. Primul lucru pe care trebuie să-l faceți este să adăugați funcția updateSpikes. Chiar sub funcția updateBlasts () adăugați următorul cod:

 --verificați dacă spațiile sunt în viață sau nu, dacă acestea sunt - atunci actualizați-le funcția corespunzătoare updateSpikes () pentru a = 1, spikes.numChildren, 1 do if (spikes [a] .isAlive == true) [a]): traduce (viteza * -1, 0) dacă (spikes [a] .x < -80) then spikes[a].x = 900 spikes[a].y = 500 spikes[a].isAlive = false end end end end

Acest lucru va face același lucru cu funcția updateBlast. Acesta va actualiza pur și simplu poziția peretelui spiralat și va verifica dacă acesta a ieșit din ecran (pe care în prezent nu îl poate face deoarece ar lovi mai întâi jucătorul). În caz contrar, vom verifica dacă ne asigurăm. Ultimul lucru pe care trebuie să-l facem este să facem un eveniment pentru asta. În checkEvent () sub celelalte verificări se adaugă:

 --cu atât mai frecvent doriți să se întâmple evenimente - mai bine ar trebui să efectuați verificările dacă (verificați> 72 și verificați < 81) then inEvent = 12 eventRun = 1 end

Vom adăuga de fapt peretele nostru în funcția updateBlocks (). În acest fel, suntem siguri că avem actualul nivel de nivel. Chiar înainte de a apela checkEvent () introduceți următoarele:

 --prin înființarea spițelor în acest fel, ni se va garanta că - au doar 3 spike-uri cel mult la un moment dat. dacă (inEvent == 12), atunci pentru a = 1, spikes.numChildren, 1 dacă dacă (spikes [a] .isAlive == true) atunci nu faceți altceva spikes [a] .isAlive = true spikes [a]. y = groundLevel - 200 spikes [a] .x = newX sfarsitul sfarsitului final

Ultimul lucru pe care trebuie să-l faceți este să adăugați detecția coliziunilor pentru a vedea dacă jucătorul a intrat în sau nu. Puneți-o imediat sub secțiunea checkCollisions (), unde verificăm coliziunile dintre blocuri și monstru.

 --opriți jocul dacă monstrul intră într-un zid spike pentru a = 1, spikes.numChildren, 1 dacă dacă (spikes [a] .isAlive == true) atunci dacă (collisionRect.y - 10> spikes [a] 170 și vârfuri [a] .x - 40 < collisionRect.x and spikes[a].x + 40 > collisionRect.x), apoi - opriți viteza de monstru = 0 sfârșitul capătului final

Asigurați-vă că adăugați din nou updateSpikes () la funcția principală de actualizare și dați-i o alergare! Ar trebui să aveți acum aceste piroane în calea monștrilor.

Dă-i un vârtej și practică să-i împușc. Nu uitați să testați pentru a vă asigura că coliziunile funcționează corect cu exploziile. De asemenea, asigurați-vă că rularea în pereți ucide player-ul. După ce ați testat acest lucru și sunteți gata pentru mai multe, începeți să puneți codul în loc pentru fantomă.

Punerea fantomei este aproape identică cu a pune zidul înăuntru. Cea mai mare diferență dintre cele două este că, pentru fantomă, vom alege unde să vină și cât de repede călătorește. De asemenea, vom face fantomele să se deplaseze în sus și în jos, astfel încât să se deplaseze mereu acolo unde este utilizatorul. Detaliile speciale de acest fel vor face ca obstacolele să se simtă complet diferite de utilizator, chiar dacă lucrează într-un mod similar.

Să începem din nou adăugând funcția updateGhosts (). În timp ce sunteți la el, continuați și adăugați updateGhosts () la funcția principală de actualizare.

 --(ghosts [a] .isAlive == true) atunci (fantome [a]): traduce (viteza * -1, 0) ) daca (fantomele [a] .y> monster.y) atunci fantomele [a] .y = fantome [a] .y - 1 sfarsit daca [ghosts [a] .y < monster.y) then ghosts[a].y = ghosts[a].y + 1 end if(ghosts[a].x < -80) then ghosts[a].x = 800 ghosts[a].y = 600 ghosts[a].speed = 0 ghosts[a].isAlive = false; end end end end

Apoi reveniți în funcția checkEvent () și adăugați aceasta sub controalele anterioare:

 --eveniment fantomă dacă (bifați> 60 și bifați < 73) then inEvent = 13 eventRun = 1 end

De data aceasta, în loc de a face ca fantomele să se miște de la funcția updateBlocks, o vom face în funcția runEvent (). Adăugați aceasta sub celelalte declarații if:

 --acest lucru va fi un pic diferit pe măsură ce vrem cu adevărat acest lucru - facem jocul să se simtă și mai aleatoriu. schimba unde fantomele - și cât de repede vin la monstru. dacă (inEvent == 13) atunci pentru a = 1, ghosts.numChildren, 1 dacă (ghosts [a] .isAlive == false) atunci fantome [a] .isAlive = fantome adevărate [a] .x = 500 fantome [ a] .y = math.random (-50, 400) fantome [a] .speed = math.random (2,4) capăt sfârșit sfârșit de rupere

Odată ce este acolo, trebuie să verificăm coliziunea dintre monstru și fantome. Adăugați acest lucru pentru a verificaColioane () imediat după ce facem lucrul pentru zidurile spicate:

 --asigurați-vă că jucătorul nu a fost lovit de o fantomă! pentru a = 1, ghosts.numChildren, 1 dacă dacă (ghosts [a] .isAlive == true) atunci dacă (((((monster.y-ghosts [a] .y))<70) and ((monster.y - ghosts[a].y) > -70)) și (fantomele [a] .x - 40 < collisionRect.x and ghosts[a].x + 40 > collisionRect.x)) - apoi opriți viteza de monstru = 0 sfârșitul capătului final

Acum ar trebui să aveți totul în loc, inclusiv fantomele pentru a scăpa!

Jocul ar trebui acum să fie mult mai distractiv și mai dificil pentru utilizatori. În următorul tutorial vom adăuga încă două lucruri care vor face jocul să se simtă mai complet: (1) un sistem de notare și (2) moartea monștrilor! Am acoperit mult în acest tutorial, așa că, dacă aveți întrebări, vă rugăm să vă faceți griji în comentariile de mai jos. Vă mulțumim pentru lectură!

Cod