Introduzione a Python Pygame
Di Pete Shinners
Indirizzo e-mail: pete@shinners.org
Questo articolo è un'introduzione alla libreria Pygame per i programmatori Python. La versione originale apparve nel Py Zine, volume 1 capitolo 3. Questa versione contiene revisioni minori, per creare un articolo in tutti i sensi migliore. Pygame è un'estensione di Python che racchiude la libreria SDL e i suoi helpers.
Storia
Pygame nacque nell'estate del 2000. Essendo un programmtore C da molti anni, scoprii sia Python sia SDL quasi nello stesso periodo. Probabilmente già conoscete Python e avete bisogno di un'introduzione a SDL, acronimo di "Simple Directmedia Library". Creata da Sam Lantinga, SDL è una libreria multipiattaforma scritta in C per gestire contenuti multimediali. Paragonabile alle DirectX, è stata usata per centinaia di giochi commerciali e open source. Fui colpito dalla chiarezza e della semplicità di entrambi i progetti e non passò molto prima che realizzassi che combinare Python e SDL poteva essere una proposta interessante.
Scoprii un piccolo progetto già in corso con appunto la stessa idea, PySDL. Creato da Mark Baker, PySDL era una chiara implementazione di SDL come un'estensione di Python. L'interfaccia era più pulita di un generico wrapping con SWIG, ma lo vedevo come una forzatura di codice "Stile C". L'improvviso abbandono di PySDL mi spinse a prendere parte a un nuovo progetto da solo.
Volevo mettere insieme un progetto che realmente sfruttasse i vantaggi di Python. Il mio obiettivo era rendere facili le cose più semplici, e chiare quelle più difficili. Pygame è stato iniziato in Ottobre, nel 2000. Sei mesi dopo fu rilasciata la versione 1.0 di Pygame.
Un piccolo assaggio
Trovo che il migliore modo per capire una nuova libreria sia quello di passare direttamente a un esempio. Nei primi giorni di Pygame, ho creato un'animazione di una palla saltellante con 7 linee di codice. Diamo un'occhiata ad una versione più simpatica che fa la stessa cosa. Questo dovrebbe essere abbastanza semplice da continuare e avviene una completa interruzione.
1 import sys, pygame
2 pygame.init()
3 size = width, height = 320, 240
4 speed = [2, 2]
5 black = 0, 0, 0
6 screen = pygame.display.set_mode(size)
7 ball = pygame.image.load("ball.bmp")
8 ballrect = ball.get_rect()
9 while 1:
10 for event in pygame.event.get():
11 if event.type == pygame.QUIT: sys.exit()
12 ballrect = ballrect.move(speed)
13 if ballrect.left < 0 or ballrect.right > width:
14 speed[0] = -speed[0]
15 if ballrect.top < 0 or ballrect.bottom > height:
16 speed[1] = -speed[1]
17 screen.fill(black)
18 screen.blit(ball, ballrect)
19 pygame.display.flip()
Questo è un modo abbastanza semplice per ottenere una palla saltellante. Per prima cosa vediamo che l'importazione e l'inizializzazione di Pygame non è nulla di notevole. "import pygame" importa il pacchetto con tutti i moduli di Pygame disponibili. La chiamata a "pygame.init()" inizializza ognuno di questi moduli.
Alla linea 8 creiamo una finestra grafica con la chiamata a "pygame.display.set_mode()". Pygame e SDL scelgono automaticamente la modalità grafica migliore per il vostro hardware video. Potete anche sovrascrivere questa modalità ed SDL provvederà a compensare tutto quello che il vostro hardware non è in grado di fare. Pygame rappresenta le immgini come Oggetti Surface. La funzione "display.set_mode()" crea un nuovo oggetto Surface che rappresenta la grafica attualmente mostrata sullo schermo. Tutto ciò che disegnate su questa Surface sarà visibile sul monitor.
Alla linea 10 carichiamo l'immagine della nostra palla. Pygame supporta una varietà di formati per immagini grazie alla libreria SDL_image, che include JPG, PNG, TGA e GIF. La funzione "pygame.image.load()" ritorna una Surface con i dati della palla. Il Surface conserverà alcuni colori o la trasparenza alpha dal file. Dopo aver caricato l'immagine della palla creiamo una variabile di nome ballrect. Pygame ha una comoda utility chiamata Rect, che rappresenta un'area rettangolare. Nella parte del codice dell'animazione, vedremo cosa fanno gli oggetti Rect.
A questo punto, alla linea 13, il nostro programma è inizializzato e pronto per l'esecuzione. All'interno dell'infinito ciclo controlliamo l'input dell'utente, muoviamo la palla, e poi disegnamo la palla. Se si sa già programmare con le GUI, si ha già esperienza con gli eventi e con i cicli di eventi. In Pygame questo non è diverso, controlliamo se è avvenuto un evento QUIT. Se è così, semplicemente usciamo dal programma, e Pygame si assicurerà che ogni cosa sia stata chiusa in modo impeccabile.
E' ora di aggiornare la posizione della palla. Le linee da 17 a 21 muovono la variabile ballrect secondo la velocità assegnata. Se la palla si muove oltre la schermata, invertiamo la velocità in quella direzione. Non si tratta esattamente della fisica Newtoniana, ma è tutto ciò di cui abbiamo bisogno.
Alla linea 23 eliminiamo la schermata riempendola con un colore RGB nero. Se non avete mai lavorato con le animazioni questo potrà sembrarvi veramente strano. Dovreste chiedervi: "Perchè dobbiamo eliminare qualcosa, perchè non muoviamo la palla solo dentro lo schermo?" Questa non è la via più semplice con cui funzionano le animazioni del computer. L'animazione non è niente di più che una serie di singole immagini, che quando mostrate in sequenza fanno davvero un buon lavoro per ingannare l'occhio umano nel far vedere il movimento. La schermata è solo una singola immagine che l'utente usa. Se non avessimo eliminato la palla dallo schermo, attualmente avremmo visto una "traccia" della palla che continuamente disegnamo nelle sue nuove posizioni.
Alla linea 24 disegnamo l'immagine della palla sullo schermo tramite il metodo "Surface.blit()". Blittare significa in poche parole copiare il colore dei pixel da un'immagine all'altra. Passiamo al metodo blit una Surface dalla quale copiare, e la posizione dove vogliamo che la Surface sia copiata.
L'ultima cosa che dobbiamo fare ora è aggiornare il display visibile. Pygame gestisce il display con un doppio buffer. Quando finiamo di disegnare chiamiamo il metodo "pygame.display.flip()". Qesto fa in modo che tutto ciò che abbiamo disegnato sullo schermo Surface diventi visibile. Questo buffering fa in modo che solo i frame completamente disegnati siano visualizzati sullo schermo. Senza di esso, l'utente vedrebbe parti completate solo per metà sullo schermo, come se stessero per essere create.
Questo conclude questa breve introduzione a Pygame. Pygame ha anche dei moduli per gestire cose come input da tastiera, mouse, e joystick. Può combinare audio e decodificare musica in streaming. Con i Surfaces putete disegnare semplici forme, ruotare e scalare l'immagine. Potete anche manipolare i pixel di un'immagine in tempo reale come array Numeric Python. C'è il supporto per i video MPEG in playback e per i CD audio. Pygame ha anche la possibilità di fare da display multipiattaforma per PyOpenGL. Molti dei moduli di Pygame sono scritti in C, alcuni invece fatti in Python. Il sito di Pygame ha tutti i riferimenti alla documentazione per ogni funzione di Pygame e i tutorial per tutti i tipi di utente. I sorgenti di Pygame includono molti esempi come il lancio della moneta e il colpire gli UFO.
Python e i giochi
"Python è adatto ai giochi?" La risposta è: "Dipende dal gioco".
Python oggi è molto efficiente nell'esecuzione dei giochi e probabilmente vi sorprenderà anche quanto è possibile in meno di 30 millesimi di secondo. Tranquilli, non è difficile raggiungere il massimo una volta che il gioco sta diventando più complesso. Qualche gioco eseguito in tempo reale userà appieno il computer.
Prima di alcuni anni fa, ci fu un'interessante tendenza nello sviluppo dei giochi, ovvero il guardare ai linguaggi di più alto livello. Normalmente un gioco è diviso in due grosse parti. Il motore del gioco, che deve essere più veloce possibile, e la logica del gioco, che fa agire il motore. Non molto tempo fa il motore del gioco era scritto in assembly, con delle parti scritte in C. Oggi invece C è stato tolto dal motore del gioco, e spesso questo è scritto in linguaggi di scripting di alto livello. Giochi come Quake3 e Unreal eseguono questi script come bytecode portabile.
All'inizio del 2001, gli sviluppatori di Rebel Act Studios portarono a termine il loro gioco, Severance: Blade of Darkness. Usavano il proprio motore 3D, mentre il resto del gioco fu scritto in Python. Si tratta di un violento gioco d'azione in terza persona, dove guidi guerrieri medievali in un'intrecciata combinazione di attacchi mentre si esplorano torri e castelli. Potete scaricare delle estensioni di terze parti, e notare che non sono altro che file sorgenti di Python.
Recentemente, Python è stato usato per diversi giochi come Freedom Force, e Humungous' Backyard Sports Series.
Pygame e SDL funzionano come un eccellente motore C per i giochi 2D. Questi troveranno ancora che gran parte della loro esecuzione in runtime è spesa all'interno della gestione SDL per la grafica. SDL può sfruttare l'accelerazione grafica delle schede video. Abilitandola, questa può cambiare un gioco dall'esecuzione di 40 a 200 frames per secondo. Quando vedete che i giochi in Python eseguono 200 frames al secondo, potete pensare che Python e i giochi possono lavorare insieme.
E' impressionante quanto funzionino bene Python e SDL su molte piattaforme. Per esempio, nel Maggio del 2001, rilasciai un progetto completo fatto con Pygame, SolarWolf, un gioco arcade in stile azione. Una cosa che mi soprese fu che l'anno dopo non ci fu bisogno di patch, bugfix o aggiornamenti. Il gioco fu sviluppato interamente su Windows, ma funzionava su Linux, Max OSX, e molti sistemi UNIX senza dover fare lavori extra.
Tranquilli, le limitazioni si superano spesso. Il migliore sistema per gestire l'accelerazione grafica non è sempre quello di ottenere risultati dal rendering del programma. Il supporto hardware non è disponibile su tutte le piattaforme. Quando un gioco diventa più complesso, spesso bisogna affidarsi all'uno o all'altro. SDL ha altre limitazioni di design, cose come lo scrolling dello schermo intero possono rapidamente portare il gioco a una velocità ingiocabile. Mentre SDL non è adatto per tutti i tipi di giochi, ricordate che delle compagnie come Loki hanno usato SDL per eseguire un'enorme varietà di giochi per vendita commerciale.
Pygame è faily basso livello quando è usato per creare giochi. Presto avrete bisogno di moduli per interfacciare funzioni comuni nell ambiente del gioco. Un punto a favore è che non c'è nulla all'interno di Pygame che vi sia d'ostacolo. Il vostro programma sarà in pieno controllo su tutto. L'effetto secondario di questo è che vi troverete a prendere in prestito un bel po' di codice per creare un framework più avanzato da mettere insieme. Dovete capire meglio cosa state per fare.
Conclusione
Sviluppare giochi è gratificante, perchè è davvero eccitante poter vedere e interagire con il codice che avete scritto. Pygame al momento è usato da più di 30 altri progetti. Alcuni di essi sono pronti per essere giocati. Dovete essere sopresi visitando il sito di Pygame, e vedere cosa sono stati capaci di fare gli altri utenti con Python.
Una cosa che mi ha colpito è l'aumento delle persone che studiando Python per la prima volta provano a sviluppare giochi. Posso capire perchè i giochi siano un'attrazione per i nuovi programmatori, ma può diventare difficile gestire la situazione dal momento che creare giochi richiede una dura conoscenza del linguaggio. Ho provato a prestare supporto a questo gruppo di utenti scrivendo molti esempi e tutorial Pygame per persone a cui questi concetti sono nuovi.
Infine, il mio avvertimento è quello di renderlo semplice. Non smetto di ribadirlo. Se state cercando di creare il vostro primo gioco, c'è molto da imparare. Anche un gioco più semplice metterà alla prova i vostri progetti, perchè i giochi complessi non significano giochi divertenti. Quando avrete capito Python, potrete usare Pygame per creare un semplice gioco in sole una o due settimane. Da lì avete bisogno di un grosso aumento del tempo necessario per effettuare pulizia in modo da renderlo un gioco completamente presentabile.
Panoramica Dei Moduli Pygame
cdrom |
gestisce le periferiche cdrom e la riproduzione audio |
cursors |
carica le immagini dei cursori, includendo quelli standard |
display |
controlla la finestra della schermata nel monitor |
event |
gestisce gli eventi e la richiesta di eventi |
font |
crea e renderizza i caratteri TrueType |
image |
salva e carica immagini |
joystick |
gestisce le periferiche joystick |
key |
gestisce la tastiera |
mouse |
gestisce il mouse |
movie |
gestisce la riproduzione di video MPEG |
sndarray |
per la manipolazione di suoni con Numeric |
surfarray |
per la manipolazione di immagini con Numeric |
time |
controlla il tempo |
transform |
scala, ruota, sfoglia immagini |