5. Condicionales

5.6. Temporizadores

Aunando los distintos conocimientos que hasta ahora hemos adquirido podemos desarrollar programas que cambien a lo largo del tiempo. Mediante el uso de variables y condicionales seremos capaces de crear sketches que detecten que ha pasado una cantidad determinada de tiempo y ejecutar ciertas acciones cuando esto ocurra. Podríamos por ejemplo quitar el noLoop() que utilizamos en el último ejemplo y hacer que obtengamos un valor aleatorio para el relleno del círculo cada 2 segundos manteniendo el sketch corriendo a 60 frames por segundo.

Para ello, podemos hacer uso del método millis() o también podemos usar la variable propia del sistema frameCount. Ambas maneras permiten llevar la cuenta del tiempo transcurrido en nuestro sketch pero lo hacen de distinta manera. La variable del sistema (como width o height) frameCount almacena el número de frame actual en el que nos encontramos. Recordemos que por defecto en P5 la velocidad de refresco es de 60 fotogramas por segundo (algo que podemos cambiar si usamos el método frameRate()), por lo que frameCount aumentará 60 unidades cada segundo que transcurra.

El número de frames por segundo (FPS) que podemos alcanzar depende de la capacidad de nuestro ordenador para procesar todas las instrucciones que tenemos en nuestro sketch. Si le pedimos que haga demasiadas cosas, no le da tiempo a hacerlo todo en 1/60 de segundo y el frame rate baja. 60 frames por segundo es un estándar en el mundo audiovisual (los televisores de 60 Hz por ejemplo, que muestran 60 imágenes por segundo), pero dependiendo del caso podría ser aceptable trabajar a 30 FPS o incluso a 15 FPS (muchas películas de animación usan 12 FPS). En nuestro caso, intentaremos mantener los 60 FPS siempre que podamos.

El método millis() es similar a utilizar frameCount, pero lo que nos devuelve millis() son los milisegundos (milésimas de segundo) que han transcurrido desde que iniciamos el sketch.

Figura 58. frameCount y millis()
Fuente: elaboración propia.
En el ejemplo de la figura anterior vemos en funcionamiento tanto la variable del sistema frameCount como el método millis(). Se puede observar un pequeño desfase (60 frames no son exactamente 1.000 milisegundos), que tiene que ver con lo comentado anteriormente sobre la capacidad de nuestro ordenador. Siempre tratará de alcanzar los 60 frames por segundo, pero si le exigimos mucho tratando de realizar muchas cosas simultáneamente, el frame rate caerá.

Veamos un par de ejemplos sencillos en los que cambiaremos el color de fondo aleatoriamente cada segundo utilizando temporizadores tanto con frameCount como con millis():

Figura 59. Contador con frameCount
Fuente: elaboración propia.
Este quizá sea el ejemplo más sencillo para hacer un contador. Primero determinamos cada cuántos frames queremos que se produzca un cambio. En nuestro caso, como queremos que el cambio se produzca cada segundo y sabemos que el sketch corre a 60 FPS, serán 60 frames. A continuación, en el draw() creamos una condición en la que utilizamos frameCount % framesToEvent == 0. El operador %, si recordamos de pasados temas, es el operador módulo, que nos da el resto de la división de frameCount entre framesToEvent. El resto de esta división será 0 siempre que el frameCount, el número de frame actual, sea múltiplo de framesToEvent. En nuestro caso, el resto de 60 entre 60 será 0, el de 120 entre 60 también 0, el de 180, 240, etc. De esta manera, la condición se cumple únicamente cada vez que transcurren 60 frames, un segundo, tal como se puede observar en la consola.

Pasemos a ver cómo podemos hacer lo mismo pero utilizando millis() en lugar de frameCount:

Figura 60. Contador con millis()
Fuente: elaboración propia.
En este caso lo que hacemos es crear una variable que lleva la cuenta de los milisegundos transcurridos restándole los milisegundos transcurridos cuando ocurrió el último evento. En la condición del if testamos si este tiempo es mayor que 1.000 milisegundos y, si fuese así, se cambia el color de fondo y se registra el tiempo en el que se ha producido el cambio para restárselo al tiempo actual y realizar de nuevo la comparación. En la consola se puede observar cómo una vez llegados a los 1.000 milisegundos transcurridos, se produce el cambio y el valor se reestablece.