Le dialecte DRAW

Article paru dans le magazine Login numéro 89

Reproduction interdite. Tous droits réservés à Posse Press et Olivier Auverlot


Continuons notre exploration de la programmation graphique avec Rebol/View. Ce mois-ci, nous allons découvrir les fonctions de dessin permettant d'afficher des formes géométriques. Celles-ci constituent en fait un dialecte nommé DRAW qui est intégré dans l'attribut EFFECT de chaque style de composant graphique. Cela peut paraître troublant ou compliqué mais c'est surtout incroyablement puissant.

Dessinons des lignes

Le dialecte DRAW fait partie du VID en tant que sous-dialecte. Vous ne pouvez l'utiliser qu'en l'intégrant dans l'attribut EFFECT d'un style. Contrairement au VID, l'ordre des paramètres n'est pas quelconque : toute substitution ou inversion d'un attribut génére une erreur ou provoque la non exécution du code DRAW. Vous pouvez placer des instructions DRAW dans chaque style : vous pouvez ainsi dessiner sur un bouton ou sur une image. En général, le style le plus pratique est BOX car il constitue une excellente surface de dessin pouvant être dotée d'un timer. Grâce à lui, la réalisation d'animations est grandement facilitée.

La couleur de tracé est définie par l'instruction PEN suivi du nom de la couleur ou de son code RGB (3 octets représentant le rouge, le vert et le bleu). Pour placer un point ou tracer une ligne, vous disposez de l'instruction LINE suivie de deux coordonnées de type PAIR! pour les positions de départ et d'arrivée. L'axe des coordonnées est de type cartésien et son origine se trouve classiquement placé en haut à gauche.

L'instruction LINE-PATTERN permet de fixer l'apparence d'une ligne utilisant des pointillés. Pour cela, vous disposez d'un maximum de huit couples de valeurs entières représentant chacun le nombre de points affichés et le nombre de points ignorés.

view layout [
	box 100x100 effect [
		draw [
			pen white
			line 0x0 100x100
			line-pattern 2 4 10 5
			line 0x100 100x0
		]
	]
]


Deux styles de lignes différents.

Les autres fonctions de dessin

Vous disposez d'un ensemble complet d'instructions de dessin. Vous pouvez dessiner un carré à l'aide de BOX suivi de deux coordonnées de type PAIR!. La commande CIRCLE dessine un cercle défini par son centre et son rayon. L'instruction FLOOD remplit un espace à partir d'une position donnée jusqu'à rencontrer des points de la couleur spécifiée.

POLYGON est une instruction puissante destinée à tracer des droites entre les différentes coordonnées indiquées, la forme géométrique est ensuite fermée en joignant le dernier et premier point. Les passionnés des formes 3D vont probablement apprécier la présence de l'instruction FILL-PEN permettant de fixer la couleur de remplissage des formes géométriques (la valeur NONE correspond à l'absence de remplissage).

view layout [
	box 300x200 effect [
		draw [
			pen white
			box 10x10 100x100
			circle 150x50 30
			polygon 200x10 290x60 270x90 210x110
			fill-pen red
			circle 150x140 40
			box 20x140 100x190
			fill-pen blue
			flood 50x160 white					
		]
	]
]

Utilisation des principales fonctions de dessin.

 

Ajouter du texte

L'instruction TEXT permet d'afficher une chaîne de caractères à la coordonnée spécifiée. La couleur du texte est fixée par l'instruction PEN. Il est ainsi très simple de réaliser des effets spéciaux tels que l'ombrage du texte :

view layout [
	box 200x100 effect [
		draw [
			pen white
			line 0x0 200x100
			line 0x100 200x0
			pen black
			text 2x42 "Texte ajouté avec DRAW"
			pen red
			text 0x40 "Texte ajouté avec DRAW"
		]
	]
]

Draw permet d'afficher du texte.

La manipulation des images

Dans une zone de dessin, vous pouvez également afficher des images de type BMP, GIF, JPEG et PNG à l'aide de l'instruction IMAGE. Celle-ci reçoit en paramètres la position de départ, un mot contenant l'image elle-même et éventuellement une couleur de transparence sous la forme d'une valeur RGB.


img-tux: load %tux.bmp
monstre: load %monstre.bmp

view layout [
	box 170x180 effect [
		draw [
			image 0x0 img-tux			
			image 30x96 monstre 0.0.255
		]
	]
]

Affichage d'un sprite sur une image.

Cette gestion des images vous permet de mettre en place très simplement des sprites, c'est à dire des formes animées qui se déplacent sur l'écran en se superposant au décor. Cette fonctionnalité est bien sûr très pratique dans le domaine du jeu vidéo !

