di  -  martedì 31 agosto 2010

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.

6 Commenti »

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.

  • # 1
    arkanoid
     scrive: 

    *dividendo per 1000

  • # 2
    01jojo
     scrive: 

    Grazie!
    Forse e’ la volta buona che inizio a programmare qualcosa! :-)

    Ciao, 01jojo

  • # 3
    luca
     scrive: 

    forse è meglio cambiare

    if x<-640:
    x=0

    x-= distanza_spostamento

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

    per il movimento da destra verso sinistra dello sfondo… che poi è quello utilizzato nel 99% dei casi.

    Ciao

  • # 4
    Mirco Tracolli
     scrive: 

    @ luca

    Lo scopo di questo articolo non era quello di spostare lo sfondo secondo la direzione indicata, ma quello di sincronizzare il movimento con il “clock di gioco”.

    Se l’effetto che tu desideri è il movimento da destra verso sinistra dello sfondo, puoi apportare benissimo le modifiche che hai suggerito, ma sarebbero inutili in questo script per quello che ho detto prima.

    Se sei interessato al parallax scrolling (penso che sia l’effetto che tu cerchi), puoi leggere l’articolo correltato:

    http://www.appuntidigitali.it/15899/sviluppare-un-gioco-in-python-parallax-scrolling/

  • # 5
    luca
     scrive: 

    sto leggendo la guida, hai fatto un bel lavoro.
    se pensi può essere utile qualche commento mentre leggo lo faccio con piacere. può servire a chi viene dopo di me.
    ciao
    Luca

  • # 6
    Mirco Tracolli
     scrive: 

    @ luca

    Puoi benissimo fare qualsiasi tipo di osservazione sulle guide, ogni contributo migliorerà la qualità di questa guid; cercherò di rispondere il più velocemente possibile :D

    Tieni conto che non è più l’argomento attuale dei miei articoli e che le guide prendono ognuna un particolare tema per svilupparlo.

Scrivi un commento!

Aggiungi il commento, oppure trackback dal tuo sito.

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.