Tutoriel 5 – Jouer avec les objets (Shape et Sprite)

Bon, on va enfin mettre les mains dans le code et afficher quelques trucs cool, le but ici est de vous montrer comment fonctionne certaines classes.

1. Créer des formes

Pour créer des formes on peut utiliser deux classes, Shape et la Sprite. Il y a deux différences fondamentales entre ces deux classes :

  1. La classe Shape n’hérite pas de InteractiveObject et ne peux donc pas réagir aux éventements clavier et souris ;
  2. La classe Shape n’hérite pas non plus de DisplayObjectContainer et ne peux donc pas contenir d’autres objets.

La classe Sprite par contre hérite de DisplayObjectContainer qui elle même hérite de InteractiveObject, mais concrètement qu’est ce que ça veut dire ? Une chose : Un objet Shape a moins de possibilités qu’un objet Sprite mais surtout il consomme moins de mémoire. Effectivement, comme un objet de type Sprite peut contenir des enfants (des DisplayObject) et qu’il peut aussi réagir à tous les événements utilisateurs, celui ci demande plus de ressources. Quand utiliser Shape et Sprite ? et bien c’est suivant vos besoins, si vous avez besoin d’avoir juste une forme simple alors un objet Shape fera l’affaire sinon utilisez un Sprite.

Voici un premier exemple d’utilisation de la classe Shape

package
{
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;

	[SWF(width="320", height="240")]

	public class ShapeExemple extends Sprite
	{
		private var couleurFond:uint = 0xff0000; // Rouge
		private var couleurBordure:uint = 0x000000; // Noir

		public function ShapeExemple()
		{
			// Dessin d'un Rectangle
			var forme:Shape = new Shape();
			forme.graphics.beginFill(couleurFond);
			forme.graphics.lineStyle(1, couleurBordure);
			// x = 30, y = 30, largeur = 60, hauteur = 40
			forme.graphics.drawRect(30, 30, 60, 40);
			forme.graphics.endFill();
			// Ajout sur la scène
			addChild(forme);
		}
	}
}

 

Capture d'écran de l'exemple sur l'objet Shape

Pour essayer cet exemple vous pouvez soit créer un nouveau projet dans FlashDevelop, soit créer un fichier du nom de ShapeExemple.as et utiliser la commande mxmlc ShapeExemple.as pour le compiler.

On va examiner un peut le code et puis je vous donnerais d’autres exemples d’utilisation. Si il y a une chose à retenir de cet exemple c’est bien la propriété graphics de l’objet forme (Classe Shape) ! Cette propriété permet d’accéder à un objet de type Graphics (flash.display.Graphics) qui permet de dessiner des formes vectoriels. Je vous invite vivement à consulter la documentation pour voir toutes les méthodes disponibles.

 

La classe Graphics (flash.display.Graphics)

Je vais vous présenter quelques méthodes, puis nous finirons sur un exemple pour synthétiser tout ça. Pour dessiner une forme vectorielle nous devons dans un premier temps appeler une des méthodes suivante :

  • beginFill(color:uint, alpha:Number = 1.0):void;
  • beginGradientFill(type:String, colors:Array, alphas:Array, ratios:Array, matrix:Matrix = null, spreadMethod:String = « pad », interpolationMethod:String = « rgb », focalPointRatio:Number = 0):void ;
  • beginBitmapFill(bitmap:BitmapData, matrix:Matrix = null, repeat:Boolean = true, smooth:Boolean = false):void .

La première permet de dessiner une forme simple comme nous l’avons fait dans l’exemple du haut, elle prend une couleur de remplissage en paramètre et c’est tout.Pour information, le mot « Fill » en anglais se traduit par « Remplir » 😉

La deuxième permet de dessiner une forme avec une couleur de remplissage en dégradé. Là par contre il y a plus de paramètres que la dernière, dont 4 obligatoires. Pour plus d’informations sur les autres paramètre consultez la documentation :p

La troisième méthode permet de remplir votre forme avec une image. En gros vous pouvez charger une image via cette méthode et dessiner des formes par dessus.

Lorsqu’une de ces méthodes a été appelée, vous pouvez dessiner des rectangles, cercles et ellipses avec des couleurs différentes. Vous pouvez déplacer le « curseur » de dessin à l’aide de la méthode moveTo(x:Number, y:Number).

