Universitat Oberta de Catalunya

Cursor animado con Lenguaje de Programación Processing

Se presenta un ejemplo de realización de cursor animado con Processing. Se trata de utilizar una estructura de datos de estilo “array” para ir almacenando las posiciones sucesivas del ratón, de manera que “al tener memoria” (es decir que sabemos por donde hemos estado pasando), podemos pintar en todas las posiciones almacenadas además de en la actual y conseguir un curioso efecto con nuestro cursor en movimiento. Una especie de “inercia” en el movimiento podríamos decir. Veámoslo en la figura 1.

Figura 1. Un curioso cursor animado programado con Processing.

Figura 1. Un curioso cursor animado programado con Processing.

Además podemos pintar los sucesivos segmentos de la estela que va dejando el color con tonalidades distintas del mismo color, con lo cual el efecto mejora notablemente. Inicialmente crearemos dos arrays de cara a almacenar las sucesivas coordenadas XY de nuestro cursor mientras se mueve. Hemos decidido crearlos de 10 posiciones aunque pueden definirse las que se desee en base a la longitud de estela que prefiera diseñarse. Veámos el código 1.

// We create 2 arrays, 10 positions each
int[] wormX = new int[10];
int[] wormY = new int[10];

// The Setup function. Called only once
void setup(){
// A 500 x 500 window to start with
size(500,500);
// We set 60 frames per second
frameRate(60);
// We hide the cursor of the mouse
noCursor();
}

Código 1. Declaración de los arrays  e inicialización de nuestro programa.

Observemos que los arrays (wormX y wormY) almacenaran datos de tipo integer (entero y por tanto sin decimales) dado que las coordenadas de ventana, básicamente parejas a los píxeles de ésta, tienen este formato. En nuestra función de inicialización setup() definimos y creamos una ventana de 500 x 500 píxeles y controlamos perfectamente a qué ritmo deseamos que “se refresque” (se vuelva a pintar en ella). En concreto 60 cuadros por segundo. Y por último escondemos el cursor para que tan sólo se vea el que nosotros creemos por código, en tonalidades rojas y con su estela. Como si de una brocha de pintura se tratara. En el código 2 observamos como “procesar” y pintar nuestra “brocha virtual”.

// The infinite loop
void draw(){
// Our background is black
background(0);
// Our cursor acts as a "worm" --> 10 segments long
// We go through every segment to render it
for(int counter=0; counter<10; counter++){
// Depending on the segment that we are dealing with (0 to 9)
// We will use a different color and a different weight for the stroke
// Values range from 23 to 50 pixels wide (strokeWeight)
strokeWeight(50-counter*3);
// Values range from 75 to 255 for the Red Component (stroke)
stroke(255-counter*20,0,0);
// We draw a point at the current segment of our "worm"
point(wormX[counter],wormY[counter]);
// We draw a line between sequential segments in our "worm"
if (counter<9) line(wormX[counter],wormY[counter],wormX[counter+1],wormY[counter+1]);
}
}

Código 2. Función draw() y ejecución de nuestra brocha virtual.

Definimos un color de fondo negro, que casa perfectamente con el rojo de nuestra estela, y a continuación utilizamos una estructura de control de bucle tipo FOR para recorrer ambos arrays, posición a posición y por tanto coordenada a coordenada de ratón almacenada. Lo hacemos mediante la variable contador counter. Lo primero que hacemos dentro del bucle es variar el color y el grueso con el que pintaremos el segmento de nuestra estela dependiendo de nuestra posición. Así para las posiciones más alejadas (aquellas por las que “hace rato” que hemos pasado con el ratón) preferiremos diámetros menores y tonos más oscuros. Evidentemente esto va a gustos y podéis variarlo a voluntad!. Con strokeWeight(50-counter*3) definimos un grueso de 50 que se hará menor a medida que la variable contador counter aumente su valor. Y vía stroke(255-counter*20,0,0) definimos un color de relleno rojo que, de nuevo, disminuirá en cuanto a tonalidad en la misma medida. Por último, y seguimos dentro del bucle, pintamos un punto por cada una de las posiciones (coordenadas XY) almacenadas, accediendo a los arrays y empleando la función que nos brinda Processing para ello: point(wormX[counter],wormY[counter]). Además unimos los puntos sucesivos con una línea. Ojo y cuidado aquí! tenemos que unirlos todos mediante líneas menos el último! Que evidentemente no tiene a “nadie detrás” para unirse. De ahí la comprobación que realizamos (if (counter<9)). en=”” la=”” figura=”” 2=”” nos=”” hacemos=”” una=”” idea=”” de=”” estructura=”” estela=”” p=””>

