Cómo hacer explotar cosas con el motor de física de Corona SDK Parte 2

Bienvenido a la segunda parte de la Cómo hacer estallar con el SDK de Corona serie tutorial En este tutorial, mejoraremos nuestra aplicación de demostración de la parte I al permitirle al usuario colocar un gráfico de bomba real en la pantalla con una explosión retardada. También modificaremos el efecto de explosión para ocasionar que las cajas exploten en lugar de volar fuera de la pantalla..

En la parte I de esta serie, tenemos una idea de cómo configurar un entorno dinámico con la biblioteca de Física fácil de usar de Corona. El entorno incluía objetos estáticos, como el piso, y objetos dinámicos generados mediante programación, como cajas. Un evento táctil del usuario generaría una fuerza explosiva que haría volar las cajas. Si aún no ha leído la parte I, le sugiero que lo haga antes de continuar. El lector debe tener cierta comprensión de los conceptos de física esenciales explicados en la Parte I para poder entender la Parte II..

Refresco

Comencemos con un poco de actualización sobre cómo configuramos nuestro entorno de física en la parte I. Incluiremos nuestro conjunto de cajas generadas mediante programación que se apilan y se sientan en nuestro piso:

 local physics = require ("physics") physics.start () physics.setScale (40) display.setStatusBar (display.HiddenStatusBar): el último parámetro "true" anula la escala automática de Corona de imágenes grandes background background = display.newImage ("bricks.png", 0, 0, verdadero) 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 =  para i = 1, 5 do para j = 1, 5 do crates [i] = display.newImage ("crate.png", 140 + (i * 50), 220 - (j * 50)) physics.addBody (cajas [i], densidad = 0.2, fricción = 0.1, rebote = 0.5) end end

Todo el funcionamiento del código anterior se explica completamente en la Parte I del tutorial, así que compruebe si algo parece confuso..

Poner la bomba!

Para nuestro primer paso, vamos a agregar una pequeña actualización gráfica a nuestro método setBomb. En lugar de que un evento táctil genere inmediatamente la explosión, colocaremos una bomba en la pantalla como su propio objeto de física:

 función local setBomb (evento) si (evento.fase == "comenzó") luego local bomba = pantalla.newImage ("bomba.png", evento.x, evento.y) physics.addBody (bomba, densidad = 0.2, fricción = 0.1, rebote = 0.5) fondo final final: addEventListener ("touch", setBomb)

Al igual que antes, estamos agregando un detector de eventos al fondo para observar cualquier evento táctil y disparar el método setBomb cuando ocurra uno. Dentro del método, estamos aislando cualquier actividad a la fase "iniciada" del evento. Si no aislamos esta fase, el código se ejecutará varias veces, ya que los eventos táctiles tienen muchas fases..

El método setBomb tal como está ahora hace muy poco. Carga un gráfico de bomba de aspecto agradable y lo agrega a la pantalla como un objeto de física dinámica. Ahora integraremos nuestro método de explosión de nuevo en el código como una función local llamada explosión:

 local circle = "" local explosion = "" local function blast (evento) 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", círculo) final blast ()

El objeto del círculo aquí nos ayuda a calcular nuestro radio de explosión. Estamos agregando un detector de eventos de colisión para detectar cuál de las cajas se encuentra dentro de la zona de explosión. Además, también estamos agregando un gráfico de explosión a la pantalla en la misma posición que el gráfico de la bomba una vez que se dispara la explosión..

Cronometrando la explosión

Si prueba el código en este punto, notará que todo sucede muy rápido y que quedan algunos artefactos gráficos. Para hacerlo más suspenso, vamos a reemplazar nuestra llamada a la función "blast ()" con un temporizador que retrasará la explosión de la bomba en 3 segundos:

 timer.performWithDelay (3000, explosión)

¡Simple como eso! La clase de temporizador tiene una función llamada performWithDelay () con dos parámetros: la cantidad de milisegundos que hay que esperar y el método para llamar. Entonces, en este caso, los 3,000 milisegundos equivalen a 3 segundos completos de retraso.

Eliminando Artefactos

Dado que la bomba explotará después de un retraso de 3 segundos, debemos eliminar este objeto de la pantalla una vez que ocurra la explosión. Esto se puede hacer muy fácilmente. Todos los objetos que están presentes en la pantalla vienen con una útil función removeSelf (). Una vez que un objeto se elimina de la pantalla, el motor de Física es lo suficientemente inteligente como para recolectar basura y eliminarlo de todos los cálculos de física también. Podemos agregar la siguiente línea a la parte inferior de la función de explosión:

 bomba: removeSelf ()

Además de eliminar la bomba, vamos a eliminar nuestro objeto de radio de explosión del círculo, así como el gráfico de explosión que agregamos para su efecto. Ya que necesitamos darle a nuestro círculo de radio de explosión un poco de tiempo para crear colisiones con nuestras jaulas, lo eliminaremos 1/10 de segundo después de que llamemos la función de explosión. Esto se puede lograr reemplazando nuestra llamada a la función de explosión programada con el siguiente código:

 función local removeStuff (evento) círculo: removeSelf () explosión: removeSelf () end timer.performWithDelay (3000, blast) timer.performWithDelay (3100, removeStuff)

