La géométrie dans Flash

Utilisation de la géométrie en ActionScript 3 (AS3)

Le but de cet article est d'étudier les différentes fonctionnalités en rapport avec la géométrie dans Flash.
Le package flash.geom contient des classes qui définissent des objets géométriques, tels que des points, des rectangles et des matrices de transformation. Ces classes ne fournissent pas nécessairement de fonctionnalité par elles-mêmes ; néanmoins, elles sont utilisées pour définir les propriétés des objets utilisés dans d'autres classes.

Toutes les classes de géométrie se basent sur la notion selon laquelle les emplacements à l'écran sont représentés comme un plan en deux dimensions. L'écran est traité comme un graphique plat avec un axe horizontal (x) et un axe vertical (y). Tout emplacement (ou point) à l'écran peut être représenté sous la forme d'une paire de valeurs x et y, appelées coordonnées de cet emplacement.

Le point d'origine, coordonnées 0, 0, de la scène de travail est le coin haut gauche de la séquence.

image11.png

Les valeurs sur l'axe x augmentent en allant vers la droite et diminuent en allant vers la gauche. Néanmoins, contrairement aux systèmes de coordonnées classiques, dans ActionScript, les valeurs sur l'axe y augmentent en allant vers le bas et diminuent en allant vers le haut de l'écran.

Utilisation de la classe Point

Un objet Point définit une paire de coordonnées cartésiennes. Il représente un emplacement dans un système de coordonnées à deux dimensions, dans lequel x est l'axe horizontal et y l'axe vertical.

Le constructeur de la classe Point prend en paramètres la valeur de la coordonnée x et la valeur de la coordonnée y.

Actionscript:
  1. var point1:Point = new Point(20, 60);

On rencontre très souvent des scripts dans lesquels nous avons besoin de mémoriser les coordonnées de départ d'un objet d'affichage. Classiquement, les développeurs vont créés 2 variables numériques et stocker les valeurs d'origine de notre objet.

Il pourrait être plus judicieux de mémoriser ces coordonnées dans un seul objet, un objet de type Point.

Les coordonnées sont ensuite accessibles avec les propriétés x et y de la classe Point.

Actionscript:
  1. var origineCarreBleu:Point = new Point(carreBleu.x, carreBleu.y);//coordonnées d'origine du carré bleu
  2. trace(origineCarreBleu.x, origineCarreBleu.y);

Calculer la distance entre 2 points

La méthode distance() de la classe Point va nous permettre de calculer la distance entre 2 points dans un espace de coordonnées. Cette méthode est une méthode statique, c'est-à-dire que c'est une méthode qui s'applique à la classe et non à une instance de classe.

Cette méthode attend 2 objets Point en paramètres et renvoie une valeur numérique.

Actionscript:
  1. //Distance entre le carre rouge et le carre vert
  2. var coordonneesRouge:Point = new Point(carreRouge.x, carreRouge.y); //coordonnées du carré rouge
  3. var coordonneesVert:Point = new Point(carreVert.x, carreVert.y); //coordonnées du carré vert
  4. var distanceRougeVert:Number = Point.distance(coordonneesRouge, coordonneesVert);
  5. trace(distanceRougeVert);

Le cas des espaces de coordonnées différents

Dans le cas où deux objets se trouvent dans deux conteneurs d'affichage différents, ils n'utiliseront pas le même espace de coordonnées. Nous devrons donc convertir les coordonnées locales en coordonnées globales en utilisant la méthode localToGlobal() de la classe DisplayObject.

Dans l'exemple suivant, nous allons créer 2 champs de texte, le premier sera ajouté à la scène et le second sera ajouté dans un conteneur Sprite. Le premier champ de texte sera donc dans l'espace de coordonnées global alors que le second sera lui dans l'espace de coordonnées local au Sprite.

Pour calculer la distance entre les 2 champs de texte, nous utiliserons la méthode localToGlobal() sur le 2ème champ de texte afin de convertir l'objet point des coordonnées de ce texte (locales) vers les coordonnées de la scène (globales).

Cette méthode attend en paramètres un objet Point correspondant aux coordonnées à convertir.

Actionscript:
  1. //Conversion de coordonnées locales en coordonnées globales
  2. var texte1:TextField = new TextField(); // 1er champ de texte
  3. texte1.text = "1er texte";
  4. addChild(texte1); // le texte est ajouté à la scène
  5. texte1.x = texte1.y = 50; // le texte est positionné aux coordonnées 50,50 par rapport à la scène
  6. var texte2:TextField = new TextField(); // 2ème champ de texte
  7. texte2.text = "2ème texte";
  8. var sprite:Sprite = new Sprite();// le conteneur du 2ème champ de texte
  9. sprite.addChild(texte2); // le texte 2 est ajouté dans le sprite
  10. addChild(sprite); // le conteneur est ajouté à la scène
  11. sprite.x = sprite.y = 200; //le conteneur est positionné aux coordonnées 200,200 par rapport à la scène
  12. var pointTexte1:Point = new Point(texte1.x, texte1.y); //Coordonnées globales du texte 1
  13. var pointTexte2:Point = new Point(texte2.x, texte2.y); //Coordonnées locales du texte 2 par rapport à son parent
  14. trace(pointTexte2.x, pointTexte2.y); //affichage de 0, 0
  15. pointTexte2 = texte2.localToGlobal(pointTexte2); //Conversion des coordonnées locales en coordonnées globales
  16. trace(pointTexte2.x, pointTexte2.y); //affichage de 200, 200
  17. var distanceTexte:Number = Point.distance(pointTexte1, pointTexte2);
  18. trace(distanceTexte);

