Eventos controlados por tiempo: timers.

¿Te has encontrado con esos escenarios de juego donde aparecen enemigos cada cierto tiempo y seguirán apareciendo hasta que derrotas al Jefe final o completas una tarea especifica? Este tipo de acción automática hace que como jugador siempre tengas que mantenerte alerta y planear muy bien lo que deseas hacer, además resulta una maravilla cuando balanceas muy bien la frecuencia de enemigos en pantalla e incluso puedes hacer que la dificultad se incremente con solo reducir el tiempo de creación de enemigos / objetos.

Afortunadamente es bastante sencillo emular este tipo de acción usando ejecuciones de funciones controladas por tiempo determinado y en Corona existe una librería que nos permite lograrlo fácilmente: la librería timer. Esta librería tiene 4 funciones especificas para controlar esta operación:

[su_table]

timer.performWithDelay( delay, listener [, iterations] ) : Crea un nuevo timer que se encargará de ejecutar una función cada cierto tiempo una cantidad de veces definida.

delay : El tiempo que espera antes de ejecutar la función. Este dato se mide en milisegundos (1000 = 1 segundo)
listener : El nombre de la función que será ejecuta al pasar el tiempo en el parámetro delay
iterations : La cantidad de veces que deseas se ejecute la función definida en el parámetro listener. Por defecto su valor es 1, pero si deseas que la función se ejecute de manera permanente coloca el valor 0 o -1.

timer.pause( timerID) : Pausa la ejecución de un timer especifico.

timerID : El Id / referencia del timer creado con la función timer.performWithDelay()

timer.resume( timerID) : Reanuda la ejecución de un timer especifico.
timerID : El Id / referencia del timer creado con la función timer.performWithDelay()
timer.cancel( timerID): Elimina la ejecución de un timer especifico.

timerID : El Id / referencia del timer creado con la función timer.performWithDelay()

[/su_table]

Ejemplo de como usar un timer

Para entender como trabajan estas funciones crearemos una función que muestre una imagen en pantalla en una posición aleatoria y con 4 botones controlaremos las diferentes funciones de la librería timer (perform, pause, resume y cancel)

Como la idea es usar botones necesitamos cargar la libería widget, ademas definimos una variable de nombre creaExplosionesTimer que es donde guardaremos la referencia del timer que vayamos a crear. Finalmente la función fnt_agregaExplosiones es la que permite mostrar una imagen en una posición aleatoria dentro de nuestra pantalla.

A continuación definimos cada una de las funciones que serán ejecutadas por nuestros botones. Observa que al crear el timer guardamos la referencia del mismo en la variable creaExplosionesTimer para poder hacer referencia a ese timer en especifico en las operaciones de pausar, reanudar y cancelar. Si necesitáramos mas de un timer se puede guardar la referencia de cada nuevo timer en una nueva variable y así tener cuantos timers hicieran falta para nuestro juego.

Finalmente creamos y colocamos los botones en pantalla, cada uno con un texto especifico y cada uno ejecutando una función diferente. Es importante que observes que todos los botones se construyen a partir del mismo conjunto de propiedades (la tabla opcionesBoton) y en esta insertamos / modificamos la información de la tabla asociativa para que cada botón tenga un texto diferente y una función diferente (Si tienes duda de porque podemos hacer esto consulta el post LUA 101 – Tablas ).

Ejecutando el ejemplo de timers.

Al realizar la ejecución en order de los botones podemos observar lo siguiente:

  • Cuando presionamos el botón Perform el timer es creado y cada segundo podemos ver como aparece una imagen en pantalla.
  • Al presionar el botón pause el timer creado se pausa y las imágenes dejarán de crearse en pantalla.
  • Al presionar el botón resume las imágenes seguirán creándose en pantalla.
  • Al presionar el botón cancel las imágenes dejarán de crearse en pantalla.

Problemas comunes al usar timers.

  • Ejecutar timer.resume() después de ejecutar timer.cancel(). Aunque desde el punto de vista de quien ve la pantalla timer.pause() y timer.cancel() parecen hacer lo mismo (detener la ejecución recurrente de una función) timer.cancel() elimina por completo un timer creado, por lo que, si quisiéramos volver a ejecutar este timer tendríamos que volver a crearlo con timer.performWithDelay(). De lo contrario veríamos un error como el siguiente:

[su_note note_color=”#FEFBBC” text_color=”#000000″]WARNING: timer.resume() cannot resume a timerId that is already expired.[/su_note]

  • Crear multiples instancias de un mismo timer. En el ejemplo que hemos creado anteriormente vemos como la función fnt_creaTimer inicializa y crea el timer pero ¿Qué sucedería si presionamos varias veces el mismo botón? Se crearían multiples instancias que ejecutan la función fnt_agregaExplosiones pero solo la última de estas instancias estaría guardad en la variable creaExplosionesTimer. Lo primero que observaríamos es que empezarían a aparecer muchas imágenes cada vez mas rápido y los botones de Pause y Cancel parecería que no sirven. En realidad siguen ejecutándose solo que pausan / cancelan el último timer creado. ¿Cómo podemos evitar esto? Simplemente validando si la variable en donde estamos guardando la referencia de un timer ya tiene un valor asignado, veamos la solución en código:

 

A continuación encontraras el código completo y corregido del ejemplo que usamos en este post.

Espero hayas disfrutado y aprendido muchas cosas de este artículo y por favor siéntete libre de compartir esta información en tus redes sociales para que otras personas interesadas también puedan conocer algo nuevo que les pueda ayudar en sus proyectos futuros. ¡Hasta la próxima!

0 comments on “Eventos controlados por tiempo: timers.Add yours →

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *