Exemple d’objet d’affichage : SpriteArranger

Flash Player 9 et les versions ultérieures, Adobe AIR 1.0 et les versions ultérieures

L’exemple d’application SpriteArranger est basé sur l’exemple d’application Geometric Shapes (voir Formation à ActionScript 3.0 ).

L’exemple SpriteArranger illustre divers concepts de gestion des objets d’affichage :

  • Extension des classes d’objet d’affichage

  • Ajout d’objets à la liste d’affichage

  • Superposition des objets d’affichage et utilisation des conteneurs d’objets d’affichage

  • Réponse aux événements d’objet d’affichage

  • Utilisation des propriétés et méthodes des objets d’affichage

Pour obtenir les fichiers d’application de cet exemple, voir www.adobe.com/go/learn_programmingAS3samples_flash_fr . Les fichiers d’application SpriteArranger résident dans le dossier Examples/SpriteArranger. L’application se compose des fichiers suivants :

Fichier

Description

SpriteArranger.mxml

ou

SpriteArranger.fla

Fichier d’application principal dans Flash (FLA) ou Flex (MXML).

com/example/programmingas3/SpriteArranger/CircleSprite.as

Classe définissant un type d’objet Sprite qui assure le rendu d’un cercle à l’écran.

com/example/programmingas3/SpriteArranger/DrawingCanvas.as

Classe définissant le rectangle de la zone de dessin, soit un conteneur d’objets d’affichage comportant des objets GeometricSprite.

com/example/programmingas3/SpriteArranger/SquareSprite.as

Classe définissant un type d’objet Sprite qui assure le rendu d’un carré à l’écran.

com/example/programmingas3/SpriteArranger/TriangleSprite.as

Classe définissant un type d’objet Sprite qui assure le rendu d’un triangle à l’écran.

com/example/programmingas3/SpriteArranger/GeometricSprite.as

Classe qui étend l’objet Sprite, utilisé pour définir une forme à l’écran. CircleSprite, SquareSprite et TriangleSprite étendent chacun cette classe.

com/example/programmingas3/geometricshapes/IGeometricShape.as

Interface de base qui définit les méthodes à implémenter par toutes les classes de formes géométriques.

com/example/programmingas3/geometricshapes/IPolygon.as

Interface qui définit les méthodes à implémenter par les classes de forme géométrique dotées de plusieurs côtés.

com/example/programmingas3/geometricshapes/RegularPolygon.as

Type de forme géométrique dont les côtés sont de longueur égale et positionnés symétriquement autour du centre de la forme.

com/example/programmingas3/geometricshapes/Circle.as

Type de forme géométrique qui définit un cercle.

com/example/programmingas3/geometricshapes/EquilateralTriangle.as

Sous-classe de RegularPolygon qui définit un triangle équilatéral.

com/example/programmingas3/geometricshapes/Square.as

Sous-classe de RegularPolygon qui définit un carré.

com/example/programmingas3/geometricshapes/GeometricShapeFactory.as

Classe qui contient une « méthode usine » permettant de créer des formes d’une taille et d’un type de forme donnés.

Définition des classes SpriteArranger

L’application SpriteArranger permet à l’utilisateur d’ajouter divers objets d’affichage au rectangle de la zone de dessin à l’écran.

La classe DrawingCanvas définit une zone de dessin, soit un type de conteneur d’objets d’affichage, à laquelle l’utilisateur peut ajouter des formes à l’écran. Ces formes sont des occurrences de l’une des sous-classes de la classe GeometricSprite.

Classe DrawingCanvas

Dans Flex, tous les objets d’affichage enfant ajoutés à un objet Container doivent appartenir à une classe issue de la classe mx.core.UIComponent. Cette application ajoute une occurrence de la classe DrawingCanvas en tant qu’enfant d’un objet mx.containers.VBox, ainsi que le définit le code MXML dans le fichier SpriteArranger.mxml. Cet héritage est défini dans la déclaration de classe DrawingCanvas, comme suit :

public class DrawingCanvas extends UIComponent

La classe UIComponent héritage des classes DisplayObject, DisplayObjectContainer et Sprite et le code de la classe DrawingCanvas utilise les méthodes et propriétés de ces dernières.

La classe DrawingCanvas étend la classe Sprite et cet héritage est défini dans la déclaration de classe DrawingCanvas, comme suit :

public class DrawingCanvas extends Sprite

La classe Sprite est une sous-classe des classes DisplayObjectContainer et DisplayObject et la classe DrawingCanvas utilise les méthodes et propriétés de ces dernières.

La méthode constructeur DrawingCanvas() définit un objet Rectangle, bounds , qui est une propriété utilisée ultérieurement lors du tracé du contour de la zone de dessin. Elle appelle ensuite la méthode initCanvas() , comme suit :

this.bounds = new Rectangle(0, 0, w, h); 
initCanvas(fillColor, lineColor);

