Pratique d'ActionScript 3 - Version 0.1.4

1096
trace("Pratique d'ActionScript 3"); // Thibault IMBERT

Transcript of Pratique d'ActionScript 3 - Version 0.1.4

trace("Pratique d'ActionScript 3");

// Thibault IMBERT

Remerciements

//

"Je voudrais remercier tout particulirement Mathieu Anthoine (Mama) pour sa relecture soigne et ses conseils aviss durant toute la rdaction de louvrage. Son exprience et sa vision du Flash est une source dinspiration. Jrme Decoster pour sa relecture attentive, son soutien et ses conseils toujours pertinents. Pour nos soires pizza discuter ActionScript 3 et te faire rentrer chez toi en vlib. Chris Georgenes (www.mudbubble.com) et Aurelien Marcheguay de Carton Blanc (www.cartonblanc.com) et Stphane Mortka pour leur soutien et leurs illustrations qui mont permis denrichir graphiquement louvrage. Je remercie tous mes compagnons flasheurs qui mont forcment soutenu et aid un moment donn : Joa Ebert, Didier Brun, Jrme Cordiez, Vincent Maitray, David Deraedt, Frderic Saunier, Benjamin Jung. Le centre Regart.net pour mavoir soutenu. A Nicolas pour ses opinions, Eric pour ses bonnes blagues, et Guylaine pour ces annes chez Regart. Justin Everett-Church dAdobe et Henri Torgemane de Yahoo pour leur aide et leur soutien. Sgolne (www.chevaldetroie.net) pour avoir relu tous ces chapitres la recherche de fautes dorthographes. Mes amis que je n'ai pas vus pendant quasiment 8 mois : Sbastien, Bessam, Laurent, Paul, Juan, Pascal, Bob Groove et bien sr Stevie Wonder. Sonia pour ce dimanche 20 aot 2006 o ma vie a change. Mes parents et ma sur qui mont soutenu pendant lcriture. Bien entendu, je ne peux pas terminer les remerciements sans remercier tous mes stagiaires que jai pu rencontrer depuis plus de trois ans de formations. Jai appris normment chaque jour vos cts, vous avez particip cet ouvrage dune faon ou dune autre."

Prface

//

"Je pratique Flash depuis maintenant 10 ans et jai pu suivre de prs toutes ses volutions. Flash 3 a accompagn mes premiers pas dans l'univers du web. J'ai dcouvert un logiciel incroyablement accessible et dont l'ergonomie astucieuse, les outils d'animation et d'interactivit rpondaient parfaitement aux besoins de l'poque. Quelques annes plus tard, un bond de gant est franchi avec Flash MX et l'apparition de la premire version robuste du langage ActionScript. Flash est alors un outil mr et quilibr. Au mme moment, sortent les premires versions de Flash Media Server et Flash Remoting qui deviennent des complments indispensables tout dveloppement ambitieux. Suivant l'volution des crations web de plus en plus dynamiques et complexes, Flash bascule, non sans mal, vers un outil de dveloppement plus sophistiqu (Flash MX 2004), ncessitant la mise en place d'quipes spcialises. L'poque du flasheur maitrisant tout de A Z est rvolue. Flash s'adresse dsormais deux publics distincts : graphistes d'un cot, dveloppeurs de l'autre. L'quilibre devient alors prcaire et la tendance favoriser le code au dtriment de l'accessibilit de loutil se dveloppe. Les ralisations du graphiste ou de l'animateur sont maintenant souvent subordonnes au travail du dveloppeur, ce qui ne favorise pas toujours la cration. Si Flash 8, grce aux filtres et mlanges, ouvre de nouvelles voies la cration et redonne un peu de place au graphiste, c'est nanmoins, le plus souvent, le dveloppeur qui contrle le projet. Flash 9 et l'ActionScript 3 reprsentent une nouvelle tape vers la technicisation de loutil. Connatre l'environnement auteur ne suffit plus, il est indispensable de comprendre et de maitriser les rouages du lecteur pour viter la ralisation dapplications totalement instables. Etant au cur de la production, j'ai toujours dplor que les ouvrages Actionscript prennent si peu en compte les ralits que peuvent rencontrer une agence, un studio, une quipe ou tout professionnel dans son travail quotidien. Japprcie particulirement louvrage de Thibault pour les exemples concrets, directement utilisables en production, quil nous livre. Il nous dispense justement dexplications trop virtuelles ou dun esthtisme superflu du code. Fort de son exprience de formateur, il reste simple et clair au moyen d'un vocabulaire prcis, sans jamais tomber, ni dans le perfectionnisme lexical, ni dans la vulgarisation imprcise. Cet ouvrage va bien au del de l'apprentissage du langage ActionScript 3 en posant les bases de sa bonne utilisation dans Flash et en fournissant un clairage neuf et pertinent sur cet outil fabuleux."

Mathieu Anthoine Game Designer et co-fondateur du studio Yamago www.yamago.net

trace("Pratique d'ActionScript 3");

//

Pratique dActionScript 3 sadresse tous les flasheurs. Cet ouvrage dresse un panorama de lutilisation dActionScript 3 et de ses nouveauts, ainsi que du nouveau lecteur Flash 9. Lauteur explique au travers de nombreux exemples et cas concrets comment traiter dsormais les objets, le texte, le son et la vido, le chargement et lenvoi de donnes externes (variables, XML, etc.), les sockets, etc. Certains sujets avancs et peu abords comme les classes bas niveau ou encore Flash Remoting sont galement traits. Enfin, lauteur livre une application complte qui reprend les diffrents points voqus.

//

Thibault IMBERT est aujourd'hui ingnieur systme chez Adobe France. Il a commenc en tant que dveloppeur Flash pour diffrentes agences, avant de rejoindre Regart.net comme formateur et responsable pdagogique pour toutes les formations conernant la plate-forme Flash. Pendant son temps libre, Thibault exprimente ActionScript 3, comme en tmoigne son site www.bytearray.org. Il travaille galement sur diffrents projets tels que WiiFlash www.wiiflash.org ou AlivePDF www.alivepdf.org

Avril 2008 Environ 1200 pages. Pour un livre tlcharg, un platane plant. Graphisme couverture : Guillaume DURAND dgezeo

Chapitre 1 Quest ce que lActionScript 3 ? - version 0.1.1

1Quest ce que lActionScript 3

HISTORIQUE .......................................................................................................... 1 10 RAISONS DE CODER EN ACTIONSCRIPT 3 .............................................. 3 OUTILS..................................................................................................................... 4 LA PLATEFORME FLASH ................................................................................... 4

HistoriqueExpliquer comment crer un projet AS dans Flex Builder Cest en 1996 que laventure Flash commence lorsque la firme Macromedia rachte la petite socit FutureWave auteur dun logiciel danimation vectoriel nomm Future Splash Animator.

1/5Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 1 Quest ce que lActionScript 3 ? - version 0.1.1

Figure 1-1. Future Splash Animator sorti en avril 1996. Dvelopp lorigine pour pouvoir animer du contenu vectoriel sur Internet, Future Splash Animator intgrait dj les bases de Flash en matire danimation mais ne possdait cette poque aucun langage de programmation associ. Macromedia renomma alors le logiciel sous le nom de Flash 1.0 en 1996, mais il faut attendre 1999 afin que la notion de programmation fasse officiellement son apparition avec Flash 4. Les documentations de lpoque ne parlent pas encore de langage ActionScript mais plus simplement dactions. Grce celles-ci, il devient possible dajouter des comportements avancs aux boutons et autres objets graphiques. De nombreux graphistes laise avec la programmation commencrent dvelopper des comportements avancs et se mirent changer des scripts par le biais de forums et autres plateformes communautaires. Flash connu alors un engouement fulgurant et devint rapidement un outil danimation avanc, capable de produire diffrents types de contenus interactifs comme des sites internet, des jeux, ou des applications multimdia. Cest en 2001 que le langage ActionScript fait officiellement apparition au sein de Flash 5. La notion de syntaxe pointe est intgre au langage qui suit pour la premire fois les spcifications ECMAScript. Nous reviendrons sur cette notion au cours du prochain chapitre intitul Langage et API.

2/5Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 1 Quest ce que lActionScript 3 ? - version 0.1.1

Afin de rpondre une demande de la communaut pour un langage ActionScript plus structur, Macromedia dveloppe alors une nouvelle version dActionScript et lintgre en 2003 au sein de Flash MX 2004 sous le nom dActionScript 2.0. Cette nouvelle version rpond aux besoins des dveloppeurs en offrant un langage orient objet et non procdural comme ctait le cas en ActionScript 1.0. A lpoque, Macromedia fait le choix dune migration en douceur, et propose un langage ActionScript 2.0 souple permettant aux dveloppeurs et graphistes de coder au sein dun mme projet en ActionScript 1.0 et 2.0. Si cette nouvelle version du langage ne satisfait pas les dveloppeurs puristes, elle permet nanmoins aux dveloppeurs dbutant de migrer doucement vers un dveloppement orient objet. Macromedia dveloppe alors une nouvelle version 3.0 du langage ActionScript afin doffrir des performances optimales leur nouvelle cration nomme Flex. Deux ans plus tard, la socit Macromedia se voit rachete par le gant Adobe et lActionScript 3 voit le jour au sein de Flash en 2007, lors de la sortie de Flash CS3.

10 raisons de coder en ActionScript 3Si vous ntes pas encore convaincu de migrer vers ActionScript 3, voici 10 raisons pour ne plus hsiter : En dcembre 2007, le lecteur Flash 9 possde un taux de pntration de plus de 95%. Il demeure le lecteur multimdia le plus prsent sur Internet. La vitesse dexcution du code est environ 10 fois suprieure aux prcdentes versions dActionScript. ActionScript 3 offre des possibilits incomparables aux prcdentes versions dActionScript. Le code ActionScript 3 savre plus logique que les prcdentes versions du langage. Le langage ActionScript 3 permet de dvelopper du contenu en Flash, Flex, ou AIR. Nous reviendrons trs vite sur ces diffrents frameworks. Il nest pas ncessaire de connatre un autre langage orient objet au pralable. ActionScript 3 est un langage orient objet. Sa connaissance vous permettra daborder plus facilement dautres langages objets tels Java, C#, ou C++. Le langage ActionScript 3 et lAPI du lecteur Flash ont t entirement repenss. Les dveloppeurs ActionScript 1 et 2 seront ravis de dcouvrir les nouveauts du langage et la nouvelle organisation de lAPI du lecteur.

