Há alguns módulos em Python de interface com a biblioteca de mídia SDL, sendo o mais conhecido PyGame.PyGame é legal, lembra a mim a antiga API gráfica do Colour BASIC do MSX (eita saudosismo!).
No entanto o Kao Félix apresentou recentemente um outro módulo menos conhecido, chamado Pyglet, que, a primeira vista, achei mais pythónica. =D
Gostaria então de sugirir dois tutoriais do Kao Félix:
Instalando Pyglet
Se você possui o EasyInstall, basta executar:
bash$ sudo easy_install -U pygletPrimeira aplicação
Resolvi fazer minha primeira aplicação segundo as dicas do Kao Félix, mas adaptando a meu jeito próprio de programar.
Iniciaremos com o hash-bang, as peculiaridades de Python e os
imports dos submódulos de Pyglet que vamos precisar:#!/usr/bin/env python
# coding: UTF-8
from __future__ import division
__metaclass__ = type
from pyglet import app, clock, resource, sprite
from pyglet.window import key, WindowCarregando os recursos iniciais
Esta é classe singleton para carregar os recursos de mídia que precisaremos.
Fiz o seguinte: baixei a bola do Kao, mas pode também baixar daqui mesmo – preferível, para não sobrecarregar o link dele.
O arquivo de som está no pacote do KDE, mas você pode baixar daqui.
Nessa classe singleton, implementaremos o método
__new__ (apenas para singleton) e __init__ para carregar as mídias.Para carregar uma imagem usamos
resource.image(). Para áudio, resource.media():class Loader:
"""Singleton class for loading resources"""
__inst = None
__initialized = False
def __new__(cls, *args, **keyw):
if not cls.__inst:
cls.__inst = object.__new__(cls)
return cls.__inst
def __init__(self):
if not self.__initialized:
self.__initialzed = True
self.images = {}
self.sounds = {}
image = resource.image("char.png")
image.anchor_x = image.width // 2
image.anchor_y = image.height // 2
self.images["ball"] = image
self.sounds["pop"] = resource.media(
"pop.wav",
streaming=False
)O parâmetro
streaming=False indica que o arquivo de áudio deve ser completamente carregado para a memória – e não tratado como um fluxo (stream).Gerenciando o teclado
Uma nova classe será usada para gerenciar o teclado. O construtor armazenará uma referência para a janela principal e o método
handle_input() gerenciará as teclas:class KeyHandler(key.KeyStateHandler):
"""Class for handling key events"""
def __init__(self, window):
super(KeyHandler, self).__init__()
self.window = window
def handle_input(self, dt):
speed = 320 * dt
dx, dy = 0, 0
if self[key.RIGHT]:
dx = 1
elif self[key.LEFT]:
dx = -1
if self[key.UP]:
dy = 1
elif self[key.DOWN]:
dy = -1
self.window.ball.x += dx * speed
self.window.ball.y += dy * speedRepare que nosso objeto
window terá um atributo ball, que é um sprite.Agora nosso sprite
Vamos criar agora uma classe que estende
sprite.Sprite, a classe de sprite de Pyglet.O único método que implementaremos será o construtor, que buscará em
Loader a imagem que desejamos:class Ball(sprite.Sprite):
"""Sprite that's a ball"""
def __init__(self, *args, **keyw):
super(Ball, self).__init__(
Loader().images["ball"],
*args, **keyw
)Janela principal
Finalmente a aplicação!
Por um mal hábito adquirido programando Tkinter, tenho o hábito de usar a mesma classe para aplicação e janela principal, porém você não precisa fazer
No entanto vou mostrar aqui da forma como estou habituado.
O construtor:
- ajustará o título da janela (
set_caption()); - criará uma nova bola (classe
Ball); - registrará o manipulador de eventos de teclas (
push_handlers()); - e registrará o método
handle_input()do manipulador de eventos de teclas para execução periódica (clock.schedule_interval()).
class MainApplication(Window):
"""Main window and application"""
def __init__(self):
super(MainApplication, self).__init__()
self.set_caption("Teste de movimento")
self.ball = Ball(x=300, y=240)
handler = KeyHandler(self)
self.push_handlers(handler)
clock.schedule_interval(handler.handle_input, 1/60)Manipulando outros eventos
Os métodos de
Window que manipulam eventos têm nome iniciado por on_, seguido pelo nome do evento. Por exemplo: on_close, on_draw, on_key_press, on_key_release.Vamos implementar
on_close() para tocar o som ao sair e on_draw() para exibir o sprite: def on_close(self):
Loader().sounds["pop"].play()
super(MainApplication, self).on_close()
def on_draw(self):
self.clear()
self.ball.draw()Fazendo funcionar
Para terminar, precisamos instanciar a aplicação e chamar o ciclo principal de Pyglet.
Veja que esse tipo de programação onde um módulo toma o controle e programamos os métodos que atenderão eventos caracteriza um framework.
if __name__ == "__main__":
window = MainApplication()
app.run()Conclusão
Vemos aqui um ótimo módulo – ou melhor, framework – para criação de aplicações gráficas usando as bibliotecas SDL e OpenGL.
[]'s
Cacilhas, La Batalema
CC-BY: Os textos deste blog podem ser reporduzidos contanto que sejam informados autor e origem.