Mudanças entre as edições de "Introdução a Python - Parte 2"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
Linha 245: Linha 245:
  
 
== Cores ==
 
== Cores ==
 +
 +
Cores são tuplas contendo os valores para vermelho, verde e azul (RGB). Por exemplo, as cores preta e branca podem ser definidas assim:
 +
 +
<syntaxhighlight lang=python>
 +
preta = (0,0,0)
 +
branca = (255, 255, 255)
 +
</syntaxhighlight>
 +
 +
Pygame possui a classe [http://pygame.org/docs/ref/color.html Color], que auxilia algumas operações sobre cores.
  
 
== Temporização ==
 
== Temporização ==

Edição das 21h39min de 20 de outubro de 2016

Pygame é um conjunto de módulos Python projetados para a escrita de jogos. Pygame adiciona funcionalidade sobre a excelente biblioteca SDL. Isso possibilita que se criem jogos repletos de recursos e programas multimidia com a linguagem Python. Pygame é altamento portável e roda em praticamente todas as plataformas e sistemas operacionais. Pygame já foi transferido milhões de vezes, e sua página oficial já recebeu milhões de acessos. (traduzido do parágrafo inicial encontrado na página oficial)

Referências

Como instalar

Em distribuições Ubuntu, a instalação de Pygame para Python3 deve ser feita com esta sequência de comandos:

sudo apt-get update
sudo apt-get install mercurial python3-dev python3-setuptools python3-numpy python3-opengl \
    libav-tools libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsmpeg-dev \
    libsdl1.2-dev libportmidi-dev libswscale-dev libavformat-dev libavcodec-dev \
    libtiff5-dev libx11-6 libx11-dev fluid-soundfont-gm libfreetype6-dev \
    xfonts-base xfonts-100dpi xfonts-75dpi xfonts-cyrillic fontconfig fonts-freefont-ttf
 
sudo apt-get install python3-pip
sudo apt-get build-dep python-pygame
sudo pip3 install hg+http://bitbucket.org/pygame/pygame

Um primeiro exemplo

Este primeiro exemplo mostra como se pode criar um pequeno programa com uma imagem em movimento. Muitos elementos de pygame já aparecem nesta simples demonstração ...

#!/usr/bin/python3

import sys
import pygame

# inicia as estruturas internas do pygame
pygame.init()

# algumas variáveis necessárias:
# size: tamanho da janela
# speed: velocidade da bola
# black: tupla que representa cor preta

size = width, height = 320, 240
speed = [2, 2]
black = (0, 0, 0)

# cria a tela da janela, dimensionando de acordo com a variável "size"
screen = pygame.display.set_mode(size)

# carrega a imagem da bola
ball = pygame.image.load("ball.gif")

# obtém o retângulo que contém as dimensões da imagem da bola
ballrect = ball.get_rect()

# laço que nunca termina ...
while True:
    # trata quaisquer eventos pendentes do pygame
    for event in pygame.event.get():
        # apenas evento QUIT é considerado: ele faz com que a
        # aplicação termine. Demais eventos são ignorados
        if event.type == pygame.QUIT: sys.exit()

    # move a bola de acordo com "speed". Isso muda as coordenadas do retângulo 
    # que a contém
    ballrect = ballrect.move(speed)

    # se limites horizontais de movimentação foram atingidos, então velocidade horizontal
    # é invertida
    if ballrect.left < 0 or ballrect.right > width:
        speed[0] = -speed[0]
    # se limites verticais de movimentação foram atingidos, então velocidade vertical
    # é invertida
    if ballrect.top < 0 or ballrect.bottom > height:
        speed[1] = -speed[1]

    # pinta toda a tela de preto
    screen.fill(black)

    # copia a imagem da bola para a região definida por "ballrect"
    screen.blit(ball, ballrect)

    # mostra a imagem que foi copiada
    pygame.display.flip()

Baixe os arquivos deste exemplo para experimentá-lo. O programa está no script ball.py.


Algumas observações:

  • Antes de mais nada, o módulo pygame deve ser importado e inicializado (linhas 4 e 7)
  • A bola provavelmente se movimenta muito rápido na tela ... reduza sua velocidade para melhor visualizá-la.

Elementos da API pygame


A API Pygame dispõe de um conjunto de elementos que podem ser usados em aplicativos gráficos. Basicamente eles se dividem em:

  • Representação da tela ou de um elemento gráfico (ex: uma imagem, como a da bola)
  • Eventos, tais como os do mouse, teclado e temporizadores
  • Cores e fontes
  • Funções para desenho
  • Imagens e Sprites
  • Temporização
  • Mouse e teclado
  • ... e alguns outros

Nesta introdução a Python são apresentados alguns desses elementos, de forma que se possam implementar o jogo proposto ao final da oficina (ou algum outro que se ache mais interessante !).

Display

O display em Pygame representa a tela ou uma janela. Um display é iniciado da seguinte forma:

resolucao = (largura, altura)
janela = pygame.display.set_mode(resolucao)

A resolução é uma tupla que especifica as dimensões da janela. Se a resolução for (0,0), então a janela terá a dimensão da tela (modo tela cheia). Há outros dois parâmetros opcionais, que podem ser usados para escolher o tipo exato de display. Maiores detalhes podem ser lidos na referência sobre a inicialização do display.

Uma vez iniciado, um display pode ser usado como uma superfície. No exemplo, essa superfície é referenciada pela variável janela. O que se pode fazer cm uma superfície, que é um elemento fundamental de pygame para representar imagens, é apresentado na próxima seção. Por enquanto, é importante saber que, sempre que se fizerem modificações na tela, deve-se executar o seguinte:

pygame.display.flip()

Todas as modificações que se fazem na tela não são apresentadas imediatamente. A tela é composta por dois buffers, sendo um o buffer cujo conteúdo é apresentado, e outro onde se fazem atualizações. O método flip troca os buffers, invertendo seus papéis. Com isso, modificações na tela são acumuladas e ao final podem ser apresentadas de uma vez só.

Surface (superfície)

Um superfície representa uma imagem, possuindo uma resolução fixa.. Qualquer elemento em pygame do tipo imagem, seja carregada de um arquivo ou gerada dinamicamente, é uma superfície. Operações típicas que podem ser feitas em superfícies são cópia de outras imagens, desenho, preenchimento com cores, deslocamento, entre outras.

Uma superfície possui coordenadas corrspondentes a suas dimensões, as quais são representadas por um retângulo. A classe Rect possui a fucionalidade para representar e manipular esse retângulo. O retângulo de uma superfície pode ser obtido pelo método get_rect, como se pode ver na linha 25 do exemplo da bola:

ballrect = ball.get_rect()

O retângulo possui os atributos right,left,top,bottom, para os limites de cada lado. Se esses atributos forem modificados, pode-se usar o retângulo para desenhar uma imagem em outra posição da tela. A modificação do retângulo pode ser feita facilmente com o método move, como feito na linha 37 do exemplo da bola:

ballrect = ballrect.move(speed)

... sendo que o parâmetro passado para move é uma tupla contendo os incrementos a serem feitos em suas coordenadas.


Algumas das operações de superfície são usadas no exemplo. Nele se trabalha com duas superfícies: screen, que representa a tela da janela, e ball, que representa a imagem da bola. A cada ciclo de execução, a bola é desenhada numa posição da tela, como mostrado nas linhas 37 a 52 destacadas a seguir:

    #
    # move a bola de acordo com "speed". Isso muda as coordenadas do retângulo 
    # que a contém
    ballrect = ballrect.move(speed)

    # se limites horizontais de movimentação foram atingidos, então velocidade horizontal
    # é invertida
    if ballrect.left < 0 or ballrect.right > width:
        speed[0] = -speed[0]
    # se limites verticais de movimentação foram atingidos, então velocidade vertical
    # é invertida
    if ballrect.top < 0 or ballrect.bottom > height:
        speed[1] = -speed[1]

    # pinta toda a tela de preto
    screen.fill(black)

    # copia a imagem da bola para a região definida por "ballrect"
    screen.blit(ball, ballrect)


A cada vez que se move o retângulo da bola (e após refletir a bola nas paredes, caso necessário), pinta-se toda a tela de preto. Isso é fundamental para limpar a tela antes de redesenhar a bola:

screen.fill(black)

... e, em seguida, desenha-se a bola na nova posição ditada pelo retângulo ballrect:

screen.blit(ball, ballrect)

Assim, toda vez que se precisar desenhar uma superfície sobre outra, usa-se o método blit da superfície que será modificada.

Por fim, note que o display deve ser atualizado após redesenhar a bola, como se pode ver na linha 55:

pygame.display.flip()

Imagens e Sprites

Imagens são superfícies cujo conteúdo (seus pixels) são carregados de um arquivo. Diversos formatos de imagem são suportados. Uma imagem é criada usando a função load, tendo como resultado uma superfície que representa a imagem:

ball = pygame.image.load('ball.gif')

Após carregada, uma imagem pode ser usada como uma superfície qualquer, podendo inclusive ser modificada e salva novamente em arquivo (ver função save).

Sprites são elementos visíveis, que podem ser agrupados e desenhados ou removidos em conjuntos. Outras funcionalidades úteis são detecção de colisão ou sobreposição de elementos visuais, e controle da ordem em que são desenhados (para representar objetos que estão sobre outros). Apesar de, a rigor, ser um elemento importante para a criação de jogos, sprites fogem do escopo desta introdução. No entanto, a documentação fornece uma boa explicação.

Eventos

Jogos e aplicativos gráficos somente são funcionais se puderem interagir com o usuário de alguma forma. A interação pode ser por teclado, mouse, joystick ou outros dispositivos. Pygame trata as entradas desses dispositivos e as apresenta para aplicativos na forma de eventos.

Eventos representam cliques e movimentações de mouse, teclas pressionadas ou liberadas, ativação de temporizadores e acontecimentos de interesse (ex: uma requisição para terminação do programa). Eventos podem ser recebidos de forma bloqueante usando a função wait, ou verificados com a função get. No [Introdução_a_Python_-_Parte_2#Um_primeiro_exemplo exemplo da bola], usa-se a função get para coletar todos os eventos pendentes antes de novamente movimentar e redesenhar a bola:

    for event in pygame.event.get():
        # apenas evento QUIT é considerado: ele faz com que a
        # aplicação termine. Demais eventos são ignorados
        if event.type == pygame.QUIT: sys.exit()

Como get retorna uma lista de eventos pendentes, pode-se iterá-la para tratar cada evento. No exemplo, trata-se apenas o evento pygame.QUIT, que representa uma requisição para terminação do programa, ignorando-se outros eventos que possam ter ocorrido. Assim, se o mouse foi movimentado ou clicado sobre a tela, nenhum efeito terá sobre o aplicativo, pois os eventos correspondentes n]ao são tratados. Os tipos de evento podem ser vistos na documentação, sendo alguns deles:

Tipo de evento Atributos Significado
QUIT none pedido de terminação do programa
ACTIVEEVENT gain, state Programa recebeu foco do mouse
KEYDOWN unicode, key, mod tecla pressionada
KEYUP key, mod tecla liberada
MOUSEMOTION pos, rel, buttons movimentação do mouse
MOUSEBUTTONUP pos, button botão do mouse pressionado
MOUSEBUTTONDOWN pos, button botão do mouse liberado
>= USEREVENT None evento gerado pelo próprio programa (ex: timer)

Cores

Cores são tuplas contendo os valores para vermelho, verde e azul (RGB). Por exemplo, as cores preta e branca podem ser definidas assim:

preta = (0,0,0)
branca = (255, 255, 255)

Pygame possui a classe Color, que auxilia algumas operações sobre cores.

Temporização

Um jogo de memória


Oficina-python-mem.png