Sito web di notizie tecnologiche e videogames.

Pygame Shooter Parte 7: Animazione degli sprite

5

Questo articolo è la settima parte del progetto PyShooter, oggi vedremo come aggiungere qualche animazione ai nostri sprite.

Animazione delle meteore

Per rendere il videogioco più interessante aggiungiamo un po’ di animazione alle nostre meteore che sembrano ancora tutte uguali.

Un metodo è quello di aggiungere un effetto di rotazione alle meteore, per fare ciò useremo la funzione pygame.transform.rotate(), prima però aggiungiamo qualche proprietà alla classe Mob:

self.rot = 0
self.rot_speed = random.randrange(-8, 8)       
self.last_update = pygame.time.get_ticks()

La prima variabile self.rot tiene traccia del valore totale della rotazione che verrà incrementato di volta in volta.

La seconda variabile indicherà di quanti gradi la meteora deve girare, maggiore sarà il valore maggiore sarà la velocità di rotazione. Il valore può essere sia positivo che negativo in modo da far girare la meteora sia in senso orario sia in senso antiorario.

La terza variabile è fondamentale perché regola ogni quanto tempo l’immagine deve essere ruotata. Usando la funzione pygame.time.get_ticks() possiamo scoprire quanti millisecondi sono passati dall’ultima volta che è scattato il clock.

In questo modo possiamo controllare se è passato abbastanza tempo per far ruotare la meteora un’altra volta.

Ruotare un’immagine

Per far ruotare la nostra immagine abbiamo bisogno di aggiungere qualche riga di codice al nostro programma, creiamo un metodo rotate() nella classe Mob:

def rotate(self):
               now = pygame.time.get_ticks()
               if now - self.last_update > 50:
                       self.last_update = now
                       # do rotation here

In questo modo prendiamo il numero di millisecondi che sono passati dall’ultimo clock (now) e sottraiamo il numero di millisecondi dell’ultimo update. Se il risultato è maggiore di 50 allora possiamo ruotare l’immagine.

Una volta definito il metodo rotate() dobbiamo richiamarlo ogni volta che il mob viene aggiornato, quindi aggiungere nel metodo update() della classe Mob la seguente riga:

        def update(self):
               self.rotate()

A questo punto se inserissimo l’istruzione per ruotare un’immagine nel metodo rotate() avremo il seguente problema:

Pygame Shooter Parte 7: Animazione degli sprite

Perdita di dati con la rotazione

Questo succede perché le immagini sono delle griglie di pixel e nel momento in cui si cerca di ruotare i pixel in una nuova posizione alcuni di loro non riescono più ad allinearsi, causando così una perdita di dati.

Nel caso in cui l’immagine venga ruotata una singola volta la perdita è accettabile, ma nel caso in cui essa venga ruotata ripetutamente l’immagine finale risulterà completamente deformata.

La soluzione è farsi una copia dell’immagine di partenza e di tenere traccia del valore totale della rotazione che aumenta di volta in volta, in questo modo basterà ruotare l’immagine originale per il valore totale della rotazione.

Facciamo una copia dell’immagine originale:

class Mob(pygame.sprite.Sprite):
 def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image_orig = random.choice(meteor_images)
        self.image_orig.set_colorkey(BLACK)
        self.image = self.image_orig.copy()

NB: l’istruzione self.image_orig = random.choice(meteor_images) ci servirà in seguito per fare spawnare meteore di forme diverse

Nel metodo rotate() della classe Mob aggiorniamo il valore di rot e applichiamo la rotazione all’immagine originale:

def rotate(self):       
    now = pygame.time.get_ticks()       
    if now - self.last_update > 50:           
        self.last_update = now           
        self.rot = (self.rot + self.rot_speed) % 360            
        self.image = pygame.transform.rotate(self.image_orig, self.rot)

NB: abbiamo usato l’operatore di resto per evitare di avere valori maggiori 360

A questo punto avremo ancora un piccolo problema:

Pygame Shooter Parte 7: Animazione degli sprite

Sembra che le meteore non abbiano un andamento stabile e lineare.

Aggiornare il contenitore dell’immagine

Nello scorso articolo abbiamo discusso dei ‘contenitori’ che possono contenere lo sprite. Ebbene una volta che si ruota un’immagine bisogna modificare anche il suo contenitore, in questo modo:

Pygame Shooter Parte 7: Animazione degli sprite

Per fare ciò è sufficiente registrare il centro del contenitore, calcolare il nuovo contenitore e settarne il centro con quello registrato in precedenza.

Aggiungere quindi al metodo rotate() le seguenti righe:

old_center = self.rect.center
     self.image = new_image
     self.rect = self.image.get_rect()
     self.rect.center = old_center

Meteore random

L’ultima cosa che ci serve per rendere le meteore più interessanti è utilizzarne di diverse e varie dimensioni.
Per fare ciò aggiungiamo le seguenti righe fuori dal game loop:
meteor_images = []
meteor_list =['meteorBrown_big1.png','meteorBrown_med1.png',
              'meteorBrown_med1.png','meteorBrown_med3.png',
              'meteorBrown_small1.png','meteorBrown_small2.png',
              'meteorBrown_tiny1.png']
for img in meteor_list:
    meteor_images.append(pygame.image.load(path.join(img_dir, img)).convert())

NB: controllare i nomi dei file che si specificano nella lista meteor_list, essi devono essere presenti all’interno della cartella specificata ad inizio programma (img_dir).

Aggiungere quindi la seguente riga al metodo __init__() della classe Mob:
        self.image_orig = random.choice(meteor_images)

Pygame Shooter Parte 7: Animazione degli sprite

Conclusione

In questo modo abbiamo dato un aspetto completamente diverso al nostro videogioco aggiungendo qualche animazione alle meteore.

Nel prossimo articolo vedremo come tenere traccia del punteggio dell’utente!

Links

Dove trovare le immagini: immagini

Codice: code 

Precedente articolo: Pygame Shooter Parte 6: Migliorare le collisioni

Commenti