Comme l’indique l’exemple suivant, la méthode initCanvas() définit diverses propriétés de l’objet DrawingCanvas, transmises en tant qu’arguments à la méthode constructeur :

this.lineColor = lineColor; 
this.fillColor = fillColor; 
this.width = 500; 
this.height = 200;

La méthode initCanvas() appelle ensuite la méthode drawBounds() qui trace le rectangle de la zone de dessin à l’aide de la propriété graphics de la classe DrawingCanvas. La propriété graphics est héritée de la classe Shape.

this.graphics.clear();         
this.graphics.lineStyle(1.0, this.lineColor, 1.0); 
this.graphics.beginFill(this.fillColor, 1.0); 
this.graphics.drawRect(bounds.left - 1,  
                        bounds.top - 1,  
                        bounds.width + 2, 
                        bounds.height + 2); 
this.graphics.endFill();

Les autres méthodes de la classe DrawingCanvas, indiquées ci-après, sont appelées en fonction des interactions de l’utilisateur avec l’application :

Classe GeometricSprite et ses sous-classes

Chaque objet d’affichage susceptible d’être ajouté par l’utilisateur au rectangle de la zone de dessin est une occurrence de l’une des sous-classes suivantes de la classe GeometricSprite :

  • CircleSprite

  • SquareSprite

  • TriangleSprite

La classe GeometricSprite étend la classe flash.display.Sprite :

public class GeometricSprite extends Sprite

La classe GeometricSprite comprend diverses propriétés communes à tous les objets GeometricSprite. Elles sont définies dans la fonction constructeur en fonction des paramètres transmis à cette dernière. Exemple :

this.size = size; 
this.lineColor = lColor; 
this.fillColor = fColor;

La propriété geometricShape de la classe GeometricSprite définit une interface IGeometricShape, qui stipule les propriétés mathématiques, mais non visuelles, de la forme. Les classes qui implémentent l’interface IGeometricShape sont définies dans l’exemple d’application GeometricShapes (voir Formation à ActionScript 3.0 ).

La classe GeometricSprite définit la méthode drawShape() , qui est affinée dans les définitions de remplacement de chaque sous-classe de GeometricSprite. Pour plus d’informations, voir ci-après « Ajout d’objets d’affichage au rectangle de la zone de dessin ».

La classe GeometricSprite propose également les méthodes suivantes :

Ajout d’objets d’affichage au rectangle de la zone de dessin

Lorsque l’utilisateur clique sur le bouton Add Shape, l’application appelle la méthode addShape() de la classe DrawingCanvas. Elle crée une occurrence de GeometricSprite en appelant la fonction constructeur appropriée de l’une des sous-classes de GeometricSprite, comme illustré dans l’exemple suivant :

public function addShape(shapeName:String, len:Number):void 
{ 
    var newShape:GeometricSprite; 
    switch (shapeName) 
    { 
        case "Triangle": 
            newShape = new TriangleSprite(len); 
            break; 
 
        case "Square": 
            newShape = new SquareSprite(len); 
            break; 
 
        case "Circle": 
            newShape = new CircleSprite(len); 
            break; 
    } 
    newShape.alpha = 0.8; 
    this.addChild(newShape); 
}

Chaque méthode constructeur appelle la méthode drawShape() , qui utilise la propriété graphics de la classe (héritée de la classe Sprite) pour dessiner le graphique vectoriel approprié. Par exemple, la méthode drawShape() de la classe CircleSprite comprend le code suivant :

this.graphics.clear(); 
this.graphics.lineStyle(1.0, this.lineColor, 1.0); 
this.graphics.beginFill(this.fillColor, 1.0); 
var radius:Number = this.size / 2; 
this.graphics.drawCircle(radius, radius, radius);

L’avant-dernière ligne de la fonction addShape() définit la propriété alpha de l’objet d’affichage (héritée de la classe DisplayObject), de sorte que chaque objet d’affichage ajouté au rectangle de la zone de dessin soit légèrement transparent, permettant ainsi à l’utilisateur de visualiser les objets placés derrière.

La derrière ligne de la méthode addChild() ajoute le nouvel objet d’affichage à la liste enfant de l’occurrence de la classe DrawingCanvas, qui figure déjà dans la liste d’affichage. Le nouvel objet d’affichage apparaît alors sur la scène.

L’interface de l’application comprend deux champs de texte, selectedSpriteTxt et outputTxt . Les propriétés de texte de ces champs sont mises à jour avec des informations relatives aux objets GeometricSprite ajoutés au rectangle de la zone de dessin ou sélectionnés par l’utilisateur. La classe GeometricSprite gère ces tâches de transmission d’informations en annulant la méthode toString() comme suit :

public override function toString():String 
{ 
    return this.shapeType + " of size " + this.size + " at " + this.x + ", " + this.y; 
}

La propriété shapeType est définie sur la valeur appropriée de la méthode constructeur de chaque sous-classe GeometricSprite. La méthode toString() pourrait par exemple renvoyer la valeur suivante pour une occurrence de CircleSprite récemment ajoutée à l’occurrence de DrawingCanvas :