3/5Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 1 Quest ce que lActionScript 3 ? - version 0.1.1

La technologie Flash ne cesse dvoluer, vous ne risquez pas de vous ennuyer. ActionScript 3 est un langage souple, qui demeure ludique et accessible.

Bien entendu, vous pouvez mmoriser ces diffrents points afin de convaincre vos amis au cours dune soire geek. ActionScript 3 ne vous sera pas dune grande utilit sans un environnement de dveloppement ddi. Nous allons nous attarder quelques instants sur les diffrents outils disponibles permettant de produire du contenu ActionScript 3.

OutilsAfin quil ny ait pas de confusions, voici les diffrents outils vous permettant de coder en ActionScript 3 : Flash CS3 : permet le dveloppement danimations et dapplications en ActionScript 3. Pour plus dinformations :

http://www.adobe.com/fr/products/flash/

Flex Builder : il sagit dun environnement auteur permettant le dveloppement dapplications riches (RIA). Flex repose sur deux langages, le MXML afin de dcrire les interfaces, et ActionScript pour la logique. Pour plus dinformations :

http://www.adobe.com/fr/products/flex/

Eclipse (SDK Flex et AIR) : les SDK de Flex et AIR permettent de produire du contenu Flex et AIR gratuitement. Il sagit de plugins pour lenvironnement de dveloppement Eclipse.

Vous avez dit plateforme ?

La plateforme FlashPar le terme de plateforme Flash nous entendons lensemble des technologies travers lesquelles nous retrouvons le lecteur Flash. Nous pouvons diviser la plateforme Flash en trois catgories : Les lecteurs Flash : parmi les diffrents lecteurs, nous comptons le lecteur Flash, le lecteur Flash intgr AIR, ainsi que Flash Lite (notons que Flash lite nest pas ce jour compatible avec ActionScript 3). Les outils de dveloppement : Flex Builder et Flash CS3 sont les deux environnements auteurs permettant de produire du contenu Flash. Notons quil est aussi possible dutiliser lenvironnement Eclipse et les SDK de Flex et AIR.

4/5Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 1 Quest ce que lActionScript 3 ? - version 0.1.1

Les frameworks : Flex est un framework conu pour faciliter le dveloppement dapplications riches. Grce AIR, ces applications peuvent sortir du navigateur et tre dployes sur le bureau.

Chaque outil de dveloppement ou framework rpond une attente spcifique et correspond un profil type. Un graphiste-dveloppeur sera intress par dinterfaces animes et de sites Internet au sein connaissance dun environnement comme Flash aussi de dvelopper des composants rutilisables AIR. le dveloppement de Flash CS3. La CS3 lui permettra au sein de Flex et

Un dveloppeur prfrera peut tre un environnement de dveloppement comme celui offert par Flex Builder. Les applications produites grce au framework Flex seront de nature diffrente et pourront facilement tre dployes sur le bureau grce AIR. Notons que les exemples prsents dans cet ouvrage peuvent tre utiliss au sein de Flash CS3, Flex et AIR. Afin dentamer cette aventure au cur dActionScript 3, nous allons nous intresser tout dabord aux diffrentes nouveauts du langage. En route pour le prochain chapitre intitul Langage et API !

5/5Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

2Langage et API

LE LANGAGE ACTIONSCRIPT 3 .........................................................................1 MACHINES VIRTUELLES ............................................................................................4 TRADUCTION DYNAMIQUE ........................................................................................5 GESTION DES TYPES A LEXECUTION .........................................................................6 ERREURS A LEXECUTION........................................................................................ 11 NOUVEAUX TYPES PRIMITIFS .................................................................................. 13 VALEURS PAR DEFAUT ............................................................................................ 18 NOUVEAUX TYPES COMPOSITES .............................................................................. 20 NOUVEAUX MOTS-CLES .......................................................................................... 20 FONCTIONS ............................................................................................................. 21 CONTEXTE DEXECUTION ........................................................................................ 24 BOUCLES ................................................................................................................. 25 ENRICHISSEMENT DE LA CLASSE ARRAY ................................................................. 26 RAMASSE-MIETTES ................................................................................................. 29 BONNES PRATIQUES ................................................................................................ 32 AUTRES SUBTILITES ................................................................................................ 33

Le langage ActionScript 3Le langage ActionScript 3 intgre de nombreuses nouveauts que nous allons traiter tout au long de cet ouvrage. Ce chapitre va nous permettre de dcouvrir les nouvelles fonctionnalits et comportements essentiels tout dveloppeur ActionScript 3. Avant de dtailler les nouveauts lies au langage ActionScript 3, il convient de dfinir tout dabord ce que nous entendons par le terme ActionScript. De manire gnrale, le terme ActionScript englobe deux composantes importantes :

1 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Le cur du langage : il sagit du langage ActionScript bas sur la spcification ECMAScript (ECMA-262) et intgre partiellement certaines fonctionnalits issues de la spcification ECMAScript 4. LAPI du lecteur Flash : il sagit des fonctionnalits du lecteur Flash. Toutes les classes ncessitant dtre importes font partie de lAPI du lecteur et non du cur du langage ActionScript.

Ainsi, linterface de programmation du lecteur ou le langage peuvent tre mise jour indpendamment. Le lecteur Flash 10 devrait normalement intgrer une gestion de la 3D native ainsi quune implmentation plus complte de la spcification ECMAScript 4. La gestion de la 3D concerne ici uniquement linterface de programmation du lecteur Flash, linverse les nouveaux objets dfinis par la spcification ECMAScript 4 sont directement lis au cur du langage ActionScript. Dun ct rside le langage ActionScript 3, de lautre lAPI du lecteur appele gnralement interface de programmation. La figure 2-1 illustre les deux entits :

Figure 2-1. Langage ActionScript 3. Contrairement aux prcdentes versions dActionScript, nous remarquons quen ActionScript 3, les diffrentes fonctionnalits du lecteur Flash sont dsormais stockes dans des paquetages spcifiques. 2 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Afin dafficher une vido nous utiliserons les objets issus du paquetage flash.media. A linverse, pour nous connecter un serveur, nous utiliserons les objets issus du paquetage flash.net. Flash CS3 est configur afin dimporter automatiquement toutes les classes issues de lAPI du lecteur Flash. Il nest donc pas ncessaire dimporter manuellement les classes lorsque nous codons au sein de lenvironnement auteur. Un fichier implicitImports.xml situ au sein du rpertoire dinstallation de Flash CS3 (C:\Program Files\Adobe\Adobe Flash CS3\fr\Configuration\ActionScript 3.0) contient toutes les dfinitions de classe importer :

Afin de crer un clip dynamiquement nous pouvons crire directement sur une image du scnario :var monClip:MovieClip = new MovieClip();

Si nous plaons notre code lextrieur de Flash au sein de classes, nous devons explicitement importer les classes ncessaires :import flash.display.MovieClip; var monClip:MovieClip = new MovieClip();

Dans cet ouvrage nous nimporterons pas les classes du lecteur lorsque nous programmerons dans lenvironnement auteur de Flash. A linverse ds lintroduction des classes au sein du chapitre 8 intitul Programmation oriente objet, nous importerons explicitement les classes utilises.

A retenir

3 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Le langage ActionScript 3 englobe deux composantes : le cur du langage ActionScript et linterface de programmation du lecteur Flash. Le cur du langage est dfini par la spcification ECMAScript.

Machines virtuellesLe code ActionScript est interprt par une partie du lecteur Flash appele machine virtuelle. Cest cette dernire qui se charge de retranscrire en langage machine le code binaire (ActionScript byte code) gnr par le compilateur. Les prcdentes versions du lecteur Flash intgraient une seule machine virtuelle appele AVM1 afin dinterprter le code ActionScript 1 et 2. En ralit, le code binaire gnr par le compilateur en ActionScript 1 et 2 tait le mme, cest la raison pour laquelle nous pouvions faire cohabiter au sein dun mme projet ces deux versions du langage ActionScript. La figure 2-2 illustre la machine virtuelle 1 (AVM1) prsente dans le lecteur Flash 8 :

Figure 2-2. AVM1 au sein du lecteur Flash 8. Le langage ActionScript 3 nest pas compatible avec cette premire machine virtuelle, pour des raisons videntes de rtrocompatibilit, le lecteur Flash 9 embarque donc deux machines virtuelles. Lors de la lecture dun SWF, le lecteur slectionne automatiquement la machine virtuelle approprie afin dinterprter le code ActionScript prsent au sein du SWF. Ainsi, une application ActionScript 1 et 2 sera interprte au sein du lecteur Flash 9 par la machine virtuelle 1 (AVM1) et ne bnficiera daucune optimisation des performances.

4 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

La figure 2-3 prsente les deux machines virtuelles au sein du lecteur Flash 9 :

Figure 2-3. Le lecteur Flash 9 et les deux machines virtuelles AVM1 et AVM2. Seules les animations compiles en ActionScript 3 pourront bnficier des optimisations ralises par la nouvelle machine virtuelle (AVM2).

A retenir Les prcdentes versions du lecteur Flash intgraient une seule machine virtuelle afin dinterprter le code ActionScript 1 et 2. La machine virtuelle 1 (AVM1) interprte le code ActionScript 1 et 2. La machine virtuelle 2 (AVM2) interprte seulement le code ActionScript 3. Le lecteur Flash intgre les deux machines virtuelles (AVM1 et AVM2). Le langage ActionScript 3 ne peut pas cohabiter avec les prcdentes versions dActionScript.

Traduction dynamiqueAfin doptimiser les performances, la machine virtuelle 2 (AVM2) du lecteur Flash 9 intgre un mcanisme innovant de compilation du code la vole. Bien que le terme puisse paratre tonnant, ce principe appel gnralement traduction dynamique permet dobtenir de meilleures performances dexcution du code en compilant ce dernier lexcution. Dans les prcdentes versions du lecteur Flash, le code prsent au sein du SWF tait directement retranscrit par la machine virtuelle en 5 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

langage machine sans aucune optimisation lie la plateforme en cours. En ActionScript 3 la machine virtuelle retranscrit le code binaire (ActionScript byte code) en langage machine laide dun compilateur la vole appel couramment compilateur la vole. (Just-in-time compiler). Ce dernier permet de compiler uniquement le code utilis et de manire optimise selon la plateforme en cours. La machine virtuelle peut donc optimiser les instructions pour un processeur spcifique tout en prenant en considration les diffrentes contraintes de la plateforme. Pour plus dinformations lies la compilation lexcution, rendez vous ladresse suivante : http://en.wikipedia.org/wiki/Just-in-time_compilation http://fr.wikipedia.org/wiki/Compilation_%C3%A0_la_vol%C3%A9e