Une fois le dessin terminé il faut appeler la méthode endFill() pour que la surface du dessin soit mise à jour. On enferme donc notre dessin entre les méthode beginXXXFill() et endFill().

Un exemple avec la classe Shape

Voici un exemple qui reprend tout ça et qui affiche plusieurs formes. Souvenez vous qu’un objet de type Sprite est un conteneur graphique et que Shape n’est qu’un objet de représentation.

package
{
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;

	[SWF(width="320", height="240")]

	public class ShapeExemple2 extends Sprite
	{
		private var couleurFond:uint = 0xff0000; // Rouge
		private var couleurBordure:uint = 0x000000; // Noir

		public function ShapeExemple2()
		{
			// taille de la zone de dessin
			var largeurStage:Number = stage.stageWidth;
			var hauteurStage:Number = stage.stageHeight;

			var rectangle1:Shape = creerRectangle(10, hauteurStage - 90, 120, 80, 0x00FF00);
			this.addChild(rectangle1);

			var rectangle2:Shape = creerRectangle(largeurStage - 130, hauteurStage - 90, 120, 80, 0x000FF0);
			this.addChild(rectangle2);

			var cercle:Shape;
			var couleurs:Array = new Array(0xFF38DD, 0x75FF60, 0xFF6C0A, 0x38FF59, 0xFF3851, 0xFF6C0A);
			for (var i = 0; i < 6; i++)
			{
				cercle = creerCercle(
					(i * 5) * (i * 2),				// position X
					(hauteurStage / 2) - (5 * i),	// position Y
					(5 * i),						// rayon
					couleurs[i]);					// Couleur

				this.addChild(cercle);
			}
		}

		private function creerRectangle(posX:int, posY:int, longueur:int, largeur:int, couleur:uint):Shape
		{
			var rectangle:Shape = new Shape();

			rectangle.graphics.beginFill(couleur);
			rectangle.graphics.drawRect(posX, posY, longueur, largeur);
			rectangle.graphics.endFill();

			return rectangle;
		}

		private function creerCercle(posX:int, posY:int, rayon:int, couleur:uint):Shape
		{
			var cercle:Shape = new Shape();
			cercle.graphics.beginFill(couleur);
			cercle.graphics.lineStyle(2, 0x000000);
			cercle.graphics.drawCircle(posX, posY, rayon);
			cercle.graphics.endFill();

			return cercle;
		}
	}
}

 

Et voilà le travail 🙂

Il n’y a pas grand chose de neuf par rapport au premier code si ce n’est que cette fois ci nous affichons plusieurs formes. Vous remarquerez qu’on peut récupérer la taille de l’application via les propriétés du stage. Souvenez vous que le stage est LE conteneur principal, c’est donc tout à fait normal de pouvoir récupérer la largeur et la hauteur de la fenêtre, je vous conseil encore une fois de lire la documentation sur la classe Stage pour voir toutes les méthodes disponibles.

On accède au stage depuis l’instance de notre classe de base ShapeExemple2 et savez vous pourquoi ? Comme je ne cesse de le dire, la fenêtre que vous voyez à l’écran est une instance de la classe Stage, cette instance est automatiquement créée, tout ce que nous avons à faire c’est d’attacher des objets dessus pour qu’ils y soient affichés. Comme la classe ShapeExemple2 est le premier enfant qui est attaché au stage, celui ci dispose automatiquement d’une propriété en lecture seule « stage », qui permet donc de récupérer toutes les informations disponibles sur la fenêtre en cours (on parle de contexte d’affichage).

Je ne sais pas si je vous ai convaincu ? Je vous propose de synthétiser tout ça avec le schéma ci-dessous :

La liste d'affichage

Voilà qui devrait clarifier un peut les choses 😉 Au sommet il y a le stage qui contient un Sprite, ce Sprite contient plusieurs Shape. Les objets Shape sont ajoutés avec la méthode addChild de la classe Sprite (en réalité cette méthode vient de DisplayObjectContainer et on l’a retrouve avec l’héritage).

Vous pouvez maintenant tenter plusieurs expériences, avec d’autres formes et d’autres couleurs. Au fait comment ça marche avec un Sprite ? exactement pareil ! vous pouvez remplacer tous les « Shape » par « Sprite » et ça fonctionnera pareil, le seul « problème » est que votre scène sera plus gourmande car les Sprite sont en plus : des conteneurs pour d’autres DisplayObject et peuvent réagirs aux événements type clavier/souris.