Circle of size 50 at 0, 0

La méthode describeChildren() de la classe DrawingCanvas parcourt la liste enfant du rectangle de la zone de dessin en utilisant la propriété numChildren (héritée de la classe DisplayObjectContainer) pour définir la limite de la boucle for . Elle génère une chaîne qui recense chaque enfant, comme suit :

var desc:String = ""; 
var child:DisplayObject; 
for (var i:int=0; i < this.numChildren; i++) 
{ 
child = this.getChildAt(i); 
desc += i + ": " + child + '\n'; 
}

La chaîne résultante permet de définir la propriété text du champ de texte outputTxt .

Cliquer-déplacer un objet d’affichage

Lorsque l’utilisateur clique sur une occurrence de GeometricSprite, l’application appelle le gestionnaire de l’événement onMouseDown() . Comme le montre le code ci-dessous, ce gestionnaire écoute les événements de clic gauche de souris dans la fonction constructeur de la classe GeometricSprite :

this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

La méthode onMouseDown() appelle ensuite la méthode showSelected() de l’objet GeometricSprite. S’il s’agit du premier appel de cette méthode sur l’objet, elle crée un objet Shape appelé selectionIndicator et utilise la propriété graphics de l’objet Shape pour dessiner un rectangle rouge de mise en valeur, comme suit :

this.selectionIndicator = new Shape(); 
this.selectionIndicator.graphics.lineStyle(1.0, 0xFF0000, 1.0); 
this.selectionIndicator.graphics.drawRect(-1, -1, this.size + 1, this.size + 1); 
this.addChild(this.selectionIndicator);

S’il ne s’agit pas du premier appel de la méthode onMouseDown() , celle-ci active simplement la propriété visible (héritée de la classe DisplayObject) de la forme selectionIndicator :

this.selectionIndicator.visible = true;

La méthode hideSelected() masque la forme selectionIndicator de l’objet précédemment sélectionné en définissant sa propriété visible sur false .

La méthode du gestionnaire d’événement onMouseDown() appelle également la méthode startDrag() (héritée de la classe Sprite), qui comprend le code suivant :

var boundsRect:Rectangle = this.parent.getRect(this.parent); 
boundsRect.width -= this.size; 
boundsRect.height -= this.size; 
this.startDrag(false, boundsRect);

L’utilisateur peut alors déplacer l’objet sélectionné sur la zone de dessin, au sein des limites définies par le rectangle boundsRect .

Lorsque l’utilisateur relâche le bouton de la souris, l’événement mouseUp est distribué. La méthode constructeur de DrawingCanvas configure l’écouteur d’événement suivant :

this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);

Cet écouteur d’événement est associé à l’objet DrawingCanvas, plutôt qu’aux objets GeometricSprite individuels. En effet, lorsque l’utilisateur déplace l’objet GeometricSprite, celui-ci risque d’être placé derrière un autre objet d’affichage (un autre objet GeometricSprite) lorsque le bouton de la souris est relâché. L’événement « mouse up » s’appliquerait à l’objet d’affichage en avant-plan, mais non à l’objet d’affichage déplacé par l’utilisateur. Ajouter l’écouteur à l’objet DrawingCanvas assure la gestion de l’événement.

La méthode onMouseUp() appelle la méthode onMouseUp() de l’objet GeometricSprite, qui appelle alors la méthode stopDrag() de l’objet GeometricSprite.

Réorganisation de l’ordre de superposition des objets d’affichage

L’interface utilisateur de l’application comprend des boutons intitulés Move Back, Move Down, Move Up et Move to Front. Lorsque l’utilisateur clique sur l’un de ces boutons, l’application appelle la méthode correspondante de la classe DrawingCanvas, à savoir : moveToBack() , moveDown() , moveUp() ou moveToFront() . Par exemple, la méthode moveToBack() comporte le code suivant :

public function moveToBack(shape:GeometricSprite):void 
{ 
    var index:int = this.getChildIndex(shape); 
    if (index > 0) 
    { 
        this.setChildIndex(shape, 0); 
    } 
}

Cette méthode utilise la méthode setChildIndex() (héritée de la classe DisplayObjectContainer) pour placer l’objet d’affichage à la position d’index 0 de la liste des enfants de l’occurrence de DrawingCanvas ( this ).

Le fonctionnement de la méthode moveDown() est similaire, mais elle décrémente la position d’index de l’objet d’affichage d’une unité dans la liste des enfants de l’occurrence de DrawingCanvas :

public function moveDown(shape:GeometricSprite):void 
{ 
    var index:int = this.getChildIndex(shape); 
    if (index > 0) 
    { 
        this.setChildIndex(shape, index - 1); 
    } 
}

Le fonctionnement des méthodes moveUp() et moveToFront() est similaire aux méthodes moveToBack() et moveDown() .