Gestion des types lexcutionActionScript 2 introduit au sein de Flash MX 2004 la notion de typage fort. Cela consistait associer un type de donnes une variable laide de la syntaxe suivante :variable:Type

Dans le code suivant, nous tentions daffecter une chane une variable de type Number :var distance:Number = "150";

Lerreur suivante tait gnre la compilation :Incompatibilit de types dans l'instruction d'affectation : String dtect au lieu de Number.

En ActionScript 3, nous bnficions du mme mcanisme de vrification des types la compilation. En compilant le mme code en ActionScript 3, lerreur suivante est gnre :1067: Contrainte implicite d'une valeur du type String vers un type sans rapport Number.

Ce comportement est appel Mode prcis dans Flash CS3 et peut tre dsactiv par lintermdiaire du panneau Paramtres dActionScript 3.0. A travers le panneau Paramtres de publication, puis de longlet Flash, nous cliquons sur le bouton Paramtres. Nous obtenons un panneau Paramtres dActionScript 3 contenant deux options lies aux erreurs comme lillustre la figure 2-4 :

6 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Figure 2-4. Options du compilateur ActionScript 3. Nous remarquons que par dfaut, le Mode prcis est activ, nous reviendrons trs vite sur le Mode avertissements. En dcochant la case Mode prcis, nous dsactivons la vrification des types la compilation afin de dcouvrir un comportement extrmement important apport par ActionScript 3. En testant le code suivant en mode non prcis, nous remarquons quaucune erreur de compilation nest gnre :var distance:Number = "150";

A lexcution, la machine virtuelle 2 (AVM2) convertit automatiquement la chane de caractres 150 en un nombre entier de type int. Afin de vrifier cette conversion automatique, nous pouvons utiliser la fonction describeType du paquetage flash.utils :var distance:Number = "150"; /* affiche : */ trace( describeType ( distance ) );

La fonction describeType renvoie un objet XML dcrivant le type de la variable. Nous pouvons remarquer que lattribut name du nud type renvoie int. En modifiant la chane de caractres nous obtenons une conversion automatique vers le type Number :var distance:Number = "150.5"; /* affiche : */

7 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

trace( describeType ( distance ) );

Si nous tentons daffecter un autre type de donnes celle-ci, la machine virtuelle 2 (AVM2) conserve le type Number et convertit implicitement les donnes lexcution. Contrairement au mode prcis, ce comportement de vrification des types lexcution ne peut pas tre dsactiv. Nous pourrions ainsi en conclure de toujours conserver le mode prcis afin de ne pas tre surpris par ce comportement, mais certaines erreurs de types ne peuvent tre dtectes par le compilateur car celles-ci ninterviennent qu lexcution. Dans le code suivant, le compilateur ne dtecte aucune erreur :var tableauDonnees:Array = [ "150", "250" ]; // l'entre du tableau est automatiquement convertie en int var distance:Number = tableauDonnees[0];

A lexcution, la chane de caractres prsente lindex 0 est automatiquement convertie en int. Cette conversion reste silencieuse tant que celle-ci russit, le cas chant une erreur lexcution est leve. Dans le code suivant, nous tentons de stocker une chane de caractres au sein dune variable de type MovieClip :var tableauDonnees:Array = [ "clip", "250" ]; // lve une erreur l'excution var clip:MovieClip = tableauDonnees[0];

A lexcution, la machine virtuelle 2 (AVM2) tente de convertir la chane en MovieClip et choue, lerreur lexcution suivante est leve :TypeError: Error #1034: Echec de la contrainte de type : conversion de "clip" en flash.display.MovieClip impossible.

Nous pouvons alors nous interroger sur lintrt dun tel comportement, pourquoi la machine virtuelle svertue-t-elle conserver les types lexcution et convertit automatiquement les donnes ? Afin de garantir des performances optimales, la machine virtuelle 2 (AVM2) sappuie sur les types dfinis par le dveloppeur. Ainsi, lorsque nous typons une variable, loccupation mmoire est optimise spcifiquement pour ce type, ainsi que les instructions processeur.

8 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Il ne faut donc pas considrer ce comportement comme un dsagrment mais comme un avantage contribuant de meilleures performances. Ce comportement diffre dActionScript 2, o la machine virtuelle 1 (AVM1) valuait dynamiquement tous les types lexcution, aucune optimisation ntait ralise. Le typage des variables ntait quune aide la compilation. La grande nouveaut lie ActionScript 3 rside donc dans lintrt du typage la compilation comme lexcution. En associant un type une variable en ActionScript 3 nous bnficions dune vrification des types la compilation et dune optimisation des calculs raliss par le processeur et dune meilleure optimisation mmoire. Il est donc primordial de toujours typer nos variables en ActionScript 3, les performances en dpendent trs nettement. Nous typerons systmatiquement nos variables durant lensemble de louvrage. Voici un exemple permettant de justifier cette dcision : Une simple boucle utilise une variable dincrmentation i de type int :var debut:Number = getTimer(); for ( var i:int = 0; i< 500000; i++ ) { } // affiche : 5 trace( getTimer() - debut );

La boucle ncessite 5 millisecondes pour effectuer 500 000 itrations. Sans typage de la variable i, la boucle suivante ncessite 14 fois plus de temps sexcuter :var debut:Number = getTimer(); for ( var i = 0; i< 500000; i++ ) { } // affiche : 72 trace( getTimer() - debut );

9 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Dans le code suivant, la variable prenom ne possde pas de type spcifique, la machine virtuelle doit valuer elle-mme le type ce qui ralentit le temps dexcution :var debut:Number = getTimer(); var prenom = "Bobby"; var prenomRaccourci:String; for ( var i:int = 0; i< 500000; i++ ) { prenomRaccourci = prenom.substr ( 0, 3 ); } // affiche : 430 trace( getTimer() - debut ); // affiche : Bob trace ( prenomRaccourci );

En typant simplement la variable prenom nous divisons le temps dexcution de presque deux fois :var debut:Number = getTimer(); var prenom:String = "Bobby"; var prenomRaccourci:String; for ( var i:int = 0; i< 500000; i++ ) { prenomRaccourci = prenom.substr ( 0, 3 ); } // affiche : 232 trace( getTimer() - debut ); // affiche : Bob trace ( prenomRaccourci );

Au sein du panneau Paramtres ActionScript 3, nous pouvons apercevoir un deuxime mode de compilation appel Mode avertissements. Ce dernier permet dindiquer plusieurs types derreurs comme par exemple les erreurs lies la migration de code. Supposons que nous tentions dutiliser la mthode attachMovie dans un projet ActionScript 3 :var ref:MovieClip = this.attachMovie ("clip", "monClip", 0);

Au lieu dindiquer un simple message derreur, le compilateur nous renseigne que notre code nest pas compatible avec ActionScript 3 et nous propose son quivalent. 10 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Le code prcdent gnre donc le message derreur suivant la compilation :Warning: 1060: Problme de migration : la mthode 'attachMovie' n'est plus prise en charge. Si le nom de la sous-classe de MovieClip est A, utilisez var mc= new A(); addChild(mc). Pour plus d'informations, consultez la classe DisplayObjectContainer.

Le Mode avertissements permet davertir le dveloppeur de certains comportements lexcution risquant de le prendre au dpourvu. Attention, les avertissements nempchent ni la compilation du code ni son excution, mais avertissent simplement que le rsultat de lexcution risque de ne pas tre celui attendu. Dans le code suivant, un dveloppeur tente de stocker une chane de caractre au sein dune variable de type Boolean :var prenom:Boolean = "Bobby";

A la compilation, lavertissement suivant est affich :Warning: 3590: String utilise alors qu'une valeur boolenne est attendue. L'expression va tre transtype comme boolenne.

Il est donc fortement conseill de conserver le Mode prcis ainsi que le mode avertissements afin dintercepter un maximum derreurs la compilation. Comme nous lavons vu prcdemment, le lecteur Flash 9 nchoue plus en silence et lve des erreurs lexcution. Nous allons nous intresser ce nouveau comportement dans la partie suivante.

A retenir Il est possible de dsactiver la vrification de type la compilation. Il nest pas possible de dsactiver la vrification de type lexcution. Le typage en ActionScript 2 se limitait une aide la compilation. Le typage en ActionScript 3 aide la compilation et lexcution. Dans un souci doptimisation des performances, il est fortement recommand de typer les variables en ActionScript 3. Il est fortement conseill de conserver le mode prcis ainsi que le mode avertissements afin dintercepter un maximum derreurs la compilation.

Erreurs lexcutionNous avons trait prcdemment des erreurs de compilation laide du mode prcis et abord la notion derreurs lexcution. 11 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Une des grandes nouveauts du lecteur Flash 9 rside dans la gestion des erreurs. Souvenez-vous, les prcdentes versions du lecteur Flash ne levaient aucune erreur lexcution et chouaient en silence. En ActionScript 3 lorsque lexcution du programme est interrompue de manire anormale, on dit quune erreur dexcution est leve. Afin de gnrer une erreur lexcution nous pouvons tester le code suivant :// dfinition d'une variable de type MovieClip // sa valeur par dfaut est null var monClip:MovieClip; // nous tentons de rcuprer le nombre d'images du scnario du clip // il vaut null, une erreur d' excution est leve var nbImages:int = monClip.totalFrames;

La fentre de sortie affiche lerreur suivante :TypeError: Error #1009: Il est impossible d'accder la proprit ou la mthode d'une rfrence d'objet nul.

Afin de grer cette erreur, nous pouvons utiliser un bloc try catch :// dfinition d'une variable de type MovieClip // sa valeur par dfaut est null var monClip:MovieClip; var nbImages:int; // grce au bloc try catch nous pouvons grer l'erreur try { nbImages = monClip.totalFrames; } { trace ( "une erreur d'excution a t leve !"); } catch ( pErreur:Error )

Bien entendu, nous nutiliserons pas systmatiquement les blocs try catch afin dviter dafficher les erreurs lexcution. Certains tests simples, que nous dcouvrirons au cours de louvrage, nous permettrons quelque fois dviter davoir recours ces blocs. Dans un contexte derreurs lexcution, il convient de dfinir les deux dclinaisons du lecteur Flash existantes : Version de dbogage (Player Debug) : cette version du lecteur est destine au dveloppement et affiche les erreurs lexcution en ouvrant une fentre spcifique indiquant lerreur en cours. Ce lecteur est install

