Introdução à Programação Gráfica
usando Processing
INTERAÇÃO
Permite executar diversas vezes o mesmo trecho
Cada execução é chamada de iteração
Pára quando uma certa condição for satisfeita
É mais fácil entender o funcionamento da estrutura de repetição quando o número de vezes que repete está associado à interação com mouse ou teclado!
while
Repete enquanto a condição for verdadeira (true)
Condição testada antes de executar o código
while(condição)
{
primeira instrução;
segunda instrução;
//...
}
do while
Repete enquanto a condição for verdadeira (true)
Condição testada depois de executar o código
do
{
// Instrução 1
// Instrução 2
} while(condição);
for
Repete enquanto a condição for verdadeira (true)
Usa uma variável para controlar a execução
for (inicialização; condição ; incremento)
{
comando 1;
comando 2;
// ...
}
+ - for é equivalente a while
inicialização
while (condição)
{
comando 1
...
comando n
incremento }
Interrompe a estrutura e passa para a próxima iteração
Estrutura | Quando é testada a condição |
Quantidade de execuções |
Efeito do comando continue |
---|---|---|---|
while | início | 0 ou mais |
Passa para a próxima iteração, ou seja, testa a condição |
do while | fim | 1 ou mais |
Passa para a próxima iteração, ou seja, testa a condição |
for | início | 0 ou mais |
Faz o incremento e depois testa a condição |
Teste no meio | Qualquer lugar |
Depende se utiliza while, do while ou for |
Depende se utiliza while, do while ou for. |
Dispositivo apontador
Nem todos os computadores possuem dois botões
Dispositivos touch funcionam como mouse
+ -
Variáveis para trabalhar com mouse
Funções para trabalhar com mouse
Ocorre quando o usuário arrasta o mouse na tela
+ - Documentação
Funções geralmente relacionadas com mouse
+ - Exemplos
PFont f;
void setup() {
size(300,300);
f = createFont("Arial", 15);
textFont(f);
}
void draw() {
background(0);
text("mouseX = " + mouseX, 10, 20);
text("mouseY =" + mouseY, 10, 60);
}
void setup() {
size(300,300);
}
void draw() {
background(0);
// O retangulo segue o cursor.
rect(mouseX, mouseY, width/3, height/3);
}
void setup() {
size(300,300);
noCursor();
}
void draw() {
background(0);
// O retângulo é desenhado em relação ao centro
rectMode(CENTER);
// O retangulo segue o cursor.
rect(mouseX, mouseY, width/5, height/5);
ellipse(mouseX,height/2, width/5, height/5);
ellipse(width/2,mouseY, width/5, height/5);
}
void setup() {
size(300,300);
noCursor(); // Desliga o mouse
}
void draw() {
background(0);
ellipse(width/2, height/2, mouseX, mouseY);
}
void setup() {
size(255,255);
}
void draw() {
background(mouseX);
rectMode(CENTER);
translate(width/2,height/2);
fill(mouseY);
rect(0,0, 60,60);
}
float k = map(valor, inicio intervalo original, fim intervalo original, inicio intervalo final, fim intervalo final)
void setup() {
size(600,400);
}
void draw() {
background(0);
fill(mouseX, 0, 0);
// O retângulo vai até o fim da tela
rect(0, height/2, mouseX, 10);
}
void setup() {
size(600,400);
}
void draw() {
background(0);
// mouseX vai de 0 a width. Gostaria que fosse de 0 a 255
float cor = map(mouseX, 0, width, 0, 255);
fill(cor, 0, 0);
// O retângulo vai até o meio da tela
// mouseX vai de 0 até width. Gostaria que fosse de 0 a width/2
float larguraBarra = map(mouseX, 0, width, 0, width/2);
rect(0, height/2, larguraBarra, 10);
}
void setup() {
size(600,400);
}
void draw() {
point(mouseX, mouseY);
}
void setup() {
size(600,400);
}
void draw() {
line(mouseX, mouseY, pmouseX, pmouseY);
}
void setup() {
size(600,400);
smooth();
strokeWeight(12);
stroke(0,0,0,128);
}
void draw() {
// Só desenhe o ponto quando o mouse for pressionado
if(mousePressed) {
point(mouseX, mouseY);
}
}
void setup() {
size(600,400);
smooth();
stroke(0,0,0,128);
}
void draw() {
// O tamanho da linha é aleatório
strokeWeight(random(5, 15));
// Só desenhe a linha quando o mouse for pressionado
if(mousePressed) {
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
+ - Função saveFrame
void setup() {
size(600,400);
smooth();
stroke(0,0,0,128);
background(128);
}
void draw() {
// O tamanho da linha é aleatório
strokeWeight(random(5, 15));
// Só desenhe a linha quando o mouse for pressionado
if(mousePressed) {
// Se for o botão esquerdo
if(mouseButton==LEFT) {
line(mouseX, mouseY, pmouseX, pmouseY);
}
// Se for o botão direito
if(mouseButton==RIGHT) {
// Salva a tela
saveFrame();
// Limpa a tela
background(128);
}
}
}
void setup() {
size(600,400);
smooth();
strokeWeight(10);
background(128);
}
void draw() {
// A cor é aleatória
stroke(random(0, 256), random(0, 256), random (0, 256), 128);
// Só desenhe a linha quando o mouse for pressionado
if(mousePressed) {
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
void setup() {
size(600,400);
smooth();
strokeWeight(10);
background(128);
}
void draw() {
// A cor é aleatória
stroke(random(0, 256), random(0, 256), random (0, 256), 128);
// Só desenhe a linha quando o mouse for pressionado
if(mousePressed) {
// mouseX deve estar restrito entre 100 e largura menos 100
float mx = constrain(mouseX, 100, width-100);
float my = constrain(mouseY, 100, height-100);
float pmx = constrain(pmouseX, 100, width-100);
float pmy = constrain(pmouseY, 100, height-100);
line(mx, my, pmx, pmy);
}
}
float x, largura;
void setup() {
size(600,400);
x = width/2;
largura = 50;
}
void draw() {
fill(0);
if(mousePressed) {
// Se x for maior que mouseX e x+largura for menor que mouseX
if( (x < mouseX) && (x+largura > mouseX) ) {
fill(255);
}
}
rect(x, 0, largura, height);
}
float x, larguraX, y, larguraY;
void setup() {
size(600,400);
x = width/2;
y = height/2;
larguraX = 50;
larguraY = 60;
}
void draw() {
fill(0);
if(mousePressed) {
// Se x for maior que mouseX e x+largura for menor que mouseX
if( (x < mouseX) && (x+larguraX > mouseX) &&
(y < mouseY) && (y+larguraY > mouseY) ) {
fill(255);
}
}
rect(x, y, larguraX, larguraY);
}
Função dist
float x, y, raio;
void setup() {
size(600,400);
x = width/2;
y = height/2;
raio = 30;
}
void draw() {
background(128);
// Movimento browniano
x = x + random(-5, 5);
y = y + random(-5, 5);
fill(0);
if(mousePressed) {
if( dist(x, y, mouseX, mouseY)<raio) {
fill(255);
}
}
ellipse(x, y, raio*2, raio*2);
}
+ - Função get
float x, y;
color corObj;
color corColisao;
void setup() {
size(600,400);
x = width/2;
y = height/2;
corColisao = color(255,0,0);
}
void draw() {
background(128);
// Movimento browniano
x = x + random(-2, 2);
y = y + random(-2, 2);
// Pinta os objetos de colisão, observe que são iguais aos
// objetos pintados
fill(corColisao);
triangle(x, y, x+50, y, x+25, y-50);
rect(x, y+10, 50, 50);
// Checa a colisão
corObj = color(0);
if(mousePressed) {
color cor = get(mouseX, mouseY);
// Se a cor clicada for igual à cor de colisão
if(cor == corColisao) {
corObj = color(255);
} else {
corObj = color(0);
}
}
// Desenha os objetos a serem mostrados
// Neste caso, o objeto mostrado é igual ao objeto de colisão
fill(corObj);
triangle(x, y, x+50, y, x+25, y-50);
rect(x, y+10, 50, 50);
}
Neste caso, criamos uma imagem de máscara e verificamos a colisão na máscara
float x, y;
PImage aviao, aviaoMask;
color corColisao = color(255,0,0);
PFont f;
String mensagem;
void setup() {
size(600,400);
x = width/2;
y = height/2;
f = createFont("Arial", 20);
textFont(f);
corColisao = color(255,0,0);
aviao = loadImage("aviaoTransp.png"); // Imagem original
aviaoMask = loadImage("aviaoMask.png"); // Máscara
}
void draw() {
background(128);
// Movimento browniano
x = x + random(-2, 2);
y = y + random(-2, 2);
// Desenha o objeto de colisão
image(aviaoMask, x, y);
// Checa a colisão
mensagem = "";
if(mousePressed) {
// Obtém a cor exata na posição
color cor = get(mouseX, mouseY);
// Se a cor clicada for igual à cor de colisão
if(cor == corColisao) {
mensagem = "Acertou!";
} else {
mensagem = "Errou!";
}
}
// Desenha os objetos a serem mostrados
background(0,0,255);
text(mensagem, 30, 60);
image(aviao, x, y);
// Como gerar a máscara dentro do Processing, se você não souber usar Gimp, Photoshop ou similar
//aviao.filter(THRESHOLD, 1);
//aviao.filter(ERODE);
//aviao.save("aviaoMascara.png");
}
color cor;
void setup() {
size(600,400);
cor = color(0);
noStroke();
}
void draw() {
// Desenha as cores disponíveis
noStroke();
fill(255,0,0);
rect(0,10,30,30);
fill(0,255,0);
rect(30,10,30,30);
fill(0,0,255);
rect(60,10,30,30);
// Se o mouse for pressionado
if(mousePressed) {
// Se estiver na barra de cores
if(mouseX>0 && mouseX<90 && mouseY>10 && mouseY<40) {
cor = get(mouseX, mouseY);
}
stroke(cor);
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
color cor;
float tam;
int tamStroke;
void setup() {
size(600,400);
cor = color(0);
noStroke();
tam = 30;
tamStroke = 1;
}
void draw() {
// Desenha as cores disponíveis
noStroke();
fill(255,0,0);
rect(0,10,tam,tam);
fill(0,255,0);
rect(30,10,tam,tam);
fill(0,0,255);
rect(60,10,tam,tam);
fill(0);
rect(90,10,tam,tam);
fill(255);
rect(120,10,tam,tam);
// Se o mouse for pressionado
if(mousePressed) {
// Se estiver na barra de cores
if(mouseX>0 && mouseX<(tam*3) && mouseY>0 && mouseY<10+tam) {
cor = get(mouseX, mouseY);
}
// Clicou no botão, aumenta o stroke
if(mouseX>90 && mouseX<90+tam && mouseY>10 && mouseY<10+tam) {
strokeWeight(tamStroke);
tamStroke++;
}
// Clicou no outro, diminui o stroke
if(mouseX>120 && mouseX<120+tam && mouseY>10 && mouseY<10+tam) {
strokeWeight(tamStroke);
tamStroke--;
}
stroke(cor);
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
+ - Exemplo errado, usando mousePressed
A pontuação é incrementada a cada draw
int pontos = 0;
PFont f;
float x, y;
void setup() {
size(600,400);
f = createFont("Arial", 20);
textFont(f);
x = width/2;
y = height/2;
}
void draw() {
background(0);
fill(255,0,0);
rect(x, y, 50, 50);
// Sem usar o mouse clicked, a pontuação fica errada!
if(mousePressed) {
color cor = get(mouseX, mouseY);
if(cor==color(255,0,0)) {
pontos++;
}
}
text(pontos, 20, 20);
}
Exemplo com mouseClicked, incrementando a pontuação apenas uma vez
Pontua depois que o mouse é solto
int pontos = 0;
PFont f;
float x, y;
color cor;
void setup() {
size(600,400);
f = createFont("Arial", 20);
textFont(f);
x = width/2;
y = height/2;
}
void draw() {
background(0);
fill(255,0,0);
rect(x, y, 50, 50);
cor = get(mouseX, mouseY);
text(pontos, 20, 20);
}
void mouseClicked() {
if(cor==color(255,0,0)) {
pontos++;
}
}
Exemplo com mousePressed, incrementando a pontuação apenas uma vez
Pontua antes que o mouse é solto
int pontos = 0;
PFont f;
float x, y;
color cor;
void setup() {
size(600,400);
f = createFont("Arial", 20);
textFont(f);
x = width/2;
y = height/2;
}
void draw() {
background(0);
fill(255,0,0);
rect(x, y, 50, 50);
cor = get(mouseX, mouseY);
text(pontos, 20, 20);
}
void mousePressed() {
if(cor==color(255,0,0)) {
pontos++;
}
}
float dragX, dragY;
void setup() {
size(600,400);
}
void draw() {
background(0);
ellipse(dragX, dragY, 100, 100);
}
// Quando faz o drag & drop, atualiza as variáveis
// de posição da elipse
void mouseDragged() {
dragX = mouseX;
dragY = mouseY;
}
float dragX, dragY;
color cor;
void setup() {
size(600,400);
cor = color(255);
}
void draw() {
background(0);
fill(cor);
ellipse(dragX, dragY, 100, 100);
}
// Quando faz o drag & drop, atualiza as variáveis
// de posição da elipse
void mouseDragged() {
dragX = mouseX;
dragY = mouseY;
cor = color(255,0,0);
}
void mouseReleased() {
cor = color(255);
}
// Adaptado de REAS 26-04
float dragX, dragY, moveX, moveY;
void setup() {
size(600,400);
smooth();
}
void draw() {
background(0);
fill(255);
ellipse(dragX, dragY, 110, 110);
fill(255,0,0);
ellipse(moveX, moveY, 100, 100);
fill(0,255,0);
ellipse(mouseX, mouseY, 90, 90);
}
// Quando faz o drag & drop, atualiza as variáveis
// de posição da elipse
void mouseDragged() {
dragX = mouseX;
dragY = mouseY;
}
void mouseMoved() {
moveX = mouseX;
moveY = mouseY;
}
Variáveis para trabalhar com o teclado
Exemplo de uso
if(keyPressed) {
// Instruções executadas quando um botão estiver pressionado
}
if(keyPressed) {
if((key=='a') || (key=='A')) {
// Instruções executadas quando a tecla for 'a' ou 'A'
}
}
if(keyPressed) {
if(int(key)==65) {
// 65 é o correspondente a 'A' em ASCII
}
}
if(key==CODED) {
if(keyCode==UP) {
// Instruções quando a tecla para cima
} else if(keyCode==DOWN) {
// Instruções quando a tecla para baixo
}
}
Funções para trabalhar com o teclado
Função chamada cada vez que uma tecla é pressionada
Evite desenhar dentro do keyPressed
Dependendo da configuração do Sistema Operacional, segurar uma tecla chama muitas vezes o keyPressed
+ - Documentação
+ - Exemplo de uso
void keyPressed() {
if(key=='a') {
// Executa quando a tecla for 'a'
} else if(key=='b') {
// Executa quando a tecla for 'b'
}
}
void keyReleased() {
// Instruções executadas quando a tecla é solta
}
Funções geralmente relacionadas com teclado
+ - Estruturas relacionadas com teclado
switch(variavel) {
case VALOR1:
// instrução executada se variaval for igual a VALOR1
break;
case VALOR2:
// instrução executada se variaval for igual a VALOR2
break;
case VALOR3:
case VALOR4:
// instrução executada se variaval for igual a VALOR3 ou VALOR4
default:
// Caso contrário (não é VALOR1, VALOR2, VALOR3 ou VALOR4
break;
}
+ - Exemplos
+ - Exibindo a tecla pressionada
PFont f;
void setup() {
size(600, 400);
// Carrega a fonte com metade da altura da tela
f = createFont("Arial", height/2);
textFont(f);
// Alinha o texto
textAlign(CENTER, BASELINE);
}
void draw() {
background(0);
// Exibe a tecla pressionada no meio da tela
text(key, width/2, height/2);
}
+ - Exibindo o valor em ASCII da tecla pressionada
PFont f;
void setup() {
size(600, 400);
// Carrega a fonte com metade da altura da tela
f = createFont("Arial", height/2);
textFont(f);
// Alinha o texto
textAlign(CENTER, BASELINE);
}
void draw() {
background(0);
// Exibe o valor da tecla pressionada no meio da tela
text(int(key), width/2, height/2);
}
+ - Associando o valor do key à posição de uma linha
PFont f;
void setup() {
size(600, 400);
// Carrega a fonte com metade da altura da tela
f = createFont("Arial", height/2);
textFont(f);
// Alinha o texto
textAlign(CENTER, BASELINE);
}
void draw() {
background(128);
// Exibe o valor da tecla pressionada no meio da tela
text(int(key), width/2, height/2);
// Exibe a tecla pressionada como uma linha
line(key, 0, key, height);
}
+ - Verificando se a tecla pressionada (key) está dentro de um intervalo numérico
PFont f;
void setup() {
size(600, 400);
// Carrega a fonte com metade da altura da tela
f = createFont("Arial", height/2);
textFont(f);
// Alinha o texto
textAlign(CENTER, BASELINE);
// Retângulo centralizado
rectMode(CENTER);
}
void draw() {
background(128);
// Exibe o valor da tecla pressionada no meio da tela
text(int(key), width/2, height/2);
// Está entre '0' e '9'
if(key>=48 && key<=57)
{
rect(width/2, height/2, (48-key)* 10, (48-key)* 10);
}
}
+ - Verificando se a tecla pressionada (key) está dentro de um intervalo numérico
Igual ao exemplo anterior
PFont f;
void setup() {
size(600, 400);
// Carrega a fonte com metade da altura da tela
f = createFont("Arial", height/2);
textFont(f);
// Alinha o texto
textAlign(CENTER, BASELINE);
// Retângulo centralizado
rectMode(CENTER);
}
void draw() {
background(128);
// Exibe o valor da tecla pressionada no meio da tela
text(int(key), width/2, height/2);
// Está entre '0' e '9'
if(key>='0' && key<='9')
{
rect(width/2, height/2, (48-key)* 10, (48-key)* 10);
}
}
Controle de movimento a partir do keyCode sem considerar quando a tecla foi pressionada
float x, y;
void setup() {
size(600, 400);
x = width/2;
y = height/2;
}
void draw() {
if(key==CODED) {
// Se for para a esquerda
if(keyCode==LEFT) {
x = x - 5;
} else if(keyCode==RIGHT) { // Se for para a direita
x = x + 5;
}
}
background(128);
ellipse(x, y, 20, 20);
}
Controle de movimento a partir do keyCode e do keyPressed
float x, y;
void setup() {
size(600, 400);
x = width/2;
y = height/2;
}
void draw() {
if(keyPressed) {
if(key==CODED) {
// Se for para a esquerda
if(keyCode==LEFT) {
x = x - 5;
} else if(keyCode==RIGHT) { // Se for para a direita
x = x + 5;
}
}
}
background(128);
ellipse(x, y, 20, 20);
}
+ - Escolhendo entre diversas teclas com switch
Uso do switch para facilitar a leitura do código
float x, y;
void setup() {
size(600, 400);
x = width/2;
y = height/2;
}
void draw() {
if(keyPressed && key==CODED) {
switch(keyCode) {
case UP:
y = y - 1;
break;
case DOWN:
y = y + 1;
break;
case LEFT:
x = x - 1;
break;
case RIGHT:
x = x + 1;
break;
}
}
background(128);
ellipse(x, y, 20, 20);
}
+ - Colisão com alvo
float x, y;
float xAlvo, yAlvo;
void setup() {
size(600, 400);
x = width/2;
y = height/2;
xAlvo = random(100,width-100);
yAlvo = random(100,height-100);
smooth();
}
void draw() {
// Verifica o teclado
if(keyPressed && key==CODED) {
switch(keyCode) {
case UP:
y = y - 1;
break;
case DOWN:
y = y + 1;
break;
case LEFT:
x = x - 1;
break;
case RIGHT:
x = x + 1;
break;
}
}
// Move o inimigo
xAlvo = xAlvo + random(-3,3);
yAlvo = yAlvo + random(-3,3);
// Verifica a colisão
// 30 é igual à soma do raio da mira e do alvo
if(dist(x,y,xAlvo,yAlvo)<30) {
background(155,0,0);
} else {
background(128);
}
fill(100, 0, 0, 128);
// Desenha a mira
ellipse(x, y, 50, 50);
line(x, y-25, x, y-5);
line(x, y+25, x, y+5);
line(x-25, y, x-5, y);
line(x+25, y, x+5, y);
// Desenha o alvo
fill(0,255,0, 128);
ellipse(xAlvo, yAlvo, 10, 10);
}
float x, y;
float xAlvo, yAlvo;
int pontos, vidaAlvo;
PFont f;
void setup() {
size(600, 400);
x = width/2;
y = height/2;
xAlvo = random(100,width-100);
yAlvo = random(100,height-100);
vidaAlvo = 3;
smooth();
f = createFont("Arial", 20);
textFont(f);
}
void draw() {
// Verifica o teclado
if(keyPressed) {
if(key==CODED) {
switch(keyCode) {
case UP:
y = y - 1;
break;
case DOWN:
y = y + 1;
break;
case LEFT:
x = x - 1;
break;
case RIGHT:
x = x + 1;
break;
}
}
if(key==' ') {
if(dist(x,y,xAlvo,yAlvo)<10) {
vidaAlvo = vidaAlvo - 1;
}
}
}
// Move o inimigo
if(vidaAlvo<0)
{
xAlvo = random(100,width-100);
yAlvo = random(100,height-100);
vidaAlvo = 3;
pontos = pontos + 1;
}
xAlvo = xAlvo + random(-3,3);
yAlvo = yAlvo + random(-3,3);
// Verifica a colisão
// 30 é igual à soma do raio da mira e do alvo
if(dist(x,y,xAlvo,yAlvo)<30) {
background(155,0,0);
}
else {
background(128);
}
fill(100, 0, 0, 128);
// Desenha a mira
ellipse(x, y, 50, 50);
line(x, y-25, x, y-5);
line(x, y+25, x, y+5);
line(x-25, y, x-5, y);
line(x+25, y, x+5, y);
// Desenha o alvo
fill(0,255,0, 128);
ellipse(xAlvo, yAlvo, 10, 10);
// Desenha o placar
text(pontos, 20, 20);
// Desenha a vida do inimigo
text(vidaAlvo, 20, 40);
}
float x, y;
float xAlvo, yAlvo;
int pontos, vidaAlvo;
PFont f;
void setup() {
size(600, 400);
x = width/2;
y = height/2;
xAlvo = random(100,width-100);
yAlvo = random(100,height-100);
vidaAlvo = 3;
smooth();
f = createFont("Arial", 20);
textFont(f);
}
void draw() {
// Verifica o teclado
if(keyPressed) {
if(key==CODED) {
switch(keyCode) {
case UP:
y = y - 1;
break;
case DOWN:
y = y + 1;
break;
case LEFT:
x = x - 1;
break;
case RIGHT:
x = x + 1;
break;
}
}
}
// Move o inimigo
if(vidaAlvo<0)
{
xAlvo = random(100,width-100);
yAlvo = random(100,height-100);
vidaAlvo = 3;
pontos = pontos + 1;
}
xAlvo = xAlvo + random(-3,3);
yAlvo = yAlvo + random(-3,3);
// Verifica a colisão
// 30 é igual à soma do raio da mira e do alvo
if(dist(x,y,xAlvo,yAlvo)<30) {
background(155,0,0);
}
else {
background(128);
}
fill(100, 0, 0, 128);
// Desenha a mira
ellipse(x, y, 50, 50);
line(x, y-25, x, y-5);
line(x, y+25, x, y+5);
line(x-25, y, x-5, y);
line(x+25, y, x+5, y);
// Desenha o alvo
fill(0,255,0, 128);
ellipse(xAlvo, yAlvo, 10, 10);
// Desenha o placar
text(pontos, 20, 20);
// Desenha a vida do inimigo
text(vidaAlvo, 20, 40);
}
void keyPressed() {
if(key==' ') {
if(dist(x,y,xAlvo,yAlvo)<10) {
vidaAlvo = vidaAlvo - 1;
}
}
}
PFont f;
String texto;
void setup() {
size(600, 400);
smooth();
f = createFont("Arial", 20);
textFont(f);
texto = "";
}
void draw() {
background(0);
// Desenha o texto
text(texto+"|", 20, 20);
}
void keyTyped() {
if(key==BACKSPACE) {
// Tira o último caractere do texto se possível
if(texto.length() > 0) {
texto = texto.substring(0,texto.length()-1);
}
} else {
texto = texto + key;
}
}