Suivez-nous sur X

|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : C - les sprites
(Article écrit par Batchman et extrait d'Amiga News - février 1991)
|
|
Tous ceux d'entre vous qui ont eu la chance de posséder un de ces dinosaures qu'étaient les C64 ou C128
font partie, passez-moi l'expression, de la génération sprite. En effet, cette machine a innové par
rapport à ses concurrents de l'époque, en matière d'animation et de graphisme grâce aux sprites.
On peut regretter que l'Amiga n'ait pas énormément augmenté leurs possibilités, contrairement aux autres domaines.
Mais c'est tout de même quelque chose d'intéressant et de facile à réaliser pour agrémenter vos programmes.
Qu'est-ce qu'un sprite ?
En anglais, cela signifie "lutin" ou "farfadet" (logique donc que l'on m'ait confié cet article).
Il s'agit, au sens Amiga du terme, d'un objet graphique, déplaçable sur tout l'écran, indépendamment
du fond. Pour fixer les idées, le pointeur de la souris est un sprite.
Quelles sont les contraintes techniques ?
Il y en a plusieurs liées au fait qu'un sprite est géré directement par les circuits vidéo
de l'Amiga. En fait, il s'agit, grosso modo, d'une image superposée à l'image du fond lors de
la création du signal vidéo à destination du moniteur. Voici ces contraintes :
- Il n'y a que huit sprites (autant que sur le C64, dis-je d'un ton amer). Dommage pour les jeux d'arcade
mais nous verrons dans le prochain article qu'ils ne manquent pas d'idées chez Commodore...
- Chaque sprite ne peut excéder 16 pixels de large. Attention, ces pixels sont de la taille de ceux
d'un écran en basse résolution (320 de large).
- Par contre, la hauteur n'est pas limitée.
- Chaque sprite est défini par deux plans de bits, soit quatre couleurs, mais une représente la couleur
de fond, donc est invisible. Soit en définitive trois couleurs utiles.
- Les huit sprites ne peuvent avoir chacun des couleurs différentes : ils sont groupés deux par deux
pour leurs quatre couleurs communes ; le 0 et le 1 ensemble, les 2 et 3, 4 et 5, 6 et 7.
- Les registres de couleurs utilisés sont les registres 16 à 31 (seize registres soit quatre pour les quatre
couples de sprites). Pour chaque couple de sprites, la couleur transparente est donnée par le premier
registre de couleur du couple, soit respectivement les n°16, 20, 24 et 28.
- Ces seize registres de couleurs peuvent être utilisés dans le cas d'un écran de cinq plans de bits, c'est-à-dire,
si vous dessinez en 32 couleurs. Mais vos sprites devront donc utiliser seize couleurs déjà présentes dans
l'écran.
- La position d'un sprite est quelconque : il peut se trouver n'importe où dans l'écran ou invisible en dehors.
- La forme du sprite est définie par deux plans de bits. Comme la largeur est de seize pixels, une ligne du
sprite est donnée par deux entiers courts, soit deux fois seize bits. La juxtaposition des bits de même rang
de ces deux entiers donne sur deux bits (de 0 à 3) le numéro du registre de couleur de ce sprite pour un pixel.
Confus ? Non, relisez bien et n'oubliez pas : un Petit Gervais, ça compte autant qu'un steak.
Manipulation des sprites
Elle se fait à l'aide de quelques fonctions de la graphics.library, que vous retrouverez dans le petit programme
qui suit. Ces fonctions sont GetSprite, ChangeSprite, MoveSprite et FreeSprite, donc peu nombreuses et relativement
simples à utiliser.
GetSprite
Pour des raisons dont on parlera dans le prochain article,
vous ne pouvez pas utiliser d'emblée n'importe quel
sprite. Il faut le demander, s'il vous plaît, pour qu'il vous soit (peut-être) alloué.
numéro alloué = GetSprite(sprite,numéro_demandé);
|
La fonction prend comme paramètres un pointeur (sprite) sur une structure sprite, définie dans graphics/sprite.h et
le numéro du sprite que l'on désire adopter. Si ce numéro vaut -1, cela signifie que vous en demandez un quelconque.
Si vous avez une préférence, passez un entier compris entre 0 et 7. GetSprite retourne un entier :
-1 si aucun sprite n'a pu être alloué (ils sont tous déjà réservés), ou un nombre de 0 à 7 indiquant le numéro
du sprite qui a été attribué.
ChangeSprite
Cette fonction modifie la représentation d'un sprite à l'écran ; en particulier, elle le fait apparaître s'il
n'était pas encore activé.
ChangeSprite(ViewPort, sprite, données_image);
|
"ViewPort" représente un pointeur sur le ViewPort dans lequel est affiché le sprite et dont il
reprend les couleurs. "sprite" est toujours un pointeur sur la structure sprite.
"données_image" est un pointeur sur un tableau d'entiers courts contenant :
- Deux entiers courts initialisés à 0.
- Les données de l'image, soit deux fois plus d'entiers courts que le sprite a de lignes.
- Deux autres entiers courts aussi initialisés à 0.
Deux remarques importantes :
- La hauteur du sprite, définie dans la structure sprite, doit avoir été établie avant l'appel de cette fonction.
- Le tableau contenant les données de l'image doit se trouver dans la mémoire Chip, sous peine de voir s'afficher
des tas de grigris au lieu de votre beau sprite. Je rappelle que pour placer ces variables dans la mémoire
Chip, il y a plusieurs méthodes, mais la plus simple consiste généralement à préciser une option lors de l'édition
de liens (Chip pour le blink). La dilatation artificielle du circuit Agnus avec un chalumeau n'augmente pas sensiblement
la quantité de mémoire Chip, comme l'a prouvé une récente expérience menée dans les laboratoires de
recherche avancée de Thomson.
MoveSprite
Quoi de plus anodin que cette fonction ? C'est pourtant elle qui permet de déplacer un sprite. Sur le modèle suivant :
MoveSprite(ViewPort, sprite, x, y);
|
"ViewPort" est toujours le ViewPort de l'écran où est affiché le sprite.
"sprite" est indubitablement l'indéracinable pointeur sur l'inébranlable structure sprite.
Quant au duo de choc, "x" et "y", ce sont à coup sûr les nouvelles coordonnées du sprite,
qui peuvent sans aucun problème se trouver hors de l'écran. Dans ce cas, le sprite n'apparaîtra
pas : aucun intérêt, mais ça ne fait pas planter la machine, alors ça mérite d'être signalé.
FreeSprite
Nous en terminons avec cette fonction, alors que s'approche l'heure de ma piqûre.
Tel le barbouze moyen, elle liquide tout ce qui bouge en restituant le sprite alloué par GetSprite.
FreeSprite(numéro_de_sprite);
|
"numéro_de_sprite" est le numéro du sprite à libérer, donc compris entre 0 et 7.
Je souhaite, dans votre intérêt, qu'il s'agisse d'un sprite déjà alloué, sinon...
Mode d'emploi du programme d'exemple
Ultra-simple, une fois le programme lancé, le sprite apparaît, gigote un peu pour montrer qu'il sait
bouger. Quand il a surmonté sa décharge d'adrénaline, cliquez sur l'icône de fermeture de la fenêtre
pour en finir définitivement avec lui (pour Patrick Sabatier, c'est un peu plus compliqué mais j'y travaille).
Voilà. Amusez-vous bien avec vos petits sprites. Le mois prochain, si j'ai réussi à m'échapper de mon
asile, je vous parlerai de la Rolls des sprites, les sprites virtuels ou VSprites.
|