12 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

automatiquement lors de linstallation de dveloppement Flash CS3 ou Flex Builder 2 et 3.

lenvironnement

de

Version production (Player Release) : cette version du lecteur est disponible depuis le site dAdobe. Les personnes nayant pas denvironnement de dveloppement install utilisent cette version du lecteur. Ce lecteur naffiche pas les erreurs lexcution afin de ne pas interrompre lexprience de lutilisateur.

Avec le lecteur de dbogage, les erreurs non gres par un bloc try catch ouvrent un panneau derreur au sein du navigateur comme lillustre la figure 2-5 :

Figure 2-5. Exemple derreur lexcution. Lorsquune erreur est leve, lexcution du code est alors mise en pause. Nous pouvons alors dcider de continuer lexcution du code bien quune erreur vienne dtre leve ou bien de stopper totalement lexcution de lapplication.

A retenir Le lecteur Flash 9 lve des erreurs lexcution. Ces erreurs ouvrent avec le lecteur de dbogage une fentre indiquant lerreur au sein du navigateur. Toutes les mthodes de lAPI du lecteur en ActionScript 3 peuvent lever des erreurs lexcution. Le lecteur Flash 9 nchoue plus en silence, le dbogage est donc facilit.

Nouveaux types primitifsEn ActionScript 2, seul le type Number existait afin de dfinir un nombre, ainsi pour stocker un nombre entier ou dcimal le type Number tait utilis :var age:Number = 20; var vitesse:Number = 12.8;

13 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Aucune distinction ntait faite entre les nombres entiers, dcimaux et non ngatifs. ActionScript 3 intgre dsormais trois types afin de reprsenter les nombres : int : reprsente un nombre entier 32 bit (32 bit signed integer) uint : reprsente un nombre entier non sign 32 bit. (32 bit unsigned integer) Number : reprsente un nombre dcimal 64 bit (64-bit IEEE 754 double-precision floating-point number)

Notons que les deux nouveaux types int et uint ne prennent pas de majuscule, contrairement au type Number dj prsent au sein dActionScript 2. Une variable de type int peut contenir un nombre oscillant entre -2147483648 et 2147483648 :// affiche : -2147483648 trace( int.MIN_VALUE ); // affiche : 2147483648 trace( int.MAX_VALUE );

Une variable de type uint peut contenir un nombre entier oscillant entre 0 et 4294967295 :// affiche : 0 trace( uint.MIN_VALUE ); // affiche : 4294967295 trace( uint.MAX_VALUE );

Attention, la machine virtuelle ActionScript 3 conserve les types lexcution, si nous tentons de stocker un nombre virgule flottante au sein dune variable de type int ou uint, le nombre est automatiquement converti en entier par la machine virtuelle :var age:int = 22.2; // affiche : 22 trace ( age );

Notons, que la machine virtuelle arrondi lentier infrieur :var age:int = 22.8; // affiche : 22 trace ( age );

Cette conversion automatique assure par la machine virtuelle savre beaucoup plus rapide que la mthode floor de la classe Math.

14 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Dans le code suivant, nous arrondissons lentier au sein dune boucle laide de la mthode floor, la boucle ncessite 111 millisecondes :var distance:Number = 45.2; var arrondi:Number; var debut:Number = getTimer(); for ( var i:int = 0; i< 500000; i++ ) { arrondi = Math.floor ( distance ); } // affiche : 111 trace( getTimer() - debut );

A prsent, nous laissons la machine virtuelle grer pour nous larrondi du nombre :var distance:Number = 45.2; var arrondi:int; var debut:Number = getTimer(); for ( var i:int = 0; i< 500000; i++ ) { arrondi = distance; } // affiche : 8 trace( getTimer() - debut ); // affiche : 45 trace( arrondi );

Nous obtenons le mme rsultat en 8 millisecondes, soit un temps dexcution presque 14 fois plus rapide. Attention, cette astuce nest valable uniquement dans le cas de nombres positifs. Dans le code suivant, nous remarquons que la mthode floor de la classe Math ne renvoie pas la mme valeur que la conversion en int par la machine virtuelle :var distance:int = -3.2; // affiche : -3 trace(distance); var profondeur:Number = Math.floor (-3.2); // affiche : -4

15 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

trace( profondeur );

Partant du principe quune distance est toujours positive, nous pouvons utiliser le type uint qui offre dans ce cas prcis des performances similaires au type int :var arrondi:uint;

Malheureusement, le type uint savre gnralement beaucoup plus lent, ds lors quune opration mathmatique est effectue. En revanche, le type Number savre plus rapide que le type int lors de division. Lors de la dfinition dune boucle, il convient de toujours prfrer lutilisation dune variable dincrmentation de type int :var debut:Number = getTimer(); for ( var i:int = 0; i< 5000000; i++ ) { } // affiche : 61 trace( getTimer() - debut );

A linverse, si nous utilisons un type uint, les performances chutent de presque 400% :var debut:Number = getTimer(); for ( var i:uint = 0; i< 5000000; i++ ) { } // affiche : 238 trace( getTimer() - debut );

Gardez lesprit, quen cas dhsitation, il est prfrable dutiliser le type Number :var debut:Number = getTimer(); for ( var i:Number = 0; i< 5000000; i++ ) { } // affiche : 102 trace( getTimer() - debut );

16 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Nous obtenons ainsi un compromis en termes de performances entre le type int et uint. De manire gnrale, il est prfrable dviter le type uint. La mme optimisation peut tre obtenue pour calculer larrondi suprieur. Nous prfrons laisser la machine virtuelle convertir lentier infrieur puis nous ajoutons 1 :var distance:Number = 45.2; var arrondi:int; var debut:Number = getTimer(); for ( var i:int = 0; i< 500000; i++ ) { arrondi = distance + 1; } // affiche : 12 trace( getTimer() - debut ); // affiche : 46 trace( arrondi );

En utilisant la mthode ceil de la classe Math, nous ralentissons les performances denviron 300% :var distance:Number = 45.2; var arrondi:Number; var debut:Number = getTimer(); for ( var i:int = 0; i< 500000; i++ ) { arrondi = Math.ceil ( distance ); } // affiche : 264 trace( getTimer() - debut ); // affiche : 46 trace( arrondi );

Pour plus dastuces lies loptimisation, rendez-vous ladresse suivante : http://lab.polygonal.de/2007/05/10/bitwise-gems-fast-integer-math/

A retenir17 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Le type uint permet de reprsenter un nombre entier 32 bit non ngatif. Il est conseill dutiliser le type int pour les nombres entiers, son utilisation permet doptimiser les performances. Il est dconseill dutiliser le type uint. En cas dhsitation, il convient dutiliser le type Number. Le type Number permet de reprsenter un nombre dcimal 64 bit.

Le type int permet de reprsenter un nombre entier 32 bit.

Valeurs par dfautIl est important de noter que les valeurs undefined et null ont un comportement diffrent en ActionScript 3. Dsormais, une variable renvoie undefined uniquement lorsque celle-ci nexiste pas o lorsque nous ne la typons pas :var prenom; // affiche : undefined trace( prenom );

Lorsquune variable est type mais ne possde aucune valeur, une valeur par dfaut lui est attribue :var var var var var var var condition:Boolean; total:int; couleur:uint; resultat:Number; personnage:Object; prenom:String; donnees:*;

// affiche : false trace( condition ); // affiche : 0 trace( total ); // affiche : 0 trace( couleur ); // affiche : NaN trace( resultat ); // affiche : null trace( personnage ); // affiche : null trace( prenom ); // affiche : undefined trace( donnees );

Le tableau suivant illustre les diffrentes valeurs attribues par dfaut aux types de donnes : 18 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Type de donnes Boolean int Number Object String uint Non type (quivalent au type *) Autres types

Valeur par dfaut false 0 NaN null null 0 undefined null

Tableau 1. Valeurs par dfaut associes aux types de donnes. De la mme manire, si nous tentons daccder une proprit inexistante au sein dune instance de classe non dynamique telle String, nous obtenons une erreur la compilation :var prenom:String = "Bob"; // gnre une erreur la compilation trace( prenom.proprieteInexistante );

Si nous tentons daccder une proprit inexistante, au sein dune instance de classe dynamique, le compilateur ne procde aucune vrification et nous obtenons la valeur undefined pour la proprit cible :var objet:Object = new Object(); // affiche : undefined trace( objet.proprieteInexistante );

Attention, une exception demeure pour les nombres, qui ne peuvent tre null ou undefined. Si nous typons une variable avec le type Number, la valeur par dfaut est NaN :var distance:Number; // affiche : NaN trace( distance );

19 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

En utilisant le type int ou uint, les variables sont automatiquement initialises 0 :var distance:int; var autreDistance:uint; // affiche : 0 trace( distance ); // affiche : 0 trace( autreDistance );

A retenir

Une variable renvoie undefined uniquement lorsque celle-ci nexiste pas ou nest pas type. Lorsquune variable est type mais ne possde aucune valeur, la machine virtuelle attribue automatiquement une valeur par dfaut.

Nouveaux types compositesDeux nouveaux types composites sont intgrs en ActionScript 3 : Les expressions rgulires (RegExp) : elles permettent deffectuer des recherches complexes sur des chanes de caractres. Nous reviendrons sur les expressions rgulires au cours de certains exercices. E4X (ECMAScript 4 XML) : la spcification ECMAScript 4 intgre un objet XML en tant quobjet natif. Nous reviendrons sur le format XML et E4X au cours de certains exercices.

Nouveaux mots-clsLe mot cl is introduit par ActionScript 3 remplace lancien mot-cl instanceof des prcdentes versions dActionScript. Ainsi pour tester si une variable est dun type spcifique nous utilisons le mot-cl is :var tableauDonnees:Array = [5654, 95, 54, 687968, 97851]; // affiche : true trace( tableauDonnees is Array ); // affiche : true trace( tableauDonnees is Object ); // affiche : false trace( tableauDonnees is MovieClip );

Un autre mot-cl nomm as fait aussi son apparition. Ce dernier permet de transtyper un objet vers un type spcifique.

20 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Dans le code suivant, nous dfinissons une variable de type DisplayObject, mais celle-ci contient en ralit une instance de MovieClip :var monClip:DisplayObject = new MovieClip();

Si nous tentons dappeler une mthode de la classe MovieClip sur la variable monClip, une erreur la compilation est gnre. Afin de pouvoir appeler la mthode sans que le compilateur ne nous bloque, nous pouvons transtyper vers le type MovieClip :// transtypage en MovieClip (monClip as MovieClip).gotoAndStop(2);

