Program Arcade Games
With Python And Pygame

Chapter 5: Introdução aos Graficos

fig.ellie

Agora que você já sabe criar laço de repetição (loop), é hora de mover o foco do aprendizado para aprender como usar as funcionalidades oferecidas pelo python para criar gráficos. O capítulo cobririrá:

5.1 Sistema de coordenadas de Computador

Video: O sistema de coordenadas para graficos em computador

O sistema de coordenadas cartesianas mostrada na figura 5.1 (Wikimedia Commons), é o sistema mais usado pelos pessoas quando trabalhando com graficos. Esse é o sistema ensinado na escola. O computador usa um istema de coordenadas parecido, mas com algumas diferenças. Por causa dessas diferenças, precisamos conhecer um pouco a historia dos computadores.

fig.Cartesian_coordinates_2D
Figure 5.1: Sistema de coordenadas cartesianas

Durante os anos 80, muitos sistemas de computadores eram baseados em texto e não suportavam graficos. A figura 5.2 (Wikimedia Commons) mostra um antigo programa de planilha rodando em um computador Aple ][ que já era popular nos anos 80. Quando posicionaram o texto na tela, os programadores começãram no topo e chamaram de linha 1. a tela continuava descendo até a linha 24 e abrangia algo em torno de 40 caracteres.

fig.apple3screen
Figure 5.2: Antiga tela de texto de um Aple

Mesmo usando somente texto, era possivel desenhar graficos rudimentares usando apenas caracteres digitados via teclado. Veja esse gatinho mostrado nessa figura 5.3 e observe cuidadosamente como ele foi desenhado. Ao desenhar essa arte, caracteres eram posicionados começando no topo, na linha 1.

fig.simpleASCII
Figure 5.3: Tela de Texto

Mais tarde, a tabela de caracteres se expandiu para incluir caixas e formas de desenhos primitivo. Caracteres poderiam ser desenhados em diferentes cores. Como mostra a figura 5.4 o grafico aqui é muito mais bem elaborado. Pesquise na internet por “ASCII art”, você pode encontrar muitos exemplos.

fig.spacewar
Figure 5.4: Tela de Texto do Spaceware

Uma vez que os computadores evoluiram para permitr maior controle individual sobre pixels para os graficos, o sistema baseado em texto tornou-se obsoleto.

fig.Computer_coordinates_2D
Figure 5.5: Sistema de coordenadas de Computador

A coordenada $x$ funciona igual ao sistema cartesiano, mas a coordenada $y$ é invertida. Enquanto o zero da coordenada $y$ no sistema cartesiano está na parte de baixo do grafico, o zero da coordenada $y$ nos computadores está no topo da tela. Aumentando o valor de $y$, a coordenada na tela do computador move-se para baixo, exatamente como as linha de texto em vez de grafico. Veja a figura 5.5.

Além disso, observe que a tela cobre o quadrante inferior direito, geralmente, o sistema de coordenadas cartesianas se concentra no quadrante superior direito. É possível desenhar itens em coordenadas negativas, mas eles serão desenhados fora da tela. Isto pode ser útil quando parte de uma figura está fora da tela. o computador descobre o que está fora da tela e o programador não precisa se ​​preocupar muito com isso.

5.2 Biblioteca Pygame

Video: Abrindo uma Janela

Fazer graficos é uma tarefa fácil se você usar Pygame. Pygame é uma biblioteca de código escrita por otras pessoas e torna muito mais simples:

A primeira coisa a fazer em um programa Pygame é carregar e inicializar a biblioteca pygame. Todos os programas que usam a biblioteca pygame começam com essas linhas:

# Importa a biblioteca de funçoes chamada 'pygame'
import pygame
# Inicializa o motor
pygame.init()

Se você ainda não instalou o pygame, veja como fazer isso em Antes de iniciar o capítulo. Se o pygame não estiver instalado no seu computador, irá retornar um erro quando você tentar rodar um programa contendo import pygame.

Nunca nomeie qualquer arquivo como “pygame.py”

Importante: A linha import pygame procura por uma biblioteca chamada pygame. Se o programador criar um novo programa e chamar ele de pygame.py, o computador irá importar esse mesmo arquivo que você acabou de nomear! E também irá impedir de qualquer outro programa que use a biblioteca pygame de funcionar até que o dito arquivo pygame.py seja deletado.

5.3 Cores

Em seguida, precisamos adicionar variáveis ​​que definam cores para o nosso programa. As cores são definidas em uma lista de três cores: vermelho, verde e azul. Você já ouviu falar de um monitor RGB? Este é o lugar de onde o termo vem. Vermelho-Verde-Azul (Red, Green, Blue do Inglês). Com monitores mais antigos, você poderia sentar-se muito perto do monitor e verificar as cores RGB separadamente. Pelo menos antes sua mãe sempre lhe avisou para não se sentar tão perto da TV. Verificar isso com monitores de alta resolução de hoje é impossível.

Cada elemento da tríade RGB é um número que varia de 0 a 255. Zero significa que não há nenhuma cor, e 255 diz que o monitor está exibindo o maior número de cores possível. As cores se combinam numa forma aditiva, por isso, as as três cores são especificadas, se a cor no monitor aparece branco. (Isto é diferente de como irá aparecer num trabalho impresso.)

listas em Python são cercadas entre colchetes ou parênteses. O (capítulo 7 trata de listas detalhadamente e a diferença entre colchetes e parenteses.) Os itens numa lista são separados por vírgulas. O exemplo abaixo mostra como criar variáveis do tipo lista ​​definindo três listas de tamnho igual com três números cada uma. Estas listas serão usadas posteriormente para especificar cores.

# Define some colors
BLACK    = (   0,   0,   0)
WHITE    = ( 255, 255, 255)
GREEN    = (   0, 255,   0)
RED      = ( 255,   0,   0)

Por que essas variáveis etão ​​em maiúsculas? Lembre-se voltando ao capítulo um, uma variável que não muda é chamada constante. Nós não esperamos que a cor de preto irá mudar; logo, é uma constante. Uma vez que nomeamos uma variável com todas sua letras em maiúsculas, estamos querendo dizer que ela é constante. Se precisarmos de uma cor que mude no decorrer do programa, como a cor_do_ceu que muda conforme o o sol se põe, então teriamos de declarar essa variável com as letras todas em minúsculas.

Usando o shell interativo IDLE, tente definir essas variáveis ​​e imprimi-las no console. Se as cinco cores acima não são as cores que você procura, você pode definir a sua própria. Para escolher uma cor, podemos encontrar um “ seletor de cores on-line” como o mostrado na Figura 5.6. Um desses seletor de cores pode se encontrado em:
http://www.colorpicker.com/

fig.colorpicker
Figure 5.6: Seletor de Cores

Extra: Alguns seletores de cores especificam cores em hexadecimal. Você pode inserir números hexadecimal, iniciando sempre com 0x. Por exemplo:

WHITE = (0xFF, 0xFF, 0xFF)

Eventualmente, o programa terá que usar o valor de $\pi$, quando for desenhar arcos, de modo que este é um bom momento para definir uma variável que contenha o valor de $\pi$. (Também é possível importar este valor a partir da biblioteca de matemática do pygame, algo tipo isso math.pi.)

PI = 3.141592653

5.4 Abrindo uma Janela

Até agora, os programas que criamos somente imprime texto na tela. Esses programas não abrem nenhuma janela, como a maioria dos programas modernos. O código para abrir uma janela não é complexo. Abaixo está o código necessário para criar uma janela e dimensionar ela para uma largura de 700 pixels e uma altura de 500 pixels:

size = (700, 500)
screen = pygame.display.set_mode(size)

Por set_mode? Por que não open_window? A razão é que este comando pode realmente fazer muito mais do que abrir uma janela. Ele também pode criar jogos que são executados em um modo de tela cheia. Isso remove o menu iniciar, barras de título, e dá o controle do jogo para toda a tela. Porque este modo é ligeiramente mais complexo de usar, e como a maioria das pessoas preferem jogos com janelas de qualquer maneira, vamos pular uma discussão mais detalhada sobre os jogos em tela cheia. Mas se você quiser saber mais sobre jogos em tela cheia, confira a documentação sobre o comando no site do pygame.

Além disso, por que o tamanho size = (700, 500) e não size = 700, 500? Pela mesma razão de colocamos parênteses em torno das definições de cores. O Python não pode normalmente armazenar dois números (altura e largura) em uma variável. A única maneira que podemos usar é se os números forem armazenados como uma lista. Listas precisam ser tanto entre parênteses como em colchetes. (Tecnicamente, parêntese em torno de um conjunto de números é mais precisamente chamado de tupla (tuple) ou uma lista imutável (imutable list). Listas cercadas por colchetes são apenas chamadas de listas. Um desenvolvedor Python experiente iria encolher chamar uma lista de números entre parênteses uma lista ao invés de uma tupla. Você pode realmente usar size = 700, 500 e será o padrão para uma tupla, mas é prefirível que as pessoas usem parênteses. Listas são abordadas em detalhes no Capítulo 7.

Para definir o título da janela (o que é mostrado na barra de títulos) use a seguinte linha de código:

pygame.display.set_caption("Jogo legal do Professor Craven")

5.5 Interagindo com o Usuário

Com apenas o código escrito até agora, o programa irá criar uma janela e abri-la na tela imediatamente. O usuário não pode interagir com a janela, nem mesmo para fechar. Tudo isso precisa ser programado. Um código deve ser adicionado de modo que o programa espere num laço de repetição (loop) até o usuário clicar no botão “Fechar”.

Esta é a parte mais complexa do programa, e por enquanto, um entendimento completo ainda não é necessário. Mas é necessário ter uma idéia do que ele faz, então, é bom passar algum tempo estudando-o e fazendo perguntas.

# Laco (loop) enquanto o usuário clica no botão fechar.
done = False

# Usado para gerenciar o quão rápido a tela é atualizada
clock = pygame.time.Clock()

# -------- Main Program Loop -----------
while not done:
    # --- Evento do laço (loop) principal
    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done = True # Flag that we are done so we exit this loop

    # --- A lógica do jogo pode vir aqui

    # --- O código para desenhar pode vir aqui

    # Primeiro, limpa a tela e pinta ela de branco. Não coloque nenhum
    # comando de desenho antes disso, porque serão apagados com esse
    # comando
    screen.fill(WHITE)

    # --- seguir em frente e atualizando a tela com o que foi desenhado
    pygame.display.flip()

    # --- Limita para 60 frames por segundo
    clock.tick(60)

Eventualmente vamos adicionar o código para lidar com os o teclado e com os cliques do mouse. O código logo abaixo do comentário no evento do laço principal na linha 9. È o código para determinar quando as balas serão disparadas e como os objetos se moverão, ficará abaixo do comentário feito para a lógica do jogo, na linha 14. Falaremos sobre isso em capítulos posteriores. O código para desenhar vem loga abaixo, onde a tela é preenchida com branco na linha 20.

5.5.1 The Event Processing Loop

Mantenha esta parte do processamento dentro do laço (loop).

Ateção! Um dos problemas mais frustrantes que os programadores tem é se atrapalhar com o processamento dentro de um laço de repetição. Este código, lida com todas as teclas digitadas e todos os cliques feitos com os botões do mouse e vários outros tipos de eventos, por exemplo, seu laço (loop) pode ser algo tipo:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            print("O usuário quer sair.")
        elif event.type == pygame.KEYDOWN:
            print("O usuário pressionou uma tecla.")
        elif event.type == pygame.KEYUP:
            print("O usuário soltou a tecla pressionada.")
        elif event.type == pygame.MOUSEBUTTONDOWN:
            print("O usuário pressionou o botão do mouse")

Os eventos como (pressionar teclas) vão todos juntos em uma lista. O programa utiliza um laço for para determinar cada evento dentro do laço. Usando uma declaração se if o código descobre qual tipo de evento ocorreu e que parte de código será tratado no evento dentro dessa declaração se if.

Toda a declaração se if devem vir juntos, dentro do laço for. Um erro comum ao copiar e colar código é o de não fundir os laços de dois programas, mas ter dois laços (loops) para cada evento.

    # Aqui tem um laço com evento
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            print("O usuário quer sair.")
        elif event.type == pygame.KEYDOWN:
            print("O usuário pressionou uma tecla.")
        elif event.type == pygame.KEYUP:
            print("Usuário soltou a tecla pressionada.")

    # Aqui o programador copiou outro laço com eventos
    # dentro do programa. Isto é RUIM. os outros eventos anda estão
    # sendo processados.
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            print("O usuário pressionou uma tecla.")
        elif event.type == pygame.MOUSEBUTTONDOWN:
            print("O usuário pressionou um botão do mouse")

O laço for na linha 2 pegou todos os eventos do usuário. O laço for na linha 13 não vai pegar todos os eventos, porque eles já foram processados ​​no circuito anterior.

Outro problema comum é começar a desenhar e em seguida tentar terminar o ciclo de eventos:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            print("O usuário quer sair.")
        elif event.type == pygame.KEYDOWN:
            print("O usuário pressionou uma tecla.")


    pygame.rect.draw(screen, GREEN, [50,50,100,100])

    # Este código processa o evento. Mas como ele não está dentro do laço
    # 'for' que precessa o evento. ele não terá garantia de funcionar.
    if event.type == pygame.KEYUP:
        print("O usuário soutou a tecla pressionada.")
    elif event.type == pygame.MOUSEBUTTONDOWN:
        print("O usuário pressionou o botão do mouse")

Isso fará com que o programa ignore alguns comandos do teclado e do mouse. Por quê? O laço for processa todos os eventos em uma lista. Assim, se houver duas teclas que devem ser atingidas, o laço for irá processar as duas concomitantemente. No exemplo acima, a declaração se if não estão no laço for. Se houver vários eventos, a declaração se if só será executada para o último evento, em vez de todos os eventos que se quer executar.

5.5.2 Processando cada Quadro (Frame)

A Ordem básica e lógica para cada quadro (frame) do jogo:

Isso torna o programa mais fácil de ler e entender, se essas etapas não estiverem todas misturadas no mesmo laço. Não faça alguns cálculos, algum desenho, mais alguns cálculos, mais algum desenho, etc. Além disso, veja como isso é similar à calculadora feita no capítulo um. Obter entrada do usuário, executar os cálculos e exibir o resultado na saída. Esse mesmo padrão se aplica aqui.

O código para desenhar a imagem na tela acontece dentro do laço while. Com o tick fixado no timer em 10, o conteúdo da janela será exibido 10 quadors. Se isso acontece muito rápido o computador ficará lento porque todo o seu tempo de processamento é gasto para atualizar a tela. Se isso não for feito dentro do laço (loop) a tela não irá ser exibida corretamente. Se o desenho estiver fora do laço, a tela pode mostrar inicialmente os gráficos, mas os gráficos não reaparecerão se a janela for minimizada, ou se outra janela for colocada na frente.

5.6 Terminar o Programa

Agora, clique no botão “Fechar” da janela durante a execução deste programa em Pygame e a IDLE fará com que o programa trave. Isto é um aborrecimento, porque requer uma grande quantidade de cliques para fechar um programa que travou.

O problema é que, mesmo que o laço (loop) tenha finalizado, o programa não pediu para o computador para fechar a janela. Ao executar o comando abaixo, o programa irá fechar todas as janelas abertas e sair como desejado.

pygame.quit()

5.7 Limpando a tela

?

O código a seguir sobrepõe tudo que está na janela preenchendo-a com um fundo branco. Lembre-se que a variável WHITE foi definida anteriormente como uma lista (tuple) com três valores RGB.

# Limpa a tela preenchendo-a com um fundo branco
screen.fill(WHITE)
Video: Desenhando Linhas

Isto deve ser feito antes de qualquer emitir qualquer comando de desenho. Limpar a tela depois que o programa desenha os gráficos, o usuário somente verá uma tela em branco.

Quando uma janela é criada pela primeira vez, ela tem um fundo preto. Entretando, várias coisas podeão ocorrer, e por isso é importante manter esta janela iniciando apagada. Um programa nunca começa assumindo que tem uma tela em branco para desenhar.

5.8 Lançando a tela

Muito importante! Você só deve executar um “flip” no “display” depois de desenhar. Do cotrário, o computador não exibirá os gráficos como você quer desenhar porque a tela irá ficar piscando. Assim, isso irá esperar para exibir a tela até que o programa termine de desenhar. O comando abaixo executa um “ flip” dos gráficos na tela.

Fracasso ao incluir este comando, ele irá fazer apenas com que o programa mostre uma tela em branco. Qualquer código de desenho após este “ FLIP” não será exibido.

# Vá em frente, e atualize a tela com o que já temos desenhado.
pygame.display.flip()

5.9 Abra uma janela em branco

Vamos trazer tudo o que já falei sobre sobre o que tem num programa completo. Este código pode ser utilizado como um modelo base para um programa PyGame. Ele abre uma janela em branco e espera que o usuário pressione uma tecla.

No site, se você clicar no botão “ Examples” você pode selecionar “ exemplos de gráficos” e então você vai encontrar esse arquivo como pygame_base_template.py.

"""
 Pygame base template for opening a window

 Sample Python/Pygame Programs
 Simpson College Computer Science
 http://programarcadegames.com/
 http://simpson.edu/computer-science/

 Explanation video: http://youtu.be/vRB_983kUMc
"""

import pygame

# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

pygame.init()

# Set the width and height of the screen [width, height]
size = (700, 500)
screen = pygame.display.set_mode(size)

pygame.display.set_caption("My Game")

# Loop until the user clicks the close button.
done = False

# Used to manage how fast the screen updates
clock = pygame.time.Clock()

# -------- Main Program Loop -----------
while not done:
    # --- Main event loop
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

    # --- Game logic should go here

    # --- Screen-clearing code goes here

    # Here, we clear the screen to white. Don't put other drawing commands
    # above this, or they will be erased with this command.

    # If you want a background image, replace this clear with blit'ing the
    # background image.
    screen.fill(WHITE)

    # --- Drawing code should go here

    # --- Go ahead and update the screen with what we've drawn.
    pygame.display.flip()

    # --- Limit to 60 frames per second
    clock.tick(60)

# Close the window and quit.
pygame.quit()

5.10 Desenho, Introdução

fig.castle

Aqui está uma lista de coisas que você pode desenhar:
http://www.pygame.org/docs/ref/draw.html
Um programa pode desenhar coisas como retângulos, polígonos, círculos, elipses, arcos e linhas. Nós também iremos tratar da exibição de textos com os gráficos. Imagens de bitmap, são abordados no Capítulo 12. Se você decidir olhar para essa referência no site do pygame, o que você verá lá será uma função definida com esta sintaxe:

pygame.draw.rect(Surface, color, Rect, width=0): return Rect

Uma causa frequente de confusão é a parte da linha que diz width = 0. O que isto significa que: se você não fornecer uma largura, o padrão será zero. Assim, Chamar essa função dessa forma:

pygame.draw.rect (tela, RED, [55, 500, 10, 5])

É o mesmo que chamar ela assim:

pygame.draw.rect(screen, RED, [55, 500, 10, 5], 0)

O : return Rect está dizendo que a função retorna um retângulo, o mesmo que foi passado dentro da declaração dela. Você pode simplesmente ignorar esta parte.

O que não vai funcionar, está tentando copiar a linha e colocar width = 0 dentro de aspas.

# Esta falha e o erro que o computador retorna é
# Realmente difícil de entender.
pygame.draw.rect(screen, RED, [55, 500, 10, 5], width=0)

5.11 desenhar linhas

O exemplo de código a seguir mostra como desenhar uma linha na tela. Ele vai desenhar uma linha verde na tela de (0, 0) para (100, 100) e com 5 pixels de largura. Lembre-se que GREEN é uma variável que foi definida anteriormente na declaração das listas (tuples) de valores RGB.

# Desenha uma linha na tela de (0, 0) para (100, 100)
# com 5 pixels de largura.
pygame.draw.line(screen, GREEN, [0, 0], [100, 100], 5)

Use o modelo base do exemplo anterior e adicione o código para desenhar linhas. Leia os comentários para descobrir exatamente onde colocar o código. Tente desenhar linhas com diferentes espessuras, cores desenho e locais. Desenhe várias linhas.

5.12 desenho de linhas com loops e Offsets

Programas podem repetir as coisas indefinidamente. O próximo código exemplo desenha uma linha mais uma e mais uma, usando um laço (loop). Programas podem usar esta técnica para fazer várias linhas, e até mesmo desenhar um carro inteiro.

Colocar uma linha de comando de desenho dentro de um laço (loop) fará múltiplas linhas serem desenhadas na tela. Mas aqui está o problema. Se cada linha iniciar e terminar na mesma coordenada, então cada linha vai aparecer em cima da outra. Ficará parecendo que apenas uma linha foi desenhada.

Para contornar esta situação, é necessário compensar as coordenadas uma de cada vez através do laço (loop). Aqui, na primeira volta do laço a variável y_offset é zero. A linha do código abaixo será iniciada a partir de (0,10) a (100, 110). Na próxima iteração do laço (loop), y_offset será acrescida para 10 e isso faz com que a próxima linha a ser desenhada para tenha novas coordenadas (0, 20) e (100, 120). Essa mudança, continua ocorrendo cada vez através do laço (loop) aumentando as coordenadas de cada linha para baixo na tela por 10 pixels.

# Desenhando varias linhas de (0, 10) a (100, 110) na tela
# com 5 pixels de espessura usando um laço while (while loop)
y_offset = 0
while y_offset < 100:
    pygame.draw.line(screen,RED,[0,10+y_offset],[100,110+y_offset],5)
    y_offset = y_offset + 10

Este mesmo código poderia ser feito mais facilmente com um laço for:

# Desenhando varias linhas de (0, 10) a (100, 110) na tela
# com 5 pixels de espessura cada usando um laço while (while loop)
for y_offset in range(0, 100, 10):
    pygame.draw.line(screen,RED,[0,10+y_offset],[100,110+y_offset],5)

Execute este código, altere y_ofssetkbd> e tente usar diferentes deslocamentos. Tente criar diferentes valores para ele. Experimente com valores diferentes até ver como isso funciona exatamente, isso é óbvio.

Por exemplo, aqui tem um laço (loop) que usa seno e cosseno para criar um conjunto mais complexo de offsets e produz a imagem mostrada na Figura 5.7.

for i in range(200):

	radians_x = i / 20
	radians_y = i / 6

	x = int( 75 * math.sin(radians_x)) + 200
	y = int( 75 * math.cos(radians_y)) + 200

	pygame.draw.line(screen, BLACK, [x,y], [x+5,y], 5)
fig.complex_offsets
Figure 5.7: Complex Offsets

Vários elementos podem ser desenhados em um laço for, tais como, o código que chama o múltiplo de X mostrado na Figura .

    for x_offset in range(30, 300, 30):
        pygame.draw.line(screen,BLACK,[x_offset,100],[x_offset-10,90],2)
        pygame.draw.line(screen,BLACK,[x_offset,90],[x_offset-10,100],2)
fig.multiple_x
Figure 5.8: Multiplos Xises

5.13 desenho de um retângulo

Video: Como desenhar retângulos e elipses

Ao desenhar um retângulo, o computador precisa de coordenadas para o canto superior esquerdo do rectângulo (a origem), uma altura e uma largura.

A Figura 5.9 Mostra um retângulo (E uma elipse, o que será explicado mais adiante), com origem em (20, 20), uma largura de 250 e uma altura de 100. Ao especificar um rectângulo o computador tem uma lista dos quatro números na ordem de (x, y, largura, altura).

fig.ellipse
Figure 5.9: Desenhando uma Ellipse

O exemplo de código seguinte desenha este retângulo. Os dois primeiros números na tupla definem o canto superior esquerdo em (20, 20). Os próximos dois números especificam primeiro a largura de 250 pixels, e em seguida a altura de 100 pixels.

O 2 no final especifica uma largura de linha de 2 pixels. Quanto maior for o número, mais grossa a linha ao redor do retângulo. Se esse número for 0, então não terá uma borda ao redor do retângulo. Em vez disso, vai ser preenchido com a cor especificada.

# Desenha um retangulo
pygame.draw.rect(screen,BLACK,[20,20,250,100],2)

5.14 Desenhando uma elipse

Uma elipse é desenhada como um retângulo. Os limites de um retângulo são especificados, e a computador desenha uma elipse dentro desses limites.

O erro mais comum em trabalhar com uma elipse é pensar que o ponto de partida especifica o centro da elipse. Na realidade, nada é desenhado no ponto de partida. O ponto de partida é o canto superior esquerdo de um retângulo que contém a elipse.

Olhando mais trás, na figura um 5.9podemos ver uma elipse de 250 pixels de largura e 100 pixels de altura. O canto superior esquerdo do retângulo de 250x100 que a contém inicia em (20, 20). Note que nada é realmente desenhada em (20, 20). Com ambos desenhados um em cima do outro é mais fácil visualizar como a elipse é especificada.

# Desenha uma elipse, usando um retangulo como coordenadas externas
pygame.draw.ellipse(screen, BLACK, [20,20,250,100], 2)

5.15 Desenhando um arco

Video: Como desenhar arocos

Como seria se um programa precisasse desenhar apenas uma parte de uma elipse? Isso pode ser feito com o comando arc. Este comando é semelhante ao comando ellipse, mas inclui ângulos iniciais e finais para o arco terminar de ser desenhado. Os ângulos são em radianos.

fig.arc
Figure 5.10: Arcs

O exemplo de código a seguir desenha quatro arcos que mostram quatro diferenças nos quadrantes do círculo. Cada quadrante é desenhado em uma cor diferente para fazer as seções dos arcos serem mais fácil de ver. O resultado deste código é mostrado na Figura 5.10.

# Desenha um arco como parte de uma elipse. Usando radianos para determinar
# que angle será desenhado.
pygame.draw.arc(screen, GREEN, [100,100,250,200],  pi/2,     pi, 2)
pygame.draw.arc(screen, BLACK, [100,100,250,200],     0,   pi/2, 2)
pygame.draw.arc(screen, RED,   [100,100,250,200],3*pi/2,   2*pi, 2)
pygame.draw.arc(screen, BLUE,  [100,100,250,200],    pi, 3*pi/2, 2)

5.16 Desenhando um Polígono

Video: Como desenhar poligonos

A próxima linha de código desenha um polígono. A forma do triângulo é definida com três pontos em (100, 100) (0, 200) e (200, 200). É possível listar tantos pontos quanto desejar. Note como os pontos são listados. Cada ponto é uma tupla de dois números, e os pontos em si estão aninhadas em outra tupla que contém todos os pontos. A chamada dste código pode ser vista na Figura 5.11.

fig.triangle
Figure 5.11: Polygon
# Isto desenha um triângulo usando o comando poligon
pygame.draw.polygon(screen, BLACK, [[100,100], [0,200], [200,200]], 5)

5.17 Desenhando Textos

Video: Como desenhar textos

Texto é um pouco mais complexo. Há três coisas que precisam ser feitas. Primeiro, o programa precisa de uma variável que contenha as informações sobre o tipo de fonte a ser usado, como fonte tamanho grande, por exemplo.

Em segundo lugar, o programa cria uma imagem do texto. Uma maneira de pensar isso seria que o programa esculpe uma “ estampa” com as letras necessárias como num caribo que vai ser mergulhado na tinta e carimbado no papel.

A terceira coisa que é feita é dizer par o programa onde esta imagem do texto deverão ser marcadas (ou “ carimbadas”) na a tela.

Aqui está um exemplo:

# Seleciona uma fonte para usar, tamannho, negrito, italico
font = pygame.font.SysFont('Calibri', 25, True, False)

# Renderização do texto. "True" significa que o texto tem anti-alias.
# O preto é a cor. A variável BLACK foi definida
# Acima como uma tupla de [0, 0, 0]
# Nota: Esta linha cria uma imagem das letras,
# Mas não a coloca na tela ainda.
text = font.render("Meu texto", True, BLACK)

# Coloca a imagem do texto na tela em 250x250
screen.blit(texto, [250, 250])

Quer imprimir o placar na tela? Isso é um pouco mais complexo. Isso não funciona:

text = font.render("Placar: ", score, True, BLACK)

Por quê? Um programa não pode simplesmente adicionar itens extras para font.render como no comando print. Apenas uma cadeia de caracteres pode ser enviada para o comando, portanto, o valor real de pontos tem de ser adicionada ao texto “ Placar:”. Mas isso ainda não serve:

text = font.render ("Score:" + pontuação: É verdade, BLACK)
text = font.render("Placar: " + score, True, BLACK)

Se a pontuação é uma variável do tipo inteiro (int), o computador não sabe como adicionar ela para um texto. Você, o programador, deve converter o resultado para texto. Depois adicionar os dois, como isto:

text = font.render("Placar: " + str(score), True, BLACK)

Agora você sabe como imprimir o placar. Se você quiser imprimir um timer, que exige uma impressão formatada, discutido em um capítulo mais adiante. Verifique o código desse exemplo. Veja também o exemplo para timer.py na seção on-line Examples:
ProgramArcadeGames.com/python_examples/f.php?file=timer.py

5.18 Listagem Programa Completo

Esta é uma lista completa do programa discutido neste capítulo. Este programa, juntamente com outros programas, pode ser baixado em:
ProgramArcadeGames.com/index.php?chapter=example_code

fig.program_result
Figure 5.12: Resultados de um programa de exemplo
"""
 Simple graphics demo

 Sample Python/Pygame Programs
 Simpson College Computer Science
 http://programarcadegames.com/
 http://simpson.edu/computer-science/

"""

# Import a library of functions called 'pygame'
import pygame

# Initialize the game engine
pygame.init()

# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

PI = 3.141592653

# Set the height and width of the screen
size = (400, 500)
screen = pygame.display.set_mode(size)

pygame.display.set_caption("Professor Craven's Cool Game")

# Loop until the user clicks the close button.
done = False
clock = pygame.time.Clock()

# Loop as long as done == False
while not done:

    for event in pygame.event.get():  # User did something
        if event.type == pygame.QUIT:  # If user clicked close
            done = True  # Flag that we are done so we exit this loop

    # All drawing code happens after the for loop and but
    # inside the main while not done loop.

    # Clear the screen and set the screen background
    screen.fill(WHITE)

    # Draw on the screen a line from (0,0) to (100,100)
    # 5 pixels wide.
    pygame.draw.line(screen, GREEN, [0, 0], [100, 100], 5)

    # Draw on the screen several lines from (0,10) to (100,110)
    # 5 pixels wide using a loop
    for y_offset in range(0, 100, 10):
        pygame.draw.line(screen, RED, [0, 10 + y_offset], [100, 110 + y_offset], 5)


    # Draw a rectangle
    pygame.draw.rect(screen, BLACK, [20, 20, 250, 100], 2)

    # Draw an ellipse, using a rectangle as the outside boundaries
    pygame.draw.ellipse(screen, BLACK, [20, 20, 250, 100], 2)

    # Draw an arc as part of an ellipse.
    # Use radians to determine what angle to draw.
    pygame.draw.arc(screen, BLACK, [20, 220, 250, 200], 0, PI / 2, 2)
    pygame.draw.arc(screen, GREEN, [20, 220, 250, 200], PI / 2, PI, 2)
    pygame.draw.arc(screen, BLUE, [20, 220, 250, 200], PI, 3 * PI / 2, 2)
    pygame.draw.arc(screen, RED, [20, 220, 250, 200], 3 * PI / 2, 2 * PI, 2)

    # This draws a triangle using the polygon command
    pygame.draw.polygon(screen, BLACK, [[100, 100], [0, 200], [200, 200]], 5)

    # Select the font to use, size, bold, italics
    font = pygame.font.SysFont('Calibri', 25, True, False)

    # Render the text. "True" means anti-aliased text.
    # Black is the color. This creates an image of the
    # letters, but does not put it on the screen
    text = font.render("My text", True, BLACK)

    # Put the image of the text on the screen at 250x250
    screen.blit(text, [250, 250])

    # Go ahead and update the screen with what we've drawn.
    # This MUST happen after all the other drawing commands.
    pygame.display.flip()

    # This limits the while loop to a max of 60 times per second.
    # Leave this out and we will use all CPU we can.
    clock.tick(60)

# Be IDLE friendly
pygame.quit()

5.19 Revisão

5.19.1 Teste de Múltipla escolha

Click here for a multiple-choice quiz.

5.19.2 Repostas curtas escritas

Click here for the chapter worksheet.

5.19.3 Lab

Click here for the chapter lab.


You are not logged in. Log in here and track your progress.