Cum să suflați lucrurile cu motorul fizic SDK Corona Partea 2

Bine ați venit în partea a doua a site-ului Cum să suflați lucrurile cu SDK Corona tutorial serie. În acest tutorial, vom îmbunătăți aplicația noastră demo de la partea I, permițând utilizatorului să introducă pe ecran un grafic cu bombă reală, cu o explozie întârziată. Vom modifica, de asemenea, efectul de explozie pentru a provoca ocazional lăzi să explodeze, mai degrabă decât să zboare de pe ecran.

În partea I a acestei serii, am simțit cum să configuram un mediu dinamic cu biblioteca fizică ușor de utilizat a Coronei. Mediul a inclus obiecte statice, cum ar fi podeaua, și obiecte dinamice generate în mod programat, cum ar fi cutii. Un eveniment tactil de utilizator ar genera apoi o forță explozivă care ar trimite cutiile care zboară. Dacă nu ați citit încă o parte, vă sugerăm să o faceți înainte de a continua. Cititorul ar trebui să aibă o înțelegere a conceptelor fizice esențiale explicate în Partea I pentru a putea înțelege Partea a II-a.

Perfecționare

Să începem cu o mică actualizare a modului în care ne-am configurat mediul fizic în partea I. Vom include setul de cutii generat programat, care sunt stivuite și așezate pe etajul nostru:

 fizica fizica.start () physics.setScale (40) display.setStatusBar (display.HiddenStatusBar) - Parametrul final "adevărat" suprascrie ajustarea automată a imaginilor mari de la Corona local background = display.newImage ("bricks.png", 0, 0, adevărat) background.x = display.contentWidth / 2 background.y = display.contentHeight / 2 etaj local = display.newImage ("floor.png" (fricțiune = 0.5) cutii locale =  pentru i = 1, 5 pentru j = 1, 5 pentru a face cratițe [i] = display.newImage ("crate.png" 140 + (i * 50), 220 - (j * 50)) fizics.addBody (cutii [i], densitate = 0.2, frecare = 0.1,

Toate lucrările codului de mai sus sunt explicate pe deplin în Partea I a tutorialului, deci verificați dacă ceva pare confuz.

Stabiliți bomba!

Pentru primul nostru pas vom adăuga o mică actualizare grafică la metoda setBomb. În locul unui eveniment tactil care generează imediat explozia, vom plasa o bomba pe ecran ca obiect al fizicii proprii:

 funcția locală setBomb (eveniment) dacă (event.phase == "a început") apoi bombul local = display.newImage (bomb.png, event.x, event.y) fizics.addBody friction = 0.1, bounce = 0.5) end end fundal: addEventListener ("touch", setBomb)

La fel ca înainte, adăugăm un fundal pentru a urmări eventualele evenimente de atingere și a declanșa metoda setBomb când apare. În cadrul metodei, izolam orice activitate în faza "început" a evenimentului. Dacă nu am izola această fază, rezultatul ar fi ca codul să fie executat de mai multe ori, iar evenimentele touch au multe faze.

Metoda setBomb în starea actuală este foarte mică. Încarcă o grafică cu bomba frumoasă și o adaugă pe ecran ca un obiect fizic dinamic. Acum vom integra metoda noastră de explozie în cod ca o funcție locală numită explozie:

 cerc local = "" explozie locală "" "funcția locală explozie (eveniment) cerc = display.newCircle (bomb.x, bomb.y, 80) explozie = display.newImage (" explosion.png ", bomb.x, bomb). y) cerc: setFillColor (0,0,0, 0) fizics.addBody (cerc, "static", isSensor = true) cerc.myName = cerc circle.collision = cercLocalCollision: addEventListener (collision, cerc) sfârșitul exploziei ()

Obiectul cercului de aici ne ajută să calculam raza noastră de explozie. Adăugăm un ascultător de evenimente de coliziune pentru a detecta care dintre cutii intră în zona de explozie. În plus, adăugăm de asemenea un grafic de explozie pe ecran în aceeași poziție cu graficul bombei, odată ce explozia se stinge.

Cu timpul

Dacă încercați codul în acest moment, veți observa că totul se întâmplă într-adevăr rapid și că unele grafice artefacte sunt lăsate în urmă. Pentru a face mai suspans, vom înlocui apelul nostru de funcții "blast ()" cu un temporizator care va întârzia explozia bombei cu 3 secunde:

 timer.performWithDelay (3000, explozie)

Simplu ca asta! Clasa timer are o funcție numită performWithDelay () cu doi parametri: numărul de milisecunde de așteptare și metoda de apelare. Deci, în acest caz, cele 3.000 de milisecunde reprezintă 3 secunde de întârziere.

Eliminarea artefactelor

Deoarece bomba va exploda după întârzierea de 3 secunde, trebuie să scoatem acest obiect de pe ecran după ce se produce explozia. Acest lucru se poate face foarte usor. Toate obiectele care sunt prezente pe ecran vin cu o functie removeSelf (). Odată ce un obiect se îndepărtează de pe ecran, motorul fizic este suficient de inteligent pentru a colecta și elimina gunoiul din toate calculele fizicii. Putem adăuga următoarea linie în partea de jos a funcției de explozie:

 bombă: removeSelf ()

În plus față de înlăturarea bombei, vom elimina obiectul de rază de cerc al exploziei, precum și graficul de explozie pe care l-am adăugat pentru efect. Din moment ce trebuie să dăm cercului nostru de rază un pic de timp pentru a crea coliziuni cu cutiile noastre, vom elimina 1/10 din secundă după ce vom numi funcția de explozie. Acest lucru poate fi realizat prin înlocuirea apelului nostru cu funcția de explozie temporizată cu următorul cod:

 funcția locală removeStuff (event) cerc: removeSelf () explozie: removeSelf () end timer.performWithDelay (3000, blast) timer.performWithDelay (3100, removeStuff)

După cum puteți vedea, sunăm funcția de blastică după o întârziere de 3 secunde de la atingerea ecranului la fel ca înainte. Am adăugat acum un alt apel întârziat, care este executat în 3,1 secunde după atingerea ecranului care curăță obiectele rămase cu funcția removeSelf ().

Întreaga funcție pe care am creat-o acum arată astfel:

 funcția locală setBomb (eveniment) dacă (event.phase == "a început") apoi bombul local = display.newImage (bomb.png, event.x, event.y) fizics.addBody fricțiune = 0.1, bounce = 0.5) cerc local = "" explozie locală "" "funcția locală explozie (eveniment) media.playEventSound (explosionSound) cerc = display.newCircle (bomb.x, bomb.y, 80) .newImage ("exploion.png", bomb.x, bomb.y) bombă: removeSelf () cerc: setFillColor (0,0,0, 0) fizics.addBody (cerc, "static", isSensor = true) Cercul: removeStuff (event) cerc: removeSelf () explozie: removeSelf () end timer.performWithDelay (3000, blast) cronometru. performWithDelay (3100, removeStuff) fundal final sfârșit: addEventListener ("touch", setBomb)

