Welkom bij deel twee van de Hoe dingen opvullen met de Corona SDK tutorial series. In deze tutorial verbeteren we onze demo-app van deel I door de gebruiker toe te staan een echte bomafbeelding op het scherm te plaatsen met een tijdvertraagde explosie. We zullen ook het explosie-effect wijzigen om af en toe ervoor te zorgen dat kratten daadwerkelijk exploderen in plaats van gewoon van het scherm te vliegen.
In deel I van deze serie hebben we een idee gekregen hoe we een dynamische omgeving kunnen instellen met de eenvoudig te gebruiken Physics-bibliotheek van Corona. De omgeving omvatte statische objecten, zoals de vloer, en programmatisch gegenereerde dynamische objecten zoals kratten. Een user touch-evenement zou dan een explosieve kracht genereren die de kratten zou laten vliegen. Als je deel I nog niet hebt gelezen, raad ik je aan dit te doen voordat je verdergaat. De lezer moet enig begrip hebben van de essentiële fysica-concepten die in Deel I zijn uitgelegd om Deel II te kunnen begrijpen.
Laten we beginnen met een kleine opfriscursus over hoe we onze fysica-omgeving instellen in deel I. We nemen onze programmatisch gegenereerde set kratten op die op onze vloer zijn gestapeld en zitten:
local physics = require ("physics") physics.start () physics.setScale (40) display.setStatusBar (display.HiddenStatusBar) - De laatste "true" -parameter overschrijft Corona's automatische schaal van grote afbeeldingen lokale achtergrond = display.newImage ("bricks.png", 0, 0, true) background.x = display.contentWidth / 2 background.y = display.contentHeight / 2 local floor = display.newImage ("floor.png", 0, 280, true) physics.addBody (floor, "static", friction = 0.5) local crates = voor i = 1, 5 do voor j = 1, 5 do crates [i] = display.newImage ("crate.png", 140 + (i * 50), 220 - (j * 50)) physics.addBody (crates [i], density = 0.2, friction = 0.1, bounce = 0.5) end end
Alle bewerkingen van de bovenstaande code worden volledig uitgelegd in deel I van de tutorial, dus kijk eens of iets verwarrend lijkt.
Voor onze eerste stap gaan we een beetje grafische update toevoegen aan onze setBomb-methode. In plaats van een aanraakgebeurtenis die onmiddellijk de explosie genereert, plaatsen we een bom op het scherm als zijn eigen fysica-object:
local function setBomb (event) if (event.phase == "started") then local bomb = display.newImage ("bomb.png", event.x, event.y) physics.addBody (bomb, dichtheid = 0.2, wrijving = 0.1, bounce = 0.5) achtergrond einde end: addEventListener ("touch", setBomb)
Net als voorheen voegen we een gebeurtenislistener toe aan de achtergrond om naar elke aanraakgebeurtenis te kijken en de methode setBomb af te vuren wanneer er zich een voordoet. Binnen de methode isoleren we elke activiteit in de "begonnen" fase van het evenement. Als we deze fase niet isoleren, zou dit ertoe leiden dat de code meerdere keren wordt uitgevoerd omdat aanraakgebeurtenissen vele fasen hebben.
De setBomb-methode zoals die nu staat, doet heel weinig. Het laadt een leuk uitziende bomafbeelding en voegt deze toe aan het scherm als een dynamisch fysica-object. Nu zullen we onze explosiemethode weer in de code integreren als een lokale functie genaamd blast:
local circle = "" local explosion = "" lokale functie blast (event) circle = display.newCircle (bomb.x, bomb.y, 80) explosion = display.newImage ("explosion.png", bomb.x, bomb. y) circle: setFillColor (0,0,0, 0) physics.addBody (circle, "static", isSensor = true) circle.myName = "circle" circle.collision = onLocalCollision circle: addEventListener ("collision", cirkel) einde explosie ()
Het cirkelobject helpt ons hier om onze straal te berekenen. We voegen een botsingsgebeurtenislistener toe om te detecteren welke van de kratten in de ontploffingszone valt. Daarnaast voegen we een explosie-afbeelding toe aan het scherm op dezelfde positie als de bomafbeelding zodra de ontploffing afgaat.
Als u de code op dit punt uitprobeert, zult u merken dat alles heel snel gebeurt en dat sommige artefact-afbeeldingen achterblijven. Om het spannender te maken, gaan we onze functie "blast ()" vervangen door een timer die de explosie van de bom met 3 seconden vertraagt:
timer.performWithDelay (3000, blast)
Simpel als dat! De timer-klasse heeft een functie met de naam performWithDelay () met twee parameters: het aantal milliseconden dat moet worden gewacht en de methode om te bellen. In dit geval is de 3000 milliseconden gelijk aan 3 hele seconden vertraging.
Omdat de bom na de vertraging van 3 seconden explodeert, moeten we dit object van het scherm verwijderen zodra de explosie optreedt. Dit kan heel gemakkelijk worden gedaan. Alle objecten die op het scherm aanwezig zijn, worden geleverd met een handige functie removeSelf (). Zodra een object zichzelf van het scherm verwijdert, is de Physics-engine slim genoeg om deze te verzamelen en te verwijderen uit alle natuurkundige berekeningen. We kunnen de volgende regel toevoegen aan de onderkant van de explosiefunctie:
bomb: removeSelf ()
Naast het verwijderen van de bom, gaan we ons straal-straal-object verwijderen evenals de explosie-afbeelding die we hebben toegevoegd voor effect. Omdat we onze explosie radiuscirkel een beetje tijd moeten geven om botsingen met onze kratten te maken, gaan we deze 1 / 10e van een seconde verwijderen nadat we de explosie-functie hebben genoemd. Dit kan worden bereikt door onze getimede blastfunctie-oproep te vervangen door de volgende code:
lokale functie removeStuff (event) circle: removeSelf () explosion: removeSelf () end timer.performWithDelay (3000, blast) timer.performWithDelay (3100, removeStuff)
Zoals je kunt zien, bellen we de explosiefunctie na een vertraging van 3 seconden om het scherm hetzelfde aan te raken als voorheen. We hebben nu een nieuwe uitgestelde oproep toegevoegd die 3,1 seconden wordt uitgevoerd nadat we het scherm hebben aangeraakt dat onze resterende objecten opruimt met de functie removeSelf ().
De volledige functie die we nu hebben gemaakt ziet er als volgt uit:
local function setBomb (event) if (event.phase == "started") then local bomb = display.newImage ("bomb.png", event.x, event.y) physics.addBody (bomb, dichtheid = 0.2, wrijving = 0.1, bounce = 0.5) lokale cirkel = "" lokale explosie = "" lokale functie blast (gebeurtenis) media.playEventSound (explosionSound) circle = display.newCircle (bomb.x, bomb.y, 80) explosion = display .newImage ("explosion.png", bomb.x, bomb.y) bomb: removeSelf () circle: setFillColor (0,0,0, 0) physics.addBody (circle, "static", isSensor = true) circle.myName = "circle" circle.collision = onLocalCollision circle: addEventListener ("collision", circle) end local function removeStuff (event) circle: removeSelf () explosion: removeSelf () end timer.performWithDelay (3000, blast) timer. perform EndDelay (3100, removeStuff) end end background: addEventListener ("touch", setBomb)
In deel I van onze tutorial zag onze botsdetectiefunctie er als volgt uit:
lokale functie op LocalCollision (self, event) if (event.phase == "started" en self.myName == "circle") dan local forcex = event.other.x-self.x local forcey = event.other.y- self.y if (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
Het vond eenvoudigweg alle kratten in onze explosie straal en bracht een kracht aan om ze weg te schieten uit het epicentrum van de explosie. Om dingen interessanter te maken, gaan we een vernietigingsdrempel toevoegen aan de kratten die ervoor zorgen dat ze exploderen als de kracht die erop wordt toegepast hoog genoeg is. Het kan zo gedaan worden:
if (math.abs (forcex)> 60 of math.abs (forcey)> 60) dan local explosion = display.newImage ("explosion.png", event.other.x, event.other.y) event.other: removeSelf () lokale functie removeExplosion (event) explosion: removeSelf () end timer.performWithDelay (100, removeExplosion) end
We moeten de kracht observeren die we hebben toegepast op elk van de kratten om te detecteren of deze hoger is dan 60. 60 in dit geval in een willekeurig aantal op basis van onze krachtberekening. We gebruiken de functie math.abs om de absolute waarde van de kracht te krijgen. In ons voorbeeld kunnen krachten positief of negatief zijn, afhankelijk van de richting van de uitgeoefende kracht. In dit geval maken we ons geen zorgen over de richting, we willen gewoon weten of de kracht de drempelwaarde van 60 overschrijdt. Speel met dit drempelnummer om te veranderen hoe zwak of sterk de kratten zijn.
In Deel I werd onze explosiekracht berekend op een manier waardoor het minder werd naarmate een kist zich verder uit het epicentrum van de explosie bevond. Dus kratten die dichter bij het epicentrum liggen, hebben een grotere kans om te worden vernietigd en de anderen vliegen gewoon van het scherm. Zoals we eerder deden met onze timer-klasse, laten we een explosie-afbeelding zien in de voormalige positie van een vernietigde kist, en dan verwijderen we deze een kwart van een seconde later van het scherm. De uiteindelijke botsingsdetectiemethode ziet er als volgt uit:
lokale functie op LocalCollision (self, event) if (event.phase == "started" en self.myName == "circle") dan local forcex = event.other.x-self.x local forcey = event.other.y- self.y if (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 of math.abs (geforceerd)> 60) dan lokale explosie = display.newImage ("explosion.png", event.other.x, event.other.y) event.other: removeSelf () local function removeExplosion (event) explosion: removeSelf () end timer.performWithDelay (50, removeExplosion) end end end
Als laatste stap in onze tutorial gaan we een explosie-effect spelen wanneer onze bom explodeert. Zoals alles in Corona is het verrassend eenvoudig om dit te doen. We beginnen met het toevoegen van de mediabibliotheek bovenaan ons project en het vooraf laden van ons geluidsbestand:
lokale media = vereisen ("media") lokale explosionSound = media.newEventSound ("explosion.mp3")
Om het geluid te spelen, voegen we de volgende regel toe aan onze blast () -functie in onze setBomb () -functie:
lokale functie blast (event) media.playEventSound (explosionSound)? einde
Als de blast () -functie wordt aangeroepen, gebruikt deze nu de functie playEventSound uit de mediabibliotheek om ons "explosion.mp3" -bestand af te spelen. Het kan niet eenvoudiger zijn als we het geprobeerd hebben!
En daar hebben we het! We hebben nu een completer voorbeeld van hoe gemakkelijk het is om explosies te creëren op het Corona-platform. Download de ritsen voor deel I en deel II van de zelfstudie en speel wat rond!