Un spritesheet est une image composée de plusieurs images plus petites ( sprites ) et / ou animations. La combinaison des petites images en une seule grande image améliore les performances du jeu, réduit l'utilisation de la mémoire et accélère le temps de démarrage et de chargement du jeu.
Voici un spritesheet :
On va stocker chaque image dans une liste pour créer une animation.
On va générer une liste de sprites où chaque sprite sera repéré par les coordonnées du premier point(en haut à gauche) et le couple (longeur, hauteur).
Pour voir l'animation, on affichera les images de liste les unes après les autres.
Voici une fonction qui permet de générer un ensemble de données :
from pygame import *
fenetre = display.set_mode((620,350))
display.set_caption('Tutoriel pygame')
init()
#les images
#les spritesheets
danse = image.load('danser.png')
#On associe les touches aux images
danseSprite = [danse.subsurface((x%8)*110,(x//8)*128,110,128)for x in range(80)]
#paramètres de départ
jouer = True
index_danse = 0
#les fonctions du jeu
while jouer:
for events in event.get():
if events.type == QUIT:
quit()
#les 4 lignes pour afficher le sprite animé
index_danse = (index_danse +1)%(len(danseSprite))
fenetre.fill((255,255,0))
fenetre.blit(danseSprite[index_danse],(100,100))
display.flip()
#définir les FPS on fait une pause 50ms entre chaque frame
time.wait(50)
Voici un spritesheet :
On voit que chaque ligne de ce spritesheet correspond à un déplacement. D'où l'idée d'associer chaque ligne avec la touche qui permettra au personnage de se déplacer.
Pour coder cela on peut utiliser un dictionnaire dont les clés sont les touches et les valeurs sont les listes de sprites.
Voici le code :
from pygame import *
fenetre = display.set_mode((620,350))
display.set_caption('Tutoriel pygame')
init()
#les images
#les spritesheets
perso = image.load('professor.png')
#On associe les touches aux images
imageSprite = {K_UP:[perso.subsurface(x,0,64,64)for x in range(0,576,64)],
K_LEFT:[perso.subsurface(x,64,64,64)for x in range(0,576,64)],
K_DOWN:[perso.subsurface(x,128,64,64)for x in range(0,576,64)],
K_RIGHT:[perso.subsurface(x,192,64,64)for x in range(0,576,64)]}
#paramètres de départ
jouer = True
xSprite,ySprite = 202,202
direction = K_DOWN
index_img = 0
#les fonctions du jeu
#fonction pour déplacer le perso
def deplacementPerso():
global xSprite,ySprite,direction,index_img
if k[K_LEFT]:#si on appuie sur la touche "flèche gauche" alors k[K_LEFT] prend la valeur 1 (sinon 0)
direction = K_LEFT
index_img = (index_img+1)%4
xSprite = xSprite - k[K_LEFT]*8
elif k[K_RIGHT]:
direction = K_RIGHT
index_img = (index_img+1)%4
xSprite = xSprite + k[K_RIGHT]*8
elif k[K_DOWN]:
direction = K_DOWN
index_img = (index_img+1)%4
ySprite = ySprite + k[K_DOWN]*8
elif k[K_UP]:
direction = K_UP
index_img = (index_img+1)%4
ySprite = ySprite - k[K_UP]*8
while jouer:
for events in event.get():
if events.type == QUIT:
quit()
#on récupère les valeurs des touches pressées dans la liste k
k = key.get_pressed()
#On affiche le sprite en fonction de son déplacement
fenetre.fill((200,200,200))
deplacementPerso()
fenetre.blit(imageSprite[direction][index_img],(xSprite,ySprite))
display.flip()
#définir les FPS on fait une pause 50ms entre chaque frame
time.wait(50)
Voici un code avec 2 sprites animés sur 2 écrans différents :
from pygame import *
fenetre = display.set_mode((620,350))
display.set_caption('Tutoriel pygame')
init()
#les images
#les spritesheets
danse = image.load('danser.png')
danseSprite = [danse.subsurface((x%8)*110,(x//8)*128,110,128)for x in range(80)]
perso = image.load('professor.png')
imageSprite = {K_UP:[perso.subsurface(x,0,64,64)for x in range(0,576,64)],
K_LEFT:[perso.subsurface(x,64,64,64)for x in range(0,576,64)],
K_DOWN:[perso.subsurface(x,128,64,64)for x in range(0,576,64)],
K_RIGHT:[perso.subsurface(x,192,64,64)for x in range(0,576,64)]}
#paramètres de départ
jouer = True
etat = 0
xSprite,ySprite = 202,202
direction = K_DOWN
index_img = 0
index_danse = 0
#les fonctions du jeu
def deplacementPerso():
global xSprite,ySprite,direction,index_img
if k[K_LEFT]:
direction = K_LEFT
index_img = (index_img+1)%4
xSprite = xSprite - k[K_LEFT]*8
elif k[K_RIGHT]:
direction = K_RIGHT
index_img = (index_img+1)%4
xSprite = xSprite + k[K_RIGHT]*8
elif k[K_DOWN]:
direction = K_DOWN
index_img = (index_img+1)%4
ySprite = ySprite + k[K_DOWN]*8
elif k[K_UP]:
direction = K_UP
index_img = (index_img+1)%4
ySprite = ySprite - k[K_UP]*8
while jouer:
for events in event.get():
if events.type == QUIT:
quit()
k = key.get_pressed()
if etat==0:
fonte = font.SysFont('comicsansms', 36)
text = fonte.render('Appuyer sur ENTER', True, (0, 255, 0), (0, 5, 255))
fenetre.fill((255,255,0))
fenetre.blit(text, (20, 20))
index_danse = (index_danse +1)%(len(danseSprite))
fenetre.blit(danseSprite[index_danse],(100,100))
if k[K_RETURN]:
etat=1
if etat==1:
deplacementPerso()
fenetre.fill((200,200,200))
fenetre.blit(imageSprite[direction][index_img],(xSprite,ySprite))
display.flip()
#définir les FPS on fait une pause 50ms entre chaque frame
time.wait(50)
Il est conseillé de choisir des spritesheets où les images sont disposées de façon régulière avec le même format. Sinon il faudra entamer un travail méticuleux pour repérer chaque image, et si chaque image n'a pas le même format, il faudra adapter sa position en fonction de sa taille.
Sinon une idée (pour les plus patients) peut être de construire un spritesheet avec des images régulières à partir du spritesheet.