Personatges en moviment ======================= Utilitzant els sprites de pygame, volem una classe que serveixi per a representar un personatge que es desplaça per la pantalla i que canvia la seva aparença depenent de la direcció en la qual es mouen o quan s'estan quiets. Com que només es podran despaçar exclusivament en vertical o en horitzontal, caldran cinc imatges diferents (una per quan s'estan quiets i les altres quatre per quan s'estan movent en cadascuna de les direccions possibles). Un exemple podrien ser aquestes cinc imatges d'un gat: .. image:: gat.png :align: center Amb aquesta finalitat, hem dissenyat la classe *Personatge* derivant-la de la classe *pygame.sprite.Sprite*, que a més a més dels atributs indispensables *image* i *rect*, en necessita dos altres: *llista_im* (una llista amb les cinc imatges possibles) i *dir*, una tupla que indica el moviment del personatge. El valor de *dir* només pot ser un d'aquests cinc possibles: (0,0), (0,-1), (0,1), (-1,0), (1,0). #. Dissenyeu el mètode *__init__(self, imatges, pos)* que té com a paràmetres una llista amb les cinc imatges (*Surfaces* de Pygame) i la posició del sprite (una tupla amb dos enters). Les cinc imatges de la llista ja seran de la mateixa mida i es correspondran, en aquest ordre, a la imatge del personatge quan està quiet, o movent-se cap amunt, avall, a la dreta i a l'esquerra (com el gat de l'exemple). Cal inicialitzar els atributs de manera que *llista_im* sigui directament el primer paràmetre, *image* i *dir* siguin els corresponents al personatge quan està quiet i *rect* sigui un rectangle de les mides de les imatges amb el vèrtex superior esquerre en *pos*. #. Dissenyeu el mètode *update(self)*, que ha de canviar l'sprite de manera mostri el personatge amb la imatge corresponent a *dir* i també ha de desplaçar-lo un píxel en la direcció adient (sempre que no estigui quiet). Remarquem que no cal fer comprovacions sobre si el sprite resta dins la finestra o no. Tot seguit, proporcionem un programa de prova per a aquesta classe, que, disposant del fitxer ``gat.png`` i havent desat la classe en el mòdul ``personatge.py``, hauria de mostrar una finestra amb un gat que l'usuari pot moure amb les tecles del cursor i que canvia d'imatge per mostrar cap on es mou o si s'està quiet. Observeu que qui s'encarrega d'assignar el valor adient a l'atribut *dir* és la part de tractament dels esdeveniments. .. code:: python import pygame import personatge def ini_sprites(): im = pygame.image.load("gat.png").convert_alpha() ample, alt = im.get_width() / 5, im.get_height() gats = [] for i in range(5): cropped = pygame.Surface((ample, alt)) cropped.blit(im, (0, 0), (ample*i, 0, ample, alt)) gats.append(cropped) grup = pygame.sprite.RenderPlain() # grup de Sprites c1 = personatge.Personatge( gats, (100, 100) ) grup.add(c1) return grup, c1 def tracta_events(heroi): dir_tecles = { pygame.K_UP : (0,-1), pygame.K_DOWN : (0,1), pygame.K_LEFT: (-1,0), pygame.K_RIGHT: (1,0) } for event in pygame.event.get(): if event.type == pygame.QUIT: return True elif event.type == pygame.KEYDOWN: if event.key in dir_tecles: heroi.dir = dir_tecles[event.key] elif event.type == pygame.KEYUP: if event.key in dir_tecles and heroi.dir == dir_tecles[event.key]: heroi.dir = (0,0) return False def main(): pygame.init() colorFons = (255, 255, 255) pantalla = pygame.display.set_mode( (400, 300) ) crono = pygame.time.Clock() sprites, heroi = ini_sprites() final = False while not final: final = tracta_events(heroi) sprites.update() # Actualitza la llista de sprites pantalla.fill(colorFons) # pinta el fons de la pantalla sprites.draw(pantalla) # pinta sprites pygame.display.flip() # visualitza la nova pantalla crono.tick(24) # limita a 24 imatges per segon (24 fps) pygame.quit() if __name__=='__main__' : main()