5. Reto 5. Sistemas

5.3. Arrays

Ya hemos hecho algo con arrays, así que más o menos ya tenéis una idea de lo que son.

Todos del mismo tipo, eso sí. El hecho de usar arrays nos permitirá trabajar con varios objetos a la vez y modificarlos todos con facilidad.

El libro empieza con dos ejemplos, el 11-1 y el 11-2, que son copia del ejemplo 8-3, pero creando dos figuras iguales al 1-11 y cinco al 11-2. En este último ejemplo ya se ve que empezamos a tener muchas variables, para, al final, hacer casi lo mismo con cada una de ellas. La solución pasa por usar un array de cinco posiciones en vez de cinco variables.

Y esto es lo que se hace en el ejemplo 11-3.

En la página 168 del libro se explica qué es un array y se ponen de relieve tres conceptos:

  • El nombre del array, que es el nombre de la variable que almacena el array.
  • El número de elemento. Un array está formado por un conjunto de elementos. Para referirnos a cada elemento, usaremos el número de la posición donde se encuentra.
  • El valor de cada elemento.

A la hora de definir un array lo que haremos es declarar una variable a la que le «asignaremos» un array vacío o un array con un contenido, como por ejemplo:

var x = [];
var y = ["coche", 40, "moto", 25, "camión", 60];
var z = [14,40,33,25,54,60];

A partir de aquí, si es necesario guardar un valor en el array, haremos esto:

x[posición_a_modificar] = valor_a_guardar;

La posición_a_modificar siempre será un número entero positivo y siempre empezaremos por 0.

Para consultar un valor que tengamos almacenado en el array lo haremos de este modo:

console.log(x[posición_a_consultar]);

También podemos consultar cuántos elementos tiene el array:

console.log(x.length);

Al final estamos sustituyendo x0, x1, x2, x3 por x[0], x[1], x[2], x[3] y nos podemos preguntar qué ganamos con esto. Con un ejemplo se ve muy fácil. Vamos a escribir en la consola los valores de todas estas variables:

console.log(x0);
console.log(x1);
console.log(x2);
console.log(x3);
for (var i = 0; i <= 3; i++) {
 console.log(x[i]);
}

Quizás con 4 variables no se ve una gran diferencia… Pero en el ejemplo 11-3 ¡se usan 3.000!

Los ejemplos 11-4, 11-5 y 11-6 son pequeños códigos que nos permiten ver en la práctica todo esto que hemos ido viendo aquí.

Vamos a darle un vistazo al ejemplo 11-7. Lo que hace es crear una variable de tipo array donde almacena, dentro del setup(), tantos valores aleatorios (entre 0 y 255) como la medida horizontal del canvas (width).

Después en el draw() dibuja width líneas verticales, del color almacenado en la posición del array que toca. El ejercicio no es nada complicado, así que lo hemos modificado un poco para darle más interés:

var gray = [];
function setup() {
 createCanvas(240, 120);
 for (var i = 0; i < width; i++) {
  gray[i] = random(0, 255);
 }
}
function draw() {
 background(204);
 for (var i = 0; i < gray.length; i++) {
  stroke(gray[i]);
  line(i, 0, i, height);
}
 stroke(0);                    // Extra
 line(mouseX,0,mouseX,height); // Extra
}

Hemos añadido dos líneas extras que hacen que se dibuje una línea negra en el lugar donde está el ratón. Como guardamos en el array el color original de las líneas, una vez el ratón cambia de lugar, la línea recupera el color que ya tenía.

El ejemplo 11-8 es bastante interesante, pero a la vez un poco complicado de entender. Para poder comprender mejor lo que hace, hemos creado un ejemplo parecido, pero más sencillo.

Lo que hace este ejemplo es dibujar un círculo cada vez que hacemos un clic con el ratón. No tiene función draw() porque solo se dibuja cuando hagamos un clic. Por lo tanto, lo que sí tenemos es la función mouseClicked(). Lo que pasa es que hemos limitado el número de círculos que podremos tener en la pantalla a 10. Cuando ya tenemos 10 círculos en la pantalla y se hace un clic con el ratón, se borra el más antiguo antes de pintar uno nuevo. Así podemos ir pintando círculos, pero siempre tendremos 10.

La complicación de este ejemplo radica en el borrado. No tenemos una manera de borrar un elemento sin borrarlo todo (borrarlo todo siempre es pintar de nuevo el fondo (background)). Por lo tanto, borrar un elemento implicará borrarlo a pesar de pintar todos los elementos menos el que queríamos borrar.