En cas dchec du transtypage, le rsultat du transtypage renvoie null, nous pouvons donc tester si le transtypage russit de la manire suivante :var monClip:DisplayObject = new MovieClip(); // affiche : true trace( MovieClip(monClip) != null );

Nous aurions pu transtyper avec lcriture traditionnelle suivante :var monClip:DisplayObject = new MovieClip(); // transtypage en MovieClip MovieClip(monClip).gotoAndStop(2);

En termes de performances, le mot cl as savre presque deux fois plus rapide. En cas dchec lors du transtypage lcriture prcdente ne renvoie pas null mais lve une erreur lexcution.

FonctionsActionScript 3 intgre de nouvelles fonctionnalits lies la dfinition de fonctions. Nous pouvons dsormais dfinir des paramtres par dfaut pour les fonctions. Prenons le cas dune fonction affichant un message personnalis :function alerte ( pMessage:String ):void { trace( pMessage ); }

Cette fonction alerte accepte un paramtre accueillant le message afficher. Si nous souhaitons lexcuter nous devons obligatoirement passer un message :alerte ("voici un message d'alerte !");

21 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Si nous omettons le paramtre :// gnre une erreur la compilation alerte ();

Lerreur la compilation suivante est gnre :1136: Nombre d'arguments incorrect. 1 attendus.

ActionScript 3 permet de dfinir une valeur par dfaut pour le paramtre :function alerte ( pMessage:String="message par dfaut" ):void { trace( pMessage ); }

Une fois dfinie, nous pouvons appeler la fonction alerte sans passer de paramtres :function alerte ( pMessage:String="message par dfaut" ):void { trace( pMessage ); } // affiche : message par dfaut alerte ();

Lorsque nous passons un paramtre spcifique, celui-ci crase la valeur par dfaut :function alerte ( pMessage:String="message par dfaut" ):void { trace( pMessage ); } // affiche : un message personnalis ! alerte ( "un message personnalis !" );

En plus de cela, ActionScript 3 intgre un nouveau mcanisme li aux paramtres alatoires. Imaginons que nous devions crer une fonction pouvant accueillir un nombre alatoire de paramtres. En ActionScript 1 et 2, nous ne pouvions lindiquer au sein de la signature de la fonction. Nous dfinissions donc une fonction sans paramtre, puis nous utilisions le tableau arguments regroupant lensemble des paramtres : 22 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

function calculMoyenne ():Number { var lng:Number = arguments.length; var total:Number = 0; for (var i:Number = 0; i< lng; i++) { total += arguments[i]; } return total / lng; } var moyenne:Number = calculMoyenne ( 50, 48, 78, 20, 90 ); // affiche : 57.2 trace( moyenne );

Bien que cette criture puisse paratre trs souple, elle posait nanmoins un problme de relecture du code. En relisant la signature de la fonction, un dveloppeur pouvait penser que la fonction calculMoyenne nacceptait aucun paramtre, alors que ce ntait pas le cas. Afin de rsoudre cette ambigut, ActionScript 3 introduit un mot-cl permettant de spcifier dans les paramtres que la fonction en cours reoit un nombre variable de paramtres. Pour cela nous ajoutons trois points de suspensions en tant que paramtre de la fonction, suivi dun nom de variable de notre choix. Le mme code scrit donc de la manire suivante en ActionScript 3 :function calculMoyenne ( ...parametres ):Number { var lng:int = parametres.length; var total:Number = 0; for (var i:Number = 0; i< lng; i++) { total += parametres[i]; } return total / lng; } var moyenne:Number = calculMoyenne ( 50, 48, 78, 20, 90 );

23 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

// affiche : 57.2 trace( moyenne );

En relisant le code prcdent, le dveloppeur ActionScript 3 peut facilement dtecter les fonctions accueillant un nombre de paramtres alatoires.

Contexte dexcutionAfin que vous ne soyez pas surpris, il convient de sattarder quelques instants sur le nouveau comportement des fonctions passes en rfrence. Souvenez-vous, en ActionScript 1 et 2, nous pouvions passer en rfrence une fonction, celle-ci perdait alors son contexte dorigine et pousait comme contexte le nouvel objet :var personnage:Object = { age : 25, nom : "Bobby" }; // la fonction parler est passe en rfrence personnage.parler = parler; function parler ( ) { trace("bonjour, je m'appelle " + this.nom + ", j'ai " + this.age + " ans"); } // appel de la mthode // affiche : bonjour, je m'appelle Bobby, j'ai 25 ans personnage.parler();

En ActionScript 3, la fonction parler conserve son contexte dorigine et ne sexcute donc plus dans le contexte de lobjet personnage :var personnage:Object = { age : 25, nom : "Bobby" }; // la fonction parler est passe en rfrence personnage.parler = parler; function parler ( ) { trace("bonjour, je m'appelle " + this.nom + ", j'ai " + this.age + " ans"); } // appel de la mthode // affiche : bonjour, je m'appelle undefined, j'ai undefined ans personnage.parler();

De nombreux dveloppeurs ActionScript se basaient sur ce changement de contexte afin de rutiliser des fonctions.

24 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Nous devrons donc garder lesprit ce nouveau comportement apport par ActionScript 3 durant lensemble de louvrage.

BouclesActionScript 3 introduit une nouvelle boucle permettant ditrer au sein des proprits dun objet et daccder directement au contenu de chacune dentre elles. Dans le code suivant, nous affichons les proprits de lobjet personnage laide dune boucle for in :var personnage:Object = { prenom : "Bobby", age : 50 }; for (var p:String in personnage) { /* affiche : age prenom */ trace( p ); }

Attention, lordre dnumration des proprits peut changer selon les machines. Il est donc essentiel de ne pas se baser sur lordre dnumration des proprits. Notons que la boucle for in en ActionScript 3 ne boucle plus de la dernire entre la premire comme ctait le cas en ActionScript 1 et 2, mais de la premire la dernire. Nous pouvons donc dsormais utiliser la boucle for in afin ditrer au sein dun tableau sans se soucier du fait que la boucle parte de la fin du tableau :var tableauDonnees:Array = [ 5654, 95, 54, 687968, 97851]; for ( var p:String in tableauDonnees ) { /* affiche : 5654 95 54 687968 97851 */ trace( tableauDonnees[p] ); }

25 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

La boucle for each accde elle, directement au contenu de chaque proprit :var personnage:Object = { prenom : "Bobby", age : 50 }; for each ( var p:* in personnage ) { /* affiche : 50 Bobby */ trace( p ); }

Nous pouvons donc plus simplement itrer au sein du tableau laide de la nouvelle boucle for each :var tableauDonnees:Array = [ 5654, 95, 54, 687968, 97851 ]; for each ( var p:* in tableauDonnees ) { /* affiche : 5654 95 54 687968 97851 */ trace( p ); }

Nous allons nous intresser dans la prochaine partie au concept de ramasse-miettes qui savre trs important en ActionScript 3.

Enrichissement de la classe ArrayLa classe Array bnficie de nouvelles mthodes en ActionScript 3 facilitant la manipulation de donnes. La mthode forEach permet ditrer simplement au sein du tableau :// Array.forEach procde une navigation simple // sur chaque lement l'aide d'une fonction spcifique var prenoms:Array = [ "bobby", "willy", "ritchie" ]; function navigue ( element:*, index:int, tableau:Array ):void { trace ( element + " : " + index + " : " + tableau); }

26 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

/* affiche : bobby : 0 : bobby,willy,ritchie willy : 1 : bobby,willy,ritchie ritchie : 2 : bobby,willy,ritchie */ prenoms.forEach( navigue );

Toutes ces nouvelles mthodes fonctionnent sur le mme principe. Une fonction de navigation est passe en paramtre afin ditrer et de traiter les donnes au sein du tableau. La mthode every excute la fonction de navigation jusqu' ce que celle ci ou llment parcouru renvoient false. Il est donc trs simple de dterminer si un tableau contient des valeurs attendues. Dans le code suivant, nous testons si le tableau donnees contient uniquement des nombres :var donnees:Array = [ 12, "bobby", "willy", 58, "ritchie" ]; function navigue ( element:*, index:int, tableau:Array ):Boolean { return ( element is Number ); } var tableauNombres:Boolean = donnees.every ( navigue ); // affiche : false trace( tableauNombres );

La mthode map permet la cration dun tableau relatif au retour de la fonction de navigation. Dans le code suivant, nous appliquons un formatage aux donnes du tableau prenoms. Un nouveau tableau de prnoms formats est cr :var prenoms:Array = ["bobby", "willy", "ritchie"]; function navigue ( element:*, index:int, tableau:Array ):String { return element.charAt(0).toUpperCase()+element.substr(1).toLowerCase(); } // on cre un tableau partir du retour de la fonction navigue var prenomsFormates:Array = prenoms.map ( navigue ); // affiche : Bobby,Willy,Ritchie trace( prenomsFormates );

La mthode map ne permet pas de filtrer les donnes. Toutes les donnes du tableau source sont ainsi places au sein du tableau gnr. 27 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Si nous souhaitons filtrer les donnes, nous pouvons appeler la mthode filter. Dans le code suivant nous filtrons les utilisateurs mineurs et obtenons un tableau dutilisateurs majeurs :var utilisateurs:Array = [ { prenom : "Bobby", age : 18 }, { prenom : "Willy", age : 20 }, { prenom : "Ritchie", age : 16 }, { prenom : "Stevie", age : 15 } ]; function navigue ( element:*, index:int, tableau:Array ):Boolean { return ( element.age >= 18 ); } var utilisateursMajeurs:Array = utilisateurs.filter ( navigue ); function parcourir ( element:*, index:int, tableau:Array ):void { trace ( element.prenom, element.age ); } /* affiche : Bobby 18 Willy 20 */ utilisateursMajeurs.forEach( parcourir );

La mthode some permet de savoir si un lment existe au moins une fois au sein du tableau. La fonction de navigation est excute jusqu ce que celle ci ou un lment du tableau renvoient true :var utilisateurs:Array = [ { { { { prenom prenom prenom prenom : : : : "Bobby", age : 18, sexe : "H" }, "Linda", age : 18, sexe : "F" }, "Ritchie", age : 16, sexe : "H"}, "Stevie", age : 15, sexe : "H" } ]