Autres utilisations

La classe Point pourra être aussi utilisée dans les méthodes des classes suivantes :

  • DisplayObjectContainer
  • BitmapData
  • Matrix
  • Rectangle

Utilisation de la classe Rectangle

Un objet Rectangle définit une zone rectangulaire. Un objet Rectangle a une position définie par les coordonnées x et y de son angle supérieur gauche, une propriété width définissant sa largeur et une propriété height  définissant sa hauteur.

Le constructeur prend en paramètres ces 4 valeurs.

Actionscript:
  1. var zone1:Rectangle = new Rectangle(50, 50, 220, 110); //zone rectangulaire de 220 pixels de large, 110 pixels de haut, positionnée aux coordonnées 50, 50

Cas d'utilisation
Recouvrement de 2 objets

La méthode intersects() de la classe Rectangle va vous permettre de savoir si 2 rectangles se recouvrent. Cette méthode peut-être utilisée pour savoir si 2 objets d'affichage (clip, sprite, image...) se recouvrent.

En effet, la méthode getBounds() de la classe DisplayObject renvoie un objet de type Rectangle correspondant à la délimitation rectangulaire de l'objet d'affichage. En récupérant la délimitation de 2 objets, on peut ensuite savoir s'ils se recouvrent en utilisant la méthode intersects() de la classe DisplayObject.

La méthode intersects() renvoie un booléen (true ou false).

Nous allons utiliser ces méthodes avec trois carrés dont 2 (le bleu et le vert) qui se recouvrent.

image21.png

Actionscript:
  1. //Cas d'utilisation
  2. var delimitationBleu:Rectangle = carreBleu.getBounds(this); // delimitation rectangulaire du carré bleu
  3. trace(delimitationBleu.x, delimitationBleu.y, delimitationBleu.width, delimitationBleu.height);
  4. var delimitationRouge:Rectangle = carreRouge.getBounds(this); // delimitation rectangulaire du carré rouge
  5. trace("Est-ce que le carré bleu recouvre le carré rouge ? Réponse : " + delimitationBleu.intersects(delimitationRouge));
  6. var delimitationVert:Rectangle = carreVert.getBounds(this); // delimitation rectangulaire du carré vert
  7. trace("Est-ce que le carré bleu recouvre le carré vert? Réponse : " + delimitationBleu.intersects(delimitationVert));

Copie d'une zone d'une image

Les classes rectangle et Point sont aussi utilisées lors de la copie d'une zone d'une image. En effet, la méthode copyPixels() de la classe BitmapData prend notamment  en paramètres un objet Rectangle et un objet Point.

L'objet Rectangle correspond à la zone rectangulaire de pixels qui sera copiées. Cet objet Rectangle définira les coordonnées x et y du point d'origine de la copie par rapport à l'image initiale et la largeur et hauteur de la zone copiée.

L'objet Point correspond au point d'origine dans la copie à partir duquel seront copiés les pixels.

Actionscript:
  1. //Cas d'utilisation : copie de pixels
  2. var pixelsDisney:Disney = new Disney(300, 201); //La classe Disney correspond à la classe auto-générée depuis l'image cars.jpg de la bibliothèque
  3. var imageDisney:Bitmap = new Bitmap(pixelsDisney); // Objet d'affichage des pixels
  4. addChild(imageDisney); //affichage de l'image dans la scène
  5. var copiePixelsDisney:BitmapData = new BitmapData(142, 105); // objet de 142 pixels de large et de 105 pixels de hauteur dans lequel les pixels seront copiés
  6. var zoneImage:Rectangle = new Rectangle(158, 96, copiePixelsDisney.width, copiePixelsDisney.height); // Cette zone rectangulaire est une zone de 142 pixels de large, 105 pixels de haut et la copie des pixels sera effectué à partir des coordonnées 158, 96 par rapport au coin haut gauche de l'image.
  7. var pointCollage:Point = new Point(0,0); //Les pixels seront collés au point de coordonnées 0,0 de l'objet BitmapData
  8. copiePixelsDisney.copyPixels(pixelsDisney, zoneImage, pointCollage); //copie d'une zone de pixels.
  9. var newDisney:Bitmap = new Bitmap(copiePixelsDisney);// objet d'affichage de la copie des pixels
  10. newDisney.y = 220; //positionnement de la copie sous l'image d'origine
  11. addChild(newDisney); //affichage de la copie

Autres utilisations

La classe Rectangle pourra être aussi utilisée dans les méthodes des classes suivantes :

  • DisplayObject
  • BitmapData
  • PrintJob
  • Sprite
  • TextField
  • Transform