Figura 2. La estela se almacena a lo largo de 10 posiciones en nuestros arrays.

Figura 2. La estela se almacena a lo largo de 10 posiciones en nuestros arrays.

En el código 3, procedemos a almacenar sucesivas posiciones de nuestro ratón mientras éste se mueve. Para ello utilizaremos el evento/callback que se invoca cada vez que, como usuarios, movemos el periférico. Es decir la función mouseMoved().

// The mouseMoved event is called whenever the mouse moves
// It means that we need to "reset" our worm's positions for the 10 segments
// 1st position = 1st segment = mouse coordinates
// 2nd position = 2nd segment = "old" 1st position
// 3rd position = 3rd segment = "old" 2nd position
// And so on...
void mouseMoved(){
// We shift the positions one segment back
for(int counter=9; counter>0; counter--){
wormX[counter]=wormX[counter-1];
wormY[counter]=wormY[counter-1];
}
// 1st position = mouse coordinates
wormX[0]=mouseX;
wormY[0]=mouseY;
}

Código 3. Almacenamos las posiciones de nuestro ratón mientras se mueve.

Nótese que cada vez que el ratón se mueve, tenemos que 1) Almacenar las nuevas coordenadas XY y 2) Desplazar todas las que ya teníamos hacia atrás. Eso mismo es lo que realizamos. Primero, y dentro del bucle FOR que podemos observar, recorremos ambos arrays (wormX y wormY) para desplazar cada par de coordenadas almacenado de la posición actual a la anterior (en nuestro caso de counter a counter-1). En segundo lugar almacenamos las coordenadas 2D actuales del ratón (variables de sistema mouseX y mouseY) dentro de la primera posición, es decir la 0, de nuestros arrays.

Para terminar podéis observar el programa completo en el código 4. Variadlo a voluntad y obtendréis resultados muy curiosos y motivadores, ¡incluso por casualidad! Pero es que sin experimentar no encontramos nuevas soluciones, ¿verdad?.

// We create 2 arrays, 10 positions each
int[] wormX = new int[10];
int[] wormY = new int[10];

// The Setup function. Called only once
void setup(){
// A 500 x 500 window to start with
size(500,500);
// We set 60 frames per second
frameRate(60);
// We hide the cursor of the mouse
noCursor();
}

// The infinite loop
void draw(){
// Our background is black
background(0);
// Our cursor acts as a "worm" --> 10 segments long
// We go through every segment to render it
for(int counter=0; counter<10; counter++){
// Depending on the segment that we are dealing with (0 to 9)
// We will use a different color and a different weight for the stroke
// Values range from 23 to 50 pixels wide (strokeWeight)
strokeWeight(50-counter*3);
// Values range from 75 to 255 for the Red Component (stroke)
stroke(255-counter*20,0,0);
// We draw a point at the current segment of our "worm"
point(wormX[counter],wormY[counter]);
// We draw a line between sequential segments in our "worm"
if (counter<9) line(wormX[counter],wormY[counter],wormX[counter+1],wormY[counter+1]);
}
}

// The mouseMoved event is called whenever the mouse moves
// It means that we need to "reset" our worm's positions for the 10 segments
// 1st position = 1st segment = mouse coordinates
// 2nd position = 2nd segment = "old" 1st position
// 3rd position = 3rd segment = "old" 2nd position
// And so on...
void mouseMoved(){
// We shift the positions one segment back
for(int counter=9; counter>0; counter--){
wormX[counter]=wormX[counter-1];
wormY[counter]=wormY[counter-1];
}
// 1st position = mouse coordinates
wormX[0]=mouseX;
wormY[0]=mouseY;
}

Código 4. Programa Processing completo para nuestra brocha/estela virtual con el cursor.

Un comentario

Deja un comentario

  1. Hola, soy alumno de la carrera de sistemas computacionales y nunca he usado processing pero me fue asignado como lenguaje para trabajar, tengo unas dudas, como puedo guardar ciertos puntos que yo vaya colocando, y que después de colocar esos puntos, se almacenen para posteriormente las pueda graficar, ya sea si coloque 3 puntos me haga un triangulo, etc, o incluso colocar puntos seguidos y me realice una curva.

    Saludos!!

    Respon

Responde Etner Bernabé Trujillo Sánchez