y - azevedolab.net

Transcrição

y - azevedolab.net
azevedolab.net
1
© 2015 Dr. Walter F. de Azevedo Jr.
Programação Orientada a
Objetos em Processing (continuação)
Solução do Exercícios das Aulas 4 e 5
www.processing.org
Na aula passada introduzimos o conceito de programação orientada a objeto. Vamos
resolver alguns dos exercícios propostos, das aulas 4 e 5. Os exercícios da aula 4
estavam centrados no conceito de funções. Os exercícios da aula 5 têm como proposta
modificarmos os códigos da aula 4, introduzindo classes. Vamos apresentar a solução
do código como função e, em seguida, o código equivalente usando programação
orientada a objeto (POO). A tabela abaixo traz a sequência a ser mostrada.
Códigos da Aula 4 (com Funções)
Códigos da Aula 5 (com POO)
flying_saucer04.pde
flying_saucer12.pde
flying_saucer05.pde
flying_saucer13.pde
2
Exercício de Programação: flying_saucer04.pde
www.processing.org
Exercício de programação: Modifique o código do programa flying_saucer03.pde, de
forma que o critério de pontuação fique mais desafiador, por exemplo, modifique o
valor inicial atribuído à variável score_antigrav, tente valores maiores que 2000. Se for
programar no Mac OS X com Processing 1.5, coloque as linhas com as funções
println() como comentários, por exemplo //println(). O restante do código deve funcionar
no Mac OS X com Processing 1.5. Chame o novo programa de flying_saucer04.pde.
Execute o código para ver se o jogo não se tornou muito desafiador.
3
Exercício de Programação: flying_saucer04.pde
float
float
float
float
float
float
float
float
x;
y;
gravity;
r;
g;
b;
score_antigrav;
maxHeight;
float speed ;
float score;
//
//
//
//
//
//
//
//
x location of flying saucer
y location of flying saucer
gravity acting on the flying saucer
intensity for red
intensity for green
intensity for blue
Initial cutoff value for antigrav
Maximum height
www.processing.org
As primeiras linhas indicam a
definição das variáveis globais.
// speed of flying saucer
// score
Em seguida temos a função
setup(),
onde
definimos
o
tamanho da tela e atribuímos
valores
iniciais
a
algumas
variáveis globais.
void setup() {
size(200, 480);
x = 100;
y = 0;
gravity = 0.1;
score_antigrav = 2000;
maxHeight = 480;
speed = 0;
}
void draw() {
background(255);
updateY();
drawFlyingSaucer(20, 20);
gameOver();
myScore();
}
//
//
//
//
Calls
Calls
Calls
Calls
updateY
drawFlyingSaucer()
function gameOver()
function updateScore()
Por últimos temos a função
draw(), onde definimos a cor de
fundo e chamamos as funções
que criamos. Nos próximos slides
4
mostramos as funções.
Exercício de Programação: flying_saucer04.pde
float updateY() {
y = y + speed;
speed = speed + gravity;
return y;
}
void drawFlyingSaucer(float cockpitX, float cockpitY) {
// Function to display the flying saucer
float saucerX = cockpitX + 100.0;
float saucerY = cockpitY;
noStroke();
ellipseMode(CENTER);
r = random(1,256);
g = random(1,256);
b = random(1,256);
fill(color(r,g,b));
// Cockpit
ellipse(x, y, cockpitX, cockpitY);
fill(175);
// Saucer
ellipse(x, y+10, saucerX, saucerY);
}
www.processing.org
As definições das funções podem
aparecer em qualquer ordem no
código. A primeira mostrada é a
updateY(), que atualiza o valor da
altura do disco voador (y), como
definimos y como variável global,
basta que a atualizemos na
função, nem precisamos retornar
seu valor.
Em seguida temos a função
drawFlyingSaucer(), que desenha
o disco voador e tem como
argumentos a largura (cockpitX) e
a altura (cockpitY) do cockpit.
Somamos
100
à
variável
cockpitX, para gerarmos a largura
do disco (variável saucerX). A
altura do disco (variável saucerY)
é a mesma do cockpit (cockpitY).
5
Exercício de Programação: flying_saucer04.pde
float updateY() {
y = y + speed;
speed = speed + gravity;
return y;
}
void drawFlyingSaucer(float cockpitX, float cockpitY) {
// Function to display the flying saucer
float saucerX = cockpitX + 100.0;
float saucerY = cockpitY;
noStroke();
ellipseMode(CENTER);
r = random(1,256);
g = random(1,256);
b = random(1,256);
fill(color(r,g,b));
// Cockpit
ellipse(x, y, cockpitX, cockpitY);
fill(175);
// Saucer
ellipse(x, y+10, saucerX, saucerY);
}
www.processing.org
Usamos variáveis aleatórias para
as cores RGB do cockpit e a cor
cinza (fill(175)), para a cor do
disco. Tomamos como referência
do centro do cockpit as
coordenadas x e y. A coordenada
x do disco é igual à coordenada
do cockpit. A coordenada y do
disco é obtida somando-se 10 à
coordenada do cockpit, para
deslocarmos a elipse do disco
com relação ao cockpit.
6
Exercício de Programação: flying_saucer04.pde
void gameOver() {
if (y > maxHeight) {
println("Your score ", score);
println("Game Over!");
noLoop();
}
}
void myScore() {
if (y < maxHeight) {
score = score + 1;
}
// If score > score_antigrav increase height
if (score > score_antigrav ) {
println("Super antigrav!");
y = y -300;
score_antigrav = 1.05*score_antigrav + 2000;
}
}
void mousePressed() {
speed = speed * -0.45;
println("Your score", score);
}
www.processing.org
A função gameOver() testa se a
condição de fim de jogo foi
satisfeita, que no caso é se a
altura do disco (variável y) é
maior que o valor atribuído à
variável maxHeight. Inicializamos
a variável maxHeight na função
setup(), onde foi atribuído 480 à
variável maxHeight.
A função myScore() atualiza o
escore do jogador. Caso o escore
(variável score) seja maior que o
valor
atribuído
à
variável
score_antigrav, subtraímos 300 à
altura do disco.
A
função
mousePressed()
multiplica a velocidade por -0.45,
o que reduz velocidade de queda
do disco e mostra o escore do
7
jogador.
Exercício de Programação: flying_saucer12.pde
www.processing.org
Exercício de programação: Modifique o código do programa flying_saucer04.pde, para
que siga o paradigma de programação orientada a objeto.
8
Exercício de Programação: flying_saucer12.pde
FlyingSaucer mySaucer;
float speed;
float score;
// Declares an object
// speed of flying saucer
// score
void setup() {
size(200, 480);
mySaucer = new FlyingSaucer();
speed = 0;
}
// Initializes object
void draw() {
background(255);
// Calls method updateY() on object mySaucer
mySaucer.updateY();
// Calls method drawFlyingSaucer() on object mySaucer
mySaucer.drawFlyingSaucer(20, 20);
// Calls method gameOver() on object mySaucer
mySaucer.gameOver();
// Calls method updateScore() on object mySaucer
mySaucer.myScore();
}
void mousePressed() {
speed = speed * -0.45;
println("Your score", score);
}
www.processing.org
As primeiras linhas indicam a
definição do objeto mySaucer da
classe
FlyingSaucer() e das
variáveis globais.
Depois temos a função setup(),
onde definimos o tamanho da
tela, inicializamos o objeto
mySaucer e atribuímos valor
inicial a variável global speed.
Na função draw(), definimos a cor
de fundo e chamamos os
métodos
sobre
o
objeto
mySaucer.
Agora
temos
a
função
mousePressed(),
que
é
executada no evento do mouse
ser pressionado. Assim, ela não
fica incorporada como método e
9
sim uma função à parte.
Exercício de Programação: flying_saucer12.pde
class FlyingSaucer {
float x;
float y;
float gravity;
float r;
float g;
float b;
float score_antigrav;
float maxHeight;
//
//
//
//
//
//
//
//
x location of flying saucer
y location of flying saucer
gravity acting on the flying saucer
intensity for red
intensity for green
intensity for blue
Initial cutoff value for antigrav
Maximum height
FlyingSaucer() {
// Constructor
x = 100;
y = 0;
gravity = 0.1;
score_antigrav = 2000;
maxHeight = 480;
}
www.processing.org
Na classe
FlyingSaucer() as
primeiras linhas indicam as
variáveis, que eram globais no
código
flying_saucer04.pde,
agora são variáveis da classe.
Em
seguida
definimos
o
construtor da classe, onde os
valores iniciais são atribuídos a
algumas variáveis, previamente
definidas no início da classe.
Compare
as
variáveis
inicializadas no construtor com
aquelas inicializadas na função
setup()
do
código
flying_saucer04.pde. As únicas
variáveis que não estão no
construtor são as variáveis score
e
speed,
que
nesta
implementação são variáveis
10
globais.
Exercício de Programação: flying_saucer12.pde
void drawFlyingSaucer(float cockpitX, float cockpitY) {
// Function to display the flying saucer
float saucerX = cockpitX + 100.0;
float saucerY = cockpitY;
noStroke();
ellipseMode(CENTER);
r = random(1, 256);
g = random(1, 256);
b = random(1, 256);
fill(color(r, g, b));
// Cockpit
ellipse(x, y, cockpitX, cockpitY);
fill(175);
// Saucer
ellipse(x, y+10, saucerX, saucerY);
}
void updateY() {
y = y + speed;
speed = speed + gravity;
}
void gameOver() {
if (y > maxHeight) {
println("Your score ", score);
println("Game Over!");
noLoop();
}
}
void myScore() {
if (y < maxHeight) {
score = score + 1;
}
// If score > score_antigrav increase height
if (score > score_antigrav ) {
println("Super antigrav!");
y = y -300;
score_antigrav = 1.05*score_antigrav + 2000;
}
} }
www.processing.org
As linhas dos códigos referentes
aos métodos drawFlyingSaucer(),
updateY(),
gameOver(),
e
myScore() são idênticas às linhas
dos
códigos
das
funções
equivalentes
do
código
flying_saucer04.pde.
11
Exercício de Programação: flying_saucer05.pde
www.processing.org
Exercício de programação: Modifique o código do programa flying_saucer04.pde, de
forma que tenhamos um sistema de fases do jogo. Mude a cor de fundo, conforme o
jogador muda de fases. Torne cada fase mais desafiadora que a anterior. Chame o
novo programa de flying_saucer05.pde.
12
Exercício de Programação: flying_saucer05.pde
float x;
float y;
float gravity;
float r;
float g;
float b;
float score_antigrav;
float maxHeight;
int newR;
int newG;
int newB;
color my_color;
float speed = 0;
float score;
//
//
//
//
//
//
//
//
//
//
//
//
//
//
x location of flying saucer
y location of flying saucer
gravity acting on the flying saucer
intensity for red
intensity for green
intensity for blue
Initial cutoff value for antigrav
Maximum height
Variable for red intensity in color
Variable for green intensity in color
Variable for red intensity in color
Variable for RGB color
speed of flying saucer
score
void setup() {
size(200, 480);
x = 100;
y = 0;
gravity = 0.1;
score_antigrav = 2000;
maxHeight = 480;
speed = 0;
newR = 0;
newG = 0;
newB = 0;
}
void draw() {
changeBackground();
updateY();
drawFlyingSaucer(20, 20);
gameOver();
myScore();
}
//
//
//
//
//
Calls
Calls
Calls
Calls
Calls
changeBackground()
updateY()
drawFlyingSaucer()
function gameOver()
function updateScore()
www.processing.org
Como nos códigos anteriores, as
primeiras linhas indicam a
definição das variáveis globais. A
principal modificação refere-se à
mudança da cor de fundo,
conforme mudamos de fase.
Assim foram introduzidas as
variáveis indicadas em vermelho,
para
trabalharmos
com
a
variação das cores.
Na função setup(), definimos o
tamanho da tela e atribuímos
valores
iniciais
a
algumas
variáveis globais, inclusive para
as novas variáveis.
Na função draw(), chamamos a
nova função para a cor de fundo,
a função changeBackground().
No próximo slide mostramos as
13
novidades do código.
Exercício de Programação: flying_saucer05.pde
void myScore() {
if (y < maxHeight) {
score = score + 1;
}
// If score > score_antigrav increase height
if (score > score_antigrav ) {
println("Super antigrav!");
y = y -300;
score_antigrav = 1.05*score_antigrav + 2000;
changeColor();
}
}
void changeColor() {
// Changes background color
if (newR < 255) {
newR = newR + 50;
} else {
newR = 0;
if (newG < 255) {
newG = newG + 50;
} else {
newG = 0;
if (newB < 255) {
newB = newB + 50;
} else {
newB = 0;
}
}
}
}
void changeBackground() {
my_color = color(newR, newG, newB);
background(my_color);
}
www.processing.org
A nova função myScore() chama
a função changeColor(), que vai
atualizando os valores atribuídos
às variáveis newR, newG e
newB. Veja que a função
changeColor() só é chamada se o
valor atribuído à variável score for
maior que o valor atribuído à
variável score_antigrav. Esta é a
situação que temos quando
mudamos de fase. A função
changeBackground()
usa
os
valores atribuídos às variáveis
newR, newG e newB para gerar a
cor de fundo.
As outras funções são idênticas
às
discutidas
no
código
flying_saucer04.pde.
14
Exercício de Programação: flying_saucer13.pde
www.processing.org
Exercício de programação: Modifique o código do programa flying_saucer05.pde, para
que siga o paradigma de programação orientada a objeto.
15
Exercício de Programação: flying_saucer13.pde
FlyingSaucer mySaucer;
float speed;
float score;
// Declares an object
// speed of flying saucer
// score
void setup() {
size(200, 480);
mySaucer = new FlyingSaucer();
speed = 0;
}
// Initializes object
www.processing.org
Como vimos, a novidade está na
mudança da cor de fundo,
implementada parcialmente no
método
changeBackground(),
indicado em vermelho na função
draw(). O restante das funções
setup(), draw() e mousePressed()
fica
como
no
código
flying_saucer12.pde.
void draw() {
// Calls method changeBackground() on object mySaucer
mySaucer.changeBackground();
// Calls method updateY() on object mySaucer
mySaucer.updateY();
// Calls method drawFlyingSaucer() on object mySaucer
mySaucer.drawFlyingSaucer(20, 20);
// Calls method gameOver() on object mySaucer
mySaucer.gameOver();
// Calls method updateScore() on object mySaucer
mySaucer.myScore();
}
void mousePressed() {
speed = speed * -0.45;
println("Your score", score);
}
16
Exercício de Programação: flying_saucer13.pde
class FlyingSaucer {
float x;
float y;
float gravity;
float r;
float g;
float b;
float score_antigrav;
float maxHeight;
int newR;
int newG;
int newB;
color my_color;
//
//
//
//
//
//
//
//
//
//
//
//
x location of flying saucer
y location of flying saucer
gravity acting on the flying saucer
intensity for red
intensity for green
intensity for blue
Initial cutoff value for antigrav
Maximum height
Variable for red intensity in color
Variable for green intensity in color
Variable for red intensity in color
Variable for RGB color
www.processing.org
Na
definição
da
classe
FlyingSaucer(), as modificações
estão indicadas em vermelho.
Como destacado no código
flying_saucer05.pde,
necessitamos
de
variáveis
adicionais para tratarmos da
mudança de cores.
FlyingSaucer() {
// Constructor
x = 100;
y = 0;
gravity = 0.1;
score_antigrav = 2000;
maxHeight = 480;
newR = 0;
newG = 0;
newB = 0;
}
17
Exercício de Programação: flying_saucer13.pde
void myScore() {
if (y < maxHeight) {
score = score + 1;
}
// If score > score_antigrav increase height
if (score > score_antigrav ) {
println("Super antigrav!");
y = y -300;
score_antigrav = 1.05*score_antigrav + 2000;
changeColor();
}
}
void changeColor() {
// Changes background color
if (newR < 255) {
newR = newR + 50;
} else {
newR = 0;
if (newG < 255) {
newG = newG + 50;
} else {
newG = 0;
if (newB < 255) {
newB = newB + 50;
} else {
newB = 0;
}
}
}
}
void changeBackground() {
my_color = color(newR, newG, newB);
background(my_color);
}
www.processing.org
Os métodos que não sofreram
alterações não são mostrados. O
método myScore() tem a inclusão
da
chamada
do
método
changeColor().
Os
métodos
changeColor()
e
changeBackground()
são
idênticos às funções equivalentes
do código flying_saucer05.pde.
18
Referências
www.processing.org
-MODEL, Mitchell L. Bioinformatics Programming Using Python. Sebastopol: O’Reilly Media, Inc., 2011. 1584 p.
-REAS, Casey & FRY, Bem. Geeting Started with Processing. Sebastopol: O’Reilly Media, Inc., 2010. 194 p.
-SHIFFMAN, Daniel. Learning Processing. A Beginner’s Guide to Programming Images, Animation, and Interaction.
Burlington: Morgan Kaufmann, 2008. 453 p.
-SHIFFMAN, Daniel. The Nature of Code: Simulating Natural Systems with Processing. Mountain View: The Nature of Code,
2012. 498 p.
Última atualização: 20 de setembro de 2015.
19

Documentos relacionados

float - azevedolab.net

float - azevedolab.net Até o momento usamos funções pré-definidas do Processing, como line(). Iremos ver como implementar nossas próprias funções, para facilitar a modularização do código, como vimos na linguagem Python,...

Leia mais

speed - azevedolab.net

speed - azevedolab.net (flying_saucer09.pde), e criarmos dois objetos, teremos dois objetos idênticos. Assim, temos que introduzir uma modificação no código, de forma que possamos passar valores para as variáveis das coo...

Leia mais

Arrays - azevedolab.net

Arrays - azevedolab.net Uma forma elegante de superarmos este problema, é por meio do uso de arrays. Vimos em Python que arrays são variáveis indexadas, onde podemos acessar um valor específico dentro de uma lista de valo...

Leia mais