Como puede ver, estamos llamando a la función de explosión después de un retraso de 3 segundos por tocar la pantalla igual que antes. Ahora hemos agregado otra llamada demorada que se ejecuta 3.1 segundos después de tocar la pantalla que limpia los objetos remanentes con la función removeSelf ().

La función completa que creamos ahora se ve así:

 función local setBomb (evento) si (evento.fase == "comenzó") luego local bomba = pantalla.newImage ("bomba.png", evento.x, evento.y) physics.addBody (bomba, densidad = 0.2, fricción = 0.1, rebote = 0.5) círculo local = "" explosión local = "" explosión de función local (evento) media.playEventSound (explosionSound) círculo = display.newCircle (bomb.x, bomb.y, 80) explosion = pantalla .newImage ("explosion.png", bomb.x, bomb.y) bomba: removeSelf () circle: setFillColor (0,0,0, 0) physics.addBody (circle, "static", isSensor = true) circle.myName = "circle" circle.collision = onLocalCollision circle: addEventListener ("collision", circle) end función local removeStuff (event) circle: removeSelf () explosion: removeSelf () end timer.performWithDelay (3000, blast) timer. Fondo de final del final de PerformWithDelay (3100, removeStuff): addEventListener ("touch", setBomb)

Creando un umbral de destrucción

En la parte I de nuestro tutorial, nuestra función de detección de colisiones tenía este aspecto:

 función local onLocalCollision (self, event) if (event.phase == "comenzó" y self.myName == "circle") entonces forcex local = 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

Simplemente encontró todas las cajas dentro de nuestro radio de explosión y aplicó una fuerza para expulsarlas del epicentro de la explosión. Para hacer las cosas más interesantes, agregaremos un umbral de destrucción a las cajas que causará que exploten si la fuerza que se les aplica es lo suficientemente alta. Se puede hacer así:

 if (math.abs (forcex)> 60 o math.abs (forcey)> 60) luego explosion local = display.newImage ("explosion.png", event.other.x, event.other.y) event.other: removeSelf () función local removeExplosion (evento) explosión: removeSelf () end timer.performWithDelay (100, removeExplosion) end

Necesitamos observar la fuerza que aplicamos a cada una de las cajas para detectar si es más alta que 60. 60 en este caso en un número arbitrario basado en nuestro cálculo de fuerza. Usamos la función math.abs para obtener el valor absoluto de la fuerza. En nuestro ejemplo, las fuerzas pueden ser positivas o negativas dependiendo de la dirección de la fuerza aplicada. No nos preocupa la dirección en este caso, simplemente queremos saber si la fuerza supera el umbral de 60. Siéntase libre de jugar con este número de umbral para cambiar qué tan débiles o fuertes son las cajas..

En la Parte I, nuestra fuerza de explosión se calculó de una manera que hizo que disminuyera cuanto más lejos esté una caja del epicentro de la explosión. Así que las cajas que están más cerca del epicentro tienen una mayor probabilidad de ser destruidas, y las otras simplemente volarán fuera de la pantalla. Como hicimos antes con nuestra clase de temporizador, estamos mostrando un gráfico de explosión en la posición anterior de una caja destruida, y luego lo estamos eliminando de la pantalla 1/10 de segundo más tarde. El método de detección de colisión final se verá así:

 función local onLocalCollision (self, event) if (event.phase == "comenzó" y self.myName == "circle") entonces forcex local = 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 o math.abs (forcey)> 60) luego local explosion = display.newImage ("explosion.png", event.other.x, event.other.y) event.other: removeSelf () función local removeExplosion (evento) explosion: removeSelf () end timer.performWithDelay (50, removeExplosion) end end end end

Sonido encendido!

Como paso final en nuestro tutorial, vamos a reproducir un efecto de sonido de explosión cuando explote nuestra bomba. Como todo lo demás en Corona, es sorprendentemente simple hacer esto. Comenzaremos incluyendo la biblioteca de medios en la parte superior de nuestro proyecto y precargando nuestro archivo de sonido:

 medios locales = requieren ("medios") local explosionSound = medios.newEventSound ("explosion.mp3")

Para reproducir el sonido, agregaremos la siguiente línea a nuestra función blast () que está dentro de nuestra función setBomb ():

 función local blast (evento) media.playEventSound (explosionSound)? fin

Ahora, cada vez que se llame a la función blast (), usará la función playEventSound de la biblioteca de medios para reproducir nuestro archivo de sonido "explosion.mp3". No podría ser más fácil si lo intentáramos.!

¡Y ahí lo tenemos! Ahora tenemos un ejemplo más completo de lo fácil que es crear explosiones en la plataforma Corona. Siéntase libre de descargar las cremalleras para la Parte I y II del tutorial y jugar.!