Séparation du design et du code dans Flash – part 3

Ces trois tutoriels font suite à un séminaire donné chez Adobe France le 23 novembre 2009, par Nicolas Gans, responsable pédagogique plate-forme Flash au centre de formation Regart.net.

Ils reprennent les slides et les exemples montrés lors de cette journée.

Le séminaire est divisé en trois parties :

- Séparation du design et du code dans Flash – part 1 : séparation .fla et .as
- Séparation du design et du code dans Flash – part 2 : compiler des .fla différents
- Séparation du design et du code dans Flash – part 3 : coder et compiler avec Flex Builder

Problématiques abordées :

Comment développer un projet en Flash et fluidifier les échanges au sein d’une équipe composée de designer Flash et de développeurs AS3 .

Quelles sont les bonnes pratiques (séparation et communication entre éléments du design et code), les techniques (librairies partagées, SWC),  outils (FlashDevelop, Flex Builder) ?

Coder et compiler des projets Flash avec Flex Builder

Travailler avec un éditeur AS3 robuste et puissant, basé sur Eclipse, cross-plateform.
Bénéficier du compilateur du Flex SDK, plus rapide.

Créer un projet AS3 dans Flex Builder

Etape 1

projet_AS3_1

Etape 2

projet_AS3_2

Etape 3 : choisir le nom de la classe du document

projet_AS3_3

Etape 4 : le projet est maintenant crée. On créera ses classes dans le dossier « src », via un clic droit sur le dossier > New > ActionScript class

projet_AS3_4

Etape 5 : la compilation. La compilation en mode debug est préférable en production : elle permet de récupérer les trace() et les erreurs à l’exécution dans le panneau de sortie (il faudra peut-être installer le player de debug sur votre machine). Une fois le projet terminé, on pourra compiler en mode Release.

projet_AS3_5

Faire la liaison Asset en bibliothèque / Classe par code

  • But : reproduire une liaison de bibliothèque de Flash au sein de Flex Builder
  • Utilisation d’Embed avec un swf contenant les assets pour en extraire les symboles exportés
  • Placer l’Embed juste avant la déclaration de la classe
  • Défaut :
    Aucun code placé dans le clip ne sera exécuté
    Pas d’utilisation de composants possible

Exemple : 08_Liaison_asset_classe_par_code_avec_FB [Télécharger l'exemple]

NOTE : pour ouvrir l’exemple, passer par fichier > importer et importer directement l’archive .zip au sein de Flex Builder.

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package asfiles
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.text.TextField;
 
	/**
	 * ...
	 * @author Nicolas Gans
	 */
 
	// on associe un asset de la librairie à notre classe = comme si on faisait une liaison par code
	[Embed (source="../assets/assets.swf", symbol="Personnage_asset")]
	public class Personnage extends MovieClip
	{
 
		public var message_txt:TextField;
 
		public function Personnage()
		{
 
		}
 
		public function clignote():void
		{
			addEventListener(Event.ENTER_FRAME, loop);
		}
 
		private function loop(e:Event):void
		{
			alpha = Math.random();
		}
 
	}
 
}

Utiliser un SWC pour les assets graphiques

  • Pas de complétion si on travaille avec des clips de la bibliothèque embedés avec la 1ere méthode.
  • On ne peut pas cibler les occurrences placées sur la scène d’un MC.
  • Solution : utiliser un SWC.
  • Introspection automatique de la classe, FD est capable d’aller chercher automatiquement les occurrences sur la scène.
  • On pourra mettre du code dans ses MovieClip : le code timeline sera conservé avec les SWC

Pour générer un .swc dans Flash, cocher la case exporter SWC dans les paramètres de publication

creation_swc_dans_flash

Quand vous compilez votre SWF via CTRL + ENTREE, un SWC est automatiquement crée à côté du SWF

creation_swc_dans_flash_2

Pour ajouter un SWC à son projet Flex : clic-droit sur le projet

ajout_SWC_projet_AS3_Flex

Puis dans le panneau des propriétés, choisir « ActionScript build path », puis « Add SWC », choisir le SWC a ajouter au projet et valider en cliquant sur « OK »

ajout_SWC_projet_AS3_Flex_2

Les classes incluses dans le SWC sont maintenant utilisables dans votre projet Flex !

