Obligement - L'Amiga au maximum

Dimanche 24 juin 2018 - 16:34  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles in other languages


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


Jeux Amiga

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


Trucs et astuces

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


Glossaire

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


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


Programmation : GFA Basic - Initiation aux graphismes
(Article écrit par Max et extrait d'Amiga News Tech - avril 1989)


Puisque ce numéro 11 de Commodore Revue est l'occasion d'un super-concours concernant le GFA Basic, il nous a semblé judicieux de vous présenter un peu mieux ce nouveau langage, afin que les petits nouveaux ne soient pas trop découragés dès le départ.

Attention toutefois, ceci n'est pas, mais alors là pas du tout une initiation au GFA Basic en général. Encore une fois, cet article et ceux qui vont suivre, se placent dans le cadre du concours ci-dessus mentionné ; le but recherché est de montrer, à partir de moultes explications et quelques exemples simples mais concrets, comment utiliser le GFA Basic pour faire du graphisme, de l'animation, de la musique et des bruitages, bases essentielles de tout jeu. Ce sera également l'occasion de présenter quelques utilitaires pouvant vous aider à concrétiser votre projet. Ainsi, tout le monde part avec des chances égales.

Graphisme en GFA

Voilà qui aurait pu être le titre d'un livre... D'ailleurs, c'est le titre d'un livre, mais pas sur Amiga. Bon, passons. Dans ce premier chapitre, nous allons rapidement voir les fonctions que le GFA Basic met à notre disposition pour faire du graphisme (l'animation viendra juste après).

Pour fixer les couleurs, nous avons tout d'abord l'instruction SETCOLOR. Il en existe deux variantes : SETCOLOR registre, rouge, vert, bleu fixe la proportion des couleurs (RVB pour les intimes) pour le registre de couleur numéro "registre". L'intensité de RVB est fixée d'après une échelle allant de 0 (très faible) à 15 (très forte). SETCOLOR registre, valeur donne au registre de couleur numéro "registre" la valeur "valeur" (merci, m'sieur Lapalisse). Le paramètre "valeur" est calculé comme suit : (rouge*512) + (vert*16) + bleu. Étant donné que chaque écran peut avoir sa propre palette, l'instruction SETCOLOR n'agit que sur l'écran en cours.

Pour déterminer la couleur avec laquelle on va écrire un texte à l'écran (un score, etc.), il faut utiliser l'instruction COLOR, suivie de trois paramètres : COLOR caracteres, fond, bord. Le paramètre "caracteres" fixe la couleur d'écriture des caractères, "fond" la couleur du fond (représenté uniquement en mode GRAPHMODE 1 - voir plus loin), et "bord" celle de la bordure des figures remplies (PBOX, PCIRCLE, PELLIPSE et POLYFILL - voir aussi plus loin).

Nous pouvons maintenant tracer des points et des lignes ; les instructions PLOT, LINE, et DRAW vont nous y aider. PLOT x,y place un point aux coordonnées "x" et "y" spécifiées, dans la couleur définie par COLOR. LINE x1, y1, x2, y2 dessine une ligne du point (x1, y1) au point (x2, y2), toujours dans la couleur définie par COLOR. Enfin, DRAW x1, y1 TO x2, y2 TO x3, y3 TO... trace une série de droites des points (x1, y1) à (x2, y2), puis de (x2, y2) à (x3, y3), etc., encore une fois dans la couleur définie par COLOR.

Le nombre de couples coordonnées possibles n'est limité que par la longueur d'une ligne dans l'éditeur (255 caractères). Notez que DRAW x, y est équivalent à PLOT x,y alors que DRAW TO x, y trace une ligne du dernier point tracé à celui de coordonnées (x, y). Enfin, DRAW x1, y1 TO x2, y2 équivaut à LINE x1, y1, x2, y2, mais dans ce dernier cas, je vous conseille d'utiliser LINE, sa mise en oeuvre étant plus rapide (l'éditeur sait en effet combien de paramètres il doit trouver après l'instruction LINE, ce qui n'est pas le cas avec DRAW). Pour les amoureux du LOGO, une variante de DRAW permet d'utiliser une sorte de macro-langage, mais elle n'est pas du tout adaptée à un jeu.

Quant à tester la couleur d'un point d'écran donné, c'est très simple avec la fonction POINT(x, y).

Rien qu'avec cela, vous devriez déjà pouvoir faire un clone de Quix... Comment ? Ça ne vous suffit pas ? Qu'à cela ne tienne, passons aux figures géométriques.

GFA Basic sait dessiner tout seul, pour peu qu'on le lui demande, quand même, faut pas exagérer, quelques-unes des figures géométriques de base, à savoir le carré (en règle générale, le parallélogramme quelconque), le cercle et l'ellipse :
  • BOX x1, y1, x2, y2 dessine un parallélogramme dont les sommets haut-gauche et bas-droit ont pour coordonnées (x1, y1) et (x2, y2).
  • CIRCLE x, y, c trace un cercle de centre (x, y) et de rayon "r".
  • ELLIPSE x, y, rx, ry trace une ellipse de centre (c, y), de rayon horizontal "rx" et de rayon vertical "ry".
Chacune de ces commandes trace une figure vide, c'est-à-dire justement son contour. Pour obtenir une figure pleine, il faut ajouter un "P" devant le nom de la commande, afin d'obtenir PBOX, PCIRCLE et PELLIPSE. Les paramètres sont bien entendu identiques.

Maintenant, il est possible que vous désiriez dessiner des polygones quelconques. Cela est réalisable en GFA Basic grâce aux commandes POLYLINE et POLYFILL :
  • POLYLINE n, x(), y() trace un polygone vide de "n" côté, dont les sommets sont définis dans les tableaux x() et y(). Le premier sommet a pour coordonnées (x(0), y(0)), le dernier (x(n-1), y(n-1)). Le premier et le dernier sommets sont automatiquement reliés entre eux.
  • POLYFILL n, x(), y() agit de même, mais en remplissant le polygone ainsi dessiné. Tout ceci rappellera sans nul doute quelque chose aux habitués de l'instruction AREA de l'AmigaBasic...
Dans tous les cas de figures pleines, l'instruction BOUNDARY 0 empêche le dessin du cadre, alors que BOUNDARY 1 l'autorise. Il est possible de définir le style des lignes employées pour dessiner le contour des figures, grâce à l'instruction DEFLINE. Cette instruction est suivie d'un paramètre dont les 16 bits déterminent l'aspect de la ligne : un bit positionné correspond à un point tracé. Reste maintenant à remplir une surface quelconque. L'instruction FILL est là pour ça.

FILL x, y opère donc une opération de remplissage d'une surface, à partir du point de coordonnées (x, y) spécifié. Un troisième paramètre permet de définir une couleur de délimitation du remplissage (couleur donc, qui ne sera pas affectée par l'opération, alors que les autres, si).

Chouette ! On peut commencer à dessiner quelques trucs mignons, surtout que la rapidité du GFA d'une part, et celle du Blitter d'autre part, autorisent, même avec ces commandes simples, quelques effets spéciaux amusants... Oui mais voilà, toutes les figures remplies sont uniformes et de la même couleur. Ne peut-on rien y faire ? Bien sûr que si, l'instruction DEFFILL n'a pas été implémentée pour rien. Il en existe même deux variantes : DEFFILL couleur, style, motif force le remplissage (avec PBOX, PCIRCLE, PELLIPSE, POLYFILL et FILL) avec la couleur "couleur", le style "style" et le motif "motif". "couleur" indique un numéro de registre de couleur et "type" peut prendre les valeurs suivantes :
  • 0 = vide.
  • 1 = rempli.
  • 2 = pointillé.
  • 3 = hachuré.
"motif", quant à lui, permet de choisir entre l'un des 24 motifs de points ou l'un des 12 motifs de ligne prédéfinis. Avec la seconde variante de DEFFILL, on peut même définir soi-même le motif de remplissage : DEFFILL couleur, motif$ où le rôle de "couleur" ne change pas et où la chaîne de caractères "motif$" contient le motif de bits désiré.

En informatique, et plus particulièrement en dessin sur ordinateur, il existe plusieurs modes de tracés de points. L'Amiga n'échappe pas à la règle (il aurait du mal) et propose quatre modes distincts : JAM1 (transparent), JAM2 (remplacer), COMPLEMENT (xor) et INVERSVID (inversion vidéo). Le mode peut être choisi grâce à l'instruction GRAPHMODE, suivie d'un nombre de 0 à 4 indiquant le mode choisi.

Pour écrire du texte à l'écran, on peut utiliser l'instruction PRINT. C'est bien, mais elle possède un défaut majeur : on ne peut pas placer le texte au pixel près à l'écran. Pour ce faire, il faut passer par l'instruction TEXT : TEXT x, y, texte$ affichera la chaîne de caractères "texte$" à la position graphique (x, y).

Une fonction sympathique, lorsqu'on désire n'afficher du graphisme que dans une fenêtre d'écran donnée (par fenêtre, entendez "section" d'écran ; il ne s'agit pas des fenêtres d'Intuition) est CLIP. Le "clipping" est une technique permettant de limiter les sorties graphiques à une zone rectangulaire de l'écran. Il faut indiquer comme paramètre à l'instruction CLIP les coordonnées des coins haut-gauche et bas-droit du rectangle de clipping : CLIP x1, y1 TO x2, y2.

Ceux qui préfèrent spécifier la hauteur et la largeur du rectangle de clipping peuvent le faire avec : CLIP x, y, larg, haut. Le clipping est désactivé (c'est-à-dire que les sorties graphiques se feront à nouveau sur la totalité de l'écran courant, grâce à CLIP OFF).

Finissons en beauté ce tour d'horizon des instructions graphiques avec PUT, GET, DISPLAY et VSYNC. PUT et GET permettent respectivement de capturer dans une chaîne de caractères, des sections rectangulaires d'écran et de les replacer par la suite. Leur syntaxe est : GET x1, y1, x2, y2, portion$ et PUT x3, y3, portion$, mode.

Là encore, (x1, y1) et (x2, y2) sont les coordonnées des coins opposés en diagonale du rectangle à capturer dans la chaîne "portion$", tandis que (x3, y3) indique les coordonnées où déposer cette même chaîne "portion$". Le paramètre "mode", facultatif, indique la combinaison logique de bits à appliquer dans la source (portion$) et la destination (le dessin présent à l'écran).

DISPLAY OFF permet de suspendre provisoirement l'affichage de l'image, en désactivant le DMA. Cela permet de dessiner et de n'afficher le résultat, qu'une fois le travail terminé. DISPLAY ON, au contraire, réactive le DMA et donc l'affichage. Enfin, VSYNC permet d'attendre le retour du faisceau vertical servant à la représentation sur le moniteur de l'écran. En d'autres termes, VSYNC permet de synchroniser la construction de l'écran, et d'éviter ainsi, de désagréables parasites lors d'animations avec PUT et GET.

Animation en GFA

Cela aussi pourrait être le titre d'un livre... Bon, tout ce qu'on vient de voir est bien joli, mais ce n'est pas avec cela que vous allez faire le shoot'em up du siècle, genre Hybris en mieux. Il faut maintenant commencer à utiliser les sprites et les BOB.

GFA Basic dispose de l'instruction SPRITE, qui permet de gérer les sprites du matériel. Si l'Amiga dispose de 8 sprites, le GFA ne permet d'en gérer que 7, le premier, de numéro 0, étant réservé au pointeur de la souris. Un sprite a obligatoirement une largeur de 16 pixels, mais sa hauteur peut être quelconque et il ne peut avoir que quatre couleurs. Avant d'utiliser un sprite, il faut définir son aspect. Ceci se fera par la commande SPRITE n, s$ où "n" est le numéro du sprite à définir et "s$" la chaîne de caractères contenant sa définition. Si vous n'avez plus besoin d'un sprite particulier, vous pouvez l'effacer de la mémoire simplement en spécifiant pour "s$" une chaîne vide (s$ = «»).

Pour déplacer un sprite, il faudra utiliser la commande SPRITE n, x, y qui a pour effet d'effacer le sprite de sa position actuelle pour le réafficher à la position (x, y).

Enfin, SPRITE OFF désactive tous les sprites en cours, y compris le pointeur de souris, tandis que SPRITE ON les réactive à nouveau.

Notez quand même que les sprites ne sont pas souvent utilisés dans les jeux, les programmeurs donnant la préférence aux BOB, que justement, ça tombe bien, voici venir.

BOB

Le moins que l'on puisse dire, c'est que le manuel d'utilisation du GFA Basic Amiga est plutôt avare en renseignements sur les BOB... Voici qui, j'espère, comblera ce manque. Un BOB (Blitter OBject) est une forme particulière de sprites, gérés par le Blitter. Leur nombre est limité à 32 767, ce qui, dans la plupart des cas, suffira amplement ! Toute une série d'instructions, empruntées il est vrai à l'AmigaBasic, existe dans le GFA Basic pour les gérer efficacement.

Comme pour les sprites, il convient de commencer par définir la forme du (des) BOB. Cela se fait très simplement grâce à la commande OBJECT.SHAPE bob, def$ où "bob" représente le numéro du BOB à définir et "def$" sa chaîne de définition (utiliser pour cela le programme IFF_TO_BOB.GFA fourni sur la disquette originale du GFA Basic). On peut également utiliser cette commande d'une autre manière : OBJECT.SHAPE bob 1, bob2 et copier ainsi la définition du BOB numéro "bob1" dans celui de numéro "bob2".

Cela suffit-il pour animer un ou plusieurs BOB à l'écran ? Malheureusement non, car il convient encore de régler tout un tas de paramètres pour chaque BOB défini. Premièrement, il faut définir la priorité des BOB, c'est-à-dire un ordre dans lequel les différents BOB seront dessinés : OBJECT.PRIORITY bob, prior où "bob" est le numéro du BOB concerné, et "prior" sa priorité, comprise entre 0 et 32 767. Les BOB, de priorité plus élevée, seront dessinés en premier, donc sous ceux de priorité plus faible.

Il faut également déterminer dans quel plan de bits, c'est-à-dire dans quelle(s) couleur(s) chaque BOB sera dessiné, et si les plans de bits non utilisés devront être effacés ou laissés tels quels. Cela se fait avec la commande OBJECT.PLANES bob, PlanePick, Plane0nOff où "bob", encore une fois, représente le numéro du BOB concerné.

PlanePick et PlaneOnOff (ce sont les noms donnés par Commodore à ces variables) sont un peu plus difficiles à mettre en oeuvre. Vous avez déjà certainement entendu dire que l'image que vous voyez sur votre moniteur est composée, en mémoire, de plans de bits. Le principe est que plusieurs bits sont nécessaires pour définir la couleur d'un point. Plus le nombre de plans de bits (on dit aussi la profondeur) utilisés est grand, plus on peut avoir de couleurs simultanément à l'écran (jusqu'à 5 plans, soit 32 couleurs), mais plus on consomme de mémoire. Le Blitter, processeur graphique de l'Amiga, permet d'afficher des BOB ayant une profondeur inférieure à celle de l'écran. Dans ce cas, il faudra déterminer quels plans de bits du BOB seront écrits dans quels plans de bits de l'écran. C'est à cela que servent les valeurs PlanePick et PlaneOnOff.

Ces valeurs peuvent être calculées avec la formule suivante : Plane = b1 + (2 * b2) + (4 * b3) + (8 * b4) + (16 * b5) où b1 à b5 représentent les numéros des cinq plans de bits possibles. Si un plan doit être utilisé par le BOB, mettre son numéro, dans la formule ci-dessus, à 1 et, à 0, dans le cas contraire. On obtient ainsi la valeur de PlanePick. On utilise la même formule pour calculer PlaneOnOff, à ceci près qu'il faut ici définir quoi faire des plans de bits de l'écran non utilisés par PlanePick : les effacer (remplacer dans la formule leur numéro par 0) ou les laisser tels quels (remplacer leur numéro par 1).

Maintenant que le Blitter sait à quoi nos objets ressemblent, dans quel ordre et de quelle manière les afficher, il faut lui dire comment il devra les déplacer, c'est-à-dire, principalement, définir leur vitesse. Il existe deux sortes de vitesses possibles, qu'il faut définir toutes les deux. La première concerne l'accélération au démarrage du BOB (un peu comme une voiture qui monte de 0 à 100), la seconde son déplacement effectif (sa vitesse de croisière). On utilise pour cela les commandes : OBJECT.AX bob, accel, OBJECT.AY bob, accel, OBJECT.VX bob, vitess et OBJECT.VY bob, vitess.

Comme vous le voyez, on peut définir des vitesses différentes pour l'axe des X et celui des Y. Le paramètre "bob" est, ça devient une habitude, le numéro du BOB concerné, tandis que "accel" et "vitess" sont exprimés en pixels/seconde (on n'arrête pas le progrès).

On a presque terminé, on peut maintenant afficher notre (nos) BOB(s). Cela se fait avec la commande OBJETC.ON bob1, bob2, bob3,.... Si aucun paramètre ne suit OBJECT.START, ce sont tous les BOB définis qui seront affichés... mais pas encore animés. Il nous faut pour cela utiliser la commande OBJECT.START bob1, bob2, bob3,... mis en mouvement ; le Blitter les anime tout seul, comme un grand, il n'y a plus qu'à le regarder faire. On arrêtera le mouvement avec OBJECT.STOP bob1, bob2, bob3,....

La même remarque que précédemment est valable quant à l'absence de paramètres derrière cette commande. Mais si l'on préfère déplacer soi-même un ou plusieurs BOB, en indiquant au fur et à mesure ses coordonnées, cela peut se faire avec OBJECT.X bob, x et OBJEXT.Y bob, y qui ira placer le BOB de numéro "bob" aux coordonnées "x" et "y" spécifiées.

Pour effacer temporairement de l'écran un ou plusieurs BOB, on utilisera judicieusement la commande OBJECT.OFF bob1, bob2, bob3,... tandis que la commande OBJECT.CLOSE bob1, bob2, bob3,... effacera définitivement un ou plusieurs BOB de la mémoire.

Reste la commande OBJECT.CLIP x1, y1, x2, y2 qui, tout comme son quasi-homologue vu plus haut, permet de définir un rectangle de clipping duquel les BOB ne pourront sortir, quitte à être "tronqués" avant d'être affichés. Cette commande affecte tous les BOB en place et est réglé sur l'écran entier par défaut.

Enfin, et puisqu'il faut bien que tout ait une fin, même cette suite interminable de OBJECT.xxxxx, le GFA Basic permet de détecter les collisions de BOB entre eux. La commande ON COLLISION GOSUB procedure permet en effet de se brancher sur la procédure de nom "procedure" en cas de collision entre deux BOB. C'est ensuite au programme de décider, au sein de cette collision, de la marche à suivre, en interrogeant le tableau COLLISION() : COLLISION(0) indique quel est le BOB responsable de la collision, tandis que COLLISION(COLLISION(0)) indique le BOB partenaire du carambolage. Si cette valeur est inférieure à 0, c'est que le BOB est entré en conflit, soit avec le bord de l'écran, soit avec le rectangle de clipping définit par OBJECT.CLIP. En ce cas, une valeur de -1 indique que c'est en haut de l'écran qu'à eu lieu la collision, -2 indique la gauche, -3 le bas et -4 la droite.

Les habitués de l'AmigaBasic regretteront certainement l'absence des instructions COLLISION ON, COLLISION OFF et COLLISION STOP.

Ouuuuufff !

Eh bien ma foi, tout cela est plutôt dur à digérer d'un seul coup... Pour mieux illuster l'animation des BOB, un petit programme suit cet exposé ma foi bien touffu. Décortiquez-le dans tous les sens et modifiez-le à loisir, c'est encore le meilleur moyen d'apprendre et de comprendre. Comme dit la sagesse populaire : "c'est en se mouchant qu'on devient moucheron..."

GFA Basic


[Retour en haut] / [Retour aux articles]