Lo sviluppo di un gioco in Python: un primo esempio

In questo articolo vedremo una parte fondamentale della realizzazione del nostro videogioco, prima però dobbiamo fare alcune considerazioni: dovete sapere che, in soldoni, un videogioco non è niente altro che una sequenza di immagini statiche; infatti non c’è nulla che si muove, letteralmente parlando. Per dare questo effetto di movimento, sia esso in 2D o in 3D, si cerca di renderizzare dei fotogrammi molto velocemente in successione, dando così l’impressione che le cose si stiano muovendo. Vale lo stesso per i comuni video che vediamo tutti i giorni, film o qualsiasi altra cosa.

Questo piccolo inganno però non è facile da controllare, infatti ci sono due punti molto delicati, ovvero che non tutti i computer possono renderizzare gli stessi frame per secondo e che la soglia con la quale noi percepiamo il movimento si aggira intorno ai 24 fps.
Inoltre non si deve dimenticare che lo schermo ha un suo tempo di refresh (rinfresco) che può essere differente dal tempo di renderizzazione della scheda video.

Detto questo ora spiegheremo come fare in modo che il nostro gioco sia percepito alla stessa velocità da chiunque lo provi. Per fare questo utilizzeremo il modulo Time della libreria pygame.
Questo modulo ci permette di sincronizzare i frame secondo il tempo da noi prestabilito, che per ora sarà di 30 fps. Riprendendo il codice del primo esempio porteremo delle modifiche per far muovere l’immagine in loop da sinistra verso destra e commenteremo per avere ulteriori dettagli.

N.B. : Il codice che segue è la versione finale, seguite i commenti per capire come modificare il codice di esempio del primo articolo:


imm_sfondo = "ciaomondo.jpg"
import pygame
from pygame.locals import*
from sys import exit
pygame.init()

screen = pygame.display.set_mode((640,480), DOUBLEBUF | HWSURFACE, 32)
pygame.display.set_caption("Ciao Mondo FPS!!!")

sfondo = pygame.image.load(imm_sfondo).convert()

x=0
speed=250
orologio = pygame.time.Clock()

while True:
   for event in pygame.event.get():
      if event.type == QUIT:
         exit()

   tempo_passato = orologio.tick(30)

   tempo_passato_sec = tempo_passato/1000.0

   distanza_spostamento = tempo_passato_sec * speed

   if x>640:
      x=0

   x+= distanza_spostamento

   screen.blit(sfondo,(x,0))
   screen.blit(sfondo,(x-640,0))

   pygame.display.flip()

L’idea è quella di far scorrere la nostra immagine da sinistra verso destra, quindi l’unica cosa da controllare sono le coordinate delle ascisse e che l’immagine risulti continua nel movimento. Per far questo abbiamo dovuto aggiungere una variabile ‘x’ per tenere conto degli spostamenti e quindi l’abbiamo opportunatamente sostituita alle coordinate da aggiornare (al posto delle ascisse) per renderizzare l’immagine.


screen.blit(sfondo,(x,0))

Cambiando solo questo però, il risultato sarà che la nostra immagine si sposterà verso destra fino ad uscire dallo schermo. Per renderizzare la parte rientrante da sinistra, utilizziamo sempre screen.blit, ma con le coordinate partendo da – 640 pixel.


screen.blit(sfondo,(x-640,0))

Per rendere il tutto consecutivo, abbiamo bisogno che qualcuno riporti le ascisse allo stato iniziale una volta raggiunto il fine spostamento, per rendere ciclica la transizione, in questo modo:


if x>640:
   x=0

Con questi piccoli accorgimenti abbiamo la nostra immagine in movimento da sinistra verso destra, in un loop infinito, che si muoverà in base alla distanza_spostamento che sommiamo alla coordinata ‘x’.

Se fate girare questo programma senza gli altri accorgimenti che andremo ad introdurre tra poco, potrete facilmente notare che la velocità di esecuzione varia molto tra un pc e l’altro o anche sullo stesso pc in base alla disponibilità delle risorse di sistema.
Per rendere il tutto più omogeneo, abbiamo bisogno di due cose:


speed=250
orologio = pygame.time.Clock()

Una velocità da noi preimpostata (speed=250) e un orologio che tenga conto del tempo passato. Fatto questo basta aggiungere :


tempo_passato = orologio.tick(30)
tempo_passato_sec = tempo_passato/1000.0
distanza_spostamento = tempo_passato_sec * speed

Tick è una funzione membro dell’oggetto Clock da  noi creato. In questo caso, passandogli l’intero 30 gli diamo la direttiva di aggiornare lo schermo 30 fps. Il valore restituito da quella funzione però è in millisecondi, quindi o si procede con il calcolo in millesimi oppure convertite il tutto in secondi semplicemente dividendo per 1000. A questo punto basta aggiornare la distanza percorsa moltiplicando il tempo passato con la velocità da noi voluta, ovvero 250 pixel per secondo.
In questo modo l’immagine da voi prodotta si muoverà alla stessa velocità su qualsiasi pc, basta che riesca a renderizzare 30 fps.

Conclusioni

Con questi piccoli accorgimenti abbiamo le basi per far sì che il nostro gioco sia percepito da tutti allo stesso modo. Dovete tenere in mente però che se un videogioco è troppo complesso è possibile che alcuni computer non possano renderizzarlo a 30 fps, quindi sta a voi decidere quali sono i limiti e come gestire queste situazioni. Dalla prossima volta vedremo le periferiche di input (mouse, tastiera e joystick), così da far interagire l’utente facendogli muovere qualcosa sullo schermo.

Press ESC to close