Välkommen till del två av Hur man blåser upp saker med Corona SDK handledning serien. I denna handledning kommer vi att förbättra vår demo-app från del I genom att tillåta användaren att placera en verklig bombgrafik på skärmen med en tidsfördröjd explosion. Vi kommer också att ändra explosionseffekten för att ibland orsaka att kasser verkligen exploderar istället för att bara flyga från skärmen.
I del I i den här serien fick vi en känsla för hur man ställer in en dynamisk miljö med Coronas lättanvända fysikbibliotek. Miljön inkluderade statiska föremål, såsom golvet, och programmatiskt genererade dynamiska objekt som kasser. En användar-touch-händelse skulle då generera en explosiv kraft som skulle skicka kassorna som flyger. Om du inte har läst del I ändå föreslår jag att du gör det innan du fortsätter. Läsaren bör ha viss förståelse för de grundläggande fysikbegreppen som förklaras i del I för att kunna förstå del II.
Låt oss börja med en liten uppdatering om hur vi installerar vår fysikmiljö i del I. Vi kommer att inkludera vår programmatiskt genererade uppsättning lådor som staplas och sitter på vårt golv:
Lokal fysik = kräver (fysik) fysik.start () physics.setScale (40) display.setStatusBar (display.HiddenStatusBar) - Den slutliga "sanna" parametern överskrider Coronas automatisk skalning av stora bilder lokal bakgrund = display.newImage ("bricks.png", 0, 0, true) background.x = display.contentWidth / 2 background.y = display.contentHeight / 2 lokala våningen = display.newImage ("floor.png", 0, 280, true) fysik.addBody (golv, "statisk", friktion = 0,5) lokala kasser = för i = 1, 5 gör för j = 1, 5 kasser [i] = display.newImage ("crate.png" 140 + (i * 50), 220 - (j * 50)) fysik.addBody (kasser [i], densitet = 0,2, friktion = 0,1, studs = 0,5) ändänden
Alla arbeten med ovanstående kod förklaras fullständigt i del I i handledningen så kolla om något verkar förvirrande.
För vårt första steg ska vi lägga till en liten grafisk uppdatering till vår setBomb-metod. Istället för en touch-händelse som genast genererar explosionen kommer vi att placera en bomb på skärmen som sitt eget fysikobjekt:
lokal funktion setBomb (händelse) om (event.phase == "började") sedan lokal bomb = display.newImage ("bomb.png", event.x, event.y) physics.addBody (bomb, densitet = 0.2, friktion = 0,1, studsa = 0,5) ändändamål: addEventListener ("touch", setBomb)
Precis som tidigare lägger vi till en händelseloggare i bakgrunden för att titta på eventuella beröringshändelser och avfyra setBomb-metoden när man inträffar. Inuti metoden isolerar vi någon aktivitet till händelsens "startade" fas. Om vi inte isolerade den här fasen skulle det leda till att koden exekveras flera gånger, eftersom beröringshändelser har många faser.
SetBomb-metoden som den står nu gör väldigt lite. Det laddar en snygg bombarderande grafik och lägger den till skärmen som ett dynamiskt fysikobjekt. Nu integrerar vi vår explosionsmetod tillbaka i koden som en lokal funktion som heter blast:
lokal cirkel = "" lokal explosion = "" lokal funktion blast (händelse) cirkel = display.newCircle (bomb.x, bomb.y, 80) explosion = display.newImage ("explosion.png", bomb.x, bomb. y) cirkel: setFillColor (0,0,0, 0) physics.addBody (cirkel, "static", isSensor = true) circle.myName = "cirkel" circle.collision = onLocalCollision-cirkel: addEventListener ("collision" cirkel) slutblast ()
Cirkelobjektet här hjälper oss att beräkna vår blastradie. Vi lägger till en kollisionshändelselyttare för att upptäcka vilken av lådorna som faller inom sprängzonen. Dessutom lägger vi också till en explosionsgrafik på skärmen i samma position som bomben grafik när sprängningen går av.
Om du försöker koden ut vid den här tiden kommer du märka att allt händer riktigt snabbt och vissa artefaktgrafik lämnas kvar. För att göra det mer spännande, kommer vi att ersätta vårt "blast ()" funktionssamtal med en timer som försenar explosionen av bomben med 3 sekunder:
timer.performWithDelay (3000, blast)
Enkelt som det! Timerklassen har en funktion som kallas performWithDelay () med två parametrar: antalet millisekunder att vänta och metoden att ringa. Så, i detta fall är 3 000 millisekunder lika med 3 hela sekunders fördröjning.
Eftersom bomben kommer att explodera efter 3 sekunders fördröjning, måste vi ta bort det här objektet från skärmen när sprängningen inträffar. Detta kan göras mycket enkelt. Alla objekt som är närvarande på skärmen kommer med en praktisk removeSelf () funktion. När ett objekt tar bort sig från skärmen är fysikmotorn tillräckligt smart för att skräp samla och ta bort det från alla fysikberäkningar också. Vi kan lägga till följande rad längst ner i blastfunktionen:
bomb: removeSelf ()
Förutom att ta bort bomben kommer vi att ta bort vårt cirkelblastradiobjekt liksom explosionsgrafiken som vi lagt till för effekt. Eftersom vi behöver ge vår cirkel runt sprängradie lite tid för att skapa kollisioner med våra lådor, kommer vi att ta bort den 1/10: e sekunden efter att vi kallar blastfunktionen. Detta kan åstadkommas genom att ersätta vårt tidsinställda funktionssamtal med följande kod:
lokal funktion removeStuff (händelse) cirkel: removeSelf () explosion: removeSelf () end timer.performWithDelay (3000, blast) timer.performWithDelay (3100, removeStuff)
Som du kan se ringer vi blastfunktionen efter en 3 sekunders fördröjning från att röra på skärmen samma som vi var tidigare. Vi har nu lagt till ett annat fördröjt samtal som körs 3,1 sekunder efter att du rörde skärmen som rensar upp våra återstående objekt med funktionen removeSelf ().
Hela funktionen som vi skapade ser så här ut:
lokal funktion setBomb (händelse) om (event.phase == "började") sedan lokal bomb = display.newImage ("bomb.png", event.x, event.y) physics.addBody (bomb, densitet = 0.2, friktion = 0,1, studs = 0.5) lokal cirkel = "" lokal explosion = "" lokal funktion blast (händelse) media.playEventSound (explosionSound) cirkel = display.newCircle (bomb.x, bomb.y, 80) explosion = display .newImage ("explosion.png", bomb.x, bomb.y) bomb: removeSelf () cirkel: setFillColor (0,0,0, 0) physics.addBody (cirkel, "statisk", isSensor = true) circle.myName = "circle" circle.collision = onLocalCollision cirkel: addEventListener ("kollision", cirkel) avsluta lokal funktion removeStuff (event) cirkel: removeSelf () explosion: removeSelf () end timer.performWithDelay (3000, blast) timer. performWithDelay (3100, removeStuff) slutet ända bakgrund: addEventListener ("touch", setBomb)
I del I i vår handledning såg vår kollisionsdetekteringsfunktion så här:
lokal funktion onLocalCollision (själv, händelse) om (event.phase == "började" och self.myName == "circle") då local forcex = event.other.x-self.x local forcey = event.other.y- self.y om (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
Det hittade helt enkelt alla lådor inom vår blastradie och applicerade en kraft för att spränga dem bort från explosionscentrets epicentrum. För att göra sakerna mer intressanta kommer vi att lägga till ett tröskelvärde för destruktion till kasser som kommer att få dem att explodera om den kraft som tillämpas på dem är tillräckligt hög. Det kan göras så här:
om (math.abs (forcex)> 60 eller math.abs (forcey)> 60) sedan lokal explosion = display.newImage ("explosion.png", event.other.x, event.other.y) event.other.other: removeSelf () lokal funktion removeExplosion (event) explosion: removeSelf () end timer.performWithDelay (100, removeExplosion) end
Vi måste observera den kraft som vi tillämpade på varje lådor för att upptäcka om den är högre än 60. 60 i det här fallet i ett godtyckligt tal baserat på vår kraftberäkning. Vi använder math.abs-funktionen för att få det absoluta värdet av kraften. I vårt exempel kan krafter vara positiva eller negativa beroende på den applicerade krafts riktning. Vi är inte oroliga för riktning i det här fallet, vi vill helt enkelt veta om kraften överstiger tröskelvärdet 60. Känn fritt att spela med detta tröskelnummer för att ändra hur svagt eller starkt lådorna är.
I del I beräknades vår explosionskraft på ett sätt som gör att det minskar ju längre en kista är från sprängets epicentrum. Så kasser som är närmare epicentret har en större sannolikhet att bli förstörda, och de andra kommer helt enkelt att flyga bort från skärmen. Som vi gjorde tidigare med vår tidsklass, visar vi en explosionsgrafik i en förstörd kista, och sedan tar vi bort den från skärmen 1 / 10th av en sekund senare. Den slutliga kollisionsdetekteringsmetoden kommer att se ut så här:
lokal funktion onLocalCollision (själv, händelse) om (event.phase == "började" och self.myName == "circle") då local forcex = event.other.x-self.x local forcey = event.other.y- self.y om (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 eller math.abs (forcey)> 60) sedan lokal explosion = display.newImage ("explosion.png", event.other.x, event.other.y) event.other: removeSelf () lokal funktion removeExplosion (event) explosion: removeSelf () end timer.performWithDelay (50, removeExplosion) ändänden
Som ett sista steg i vår handledning kommer vi att spela en explosionsljudseffekt när vår bomb exploderar. Precis som allt annat i Corona är det överraskande enkelt att göra detta. Vi börjar med att inkludera mediebiblioteket längst upp i vårt projekt och förladdning av vår ljudfil:
lokala medier = kräver ("media") lokal explosionSound = media.newEventSound ("explosion.mp3")
För att spela ljudet lägger vi till följande rad i vår blast () -funktion som ligger inne i vår setBomb () -funktion:
lokal funktion blast (händelse) media.playEventSound (explosionSound)? slutet
Nu när som helst blast () -funktionen heter, kommer den att använda funktionen playEventSound från mediebiblioteket för att spela vår "explosion.mp3" ljudfil. Det kunde inte bli enklare om vi försökte!
Och där har vi det! Vi har nu ett mer komplett exempel på hur lätt det är att skapa explosioner i Corona-plattformen. Ta gärna ner blixtlådorna för både del I och II i handledningen och spela om!