Les sprites sont des éléments graphiques qui
se déplacent sur un écran sans en altérer le contenu.
Il y a deux façons de mettre en oeuvre des sprites.
Par circuiterie hardware comme c'est le cas des bornes d'arcade
et de certains ordinateurs comme l'Amiga ou comme les consoles
(Megadrive, Super Nintendo, NeoGeo...).
Par programmation ou une fonction va permettre de les afficher et
de restituer le contenu de l'écran.
THEORIE
DES SPRITES
GESTION
DES SPRITES PAR LES TABLES
MISE EN OEUVRE DES ROUTINES
Principe:
Un sprite est défini par ses coordonnées x et y, sa largeur
et sa hauteur et par son adresse mémoire où se trouve l'image
réelle de celui-ci.
Lors de l'affichage de celui-ci, la fonction a besoin de
connaître les données suivantes:
On peut remarquer que le nombre de paramètres peut être
diminué en utilisant des tables ayant certaines données
initialisées ou calculées. Dans Totalwar, j'utilise une table
(ex: Definition_sprite[500]) qui va
regrouper l'adresse de l'image du sprite qui aura été calculée
une bonne fois pour toute ainsi que la largeur et la hauteur.
Pour indiquer quel sprite affiché, il suffit de lui donner un
numéro, la fonction d'affichage se contentant de récupérer ces
données.
En partant de ce principe, le nombre de paramètres devient:
Notons que certaines fonctions ne demandent plus l'adresse de l'écran d'affichage. Celui-ci étant considérer comme l'écran final soit &buffer[ecran1] dans le plan du buffer de Totalwar.
(Le fond d'ecran ou se trouve le sprite n'est pas sauvegarde. Leur effacement est simplement effectué en recopiant le fond du decor. Pour cela voyez la scetion CONSTRUCTION D'UNE IMAGE)
GESTION DES SPRITES PAR LES TABLES:
Comme cité précédemment, la gestion des sprites par des
tables offrent des avantages lors de la programmation d'un jeu.
Dans Totalwar, la gestion des sprites est effectué à l'aide de
3 tables (tableaux).
La définition des sprites:
La table de définition:
Cette table donne la position x et y du sprite sur l'image où il a été initialement dessiné. On lui donne aussi sa largeur ainsi que sa hauteur. Son ordre de définition dans la table en fourni son numéro.
unsigned short definition_sprite[]={0,0,16,20,32,64,15,5,60,10,12,8,0x0FFFF};
Dans la ligne ci-dessus, le sprite numéro 0 (couleur rouge) a pour coordonnées x et y les valeurs 0 et 0. Sa largeur est de 16 et sa hauteur de 20.
le sprite numéro 1 (couleur orange) a pour coordonnées x et y les valeurs 32 et 64. Sa largeur est de 15 et sa hauteur de 5.
le sprite numéro 2 (couleur bleue) a pour coordonnées x et y les valeurs 60 et 10. Sa largeur est de 12 et sa hauteur de 8.
La valeur 0x0FFFF indique la fin de la table.Il n'y a donc pas à gérer le numéro de sprite, celui est désigné par sa position lors de la définition.
Le ou les sprites sont dessinés sur une image de 320x200x256c avec n'importe quel logiciel de dessin et chargé par la suite dans le programme. Il suffira juste d'indiquer la position des sprites sur cette image. Si vous décidez par la suite de modifier un sprite vous devrez alors modifier en conséquence sa définition dans cette table.
La table des adresses images:
Afin que la fonction puisse connaître l'adresse de l'image du sprite (le dessin dans l'image PCX), il faut soit calculer à chaque fois cette adresse ou bien la calculer une fois pour toute. C'est la fonction de cette table que de garder en mémoire l'adresse de chacun des sprites. Vous n'avez pas à gérer cette table.
Les images PCX des sprites doivent être placées en 256000 et 320000 (&buffer[spriteecr] et/ou &buffer[spriteecr1]).Lorsque vous indiquerez à la fonction d'affichage de placer le sprite à telles coordonnées, celle-ci ira prendre automatiquement la largeur et hauteur du sprite dans la table de définition et ira de la même façon prendre l'adresse de l'image du sprite dans la table des adresses images.
De ce fait, rien qu'en indiquant le numéro du sprite à afficher, elle en connaîtra sa hauteur, largeur et adresse !.
La table des sprites:
Cette dernière table permet de gérer tous les sprites qui se trouvent à l'écran. Elle garde en mémoire tous les sprites qui devront être afficher à l'écran, leur position, leurs caractéristiques... Elle sert surtout pour gérer les collisions, pour savoir si c'est un bonus, un ennemi, une balle. Chaque sprite utilise 32 octets de mémoire à cette fin. Certain des champs sont prédéfinis comme x,y,n° de sprite, largeur, hauteur mais le reste est à utiliser à votre convenance.
Si vous créez un jeu comme le Pac man, vous n'avez pas trop besoin de table mais si vous faîtes comme dans Totalwar ou il peut avoir près de 200 sprites à l'écran (si, si !!), là, vous êtes obligé de passer par cette méthode.
Différentes fonctions pour utiliser cette table:
- Insertion d'un sprite.
- Annulation de tous les sprites
- Élimination d'un sprite.
- Affichage de cette table (avec animation automatique !!!).
- Connaissance à tous moment du nombre de sprite contenu.
Fonctionnement des tables entre-elles:
Ce graph. montre de quelle façon les tables sont utilisées. Dans tablesprite, si la fonction doit afficher le sprite n°2 alors elle va prendre dans table_adresse_sprite l'adresse de l'image du sprite. Ensuite, elle va prendre dans definition_sprite la largeur et la hauteur. Ces données étant initialisées au debut, vous n'avez plus à vous en soucier par la suite.
Ce système par numéro a un autre avantage. Lors de la détection de collision, la routine peut renvoyer le n° du sprite, donc si votre sprite est par exemple le n°4 et que pour vous c'est un vaisseau ennemi, vous pouvez en déduire la procédure à suivre.La désignation des tables se trouve ici.
Déclaration des sprites:
unsigned short definition_sprite[]={0,0,16,20,32,64,15,5,60,10,12,8,[sprites suivants],0x0FFFF};
Cette déclaration a été expliquée plus haut dans cette page. Le nombre maxi de sprites est de 256.
Initialisation des tables:
load_definition_sprite(&definition_sprite[0],&buffer[0]);
sprite_adr_insere(&buffer[0]);La première fonction va copier les définitions de sprites (x, y, largeur, hauteur) dans le buffer (580000).
La deuxième fonction va calculer les adresses des sprites et les stocker dans le buffer (585000).
Insertion de sprite dans la table:
insere_sprite_dans_table(&buffer[0],0,100,100,1,3);
Cette fonction insère un sprite dans la table des sprites (560000).
Les paramètres sont:L'adresse de début du buffer.
Le numero de sprite à afficher.
La coordonnée x d'affichage du sprite
La coordonnée y d'affichage du sprite
Le nombre d'animation du sprite
La temporisation entre deux animationsL'image du sprite se trouve à l'offset 256000. Vous devez charger l'écran à cette adresse. Le deuxième écran se trouve juste après (320000). Pour les repères de coordonnées, le y sur le deuxième écran n'est pas 0 mais 200. Il vous suffit d'ajouter 200 à la coordonnée y pour ces sprites.
Ces images étant contiguës en mémoire, vous pouvez dessiner un sprite sur le 1er écran et le finir sur le 2èmé.
Effacer tous les sprites de la table de sprite:
buffer[tablesprite]=0; ou
buffer[560000]=0;
Il suffit de mettre à 0 le premier octet de la table des sprites
Vous pouvez connaître l'organisation de cette table sur la page des tables.
Affichage de la table des sprites
affiche_tablesprite(&buffer[0],&buffer[tablesprite]);
Il n'est pas très aisé d'expliquer
tout ceci, donc n'hésiter pas à m'envoyer toutes suggestions ou
critiques.
La méthode utilise
ne stocke en aucun cas le contenu se trouvant en dessous du
sprite. Pour effacer les sprites, recopier tout le décor sur la
page.