Versão atual = 14/08/2011 GRUPO DE PESQUISA EM PEDAGOGIA LÚDICA PYTHON : ESTUDO DIRIGIDO versão inicial : 07/07/2007 - | André Koscianski µ guia de estudos python André Koscianski Prefácio Este pequeno guia vai ajudá ajudá-lo lo a estudar a linguagem de programação Python. Eventualmente, ele também poderá ajudá-lo lo a melhorar sua habilidade de programação. Python possui uma vantagem importante em relação a linguagem C e todas as suas derivadas (Java, C++, C#...): ...): a sintaxe é mais simples e evita símbolos como { } ; . Isso permite se concentrar mais nos problemas e seus respectivos algoritmos e menos na sintaxe do código sendo escrito. escrito Por isso Python é uma ótima linguagem inicial. se. Leia o texto, complemente-o complemente com informação Para que o trabalho funcione é preciso dedicar-se. oriunda da Internet e, sobretudo, resolva os problemas propostos propostos. Fazendo isso – ou seja, concentrando energia no trabalho – você tem todas as chances de obter bons resultados. Boa leitura! 3 µ guia de estudos python André Koscianski O texto não deve ser usado fora da UTFPR sem o consentimento do autor. Sumário Parte um: Linguagem básica ................................ ................................................................................................ ................................................... 7 1. PRINT e operações aritméticas ................................................................ .................................................................... 8 2. Variáveis ................................ ................................................................................................................................ ...................................... 9 3. PRINT e números, parte II................................................................................................ ............................................ 9 4. IMPORT ................................ ................................................................................................................................ ...................................... 10 5. IF ELSE ................................ ................................................................................................................................ ........................................ 11 6. Raízes de Equação ................................ ................................................................................................ ..................................................... 12 7. Entrada de Dados ................................ ................................................................................................ ...................................................... 12 8. Laços for................................ ................................................................................................................................ ..................................... 13 9. Números aleatórios ................................ ................................................................................................ ................................................... 13 10. Números aleatórios em um intervalo................................................................ .................................................... 13 11. Laço WHILE ................................ ................................................................................................ ............................................................ 14 12. Asteriscos KGB ................................ ................................................................................................ ....................................................... 15 13. FROM ... IMPORT ................................ ................................................................................................ ................................................... 17 14. Sub-rotinas................................ ................................................................................................ ............................................................. 18 15. Acentuação ................................ ................................................................................................ ............................................................ 18 16. Laços FOR com listas................................................................................................ .............................................. 19 Parte dois: PYGAME básico................................ ................................................................................................ ................................................... 20 17. FROM ... IMPORT parte IIII................................................................................................ ...................................... 21 18. Mostrar objeto na tela tela................................................................................................ ........................................... 22 19. Mover objeto ................................ ................................................................................................ ......................................................... 24 20. Figuras com Transparências ................................................................ .................................................................. 25 21. Problema: iô-iô ................................ ................................................................................................ ...................................................... 26 22. Problema: dois iô-iôs iôs ................................................................................................ ............................................. 26 4 µ guia de estudos python André Koscianski 23. MRUV, Movimento retilíneo uniformemente acelerado ...................................................... ................................ 27 24. MRUV com atrito ................................ ................................................................................................ ................................................... 28 25. Controle do teclado ................................................................................................ ............................................... 29 26. Problema: teste da fila de eventos. ................................................................ ....................................................... 31 27. Estado atual do teclado ................................................................................................ ......................................... 31 28. Problema: iô-iô iô com controle ................................................................ ................................................................ 32 29. Problema: iô-iô iô com super super-controle ................................................................ ..................................................... 32 30. Canhão anti-aéreo ................................ ................................................................................................ ................................................. 33 31. Escrevendo na tela gráfica ................................................................................................ ..................................... 34 Parte rte três: Orientação a Objetos básica em Python................................................................ ............................................. 35 32. Rudimentos de OO em Python , parte I ................................................................ ................................................ 36 33. Rudimentos de OO em Python , parte II ................................................................ ............................................... 36 34. Objetos são variáveis ................................................................................................ ............................................. 37 35. A variável self de Python................................................................................................ ...................................... 38 36. Atributos de objetos ................................................................................................ .............................................. 39 37. Aviões – objetos ................................ ................................................................................................ .................................................... 40 38. Esqueleto o de jogo: pouso lunar, parte I ................................................................ ................................................ 41 39. Esqueleto de jogo: pouso lunar, parte II ................................................................ ............................................... 42 5 µ guia de estudos python André Koscianski Como este guia funciona Este guia de estudos é composto de uma série de problemas em ordem crescente de dificuldade. Para que o trabalho corra bem, há algumas dicas. Em primeiro lugar, procure não misturar estudo com rádio, briga com o irmão mais novo ou, muito pior, assistir novela ou jornal nacional (estes dois últimos terão efeitos negativos sobre seu cérebro). Isso vale para qualquer disciplina: jamais estude pensando em outra coisa. Você só perderá tempo. Segundo conselho, não exagere exagere.. Ao invés de estudar cinco horas durante o fim de semana todo, estude 30 minutos por dia e depois mude de assunto. Use isso para aprender mais sobre Python e jogos/PyGame,, mas também para TODAS as disciplinas d do o curso. Fazendo isso você nunca enjoa ou cansa. Estudando mais atento e descansado, seu trabalho renderá o dobro. Resolva todos os problemas na ordem em que aparecem, salvo em dois casos: 1) se um problema for muito fácil, construa a solução mentalment mentalmente. Mas: se s surgir alguma dúvida ou se sentir inseguro, pode ser melhor implementar implementar. 2) se um problema parecer muito difícil, você pode tentar passar para o problema seguinte. Algumas vezes a ordem de dificuldade proposta não é exatamente a SUA ordem de di dificuldade. ficuldade. Se isso tudo acima não funcionar apele a um colega ou a um professor. Mãos a obra. 6 µ guia de estudos python André Koscianski Parte um: Linguagem básica Você deve instalar o interpretador de Python em sua máquina. Ao fazê-lo lo é bom usar o diretóriodefault da instalação. Isso significa pressionar “Ok” e “Yes” a todas as perguntas durante a instalação. A última versão pode ser encontrada na internet ((www.python.org). Usaremos o Cpython (e não ironpython ou outras implementações. Nada impede, contudo, de testá testá-las). Você pode executar comandos Python diretamente. Para saber se o interpretador funciona, faça como mostra esta figura: Caso não funcione, funcione verifique em "meu computador/propriedades/avançado/variáveis de ambiente" se a variável PATH contem referência ao diretório onde o interpretador rpretador Python foi instalado. Como último recurso, desinstale e instale novamente o interpretador. 7 µ guia de estudos python André Koscianski 1. PRINT e operações aritméticas Vamos ao primeiro problema deste guia. Você pode resolvê-lo sem usar um editor de textos! Basta B ativar o interpretador Python (simplesmente d digite: python <ENTER>) e escrever os comandos "dentro" do ambiente por ele fornecido. Usando apenas o comando print, teste os operadores aritméticos usando números inteiros e fracionários. Os operadores são: + - * ** / // e % . Comece observando esta cópia de tela para entender como funciona: Faça testes simples com números grandes e pequenos, positivos e negativos. Descubra para que servem os operadores ** e % (ex.: 3**4 e 40 % 3). Depois, teste este parentização. Por exemplo, calcule 11 ∗ 137 51 144 1 2 4 Você deverá incluir vários parênteses adicionais e ssua expressão deverá verá começar assim: (11 * ( ( 137 – Em caso de dúvida parentize cada operação. Lembre-se se da ordem de precedência de operações. O resultado de 5-2*2 2*2 é igual a 1 e não 6. (Ok, ok, você já sabia. Mas não custava lembrar!). 8 µ guia de estudos python André Koscianski 2. Variáveis Assim como a linguagem Basic, Python dispensa declaração de variáveis. Variáveis passam a existir assim que recebem um valor valor. Veja: sugestão: aprenda + sobre isto na Wikipedia Python utiliza tipagem dinâmica dinâmica. Isso permite certas diabruras impossíveis is em outras linguagens: linguagens Percebeu o que aconteceu com a variável “a” acima? Essa liberdade toda pode ter um u efeito colateral negativo. Um m programador mediano ou ruim pode escrever código extraodinariamente sujo. Código bom se aprende lendo. Uma pequena lista de bons autores / bons programadores é: Niklaus Wirth (deveria ser obrigatório no o curso de Fundamentos da Programação Programação),, Kernighan & Ritchie (autores da linguagem C), S. Maguire (Writing Solid Code) Code), D. Knuth, A. N. Tenembaum (Data Structures), Struct Stroustrup (pai da linguagem C++). 3. PRINT e números, parte II Tente este comando: prompt python >>>print 1, 2, 3; 4; 5 e em seguida, este: prompt python >>>print 1.2151E3 + 6.28E 6.28E-1 Explique os resultados que aparecem na tela. 9 µ guia de estudos python André Koscianski 4. IMPORT Python possui várias biblioteca bibliotecas embutidas e mais um milhão de outras na Internet! Internet carregadas conforme você precisa. A lógica disso é clara: não perder tempo e As bibliotecas são carregada memória carregando coisas do disco que não serão utilizadas. Semelhante às declarações #include usadas nas linguagens da família C, Python requer que você lhe avise sobre as bibliotecas a serem utilizadas. import. Isto é feito com o comando import Exemplo 1: Escreva o código a seguir no bloco de notas ou use o editor N Notepad++. otepad++. Salve o arquivo com extensão .PY teste.py import math print math.sqrt (9) (sqrt = squared root) Exemplo 2: prompt python >>>import math >>>help (math) Teste o código acima! Você deverá pressionar <ENTER> para rolar a lista e <CTRL>+C para interromper. interromper 10 µ guia de estudos python André Koscianski 5. IF ELSE Um exemplo explicará tudo rapidamente teste-if.py if 1 > 2 print print else : print print : "nunca" "nunquinha" "ok ok" "tem razao" print "Era isso por hoje." No código acima existem blocos de comandos. Observe: 1) a presença de dois pontos sinalizando o início de um bloco 2) o fato de todas as linhas do bloco serem igualmente identadas Dica: Nas opções do Notepad++ ou de seu editor predileto, configure a troca de tabulações por espaços em branco. Isso pode evitar muitas dores de cabeça. 11 µ guia de estudos python André Koscianski 6. Raízes de Equação Abra o artigo da Wikipedia em português sobre a linguagem FORTRAN. Adapte para Python o código FORTRAN que calcula os zeros de um polinômio de segundo grau, (caso o artigo da Wikipedia tenha sido modificado, você não deverá ter dificuldade em encontrar a fórmula em outro site). - E por que você não coloca a fórmula aqui, ora? ntão está realmente em maus mau lençóis... - Por que se você não puder achar a fórmula via Google, eentão 7. Entrada de Dados Experimente a função input() input(). Adapte o programa anterior para que o usuário digite os coeficientes a,b,c. 12 µ guia de estudos python André Koscianski 8. Laços for Extremamente fácil: teste-for.py for i in range(10) : print i ; print "Era isso por hoje." cio: descubra as diferenças entre range (n), range(a,b) e xrange (n). Exercício: 9. Números aleatórios Teste isto (e naturalmente experimente modificações para ver o que acontece) : teste-for.py import random print random.random( random.random() print int (100.0 100.0 * random.random()) Depois, crie um programa para imprimir 10 números aleatórios (usando, é claro, um FOR – talvez você nem precise escrever o programa, se já houver entendido o código acima acima). 10. Números aleatórios em um intervalo Escreva um programa para gerar 10 números aleatórios. Os números gerados devem estar dentro do intervalo [25 ; 77]. Restrição: em m seu programa você só pode invocar a função random 10 vezes. Dica: use o operador de resto de divisão. 13 µ guia de estudos python André Koscianski 11. Laço WHILE Aqui está: teste-while.py i = 1 while i < 10 : print i; i = i + 1 Problema: efetue duas modificações no programa do problema anterior. 1) utilize um laço WHILE em lugar de um FOR 2) os números impressos devem ser todos pares (valem as restrições anteriores: random é chamada 10 vezes, o intervalo válido é [25 ; 77]) E veja também isto: laco-infinito.py infinito.py while 1 : print "nunca para!" , Ok? Como nas linguagens C e C++, um valor diferente de zero representa true;; logo, este laço é infinito. 14 µ guia de estudos python André Koscianski 12. Asteriscos KGB Os problemas a seguir usam laços aninhados e servem para exercitar programação. Deve ser feitos observando a seqüência de dificuldade proposta. Em todo caso, se quiser se divertir, pode saltar para o final da lista. Astericos KGB: regra geral Em todos os problemas a seguir: • devem ser usados laços ; • a impressão na tela só pode ser feita um caracter por vez . Por exemplo, para imprimir dois asteriscos: certo for i in xrange(2) PRINT “*” ERRADO PRINT “**” KGB , problema 1 2 linhas de código Imprima 10 asteriscos em uma linha, assim: ********** KGB , problema 2 4 linhas de código Imprima um bloco 10 X 10 de asteriscos no vídeo ********** ********** ... ********** KGB , problema 2 4 linhas de código Obtenha este desenho na tela * ** *** **** ***** 15 µ guia de estudos python André Koscianski KGB , problema 3 4 linhas de código Obtenha este desenho na tela: * ** *** ... ********** KGB , problema 3 7 linhas de código Obtenha este desenho na tela: + *+ +*+ *+*+ +*+*+ ... KGB , problema 4 sem recursão, 9 linhas de código Obtenha este desenho na tela: * ** *** ** * ** *** ** ... (repetir quantas vezes desejar) KGB , problema 5 14 linhas de código Obtenha este desenho na tela: * * * *** *** *** ************** (repetir horizontalmente 4 ou 5 vezes) KGB , problema 4 Obtenha este desenho na tela: ***** ***** * * * * ***** ***** **** 16 µ guia de estudos python André Koscianski 13. FROM ... IMPORT Você deve lembrar disto teste.py import math print math.sqrt math.sqrt(9) + math.sin(0.1) Ok. Agora compare cuidadosamente o código acima com este: teste.py from math import sqrt print sqrt(9) (9) + math.sin(0.1) Percebeu? Usamos uma sintaxe um pouco diferente para simplificar as chamadas à sqrt(). Podemos ir ainda mais longe e escrever assim: teste.py from math import * print sqrt(9) (9) + sin(0.1) Problema:: explique o que acontece nesta tela: 17 µ guia de estudos python André Koscianski 14. Sub-rotinas Podem ser parametrizadas ou não. A sintaxe é simplíssima. no_parms.py def bonjour (): print "ok?" def a_plus (): print "bye. bye." print "vamos invocar as sub sub-rotinas" bonjour () a_plus () E com parâmetros: with_parms.py parms.py def bonjour ( (n): for i in xrange(n): print "ok?" print "vamos invocar a sub-rotina" bonjour (10) ) 15. Acentuação Python suporta Unicode. Para isso você deve incluir duas modificações em seu código. no_parms.py # -*- coding: iso iso-8859-1 -*print "bla-bla" bla" print u"áéíóú." prefixo u 18 primeira linha µ guia de estudos python André Koscianski 16. Laços FOR com listas Rode este exemplo. forlista.py for x in [2,4, [2,4,-3,-1,103]: print x, Fácil? Listas são estruturas de dados muito úteis. Sua manipulação em Python é bastante simples. 19 µ guia de estudos python André Koscianski Parte dois: PYGAME básico Do início das atividades de programação até aqui, foram apenas 10 E agora já vamos iniciar as explicações sobre a biblioteca de jogos! páginas! páginas . Conforme prometido, o guia é bastante objetivo. Mas, antes ntes de continuar, um conselho dentro de uma pergunta: - Você resolveu os problemas propostos? Para continuar: Você precisa da biblioteca PYGAME instalada em sua máquina. Para instalá-la: 1. faça a transferência ((download) 2. execute o .EXE A linguagem Python possui todo um mecanismo para gerir bibliotecas e sua instalação. Talvez isto não seja tratado neste guia. 20 µ guia de estudos python André Koscianski 17. FROM ... IMPORT parte II Digite e salve estes dois programas no mesmo diretório. minhalib.py def minhasub minhasubrotina (s): print "Biblioteca presente" presente", s meuprog.py import minhalib minhalib.minhasubrotina ("teste") Fácil? Como isto pode ser usado? Exemplo: era uma vez dois amigos, Ana e Carlos. Ana escreveu um módulo Python, para mostra um placar colorido na tela.. Ela o gravou como com “placar.PY”. Carlos copiou o código do placar e o colou dentro de cada jogo que fez. Ana preferiu usar “import placar” Um dia, Ana percebeu um erro no cálculo do placar. Ela corrigiu o erro em 10 0 minutos, no módulo placar.py. Automaticamente, todos odos os jogos que utilizavam import ficaram corrigidos. Carlos gastou um dia inteiro procurando e corrigindo o código do placar dentro de cada jogo. 21 µ guia de estudos python André Koscianski 18. Mostrar objeto na tela Desenhe uma bola usando o PaintBrush. Grave como BMP. No mesmo diretório, salve o programa a seguir e execute execute-o. bola0.py import pygame pygame.init () tela = pygame.display.set_mode ((320,240)) bola = pygame.image.load ("bo ("bola.bmp") bolaret = bola.get_rect () tela.blit (bola, bolaret) pygame.display.flip() a = raw_input ("Voila") Na próxima página vamos analisar cada linha do código. 22 µ guia de estudos python André Koscianski # Linha Significado 0 import pygame Importa toda a biblioteca pygame. 1 pygame.init () Inicializa todos os os componentes da biblioteca, deixando-a deixando “pronta para uso”. 2 tela = pygame.display. set_mode ((320,240)) Pode-se também inicializar apenas pedaços da biblioteca, individualmente. É mais rápido quando se sabe que apenas um pedaço dela será usado (ex.: um programa que não tem som, não precisa inicializar essa parte!). Cria uma janela gráfica com m as dimensões especificadas. Tais dimensões são passadas à sub-rotina sub por meio de uma tupla – um conjunto de valores separados por vírgulas e circundados por parênteses. 3 bola = pygame.image.load ("bola.bmp") Entendeu? Esta chamada de sub-rotina rotina usou apenas UM parâmetro, que é a tupla (320, 240).. A variável bola é um m pouco mais que uma variável comum, como uma variável inteira que se pode somar A=B+C. A variável bola é um objeto. 4 bolaret = bola.get_rect () 5 tela.blit (bola, bolaret) 6 pygame.display.flip () Um objeto pode conter variáveis e sub-rotinas. sub Neste caso, a variável bola contem a imagem feita no PantBrush. A variável bolaret guarda o tamanho (comprimento e altura) da imagem contida no o objeto bola. Veja novamente a linha 2:: o objeto tela lá obtido é usado aqui. A sub-rotina blit() “carimba” a imagem da bola na tela. Isto é um truque: na verdade existem DUAS telas, uma que você vê e outra que fica escondida. Todos os desenhos são feitos na tela escondida. A sub-rotina rotina flip() troca essas telas. O resultado é que o usuário terá a impressão de que o desenho foi feito instantâneamente. 7 a = raw_input ("Voila") Sem esta linha o programa terminaria rminaria imediatamente. Você veria apenas a tela piscar e.. fim. a = input() não funciona (experimente testar), então foi usado raw_input(). 23 µ guia de estudos python André Koscianski 19. Mover objeto Teste este programa. ATENÇÃO: p para terminá-lo você precisará fechar a janela DOS. bola1.py import pygame pygame.init () 1) size = width, height = 320, 240 2) speed = [2, 2] screen = pygame.display.set_mode (size) ball = pygame.image.load ("ball.bmp") ballrect = ball.get_rect () screen.blit (ball, ballrect) pygame.display.flip() for i in xrange(100): 3) ballrect = ballrect.move (speed) print ballrect 4) 5) screen.fill ((0, 0, 0)) screen.blit (ball, ballrect) pygame.display.flip () pygame.time.delay (10) A seta preta (1) mostra atribuições em seqüência: • “size” recebe a tupla (320, 240) • width recebe 320 e height recebe 240. A seta branca (2) mostra a criação de uma lista com 2 elementos. Na seta verde (3) mostra as coordenadas contidas em ballrect são movidas. Na seta vermelha (4) a tela é toda preenchi preenchida da (to fill, em inglês) com cor preta (RGB = 0,0,0). Na seta laranja (5),, pygame “manda” o programa ficar paralisado durante 10 mili-segundos. mili 24 µ guia de estudos python André Koscianski 20. Figuras com Transparências Você deve ter observado que a figura da bola tem uma estranha borda branca: . Isso acontece pois a figura é na verdade um quadrado quadrado.. Mas seria bem melhor algo assim: Para conseguir esse efeito, avise a pygame que uma das cores da figura deve ser interpretada como “buracos”. Ou seja, essa cor representa representará espaços transparentes. Modifique o programa anterior assim: bola2.py ... colorkey = ball.get_at ((0,0)) ball.set_colorkey (colorkey, pygame.RLEACCEL) for i in xrange(100): ... Na seta vermelha, lemos a cor do pixel superior esquerdo da figura (coordenadas 0,0). Na seta laranja, avisamos ao objeto ball que essa cor deve ser tratada como transparente. 25 µ guia de estudos python André Koscianski 21. Problema: iô-iô iô Modifique o programa anterior de forma que a bola faça um movimento de iô-iô, subindo e descendo na tela. Você precisará usar um comando IF e também precisará mudar o conteúdo da variável speed. 22. Problema: dois iô-iôs Modifique o programa iô-iô para que existam duas bolas de cores diferentes pulando na tela. Você deverá criar uma segunda bola com o PaintBrush. Precisará tam também bém de uma segunda variável, bola2, que receberá a figura lida do disco ball2 = pygame.image.load ("ball ("ball2.bmp") ballrect2 = ball.get_rect () Você também precisará modificar a variável ballrect2,, para evitar que as duas bolas apareçam no mesmo lugar da tela (uma sobre a outra). 26 µ guia de estudos python André Koscianski 23. MRUV, Movimento retilíneo uniformemente acelerado Vamos modificar o primeiro programa do iô-iô, iô, para dar um toque de realismo físico. Quando a bola se move na tela, possui uma certa velocidade, certo? A cada vez que o laço é executado, a imagem da bola é apagada e depois surge novamente alguns pixels ixels mais longe. Quanto maior o número de pixels, maior a velocidade. Vamos então mudar a velocidade e acelerar a bola,, fazendo ela cair cada vez mais rápido – como acontece com uma bola de verdade. Como? A melhor maneira é aplicar Física de verdade. Comece lembrando desta fórmula: (1) A variável da fórmula corresponde, no programa, à variável speed. À medida em que o tempo passa (= à cada iteração do laço principal do programa), programa a velocidade deverá ser re-calculada calculada usando essa fórmula. Outra forma de trabalhar – e neste caso mais fácil – é assim: Δ (2) Fisicamente é a mesma idéia, mas agora não dependemos mais de . Percebeu? Para aplicar (2), observe que Δ corresponde à uma iteração do laço. É o valor que você usou na chamada à pygame.time.delay(). Para implementar o programa, você deve criar uma variável “velocidadenova” e uma “velocidadeantiga”. Deve relacionar essas variáveis com a fórmula (2). Finalmente, assim que a bola toca o chão, você pode fazê-la pular! Isso é muito fácil; basta mudar o sinal da velocidade: (3) Dica: a aceleração deve ser fixa e seria bom você começar com um valor baixo – algo como 0.001. Se o programa “rodar” corretamente (sem travar), você aumentará esse número até achar o valor certo. 27 µ guia de estudos python André Koscianski 24. MRUV com atrito Continuando o programa anter anterior, ior, você sabe que uma bola de verdade pula cada vez mais baixo. Isso acontece porque ela perde energia. Isso acontece de várias formas. • parte arte da energia é perdida pela fricção entre a bola e o ar ar; • outra utra parte é gasta criando barulho ( foi preciso gastar energia para criar uma onda de som); • também há perdas fazendo o chão vibrar vibrar; • e é gasta uma parcela de energia fazendo a bola se deformar. Incluir todas as equações de Mecânica envolvidas seria um trabalho insano. Mas há uma saída simples, imples, tipicamente usada por engenheiros. Como não é possível medir todos os efeitos acima, arredondamos tudo dentro de um coeficiente. É um número um pouco mágico, mas que se for bem calibrado vai nos poupar muito trabalho. Faça o seguinte: quando a bo bola la toca o chão, mude o sinal da velocidade mas ao mesmo tempo subtraia um pouco dessa velocidade. Tecnicamente, o que estamos fazendo é dizer que a bola perdeu momento (ou energia cinética). A fórmula a ser aplicada quando a bola toca o chão é: Entendeu? Uma parcela da velocidade “evapora” = energia perdida. Modifique o programa usando essa fórmula. Atenção:: a fórmula está um pouco complicada em excesso e seria muito bom simplificá-la. simplificá Usar menos cálculos significa obter um programa que roda mais depressa, algo que é muito importante e muito valorizado por todo programador de jogos. Com mais CPU livre é possível enriquecer o jogo. Para simplificar a fórmula acima, isole a variável (isto é, coloque-aa “em evidência”). A fórmula mais simples possível contem apenas uma operação de multiplicação. 28 µ guia de estudos python André Koscianski 25. Controle do teclado Até agora usamos apenas as sub sub-rotinas input() e raw_input(). Essas rotinas deixam o programa congelado até que o usuário use a tecla <ENTER>. Evidentemente isto não serve para controlar um jogo: a entrada de dados deve acontecer durante o funcionamento do mesmo, sem paralizá paralizá-lo. Leitura direta (sem espera na fila)al fila) caminho-2 Sistema Operacional fila de eventos Word fila de eventos Excel fila de eventos prog. Python caminho caminho-1 As setas laranjas são automaticamente gerenciadas pelo Sistema Operacional. Ele recebe teclas e cliques de mouse e os coloca na fila do aplicativo “dono” da tela que recebeu os dados. As setas vermelhas são gerenciada gerenciadas pelos programas aplicativos. As setas verdes mostram um caminho alternativo também oferecido pelo S.O.; ele permite ler direta e imediatamente o estado pressionado/não pressionado de uma tecla qualquer. As filas de eventos (setas vermelhas) mostram o quee aconteceu no passado recente.As As linhas verdes acessam o estado atual do teclado. O estado passado da entrada é suficiente na maioria das vezes – mesmo em jogos. Se quisermos o estado atual da entrada, em Python, precisamos de alguma função de biblioteca bibliotec para fazer isso. Essa função deve pedir ao SO (seja ele Windows, Linux, MacOS...) para examinar o teclado. Vamos começar pela lógica das setas vermelhas e ler o estado passado do teclado. Veja o programa na próxima página. 29 µ guia de estudos python André Koscianski Digite e teste: eventos_teclado.py .py import pygame from pygame.locals import * pygame.init() screen = pygame.display.set_mode((640, 480)) pygame.display.set_caption('Pygame Caption') pygame.mouse.set_visible(0) done = False while not done: for event in pygame.event.get(): if (event.type == KEYUP) or \ (event.type == KEYDOWN): print event if (event.key == K_ESCAPE): done = True Aqui está um exemplo de saída. Python quebrando-a com o A seta verde mostra como escrever uma linha de código muito longa em Python: caracter barra invertida \ . A seta vermelha mostra um laço for ; esse laço itera sobre uma lista.. Essa lista é retornada pela rotina que lê a fila de eventos do programa1. Você também m poderia programar esse laço assim: ... fila_de_ fila_de_eventos = pygame.event.get() for event in fila_de_eventos: ... 1 Note ote como esta frase contem “lista” e “fila” “fila”.. São estruturas de dados diferentes quanto às operações possíveis. Uma fila não permite inserção/remoção de elementos no meio meio. 30 µ guia de estudos python André Koscianski 26. Problema: teste da fila de eventos. A biblioteca pygame possui uma função que paraliza a execução do programa durante alguns instantes. Lembrou? (Ela já foi usada dentro deste guia). Use essa rotina no programa de leitura do teclado e descubra se, enquanto o programa está paralizado, a fila de eventos ainda é alimentada pelo S.O. 27. Estado atual do teclado Agora vamos usar uma função para ler o estado atual do teclado, sem consultar a fila de eventos. Essa função será bastante útil em jogos. Veja: estado_teclado.py import pygame from pygame.locals import * pygame.init() screen = pygame.display.set_mode((100,100)) 1) acc = 0 while (acc < 50): L = pygame.key.get_pressed() 2) pygame.event.get() 3) if L[K_SPACE]: #barra de espaco spaco pressionada? acc += 1 else: acc = 0 print acc , pygame.time.delay (5) Na seta vermelha (1), obtemos de pygame uma lista de valores booleanos.. Cada elemento dessa d lista representa o estado pressionado/livre de uma tecla. A lista pode ser indexada usando constantes prépré definidas: K_SPACE, K_a , K_b ... Na seta vermelha(2), chamamos uma função de pygame; sem essa chamada este programa não funciona. O motivo? Hmm... Na seta laranja(3) verificamos se o elemento da lista L correspondente à barra de espaço contem True ou False. 31 µ guia de estudos python André Koscianski 28. Problema: iô-iô iô com controle Volte aos problemas as envolvendo uma bola pulando (ou iô iô-iô...). Modifique o programa para que a bola seja capturada/liberada liberada quando for pressionada a tecla <ENTER>. 29. Problema: iô-iô iô com super super-controle Volte ao problema anterior, do “iô “iô-iô com controle”. Descubra os códigos para as teclas de seta à esquerda, direita, cima e baixo. Modifique o programa para movimentar a bola na direção desejada, enquanto a tecla correspondente estiver pressionada. Ao soltar a tecla, a bola para de se mover. Dica: todo o controle passa sa pela variável speed. 32 µ guia de estudos python André Koscianski 30. Canhão anti-aéreo aéreo (1) Desenhe um projétil no PaintBrush. Escreva um programa que dispara projéteis verticalmente, de baixo para cima, quando o jogador pressiona a barra de espaço. Apenas um projétil deve aparecer na tela. Ele surge ao pressionar a tecla, sobe até o topo da tela e desaparece. A tecla <ESC> deve encerrar o programa. (2) Inclua no seu programa um objeto (um avião) que cruza a tela da esquerda para a direita. Ao “vazar” o lado direito, ele simplesmente reaparece do lado esquerdo. (3) Crie um teste de colisão. Se o projétil ficar muito próximo do avião, você ganha um ponto. Para isso, use esta fórmula: ! " #$ % %#$ e este código: IF d < dmin: pontos += 1 (4) Crie um desenho de uma explosão e mostre mostre-a quando o avião for acertado. (5) Altere o cálculo de pontuação: quanto mais próximo o tiro passar do avião, mais pontos você ganha. (6) Calibre suas coordenadas para atingir o centro do avião. (7) Coloque dois aviões na tela, voando em direções (velocidades) opostas e altitudes diferentes. (8) Coloque vários aviões na tela. Use vetores contendo posição e velocidade dos aviões. Por exemplo, a velocidade e posição do avião 2 estarão guardados em: velocidadeX[2] velocidadeY[2] posX[2] posY[2] 33 µ guia de estudos python André Koscianski 31. Escrevendo na tela gráfica Depois de implementar o último programa, n nós já temos um jogo completo! Agora falta mostrar um placar no vídeo. O programa a seguir mostra como fazer isso. teste.py import pygame pygame.init () screen = pygame.display.set_mode ((200,100)) #cor de fundo screen.fill ((0, 0, 255)) #fontes funcionando? if pygame.font: #escolha fonte default font= pygame.font.Font(None, 22) #crie o texto text=font.render("ola mundo!", 1, (255, 250, 0)) #obtenha o retangulo que contem o texto textpos = text.get_rect() #carimbe o texto na tela screen.blit(text, (50,50)) pygame.display.flip() #aguarde o usuario digitar algo x = raw_input() Problema:: a partir deste exemplo, crie um placar para seu jogo de canhão anti-aéreo. anti 34 µ guia de estudos python André Koscianski Parte três: Orientação ção a Objetos básica em Python As partes um e dois deste guia apresentaram uma visão geral sobre Python e Pygame. Se você resolveu todos os problemas propostos, já é capaz de programar desde jogos simples, como FORCA ou JOGO da VELHA, até alguns com figuras em movimento, como BREAKOUT ou ALIENS INVASION. Vale um lembrete importante. Este guia não tem o objetivo de ensinar todos os detalhes. O guia tem o objetivo de guiar. guiar Entende? Excelente. A próxima parte do guia descreve em linhas gerais o uso de Orientação a Objetos em Python. Você cetamente precisará conhecer esses recursos para poder avançar em direção a programas mais complexos. Programas grandes devem ser divididos em pedaços. Dividi Dividi-los los em objetos é uma ótima forma de organizá-los. los. No caso de jogos, é natural que cada personagem do jogo (avião, robo, tiro, bicho-papão) bicho seja programado dentro de um objeto. 35 µ guia de estudos python André Koscianski 32. Rudimentos de OO em Python , parte I Vamos começar analisando este trecho de código: monstro1.py class Monstro(): onstro(): # de praxe letra maiuscula def diga_alo(self): print "alo" onstro() jorgival = Monstro() jorgival.diga_alo() Aqui é criada uma classe de monstros, que sabem escrever “alo” no vídeo. Em seguida é criado um m monstro chamado jorgival e, finalmente, jorgival diz “alo”. Uma classe é como uma forma de bolo: a partir dela você pode fabricar objetos. objetos Uma classe contem funções. Objetos fabricados com a classe podem usar (chamar) essas funções. 33. Rudimentos de OO em Python , parte II Vamos ampliar um pouco o programa anterior. monstro2.py class Monstro(): onstro(): peso = 100 def diga_alo(self): print "alo" def diga_peso(self): print "Eu peso ", self.peso, " toneladas." jorgival = Monstro() onstro() anaiaia = Monstro() onstro() jorgival.peso = 277 jorgival.diga_peso() anaiaia .diga_peso() Agora um objeto monstro contem duas rotinas e uma variável. Cada objeto possui suas próprias variáveis variáveis: neste este exemplo, cada monstro tem seu próprio peso. E, como mostra o código, o peso de cada monstro pode ser diferente. 36 µ guia de estudos python André Koscianski 34. Objetos são variáveis Problema:: escreva no programa uma rotina que recebe um monstro e aumenta seu peso em 10%. Essa rotina deve receber um parâmetro que é, logicamente, o monstro. Exemplo de chamada: monstro2.py jorgival.diga_ .diga_peso() #mostra 277 na tela engorde (jorgival) jorgival.diga_ .diga_peso() #mostra 304.7 na tela 37 µ guia de estudos python André Koscianski 35. A variável self de Python As sub-rotinas rotinas de uma classe são conhecidas como métodos. E existe uma diferença importante entre métodos de uma classe e sub-rotinas rotinas comuns. Quando invocamos um método, ele deve agir em um determinado objeto: jorgival.diga_ .diga_peso() anaiaia .diga_ .diga_peso() Ou seja: é a mesma sub-rotina, rotina, mas trabalhando para um monstro diferente. Pergunta:: como o método “sabe” qual é o monstro que está sendo utilizado? Resposta:: usando o parâmetro self . Veja este exemplo: monstro_self.py class monstro (): peso = 100 def diga_peso (self): print "Eu peso ", self.peso, " toneladas." jorgival = Monstro onstro () anaiaia = Monstro onstro () 1) jorgival.diga_peso () anaiaia .diga_peso () 2) onstro.diga_peso (jorgival) Monstro.diga_peso Monstro.diga_peso onstro.diga_peso (anaiaia) Na seta vermelha (1) é feita uma chamada “comum”, que você já conhece conhece,, ao monstro jorgival. Na seta amarela (2) é chamda a função “diga_peso” da classe “monstro”.. Nessa chamada estamos avisando à função que o monstro a ser us usado é “jorgival”. Para a linguagem Python, as duas chamadas são iguais. Ao ler o código da seta vermelha, o compilador imediatamente identifica o parâmetro self=jorgival. Ao ler o código da seta amarela, novamente self=jorgival. São duas maneiras de escrever a mesma coisa. A forma mostrada na seta vermelha é a mais comum.. Ela corresponde ao que se faz em C++, Java, C# e outras linguagens com orientação a objetos. 38 µ guia de estudos python André Koscianski 36. Atributos de objetos Vamos aprender mais uma coisa sobre a variável self. Veja este código: atributos.py class Monstro onstro (): 1) peso = 100 nome = "" 2) def batizar (self, string): self.nome = string 3) def diga_peso (self): peso = 123 print "Ola, sou o monstro ", self.nome print "Variavel local vale ", peso 2) print "Eu tenho ", self.peso, " toneladas." x = Monstro onstro () x.batizar ("cleocivaldo") x.diga_peso () Na seta vermelha (1) são criadas variáveis que pertencem a um monstro (ou ATRIBUTOS): ATRIBUTOS) • peso • nome Na setas amarelas (2) os atributos de um determinado monstro são usados. Só é possível saber qual é o monstro, quando a rotina é chamada (lembrou para que serve o parâmetro self ?): ?) • self.peso • self.nome “solta”. Ela pertence à sub-rotina, não ao objeto. objeto Note que Na seta azuL (3), você vê uma variável “solta” “self.peso” e “peso” são diferentes. E esta é a saída do programa acima: 39 µ guia de estudos python André Koscianski 37. Aviões – objetos Aperfeiçoamento de um programa programa: volte ao jogo do canhão anti-aéreo. Crie uma classe avião que contem coordenadas x,y e velocidade vx,vy e um conjunto de aviões: avioes.py N_AVIOES = 10 ... class Aviao(): rect_aviao=[] vel_x = 0 vel_y = 0 pos_x = 0 pos_y = 0 ... aviao = [] for idx in xrange( xrange(N_AVIOES): aviao[idx] = Aviao() aviao[idx].v aviao[idx].vel_x = random.random() * 10 aviao[idx].pos_x = random.random() * 10 Para movimentar os aviões, use um laço assim: for idx in xrange ( (N_AVIOES): aviao[idx]. aviao[idx].mover () e crie um método dentro da classe Avião, assim: class Aviao(): ... def mover(self): aux = self.rect.move((self.vel_x, self.vel_y)) self.rect = aux 40 µ guia de estudos python André Koscianski 38. Esqueleto de jogo: pouso lunar lunar, parte I Vamos exercitar um pouco mais n nossos ossos conhecimentos de Mecânica e criar um jogo bastante conhecido. Começamos por um dos programas de iô iô-iô que você fez, como o de MRUV da seção 23 deste guia. (1) Primeiro, crie uma classe Nave(). Assim como a bola (ou o avião), a imagem controlada por esta classe deve poder se mover na tela. Programe a rotina de movimento de forma que sse a nave “vazar” o canto direito da tela, ela reaparecerá no canto esquerdo – e vice vice-versa. (2) Inclua na classe Nave() uma variável de aceleração, acc.. Essa variável, que faz parte da Nave() (self.acc),, servirá para calcular a velocidade usando esta fórmula: 0.1 ∗ Δ. O valor constante 0.1 na fórmula acima serve para representar um campo gravitacional que atrai a nave para o chão. Você deverá calibrar esse valor por tentativa e erro, assim como no programa do MRUV. Inicialmente, faça aparecer a nave na tela, atribua o valor self.acc = 0 e simule movimento. Você deve obter uma nave que cai no chão, acelerando, exatamente como o programa da bola fazia. (3) Agora inclua no programa a capacidade de ler o teclado.. Você precisa de uma única tecla – por exemplo a barra de espaço. Enquanto essa tecla estiver acionada, a variável self.acc deve ser incrementada. O valor do incremento deve ser algo em torno de um décimo da força da gravidade. Assim que o usuário solta essa tecla, imediatamente a variável self.acc deve receber zero. ze Para resolver esse problema, observe com atenção o programa programa-exemplo da seção 27 deste guia. (4) Coloque um comando IF no código, de forma que se a nave colidir no chão com uma velocidade muito elevada, ela explode. (5) Inclua um placar gráfico na tela, que mostra a velocidade atual da nave. 41 µ guia de estudos python André Koscianski 39. Esqueleto de jogo: pouso lunar lunar, parte II Agora que a parte I do jogo está funcionando, vamos em frente. (1) Inclua mais uma variável na Nave: self.accX. Essa variável contem a aceleração horizontal da Nave. (2) Agora programe as teclas de seta à esquerda (K_LEFT) e seta à direita (K_RIGHT) para modificar o valor da variável self.accX. Quando a tecla K_RIGHT estiver tiver apertada, o valor de self.accX deve ser incrementado, exatamente da mesma forma como você fez com a variável self.acc e a tecla K_ESPACE. Siga o mesmo raciocínio e programe a tecla K_LEFT para decrementar a variável self.hacc. (3) Em seguida, inclua no código esta fórmula: ( 0.9 ∗ ( ( ∗ Δ. Ela é muito parecida com a fórmula (2) da seção 23. Aqui, a variável VX V contem a velocidade horizontal da nave. A multiplicação por 0.9 faz que a nova velocidade seja menor que a antiga – a menos que o usuário acelere a nave, pressionando as teclas de seta e mudando o valor de self.accX. self.acc A fórmula deve ser calculada à cada iteração do o laço principal do programa. Um local mais lógico para incluir a fórmula é dentro da classe Nave(). Entende o motivo? O laço principal do programa pode poderá ficar mais ou menos assim: while (True): #leia leia teclado teclado; v = seta esquerda/direita, # h = espaco apertado/nao minhanave.controlar_aceleracao_Vertical nhanave.controlar_aceleracao_Vertical (v) minhanave.controlar_aceleracao_Horizontal nhanave.controlar_aceleracao_Horizontal (h) minhanave.atualizar_velocidade_Vertical () minhanave.atualizar_velocidade_Horizontal () minhanave.mover () minhanave.testar_aterrisagem () pygame.time.delay (5) (4) Último passo: desenhee no PaintBrush uma plataforma de pouso no paint-brush brush e mostre-a mostre na tela. O jogador deve conseguir pousar a nave exatamente sobre a plataforma, com uma velocidade vertical verti não muito grande. Se a velocidade estiver muito alta, ou se o pouso for longe demais da plataforma, a nave explode! 42