Joan Soler-Adillon || Programació: Conceptes
Despatx 234 || 935 421 484
----------------------------------------------------------------
----------------------------------------------------------------
PROGRAMACIÓN: CONCEPTOS || MASTER EN ARTES DIGITALES
Sección 8: Arrays
1. Arrays
2. Arrays y loops
3. Ejemplos
4. PRACTICA
Un Array es una lista de valores. Es un contenedor de múltiples variables, de tal o cual tipo de datos, a los que nos referimos por su posición dentro de dicha lista.
Una vez hemos visto bucles, condicionales, y variables, muy fácilmente uno se puede encontrar en una situación donde se empiezan a crear múltiples variables que tienen a ver entre ellas. Por ejemplo, si en nuestros ejemplos de la pelota queremos tener más de una, tenemos que hacer algo como posX1, posX2, posX3, etc.
Pues arrays al rescate! Podemos tener un sólo contenedor de posiciones: posicionesX, p.e., donde puede haber los valores que haga falta.
La cosa va así:
//creamos un array de enteros llamado listaPosiciones: int[] listaPosiciones = { 14, 94, 120, 80 };
Vamos por partes: int[] indica que declaramos un array del tipo de datos int, nada más. Es decir, una lista de enteros. "listaPosiciones" es el nombre que le damos al array, y los números que van entre claves y separados por comas son sus valores.
Para acceder a uno de estos valores, si con una variable normal nos basta con su nombre, en un array necesitamos el nombre del array y el índice. Atención: el primer elemento de un array está siempre en la posición cero!. Así
se refiere al tercer valor en el array. En el ejemplo anterior, 120. Se puede comprobar con el código que sigue:
//creamos un array de enteros llamada listaPosiciones: int[] listaPosiciones = { 14, 94, 120, 80 }; //e imprimimos un par de sus valores a la consola: println(listaPosiciones[0]); println(listaPosiciones[3]);
Así, un array no es más que un conjunto de variables, que podemos utilizar como tales:
//creamos un array de enteros llamada listaPosiciones: int[] listaPosiciones = { 14, 94, 120, 80 }; size(200,200); // y dibujamos cuatro de elipses según el array: ellipse(listaPosiciones[0], 100,25,25); ellipse(listaPosiciones[1], 100,25,25); ellipse(listaPosiciones[2], 100,25,25); ellipse(listaPosiciones[3], 100,25,25);
Tambien es útil saber que para canviar un valor en un array, se realiza una asignación como con cualquier variable:
int[] listaPosiciones = { 14, 94, 120, 80 }; // pasan cosas... //y cambio: listaPosiciones[0] = 99; println(listaPosiciones[0]);
En la sección de ejemplos se puede ver otra manera de declarar un array, que consiste en especificar el tamaño del mismo pero no el valor de lo que contiene:
Luego, a cada una de las posiciones del array que hemos creado, podemos asignar un valor tal y como lo hacemos con las variables normales (cosa que de hecho puede hacerse también para luego cambiar los valores, igual que en el caso de crear el array tal y como vimos en el primer ejemplo):
Para arrays grandes, este sistema mucho más eficiente en la mayoría de casos.
2.- Arrays y loops
Donde el poder de los arrays se aprovecha mejor, es en su combinación con los bucles. Es bastante lógico que si tenemnos una estructura que puede guardar varias variables indexadas, y otra que nos permite iterar una misma acción en distintos elementos, las utilizemos conjuntamente.
Si no, sólo hay que mirar el último ejemplo de la sección anterior, donde el hecho de estar utilizando un array no nos reduce para nada la cantidad de código que hay que escribir. Sería exactamente lo mismo si utilizáramos cuatro variables. En cambio, si combinamos el array con un loop, podemos hacer algo así:
int[] listaPosiciones = { 14, 94, 120, 80 }; size(200,200); // y dibujamos las elipses via loop: for(int i=0; i<4; i++){ ellipse(listaPosiciones[i], 100,25,25); }
El resultado es exactamente el mismo, pero aquí, gracias a utilizar listaPosiciones[i] dentro del loop, estamos aprovechando las iteraciones del bucle para afectar todos los elementos del array. Cuatro en este caso, pero que pueden ser muchísimos más.
int[] listaPosiciones = { 14, 25, 39, 64, 94, 109, 122, 150, 170, 178, 190 }; size(200,200); // y dibujamos las elipses via loop: for(int i=0; i<11; i++){ ellipse(listaPosiciones[i], 100,25,25); }
¿Pero qué passa cuando tenemos ya muchos elementos? Contarlos puede llegar a ser un poco tedioso, y, sobretodo, ineficiente si cambiamos en algún momento la cantidad de valores que le damos al array en la declaración.
Así, podemos substituir en el ejemplo anterior la línea de declaración de for loop por:
for(int i=0; i<listaPosiciones.length; i++){
Así utilizamos una variable que Processing ya calcula para nosotros: array.length que, como su nombre indica, corresponde a la cantidad de elementos presentes en el array en cuestión.
Atención: array.length nos indica el número de elementos en el array, pero el índice de dichos elementos empieza por 0, así que de hecho array[array.length] no existe! De aquí que en la condición le decimos al loop que se ejecute cuando "i" es MENOR a listaEnteros.length.
Finalmente, aprovechando el random para ser más eficientes, podemos hacer lo que sigue:
float[] listaPosiciones = new float[13]; size(200,200); // creamos aleatoriamente todas las posiciones: for(int i=0; i<13; i++){ listaPosiciones[i] = random(0,200); } // y dibujamos las elipses via loop: for(int i=0; i<13; i++){ ellipse(listaPosiciones[i], 100,25,25); }
3.- Ejemplos
Vimos en el punto uno que se pueden declarar variables sin asignarle valores immediatamente. Esto, por ejemplo, lo podemos utilizar para... sorpresa! Un ejemplo de pelotitas!
Con esto dentro de SETUP:
for(int i = 0; i<numeroBolas; i++){
posicionesX[i] = width/2;
posicionesY[i] = height/2;
velocidadesX[i] = random(2,6);
velocidadesY[i] = random(2,6);
}
Iniciamos una serie de posiciones en el eje X e Y en el punto medio del applet, y unas velocidades X e Y entre 2 y 6. Los cuatro arrays con los que trabajamos aquí son de floats.
Una vez hecho esto, sin cambiar casi nada el código del ejemplo con una sola pelota, podemos multiplicar los elementos que afectamos. Así, dentro del DRAW:
//iniciamos un bucle para que realize la acción para todos los //elementos del array: for(int i = 0; i<numeroBolas; i++){ //actualitzamos las posiciones posicionesX[i] += velocidadesX[i]; posicionesY[i] += velocidadesY[i]; //comprobamos los bordes X if((posicionesX[i]<0)||(posicionesX[i]>width)){ velocidadesX[i] = -velocidadesX[i]; } //comprobamos los bordes Y if((posicionesY[i]<0)||(posicionesY[i]>height)){ velocidadesY[i] = -velocidadesY[i]; } } //acabado el proceso, creamos otro bucle //donde dibujamos las elipses: for(int i = 0; i<numeroBolas; i++){ ellipse(posicionesX[i],posicionesY[i],sz,sz); }
El ejemplo completo de las multibolas está aquí:
Source code: arraybball
También podemos añadir colorines, y encima un "reset" utilizando una función de sistema: el mousePressed:
void mousePressed(){ //reinicializamos las velocidades: for(int i = 0; i<numeroBolas; i++){ velocidadesX[i] = random(2,10); velocidadesY[i] = random(2,10); } }
MousePressed es una función que hay que colocar fuera del setup y del draw, ya que se ejecuta independientemnte de estos procesos.
Podéis mirar colorMode() para entender cómo se utiliza en el ejemplo el color, y el ejemplo de las bolas con colorines aquí:
Source code: arraybballcolors
Otro ejemplo, un poco más complejo, pero que sirve para introducir el uso del texto: la frase:
Source code: texttext
----------------------------------------------------------------------------------------------------