3. Repte 3. Interaccions

3.6. p5.js als dispositius mòbils

Podem fer servir la nostra aplicació als dispositius mòbils. p5.js s’encarrega de traduir els events de pantalla a events de teclat, de manera que un toc a la pantalla equivaldrà a un clic del ratolí.

Els exemples 5-20 i 5-21 estan pensats per a fer-los servir amb dispositius mòbils.

Funcions específiques per a dispositius mòbils

Malgrat podem fer servir les funcions i variables del ratolí per a interaccionar amb la pantalla d’un dispositiu mòbil, p5.js ens proporciona algunes opcions interessants per a fer-ho.

Per tal que els programes que fem funcionin bé als dispositius mòbils, també caldrà una petita modificació de l’arxiu HTML que fem servir com a base i que és el que sempre haureu de fer servir.

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
  <style>
    body {margin: 0; padding: 0;}
  </style>
  <script src="js/p5.min.js"></script>
  <script src="js/sketch.js"></script>
 </head>
 <body>
 </body>
</html>

touches

touches és una variable del sistema que ens guarda informació de les posicions on s’ha tocat la pantalla. Les pantalles dels nostres dispositius mòbils són multitàctils, la qual cosa vol dir que poden detectar més d’un toc alhora. La variable touches emmagatzema totes les posicions de la pantalla que s’estan tocant. És el que denominem array i, tot i que ho veurem explicat amb més detall en el repte següent, vegem ara com funciona.

Els arrays són una estructura de dades que ens permet guardar més d’una dada alhora. A la variable touches hi podem guardar tots els tocs simultanis a la pantalla. Per a poder consultar els diferents valors que pot guardar una variable de tipus array fem servir aquesta notació:

touches[n];

On n és la posició que volem consultar. En el cas de touches, a més a més tindrem un valor per a la posició x i un altre per a la posició y, així que per a consultar la posició x i y del primer toc que es faci a la pantalla, farem aquesta consulta:

var posX = touches[0].x
var posY = touches[0].y

Si hi ha dos dits tocant la pantalla, com accedirem a la posició del segon dit? Fàcil, si la primera posició era 0, la segona és 1:

var posX = touches[1].x
var posY = touches[1].y

Vegem un primer exemple amb la variable touches. Volem que quan fem un toc a la pantalla es dibuixi un cercle a la posició on s’ha fet el toc.

// En el setup creem el canvas. El farem de l’amplada i l’alçada
// màxima de la pantalla.

function setup() {
 createCanvas(windowWidth, windowHeight);
 background("white");
 fill(255);
}
function draw() {
 if (touches.length>0) {
   ellipse(touches[0].x, touches[0].y, 50, 50);
 }
}

Si proveu aquest exemple us adonareu que la pantalla del mòbil es mou al moure el dit. És un efecte estrany i lleig per a l’usuari, però arreglar-ho és molt fàcil. Hem d’afegir aquesta funció al final (l’explicarem millor més endavant):

function touchMoved() {
return false;
}

Ara, amb tot el codi, si provem l’exemple funcionarà millor.

Exercicis

  1. Modificar el codi per tal que, en comptes de pintar un cercle, pinti un punt negre.
  2. Modificar el codi perquè dibuixi dos cercles si s’està tocant la pantalla amb dos dits.
  3. Modificar el codi perquè el primer dit faci dibuixar un cercle i el segon dit faci que canviï el color (negre si no hi ha un segon dit, vermell en cas contrari).
  4. Modificar el codi per tal que el color de fons canviï segons el nombre de dits (fins a 4) que toquen la pantalla.

touchStarted()

La funció touchStarted(), per defecte, no té cap codi associat a p5.js, així que haurem d’escriure nosaltres el codi si la volem fer servir. Aquesta funció és cridada en el moment que es detecta un toc a la pantalla o un clic amb el ratolí. Si aquesta funció no existeix, és a dir, si no l’hem escrit nosaltres, aleshores es busca la variable mouseIsPressed. El funcionament però és diferent i, per tant, la programació també serà diferent si es fa servir la funció o la variable.

Vegem ara un parell d’exemples extrets del manual de referència de p5.js:

Exemple 1

var value = 0;
function setup() {
 createCanvas(windowWidth, windowHeight);
 background("white");
}
function draw() {
 fill(value);
 rect(25, 25, 50, 50);
}
function touchStarted() {
 if (value === 0) {
  value = 255;
 } else {
  value = 0;
 }
}

Com podem veure, quan es fa un toc a la pantalla es canvia el color del quadre. Veureu que amb el ratolí funciona molt bé, però al mòbil només funciona bé si mantenim tocant amb el dit la pantalla almenys un segon.

El segon codi és aquest:

function setup() {
 createCanvas(windowWidth, windowHeight);
 background(124);
 fill(255);
}

function touchStarted() {
 ellipse(mouseX, mouseY, 5, 5);
 // prevent default
 return false;
}

En aquest cas, cada cop que fem un clic amb el ratolí o toquem la pantalla es dibuixarà un cercle. Prova l’exemple i comprova què passa quan, mantenint un dit tocant la pantalla, fas un toc amb un altre dit.

touchMoved()

La funció definible touchMoved(), es crida quan movem el dit per sobre de la pantalla. Si no està definida es crida a la funció mouseDragged(). Sens dubte, la millor manera d’entendre el funcionament d’aquesta funció és amb un exemple, que serà el segon que hem fet servir per la funció touchStarted(), però canviant la funció definida:

function setup() {
 createCanvas(windowWidth, windowHeight);
 background(124);
 fill(255);
}

function touchMoved() {
 ellipse(mouseX, mouseY, 5, 5);
 // prevent default
 return false;
}

Afegim una funció touchStarted() per a esborrar el contingut:

function setup() {
 createCanvas(windowWidth, windowHeight);
 background(124);
 fill(255);
}

function touchMoved() {
 ellipse(mouseX, mouseY, 5, 5);
 // prevent default
 return false;
}

function touchStarted() {
 background(124);
}

touchEnded()

La funció touchEnded() es crida quan el toc finalitza. De nou, farem servir un exemple per a veure millor el seu funcionament:

var xIni, yIni = 0;
var xFin, yFin = 0;

function setup() {
 createCanvas(windowWidth, windowHeight);
 background(124);
 fill(255);
}

function touchStarted() {
 background(124);
  xIni = mouseX;
  yIni = mouseY;
		print(xIni);
}

function touchMoved() {
 ellipse(mouseX, mouseY, 5, 5);
    xFin = mouseX;
    yFin = mouseY;
 return false;
}

function touchEnded() {
  line (xIni, yIni, xFin, yFin);
}

Fixeu-vos que hem fet servir mouseX i mouseY per a conèixer la posició del dit a la pantalla en cada moment. Cal dir que aquest codi funcionarà tant en un dispositiu mòbil com en un ordinador, en el dispositiu mòbil reaccionarà als tocs de pantalla i a l’ordinador als clics i moviments del ratolí.

La funció map()

La funció map() es fa servir per a canviar l’escala d’un valor. A fi d’explicar-ho, al llibre hi ha un exemple (el 5-22) que no fa servir aquesta funció però fa una cosa semblant.

Però l’exemple 5-23, que sí que fa servir la funció map() és més clar. Tenim dues ratlles, una, la blanca que fem que arribi des de la posició 0 fins a la posició màxima del canvas. I una segona, negra, que només volem que es mogui entre el rang de 60 a 180. Així, el que farem serà indicar el valor d’x que, pot estar entre 0 i 240, a un nombre que anirà entre el 60 i el 180.