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
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 maisspeed - 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 maisArrays - 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