function navigue ( element:*, index:int, tableau:Array ):Boolean { return ( element.sexe == "F" ); } // y'a t'il une femme au sein du tableau d'utilisateurs ? var resultat:Boolean = utilisateurs.some ( navigue ); // affiche : true trace( resultat );

28 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

Les mthodes indexOf et lastIndexOf font elles aussi leur apparition au sein de la classe Array, celles-ci permettent de rechercher si un lment existe et dobtenir sa position :var utilisateurs:Array = [ "Bobby", "Linda", "Ritchie", "Stevie", "Linda" ]; var position:int = utilisateurs.indexOf ("Linda"); var positionFin:int = utilisateurs.lastIndexOf ("Linda"); // affiche : 1 trace( position ); // affiche : 4 trace( positionFin );

Les mthodes indexOf et lastIndexOf permettent de rechercher un lment de type primitif mais aussi de type composite. Nous pouvons ainsi rechercher la prsence de rfrences au sein dun tableau :var monClip:DisplayObject = new MovieClip(); var monAutreClip:DisplayObject = new MovieClip(); // une rfrence au clip monClip est place au sein du tableau var tableauReferences:Array = [ monClip ]; var position:int = tableauReferences.indexOf (monClip); var autrePosition:int = tableauReferences.lastIndexOf (monAutreClip); // affiche : 0 trace( position ); // affiche : -1 trace( autrePosition );

Nous reviendrons sur certaines de ces mthodes au sein de louvrage.

A retenir Pensez utiliser les nouvelles mthodes de la classe Array afin de traiter plus facilement les donnes au sein dun tableau.

Ramasse-miettesTout au long de louvrage nous reviendrons sur le concept de ramassemiettes. Bien que le terme puisse paraitre fantaisiste, ce mcanisme va savrer extrmement important durant nos dveloppements ActionScript 3. Pendant la dure de vie dun programme, certains objets peuvent devenir inaccessibles. Afin, de ne pas saturer la mmoire, un mcanisme de suppression des objets inutiliss est intgr au sein du 29 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

lecteur Flash. Ce mcanisme est appel ramasse-miettes ou plus couramment Garbage collector en Anglais. Afin de bien comprendre ce mcanisme, nous dfinissons un simple objet rfrenc par une variable personnage :var personnage:Object = { prenom : "Bobby", age : 50 };

Pour rendre cet objet inaccessible et donc ligible la suppression par le ramasse-miettes, nous pourrions tre tents dutiliser le mot cl delete :var personnage:Object = { prenom : "Bobby", age : 50 }; // gnre une erreur la compilation delete personnage;

Le code prcdent, gnre lerreur de compilation suivante :1189: Tentative de suppression de la proprit fixe personnage. proprits dfinies dynamiquement peuvent tre supprimes. Seules les

Cette erreur traduit une modification du comportement du mot cl delete en ActionScript 3, qui ne peut tre utilis que sur des proprits dynamiques dobjets dynamiques. Ainsi, le mot cl delete pourrait tre utilis pour supprimer la proprit prenom au sein de lobjet personnage :var personnage:Object = { prenom : "Bobby", age : 50 }; // affiche : Bobby trace( personnage.prenom ); // supprime la proprit prenom delete ( personnage.prenom ); // affiche : undefined trace( personnage.prenom );

Afin de supprimer correctement une rfrence, nous devons affecter la valeur null celle-ci :var personnage:Object = { prenom : "Bobby", age : 50 }; // supprime la rfrence vers lobjet personnage personnage = null;

Lorsque lobjet ne possde plus aucune rfrence, nous pouvons estimer que lobjet est ligible la suppression. Nous devrons donc toujours veiller ce quaucune rfrence ne subsiste vers notre objet, au risque de le voir conserv en mmoire. Attention, laffectation de la valeur null une rfrence ne dclenche en aucun cas le passage du 30 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

ramasse-miettes. Nous rendons simplement lobjet ligible la suppression. Il est important de garder lesprit que le passage du ramasse-miettes reste potentiel. Lalgorithme de nettoyage effectu par ce dernier tant relativement gourmand en termes de ressources, son dclenchement reste limit au cas o le lecteur utiliserait trop de mmoire. Dans le code suivant, nous supprimons une des deux rfrences seulement :var personnage:Object = { prenom : "Bobby", age : 50 }; // copie d'une rfrence au sein du tableau var tableauPersonnages:Array = [ personnage ]; // suppression dune seule rfrence personnage = null;

Une autre rfrence vers lobjet personnage subsiste au sein du tableau, lobjet ne sera donc jamais supprim par le ramasse-miettes :var personnage:Object = { prenom : "Bobby", age : 50 }; // copie d'une rfrence au sein du tableau var tableauPersonnages:Array = [ personnage ]; // supprime une des deux rfrences seulement personnage = null; var personnageOrigine:Object = tableauPersonnages[0]; // affiche : Bobby trace( personnageOrigine.prenom ); // affiche : 50 trace( personnageOrigine.age );

Nous devons donc aussi supprimer la rfrence prsente au sein du tableau afin de rendre lobjet personnage ligible la suppression :var personnage:Object = { prenom : "Bobby", age : 50 }; // copie d'une rfrence au sein du tableau var tableauPersonnages:Array = [ personnage ]; // supprime la premire rfrence personnage = null; // supprime la seconde rfrence tableauPersonnages[0] = null;

Si la situation nous le permet, un moyen plus radical consiste craser le tableau contenant la rfrence :var personnage:Object = { prenom : "Bobby", age : 50 };

31 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

// copie d'une rfrence au sein du tableau var tableauPersonnages:Array = [ personnage ]; // supprime la premire rfrence personnage = null; // crase le tableau stockant la rfrence tableauPersonnages = new Array();

Depuis la version 9.0.115 du lecteur Flash 9, il est possible de dclencher le ramasse-miettes manuellement laide de la mthode gc de la classe System. Notons que cette fonctionnalit nest accessible quau sein du lecteur de dbogage. Nous reviendrons sur cette mthode au cours du prochain chapitre intitul Le modle vnementiel.

A retenir Il est possible de dclencher manuellement le ramasse-miettes au sein du lecteur de dbogage 9.0.115. Afin quun objet soit ligible la suppression par le ramasse-miettes nous devons passer toutes ses rfrences null. Le ramasse-miettes intervient lorsque la machine virtuelle juge cela ncessaire.

Bonnes pratiquesDurant lensemble de louvrage nous ferons usage de certaines bonnes pratiques, dont voici le dtail : Nous typerons les variables systmatiquement afin doptimiser les performances de nos applications et garantir une meilleure gestion des erreurs la compilation. Lors de la dfinition de boucles, nous utiliserons toujours une variable de rfrence afin dviter que la machine virtuelle ne rvalue la longueur du tableau chaque itration. Nous prfrerons donc le code suivant :var tableauDonnees:Array = [ 5654, 95, 54, 687968, 97851]; // stockage de la longueur du tableau var lng:int = tableauDonnees.length; for ( var i:int = 0; i< lng; i++ ) { }

A cette criture non optimise : 32 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

var tableauDonnees:Array = [ 5654, 95, 54, 687968, 97851]; for ( var i:int = 0; i< tableauDonnees.length; i++ ) { }

De la mme manire, nous viterons de redfinir nos variables au sein des boucles. Nous prfrerons lcriture suivante :var tableauDonnees:Array = [5654, 95, 54, 687968, 97851]; var lng:int = tableauDonnees.length; // dclaration de la variable elementEnCours une seule et unique fois var elementEnCours:int; for ( var i:int = 0; i< lng; i++ ) { elementEnCours = tableauDonnees[i]; }

