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) ?
Compiler des .fla différents
Comment permettre aux différents intervenants de travailler en parallèle sans avoir à compiler le même fichier ?
Utilisation de SWF en tant que bibliothèque externe : chargement à l’exécution
- Chargement avec un Loader
- Extraction des assets avec la classe ApplicationDomain et la méthode getDefinition()
- On peut mettre en bibliothèque tout type d’assets
- Il faut connaître le nom des assets, sinon on peut utiliser des classes qui introspectent la totalité des classes disponibles dans le SWF
http://www.bytearray.org/?p=175 (uniquement pour les symboles DisplayObject)
ou
http://etcs.ru/pre/getDefinitionNamesSource/ (extraction de tous les types d’assets) - Problèmes :
Obligé de typer avec le superType, pas de vérification de type précise, ni de complétion spécifique dans un éditeur de code. - Solutions :
utilisation d’interfaces
Exemple : 04_chargement_bibliotheque [Télécharger l'exemple]
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | package { import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.MovieClip; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.net.URLRequest; import flash.system.ApplicationDomain; import flash.utils.describeType; import flash.utils.getDefinitionByName; /** * ... * @author Nicolas Gans */ public class Main extends Sprite { private var chargeur:Loader; // le nom des classes chargées private var assetsClassName:Array = ["Perso1", "Perso2"]; private var localeLib:Object = new Object(); public function Main():void { chargeur = new Loader(); chargeur.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete); chargeur.load(new URLRequest("bibliotheque.swf")); createPerso1_btn.addEventListener(MouseEvent.CLICK, instanciate); createPerso2_btn.addEventListener(MouseEvent.CLICK, instanciate); } private function onComplete(e:Event):void { // récupération d'une instance d'ApplicationDomain // sur la propriété applicationDomain du contentLoaderInfo (e.target) var appDomain:ApplicationDomain = LoaderInfo(e.target).applicationDomain; // on crée dynamiquement une bibliotheque locale for each (var className:String in assetsClassName) { if (appDomain.hasDefinition(className)) { localeLib[className] = appDomain.getDefinition(className) as Class; } } // pour infos for (var prop:String in localeLib) { trace(prop, ":", localeLib[prop]); } } private function instanciate(e:MouseEvent):void { // on crée dynamiquement la classe var MaClasse:Class = (e.currentTarget == createPerso1_btn) ? localeLib["Perso1"] : localeLib["Perso2"]; // on pourrait en savoir plus sur la classe avec describeType //trace(describeType(MaClasse)); trace(getSuperType(MaClasse)); // puis on l'instancie // on doit typer avec le super-type de la classe // on pourrait ici utiliser une interface pour avoir un typage plus fort var perso:MovieClip = new MaClasse(); perso.scaleX = perso.scaleY = Math.random() * .4 + .3; perso.x = Math.random() * (stage.stageWidth - perso.width); perso.y = Math.random() * (stage.stageHeight - perso.height - 40); addChild(perso); } // petite méthode pour connaître dynamiquement le superType d'un asset private function getSuperType(pClass:Class):String { var superType:String = describeType(pClass).factory.extendsClass[0].@type; return superType.split("::")[1]; } } } |
Le MetaTag [Embed] et les SWC
Utilisation du MetaTag embed : externalisation des assets
- Depuis Flash CS4, le compilateur permet l’utilisation du MetaTag [Embed]
- Permet d’externaliser la bibliothèque de Flash en incluant des éléments multimédia externes dans son SWF : polices, MC, XML, sons…
- En aucun cas du chargement dynamique, les assets sont inclus dans le SWF : ajoute du poids au SWF !!
- Ce n’est pas de l’AS3, ces balises sont transformées en AS3 avant la compilation
Embed d’images, sons, swf et typo
- Ecriture :
1 2 | [Embed (source=’image.jpg’)] var ClasseImage:Class |
- Les instances sont de type BitmapAsset, SoundAsset, SpriteAsset, MovieClipAsset…
- Types issus du framework Flex : nécessaire d’inclure les classes de ce framework en utilisant des .SWC du Flex SDK (gratuit et téléchargeable ici)
- Il faut intégrer le flex.swc via les paramètres d’ActionScript 3 dans l’onglet Flash des paramètres de publication
Exemple : 05_MetaTag_Embed [Télécharger l'exemple]
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | package { import flash.display.Bitmap; import flash.display.MovieClip; import flash.display.Sprite; import flash.events.MouseEvent; import flash.media.Sound; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; // classes issues du framework Flex : indispensables pour utiliser l'embed dans Flash CS4 import mx.core.*; /** * ... * @author Nicolas Gans */ public class Main extends MovieClip { // attention : le chemin source se fait depuis le répertoir où se trouve // le fichier .as, pas depuis la racine du projet !! [Embed (source="assets/LogoRegart.jpg")] var LogoRegart:Class; [Embed (source="assets/son.mp3")] var SonExterne:Class; [Embed (source="assets/bibliotheque.swf", symbol="Personnage")] var Personnage:Class; [Embed(source='assets/SerifaStd-Light.otf', fontName='maPolice', mimeType = 'application/x-font', unicodeRange = 'U+0030-U+0039, U+0041-U+0051, U+0052-U+007A')] // chiffres de 0 à 9, les minuscules de a à z et les majuscules de A à Z // Attention : ne pas utiliser ce nom de classe pour choisir sa typo via un TextFormat // ou une CSS externe, mais la propriété fontName, dans notre cas 'maPolice' var font:Class; private var monSon:Sound; private var conteneurLogo:Sprite; private var monLogo:Bitmap; private var monPerso:Sprite; public function Main():void { // LOGO ====================================================== conteneurLogo = new Sprite(); conteneurLogo.x = conteneurLogo.y = 40; monLogo = new LogoRegart(); conteneurLogo.addChild(monLogo); addChild(conteneurLogo); conteneurLogo.buttonMode = true; // SON ====================================================== monSon = new SonExterne(); conteneurLogo.addEventListener(MouseEvent.CLICK, onLogoClick); // MOVIECLIP ====================================================== monPerso = new Personnage() as Sprite; //trace(flash.utils.describeType(monPerso)); monPerso.x = 220; monPerso.y = 140; monPerso.scaleX = monPerso.scaleY = .8; addChild(monPerso); // FONT ========================================================= var champTexte:TextField = new TextField(); champTexte.x = 400; champTexte.y = 200; // ne pas oublier de passer embedFonts à true ! champTexte.width = 120; champTexte.wordWrap = true; champTexte.embedFonts = true; champTexte.autoSize = TextFieldAutoSize.LEFT; champTexte.rotation = -10; champTexte.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; // on passe en premier argument du constructeur le fontName défini dans l'embed : "maPolice" var tf:TextFormat = new TextFormat("maPolice", 22, 0xCC0000); champTexte.setTextFormat(tf); addChild(champTexte); } private function onLogoClick(e:MouseEvent):void { monSon.play(); } } } |
Qu’est-ce qu’un SWC ?
- Librairie de classes compilées (// SWF)
- Distribution de classes sans livrer les sources.
- Utilisation d’assets sous forme de classe.
Utilisation d’Embed pour intégrer des typo
- Permet de créer l’équivalent d’un symbole police de bibliothèque MAIS on va pouvoir choisir les glyphes embarqués !
- Utilisation d’un SWF dans lequel on crée des champs texte avec intégration des caractères.
- Attention : dans les champs textes posés sur la scène, ne surtout pas choisir la même typo que celle que l’on va appliquer en tant qu’embedFont (prendre de préférence une police de périphérique) > sinon l’intégration ne fonctionne pas !!
Exemple : 06_embed_et_typo_dans_SWF [Télécharger l'exemple]
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 | package { import flash.display.Sprite; import flash.text.Font; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; /** * ... * @author Nicolas Gans */ public class Main extends Sprite { [Embed(source='Calibri_font.swf', fontName = 'Calibri' )] private static var CalibriRegular:Class; [Embed(source='Calibri_font.swf', fontName = 'Calibri', fontStyle = 'italic' )] private static var CalibriItalic:Class; [Embed(source='Calibri_font.swf', fontName = 'Calibri', fontWeight = 'bold' )] private static var CalibriBold:Class; public function Main() { regular_txt.embedFonts = true; regular_txt.text = "Je peux parler en Calibri regular..."; //regular_txt.rotation = 2; var tf:TextFormat = new TextFormat("Calibri", 22, 0xFFFFFF); regular_txt.setTextFormat(tf); italic_txt.embedFonts = true; italic_txt.text = "Mais aussi en Calibri italic..."; tf = new TextFormat("Calibri", 22, 0xFFFFFF); tf.italic = true; //italic_txt.rotation = 2; italic_txt.setTextFormat(tf); bold_txt.embedFonts = true; bold_txt.text = "Ou encore en Calibri bold..."; tf = new TextFormat("Calibri", 22, 0xFFFFFF); tf.bold = true; //bold_txt.rotation = 2; bold_txt.setTextFormat(tf); french_txt.embedFonts = true; french_txt.text = "Et je n'embarque que les 140 caractères français."; tf = new TextFormat("Calibri", 13, 0xFFFFFF); tf.leading = -2; french_txt.setTextFormat(tf); } } } |
Utilisation de SWC Flex (ou autres) non-graphique : se connecter à un webservice avec le rpc.swc du framework Flex
- Classe WebService existait en AS2.
- Classe Webservice n’existe pas en AS3 dans l’API de Flash, mais existe dans le framework Flex.
- Utilisation du rpc.swc du framework Flex pour travailler avec la classe WebService de Flex.
Exemple : 07_webservice_avec_le_rpc_swc [Télécharger l'exemple]
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 | package { import flash.display.Sprite; // classes du framework Flex intégrées // via le rpc.swc et le framework.swc import mx.rpc.soap.*; import mx.core.*; import mx.rpc.events.*; import flash.events.MouseEvent; /** * ... * @author Nicolas Gans */ public class Main extends Sprite { private var monService:WebService; public function Main() { monService = new WebService(); // mx.rpc.soap.LoadEvent (hérite de WSDLLoadEvent) monService.addEventListener(LoadEvent.LOAD, onWSDLLoad); monService.loadWSDL("http://www.boyzoid.com/comp/randomQuote.cfc?wsdl"); bouton.addEventListener(MouseEvent.CLICK, getQuoteClick); } function onWSDLLoad(e:LoadEvent):void { trace(e); // on écoute le résultat monService.getQuote.addEventListener(ResultEvent.RESULT, getQuoteResult); // on écoute les éventuels échecs de l'appel monService.getQuote.addEventListener(FaultEvent.FAULT, getQuoteFault); // appel de la méthode distante getQuote() sur le webservice monService.getQuote(true); texte.htmlText = "Retrieving quote..."; } function getQuoteClick(e:MouseEvent):void { monService.getQuote(true); texte.htmlText = "Retrieving quote..."; } function getQuoteResult(e:ResultEvent):void { trace(e.result); texte.htmlText = e.result as String; } function getQuoteFault(e:FaultEvent):void { trace(e); texte.htmlText = "Oups, le webservice n'a pas l'air de fonctionner..."; } } } |


Cool !! Ben mince!! il me semble que tu viens d’aborder un souci que je viens d’avoir mais que j’ai résolu autrement.. je venais justement sur le forum pour poster une info à ce sujet.. il s’agit des classes remoting AS2 qui n’existe plus dans CS4 et je devais éditer et recompiler un vieux site web AS2..
Je ne me rappelais plus que Flex SDK possédait ces classes..
27 nov 2009 @ 17:24