Crearea unui prag de distrugere

În partea I a tutorialului nostru, funcția noastră de detectare a coliziunilor a arătat astfel:

 funcția locală onLocalCollision (auto, eveniment) în cazul în care (event.phase == "a început" și self.myName == "cerc"), apoi forcex = event.other.x-self.x local forcey = auto.y dacă (forcex < 0) then forcex = 0-(80 + forcex)-12 else forcex = 80 - forcex+12 end event.other:applyForce( forcex, forcey, self.x, self.y ) end end

Pur și simplu a găsit toate lăzile din raza noastră de aprindere și a aplicat o forță pentru a le distruge de epicentrul exploziei. Pentru a face lucrurile mai interesante, vom adăuga un prag de distrugere la lăzile care le va face să explodeze dacă forța aplicată lor este suficient de mare. Se poate face astfel:

 dacă (math.abs (forcex)> 60 sau math.abs (forcey)> 60), atunci explozia locală = display.newImage ("exploion.png", event.other.x, event.other.y) removeSelf () funcția locală removeExplosion (eveniment) explozie: removeSelf () end timer.performWithDelay (100, removeExplosion) sfârșit

Trebuie să observăm forța pe care am aplicat-o pentru fiecare dintre cutii pentru a detecta dacă este mai mare decât 60. 60 în acest caz într-un număr arbitrar bazat pe calculul forței noastre. Folosim funcția math.abs pentru a obține valoarea absolută a forței. În exemplul nostru, forțele pot fi pozitive sau negative în funcție de direcția forței aplicate. Nu suntem îngrijorați de direcție în acest caz, pur și simplu vrem să știm dacă forța depășește pragul de 60. Simțiți-vă liber să jucați cu acest număr de prag pentru a schimba cât de slabi sau puternici sunt lăzile.

În Partea I, forța noastră de explozie a fost calculată într-un mod care determină diminuarea în continuare a unei cutii de la epicentrul exploziei. Astfel, cutiile care sunt mai aproape de epicentrul au o probabilitate mai mare de a fi distruse, iar ceilalți pur și simplu vor zbura de pe ecran. Așa cum am făcut înainte cu clasa noastră de timp, afișăm un grafic de explozie în poziția anterioară a unei cutii distruse și apoi îl scoatem din ecran 1/10 din secundă mai târziu. Metoda finală de detectare a coliziunilor va arăta astfel:

 funcția locală onLocalCollision (auto, eveniment) în cazul în care (event.phase == "a început" și self.myName == "cerc"), apoi forcex = event.other.x-self.x local forcey = auto.y dacă (forcex < 0) then forcex = 0-(80 + forcex)-12 else forcex = 80 - forcex+12 end event.other:applyForce( forcex, forcey, self.x, self.y ) if(math.abs(forcex) > 60 sau math.abs (forță)> 60), apoi explozie locală = display.newImage ("exploion.png", event.other.x, event.other.y) eveniment.other: removeSelf () funcția locală removeExplosion explozie: removeSelf () end timer.performWithDelay (50, removeExplosion) end end end

Sunet pornit!

Ca ultim pas în tutorialul nostru, vom juca un efect de sunet exploziv când explodează bomba noastră. Ca orice altceva în Corona, este surprinzător de simplu să faci asta. Vom începe prin includerea bibliotecii media în partea de sus a proiectului nostru și preîncărcarea fișierului nostru de sunet:

 media locală = necesită ("media") explozie localăSound = media.newEventSound ("exploion.mp3")

Pentru a reda sunetul vom adăuga următoarea linie la funcția noastră de explozie () care se află în interiorul funcției setBomb ():

 funcția locală explozie (eveniment) media.playEventSound (explozie)? Sfârșit

Acum, oricând este apelată funcția de explozie (), va folosi funcția playEventSound din biblioteca media pentru a reda fișierul de sunet "explosion.mp3". Nu ar fi mai ușor dacă am încerca!

Și acolo avem! Acum avem un exemplu mai complet despre cât de ușor este să creați explozii în platforma Corona. Simțiți-vă liber să descărcați zipurile pentru partea I și II a tutorialului și să jucați în jur!

Cod