A lcriture suivante non optimise :var tableauDonnees:Array = [5654, 95, 54, 687968, 97851]; for ( var i:int = 0; i< tableauDonnees.length; i++ ) { // dclaration de la variable elementEnCours chaque itration var elementEnCours:int = tableauDonnees[i]; }

Dcouvrons prsent quelques dernires subtilits du langage ActionScript 3.

Autres subtilitsAttention, le type Void existant en ActionScript 2, utilis au sein des signatures de fonctions prend dsormais un v minuscule en ActionScript 3. Une fonction ActionScript 2 ne renvoyant aucune valeur scrivait de la manire suivante :function initilisation ( ):Void { }

33 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

En ActionScript 3, le type void ne prend plus de majuscule :function initilisation ( ):void { }

ActionScript 3 intgre un nouveau type de donnes permettant dindiquer quune variable peut accueillir nimporte quel type de donnes. En ActionScript 2 nous nous contentions de ne pas dfinir de type, en ActionScript 3 nous utilisons le type * :var var var var var var condition:* = true; total:* = 5; couleur:* = 0x990000; resultat:* = 45.4; personnage:* = new Object(); prenom:* = "Bobby";

Nous utiliserons donc systmatiquement le type * au sein dune boucle for each, car la variable p doit pouvoir accueillir nimporte quel type de donnes :var personnage:Object = { prenom : "Bobby", age : 50 }; for each ( var p:* in personnage ) { /* affiche : 50 Bobby */ trace( p ); }

En utilisant un type spcifique pour la variable ditration p, nous risquons de convertir implicitement les donnes itres. Dans le code suivant, nous utilisons le type Boolean pour la variable p:var personnage:Object = { prenom : "Bobby", age : 50 }; for each ( var p:Boolean in personnage ) { /* affiche : true true */ trace( p );

34 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 2 Langage et API - version 0.1.2

}

Le contenu des proprits est automatiquement converti en boolen. Au cas o une donne ne pourrait tre convertie en boolen, le code prcdent pourrait lever une erreur lexcution. Passons prsent aux nouveauts lies linterface de programmation du lecteur Flash. Les deux grandes nouveauts du lecteur Flash 9 concernent la gestion de laffichage ainsi que le modle vnementiel. Au cours du prochain chapitre intitul Le modle vnementiel nous allons nous intresser ce nouveau modle travers diffrents exercices dapplications. Nous apprendrons matriser ce dernier et dcouvrirons comment en tirer profit tout au long de louvrage. Puis nous nous intresserons au nouveau mcanisme de gestion de laffichage appele Liste daffichage au cours du chapitre 4, nous verrons que ce dernier offre beaucoup plus de souplesse en termes de manipulation des objets graphiques et doptimisation de laffichage. Vous tes prt pour la grande aventure ActionScript 3 ?

35 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

3Le modle vnementiel

LHISTOIRE ............................................................................................................ 1 UN NOUVEAU MODELE EVENEMENTIEL ..................................................... 6 TOUT EST VNEMENTIEL ....................................................................................... 8 ECOUTER UN VNEMENT ..................................................................................... 10 LOBJET VNEMENTIEL ....................................................................................... 13 LA CLASSE EVENT................................................................................................. 16 LES SOUS-CLASSES DEVENT ......................................................................... 17 ARRTER LCOUTE DUN VNEMENT ................................................................. 19 MISE EN APPLICATION ........................................................................................... 20 LA PUISSANCE DU COUPLAGE FAIBLE....................................................... 25 SOUPLESSE DE CODE ............................................................................................. 28 ORDRE DE NOTIFICATION .............................................................................. 30 REFERENCES FAIBLES ..................................................................................... 32 SUBTILITES .......................................................................................................... 34

LhistoireActionScript 3 intgre un nouveau modle vnementiel que nous allons tudier ensemble tout au long de ce chapitre. Avant de laborder, rappelons-nous de lancien modle apparu pour la premire fois avec le lecteur Flash 6. Jusqu maintenant nous dfinissions des fonctions que nous passions en rfrence lvnement cout. Prenons un exemple simple, pour couter lvnement onRelease dun bouton nous devions crire le code suivant :monBouton.onRelease = function ()

1 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

{ // affiche : _level0.monBouton trace ( this ); this._alpha = 50; }

Une fonction anonyme tait dfinie sur la proprit onRelease du bouton. Lorsquun clic souris intervenait sur le bouton, le lecteur Flash excutait la fonction que nous avions dfinie et rduisait lopacit du bouton de 50%. Cette criture posait plusieurs problmes. Dans un premier temps, la fonction dfinie sur le bouton ne pouvait pas tre rutilise pour un autre vnement, sur un objet diffrent. Pour pallier ce problme de rutilisation, certains dveloppeurs faisaient appels des rfrences de fonctions afin de grer lvnement :function clicBouton () { // affiche : _level0.monBouton trace (this); this._alpha = 50; } monBouton.onRelease = clicBouton;

Cette criture permettait de rutiliser la fonction clicBouton pour dautres vnements lis diffrents objets, rendant le code plus ar en particulier lors de lcoute dvnements au sein de boucles. Point important, le mot-cl this faisait ici rfrence au bouton et non au scnario sur lequel est dfinie la fonction clicBouton. Le contexte dexcution dorigine de la fonction clicBouton tait donc perdu lorsque celle-ci tait passe en rfrence. La fonction pousait le contexte de lobjet auteur de lvnement. Ensuite lauto rfrence traduite par lutilisation du mot-cl this tait le seul moyen de faire rfrence ce dernier. Ce comportement tait quelque peu droutant pour une personne dcouvrant ActionScript. Voici un exemple mettant en vidence lambigut possible :function clicBouton () { // affiche : _level0.monBouton

2 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

trace ( this ); this._alpha = 50; } monBouton.onRelease = clicBouton; clicBouton();

En excutant la fonction clicBouton de manire traditionnelle le mot-cl this faisait alors rfrence au scnario sur lequel elle tait dfinie, cest dire son contexte dorigine. Le code suivant tait peu digeste et rigide :var ref:MovieClip; for ( var i:Number = 0; i< 50; i++ ) { ref = this.attachMovie ( "monClip", "monClip"+i, i ); ref.onRelease = function () { trace("cliqu"); } }

Les dveloppeurs prfraient donc lutilisation dune fonction spare rutilisable :var ref:MovieClip; for ( var i:Number = 0; i< 50; i++ ) { ref = this.attachMovie ( "monClip", "monClip"+i, i ); ref.onRelease = clicBouton; } function clicBouton ( ) { trace("cliqu"); }

Le mcanisme tait le mme pour la plupart des vnements. Macromedia, lpoque de Flash MX (Flash 6) stait rendu compte du manque de souplesse de ce systme de fonctions dfinies sur les 3 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

vnements, et intgra la notion dcouteurs et de diffuseurs au sein du lecteur Flash 6. Les classes Key, Selection, TextField furent les premires utiliser cette notion de diffuseurs couteurs. Pour couter la saisie dans un champ texte, nous pouvions alors utiliser la syntaxe suivante :var monEcouteur:Object = new Object(); monEcouteur.onChanged = function(pChamp:TextField) { trace ( pChamp._name + " a diffus lvnement onChanged" ); }; monChampTexte.addListener ( monEcouteur );

En appelant la mthode addListener sur notre champ texte nous souscrivions un objet appel ici monEcouteur en tant qucouteur de lvnement onChanged. Une mthode du mme nom devait tre dfinie sur lobjet couteur afin que celle-ci soit excute lorsque lvnement tait diffus. Pour dterminer quelle touche du clavier tait enfonce, nous pouvions crire le code suivant :var monEcouteur:Object = new Object(); monEcouteur.onKeyDown = function() { trace ( "La touche " + String.fromCharCode( Key.getCode() ) + " est enfonce" ); }; Key.addListener ( monEcouteur );

Cette notion de mthode portant le nom de lvnement diffus ntait pas vidente comprendre et souffrait de la faiblesse suivante. Aucun contrle du nom de lvnement ntait effectu la compilation ou lexcution. Le code suivant ne gnrait donc aucune erreur bien quune faute de frappe sy soit glisse :var monEcouteur:Object = new Object(); monEcouteur.onKeydown = function() { trace ( "La touche " + String.fromCharCode( Key.getCode() ) + " est enfonce" );

4 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

}; Key.addListener ( monEcouteur );

Bien que critique, cette approche permettait nanmoins de souscrire un nombre illimit dcouteurs auprs dun vnement, mais aussi de renvoyer des paramtres la mthode couteur. Ces paramtres taient gnralement des informations lies lvnement, par exemple lauteur de lvnement diffus. En 2004, lors de la sortie du lecteur Flash 7 (Flash MX 2004), ActionScript 2 fit son apparition accompagn dun lot de nouveaux composants appels composants V2. Ces derniers tendaient le concept de diffuseurs couteurs en intgrant une mthode addEventListener pour souscrire un couteur auprs dun vnement. Contrairement la mthode addListener, cette mthode stockait chaque couteur dans des tableaux internes diffrents pour chaque vnement. En regardant lvolution dActionScript au cours des dernires annes, nous pouvons nous rendre compte du travail des ingnieurs visant intgrer la notion dcouteurs auprs de tous nouveaux objets crs. ActionScript 3 a t dvelopp dans le but doffrir un langage puissant et standard et prolonge ce concept en intgrant un nouveau modle vnementiel appel Document Object Model (DOM3 Event Model) valable pour tous les objets lis lAPI du lecteur Flash 9. Le W3C dfinit la spcification de ce modle vnementiel. Vous pouvez lire les dernires rvisions ladresse suivante : http://www.w3.org/TR/DOM-Level-3-Events/ Les dveloppeurs ActionScript 2 ayant dj utilis la classe EventDispatcher seront ravis de savoir que toutes les classes de lAPI du lecteur Flash hritent directement de celle-ci. Nous allons donc dcouvrir en profondeur le concept de diffuseurs couteurs et voir comment cela amliore la clart et la souplesse de notre code.

A retenir

5 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

Lancien modle vnementiel a t entirement revu en ActionScript 3. La grande puissance dActionScript 3 rside dans limplmentation native dEventDispatcher.

Un nouveau modle vnementielEn ActionScript 3, le modle vnementiel a clairement volu. La manire dont les objets interagissent entre eux a t entirement revue. Le principe mme de ce modle vnementiel est tir dun modle de conception ou Design Pattern appel Observateur qui dfinit linteraction entre plusieurs objets daprs un dcoupage bien spcifique. Habituellement ce modle de conception peut tre dfini de la manire suivante : Le modle de conception observateur dfinit une relation entre objets de type un plusieurs, de faon que, lorsque un objet change dtat, tous ceux qui en dpendent en soient notifis et soient mis jour automatiquement . Le modle de conception Observateur met en scne trois acteurs : Le sujet Il est la source de lvnement, nous lappellerons sujet car cest lui qui diffuse les vnements qui peuvent tre couts ou non par les observateurs. Ce sujet peut tre un bouton, ou un clip par exemple. Ne vous inquitez pas, tous ces vnements sont documents, la documentation prsente pour chaque objet les vnements diffuss. Lvnement Nous pouvons conceptualiser la notion dvnement comme un changement dtat au sein du sujet. Un clic sur un bouton, la fin dun chargement de donnes provoquera la diffusion dun vnement par lobjet sujet. Tous les vnements existants en ActionScript 3 sont stocks dans des proprits constantes de classes lies lvnement. Lcouteur Lcouteur a pour mission dcouter un vnement spcifique auprs dun ou plusieurs sujets. Il peut tre une fonction ou une mthode. Lorsque le sujet change dtat, ce dernier diffuse un vnement appropri, si lcouteur est souscrit auprs de lvnement diffus, il en est notifi et excute une action. Il est 6 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

important de souligner quil peut y avoir de multiples couteurs pour un mme vnement. Cest justement lun des points forts existant au sein de lancien modle qui fut conserv dans ce nouveau reprsent par la figure 3-1 :

Figure 3-1. Schma du modle de conception Observateur Nos couteurs sont dpendants du sujet, ils y ont souscrit. Le sujet ne connat rien des couteurs, il sait simplement sil est observ ou non travers sa liste interne dcouteurs. Lorsque celui-ci change dtat un vnement est diffus, nos couteurs en sont notifis et peuvent alors ragir. Tout vnement diffus envoie des informations aux couteurs leur permettant dtre tenus au courant des modifications et donc de rester jour en permanence avec le sujet. Nous dcouvrirons au fil de ces pages, la souplesse apporte par ce nouveau modle vnementiel, et vous apprcierez son fonctionnement trs rapidement. Cela reste encore relativement abstrait, pour y remdier voyons ensemble comment ce modle vnementiel stablit au sein dune application Flash traditionnelle. Prenons un exemple simple constitu dun bouton et dune fonction couteur ragissant lorsque lutilisateur clique sur ce bouton. Nous avons dans ce cas nos trois acteurs mettant en scne le nouveau modle vnementiel ActionScript 3 : Le sujet : le bouton Lvnement : le clic bouton

7 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

Lcouteur : la fonction

Transpos dans une application ActionScript 3 traditionnelle, nous pouvons tablir le schma suivant :

Figure 3-2. Modle vnementiel dans une application ActionScript 3 Notre bouton est un sujet pouvant diffuser un vnement. Celui-ci est cout par une fonction couteur.

A retenir Il existe un seul et unique modle vnementiel en ActionScript 3. Ce modle vnementiel est bas sur le modle de conception Observateur. Les trois acteurs de ce nouveau modle vnementiel sont : le sujet, lvnement, et lcouteur. Nous pouvons avoir autant dcouteurs que nous le souhaitons. Plusieurs couteurs peuvent couter le mme vnement. Un seul couteur peut tre souscrit diffrents vnements.

Tout est vnementielLessentiel du modle vnementiel rside au sein dune seule et unique classe appele EventDispatcher. Cest elle qui offre la possibilit un objet de diffuser des vnements. Tous les objets issus de lAPI du lecteur 9 et 10 hritent de cette classe, et possdent de ce fait la capacit de diffuser des vnements.

8 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

Souvenez-vous que toutes les classes issues du paquetage flash sont relatives lAPI du lecteur Flash. Avant le lecteur 9, ces objets hritaient simplement de la classe Object, si nous souhaitions pouvoir diffuser des vnements nous devions nous mme implmenter la classe EventDispatcher au sein de ces objets. Voici la chane dhritage de la classe MovieClip avant le lecteur Flash 9 :Object | +-MovieClip

Dans les prcdentes versions du lecteur Flash, la classe MovieClip tendait directement la classe Object, si nous souhaitions pouvoir diffuser des vnements partir dun MovieClip nous devions implmenter nous-mmes un nouveau modle vnementiel. Voyons comme cela a volu avec lActionScript 3 au sein du lecteur 9. Depuis le lecteur 9 et ActionScript 3 :Object | +-EventDispatcher

La classe EventDispatcher hrite dsormais de la classe Object, tous les autres objets hritent ensuite dEventDispatcher et bnficient donc de la diffusion dvnements en natif. Cest une grande volution pour nous autres dveloppeurs ActionScript, car la plupart des objets que nous manipulerons auront la possibilit de diffuser des vnements par dfaut. Ainsi la classe MovieClip en ActionScript 3 hrite dabord de la classe Object puis dEventDispatcher pour ensuite hriter des diffrentes classes graphiques. Toutes les classes rsidant dans le paquetage flash ne drogent pas la rgle et suivent ce mme principe. Voici la chane dhritage complte de la classe MovieClip en ActionScript 3 :Object | +-EventDispatcher | +-DisplayObject | +-InteractiveObject |

9 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

+-DisplayObjectContainer | +-Sprite | +-MovieClip

Voyons ensemble comment utiliser ce nouveau modle vnementiel travers diffrents objets courants.

Ecouter un vnementLorsque vous souhaitez tre tenu au courant des dernires nouveauts de votre vidoclub, vous avez plusieurs possibilits. La premire consiste vous dplacer jusquau vidoclub afin de dcouvrir les dernires sorties. Une approche classique qui ne savre pas vraiment optimise. Nous pouvons dj imaginer le nombre de visites que vous effectuerez dans le magasin pour vous rendre compte quaucun nouveau DVD ne vous intresse. Une deuxime approche consiste laisser une liste de films que vous attendez au grant du vidoclub et attendre que celui-ci vous appelle lorsquun des films est arriv. Une approche beaucoup plus efficace pour vous et pour le grant qui en a assez de vous voir repartir du. Le grant incarne alors le diffuseur, et vous-mme devenez lcouteur. Le grant du vidoclub ne sait rien sur vous si ce nest votre nom et votre numro de tlphone. Il est donc le sujet, vous tes alors lcouteur car vous tes souscrit un vnement prcis : la disponibilit dun film que vous recherchez . En ActionScript 3 les objets fonctionnent de la mme manire. Pour obtenir une notification lorsque lutilisateur clique sur un bouton, nous souscrivons un couteur auprs dun vnement diffus par le sujet, ici notre bouton. Afin dcouter un vnement spcifique, nous utilisons la mthode addEventListener dont voici la signature :addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void

Le premier attend lvnement couter sous la forme dune chane de caractres. Le deuxime paramtre prend en rfrence lcouteur qui sera souscrit auprs de lvnement. Les trois derniers paramtres seront expliqus plus tard. Souvenez-vous que seuls les objets rsidant dans le paquetage flash utilisent ce modle vnementiel. Le schma mmoriser est donc le suivant : 10 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

sujet.addEventListener("evenement", ecouteur);

Voyons laide d'un exemple simple, comment couter un vnement. Dans un nouveau document Flash, crez un symbole bouton, et placez une occurrence de ce dernier sur la scne et nommez la monBouton. Sur un calque AS tapez le code suivant :monBouton.addEventListener ( "click", clicBouton ); function clicBouton ( pEvt:MouseEvent ):void { // affiche : vnement diffus trace("vnement diffus");

}

Nous coutons ici lvnement click sur le bouton monBouton et nous passons la fonction clicBouton comme couteur. Lorsque lutilisateur clique sur le bouton, il diffuse un vnement click qui est cout par la fonction clicBouton. Attention ne pas mettre de doubles parenthses lorsque nous passons une rfrence la fonction couteur. Nous devons passer sa rfrence et non le rsultat de son excution. Revenons un instant sur notre code prcdent :monBouton.addEventListener ( "click", clicBouton ); function clicBouton ( pEvt:MouseEvent ):void { // affiche : vnement diffus trace("vnement diffus");

}

Mme si cette syntaxe fonctionne, et ne pose aucun problme pour le moment, que se passe t-il si nous spcifions un nom dvnement incorrect ? Imaginons le cas suivant, nous faisons une erreur et coutons lvnement clicck :monBouton.addEventListener( "clicck", clicBouton );

Si nous testons le code ci-dessus, la fonction clicBouton ne sera jamais dclenche car le nom de lvnement click possde une erreur de saisie et de par sa non-existence nest jamais diffus.

11 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

Afin dviter ces problmes de saisie, tous les noms des vnements sont dsormais stocks dans des classes lies chaque vnement. Lorsque vous devez couter un vnement spcifique pensez immdiatement au type dvnement qui sera diffus. Les classes rsidant dans le paquetage flash.events constituent lensemble des classes vnementielles en ActionScript 3. Elles peuvent tre divises en deux catgories. On peut ainsi distinguer les classes vnementielles lies aux vnements autonomes : flash.events.Event flash.events.FullScreenEvent flash.events.IOErrorEvent

flash.events.HTTPStatusEvent flash.events.NetStatusEvent flash.events.ProgressEvent flash.events.StatusEvent flash.events.SyncEvent flash.events.TimerEvent flash.events.SecurityErrorEvent

Puis, celles lies aux vnements interactifs : flash.events.FocusEvent flash.events.IMEEvent flash.events.KeyboardEvent flash.events.MouseEvent flash.events.TextEvent

Dans notre cas, nous souhaitons couter un vnement qui relve dune interactivit utilisateur provenant de la souris. Nous nous dirigerons logiquement au sein de la classe MouseEvent. Pour rcuprer le nom dun vnement, nous allons cibler ces proprits constantes statiques, la syntaxe repose sur le systme suivant :ClasseEvenement.MON_EVENEMENT

Pour bien comprendre ce concept, crez un nouveau document Flash et sur un calque AS tapez la ligne suivante :// affiche : click trace ( MouseEvent.CLICK );

12 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

La classe MouseEvent contient tous les vnements relatifs la souris, en ciblant la proprit constante statique CLICK nous rcuprons la chane de caractres click que nous passerons en premier paramtre de la mthode addEventListener. En ciblant un nom dvnement par lintermdiaire dune proprit de classe nous bnficions de deux avantages. Si jamais une erreur de saisie survenait de par la vrification du code effectue par le compilateur notre code ne pourrait pas tre compil. Ainsi le code suivant chouerait la compilation :monBouton.addEventListener ( MouseEvent.CLICCK, clicBouton );

Il afficherait dans la fentre de sortie le message derreur suivant :1119: Accs la proprit CLICCK peut-tre non dfinie, via la rfrence de type static Class.

Au sein de Flash CS3, Flash CS4 ou Flex Builder le simple fait de cibler une classe vnementielle comme MouseEvent vous affiche aussitt tout les vnements lis cette classe. Vous naurez plus aucune raison de vous tromper dans le ciblage de vos vnements. A plus long terme, si le nom de lvnement click venait changer ou disparatre dans une future version du lecteur Flash, notre ancien code pointant vers la constante continuerait de fonctionner car ces proprits seront mises jour dans les futures versions du lecteur Flash. Pour couter le clic souris sur notre bouton, nous rcuprons le nom de lvnement et nous le passons la mthode addEventListener :monBouton.addEventListener( MouseEvent.CLICK, clicBouton );

Cette nouvelle manire de stocker le nom des vnements apporte donc une garantie la compilation mais rgle aussi un souci de compatibilit future. Voyons ensemble les diffrentes classes lies aux vnements existant en ActionScript 3.

Lobjet vnementielLorsquun vnement est diffus, un objet est obligatoirement envoy en paramtre la fonction couteur. Cet objet est appel objet vnementiel. Pour cette raison, la fonction couteur doit imprativement contenir dans sa signature un paramtre du type de lvnement diffus. Afin de ne jamais vous tromper, souvenez-vous de la rgle suivante.

13 / 35Thibault Imbert pratiqueactionscript3.bytearray.org

Chapitre 3 Le modle vnementiel - version 0.1.3

Le type de lobjet vnementiel correspond toujours au type de la classe contenant le nom de lvnement. Dans notre exemple il sagit de MouseEvent. Lobjet vnementiel contient des informations lies lvnement en cours de diffusion. Ces informations sont disponibles travers des proprits de lobjet vnementiel. Nous nous attarderons pour linstant sur trois de ces proprits, target, currentTarget et type. La proprit target fait rfrence lobjet cible de lvnement. De nimporte o nous pouvons savoir qui est lorigine de la propagation de lvnement. La proprit currentTarget fait rfrence lobjet diffuseur de lvnement (le sujet). Il sagit toujours de lobjet sur lequel nous avons appel la mthode addEventListener. La proprit type contient, elle, le nom de lvnement diffus, ici click.

Le code suivant rcupre une rfrence vers lobjet cible, le sujet, ainsi que le nom de lvnement :monBouton.addEventListener ( MouseEvent.CLICK, clicBouton ); function clicBouton ( pEvt:MouseEvent ):void { // affiche : [object SimpleButton] trace( pEvt.target ); // affiche : [object SimpleButton] trace( pEvt.currentTarget ); // affiche : click trace( pEvt.type ); }

Nous reviendrons au cours du chapitre 6 intitul Propagation vnementielle sur les diffrences subtiles entre les proprits t