Tenemos tres variables globales, dos, circX y circY nos guardan las posiciones x e y de todos los círculos dibujados. A cada círculo que dibujamos le asignaremos una posición en los arrays. Y usaremos la variable pos para saber en qué posición de los arrays guardaremos el próximo círculo que dibujamos. También nos servirá para decidir cuál es el círculo que hay que borrar.

Para borrar el círculo que toca, usamos la función borrar que, de hecho, lo que hace es borrar todo el canvas y volver a pintar todos los círculos menos el que toca borrar.

Con un sencillo ejemplo lo veremos más claro. Supongamos que ya tenemos los 10 círculos pintados y que llevamos un rato haciendo clic con el ratón. Supongamos que en la variable pos hay un 5. ¿Qué haremos? Pues borraremos el canvas y pintaremos todos los círculos menos el que está en la posición 5. Después pintaremos un nuevo círculo y guardaremos su posición en el canvas (los valores de x e y) en la posición pos de los arrays. Finalmente, incrementaremos el valor de la variable pos para que el próximo círculo que pintemos se guarde una posición más allá y no borremos el que acabamos de pintar.

var circX = []; // Variables donde guardaremos las posiciones
var circY = []; // x e y de los círculos que dibujamos.
var pos = 0;   // Círculo que estamos dibujando.
var mx = 10;   // Número máximo de círculos

function setup() {
  createCanvas(400, 400); // Creamos el canvas
  background(220);   // Ponemos un fondo 
  noStroke();     // No queremos filete a los círculos
  for (var i = 0; i < 10; i++){
    circX[i] = -100;
    circY[i] = -100;
}
  fill(0);
}

function mouseClicked() { // Cuando se hace clic con el ratón
 esborrar(pos, mx);       // Borramos el círculo que toca
 circX[pos] = mouseX;     // Guardamos la posición del ratón
 circY[pos] = mouseY;
 ellipse(circX[pos],circY[pos],50,50); // Dibujamos el nuevo círculo
 pos++;                   // Incrementamos la variable pos.
 if (pos === mx){         // Si pos vale mx le damos el valor de 
  pos = 0;                // 0. Así controlamos el número de 
 }                        // círculos.
}

function borrar(elemento, mx) {
  background(220);
  for (var i = 0; i < elemento; i++){ // Pintamos de 0 a pos
    ellipse(circX[i],circY[i],50,50);
}
  for (i = elemento+1; i < mx; i++){ // Pintamos de pos hasta el final
    ellipse(circX[i],circY[i],50,50);
 }
}

Ahora podemos mirar el ejemplo 11-8. Este usa dos arrays (igual que hemos hecho con nuestro ejemplo) para guardar la información de las posiciones por donde ha pasado el círculo y poder hacer así un rastro. Como el círculo se dibuja siguiendo el ratón, aquí sí que se hace todo dentro de la función draw().

Echemos un vistazo al ejemplo:

var num = 60; // Tamaño del rastro. Si lo incrementamos, el rastro será
              // más largo
var x = [];
var y = [];

function setup() {
  createCanvas(240, 120);
  noStroke();
           // Inicializamos las dos tablas poniendo 0 en todas
           // las posiciones. Es conveniente poner siempre un valor
           // inicial en todas las variables que usamos.
  for (var i = 0; i < num; i++) {
    x[i] = 0;
    y[i] = 0;
 }
}
function draw() {
  background(0); // Borramos la pantalla para volver a dibujarlo
                 // todo de nuevo
    // Mueve todos los valores de las variables a una posición más alta
    // Así mantiene el histórico de los lugares por los que ha pasado el
    // círculo.
  for (var i = num-1; i > 0; i--) {
    x[i] = x[i-1];
    y[i] = y[i-1];
}
// Guarda la posición actual del ratón en el primer elemento de las
// dos tablas
x[0] = mouseX; // Set the first element
y[0] = mouseY; // Set the first element
// Dibuja todos los círculos, tanto el primero como los que hacen el
// rastro. Va haciendo el color del círculo más oscuro conforme la
// la posición es más grande.
  for (var i = 0; i < num; i++) {
    fill(i * 4);
    ellipse(x[i], y[i], 40, 40);
 }
}

En la página 174 del libro se explica cómo se van moviendo los valores para poder hacer el rastro.

Antes de acabar, el libro pone dos ejemplos más, el 11-9 y el 11-10, pero usa objetos y es un tema que solo veremos, ahora mismo, un poco por encima, así que no los usaremos en la asignatura.