7. Movimiento

7.5. Movimiento aleatorio

En temas anteriores hemos utilizado el método random() para obtener valores aleatorios. Podemos usar estos valores para cambiar en cada frame las coordenadas en las que dibujamos alguna de nuestras figuras. Veamos un ejemplo:

Figura 92. Aplicando random() a la posición de un círculo
Fuente: elaboración propia.
Como se observa en la figura anterior, el cambio de un frame al siguiente es demasiado brusco. El método random() nos devuelve en este caso un número entre 0 y 400 cada vez que lo invocamos. Podemos imprimir estos valores en la consola utilizando console.log() y observaremos que efectivamente el salto de una posición a otra es demasiado brusco.

Figura 93. Monitorizando los valores de random() en la consola
Fuente: elaboración propia.
Utilizando random() de esta manera no podremos crear una sensación de movimiento convincente, deberemos explorar otras técnicas.

Random walk

Una de estas técnicas es el random walk: paseo aleatorio. En esta, en lugar de utilizar los valores de random() directamente para establecer la posición de la figura que queremos mover, tendremos una posición inicial a la que sumaremos un pequeño valor aleatorio en cada frame. Veámoslo en acción:

Figura 94. Random walk
Fuente: elaboración propia.

Partiendo desde el centro del canvas, en cada frame sumamos una pequeña cantidad, definida en este caso con la variable offset, a la posición del círculo tanto en el eje x como en el y. De esta manera, nuestro círculo se moverá entre –2 y 2 píxeles en ambas direcciones cada vez que se ejecuta el draw().

Noise

Otra de las técnicas para obtener un movimiento aleatorio más orgánico es utilizando el método de P5 noise(). Este método nos devuelve valores pseudoaleatorios entre 0 y 1 utilizando una función de ruido Perlin (Perlin noise). Esta función, creada por Ken Perlin para generar las texturas de la película Tron de 1982, es ampliamente utilizada en muchos ámbitos de la creación gráfica digital, desde para la creación de efectos de humo o fuego hasta para la distribución de los distintos paisajes del videojuego Minecraft. La ventaja que noise() nos ofrece respecto a random() es que nos otorga una aleatoriedad con continuidad, sin saltos bruscos. A continuación, podemos ver un ejemplo de función de ruido.

Figura 95. Función de ruido
Fuente: elaboración propia.

A noise() le pasamos un parámetro que equivale a la coordenada x de la función de ruido y nos devuelve el valor de la coordenada y (entre 0 y 1). En el ejemplo de la figura anterior, si le pasamos el valor noise(3), nos devolverá un valor cercano a 0,75. Si le vamos pasando a noise() valores cercanos, los que nos devuelva lo serán también. Veamos cómo podemos utilizarlo en P5.

Figura 96. Usando noise() en P5
Fuente: elaboración propia.
Como se puede observar, los valores que nos va devolviendo noise() son relativamente cercanos entre sí, por lo que ahora sí que podremos utilizarlos para crear un movimiento aleatorio fluido:

Figura 97. Aplicando noise() a la posición de un círculo
Fuente: elaboración propia.
En este caso utilizamos dos ruidos distintos, uno para la posición en x del círculo y otro para la posición en y. Antes de calcular cada uno de los ruidos, especificamos un noiseSeed() distinto para cada uno; si no lo hacemos, los valores que obtendremos serán iguales, ya que ambos métodos noise() estarán usando la misma curva de ruido. Otra manera de obtener valores diferentes es establecer distintos puntos de partida en la misma curva. Para ello, podríamos cambiar los valores de offX y offY que hemos definido al principio del código con el fin de que estén más separados entre sí en la curva. Variando el incremento de offX y offY podemos controlar la velocidad a la que nos movemos en la curva de valores pseudoaleatorios: a valores más pequeños le corresponden movimientos más suaves, mientras que si aumentamos mucho el incremento, los valores que noise() nos devolverá serán cada vez más similares a los que nos devolvería random(), ya que los saltos en la curva pseudoaleatoria serán mayores.

De la misma manera como anteriormente hemos utilizado los valores animados no únicamente para la posición de las figuras en el canvas sino también para su tamaño, color u otros parámetros, podemos también utilizar las animaciones aleatorias para el propósito que consideremos oportuno. Creemos un par de ruidos más para aplicarlos al tamaño y al color del círculo:

Figura 98. Utilizando noise para el tamaño y el color
Fuente: elaboración propia.
En la figura anterior vemos que se han creado un par de variables más para almacenar la posición en la curva de ruido para el tamaño y el color, con distintos valores para que estos valores no estén asociados entre sí. A continuación, se han utilizado estos valores para pasarlos como parámetro a distintos noise() que se usan para definir la posición, el tamaño y el color del círculo, de modo que todos estos parámetros varían aleatoriamente de manera fluida a lo largo del tiempo.