Processing
![](/daisy/Materials/img/uoc_masterbrand.png)
Índice
- Introducción
- 1.Estructura básica de un programa
- 1.1.“Hola mundo”
- 1.2.Elementos básicos
- 1.2.1.Inserción de comentarios
- 1.2.2.Declaración de variables
- 1.2.3.Función setup
- 1.2.4.Función draw
- 2.Tipo de datos básicos
- 3.Tipos de datos gráficos
- 3.1.Formas básicas
- 3.1.1.Líneas
- 3.1.2.Elipses
- 3.1.3.Rectángulos
- 3.1.4.Triángulos
- 3.2.Gestión del color de las formas
- 3.2.1.Relleno de las formas
- 3.2.2.Contorno de las formas
- 3.1.Formas básicas
- 4.Animación básica
- 5.Interacción básica: capturar el ratón
- 6.Organización del código
- 7.Trabajar con imágenes
- 8.Transformaciones básicas
- 9.Bibliotecas
Introducción
![Figura 1. Referencia en línea](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_01.jpg)
-
http://mosaic.uoc.edu/2013/02/19/cursor-animado-con-lenguaje-de-programacion-Processing/
-
http://mosaic.uoc.edu/2013/02/27/caleidoscopio-con-lenguaje-de-programacion-Processing/
-
http://mosaic.uoc.edu/2013/02/27/sistema-de-particulas-con-lenguaje-de-programacion-Processing/
-
http://mosaic.uoc.edu/2013/02/27/colisiones-y-particulas-con-lenguaje-de-programacion-Processing
-
http://mosaic.uoc.edu/2013/03/26/Processing-practico-parte-2-de-3/
-
http://mosaic.uoc.edu/2013/04/24/Processing-practico-parte-3-de-3/
-
http://mosaic.uoc.edu/2013/03/25/carga-de-un-modelo-3d-con-lenguaje-de-programacion-Processing/
-
http://mosaic.uoc.edu/2013/03/25/imagenes-y-luts-en-programacion-Processing/
-
http://mosaic.uoc.edu/2013/03/25/sonido-con-lenguaje-de-programacion-Processing-primer-ejemplo/
-
http://mosaic.uoc.edu/2013/03/25/sonido-con-lenguaje-de-programacion-Processing-segundo-ejemplo/
-
http://mosaic.uoc.edu/2013/04/24/realidad-aumentada-con-lenguaje-de-programacion-Processing/
-
http://mosaic.uoc.edu/2013/04/24/deteccion-de-colisiones-con-lenguaje-de-programacion-Processing/
-
http://mosaic.uoc.edu/2013/04/24/acceso-a-webcam-y-luts-en-programacion-Processing/
-
http://mosaic.uoc.edu/2013/04/24/acceso-a-webcam-y-procesado-en-programacion-Processing/
-
http://mosaic.uoc.edu/2013/04/24/operaciones-con-imagenes-en-programacion-Processing/
-
Vamos al apartado de descargas, donde podemos decidir hacer una donación para apoyar el desarrollo de este proyecto de código abierto.
![Figura 2. Página inicial de descarga](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_02.jpg)
-
Seleccionamos download y accederemos a la página donde podremos seleccionar el sistema operativo de nuestro ordenador y la versión de Processing que queremos descargar.
![Figura 3. Página de descarga, selección del sistema operativo](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_03.jpg)
-
Una vez finalizada la descarga, solo habrá que descomprimir el fichero y aparecerá el directorio donde está el programa.
-
Para ejecutarlo, solo habrá que entrar dentro del directorio creado y ejecutar el fichero processing.exe en el caso de utilizar el Windows o el equivalente de cada sistema operativo, y ya nos aparecerá el entorno de desarrollo que utilizaremos para hacer las actividades.
1.Estructura básica de un programa
1.1.“Hola mundo”
void setup() { size(200, 100); } void draw() { text ("Hello world", 10, 10); }
![Figura 4. Ejecución de un programa](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_04.jpg)
![Figura 5. Ventana del programa](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_05.jpg)
![Figura 6. Coordenadas de la pantalla](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_06.jpg)
1.2.Elementos básicos
1.2.1.Inserción de comentarios
/* * Hello world with comments * Version: 2 */ // Main initialization function void setup() { size(200, 100); //Window size } void draw() { text ("Hello world", 10, 10); }
1.2.2.Declaración de variables
String message; void setup() { size(200, 100); message = "Hello world"; } void draw() { text (message, 10, 10); }
1.2.3.Función setup
void setup() { size(200, 100); .... .... }
size(displayWidth, displayHeight);
background (255, 0, 0);
stroke (0, 255, 0);
line (0, 0, 200, 100);
1.2.4.Función draw
Repetición infinita
int index; void setup() { size(200, 100); index = 0; } void draw() { println (index); index = index + 1; }
![Figura 7. Ejecución del programa](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_07.jpg)
-
Escribimos el valor de la variable.
-
Incrementamos el valor de la variable.
frameRate (1);
Importancia del orden de los elementos
void setup() { size(200, 100); } void draw() { stroke (255, 0, 0); rect (10, 10, 50, 50); stroke (0, 255, 0); rect (30, 30, 70, 70); }
![Figura 8. Orden de pintar](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_08.jpg)
void draw() { stroke (0, 255, 0); rect (30, 30, 70, 70); stroke (255, 0, 0); rect (10, 10, 50, 50); }
int index; void setup() { size(200, 150); frameRate (1); index = 0; } void draw() { println (index); text (index, 0, 10); index = index + 1; }
![Figura 9. Texto gráfico borroso](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_09.jpg)
void draw() { background (128, 128, 128); println (index); text (index, 0, 10); index = index + 1; }
![Figura 10. Texto gráfico visible](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_10.jpg)
textSize (30);
2.Tipo de datos básicos
2.1.Definición e inicialización de variables
tipus_de_variable nom_de_variable; void setup() { nom_de_variable = valor_inicial; } void draw() { }
2.2.Variables: booleanas
boolean a; void setup() { a = true; a = false; }
2.3.Variables: números enteros
int index; void setup() { index = 0; }
int index; int doble; void setup() { index = 0; doble = 0; } void draw() { println ("index: "+ index +" valor doble: " + doble); index = index + 1; doble = index * 2; }
println ("index: "+ index +" valor doble: " + doble);
2.4.Variables: números decimales
float decimal; void setup() { decimal = 0.0; }
int a; int b; float result; void setup() { a = 11; b = 2; result = a / b; println ("a/b = " + result); result = 11 / 2; println ("a/2 = " + result); result = a / 2.0; println ("a/2 = " + result); }
a/b = 5.0 a/2 = 5.0 a/2 = 5.5
2.5.Variables: conjuntos
int[] int_array;
2.5.1.Inicialización con todos los valores conocidos
int[] int_array = { 10, 20, 30 }; void setup() { }
2.5.2.Inicialización sin valores
int[] int_array; void setup() { int_array = new int [3]; }
2.5.3.Acceso a los datos del array
int_array[1]=444;
println (int_array[1]);
int[] int_array = { 10, 20, 30 }; void setup() { println (int_array[0]); println (int_array[1]); println (int_array[2]); }
println (int_array.length);
2.6.Variables: cadenas de texto
String text; void setup() { text = new String ("Hello"); println (text); }
void setup() { text = new String ("Hello"); text = "bye!"; println (text); }
2.7.Variables: color
color c; void setup() { c = color (255, 0, 0); } void draw() { background (c); }
![Figura 11. Variable color](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_11.jpg)
color c; void setup() { c = color (255, 120, 60); println ("Direct value: " + c); println ("Hexadecimal value: " + hex(c)); }
Direct value: -34756 Hexadecimal value: FFFF783C
-
AA: Valores entre 00 y FF (0 a 255 en decimal), definen el canal alfa, o lo que es el mismo, la transparencia del color.
-
RR: Valores entre 00 y FF (0 a 255 en decimal), definen el canal rojo.
-
GG: Valores entre 00 y FF (0 a 255 en decimal), definen el canal verde.
-
BB: Valores entre 00 y FF (0 a 255 en decimal), definen el canal azul.
2.8.Ejemplo: “Hola mundo” utilizando variables
void setup() { size(300, 200); } void draw() { textSize (30); text ("Hello world", 10, 30); }
String message; void setup() { size(300, 200); message = new String ("Hello world"); } void draw() { textSize (30); text (message, 10, 30); }
String message; int size; void setup() { size(300, 200); message = new String ("Hello world"); size = 10; } void draw() { textSize (size); text (message, 10, 30); }
String message; int size; void setup() { size(300, 200); frameRate (1); message = new String ("Hello world"); size = 10; } void draw() { textSize (size); text (message, 10, 30); size = size + 1; }
String message; int size; color c; void setup() { size(300, 200); frameRate (1); message = new String ("Hello world"); size = 10; c = color (100, 100, 100); } void draw() { background (c); textSize (size); text (message, 10, 30); size = size + 1; }
String[] message; int size; color c; void setup() { size(300, 200); frameRate (1); message = new String [2]; message[0] = new String ("Hello"); message[1] = new String ("world!"); size = 10; c = color (100, 100, 100); } void draw() { background (c); textSize (size); text (message[(size % 2)], 10, 30); size = size + 1; }
-
Definimos la variable array, que contiene información de tipo string.
-
message = new String [2]: inicializamos el array y decimos que tendrá lugar para 2 elementos de tipo string.
-
message[0] = new String ("Hello"): inicializamos cada una de las posiciones (en este caso el elemento 0) con un dato de tipo string. Aquí lo que puede sorprender es que volvemos a hacer un newString, pero recordad que es porque para crear una cadena de texto normal, también teníamos que hacerlo de esta manera. En el caso de un entero o un decimal, pondríamos directamente el valor. Repasad el ejemplo que está en el apartado de arrays para verlo más claro.
-
Una vez tenemos los dos textos cargados en el array, uno en la posición 0 y otro en la posición 1, hay que buscar la manera de que se vayan alternando. En nuestro caso, aprovecharemos la variable size, que se va incrementando, y la función módulo (%). Al hacer el cálculo (size % 2) nos está devolviendo el valor 0 cuando el valor size es par o 1 cuando es impar, y por lo tanto, lo podemos aprovechar para seleccionar qué elemento del array enseñamos en cada momento.
2.9.Ejemplo: calculando el tiempo
int time_now; int time_old; int time_delta; void setup() { size (400, 150); frameRate (20); time_now = 0; time_old = 0; time_delta = 0; } void draw() { time_now = millis(); time_delta = time_now - time_old; time_old = time_now; background(0, 0, 0); textSize (30); text (time_delta, 50, 35); text ("ms", 130, 35); }
![Figura 12. Calculando el tiempo entre planos](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_12.jpg)
//frameRate (20);
![Figura 13. Tiempo mínimo entre planos](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_13.jpg)
int time_now; int time_old; int time_delta; float sec; void setup() { size (400, 150); //frameRate (20); time_now = 0; time_old = 0; time_delta = 0; sec = 0; } void draw() { time_now = millis(); time_delta = time_now - time_old; time_old = time_now; sec = time_delta / 1000.0; background(0, 0, 0); textSize (30); text (time_delta, 50, 35); text ("ms", 150, 35); text (sec, 50, 70); text ("segons", 150, 70); }
![Figura 14. Tiempo en segundos](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/76520_m1_14.jpg)
int time_now; int time_old; int time_delta; float sec; float fps; void setup() { size (400, 150); //frameRate (20); time_now = 0; time_old = 0; time_delta = 0; sec = 0; fps = 0; } void draw() { time_now = millis(); time_delta = time_now - time_old; time_old = time_now; sec = time_delta / 1000.0; fps = 1.0 / sec; background(0, 0, 0); textSize (30); text (time_delta, 50, 35); text ("ms", 170, 35); text (sec, 50, 70); text ("segons", 170, 70); text (fps, 50, 105); text ("FPS", 170, 105); }
![Figura 15. Planos por segundo](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/76520_m1_15.jpg)
3.Tipos de datos gráficos
void setup() { size(500, 400); } void draw() { background (255, 255, 255); }
3.1.Formas básicas
3.1.1.Líneas
line (10, 20, 400, 100);
![Figura 16. Dibujar líneas](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_16.jpg)
3.1.2.Elipses
ellipse (150, 150, 100, 50); ellipse (150, 250, 100, 100);
![Figura 17. Dibujar elipses](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_17.jpg)
3.1.3.Rectángulos
rect (200, 125, 100, 50); rect (200, 200, 100, 100);
![Figura 18. Dibujar rectángulos](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_18.jpg)
rect (310, 125, 100, 50, 10);
![Figura 19. Dibujar rectángulos con opciones (1)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_19.jpg)
rect (310, 200, 100, 100, 10, 20, 30, 40);
![Figura 20. Dibujar rectángulos con opciones (2)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_20.jpg)
3.1.4.Triángulos
triangle (50, 390, 150, 300, 250, 390);
![Figura 21. Dibujar triángulos](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_21.jpg)
3.2.Gestión del color de las formas
color c_black; color c_white; color c_green; color c_red; color c_blue; void setup() { size(500, 400); c_black = color (0, 0, 0); c_white = color (255, 255, 255); c_green = color (0, 255, 0); c_red = color (255, 0, 0); c_blue = color (0, 0, 255); } void draw() { background (c_black); rect (10, 10, 100, 100); }
3.2.1.Relleno de las formas
void draw() { background (c_black); fill (c_red); rect (10, 10, 100, 100); }
![Figura 22. Función fill: cuadrado rojo](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_22.jpg)
void draw() { background (c_black); fill (c_red); rect (10, 10, 100, 100); rect (120, 120, 200, 200); fill (c_blue); rect (150, 200, 100, 100); }
![Figura 23. Función fill: orden de pintar](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_23.jpg)
fill (c_green); rect (200, 150, 200, 200);
![Figura 24. Función noFill: figura opaca](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_24.jpg)
noFill (); rect (200, 150, 200, 200);
![Figura 25. Función noFill: figura transparente](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_25.jpg)
3.2.2.Contorno de las formas
stroke (c_green);
![Figura 26. Función stroke](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_26.jpg)
fill (c_blue); noStroke(); rect (150, 200, 100, 100);
![Figura 27. Función noStroke](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_27.jpg)
void draw() { background (c_black); stroke (c_green); fill (c_red); rect (10, 10, 100, 100); rect (120, 120, 200, 200); fill (c_blue); noStroke(); rect (150, 200, 100, 100); noFill (); stroke (c_white); rect (200, 150, 200, 200); }
-
Indicamos que el color de fondo es el negro.
-
Definimos que queremos contornear de color verde y pintar de color rojo.
-
Dibujamos dos cuadrados.
-
Definimos que queremos pintar de color azul y que no queremos contornear.
-
Dibujamos el cuadrado pequeño.
-
Definimos que no queremos pintar las figuras y las queremos contornear de color blanco.
-
Dibujamos el cuadrado grande.
![Figura 28. Funciones stroke/noStroke/fill/noFill](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_28.jpg)
4.Animación básica
void setup() { size(800, 400); frameRate (20); } void draw() { background(255, 255, 255); fill (0, 0, 0); }
int ball_x; int ball_y; int ball_radius; void setup() { size(800, 400); frameRate (20); ball_x = 10; ball_y = 200; ball_radius = 10; } void draw() { background(255, 255, 255); fill (0, 0, 0); ellipse (ball_x, ball_y, ball_radius, ball_radius); }
![Figura 29. Animación: punto de partida](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_29.jpg)
ball_x = ball_x + 1;
4.1.Estructura condicional if...else
void draw() { background(255, 255, 255); fill (0, 0, 0); ellipse (ball_x, ball_y, ball_radius, ball_radius); if (ball_x < 800){ ball_x = ball_x + 1; }else{ text ("STOP", 400, 200); } }
-
if (ball_x < 800): comprobamos si la posición de la bola en le eje x es inferior a 800, que es la anchura de nuestra ventana.
-
Si la condición se cumple, la bola todavía no ha llegado al final de la ventana, incrementamos la variable ball_x para que la bola continúe avanzando.
-
Si la condición no se cumple, la bola ha llegado al final, saltamos al bloque de código que hay en el else, y en este caso escribimos un texto en la pantalla y ya no incrementamos la variable de la posición de la bola.
4.2.Variables height y width
size(400, 400);
void draw() { background(255, 255, 255); fill (0, 0, 0); text ("Height: "+height+", Width: "+width, 10, 15); ellipse (ball_x, ball_y, ball_radius, ball_radius); if (ball_x < width){ ball_x = ball_x + 1; }else{ text ("STOP", 400, 200); } }
if (ball_x < width)
4.3.Simulaciones físicas
ball_x = ball_x + 1;
int ball_x; int ball_y; int ball_radius; void setup() { size(400, 400); frameRate (20); ball_x = 200; ball_y = 10; ball_radius = 10; } void draw() { background(255, 255, 255); fill (0, 0, 0); ellipse (ball_x, ball_y, ball_radius, ball_radius); if (ball_y < height){ ball_y = ball_y + 10; }else{ text ("STOP", width/2, height/2); } }
// Time variables int time_now; int time_old; int time_delta; // Ball variables int ball_x; int ball_radius; float ball_y; float ball_y_old; float ball_y_speed; float ball_y_speed_old; float ball_y_acceleration;
void setup() { size(400, 400); frameRate (20); //Time init time_now = 0; time_old = 0; time_delta = 0; //Ball init ball_x = 200; ball_y = 10.0; ball_y_old = 10.0; ball_radius = 10; ball_y_speed = 0.0; ball_y_speed_old = 0.0; ball_y_acceleration = 9.8; }
time_now = millis(); time_delta = time_now - time_old; time_old = time_now;
if (ball_y < height){ ball_y_speed = ball_y_speed_old + (ball_y_acceleration * (time_delta/1000.0)); ball_y = ball_y_old + (ball_y_speed_old * (time_delta/1000.0)) + ( (ball_y_acceleration * (time_delta/1000.0) * (time_delta/1000.0)) / 2.0 ); ellipse (ball_x, ball_y, ball_radius, ball_radius); ball_y_speed_old = ball_y_speed; ball_y_old = ball_y; }else{ text ("STOP", width/2, height/2); }
-
Calculamos la velocidad que tiene que tener en función de la velocidad anterior y el tiempo que ha pasado. Fijaos que estamos dividiendo la variable time_delta entre 1.000,0, puesto que este valor es en milisegundos y nosotros lo necesitamos expresado en segundos.
-
Calculamos la nueva posición utilizando la ecuación que hemos visto.
-
Dibujamos la bola en la posición nueva que acabamos de calcular.
-
Actualizamos el valor de las variables antiguas con las que hemos calculado ahora, de esta manera ya estaremos preparados para hacer el próximo cálculo.
4.4.Mesa de billar
int ball_x; int ball_y; int ball_radius; void setup() { size(800, 400); frameRate (20); ball_x = 10; ball_y = 200; ball_radius = 10; } void draw() { background(255, 255, 255); fill (0, 0, 0); ellipse (ball_x, ball_y, ball_radius, ball_radius); if (ball_x < 800){ ball_x = ball_x + 1; }else{ text ("STOP", 400, 200); } }
int ball_x; int ball_y; int ball_radius; int inc_x; int inc_y; void setup() { size(800, 400); frameRate (20); ball_x = 10; ball_y = 200; ball_radius = 10; inc_x = 5; inc_y = 2; } void draw() { background(255, 255, 255); fill (0, 0, 0); ball_x = ball_x + inc_x; ball_y = ball_y + inc_y; ellipse (ball_x, ball_y, ball_radius, ball_radius); if ( (ball_x <= 0) || (ball_x >= width)) { inc_x = inc_x * -1; } if ( (ball_y <= 0) || (ball_y >= height)) { inc_y = inc_y * -1; } }
5.Interacción básica: capturar el ratón
void setup() { size(400, 400); frameRate (20); } void draw() { background(0, 0, 0); text ("Mouse position:\n X: "+"\n Y:",10, 20); }
![Figura 30. Interacción con el ratón: código inicial](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_30.jpg)
5.1.Conocemos la posición actual
text ("Mouse position:\n X: "+mouseX+"\n Y: "+mouseY,10, 20);
![Figura 31. Interacción con el ratón: mouseX/mouseY](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_31.jpg)
5.2.Perseguimos el ratón
float ball_x; float ball_y; float dir_x; float dir_y;
ball_x = width/2.0; ball_y = height/2.0; dir_x = 1.0; dir_y = 1.0;
-
ball_*: nos sirve para indicar la posición actual de la bola y está inicializada en el centro de la ventana.
-
dir_*: indica hacia dónde se moverá la bola; de momento decimos que se mueva hacia abajo a la derecha.
ball_x = ball_x + dir_x; ball_y = ball_y + dir_y; ellipse (ball_x, ball_y, 10, 10);
![Figura 32. Perseguimos el ratón](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_32.jpg)
![Figura 33. Cálculo del desplazamiento](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_33.jpg)
void draw() { background(0, 0, 0); text ("Mouse position:\n X: "+mouseX+"\n Y: "+mouseY,10, 20); dir_x = mouseX - ball_x; dir_y = mouseY - ball_y; ball_x = ball_x + dir_x; ball_y = ball_y + dir_y; ellipse (ball_x, ball_y, 10, 10); }
5.3.Capturar los clics del ratón
float ball_x; float ball_y; float dir_x; float dir_y; boolean run; void setup() { size(400, 400); frameRate (20); ball_x = width/2.0; ball_y = height/2.0; dir_x = 1.0; dir_y = 1.0; run = false; } void draw() { background(0, 0, 0); text ("Mouse position:\n X: "+mouseX+"\n Y: "+mouseY,10, 20); if (run == true){ dir_x = mouseX - ball_x; dir_y = mouseY - ball_y; ball_x = ball_x + dir_x; ball_y = ball_y + dir_y; } ellipse (ball_x, ball_y, 10, 10); }
-
Hemos añadido la variable run, que utilizaremos para indicar si la bola se tiene que mover o no. De momento la hemos dejada inicializada con el valor false, de manera que, aunque movamos el ratón, la bola no se moverá.
-
Hemos añadido un bloque if...else que comprueba el valor de la variable run. En el supuesto de que el valor sea true, calculamos el movimiento que tiene que hacer la bola del mismo modo que habíamos visto en el ejemplo anterior.
void mousePressed() { run = true; }
void mousePressed() { if (mouseButton == LEFT){ run = true; }else{ if (mouseButton == RIGHT){ run = false; } } }
5.4.Utilización de la rueda del ratón
void mouseWheel(MouseEvent event) { float incr = event.getAmount(); println(incr); }
![Figura 34. Rueda del ratón](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_34.jpg)
-
El valor 1 indicará la velocidad más lenta.
-
El valor 100 indicará la más rápida, que será la velocidad con que se está moviendo ahora la bola.
float vel;
vel = 100.0;
text ("Mouse position:\n X: "+mouseX+"\n Y: "+mouseY+"\n Vel: "+vel,10, 20);
void mouseWheel(MouseEvent event) { float incr = event.getAmount(); vel = vel + incr; if (vel < 1.0){ vel = 1.0; } if (vel > 100.0){ vel = 100.0; } }
if (run == true){ dir_x = mouseX - ball_x; dir_y = mouseY - ball_y; dir_x = (dir_x * vel) / 100.0; dir_y = (dir_y * vel) / 100.0; ball_x = ball_x + dir_x; ball_y = ball_y + dir_y; }
6.Organización del código
6.1.Las funciones
6.1.1.Estructura básica de las funciones
<tipus_retorn> <nom_funció> (<parametres_que_rep>){ <codi_de_la_funció> return <variable_que_retornem> }
void setup(){}
int funcioTornamUnNombre(){}
void nomFuncio (int nombre, String text){}
return variable
int tornaEnter(){}
6.1.2.Definimos la primera función
float ball_x; float ball_y; float dir_x; float dir_y; boolean run; float vel; void setup() { size(400, 400); frameRate (20); ball_x = width/2.0; ball_y = height/2.0; dir_x = 1.0; dir_y = 1.0; run = false; vel = 100.0; } void draw() { background(0, 0, 0); text ("Mouse position:\n X: "+mouseX+"\n Y: "+mouseY+"\n Vel: "+vel,10, 20); if (run == true){ dir_x = mouseX - ball_x; dir_y = mouseY - ball_y; dir_x = (dir_x * vel) / 100.0; dir_y = (dir_y * vel) / 100.0; ball_x = ball_x + dir_x; ball_y = ball_y + dir_y; } ellipse (ball_x, ball_y, 10, 10); } void mousePressed() { if (mouseButton == LEFT){ run = true; }else{ if (mouseButton == RIGHT){ run = false; } } } void mouseWheel(MouseEvent event) { float incr = event.getAmount(); vel = vel + incr; if (vel < 1.0){ vel = 1.0; } if (vel > 100.0){ vel = 100.0; } }
if (run == true){ dir_x = mouseX - ball_x; dir_y = mouseY - ball_y; dir_x = (dir_x * vel) / 100.0; dir_y = (dir_y * vel) / 100.0; ball_x = ball_x + dir_x; ball_y = ball_y + dir_y; }
void calculatePosition() { dir_x = mouseX - ball_x; dir_y = mouseY - ball_y; dir_x = (dir_x * vel) / 100.0; dir_y = (dir_y * vel) / 100.0; ball_x = ball_x + dir_x; ball_y = ball_y + dir_y; }
void draw() { background(0, 0, 0); text ("Mouse position:\n X: "+mouseX+"\n Y: "+mouseY+"\n Vel: "+vel,10, 20); if (run == true){ calculatePosition(); } ellipse (ball_x, ball_y, 10, 10); }
6.1.3.Otros ejemplos
int i; void setup() { size(200, 100); frameRate (1); i = 1; } void draw() { background(0, 0, 0); text ("i value: "+i,10, 20); i = i +1; }
Función plusOne
void draw() { background(0, 0, 0); text ("i value: "+i,10, 20); plusOne(); } void plusOne(){ i = i + 1; }
Función plusX
void draw() { background(0, 0, 0); text ("i value: "+i,10, 20); plusX(10); } void plusX (int x){ i = i + x; }
Función addXY
void draw() { background(0, 0, 0); text ("i value: "+i,10, 20); i = addXY (i, 10); } int addXY (int x, int y){ int sum; sum = x + y; return sum; }
6.2.Los frames y la gestión del flujo del programa
6.2.1.El guion animado y el diagrama de estados
![Figura 35. Guion animado](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_35.gif)
![Figura 36. Máquina de estados](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_36.gif)
-
Con la rueda del ratón modificamos el tiempo que querremos que se mueva la bola.
-
Al hacer clic en el ratón saltaremos al frame 2.
-
Mientras el tiempo pendiente sea superior a 0, la bola se continúa moviendo.
-
Cuando el tiempo sea 0, saltaremos al estado siguiente.
6.2.2.Del guion animado al código: la estructura switch
if (c == 1){ //Do 1 }else{ if (c == 2){ //Do 2 }else{ if (c == 3){ //Do 3 }else{ //Do 4 } } }
switch(num) { case 0: println("Zero"); break; case 1: println("One"); break; default: println("None"); break; }
int frame; void setup() { size(400, 400); frameRate (20); frame = 1; } void draw() { background(0, 0, 0); switch (frame){ case 1: //Stopped ball, time control, waiting click break; case 2: //Moving ball, countdown break; case 3: //Stopped ball, waiting click break; } }
int frame; int ball_x; int ball_y; int time; String message; float crono; void setup() { size(400, 400); frameRate (20); frame = 1; ball_x = 15; ball_y = height - 15; time = 0; message = new String ("TIME: "); crono = 0.0; } void draw() { background(0, 0, 0); switch (frame){ case 1: //Stopped ball, time control, waiting click break; case 2: //Moving ball, countdown break; case 3: //Stopped ball, waiting click break; } ellipse (ball_x, ball_y, 10, 10); text (message+time, 10, 20); }
![Figura 37. Estructura básica de máquina de estados](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_37.jpg)
Estado 1
void mouseWheel(MouseEvent event) { float incr = event.getAmount(); time = time + int(incr); if (time < 0){ time = 0; } }
void draw() { background(0, 0, 0); switch (frame){ case 1: //Stopped ball, time control, waiting click if (mousePressed){ crono = time; frame = 2; } break; case 2: //Moving ball, countdown break; case 3: //Stopped ball, waiting click break; } ellipse (ball_x, ball_y, 10, 10); text (message+time, 10, 20); text (frame, width-20, 20); }
Estado 2
void draw() { background(0, 0, 0); clock(); switch (frame){ case 1: //Stopped ball, time control, waiting click if (mousePressed){ crono = time; frame = 2; } break; case 2: //Moving ball, countdown countdown(); time = int (crono); break;
void clock() { time_now = millis(); time_delta = time_now - time_old; time_old = time_now; }
void countdown() { crono = crono - (time_delta / 1000.0); }
case 2: //Moving ball, countdown countdown(); time = int (crono); if (time <= 0){ frame = 3; } break;
case 2: //Moving ball, countdown countdown(); time = int (crono); move_ball(); if (time <= 0){ frame = 3; } break;
void move_ball() { ball_x = ball_x + 1; ball_y = ball_y - 1; }
Estado 3
case 3: //Stopped ball, waiting click if (mousePressed){ frame = 1; ball_x = 15; ball_y = height - 15; } break;
7.Trabajar con imágenes
7.1.Elementos básicos
void setup() { size(800, 331); frameRate (20); } void draw() { }
![Figura 38. Cargar imagen (1)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_38.jpg)
![Figura 39. Cargar imagen (2)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_39.jpg)
![Figura 40. Cargar imagen (3)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_40.jpg)
PImage img; void setup() { size(800, 331); frameRate (20); img = loadImage ("background.JPG"); } void draw() { image (img, 0, 0); }
![Figura 41. Cargar una imagen de fondo](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_41.jpg)
7.2.Tipo de imágenes que podemos utilizar
-
JPG: Es el formato que utilizaremos más, nos permite cargar imágenes y mantener una medida de fichero reducida.
-
GIF: Puede ser útil para imágenes pequeñas con detalles muy finos como los de los iconos, por ejemplo, pero el uso más interesante es que podremos cargar imágenes animadas y ver esta animación al ejecutar el programa.
-
PNG: este formato nos permite trabajar con imágenes con zonas transparentes, cosa que nos puede dar bastante juego. Veremos un ejemplo a continuación.
7.3.Añadimos una bola
PImage img; PImage ball; void setup() { size(800, 331); frameRate (20); img = loadImage ("background.JPG"); ball = loadImage ("ball.jpg"); } void draw() { image (img, 0, 0); image (ball, 20, 20); }
![Figura 42. Una bola “maquillada”](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_42.jpg)
PImage img; PImage ball; PImage ball_alfa; void setup() { size(800, 331); frameRate (20); img = loadImage ("background.JPG"); ball = loadImage ("ball.jpg"); ball_alfa = loadImage ("ball.png"); } void draw() { image (img, 0, 0); image (ball, 20, 20); image (ball_alfa, 300, 20); }
![Figura 43. Imágenes transparentes](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_43.jpg)
![Figura 44. Preparamos la imagen con el Photoshop](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_44.jpg)
void draw() { image (img, 0, 0); image (ball, 20, 20); image (ball_alfa, 300, 20); image (ball_alfa, 550, 60, 100, 100); }
![Figura 45. Redimensionar la imagen](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_45.jpg)
8.Transformaciones básicas
8.1.Transformaciones
void setup() { size(400, 400); frameRate (20); } void draw() { background(0, 0, 0); ellipse (0, 0, 80, 40); }
![Figura 46. Código base de transformaciones](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_46.jpg)
8.1.1.Traslación
void draw() { background(0, 0, 0); translate ((width/2), (height/2)); ellipse (0, 0, 80, 40); }
![Figura 47. Traslación](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_47.jpg)
8.1.2.Rotación
void draw() { background(0, 0, 0); translate ((width/2), (height/2)); rotate (HALF_PI); ellipse (0, 0, 80, 40); }
![Figura 48. Rotación](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_48.jpg)
Xradians = radians (Ydegree); Ydegree = degrees (Xradians);
8.1.3.Escala
void draw() { background(0, 0, 0); translate ((width/2), (height/2)); rotate (HALF_PI); scale (3.0); ellipse (0, 0, 80, 40); }
![Figura 49. Escala](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_49.jpg)
scale (3.0, 3.0);
8.2.El problema de la referencia al origen de coordenadas
void setup() { size(400, 400); frameRate (20); } void draw() { background(0, 0, 0); fill (255, 255, 255); ellipse (300, 50, 80, 40); fill (255, 0, 0); rotate (HALF_PI/2); ellipse (300, 50, 80, 40); }
![Figura 50. Transformaciones y origen de coordenadas (1)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_50.jpg)
![Figura 51. Transformaciones y origen de coordenadas (2)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_51.jpg)
rect (5, 5, 2, 2);
![Figura 52. Transformaciones y origen de coordenadas (3)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_52.jpg)
void draw() { background(0, 0, 0); fill (255, 0, 0); stroke (255, 0, 0); rect (5, 5, 2, 2); noFill (); stroke (0, 0, 255); rect (5, 5, 2, 2); }
![Figura 53. Transformaciones y origen de coordenadas (4)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_53.jpg)
void draw() { background(0, 0, 0); fill (255, 0, 0); stroke (255, 0, 0); rect (5, 5, 2, 2); translate (5, 0); noFill (); stroke (0, 0, 255); rect (5, 5, 2, 2); }
![Figura 54. Transformaciones y origen de coordenadas (5)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_54.jpg)
-
Desplazamos el origen de coordenadas a la posición (5, 0).
-
Dibujamos el cuadrado teniendo en cuenta las nuevas coordenadas de referencia.
![Figura 55. Transformaciones y origen de coordenadas (6)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_55.jpg)
void setup() { size(400, 400); frameRate (20); } void draw() { background(0, 0, 0); fill (255, 0, 0); stroke (255, 0, 0); rect (150, 150, 100, 100); noFill (); stroke (0, 0, 255); rect (150, 150, 100, 100); }
![Figura 56. Transformaciones y origen de coordenadas (7)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_56.jpg)
noFill (); stroke (0, 0, 255); rotate (radians (30)); rect (150, 150, 100, 100);
![Figura 57. Transformaciones y origen de coordenadas (8)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_57.jpg)
noFill (); stroke (0, 0, 255); translate (150, 150); rotate (radians (30)); rect (150, 150, 100, 100);
![Figura 58. Transformaciones y origen de coordenadas (9)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_58.jpg)
![Figura 59. Transformaciones y origen de coordenadas (10)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_59.jpg)
noFill (); stroke (0, 0, 255); translate (150, 150); rotate (radians (30)); rect (0, 0, 100, 100);
![Figura 60. Transformaciones y origen de coordenadas (11)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_60.jpg)
8.3.Ámbito de las transformaciones
void setup() { size(400, 200); frameRate (20); } void draw() { background(0, 0, 0); rect (20, 20, 20, 20); translate (100,50); rect (20, 20, 20, 20); ellipse (20, 50, 15, 15); }
![Figura 61. Ámbito de las transformaciones](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_61.jpg)
8.3.1.Ordenación de los elementos en función de las transformaciones
void draw() { background(0, 0, 0); rect (20, 20, 20, 20); ellipse (20, 50, 15, 15); translate (100,50); rect (20, 20, 20, 20); }
![Figura 62. Ordenación de las transformaciones](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_62.jpg)
8.3.2.Invertir los efectos aplicados
void draw() { background(0, 0, 0); rect (20, 20, 20, 20); translate (100,50); rect (20, 20, 20, 20); translate (-100, -50); ellipse (20, 50, 15, 15); }
8.3.3.La pila de transformaciones
-
pushMatrix: Guardará la situación actual en la pila, con todas las transformaciones que haya aplicadas.
-
PopMatrix: Recuperará el último estado que habíamos guardado, de manera que dejaremos de aplicar las transformaciones que teníamos definidas ahora, y volveremos a utilizar las anteriores.
void draw() { background(0, 0, 0); rect (20, 20, 20, 20); pushMatrix(); translate (100,50); rect (20, 20, 20, 20); popMatrix(); ellipse (20, 50, 15, 15); }
void draw() { background(0, 0, 0); fill (255, 0, 0); rect (20, 20, 20, 20); pushMatrix(); translate (100,50); fill (0, 255, 0); rect (20, 20, 20, 20); pushMatrix (); fill (0, 0, 255); rotate (radians(30)); rect (20, 20, 20, 20); ellipse (20, 50, 15, 15); popMatrix(); fill (0, 255, 0); ellipse (20, 50, 15, 15); popMatrix(); fill (255, 0, 0); ellipse (20, 50, 15, 15); }
![Figura 63. Pila de transformaciones](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_63.jpg)
-
Color rojo para las figuras sin ninguna transformación aplicada.
-
Color verde para las figuras que solo tienen la traslación.
-
Color azul para las que tienen la traslación y la rotación.
-
Aplicamos una rotación de 30º, que se suma al desplazamiento que ya teníamos aplicado.
-
Dibujamos el cuadrado azul.
-
Dibujamos el círculo azul.
-
Recuperamos el último estado que tenemos en la pila.
![Figura 64. Cadena cinemática](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_64.jpg)
9.Bibliotecas
apple (20, red);
-
Minim: Es una biblioteca que por defecto ya está cargada y que nos permite trabajar con ficheros de audio.
-
ControlP5: Esta biblioteca no está cargada por defecto y nos permite crear rápidamente interfaces gráficas con botones, desplegables, etc.
9.1.Gestión de bibliotecas
![Figura 65. Lista de bibliotecas](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_65.jpg)
9.1.1.Instalación de la biblioteca ControlP5
![Figura 66. Instalación de bibliotecas (1)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_66.jpg)
![Figura 67. Instalación de bibliotecas (2)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_67.jpg)
![Figura 68. Instalación de bibliotecas (3)](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_68.jpg)
import controlP5.*;
9.2.Biblioteca Minim
void setup() { size(400, 200); } void draw() {
import ddf.minim.spi.*; import ddf.minim.signals.*; import ddf.minim.*; import ddf.minim.analysis.*; import ddf.minim.ugens.*; import ddf.minim.effects.*; void setup() { size(400, 200); } void draw() {
Minim minim; AudioPlayer player;
void setup() { size(400, 200); minim = new Minim(this); player = minim.loadFile("buzzer.mp3"); }
void setup() { size(400, 200); minim = new Minim(this); player = minim.loadFile("buzzer.mp3"); player.play(); }
void draw() { player.play(); }
void mousePressed() { player.play(); }
9.3.Biblioteca ControlP5
![Figura 69. Controles de la biblioteca ControlP5](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_69.jpg)
![Figura 70. Ejemplos disponibles](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_70.jpg)
void setup() { size(400, 200); } void draw() { background (0, 0, 0); }
import controlP5.*;
import controlP5.*; ControlP5 userinterface; void setup() { size(400, 200); userinterface = new ControlP5 (this); }
void setup() { size(400, 200); userinterface = new ControlP5 (this); userinterface.addButton ("button11", 1, 20, 20, 100, 100); }
![Figura 71. ControlP5: el primer botón](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_71.jpg)
void controlEvent(ControlEvent theEvent) { if(theEvent.isController()) { println("control event from : "+theEvent.controller().name()+", value : "+theEvent.controller().value()); if(theEvent.controller().name().equals("button1")) { println ("BUTTON PRESSED"); } } }
import controlP5.*; ControlP5 userinterface; int ball_x; int count; void setup() { size(400, 200); userinterface = new ControlP5 (this); userinterface.addButton ("button1", 1, 20, 20, 100, 100); ball_x = 20; count = 0; } void draw() { background (0, 0, 0); text ("Pressed "+count+" times", 150, 60); ellipse (ball_x, 150, 20, 20); } void controlEvent(ControlEvent theEvent) { if(theEvent.isController()) { println("control event from : "+theEvent.controller().name()+", value : "+theEvent.controller().value()); if(theEvent.controller().name().equals("button1")) { println ("BUTTON PRESSED"); pressedButton1(); } } } void pressedButton1(){ ball_x = ball_x + 10; count = count + 1; }
![Figura 72. ControlP5: botón funcional](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_72.jpg)
![Figura 73. ControlP5: Ejemplo práctico](http://materials.cv.uoc.edu/daisy/Materials/PID_00216129/html5/img/06520_m1_73.jpg)