Génération d'un fichier graphique

Lorsque vous avez terminé votre dessin, vous pouvez générer une image à partir de celui-ci. Cette image peut rester en mémoire et être utilisée de la même manière que les autres images (application d'effets, affichage, affectation à un style, etc.) mais aussi être sauvegardée sur votre disque dur dans les deux formats que sont le PNG et le BMP. Il suffit pour cela d'utiliser le mot SAVE avec le raffinement adéquat (/BMP ou /PNG) et de convertir la zone de dessin en une donnée de type IMAGE!. Vous obtenez alors un fichier graphique lisible par d'autres logiciels.

view layout [
	boite: box 100x100 effect [
		draw [
			pen white
			line 0x0 100x100
			line 0x100 100x0
		]
	]
	button "sauver" [ save/png %test.png (make image! boite) ]
]

Deux lignes tracées dans un style BOX.

Manipulation dynamique de DRAW

Jusqu'à maintenant, les exemples présentés ont été très statiques. Vous devez probablement vous poser certaines questions : comment faire pour représenter une série de chiffres sous la forme d'un graphique ou encore, comment faire déplacer un sprite sur une zone de dessin ? Pas de panique ! VID et DRAW se montrent ici encore d'une souplesse exemplaire.

En fait, les instructions de DRAW ne sont qu'un bloc de données. Si vous voulez "générer dynamiquement" des instructions de dessin, il suffit de modifier le contenu du bloc EFFECT/DRAW du style les contenant.

Pour mieux comprendre, nous allons dessiner un histogramme à partir d'une série de nombres. Ceux-ci sont contenus dans une série et représentent la hauteur en pixels de chaque rectangle.

nombres: [ 100 130 80 110 50 90 ]

Lorsque l'utilisateur clique sur le bouton "Tracer", le script initialise le bloc GRAPH/EFFECT/DRAW avec la couleur de dessin et les deux axes (ordonnée et abscisse). Puis, une boucle FOREACH lit chaque valeur et calcule les coordonnées du rectangle représentant la donnée. A chaque passage dans la boucle, on ajoute des instructions BOX dans le bloc GRAPH/EFFECT/DRAW. Une fois l'opération terminée, il ne reste plus qu'à raffraîchir l'affichage du style nommé GRAPH : l'histogramme apparaît alors à l'écran.


view layout [
	graph: box 200x200 effect [ draw [] ]
	button "Tracer" [
		pos-dep: 10x190
		graph/effect/draw: copy [ 
			pen white 
			line 5x0 5x200
			line 0x190 200x190
		]
		foreach valeur nombres [
			pos-fin: pos-dep + make pair! reduce [ 20 (valeur * -1) ]
			append graph/effect/draw reduce [ 'box pos-dep pos-fin ]
			pos-dep: pos-dep + 20x0
		] 
		show graph
	]
]
L'histogramme est généré dynamiquement.

Un peu d'animation

A l'aide du dialecte DRAW, il est possible de réaliser des animations d'excellente qualité. L'une des raisons à cela est que Rebol utilise un écran logique pour construire l'affichage. La recopie vers l'écran physique est réalisée par l'instruction SHOW. Il n'y a donc pas de clignotements. De plus, VID offre au programmeur des timers qui permettent de mettre en place des repères temporels. Grâce à eux, vous pouvez par exemple animer un sprite tous les 5 dixièmes de secondes. Ceci permet d'obtenir une vitesse d'animation identique quelque soit la puissance de la machine utilisée.

Dans VID, la plupart des styles ont leur propre timer intégré et indépendant des autres. Il suffit de modifier l'attribut RATE en lui spécifiant le délai d'activation ou le nombre de déclenchements par seconde. L'exemple qui suit affiche des lignes aléatoires dix fois par seconde :

view layout [
	boite: box 200x200 rate 10 effect [ draw [] ] feel [
		engage: func [ f a e ] [
			if a = 'time [
				append boite/effect/draw reduce [
					'pen (random 255.255.255)
					'line (random 200x200) (random 200x200) 
				]			
				show boite
			]
		]
	]
]


Animation à partir de lignes aléatoires.

Comme vous pouvez le constater, vous devez ici mettre en place une gestion d'événements avec l'attribut FEEL pour détecter un événement de type TIME. Cet aspect de la programmation avec VID sera d'ailleurs le sujet du prochain article dans Login. Nous détaillerons les principaux événements ainsi que les différentes méthodes pour les intercepter. Vous aurez alors tous les éléments nécessaires à la réalisation d'applications graphiques complexes avec Rebol/View.

Retour