Exemple : 09_Utilisation_de_SWC [Télécharger l'exemple]

This movie requires Flash Player 9

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package {
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.MouseEvent;
 
	[SWF (width="640", height="480", frameRate="30", backgroundColor="0xCCCCCC")]
	public class Main extends Sprite
	{
 
		private var monPerso:Personnage_asset;
		private const defaultInput:String = "votre message";
 
		public function Main()
		{
 
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
 
			// on instancie la classe Personnage_asset issue du .swc
			monPerso = new Personnage_asset();
			monPerso.x = 200;
			monPerso.y = 50;
			addChild(monPerso);
 
			monPerso.addEventListener("AnimationTerminee", animeTerminee);
 
		}
 
		private function animeTerminee(e:Event):void
		{
 
			monPerso.message_txt.text = "HiDiHo!";
			// on peut utiliser des composants Flash
			monPerso.ok_btn.addEventListener(MouseEvent.CLICK, clickOK);
			monPerso.input_txt.addEventListener(FocusEvent.FOCUS_IN, onInputFocusIn);
			monPerso.input_txt.addEventListener(FocusEvent.FOCUS_OUT, onInputFocusOut);
 
		}
 
		private function clickOK(e:MouseEvent):void
		{
 
			monPerso.message_txt.text = monPerso.input_txt.text;
 
		}
 
		private function onInputFocusIn(e:FocusEvent):void
		{
			if (monPerso.input_txt.text == defaultInput)
			{
				monPerso.input_txt.text = "";
			}
		}
 
		private function onInputFocusOut(e:FocusEvent):void
		{
			if (monPerso.input_txt.text == "")
			{
				monPerso.input_txt.text = defaultInput;
			}
		}
	}
}

Utilisation de SWC au sein  de Flex Builder : séparation design et code

Composition vs Héritage

Méthode 1 : héritage

  • Faire un symbole MonSymbole_skin dans flash
  • Faire une classe MonSymbole dans Flex Builder qui hérite de MonSymbole_skin
  • On accède aux occurrences de manière transparente
  • Problème :
    Contrainte liée à l’héritage : on ne peut pas faire hériter d’une classe abstraite notre classe

SWC_heritage_small

Exemple : 10_SWC_et_separation_design_code_heritage [Télécharger l'exemple]

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package classes
{
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.MouseEvent;
 
	// notre classe contenant la logique, crée dans Flex, hérite de la classe graphique
	// crée par le graphiste dans Flash et stockée dans le assets.swc
	public class Personnage extends Personnage_asset
	{
 
		private const defaultInput:String = "votre message";
 
		public function Personnage():void
		{
 
			addEventListener("AnimationTerminee", animeTerminee);
 
		}
 
		private function animeTerminee(e:Event):void
		{
 
			// par héritage, on accède aux occurrences posées sur la scène
			// de Personnage_asset par le designer
			message_txt.text = "HiDiHo!";
			ok_btn.addEventListener(MouseEvent.CLICK, clickOK);
			input_txt.addEventListener(FocusEvent.FOCUS_IN, onInputFocusIn);
			input_txt.addEventListener(FocusEvent.FOCUS_OUT, onInputFocusOut);
 
		}
 
		private function clickOK(e:MouseEvent):void
		{
 
			message_txt.text = input_txt.text;
 
		}
 
		private function onInputFocusIn(e:FocusEvent):void
		{
			if (input_txt.text == defaultInput)
			{
				input_txt.text = "";
			}
		}
 
		private function onInputFocusOut(e:FocusEvent):void
		{
			if (input_txt.text == "")
			{
				input_txt.text = defaultInput;
			}
		}
 
	}
}

Méthode 2 : composition

  • On fait une propriété skin dans la classe logique
  • On accède aux occurrences de la scène via la propriété skin
  • Permet de faire hériter la classe logique d’une classe abstraite

SWC_composition_small

Exemple : 11_SWC_et_separation_design_code_composition [Télécharger l'exemple]

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package classes
{
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.MouseEvent;
 
	// comme on fait de la composition pour l'aspect visuel
	// notre classe peut hériter d'une (pseudo) classe Abstraite
	// issue de notre framework et implémentant une logique de base
	// pour les DisplayObject
	public class Personnage extends AbstractView
	{
 
		private const defaultInput:String = "votre message";
		// composition : la skin est une propriété de notre classe logique
		// qui va la contenir
		public var skin:Personnage_asset;
 
		public function Personnage():void
		{
			// on instancie la skin
			skin = new Personnage_asset();
			// et on l'ajoute à la displayList de notre classe logique
			// (qui doit hériter de DisplayObjectContainer, ici via la classe abstraite AbstractView)
			addChild(skin);
			skin.addEventListener(TransitionEvent.TRANSITION_IN_COMPLETE, transitionInComplete);
 
		}
 
		override protected function transitionInComplete(e:Event=null):void
		{
			super.transitionInComplete(e);
 
			skin.message_txt.text = "HiDiHo!";
			skin.ok_btn.addEventListener(MouseEvent.CLICK, clickOK);
			skin.input_txt.addEventListener(FocusEvent.FOCUS_IN, onInputFocusIn);
			skin.input_txt.addEventListener(FocusEvent.FOCUS_OUT, onInputFocusOut);
 
		}
 
		private function clickOK(e:MouseEvent):void
		{
 
			skin.message_txt.text = skin.input_txt.text;
 
		}
 
		private function onInputFocusIn(e:FocusEvent):void
		{
			if (skin.input_txt.text == defaultInput)
			{
				skin.input_txt.text = "";
			}
		}
 
		private function onInputFocusOut(e:FocusEvent):void
		{
			if (skin.input_txt.text == "")
			{
				skin.input_txt.text = defaultInput;
			}
		}
 
	}
}
Bookmark and Share

Une réponse Souscrire aux commentaires


  1. switcherdav

    Bien sympa cet article, perso, j’utilise la dernière méthode SWC + composition

    Je l’ai peut-être loupé, mais le fait que le SWC soit intégré systématiquement au projet n’est pas précisé, dès lors, le SWF final s’en ressentira forcement au niveau du poids

    je passe à la part.2 …

    07 mar 2010 @ 19:31

Répondre